17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 237c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 27*3e1bd7a2Ssjelinek * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 287c478bd9Sstevel@tonic-gate * Use is subject to license terms. 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include <stdio.h> 347c478bd9Sstevel@tonic-gate #include <limits.h> 357c478bd9Sstevel@tonic-gate #include <locale.h> 367c478bd9Sstevel@tonic-gate #include <libintl.h> 377c478bd9Sstevel@tonic-gate #include <sys/fstyp.h> 387c478bd9Sstevel@tonic-gate #include <errno.h> 397c478bd9Sstevel@tonic-gate #include <sys/vfstab.h> 407c478bd9Sstevel@tonic-gate #include <sys/types.h> 417c478bd9Sstevel@tonic-gate #include <sys/stat.h> 427c478bd9Sstevel@tonic-gate #include <fcntl.h> 437c478bd9Sstevel@tonic-gate #include <string.h> 44*3e1bd7a2Ssjelinek #include <libdiskmgt.h> 45*3e1bd7a2Ssjelinek #include "fslib.h" 46*3e1bd7a2Ssjelinek 47*3e1bd7a2Ssjelinek 48*3e1bd7a2Ssjelinek static int match(char **opts, char *s); 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #define FSTYPE_MAX 8 517c478bd9Sstevel@tonic-gate #define ARGV_MAX 1024 527c478bd9Sstevel@tonic-gate #define VFS_PATH "/usr/lib/fs" 537c478bd9Sstevel@tonic-gate #define ALT_PATH "/etc/fs" 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate extern char *default_fstype(); 567c478bd9Sstevel@tonic-gate void stat_snap(char *, char *, char *); 577c478bd9Sstevel@tonic-gate char *special = NULL; /* device special name */ 587c478bd9Sstevel@tonic-gate char *fstype = NULL; /* fstype name is filled in here */ 597c478bd9Sstevel@tonic-gate char *cbasename; /* name of command */ 607c478bd9Sstevel@tonic-gate char *newargv[ARGV_MAX]; /* args for the fstype specific command */ 617c478bd9Sstevel@tonic-gate char vfstab[] = VFSTAB; 627c478bd9Sstevel@tonic-gate int newargc = 2; 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate /* 657c478bd9Sstevel@tonic-gate * TRANSLATION_NOTE - the usage strings in the c_usgstr[] of the 667c478bd9Sstevel@tonic-gate * following structures should be given a translation; the call to gettext 677c478bd9Sstevel@tonic-gate * is in the usage() function. The strings are the ones containing 687c478bd9Sstevel@tonic-gate * "[-F FSType]". 697c478bd9Sstevel@tonic-gate */ 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate struct commands { 727c478bd9Sstevel@tonic-gate char *c_basename; 737c478bd9Sstevel@tonic-gate char *c_optstr; 747c478bd9Sstevel@tonic-gate char *c_usgstr[4]; /* make sure as large as largest array size */ 757c478bd9Sstevel@tonic-gate } cmd_data[] = { 767c478bd9Sstevel@tonic-gate "clri", "F:o:?V", 777c478bd9Sstevel@tonic-gate { 787c478bd9Sstevel@tonic-gate "[-F FSType] [-V] special inumber ...", 797c478bd9Sstevel@tonic-gate NULL 807c478bd9Sstevel@tonic-gate }, 817c478bd9Sstevel@tonic-gate "mkfs", "F:o:mb:?V", 827c478bd9Sstevel@tonic-gate { 837c478bd9Sstevel@tonic-gate "[-F FSType] [-V] [-m] [-o specific_options] special ", 847c478bd9Sstevel@tonic-gate "[operands]", NULL 857c478bd9Sstevel@tonic-gate }, 867c478bd9Sstevel@tonic-gate "dcopy", "F:o:?V", 877c478bd9Sstevel@tonic-gate { 887c478bd9Sstevel@tonic-gate "[-F FSType] [-V] special inumber ...", 897c478bd9Sstevel@tonic-gate NULL 907c478bd9Sstevel@tonic-gate }, 917c478bd9Sstevel@tonic-gate "fsdb", "F:o:z:?V", 927c478bd9Sstevel@tonic-gate { 937c478bd9Sstevel@tonic-gate "[-F FSType] [-V] [-o specific_options] special", 947c478bd9Sstevel@tonic-gate NULL 957c478bd9Sstevel@tonic-gate }, 967c478bd9Sstevel@tonic-gate "fssnap", "F:dio:?V", 977c478bd9Sstevel@tonic-gate { 987c478bd9Sstevel@tonic-gate "[-F FSType] [-V] -o special_options /mount/point", 997c478bd9Sstevel@tonic-gate "-d [-F FSType] [-V] /mount/point | dev", 1007c478bd9Sstevel@tonic-gate "-i [-F FSType] [-V] [-o special-options] [/mount/point | dev]", 1017c478bd9Sstevel@tonic-gate NULL 1027c478bd9Sstevel@tonic-gate }, 1037c478bd9Sstevel@tonic-gate "labelit", "F:o:?nV", 1047c478bd9Sstevel@tonic-gate { 1057c478bd9Sstevel@tonic-gate "[-F FSType] [-V] [-o specific_options] special [operands]", 1067c478bd9Sstevel@tonic-gate NULL 1077c478bd9Sstevel@tonic-gate }, 1087c478bd9Sstevel@tonic-gate NULL, "F:o:?V", 1097c478bd9Sstevel@tonic-gate { 1107c478bd9Sstevel@tonic-gate "[-F FSType] [-V] [-o specific_options] special [operands]", 1117c478bd9Sstevel@tonic-gate NULL 1127c478bd9Sstevel@tonic-gate } 1137c478bd9Sstevel@tonic-gate }; 1147c478bd9Sstevel@tonic-gate struct commands *c_ptr; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate main(argc, argv) 1177c478bd9Sstevel@tonic-gate int argc; 1187c478bd9Sstevel@tonic-gate char *argv[]; 1197c478bd9Sstevel@tonic-gate { 1207c478bd9Sstevel@tonic-gate register char *ptr; 1217c478bd9Sstevel@tonic-gate char full_path[PATH_MAX]; 1227c478bd9Sstevel@tonic-gate char *vfs_path = VFS_PATH; 1237c478bd9Sstevel@tonic-gate char *alt_path = ALT_PATH; 1247c478bd9Sstevel@tonic-gate int i; 125*3e1bd7a2Ssjelinek int j; 1267c478bd9Sstevel@tonic-gate int verbose = 0; /* set if -V is specified */ 1277c478bd9Sstevel@tonic-gate int F_flg = 0; 1287c478bd9Sstevel@tonic-gate int mflag = 0; 129*3e1bd7a2Ssjelinek int Nflag = 0; 1307c478bd9Sstevel@tonic-gate char *oopts = NULL; 131*3e1bd7a2Ssjelinek char *tmpopts = NULL; /* used for in use checking */ 1327c478bd9Sstevel@tonic-gate int iflag = 0; 1337c478bd9Sstevel@tonic-gate int usgflag = 0; 1347c478bd9Sstevel@tonic-gate int arg; /* argument from getopt() */ 135*3e1bd7a2Ssjelinek char *msg; 136*3e1bd7a2Ssjelinek int error; 1377c478bd9Sstevel@tonic-gate extern char *optarg; /* getopt specific */ 1387c478bd9Sstevel@tonic-gate extern int optind; 1397c478bd9Sstevel@tonic-gate extern int opterr; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 1447c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 1457c478bd9Sstevel@tonic-gate #endif 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate cbasename = ptr = argv[0]; 1507c478bd9Sstevel@tonic-gate while (*ptr) { 1517c478bd9Sstevel@tonic-gate if (*ptr++ == '/') 1527c478bd9Sstevel@tonic-gate cbasename = ptr; 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate if (argc == 1) { 1577c478bd9Sstevel@tonic-gate for (c_ptr = cmd_data; ((c_ptr->c_basename != NULL) && 1587c478bd9Sstevel@tonic-gate (strcmp(c_ptr->c_basename, cbasename) != 0)); c_ptr++) 1597c478bd9Sstevel@tonic-gate ; 1607c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 1617c478bd9Sstevel@tonic-gate exit(2); 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate for (c_ptr = cmd_data; ((c_ptr->c_basename != NULL) && 1657c478bd9Sstevel@tonic-gate (strcmp(c_ptr->c_basename, cbasename) != 0)); c_ptr++) 1667c478bd9Sstevel@tonic-gate ; 1677c478bd9Sstevel@tonic-gate while ((arg = getopt(argc, argv, c_ptr->c_optstr)) != -1) { 1687c478bd9Sstevel@tonic-gate switch (arg) { 1697c478bd9Sstevel@tonic-gate case 'V': /* echo complete command line */ 1707c478bd9Sstevel@tonic-gate verbose = 1; 1717c478bd9Sstevel@tonic-gate break; 1727c478bd9Sstevel@tonic-gate case 'F': /* FSType specified */ 1737c478bd9Sstevel@tonic-gate F_flg++; 1747c478bd9Sstevel@tonic-gate fstype = optarg; 1757c478bd9Sstevel@tonic-gate break; 1767c478bd9Sstevel@tonic-gate case 'o': /* FSType specific arguments */ 1777c478bd9Sstevel@tonic-gate newargv[newargc++] = "-o"; 1787c478bd9Sstevel@tonic-gate newargv[newargc++] = optarg; 1797c478bd9Sstevel@tonic-gate oopts = optarg; 180*3e1bd7a2Ssjelinek if (!Nflag) { 181*3e1bd7a2Ssjelinek tmpopts = optarg; 182*3e1bd7a2Ssjelinek Nflag = has_Nflag(tmpopts); 183*3e1bd7a2Ssjelinek } 1847c478bd9Sstevel@tonic-gate break; 1857c478bd9Sstevel@tonic-gate case '?': /* print usage message */ 1867c478bd9Sstevel@tonic-gate newargv[newargc++] = "-?"; 1877c478bd9Sstevel@tonic-gate usgflag = 1; 1887c478bd9Sstevel@tonic-gate break; 1897c478bd9Sstevel@tonic-gate case 'm': /* FSType specific arguments */ 1907c478bd9Sstevel@tonic-gate mflag = 1; 1917c478bd9Sstevel@tonic-gate newargv[newargc] = (char *)malloc(3); 1927c478bd9Sstevel@tonic-gate sprintf(newargv[newargc++], "-%c", arg); 1937c478bd9Sstevel@tonic-gate if (optarg) 1947c478bd9Sstevel@tonic-gate newargv[newargc++] = optarg; 1957c478bd9Sstevel@tonic-gate break; 1967c478bd9Sstevel@tonic-gate case 'i': /* fssnap only */ 1977c478bd9Sstevel@tonic-gate iflag = 1; 1987c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 1997c478bd9Sstevel@tonic-gate default: 2007c478bd9Sstevel@tonic-gate newargv[newargc] = (char *)malloc(3); 2017c478bd9Sstevel@tonic-gate sprintf(newargv[newargc++], "-%c", arg); 2027c478bd9Sstevel@tonic-gate if (optarg) 2037c478bd9Sstevel@tonic-gate newargv[newargc++] = optarg; 2047c478bd9Sstevel@tonic-gate break; 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate optarg = NULL; 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate if (F_flg > 1) { 209*3e1bd7a2Ssjelinek (void) fprintf(stderr, 210*3e1bd7a2Ssjelinek gettext("%s: more than one FSType specified\n"), 2117c478bd9Sstevel@tonic-gate cbasename); 2127c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2137c478bd9Sstevel@tonic-gate exit(2); 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate if (fstype != NULL) { 2167c478bd9Sstevel@tonic-gate if (strlen(fstype) > FSTYPE_MAX) { 217*3e1bd7a2Ssjelinek (void) fprintf(stderr, 2187c478bd9Sstevel@tonic-gate gettext("%s: FSType %s exceeds %d characters\n"), 2197c478bd9Sstevel@tonic-gate cbasename, fstype, FSTYPE_MAX); 2207c478bd9Sstevel@tonic-gate exit(2); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate /* perform a lookup if fstype is not specified */ 2257c478bd9Sstevel@tonic-gate special = argv[optind]; 2267c478bd9Sstevel@tonic-gate optind++; 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate /* handle -i (fssnap command only) */ 2297c478bd9Sstevel@tonic-gate if (iflag) { 2307c478bd9Sstevel@tonic-gate int diff = argc - optind; 2317c478bd9Sstevel@tonic-gate /* 2327c478bd9Sstevel@tonic-gate * There is no reason to ever call a file system specific 2337c478bd9Sstevel@tonic-gate * version since its all in kstats. 2347c478bd9Sstevel@tonic-gate */ 2357c478bd9Sstevel@tonic-gate if (diff > 0) /* gave more than one mountpoint or device */ 2367c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2377c478bd9Sstevel@tonic-gate stat_snap(cbasename, diff == 0 ? argv[argc-1] : NULL, oopts); 2387c478bd9Sstevel@tonic-gate exit(0); 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate if ((special == NULL) && (!usgflag)) { 242*3e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("%s: special not specified\n"), 2437c478bd9Sstevel@tonic-gate cbasename); 2447c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2457c478bd9Sstevel@tonic-gate exit(2); 2467c478bd9Sstevel@tonic-gate } 247*3e1bd7a2Ssjelinek 2487c478bd9Sstevel@tonic-gate if ((fstype == NULL) && (usgflag)) 2497c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2507c478bd9Sstevel@tonic-gate if (fstype == NULL) 2517c478bd9Sstevel@tonic-gate lookup(); 2527c478bd9Sstevel@tonic-gate if (fstype == NULL) { 253*3e1bd7a2Ssjelinek (void) fprintf(stderr, 254*3e1bd7a2Ssjelinek gettext("%s: FSType cannot be identified\n"), cbasename); 2557c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2567c478bd9Sstevel@tonic-gate exit(2); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate newargv[newargc++] = special; 2597c478bd9Sstevel@tonic-gate for (; optind < argc; optind++) 2607c478bd9Sstevel@tonic-gate newargv[newargc++] = argv[optind]; 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate /* build the full pathname of the fstype dependent command */ 2637c478bd9Sstevel@tonic-gate sprintf(full_path, "%s/%s/%s", vfs_path, fstype, cbasename); 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate newargv[1] = cbasename; 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate if (verbose) { 2687c478bd9Sstevel@tonic-gate printf("%s -F %s ", cbasename, fstype); 2697c478bd9Sstevel@tonic-gate for (i = 2; newargv[i]; i++) 2707c478bd9Sstevel@tonic-gate printf("%s ", newargv[i]); 2717c478bd9Sstevel@tonic-gate printf("\n"); 2727c478bd9Sstevel@tonic-gate exit(0); 2737c478bd9Sstevel@tonic-gate } 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate /* 276*3e1bd7a2Ssjelinek * Prior to executing the command for mkfs check for device in use. 277*3e1bd7a2Ssjelinek * If the mflag is set, user wants to see command that created 278*3e1bd7a2Ssjelinek * an already existing filesystem. Do not check for in use in this 279*3e1bd7a2Ssjelinek * case. If Nflag is set user wants to see what the parameters 280*3e1bd7a2Ssjelinek * would be to create the filesystem. Do not check for in use in 281*3e1bd7a2Ssjelinek * this case. 282*3e1bd7a2Ssjelinek */ 283*3e1bd7a2Ssjelinek if (strcmp(cbasename, "mkfs") == 0 && !mflag && !Nflag) { 284*3e1bd7a2Ssjelinek if (dm_inuse(special, &msg, DM_WHO_MKFS, &error) || 285*3e1bd7a2Ssjelinek error) { 286*3e1bd7a2Ssjelinek if (error != 0) { 287*3e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("Error occurred" 288*3e1bd7a2Ssjelinek " with device in use checking: %s\n"), 289*3e1bd7a2Ssjelinek strerror(error)); 290*3e1bd7a2Ssjelinek } else { 291*3e1bd7a2Ssjelinek (void) fprintf(stderr, "%s", msg); 292*3e1bd7a2Ssjelinek free(msg); 293*3e1bd7a2Ssjelinek exit(2); 294*3e1bd7a2Ssjelinek } 295*3e1bd7a2Ssjelinek } 296*3e1bd7a2Ssjelinek } 297*3e1bd7a2Ssjelinek 298*3e1bd7a2Ssjelinek /* 2997c478bd9Sstevel@tonic-gate * Execute the FSType specific command. 3007c478bd9Sstevel@tonic-gate */ 3017c478bd9Sstevel@tonic-gate execv(full_path, &newargv[1]); 3027c478bd9Sstevel@tonic-gate if ((errno == ENOENT) || (errno == EACCES)) { 3037c478bd9Sstevel@tonic-gate /* build the alternate pathname */ 3047c478bd9Sstevel@tonic-gate sprintf(full_path, "%s/%s/%s", alt_path, fstype, cbasename); 3057c478bd9Sstevel@tonic-gate if (verbose) { 3067c478bd9Sstevel@tonic-gate printf("%s -F %s ", cbasename, fstype); 3077c478bd9Sstevel@tonic-gate for (i = 2; newargv[i]; i++) 3087c478bd9Sstevel@tonic-gate printf("%s ", newargv[i]); 3097c478bd9Sstevel@tonic-gate printf("\n"); 3107c478bd9Sstevel@tonic-gate exit(0); 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate execv(full_path, &newargv[1]); 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate if (errno == ENOEXEC) { 3157c478bd9Sstevel@tonic-gate newargv[0] = "sh"; 3167c478bd9Sstevel@tonic-gate newargv[1] = full_path; 3177c478bd9Sstevel@tonic-gate execv("/sbin/sh", &newargv[0]); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate if (errno != ENOENT) { 3207c478bd9Sstevel@tonic-gate perror(cbasename); 321*3e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("%s: cannot execute %s\n"), 322*3e1bd7a2Ssjelinek cbasename, full_path); 3237c478bd9Sstevel@tonic-gate exit(2); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate if (sysfs(GETFSIND, fstype) == (-1)) { 327*3e1bd7a2Ssjelinek (void) fprintf(stderr, 3287c478bd9Sstevel@tonic-gate gettext("%s: FSType %s not installed in the kernel\n"), 3297c478bd9Sstevel@tonic-gate cbasename, fstype); 3307c478bd9Sstevel@tonic-gate exit(2); 3317c478bd9Sstevel@tonic-gate } 332*3e1bd7a2Ssjelinek (void) fprintf(stderr, 3337c478bd9Sstevel@tonic-gate gettext("%s: Operation not applicable for FSType %s \n"), 3347c478bd9Sstevel@tonic-gate cbasename, fstype); 3357c478bd9Sstevel@tonic-gate exit(2); 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate usage(cmd, usg) 3397c478bd9Sstevel@tonic-gate char *cmd; 3407c478bd9Sstevel@tonic-gate char **usg; 3417c478bd9Sstevel@tonic-gate { 3427c478bd9Sstevel@tonic-gate int i; 343*3e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("Usage:\n")); 3447c478bd9Sstevel@tonic-gate for (i = 0; usg[i] != NULL; i++) 345*3e1bd7a2Ssjelinek (void) fprintf(stderr, "%s %s\n", gettext(cmd), 346*3e1bd7a2Ssjelinek gettext(usg[i])); 3477c478bd9Sstevel@tonic-gate exit(2); 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate /* 3527c478bd9Sstevel@tonic-gate * This looks up the /etc/vfstab entry given the device 'special'. 3537c478bd9Sstevel@tonic-gate * It is called when the fstype is not specified on the command line. 3547c478bd9Sstevel@tonic-gate * 3557c478bd9Sstevel@tonic-gate * The following global variables are used: 3567c478bd9Sstevel@tonic-gate * special, fstype 3577c478bd9Sstevel@tonic-gate */ 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate lookup() 3607c478bd9Sstevel@tonic-gate { 3617c478bd9Sstevel@tonic-gate FILE *fd; 3627c478bd9Sstevel@tonic-gate int ret; 3637c478bd9Sstevel@tonic-gate struct vfstab vget, vref; 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate if ((fd = fopen(vfstab, "r")) == NULL) { 366*3e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("%s: cannot open vfstab\n"), 367*3e1bd7a2Ssjelinek cbasename); 3687c478bd9Sstevel@tonic-gate exit(1); 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate vfsnull(&vref); 3717c478bd9Sstevel@tonic-gate vref.vfs_special = special; 3727c478bd9Sstevel@tonic-gate ret = getvfsany(fd, &vget, &vref); 3737c478bd9Sstevel@tonic-gate if (ret == -1) { 3747c478bd9Sstevel@tonic-gate rewind(fd); 3757c478bd9Sstevel@tonic-gate vfsnull(&vref); 3767c478bd9Sstevel@tonic-gate vref.vfs_fsckdev = special; 3777c478bd9Sstevel@tonic-gate ret = getvfsany(fd, &vget, &vref); 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate fclose(fd); 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate switch (ret) { 3827c478bd9Sstevel@tonic-gate case -1: 3837c478bd9Sstevel@tonic-gate fstype = default_fstype(special); 3847c478bd9Sstevel@tonic-gate break; 3857c478bd9Sstevel@tonic-gate case 0: 3867c478bd9Sstevel@tonic-gate fstype = vget.vfs_fstype; 3877c478bd9Sstevel@tonic-gate break; 3887c478bd9Sstevel@tonic-gate case VFS_TOOLONG: 389*3e1bd7a2Ssjelinek (void) fprintf(stderr, 3907c478bd9Sstevel@tonic-gate gettext("%s: line in vfstab exceeds %d characters\n"), 3917c478bd9Sstevel@tonic-gate cbasename, VFS_LINE_MAX-2); 3927c478bd9Sstevel@tonic-gate exit(1); 3937c478bd9Sstevel@tonic-gate break; 3947c478bd9Sstevel@tonic-gate case VFS_TOOFEW: 395*3e1bd7a2Ssjelinek (void) fprintf(stderr, 3967c478bd9Sstevel@tonic-gate gettext("%s: line in vfstab has too few entries\n"), 3977c478bd9Sstevel@tonic-gate cbasename); 3987c478bd9Sstevel@tonic-gate exit(1); 3997c478bd9Sstevel@tonic-gate break; 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate void 4047c478bd9Sstevel@tonic-gate stat_snap(cmd, mountpoint, opts) 4057c478bd9Sstevel@tonic-gate char *cmd; 4067c478bd9Sstevel@tonic-gate char *mountpoint; 4077c478bd9Sstevel@tonic-gate char *opts; 4087c478bd9Sstevel@tonic-gate { 4097c478bd9Sstevel@tonic-gate int fd; /* check mount point if given */ 4107c478bd9Sstevel@tonic-gate int en; 4117c478bd9Sstevel@tonic-gate char *errstr; 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate if (mountpoint) { 4147c478bd9Sstevel@tonic-gate if ((fd = open(mountpoint, O_RDONLY)) < 0) { 4157c478bd9Sstevel@tonic-gate en = errno; 4167c478bd9Sstevel@tonic-gate errstr = strerror(errno); 4177c478bd9Sstevel@tonic-gate if (errstr == NULL) 4187c478bd9Sstevel@tonic-gate errstr = gettext("Unknown error"); 4197c478bd9Sstevel@tonic-gate 420*3e1bd7a2Ssjelinek (void) fprintf(stderr, 421*3e1bd7a2Ssjelinek gettext("%s: %s: error %d: %s\n"), 4227c478bd9Sstevel@tonic-gate cmd, mountpoint, en, errstr); 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate exit(2); 4257c478bd9Sstevel@tonic-gate } 4267c478bd9Sstevel@tonic-gate close(fd); 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate fssnap_show_status(mountpoint, opts, 1, (opts ? 0 : 1)); 4297c478bd9Sstevel@tonic-gate } 430*3e1bd7a2Ssjelinek static int 431*3e1bd7a2Ssjelinek has_Nflag(char *opts) 432*3e1bd7a2Ssjelinek { 433*3e1bd7a2Ssjelinek while (opts != NULL && *opts != '\0') { 434*3e1bd7a2Ssjelinek if (match(&opts, "N")) { 435*3e1bd7a2Ssjelinek return (1); 436*3e1bd7a2Ssjelinek } 437*3e1bd7a2Ssjelinek if (!opts) 438*3e1bd7a2Ssjelinek break; 439*3e1bd7a2Ssjelinek if (*opts == ',') 440*3e1bd7a2Ssjelinek opts ++; 441*3e1bd7a2Ssjelinek if (*opts == ' ') 442*3e1bd7a2Ssjelinek opts ++; 443*3e1bd7a2Ssjelinek } 444*3e1bd7a2Ssjelinek return (0); 445*3e1bd7a2Ssjelinek } 446*3e1bd7a2Ssjelinek /* 447*3e1bd7a2Ssjelinek * Parses the -o [fs specific options string] to search for the UFS -N flag. 448*3e1bd7a2Ssjelinek * Return the opts string pointing to the next position in the string if 449*3e1bd7a2Ssjelinek * match is not found. A delimiter of , or ' ' can be used depending on the 450*3e1bd7a2Ssjelinek * caller, newfs or mkfs. 451*3e1bd7a2Ssjelinek */ 452*3e1bd7a2Ssjelinek static int 453*3e1bd7a2Ssjelinek match(char **opts, char *s) 454*3e1bd7a2Ssjelinek { 455*3e1bd7a2Ssjelinek char *cs; 456*3e1bd7a2Ssjelinek char *tmp_str; 457*3e1bd7a2Ssjelinek 458*3e1bd7a2Ssjelinek cs = *opts; 459*3e1bd7a2Ssjelinek 460*3e1bd7a2Ssjelinek while (*cs++ == *s) { 461*3e1bd7a2Ssjelinek if (*s++ == '\0') { 462*3e1bd7a2Ssjelinek goto true; 463*3e1bd7a2Ssjelinek } 464*3e1bd7a2Ssjelinek } 465*3e1bd7a2Ssjelinek if (*s != '\0') { 466*3e1bd7a2Ssjelinek /* 467*3e1bd7a2Ssjelinek * If we cannot find the delimiter it means we 468*3e1bd7a2Ssjelinek * have hit the end of the string. 469*3e1bd7a2Ssjelinek */ 470*3e1bd7a2Ssjelinek tmp_str = strchr(*opts, ','); 471*3e1bd7a2Ssjelinek if (!tmp_str) 472*3e1bd7a2Ssjelinek tmp_str = strchr(*opts, ' '); 473*3e1bd7a2Ssjelinek 474*3e1bd7a2Ssjelinek *opts = tmp_str; 475*3e1bd7a2Ssjelinek return (0); 476*3e1bd7a2Ssjelinek } 477*3e1bd7a2Ssjelinek true: 478*3e1bd7a2Ssjelinek cs--; 479*3e1bd7a2Ssjelinek *opts = cs; 480*3e1bd7a2Ssjelinek return (1); 481*3e1bd7a2Ssjelinek } 482