4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
35 #include <sys/fstyp.h>
37 #include <sys/vfstab.h>
39 #include <sys/types.h>
42 #define FULLPATH_MAX 64
44 #define VFS_PATH "/usr/lib/fs"
46 extern char *default_fstype();
48 char *special
= NULL
; /* device special name */
49 char *fstype
= NULL
; /* fstype name is filled in here */
50 char *cbasename
; /* name of command */
51 char *newargv
[ARGV_MAX
]; /* args for the fstype specific command */
52 char vfstab
[] = VFSTAB
;
53 char full_path
[FULLPATH_MAX
];
54 char *vfs_path
= VFS_PATH
;
62 "ff", "F:o:p:a:m:c:n:i:?IlsuV",
63 "[-F FSType] [-V] [current_options] [-o specific_options] special ...",
64 "ncheck", "F:o:?i:asV",
65 "[-F FSType] [-V] [current_options] [-o specific_options] [special ...]",
67 "[-F FSType] [-V] [current_options] [-o specific_options] special ..."
69 struct commands
*c_ptr
;
71 static void usage(char *cmd
, char *usg
);
72 static void exec_specific(void);
73 static void lookup(void);
76 main(int argc
, char *argv
[])
82 int verbose
= 0; /* set if -V is specified */
86 int arg
; /* argument from getopt() */
87 extern char *optarg
; /* getopt specific */
92 cbasename
= ptr
= argv
[0];
98 * If there are no arguments and command is ncheck then the generic
99 * reads the VFSTAB and executes the specific module of
100 * each entry which has a numeric fsckpass field.
103 if (argc
== 1) { /* no arguments or options */
104 if (strcmp(cbasename
, "ncheck") == 0) {
106 if ((fp
= fopen(VFSTAB
, "r")) == NULL
) {
107 fprintf(stderr
, "%s: cannot open vfstab\n",
111 while ((i
= getvfsent(fp
, &vfsbuf
)) == 0) {
112 if (numbers(vfsbuf
.vfs_fsckpass
)) {
113 fstype
= vfsbuf
.vfs_fstype
;
114 newargv
[newargc
] = vfsbuf
.vfs_special
;
120 fprintf(stderr
, "Usage:\n");
122 "%s [-F FSType] [-V] [current_options] [-o specific_options] special ...\n",
127 for (c_ptr
= cmd_data
; ((c_ptr
->c_basename
!= NULL
) &&
128 (strcmp(c_ptr
->c_basename
, cbasename
) != 0)); c_ptr
++)
130 while ((arg
= getopt(argc
, argv
, c_ptr
->c_optstr
)) != -1) {
132 case 'V': /* echo complete command line */
135 case 'F': /* FSType specified */
139 case 'o': /* FSType specific arguments */
140 newargv
[newargc
++] = "-o";
141 newargv
[newargc
++] = optarg
;
143 case '?': /* print usage message */
144 newargv
[newargc
++] = "-?";
148 newargv
[newargc
] = (char *)malloc(3);
149 sprintf(newargv
[newargc
++], "-%c", arg
);
151 newargv
[newargc
++] = optarg
;
157 fprintf(stderr
, "%s: more than one FSType specified\n",
159 usage(cbasename
, c_ptr
->c_usgstr
);
161 if (F_flg
&& (strlen(fstype
) > (size_t)FSTYPE_MAX
)) {
162 fprintf(stderr
, "%s: FSType %s exceeds %d characters\n",
163 cbasename
, fstype
, FSTYPE_MAX
);
166 if (optind
== argc
) {
167 /* all commands except ncheck must exit now */
168 if (strcmp(cbasename
, "ncheck") != 0) {
169 if ((F_flg
) && (usgflag
)) {
173 usage(cbasename
, c_ptr
->c_usgstr
);
175 if ((F_flg
) && (usgflag
)) {
180 usage(cbasename
, c_ptr
->c_usgstr
);
183 if ((fp
= fopen(VFSTAB
, "r")) == NULL
) {
184 fprintf(stderr
, "%s: cannot open vfstab\n", cbasename
);
187 while ((i
= getvfsent(fp
, &vfsbuf
)) == 0) {
188 if (!numbers(vfsbuf
.vfs_fsckpass
))
190 if ((F_flg
) && (strcmp(fstype
, vfsbuf
.vfs_fstype
) != 0))
193 fstype
= vfsbuf
.vfs_fstype
;
194 newargv
[newargc
] = vfsbuf
.vfs_special
;
196 printf("%s -F %s ", cbasename
,
198 for (i
= 2; newargv
[i
]; i
++)
199 printf("%s\n", newargv
[i
]);
206 * if (sysfs(GETFSIND, fstype) == (-1)) {
208 * "%s: FSType %s not installed in the kernel\n",
209 * cbasename, fstype);
218 /* All other arguments must be specials */
219 /* perform a lookup if fstype is not specified */
221 for (; optind
< argc
; optind
++) {
222 newargv
[newargc
] = argv
[optind
];
223 special
= newargv
[newargc
];
224 if ((F_flg
) && (usgflag
)) {
229 usage(cbasename
, c_ptr
->c_usgstr
);
233 printf("%s -F %s ", cbasename
, fstype
);
234 for (i
= 2; newargv
[i
]; i
++)
235 printf("%s ", newargv
[i
]);
246 /* see if all numbers */
252 while ('0' <= *yp
&& *yp
<= '9')
260 usage(char *cmd
, char *usg
)
262 fprintf(stderr
, "Usage:\n");
263 fprintf(stderr
, "%s %s\n", cmd
, usg
);
269 * This looks up the /etc/vfstab entry given the device 'special'.
270 * It is called when the fstype is not specified on the command line.
272 * The following global variables are used:
281 struct vfstab vget
, vref
;
283 if ((fd
= fopen(vfstab
, "r")) == NULL
) {
284 fprintf(stderr
, "%s: cannot open vfstab\n", cbasename
);
288 vref
.vfs_special
= special
;
289 ret
= getvfsany(fd
, &vget
, &vref
);
293 vref
.vfs_fsckdev
= special
;
294 ret
= getvfsany(fd
, &vget
, &vref
);
300 fstype
= default_fstype(special
);
303 fstype
= vget
.vfs_fstype
;
306 fprintf(stderr
, "%s: line in vfstab exceeds %d characters\n",
307 cbasename
, VFS_LINE_MAX
-2);
311 fprintf(stderr
, "%s: line in vfstab has too few entries\n",
316 fprintf(stderr
, "%s: line in vfstab has too many entries\n",
326 int status
, pid
, ret
;
328 sprintf(full_path
, "%s/%s/%s", vfs_path
, fstype
, cbasename
);
329 newargv
[1] = &full_path
[FULLPATH_MAX
];
330 while (*newargv
[1]-- != '/');
332 switch (pid
= fork()) {
334 execv(full_path
, &newargv
[1]);
335 if (errno
== ENOEXEC
) {
337 newargv
[1] = full_path
;
338 execv("/sbin/sh", &newargv
[0]);
340 if (errno
!= ENOENT
) {
342 fprintf(stderr
, "%s: cannot execute %s\n", cbasename
,
346 if (sysfs(GETFSIND
, fstype
) == (-1)) {
348 "%s: FSType %s not installed in the kernel\n",
352 fprintf(stderr
, "%s: operation not applicable for FSType %s\n",
356 fprintf(stderr
, "%s: cannot fork process\n", cbasename
);
360 * if cannot exec specific, or fstype is not installed, exit
361 * after first 'exec_specific' to avoid printing duplicate
365 if (wait(&status
) == pid
) {
366 ret
= WHIBYTE(status
);