Пример #1
0
static void
setupdevs()
{
	int dirno = 0;
	char **srch_dirs;

	hashtab = malloc(NDEVS * sizeof (struct devhash));
	if (hashtab == NULL) {
		(void) fprintf(stderr, gettext("No memory for device table\n"));
		return;
	}

	srch_dirs = get_pri_dirs();

	while (srch_dirs[dirno] != NULL) {
		if (srch_dir(srch_dirs[dirno]) < 0)
			return;
		dirno++;
	}

	dirno = 0;
	while (srch_dirs[dirno] != NULL) {
		if (strcmp("/dev", srch_dirs[dirno]) == 0)
			/*
			 * Don't search /dev twice.
			 */
			return;
		dirno++;
	}
}
Пример #2
0
static int
srch_dir(const entry_t path,	/* current path */
	int match_mask,		/* flags mask */
	int depth,		/* current depth (/dev = 0) */
	const entry_t skip_dirs[], /* directories not needing searching */
	struct stat64 *fsb)	/* the file being searched for */
{
	DIR *dirp;
	struct dirent64 *direntp;
	struct stat64 tsb;
	char file_name[MAX_DEV_PATH];
	entry_t file;
	char *last_comp;
	int found = 0;
	int dirno = 0;
	size_t path_len;

	file.name = file_name;
	file.flags = path.flags & match_mask;
	if (file.flags == 0)
		file.flags = match_mask;

	/*
	 * do we need to search this directory? (always search /dev at depth 0)
	 */
	if ((skip_dirs != NULL) && (depth != 0))
		while (skip_dirs[dirno].name != NULL)
			if (strcmp(skip_dirs[dirno++].name, path.name) == 0)
				return (0);

	/*
	 * open directory
	 */
	if ((dirp = opendir(path.name)) == NULL) {
		return (0);
	}

	/*
	 * skip two first entries ('.' and '..')
	 */
	if (((direntp = readdir64(dirp)) == NULL) ||
	    ((direntp = readdir64(dirp)) == NULL)) {
		(void) closedir(dirp);
		return (0);
	}

	path_len = strlen(path.name);
	(void) strcpy(file_name, path.name);
	last_comp = file_name + path_len;
	*last_comp++ = '/';

	/*
	 * read thru the directory
	 */
	while ((!found) && ((direntp = readdir64(dirp)) != NULL)) {

		/*
		 * if the file name (path + "/" + d_name + NULL) would be too
		 * long, skip it
		 */
		if ((path_len + strlen(direntp->d_name) + 2) > MAX_DEV_PATH)
			continue;
		else
			(void) strcpy(last_comp, direntp->d_name);

		if (stat64(file_name, &tsb) < 0)
			continue;

		/*
		 * if a file is a directory and we are not too deep, recurse
		 */
		if ((tsb.st_mode & S_IFMT) == S_IFDIR)
			if (depth < MAX_SRCH_DEPTH)
				found = srch_dir(file, match_mask, depth+1,
						skip_dirs, fsb);
			else
				continue;

		/*
		 * else if it is not a directory, is it a character special
		 * file?
		 */
		else if ((tsb.st_mode & S_IFMT) == S_IFCHR) {
			int flag = 0;
			if (tsb.st_dev == fsb->st_dev)
				flag |= MATCH_FS;
			if (tsb.st_rdev == fsb->st_rdev)
				flag |= MATCH_MM;
			if (tsb.st_ino == fsb->st_ino)
				flag |= MATCH_INO;

			if ((flag & file.flags) == file.flags) {
				(void) strcpy(rbuf, file.name);
				found = 1;
			} else if ((flag & (MATCH_MM | MATCH_FS)) ==
					(MATCH_MM | MATCH_FS)) {

				/*
				 * no (inodes do not match), but save the name
				 * for later
				 */
				(void) strcpy(dev_rbuf, file.name);
				dev_flag = 1;
			}
		}
	}
	(void) closedir(dirp);
	return (found);
}
Пример #3
0
static char *
_ttyname_common(struct stat64 *fsp, char *buffer, uint_t match_mask)
{
	struct stat64 tfsb;
	const entry_t *srch_dirs;	/* priority directories */
	spcl_t *spclp;
	int i;
	int found = 0;
	int dirno = 0;
	int is_pts = 0;
	char *retval = NULL;
	char *pt = NULL;

	/*
	 * We can't use lmutex_lock() here because we call malloc()/free()
	 * and _libc_gettext().  Use the brute-force fork_lock_enter().
	 */
	(void) fork_lock_enter(NULL);

	/*
	 * match special cases
	 */

	for (spclp = special_case, i = 0; i < NUMSPECIAL; spclp++, i++) {
		if ((spclp->spcl_inum | spclp->spcl_fsdev |
		    spclp->spcl_rdev) == 0) {
			if (stat64(spclp->spcl_name, &tfsb) != 0)
				continue;
			spclp->spcl_rdev = tfsb.st_rdev;
			spclp->spcl_fsdev = tfsb.st_dev;
			spclp->spcl_inum = tfsb.st_ino;
		}
		if (match_mask == MATCH_MM) {
			if (spclp->spcl_rdev == fsp->st_rdev) {
				retval = strcpy(rbuf, spclp->spcl_name);
				goto out;
			}
		} else if (spclp->spcl_fsdev == fsp->st_dev &&
		    spclp->spcl_rdev == fsp->st_rdev &&
		    spclp->spcl_inum == fsp->st_ino) {
			retval = strcpy(rbuf, spclp->spcl_name);
			goto out;
		}
	}
	/*
	 * additional special case: ptm clone device
	 *   ptm devs have no entries in /dev
	 *   if major number matches, just short circuit any further lookup
	 *   NOTE: the minor number of /dev/ptmx is the ptm major number
	 */
	spclp = &ptmspecial;
	if ((spclp->spcl_inum | spclp->spcl_fsdev | spclp->spcl_rdev) == 0) {
		if (stat64(spclp->spcl_name, &tfsb) == 0) {
			spclp->spcl_rdev = tfsb.st_rdev;
			spclp->spcl_fsdev = tfsb.st_dev;
			spclp->spcl_inum = tfsb.st_ino;
		}
	}
	if ((spclp->spcl_rdev != 0) &&
	    (minor(spclp->spcl_rdev) == major(fsp->st_rdev)))
		goto out;

	/*
	 * additional special case: pty dev
	 *  one of the known default pairs of /dev/ptyXX or /dev/ttyXX
	 */
	if ((retval = ispty(fsp, match_mask)) != NULL)
		goto out;

	/*
	 * search the priority directories
	 */


	srch_dirs = get_pri_dirs();
	dev_flag = 0;

	while ((!found) && (srch_dirs[dirno].name != NULL)) {

		/*
		 * if /dev is one of the priority directories, only
		 * search its top level(set depth = MAX_SEARCH_DEPTH)
		 */

		/*
		 * Is /dev/pts then just do a quick check. We don't have
		 * to stat the entire /dev/pts dir.
		 */
		if (strcmp(PTS, srch_dirs[dirno].name) == NULL) {
			if ((pt = ispts(fsp, match_mask)) != NULL) {
				is_pts = 1;
				found = 1;
			}
		} else {
			found = srch_dir(srch_dirs[dirno], match_mask,
				((strcmp(srch_dirs[dirno].name,
				dev_dir.name) == 0) ?
				MAX_SRCH_DEPTH : 1), 0, fsp);
		}
		dirno++;
	}

	/*
	 * search the /dev/ directory, skipping priority directories
	 */
	if (!found)
		found = srch_dir(dev_dir, match_mask, 0, srch_dirs, fsp);


	/*
	 * return
	 */

	if (found) {
		if (is_pts)
			retval = pt;
		else
			retval = rbuf;
	} else if (dev_flag)
		retval = dev_rbuf;
	else
		retval = NULL;
out:	retval = (retval ? strcpy(buffer, retval) : NULL);
	fork_lock_exit();
	return (retval);
}
Пример #4
0
inoptr kn_open(char *namep, inoptr *parent)
{
    staticfast inoptr wd;     /* the directory we are currently searching. */
    staticfast inoptr ninode;
    inoptr temp;
    staticfast char *name;

    name = namep;
#ifdef DEBUG
    kprintf("kn_open(\"%s\")\n", name);
#endif

    if(*name == '/')
        wd = udata.u_root;
    else
        wd = udata.u_cwd;

    i_ref(ninode = wd);
    i_ref(ninode);

    for(;;)
    {
        if(ninode)
            magic(ninode);

        /* cheap way to spot rename inside yourself */
        if (udata.u_rename == ninode)
            udata.u_rename = NULLINODE;

        /* See if we are at a mount point */
        if(ninode)
            ninode = srch_mt(ninode);

        while(*name == '/')    /* Skip(possibly repeated) slashes */
            ++name;
        if(!*name)           /* No more components of path? */
            break;
        if(!ninode){
            udata.u_error = ENOENT;
            goto nodir;
        }
        i_deref(wd);
        wd = ninode;
        if(getmode(wd) != F_DIR){
            udata.u_error = ENOTDIR;
            goto nodir;
        }
        if(!(getperm(wd) & OTH_EX)){
            udata.u_error = EPERM;
            goto nodir;
        }

        /* See if we are going up through a mount point */
        if((wd == udata.u_root || (wd->c_num == ROOTINODE && wd->c_dev != root_dev)) &&
                name[0] == '.' && name[1] == '.' &&
                (name[2] == '/' || name[2] == '\0')){
            if (wd == udata.u_root) {
                ninode = wd;
                name += 2;
                continue;
            }
            temp = fs_tab_get(wd->c_dev)->m_fs->s_mntpt;
            ++temp->c_refs;
            i_deref(wd);
            wd = temp;
        }

        ninode = srch_dir(wd, name);

        while(*name != '/' && *name)
            ++name;
    }

    if(parent)
        *parent = wd;
    else
        i_deref(wd);

    if(!(parent || ninode))
        udata.u_error = ENOENT;

    return ninode;

nodir:
    if(parent)
        *parent = NULLINODE;
    i_deref(wd);
    return NULLINODE;
}