コード例 #1
0
static int
get_media_info(char *path, char **mtypep, int *mnump, char **spclp)
{
	FILE		*fp = NULL;
	int		fd = -1;
	char		*cn = NULL;		/* char spcl pathname */
	struct stat64	sb;
	struct dk_cinfo	info;
	struct mnttab	mnt;
	int		ret_val = FALSE;

	if ((fp = fopen(MNTTAB, "rF")) == NULL) {
		/* mtab is gone... let him go */
		goto dun;
	}

	/* get char spcl pathname */
	if ((cn = volmgt_getfullrawname(path)) == NULL) {
		goto dun;
	}
	if (cn[0] == NULLC) {
		goto dun;
	}

	if ((fd = open(cn, O_RDONLY|O_NDELAY)) < 0) {
		goto dun;
	}

	if (fstat64(fd, &sb) < 0) {
		goto dun;
	}

	if (ioctl(fd, DKIOCINFO, &info) != 0) {
		goto dun;
	}

	/* if we found the entry then disect it */
	if (vol_getmntdev(fp, &mnt, sb.st_rdev, &info) != 0) {
		char		*cp;
		char		*mtype;
		char		*mnt_dir;
		int		mtype_len;
		DIR		*dirp = NULL;
		struct dirent64	*dp;
		char		*volname;


		/* return the spcl device name found */
		*spclp = strdup(mnt.mnt_special);

		/*
		 * try to get the media type (e.g. "floppy") from the mount
		 * point (e.g. "/floppy/NAME") if vold is running
		 */

		if (!volmgt_running() ||
		    (!volmgt_ownspath(*spclp) &&
		    volmgt_symname(*spclp) == NULL)) {
			ret_val = TRUE;		/* success (if limited) */
			goto dun;
		}

		/* get the first part of the mount point (e.g. "floppy") */
		cp = mnt.mnt_mountp;
		if (*cp++ != '/') {
			goto dun;
		}
		mtype = cp;
		if ((cp = strchr(mtype, '/')) == NULL) {
			goto dun;
		}
		*cp++ = NULLC;
		mnt_dir = mnt.mnt_mountp;	/* save dir path */

		/* get the volume name (e.g. "unnamed_floppy") */
		volname = cp;

		/* scan for the symlink that points to our volname */
		if ((dirp = opendir(mnt_dir)) == NULL) {
			goto dun;
		}
		mtype_len = strlen(mtype);
		while ((dp = readdir64(dirp)) != NULL) {
			char		lpath[2 * (MAXNAMELEN+1)];
			char		linkbuf[MAXPATHLEN+4];
			int		lb_len;
			struct stat64	sb;


			if (strncmp(dp->d_name, mtype, mtype_len) != 0) {
				continue;	/* not even close */
			}

			(void) sprintf(lpath, "%s/%s", mnt_dir,
			    dp->d_name);
			if (lstat64(lpath, &sb) < 0) {
				continue;	/* what? */
			}
			if (!S_ISLNK(sb.st_mode)) {
				continue;	/* not our baby */
			}
			if ((lb_len = readlink(lpath, linkbuf,
			    sizeof (linkbuf))) < 0) {
				continue;
			}
			linkbuf[lb_len] = NULLC; /* null terminate */
			if ((cp = vol_basename(linkbuf)) == NULL) {
				continue;
			}
			/* now we have the name! */
			if (strcmp(cp, volname) == 0) {
				/* found it !! */
				if (sscanf(dp->d_name + mtype_len, "%d",
				    mnump) == 1) {
					*mtypep = strdup(mtype);
					ret_val = TRUE;
				}
				break;
			}
		}
		(void) closedir(dirp);
	}

dun:
	if (fp != NULL) {
		(void) fclose(fp);
	}
	if (fd >= 0) {
		(void) close(fd);
	}
	if (cn != NULL) {
		free(cn);
	}
#ifdef	DEBUG
	if (ret_val) {
		dexit("get_media_info: returning mtype=%s, mnum=%d, spcl=%s\n",
		    *mtypep == NULL ? "<null ptr>" : *mtypep,
		    *mnump,
		    *spclp == NULL ? "<null ptr>" : *spclp);
	} else {
		dexit("get_media_info: FAILED\n");
	}
#endif
	return (ret_val);
}
コード例 #2
0
/*
 * call the appropriate unmount program, returning its success (TRUE)
 * or failure (FALSE)
 */
static int
call_unmount_prog(int mi_gotten, int use_rmm, char *mtype, int mnum,
    char *spcl, char *bn)
{
	pid_t		pid;			/* forked proc's pid */
	int		ret_val = FALSE;
	const char	*etc_umount = "/etc/umount";
	const char	*rmm = "/usr/sbin/rmmount";
	int		rval;			/* proc's return value */


#ifdef	DEBUG
	denter(
	"call_unmount_prog(%s, %s, \"%s\", %d, \"%s\", \"%s\"): entering\n",
	    mi_gotten ? "TRUE" : "FALSE", use_rmm ? "TRUE" : "FALSE",
	    mtype ? mtype : "<null ptr>", mnum, spcl ? spcl : "<null ptr>",
	    bn);
#endif
	/* create a child to unmount the path */
	if ((pid = fork()) < 0) {
		goto dun;
	}

	if (pid == 0) {
		/* the child */
#ifndef	DEBUG
		int		xfd;
#endif
		char		env_buf[MAXPATHLEN];

#ifndef	DEBUG
		/* get rid of those nasty err messages */
		if ((xfd = open(NULL_PATH, O_RDWR)) >= 0) {
			(void) dup2(xfd, fileno(stdin));
			(void) dup2(xfd, fileno(stdout));
			(void) dup2(xfd, fileno(stderr));
		}
#endif

		if (use_rmm) {
			/* set up environment vars */
			(void) putenv("VOLUME_ACTION=eject");
			(void) putenv(strdup(env_buf));
			if (mi_gotten) {
				(void) sprintf(env_buf,
				    "VOLUME_MEDIATYPE=%s", mtype);
				(void) putenv(strdup(env_buf));
				(void) sprintf(env_buf, "VOLUME_SYMDEV=%s%d",
				    mtype, mnum);
				(void) putenv(strdup(env_buf));
				(void) sprintf(env_buf, "VOLUME_PATH=%s",
				    spcl);
				(void) putenv(strdup(env_buf));
				(void) sprintf(env_buf, "VOLUME_NAME=%s",
				    vol_basename(spcl));
				(void) putenv(strdup(env_buf));
			} else {
				(void) sprintf(env_buf, "VOLUME_PATH=%s", bn);
				(void) putenv(strdup(env_buf));
				(void) sprintf(env_buf, "VOLUME_NAME=%s",
				    vol_basename(bn));
				(void) putenv(strdup(env_buf));
			}
#ifdef	DEBUG
			dprintf("call_unmount_prog: calling \"%s -D\"\n", rmm);
			(void) execl(rmm, rmm, "-D", NULL);
#else
			(void) execl(rmm, rmm, NULL);
#endif
		} else {
#ifdef	DEBUG
			dprintf("call_unmount_prog: calling \"%s %s\"\n",
			    etc_umount, mi_gotten ? spcl : bn);
#endif
			(void) execl(etc_umount, etc_umount,
			    mi_gotten ? spcl : bn,
			    NULL);
		}
		exit(-1);
		/*NOTREACHED*/
	}

	/* wait for the umount command to exit */
	if (waitpid(pid, &rval, 0) == pid) {
		if (WIFEXITED(rval)) {
			if (WEXITSTATUS(rval) == 0) {
				ret_val = TRUE;	/* success */
			}
		}
	}

dun:
	return (ret_val);
}
コード例 #3
0
ファイル: volname.c プロジェクト: andreiw/polaris
/*
 * Return a raw name, given a starting point.
 *
 * Assume: input string ptr is not null
 */
static char *
media_findname_work(char *start)
{
	extern char		*vol_basename(char *);
	static void		volmgt_deref_link(char *, char *, char *);
	char			pathbuf[MAXPATHLEN+1];
	char			*rv;
	char			*s;
	char			linkbuf[MAXNAMELEN+1];
	char			*nameptr;
	struct stat64		sb;
	int			n;
	int			i;
	static const char	*vold_root = NULL;
	static char		vold_alias_dir[MAXPATHLEN+1];
	char			*res = NULL;
	DIR			*dirp = NULL;
	struct dirent64		*dp;



#ifdef	DEBUG
	denter("media_findname_work(%s): entering\n", start);
#endif

	if (vold_root == NULL) {
		vold_root = volmgt_root();
		(void) concat_paths(vold_alias_dir, (char *)vold_root,
		    (char *)ALIAS_DIR, NULL);
	}

	/*
	 * if this is an absolute path name then
	 *  if it's a symlink deref it
	 *  if it's a raw device then we're done
	 *  else if it's a directory then look for a dev under it
	 */
	if (IS_ABS_PATH(start)) {

		/* try to get data on name passed in */
		if (lstat64(start, &sb) < 0) {
#ifdef	DEBUG
			dprintf(
			"media_findname_work: lstat of \"%s\" (errno %d)\n",
			    start, errno);
#endif
			goto dun;		/* error exit */
		}

		/*
		 * if is this a link to something else (e.g. ".../floppy0")
		 * and it's in the volmgt namespace, then deref it
		 */
		if (S_ISLNK(sb.st_mode) && (strncmp(start, vold_alias_dir,
		    strlen(vold_alias_dir)) == 0)) {

			/* it's a symlink */
			if ((n = readlink(start, linkbuf, MAXNAMELEN)) <= 0) {
				/* we can't read the link */
#ifdef	DEBUG
				dprintf(
		"media_findname_work: readlink(\"%s\") failed (errno %d)\n",
				    start, errno);
#endif
				goto dun;	/* error exit */
			}
			linkbuf[n] = NULLC;

			/* dereference the link */
			volmgt_deref_link(pathbuf, start, linkbuf);

			/* stat where "start" pointed at */
			if (stat64(pathbuf, &sb) < 0) {
#ifdef	DEBUG
				dprintf(
		"media_findname_work: stat failed on \"%s\" (errno %d)\n",
				    pathbuf, errno);
#endif
				goto dun;	/* error exit */
			}
			nameptr = pathbuf;

		} else {
			nameptr = start;
		}

		/* do we already have a char-spcl device ?? */
		if (S_ISCHR(sb.st_mode)) {
			/*
			 * absoluate pathname of a char-spcl device passed in
			 */
			res = strdup(nameptr);
			goto dun;		/* success */
		}

		/* not a char-spcl device -- is it a dir ?? */
		if (S_ISDIR(sb.st_mode)) {
			/* open the dir and find first char-spcl device */
			if ((s = getrawpart0(nameptr)) != NULL) {
				/*
				 * absoluate pathname to a directory passed
				 * in, under which there is at least one
				 * char-spcl device
				 */
				free(s);
				res = strdup(nameptr);
				goto dun;	/* success */
			}
		}

		/*
		 * try to get the char-spcl name if this is a blk-spcl
		 *
		 * XXX: shouldn't we ensure this is a blk spcl device?
		 */
		rv = volmgt_getfullrawname(nameptr);
		if ((rv == NULL) || (*rv == NULLC)) {
			goto dun;		/* error exit */
		}

		/* stat the fullrawname device (to see if it's char-spcl) */
		if (stat64(rv, &sb) < 0) {
#ifdef	DEBUG
			dprintf(
			    "media_findname_work: stat of \"%s\" (errno %d)\n",
			    rv, errno);
#endif
			goto dun;		/* error exit */
		}

		/* have we found the char-spcl device ?? */
		if (S_ISCHR(sb.st_mode)) {
			/*
			 * absolute pathname to block device supplied and
			 * converted to an absoluate pathname to a char device
			 */
			res = rv;		/* already malloc'ed */
			goto dun;		/* success */
		}

		/*
		 * fullrawname not a char-spcl device -- is it a dir ??
		 *
		 * XXX: didn't we already check for a directory name
		 * being supplied above?
		 */
		if (S_ISDIR(sb.st_mode)) {
			/* open dir and find first char-spcl device */
			if ((s = getrawpart0(rv)) != NULL) {
				/*
				 * the absolute pathname of directory
				 * containing at least one char-spcl device
				 * was passed in
				 */
				free(s);
				res = strdup(rv);
				goto dun;	/* success */
			}
		}

		/* having a full pathname didn't help us */
		goto dun;	/* failure -- pathname not found */
	}

	/*
	 * Ok, now we check to see if it's an alias.
	 * Note here that in the case of an alias, we prefer
	 * to return what the alias (symbolic link) points
	 * at, rather than the symbolic link.  Makes for
	 * nicer printouts and such.
	 */
	(void) concat_paths(pathbuf, vold_alias_dir, start, NULL);

#ifdef	DEBUG
	dprintf("media_findname_work: looking for \"%s\"\n", pathbuf);
#endif

	if (stat64(pathbuf, &sb) == 0) {
#ifdef	DEBUG
		dprintf("media_findname_work: is \"%s\" a chr-spcl dev?\n",
		    pathbuf);
#endif
		/* is this a char-spcl device ?? */
		if (S_ISCHR(sb.st_mode)) {
			/* it's probably a link, so ... */
			if ((n = readlink(pathbuf,
			    linkbuf, MAXNAMELEN)) <= 0) {
				/*
				 * error (since we are in the symlink
				 * directory) not a link, but just punt
				 * anyway
				 */
				res = strdup(pathbuf);
			} else {
				/* it was a link */
				linkbuf[n] = NULLC;
				res = strdup(linkbuf);
			}
			goto dun;		/* success */
		}

#ifdef	DEBUG
		dprintf("media_findname_work: not chr-spcl -- is it a dir?\n");
#endif
		/* not a char-spcl device -- is it a dir ?? */
		if (S_ISDIR(sb.st_mode)) {
			/* it's probably a link, so ... */
			if ((n = readlink(pathbuf,
			    linkbuf, MAXNAMELEN)) <= 0) {
				/*
				 * error, but just punt anyway
				 */
				nameptr = pathbuf;
				s = getrawpart0(pathbuf);
			} else {
				/* it was a link */
				linkbuf[n] = NULLC;
				/* open dir, finding first char-spcl dev */
				nameptr = linkbuf;
				s = getrawpart0(linkbuf);
			}
			if (s != NULL) {
				free(s);
				res = strdup(nameptr);
				goto dun;
			}
		}
	}

	/*
	 * check all aliases in the alias dir, to see if any match
	 */
	if ((dirp = opendir(vold_alias_dir)) == NULL) {
		goto try_hack;
	}

	while (dp = readdir64(dirp)) {

		/* skip uninteresting entries */
		if (strcmp(dp->d_name, ".") == 0) {
			continue;
		}
		if (strcmp(dp->d_name, "..") == 0) {
			continue;
		}

#ifdef	DEBUG
		dprintf("media_findname_work: scanning alias \"%s\" ...\n",
		    dp->d_name);
#endif
		/*
		 * open the link and see if it points at our entry
		 */
		(void) concat_paths(pathbuf, vold_alias_dir, dp->d_name,
		    NULL);
		if ((n = readlink(pathbuf, linkbuf, MAXNAMELEN)) <= 0) {
#ifdef	DEBUG
				dprintf(
		"media_findname_work: readlink(\"%s\") failed (errno %d)\n",
				    pathbuf, errno);
#endif
			continue;
		}
		linkbuf[n] = NULLC;

#ifdef	DEBUG
		dprintf("media_findname_work: scanning link \"%s\" ...\n",
		    linkbuf);
#endif
		if (strcmp(vol_basename(linkbuf), start) == 0) {

			/* we *think* we've found a match */

			if (stat64(linkbuf, &sb) == 0) {

				if (S_ISCHR(sb.st_mode)) {
					res = strdup(linkbuf);
					goto dun;
				}

				if (S_ISDIR(sb.st_mode)) {
					res = getrawpart0(linkbuf);
					if (res != NULL) {
						free(res);
						res = strdup(linkbuf);
					}
					goto dun;
				}

			}

		}
	}

try_hack:

	/*
	 * Ok, well maybe that's not it.  Let's try the
	 * hackname alias.
	 */

	/*
	 * This creates the "hack" name.  The model
	 * is that xx# has the alias xx.  So, cdrom#
	 * and floppy# (the most frequent case) can
	 * be referred to as cdrom and floppy.
	 * We poke at what we consider to be a reasonable number of
	 * devices (currently 5) before giving up.
	 */

	for (i = 0; i < HACKNAME_MAX; i++) {
		char	num_buf[NUMBUF_SZ];


		(void) sprintf(num_buf, "%d", i);
		(void) concat_paths(pathbuf, vold_alias_dir, start, num_buf);

		if (stat64(pathbuf, &sb) == 0) {

			/* is it a char-spcl device ?? */
			if (S_ISCHR(sb.st_mode)) {
				/* it's probably a link, so... */
				if ((n = readlink(pathbuf,
				    linkbuf, MAXNAMELEN)) <= 0) {
					/* it wasn't a link */
					res = strdup(pathbuf);
				} else {
					/* it was a link */
					linkbuf[n] = NULLC;
					res = strdup(linkbuf);
				}
				goto dun;
			}

			/* not a char-spcl device -- is it a dir ?? */
			if (S_ISDIR(sb.st_mode)) {
				/* it's probably a link, so ... */
				if ((n = readlink(pathbuf,
				    linkbuf, MAXNAMELEN)) <= 0) {
					/* get fist char-spcl dev in dir */
					nameptr = pathbuf;
					s = getrawpart0(pathbuf);
				} else {
					/* it was a link */
					linkbuf[n] = NULLC;
					/* get fist char-spcl dev in dir */
					nameptr = linkbuf;
					s = getrawpart0(linkbuf);
				}
				if (s != NULL) {
					free(s);
					res = strdup(nameptr);
					goto dun;
				}
			}
		}
	}

#ifdef	DEBUG
	dprintf("media_findname_work: %s didn't match any test!\n", start);
#endif

dun:
	if (dirp != NULL) {
		(void) closedir(dirp);
	}

#ifdef	DEBUG
	dexit("media_findname_work: returning \"%s\"\n",
	    res ? res : "<null ptr>");
#endif
	return (res);
}