1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 22 /* All Rights Reserved */ 23 24 25 /* 26 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 /* 31 * generic interface to dfs commands. 32 * 33 * usage: cmd [-F fstype] [-o fs_options] [ args ] 34 * 35 * exec's /usr/lib/fs/<fstype>/<cmd> 36 * <cmd> is the basename of the command. 37 * 38 * if -F is missing, fstype is the first entry in /etc/dfs/fstypes 39 */ 40 41 #include <sys/types.h> 42 #include <sys/stat.h> 43 #include <ctype.h> 44 #include <stdio.h> 45 #include <stdlib.h> 46 #include <unistd.h> 47 #include <dirent.h> 48 #include <string.h> 49 50 #define DFSTYPES "/etc/dfs/fstypes" /* dfs list */ 51 #define FSCMD "/usr/lib/fs/%s/%s" 52 53 #define ARGVPAD 4 /* non-[arg...] elements in new argv list: */ 54 /* cmd name, -o, opts, (char *)0 terminator */ 55 56 static char *getfs(); 57 static int invalid(); 58 void perror(); 59 60 int 61 main(argc, argv) 62 int argc; 63 char **argv; 64 { 65 extern char *optarg; 66 extern int optind; 67 FILE *dfp; /* fp for dfs list */ 68 int c, err = 0; 69 char subcmd[BUFSIZ]; /* fs specific command */ 70 char *cmd; /* basename of this command */ 71 char *fsname = NULL; /* file system name */ 72 char *opts = NULL; /* -o options */ 73 char **nargv; /* new argv list */ 74 int nargc = 0; /* new argc */ 75 static char usage[] = 76 "usage: %s [-F fstype] [-o fs_options ] [arg ...]\n"; 77 78 cmd = strrchr(argv[0], '/'); /* find the basename */ 79 if (cmd) 80 ++cmd; 81 else 82 cmd = argv[0]; 83 84 while ((c = getopt(argc, argv, "F:o:")) != -1) 85 switch (c) { 86 case 'F': 87 err |= (fsname != NULL); /* at most one -F */ 88 fsname = optarg; 89 break; 90 case 'o': /* fs specific options */ 91 err |= (opts != NULL); /* at most one -o */ 92 opts = optarg; 93 break; 94 case '?': 95 err = 1; 96 break; 97 } 98 if (err) { 99 (void) fprintf(stderr, usage, cmd); 100 exit(1); 101 } 102 103 if ((dfp = fopen(DFSTYPES, "r")) == NULL) { 104 (void) fprintf(stderr, "%s: cannot open %s\n", 105 cmd, DFSTYPES); 106 exit(1); 107 } 108 109 if (fsname) { /* generate fs specific command name */ 110 if (invalid(fsname, dfp)) { /* valid ? */ 111 (void) fprintf(stderr, 112 "%s: invalid file system name\n", cmd); 113 (void) fprintf(stderr, usage, cmd); 114 exit(1); 115 } else { 116 (void) snprintf(subcmd, sizeof (subcmd), 117 FSCMD, fsname, cmd); 118 } 119 } else if (fsname = getfs(dfp)) { /* use 1st line in dfstypes */ 120 (void) snprintf(subcmd, sizeof (subcmd), FSCMD, fsname, cmd); 121 } else { 122 (void) fprintf(stderr, 123 "%s: no file systems in %s\n", cmd, DFSTYPES); 124 (void) fprintf(stderr, usage, cmd); 125 exit(1); 126 } 127 128 /* allocate a block for the new argv list */ 129 if (!(nargv = (char **)malloc(sizeof (char *)*(argc-optind+ARGVPAD)))) { 130 (void) fprintf(stderr, "%s: malloc failed.\n", cmd); 131 exit(1); 132 /*NOTREACHED*/ 133 } 134 nargv[nargc++] = cmd; 135 if (opts) { 136 nargv[nargc++] = "-o"; 137 nargv[nargc++] = opts; 138 } 139 for (; optind <= argc; ++optind) /* this copies the last NULL */ 140 nargv[nargc++] = argv[optind]; 141 142 (void) execvp(subcmd, nargv); 143 perror(subcmd); 144 return (1); 145 } 146 147 148 /* 149 * invalid(name, f) - return non-zero if name is not in 150 * the list of fs names in file f 151 */ 152 153 static int 154 invalid(name, f) 155 char *name; /* file system name */ 156 FILE *f; /* file of list of systems */ 157 { 158 char *s; 159 160 while (s = getfs(f)) /* while there's still hope ... */ 161 if (strcmp(s, name) == 0) 162 return (0); /* we got it! */ 163 return (1); 164 } 165 166 167 /* 168 * getfs(fp) - get the next file system name from fp 169 * ignoring lines starting with a #. 170 * All leading whitespace is discarded. 171 */ 172 173 static char buf[BUFSIZ]; 174 175 static char * 176 getfs(fp) 177 FILE *fp; 178 { 179 char *s; 180 181 while (s = fgets(buf, BUFSIZ, fp)) { 182 while (isspace(*s)) /* leading whitespace doesn't count */ 183 ++s; 184 if (*s != '#') { /* not a comment */ 185 char *t = s; 186 187 while (!isspace(*t)) /* get the token */ 188 ++t; 189 *t = '\0'; /* ignore rest of line */ 190 return (s); 191 } 192 } 193 return (NULL); /* that's all, folks! */ 194 } 195