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.
31 #pragma ident "%Z%%M% %I% %E% SMI"
36 #include <sys/fstyp.h>
38 #include <sys/vfstab.h>
40 #include <sys/types.h>
43 #define FULLPATH_MAX 64
45 #define VFS_PATH "/usr/lib/fs"
47 extern char *default_fstype();
49 char *special
= NULL
; /* device special name */
50 char *fstype
= NULL
; /* fstype name is filled in here */
51 char *cbasename
; /* name of command */
52 char *newargv
[ARGV_MAX
]; /* args for the fstype specific command */
53 char vfstab
[] = VFSTAB
;
54 char full_path
[FULLPATH_MAX
];
55 char *vfs_path
= VFS_PATH
;
63 "ff", "F:o:p:a:m:c:n:i:?IlsuV",
64 "[-F FSType] [-V] [current_options] [-o specific_options] special ...",
65 "ncheck", "F:o:?i:asV",
66 "[-F FSType] [-V] [current_options] [-o specific_options] [special ...]",
68 "[-F FSType] [-V] [current_options] [-o specific_options] special ..."
70 struct commands
*c_ptr
;
72 static void usage(char *cmd
, char *usg
);
73 static void exec_specific(void);
74 static void lookup(void);
77 main(int argc
, char *argv
[])
83 int verbose
= 0; /* set if -V is specified */
87 int arg
; /* argument from getopt() */
88 extern char *optarg
; /* getopt specific */
93 cbasename
= ptr
= argv
[0];
99 * If there are no arguments and command is ncheck then the generic
100 * reads the VFSTAB and executes the specific module of
101 * each entry which has a numeric fsckpass field.
104 if (argc
== 1) { /* no arguments or options */
105 if (strcmp(cbasename
, "ncheck") == 0) {
107 if ((fp
= fopen(VFSTAB
, "r")) == NULL
) {
108 fprintf(stderr
, "%s: cannot open vfstab\n",
112 while ((i
= getvfsent(fp
, &vfsbuf
)) == 0) {
113 if (numbers(vfsbuf
.vfs_fsckpass
)) {
114 fstype
= vfsbuf
.vfs_fstype
;
115 newargv
[newargc
] = vfsbuf
.vfs_special
;
121 fprintf(stderr
, "Usage:\n");
123 "%s [-F FSType] [-V] [current_options] [-o specific_options] special ...\n",
128 for (c_ptr
= cmd_data
; ((c_ptr
->c_basename
!= NULL
) &&
129 (strcmp(c_ptr
->c_basename
, cbasename
) != 0)); c_ptr
++)
131 while ((arg
= getopt(argc
, argv
, c_ptr
->c_optstr
)) != -1) {
133 case 'V': /* echo complete command line */
136 case 'F': /* FSType specified */
140 case 'o': /* FSType specific arguments */
141 newargv
[newargc
++] = "-o";
142 newargv
[newargc
++] = optarg
;
144 case '?': /* print usage message */
145 newargv
[newargc
++] = "-?";
149 newargv
[newargc
] = (char *)malloc(3);
150 sprintf(newargv
[newargc
++], "-%c", arg
);
152 newargv
[newargc
++] = optarg
;
158 fprintf(stderr
, "%s: more than one FSType specified\n",
160 usage(cbasename
, c_ptr
->c_usgstr
);
162 if (F_flg
&& (strlen(fstype
) > (size_t)FSTYPE_MAX
)) {
163 fprintf(stderr
, "%s: FSType %s exceeds %d characters\n",
164 cbasename
, fstype
, FSTYPE_MAX
);
167 if (optind
== argc
) {
168 /* all commands except ncheck must exit now */
169 if (strcmp(cbasename
, "ncheck") != 0) {
170 if ((F_flg
) && (usgflag
)) {
174 usage(cbasename
, c_ptr
->c_usgstr
);
176 if ((F_flg
) && (usgflag
)) {
181 usage(cbasename
, c_ptr
->c_usgstr
);
184 if ((fp
= fopen(VFSTAB
, "r")) == NULL
) {
185 fprintf(stderr
, "%s: cannot open vfstab\n", cbasename
);
188 while ((i
= getvfsent(fp
, &vfsbuf
)) == 0) {
189 if (!numbers(vfsbuf
.vfs_fsckpass
))
191 if ((F_flg
) && (strcmp(fstype
, vfsbuf
.vfs_fstype
) != 0))
194 fstype
= vfsbuf
.vfs_fstype
;
195 newargv
[newargc
] = vfsbuf
.vfs_special
;
197 printf("%s -F %s ", cbasename
,
199 for (i
= 2; newargv
[i
]; i
++)
200 printf("%s\n", newargv
[i
]);
207 * if (sysfs(GETFSIND, fstype) == (-1)) {
209 * "%s: FSType %s not installed in the kernel\n",
210 * cbasename, fstype);
219 /* All other arguments must be specials */
220 /* perform a lookup if fstype is not specified */
222 for (; optind
< argc
; optind
++) {
223 newargv
[newargc
] = argv
[optind
];
224 special
= newargv
[newargc
];
225 if ((F_flg
) && (usgflag
)) {
230 usage(cbasename
, c_ptr
->c_usgstr
);
234 printf("%s -F %s ", cbasename
, fstype
);
235 for (i
= 2; newargv
[i
]; i
++)
236 printf("%s ", newargv
[i
]);
247 /* see if all numbers */
253 while ('0' <= *yp
&& *yp
<= '9')
261 usage(char *cmd
, char *usg
)
263 fprintf(stderr
, "Usage:\n");
264 fprintf(stderr
, "%s %s\n", cmd
, usg
);
270 * This looks up the /etc/vfstab entry given the device 'special'.
271 * It is called when the fstype is not specified on the command line.
273 * The following global variables are used:
282 struct vfstab vget
, vref
;
284 if ((fd
= fopen(vfstab
, "r")) == NULL
) {
285 fprintf(stderr
, "%s: cannot open vfstab\n", cbasename
);
289 vref
.vfs_special
= special
;
290 ret
= getvfsany(fd
, &vget
, &vref
);
294 vref
.vfs_fsckdev
= special
;
295 ret
= getvfsany(fd
, &vget
, &vref
);
301 fstype
= default_fstype(special
);
304 fstype
= vget
.vfs_fstype
;
307 fprintf(stderr
, "%s: line in vfstab exceeds %d characters\n",
308 cbasename
, VFS_LINE_MAX
-2);
312 fprintf(stderr
, "%s: line in vfstab has too few entries\n",
317 fprintf(stderr
, "%s: line in vfstab has too many entries\n",
327 int status
, pid
, ret
;
329 sprintf(full_path
, "%s/%s/%s", vfs_path
, fstype
, cbasename
);
330 newargv
[1] = &full_path
[FULLPATH_MAX
];
331 while (*newargv
[1]-- != '/');
333 switch (pid
= fork()) {
335 execv(full_path
, &newargv
[1]);
336 if (errno
== ENOEXEC
) {
338 newargv
[1] = full_path
;
339 execv("/sbin/sh", &newargv
[0]);
341 if (errno
!= ENOENT
) {
343 fprintf(stderr
, "%s: cannot execute %s\n", cbasename
,
347 if (sysfs(GETFSIND
, fstype
) == (-1)) {
349 "%s: FSType %s not installed in the kernel\n",
353 fprintf(stderr
, "%s: operation not applicable for FSType %s\n",
357 fprintf(stderr
, "%s: cannot fork process\n", cbasename
);
361 * if cannot exec specific, or fstype is not installed, exit
362 * after first 'exec_specific' to avoid printing duplicate
366 if (wait(&status
) == pid
) {
367 ret
= WHIBYTE(status
);