summaryrefslogtreecommitdiff
path: root/usr/src/lib/libvolmgt/common/volname.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libvolmgt/common/volname.c')
-rw-r--r--usr/src/lib/libvolmgt/common/volname.c778
1 files changed, 0 insertions, 778 deletions
diff --git a/usr/src/lib/libvolmgt/common/volname.c b/usr/src/lib/libvolmgt/common/volname.c
deleted file mode 100644
index d04ffa22cf..0000000000
--- a/usr/src/lib/libvolmgt/common/volname.c
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (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 (c) 1996 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-/*LINTLIBRARY*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <unistd.h>
-#include <volmgt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <sys/vol.h>
-
-#include "volmgt_private.h"
-
-
-
-#define ALIAS_DIR "dev/aliases"
-#define HACKNAME_MAX 5 /* max aliases to try */
-#define NUMBUF_SZ 10 /* big enough for HACKNAME */
-
-
-/* a shortcut for checkinf for absolute pathnames */
-#define IS_ABS_PATH(p) (*(p) == '/')
-
-
-/*
- * 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);
-}
-
-
-/*
- * 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);
-}
-
-
-/*
- * deref the link (in link_buf) read from path_buf into res_buf
- *
- * if there's any problem then just return the contents of the link buffer
- */
-static void
-volmgt_deref_link(char *res_buf, char *path_buf, char *link_buf)
-{
- static char *vol_dirname(char *);
- char buf[MAXPATHLEN+1];
- char *path_dirname;
-
-
- if (IS_ABS_PATH(link_buf)) {
-
- /* degenerate case -- link is okay the way it is */
- (void) strncpy(res_buf, link_buf, MAXPATHLEN);
-
- } else {
-
- /* link pathname is relative */
-
- /* get a writable copy of the orig path */
- (void) strncpy(buf, path_buf, MAXPATHLEN);
-
- /* get the dir from the orig path */
- if ((path_dirname = vol_dirname(buf)) == NULL) {
-
- /* oh oh -- just use the link contents */
- (void) strncpy(res_buf, link_buf, MAXPATHLEN);
-
- } else {
-
- /* concat the orig dir with the link path (if room) */
- (void) concat_paths(res_buf, path_dirname, link_buf,
- NULL);
- }
- }
-}
-
-
-/*
- * return the dirname part of a path (i.e. all but last component)
- *
- * NOTE: may destuctively change "path" (i.e. it may write a null over
- * the last slash in the path to convert it into a dirname)
- */
-static char *
-vol_dirname(char *path)
-{
- char *cp;
-
-
- /* find the last seperator in the path */
- if ((cp = strrchr(path, '/')) == NULL) {
- /* must be just a local name -- use the local dir */
- return (".");
- }
-
- /* replace the last slash with a null */
- *cp = NULLC;
-
- /* return all but the last component */
- return (path);
-}
-
-
-/*
- * This function runs through the list of "old" aliases to
- * see if someone is calling a device by an old name before
- * the glory of volume management.
- */
-
-struct alias {
- char *alias;
- char *name;
-};
-
-static struct alias volmgt_aliases[] = {
- { "fd", "floppy0" },
- { "fd0", "floppy0" },
- { "fd1", "floppy1" },
- { "diskette", "floppy0" },
- { "diskette0", "floppy0" },
- { "diskette1", "floppy1" },
- { "rdiskette", "floppy0" },
- { "rdiskette0", "floppy0" },
- { "rdiskette1", "floppy1" },
- { "cd", "cdrom0" },
- { "cd0", "cdrom0" },
- { "cd1", "cdrom1" },
- { "sr", "cdrom0" },
- { "sr0", "cdrom0" },
- { "/dev/sr0", "cdrom0" },
- { "/dev/rsr0", "cdrom0" },
- { "", ""}
-};
-
-
-/*
- * "old" aliases -- XXX: only make sense if vold not running?
- */
-static struct alias device_aliases[] = {
- { "fd", "/dev/rdiskette" },
- { "fd0", "/dev/rdiskette" },
- { "fd1", "/dev/rdiskette1" },
- { "diskette", "/dev/rdiskette" },
- { "diskette0", "/dev/rdiskette0" },
- { "diskette1", "/dev/rdiskette1" },
- { "rdiskette", "/dev/rdiskette" },
- { "rdiskette0", "/dev/rdiskette0" },
- { "rdiskette1", "/dev/rdiskette1" },
- { "floppy", "/dev/rdiskette" },
- { "floppy0", "/dev/rdiskette0" },
- { "floppy1", "/dev/rdiskette1" },
- { "cd", "cdrom0" },
- { "cd0", "cdrom0" },
- { "cd1", "cdrom1" },
- { "", ""}
-};
-
-
-/*
- * 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);
-}
-
-
-/*
- * This is an ON Consolidation Private interface.
- *
- * Print out the aliases available to the program user. Changes
- * depending in whether volume management is running.
- */
-void
-_media_printaliases(void)
-{
- struct alias *s;
- DIR *dirp;
- struct dirent64 *dp;
- char pathbuf[MAXPATHLEN+1];
- char *p;
- static const char *vold_root = NULL;
-
-
-
- if (vold_root == NULL) {
- vold_root = volmgt_root();
- }
-
- if (!volmgt_running()) {
- /* no volume management */
- for (s = device_aliases; *s->alias != NULLC; s++) {
- (void) printf("\t%s -> %s\n", s->alias, s->name);
- }
- return;
- }
-
- for (s = volmgt_aliases; *s->alias != NULLC; s++) {
- (void) printf("\t%s -> %s\n", s->alias, s->name);
- }
-
- (void) concat_paths(pathbuf, (char *)vold_root, ALIAS_DIR, NULL);
-
- if ((dirp = opendir(pathbuf)) == NULL) {
- return;
- }
- while (dp = readdir64(dirp)) {
- if (strcmp(dp->d_name, ".") == 0) {
- continue;
- }
- if (strcmp(dp->d_name, "..") == 0) {
- continue;
- }
- if ((p = media_findname(dp->d_name)) != NULL) {
- (void) printf("\t%s -> %s\n", dp->d_name, p);
- }
- }
- (void) closedir(dirp);
-}