OpenSolaris_b135/lib/lvm/libsvm/common/metaconf.c

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/mkdev.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <limits.h>
#include <string.h>
#include <libsvm.h>
#include <svm.h>
#include <errno.h>


#define	VERSION "1.0"
#define	DISK_DIR "/dev/rdsk"

extern int _map_to_effective_dev();

static int is_blank(char *);

/*
 * is_blank() returns 1 (true) if a line specified is composed of
 * whitespace characters only. otherwise, it returns 0 (false).
 *
 * Note. the argument (line) must be null-terminated.
 */
static int
is_blank(char *line)
{
	for (/* nothing */; *line != '\0'; line++)
		if (!isspace(*line))
			return (0);
	return (1);
}

/*
 * FUNCTION: write_targ_nm_table
 *	creates a tuple table of <driver name, major number > in md.conf
 * INPUT: rootpath
 *
 * RETURN VALUES:
 *	RET_SUCCESS
 *	RET_ERROR
 */

int
write_targ_nm_table(char *path)
{
	FILE	*targfp = NULL;
	FILE	*mdfp = NULL;
	char	buf[PATH_MAX], *cp;
	int	retval = RET_SUCCESS;
	int	first_entry = 1;

	if ((mdfp = fopen(MD_CONF, "a")) == NULL)
		return (RET_ERROR);

	(void) snprintf(buf, sizeof (buf), "%s%s", path, NAME_TO_MAJOR);

	if ((targfp = fopen(buf, "r")) == NULL) {
		(void) fclose(mdfp);
		return (RET_ERROR);
	}

	while (fgets(buf, PATH_MAX, targfp) != NULL &&
	    (retval == RET_SUCCESS)) {
		/* remove a new-line character for md_targ_nm_table */
		if ((cp = strchr(buf, '\n')) != NULL)
			*cp = 0;
		/* cut off comments starting with '#' */
		if ((cp = strchr(buf, '#')) != NULL)
			*cp = 0;
		/* ignore comment or blank lines */
		if (is_blank(buf))
			continue;
		if (first_entry) {
			if (fprintf(mdfp, "md_targ_nm_table=\"%s\"", buf) < 0)
				retval = RET_ERROR;
			first_entry = 0;
		} else {
			if (fprintf(mdfp, ",\"%s\"", buf) < 0)
					retval = RET_ERROR;
		}
	}
	if (!first_entry)
		if (fprintf(mdfp, ";\n") < 0)
			retval = RET_ERROR;
	(void) fclose(mdfp);
	(void) fclose(targfp);
	return (retval);
}

/*
 * FUNCTION: write_xlate_to_mdconf
 *	creates a tuple table of <miniroot devt, target devt> in md.conf
 * INPUT: rootpath
 *
 * RETURN VALUES:
 *	RET_SUCCESS
 *	RET_ERROR
 */

int
write_xlate_to_mdconf(char *path)
{
	FILE		*fptr = NULL;
	struct dirent	*dp;
	DIR		*dirp;
	struct stat	statb_dev;
	struct stat	statb_edev;
	char		*devname;
	char		edevname[PATH_MAX];
	char		targname[PATH_MAX];
	char		diskdir[PATH_MAX];
	char		linkpath[PATH_MAX];
	int		first_devid = 1;
	int		ret = RET_SUCCESS;

	if ((fptr = fopen(MD_CONF, "a")) == NULL) {
		return (RET_ERROR);
	}


	(void) snprintf(diskdir, sizeof (diskdir), "%s%s", path, DISK_DIR);
	if ((dirp = opendir(diskdir)) == NULL) {
		(void) fclose(fptr);
		return (RET_ERROR);
	}

	/* special case to write the first tuple in the table */
	while (((dp = readdir(dirp)) != (struct dirent *)0) &&
	    (ret != RET_ERROR)) {
		if ((strcmp(dp->d_name, ".") == 0) ||
		    (strcmp(dp->d_name, "..") == 0))
			continue;

		if ((strlen(diskdir) + strlen(dp->d_name) + 2) > PATH_MAX) {
			continue;
		}

		(void) snprintf(targname, sizeof (targname), "%s/%s",
		    diskdir, dp->d_name);

		/*
		 * stat /devices to see if it's a devfs based file system
		 * On Solaris 10 and up, the devfs has been built on the
		 * fly for the mini-root. We need to adjust the path
		 * accordingly.
		 * If it's not devfs, just use the targname as it is.
		 */

		if (stat("/devices", &statb_dev) != 0) {
			continue;
		}

		if (strncmp("devfs", statb_dev.st_fstype, 5) == 0) {
			if (readlink(targname, linkpath,
			    sizeof (linkpath)) == -1) {
				continue;
			}
			/*
			 * turn ../../devices/<path> into /devices/<path>
			 * and stat that into statb_dev
			 */
			if (stat(strstr(linkpath, "/devices"),
			    &statb_dev) != 0) {
				continue;
			}
		} else {
			if (stat(targname, &statb_dev) != 0) {
				continue;
			}
		}

		if ((devname = strstr(targname, DISK_DIR)) == NULL) {
			continue;
		}

		if (_map_to_effective_dev((char *)devname, (char *)&edevname)
		    != 0) {
			continue;
		}

		if (stat(edevname, &statb_edev) != 0) {
			continue;
		}

		if (first_devid) {
			if (fprintf(fptr, "md_xlate_ver=\"%s\";\n"
			    "md_xlate=%lu,%lu", VERSION,
			    statb_edev.st_rdev, statb_dev.st_rdev) < 0)
				ret = RET_ERROR;
			first_devid = 0;
		}
		if (fprintf(fptr, ",%lu,%lu", statb_edev.st_rdev,
		    statb_dev.st_rdev) < 0)
			ret = RET_ERROR;
	} /* end while */

	if (!first_devid)
		if (fprintf(fptr, ";\n") < 0)
			ret = RET_ERROR;
	(void) fclose(fptr);
	(void) closedir(dirp);
	return (ret);
}