예제 #1
0
char *
volmgt_getfullrawname(char *n)
{
	extern char	*getfullrawname(char *);
	char		*rval;
	char		namebuf[MAXPATHLEN+1];
	char		*s;
	char		c;
	char		*res;


#ifdef	DEBUG
	denter("volmgt_getfullrawname(%s): entering\n", n);
#endif
	/* try to get full char-spcl device name */
	rval = getfullrawname(n);
	if ((rval != NULL) && (*rval != NULLC)) {
		/* found it */
		res = rval;
		goto dun;
	}

	/* we have a null-string result */
	if (rval != NULL) {
		/* free null string */
		free(rval);
	}

	/* ok, so we either have a bad device or a floppy */

	/* try the "fd", "diskette", and the "dsk" form */
	if (((s = strstr(n, "/fd")) != NULL) ||
	    ((s = strstr(n, "/diskette")) != NULL) ||
	    ((s = strstr(n, "/dsk/")) != NULL)) {
		/*
		 * ensure we have room to add one more char
		 */
		if (strlen(n) < (MAXPATHLEN - 1)) {
			c = *++s;		/* save the first char */
			*s = NULLC;		/* replace it with a null */
			(void) strcpy(namebuf, n); /* save first part of str */
			*s = c;			/* put first charback */
			(void) strcat(namebuf, "r"); /* insert an 'r' */
			(void) strcat(namebuf, s); /* copy rest of str */
			res = strdup(namebuf);
			goto dun;
		}
	}

	/* no match found */
	res = strdup("");
dun:
#ifdef	DEBUG
	dexit("volmgt_getfullrawname: returning %s\n",
	    res ? res : "<null ptr>");
#endif
	return (res);
}
예제 #2
0
/*
 * translate suplied vol name into a pathname
 *
 * if volmgt is running, this pathname will be in /vol (or its equiv)
 *
 * if volmgt is not running then this path may be anywhere
 *
 * in either case the pathname will *not* be verified as a blk/chr dev
 *
 * if the return value is non-null then it's been alloced
 *
 * NOTE: assume "vol" is not a NULL ptr
 */
static char *
fsi_xlate_name(char *vol)
{
	char	*res = NULL;			/* result to return */
	char	*vr;				/* volmgt root dir */
	bool_t	vm_running = volmgt_running();	/* volmgt running? */


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

	/* is it an absolute pathname ?? */
	if (*vol == '/') {

		if (vm_running) {
			/* pathname must be in the /vol namespace */
			vr = (char *)volmgt_root();
			if (strncmp(vol, vr, strlen(vr)) != 0) {
				/* not a cool pathname */
				errno = EINVAL;	/* XXX: is this correct */
				goto dun;
			}
		}

		res = strdup(vol);

	} else {

		/*
		 * if volmgt is running we can try to dereference it
		 * if volmgt isn't running then just give up
		 */

		if (!vm_running) {
			/* some unknown "name" */
			errno = ENOENT;
			goto dun;
		}

		res = volmgt_symdev(vol);

	}

dun:
#ifdef	DEBUG
	dexit("fsi_xlate_name: returning %s\n", res ? res : "<null ptr>");
#endif
	return (res);
}
예제 #3
0
파일: volname.c 프로젝트: andreiw/polaris
/*
 * arc approved interface (pending)
 *	- can not be modified without approval from an arc
 *
 * committment level:
 *	public
 *
 * description:
 *	media_findname: try to come up with the character device when
 *	provided with a starting point.  This interface provides the
 *	application programmer to provide "user friendly" names and
 *	easily determine the "/vol" name.
 *
 * arguments:
 *	start - a string describing a device.  This string can be:
 *		- a full path name to a device (insures it's a
 *		  character device by using getfullrawname()).
 *		- a full path name to a volume management media name
 *		  with partitions (will return the lowest numbered
 *		  raw partition.
 *		- the name of a piece of media (e.g. "fred").
 *		- a symbolic device name (e.g. floppy0, cdrom0, etc)
 *		- a name like "floppy" or "cdrom".  Will pick the lowest
 *		  numbered device with media in it.
 *
 * return value(s):
 *	A pointer to a string that contains the character device
 *	most appropriate to the "start" argument.
 *
 *	NULL indicates that we were unable to find media based on "start".
 *
 *	The string must be free(3)'d.
 *
 * preconditions:
 *	none.
 */
char *
media_findname(char *start)
{
	static char 	*media_findname_work(char *);
	char		*s = NULL;


	/*
	 * This is just a wrapper to implement the volmgt_check nastyness.
	 */
#ifdef	DEBUG
	denter("media_findname(%s): entering\n", start ? start : "<null ptr>");
#endif

	if (start == NULL) {
		errno = EFAULT;
		goto dun;
	}

	/*
	 * If we don't get positive results, we kick volume management
	 * to ask it to look in the floppy drive.
	 *
	 * XXX: maybe this should be configurable ???
	 */
	if ((s = media_findname_work(start)) == NULL) {
#ifdef	DEBUG
		dprintf("media_findname: calling volcheck and trying again\n");
#endif
		(void) volmgt_check(NULL);
		s = media_findname_work(start);
	}

dun:
#ifdef	DEBUG
	dexit("media_findname: returning \"%s\"\n", s ? s : "<null ptr>");
#endif
	return (s);
}
예제 #4
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);
}
예제 #5
0
/*
 * find a mnttab entry that has the same dev as the supplied dev,
 *  returning it and a non-zero value if found, else returning 0
 *
 * this is just like getmntany(), except that it scans based on st_rdev,
 * and it even finds different slices on the same device/unit (thanx to
 * code copied from format.c)
 */
static int
vol_getmntdev(FILE *fp, struct mnttab *mp, dev_t dev, struct dk_cinfo *ip)
{
	int		fd;		/* dev-in-question fd */
	struct stat64	sb;		/* dev-in-question stat struct */
	int		ret_val = 0;	/* default value: no match found */
	char		*cn;		/* char pathname */
	struct dk_cinfo	dkinfo;		/* for testing for slices */


#ifdef	DEBUG
	denter(
	    "vol_getmntdev: entering for %d.%d, ctype/cnum/unit = %d/%d/%d\n",
	    (int)major(dev), (int)minor(dev), ip->dki_ctype, ip->dki_cnum,
	    ip->dki_unit);
#endif

	/* reset the mnttab -- just in case */
	rewind(fp);

	/* scan each entry in mnttab */
	while (getmntent(fp, mp) == 0) {

		/* don't even try unless it's a local pathname */
		if (mp->mnt_special[0] != '/') {
			continue;
		}

		/* get char pathname */
		if ((cn = volmgt_getfullrawname(mp->mnt_special)) == NULL) {
			continue;
		}
		if (cn[0] == NULLC) {
			free(cn);
			continue;	/* couldn't get raw name */
		}

		/* open the device */
		if ((fd = open(cn, O_RDONLY|O_NDELAY)) < 0) {
			/* if we can't open it *assume* it's not a match */
			free(cn);
			continue;
		}

		/* stat the device */
		if (fstat64(fd, &sb) < 0) {
			free(cn);
			(void) close(fd);
			continue;	/* ain't there: can't be a match */
		}

		/* ensure we have a spcl device (a double check) */
		if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)) {
			free(cn);
			(void) close(fd);
			continue;
		}

		/* (almost) finally -- check the dev_t for equality */
		if (sb.st_rdev == dev) {
			ret_val = 1;		/* match found! */
			free(cn);
			(void) close(fd);
			break;
		}

		/*
		 * check that the major numbers match, since if they
		 * don't then there's no reason to use the DKIOCINFO
		 * ioctl to see if we have to major/minor pairs that
		 * really point to the same device
		 */
		if (major(sb.st_rdev) != major(dev)) {
			/* no use continuing, since major devs are different */
			free(cn);
			(void) close(fd);
			continue;
		}

		/* one last check -- for diff. slices of the same dev/unit */
		if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) {
			free(cn);
			(void) close(fd);
			continue;
		}

		free(cn);		/* all done with raw pathname */
		(void) close(fd);	/* all done with file descriptor */

		/* if ctrler type/number and unit match, it's a match */
		if ((ip->dki_ctype == dkinfo.dki_ctype) &&
		    (ip->dki_cnum == dkinfo.dki_cnum) &&
		    (ip->dki_unit == dkinfo.dki_unit)) {
			/*
			 * even though minor numbers differ we have a
			 * match
			 */
			ret_val = 1;
			break;
		}

		/* go around again */
	}

	return (ret_val);
}
예제 #6
0
/*
 * arc approved interface
 *	- can not be modified without approval from an arc
 *
 * committment level:
 *	uncommitted
 *
 * description:
 *	volmgt_acquire: try to acquire the volmgt advisory device reservation
 *	for a specific device.
 *
 * arguments:
 *	dev - a device name to attempt reserving.  This string can be:
 *		- a full path name to a device
 *		- a symbolic device name (e.g. floppy0)
 *
 *	id  - a reservation string that hopefully describes the application
 *		making this reservation.
 *
 *	pid - a pointer to a pid_t type.  If this argument is not NULL
 *		and the requested device is already reserved, the process
 *		id of the reservation owner will be returned in this
 *		location.
 *
 *	ovr - an override indicator.  If set to non-zero, the caller requests
 *		that this reservation be made unconditionally.
 *
 *	err - the address of a pointer to a string which is to receive the
 *		id argument used when the current device was reserved.  This
 *		is only used when the current reservation attempt fails due
 *		to an already existing reservation for this device.
 *
 * return value(s):
 *	A non-zero indicator if successful.
 *
 *	A zero indicator if unsuccessful.  If errno is EBUSY, then the err
 *	argument will be set to point to the string that the process currently
 *	holding the reservation supplied when reserving the device.  It is up
 *	to the caller to release the storage occupied by the string via
 *	free(3C) when no longer needed.
 *
 * preconditions:
 *	none
 */
int
volmgt_acquire(char *dev, char *id, int ovr, char **err, pid_t *pidp)
{
	char			*targ_name = NULL;
	struct stat		sb;
	dev_t			idev;
	vol_dbid_t		dbid = (vol_dbid_t)-1;
	vol_db_entry_t		dbe;
	vol_db_entry_t		*dbp;
	int			retval = 0;	/* default return => ERROR */
	int			reterr = 0;


#ifdef	DEBUG
	denter("volmgt_acquire(\"%s\", \"%s\", %s, %#p, %#p): entering\n",
	    dev ? dev : "<null ptr>", id ? id : "<null ptr>",
	    ovr ? "TRUE" : "FALSE", err, pidp);
#endif
	/*
	 * the supplied arguments must not be NULL
	 */
	if ((dev == NULL) || (id == NULL) || (err == NULL)) {
		errno = EINVAL;
		goto dun;
	}

	/*
	 * the id string must not be longer than the maximum allowable
	 * number of characters
	 */
	if (strlen(id) > VOL_RSV_MAXIDLEN) {
		errno = E2BIG;
		goto dun;
	}

	if ((targ_name = fsi_xlate_name(dev)) == NULL) {
		goto dun;
	}

	/*
	 * convert 'char *dev' to major/minor pair
	 */
	if (stat(targ_name, &sb) < 0) {
		goto dun;
	}
	idev = sb.st_rdev;

	/*
	 * open the database file
	 */
	if ((dbid = vol_db_open()) < 0) {
		goto dun;
	}

	if ((dbp = vol_db_find(dbid, idev)) == NULL) {
		/*
		 * the entry wasn't found, so reserve it
		 */
		dbe.dev_major = major(idev);
		dbe.dev_minor = minor(idev);
		dbe.pid = getpid();
		dbe.id_tag = id;
		if (vol_db_insert(dbid, &dbe) != 0) {
			retval = 1;		/* success! */
		}
	} else {
		if (ovr || (vol_db_proc_find(dbp->pid) == 0)) {
			/*
			 * the entry exists but either override was specified
			 * or the process holding the reservation is no longer
			 * active
			 *
			 * in either case we'll usurp the reservation
			 */
			if (vol_db_remove(dbid, idev) != 0) {
				/* reserve the device */
				dbe.dev_major = major(idev);
				dbe.dev_minor = minor(idev);
				dbe.pid = getpid();
				dbe.id_tag = id;
				if (vol_db_insert(dbid, &dbe) != 0) {
					retval = 1;
				}
			}

		} else {

			/*
			 * the entry exists and override was NOT specified
			 */

			/*
			 * optionally return the pid of the reservation
			 * owner
			 */
			if (pidp != NULL) {
				*pidp = dbp->pid;
			}

			*err = strdup(dbp->id_tag);
			reterr = EBUSY;
		}
		vol_db_free(dbp);	/* Release the entry */
	}


	/*
	 * if an error was encountered (currently only EBUSY supported)
	 * set errno to reflect it
	 */
	if (reterr != 0) {
		errno = reterr;
	}

dun:
	if ((int)dbid >= 0) {
		(void) vol_db_close(dbid);
	}
	if (targ_name != NULL) {
		free(targ_name);
	}
#ifdef	DEBUG
	dexit("volmgt_acquire: returning %s\n", retval ? "TRUE" : "FALSE");
#endif
	return (retval);
}
예제 #7
0
/*
 * arc approved interface
 *	- can not be modified without approval from an arc
 *
 * committment level:
 *	uncommitted
 *
 * description:
 *	volmgt_release: try to release the volmgt advisory device reservation
 *	for a specific device.
 *
 * arguments:
 *	dev - a device name to attempt reserving.  This string can be:
 *		- a full path name to a device
 *		- a symbolic device name (e.g. floppy0)
 *
 * return value(s):
 *	A non-zero indicator if successful
 *	A zero indicator if unsuccessful
 *
 * preconditions:
 *	none
 */
int
volmgt_release(char *dev)
{
	char			*targ_name = NULL;
	struct stat		sb;
	long			idev;
	vol_dbid_t		dbid;
	vol_db_entry_t		*dbp;
	int			retval = 0;	/* default return => FAILURE */
	int			reterr = 0;


#ifdef	DEBUG
	denter("volmgt_release(\"%s\"): entering\n", dev ? dev : "<null ptr>");
#endif
	/*
	 * first let's do some minimal validation of the supplied arguments
	 */

	/*
	 * the supplied argument must not be NULL
	 */
	if (dev == NULL) {
		errno = EINVAL;
		goto dun;
	}

	if ((targ_name = fsi_xlate_name(dev)) == NULL) {
		goto dun;
	}

	/*
	 * convert 'char *dev' to major/minor pair
	 */
	if (stat(targ_name, &sb) < 0) {
		goto dun;
	}
	idev = sb.st_rdev;

	/*
	 * open the database file
	 */
	if ((dbid = vol_db_open()) < 0) {
		goto dun;
	}

	if ((dbp = vol_db_find(dbid, idev)) == NULL) {
		/* the entry wasn't found so I can't clear reservation */
		errno = ENOENT;
		goto dun;
	}

	/* the entry was found so make sure I can clear it */
	if (dbp->pid == getpid()) {
		/*
		 * the reservation was made by me, clear it
		 */
		if (vol_db_remove(dbid, idev) != 0) {
			retval = 1;
		}
	} else {
		/*
		 * the entry wasn't made by me
		 */
		reterr = EBUSY;
	}
	vol_db_free(dbp);

	/*
	 * if an error was encountered (currently only EBUSY supported)
	 * set errno to reflect it
	 */
	if (reterr != 0) {
		errno = reterr;
	}
dun:
	if ((int)dbid >= 0) {
		(void) vol_db_close(dbid);
	}
	if (targ_name != NULL) {
		free(targ_name);
	}
#ifdef	DEBUG
	dexit("volmgt_release: returning %s\n", retval ? "TRUE" : "FALSE");
#endif
	return (retval);
}
예제 #8
0
파일: volname.c 프로젝트: andreiw/polaris
/*
 * This is an ON Consolidation Private interface.
 */
char *
_media_oldaliases(char *start)
{
	struct alias	*s, *ns;
	char		*p;
	char		*res;



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

	for (s = device_aliases; *s->alias != NULLC; s++) {
		if (strcmp(start, s->alias) == 0) {
			break;
		}
	}

	/* we don't recognize that alias at all */
	if (*s->alias == NULLC) {
#ifdef	DEBUG
		dprintf("_media_oldaliases: failed\n");
#endif
		res = NULL;
		goto dun;
	}

	/* if volume management isn't running at all, give him back the name */
	if (!volmgt_running()) {
#ifdef	DEBUG
		dprintf("_media_oldaliases: no vold!\n");
#endif
		res = strdup(s->name);
		goto dun;
	}
	/*
	 * If volume management is managing that device, look up the
	 * volume management name.
	 */
	if (volmgt_inuse(s->name)) {
		for (s = volmgt_aliases; *s->alias != NULLC; s++) {
			if (strcmp(start, s->alias) == 0) {
				res = strdup(s->name);
				goto dun;
			}
		}
#ifdef	DEBUG
		dprintf("_media_oldaliases: failed\n");
#endif
		res = NULL;
		goto dun;
	}

	/*
	 * If volume management isn't managing the device, it's possible
	 * that he's given us an alias that we should recognize, but the
	 * default name is wrong.  For example a user might have his
	 * cdrom on controller 1, being managed by volume management,
	 * but we would think it isn't because volmgt_inuse just told
	 * us that c0t6d0s2 isn't being managed.  So, before we return
	 * the /dev name, we'll test the alias out using media_findname.
	 * If media_findname can't make sense out of the alias, it probably
	 * means that we really, really aren't managing the device and
	 * should just return the /dev name.  Whew.  Isn't this grody?
	 */

	for (ns = volmgt_aliases; *ns->alias != NULLC; ns++) {
		if (strcmp(start, ns->alias) == 0) {
			if ((p = media_findname_work(ns->name))) {
				res = p;
				goto dun;
			} else {
				break;
			}
		}
	}

	res = strdup(s->name);
dun:
#ifdef	DEBUG
	dexit("_media_oldaliases: returning %s\n", res ? res : "<null ptr>");
#endif
	return (res);
}
예제 #9
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);
}