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 /* 273e1bd7a2Ssjelinek * 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> 443e1bd7a2Ssjelinek #include <libdiskmgt.h> 453e1bd7a2Ssjelinek #include "fslib.h" 463e1bd7a2Ssjelinek 473e1bd7a2Ssjelinek 483e1bd7a2Ssjelinek 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 116*08190127Sdh145677 static void usage(char *cmd, char **usg); 117*08190127Sdh145677 static void lookup(void); 118*08190127Sdh145677 119*08190127Sdh145677 int 120*08190127Sdh145677 main(int argc, char *argv[]) 1217c478bd9Sstevel@tonic-gate { 122*08190127Sdh145677 char *ptr; 1237c478bd9Sstevel@tonic-gate char full_path[PATH_MAX]; 1247c478bd9Sstevel@tonic-gate char *vfs_path = VFS_PATH; 1257c478bd9Sstevel@tonic-gate char *alt_path = ALT_PATH; 1267c478bd9Sstevel@tonic-gate int i; 1273e1bd7a2Ssjelinek int j; 1287c478bd9Sstevel@tonic-gate int verbose = 0; /* set if -V is specified */ 1297c478bd9Sstevel@tonic-gate int F_flg = 0; 1307c478bd9Sstevel@tonic-gate int mflag = 0; 1313e1bd7a2Ssjelinek int Nflag = 0; 1327c478bd9Sstevel@tonic-gate char *oopts = NULL; 1333e1bd7a2Ssjelinek char *tmpopts = NULL; /* used for in use checking */ 1347c478bd9Sstevel@tonic-gate int iflag = 0; 1357c478bd9Sstevel@tonic-gate int usgflag = 0; 1367c478bd9Sstevel@tonic-gate int arg; /* argument from getopt() */ 1373e1bd7a2Ssjelinek char *msg; 1383e1bd7a2Ssjelinek int error; 1397c478bd9Sstevel@tonic-gate extern char *optarg; /* getopt specific */ 1407c478bd9Sstevel@tonic-gate extern int optind; 1417c478bd9Sstevel@tonic-gate extern int opterr; 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 1467c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 1477c478bd9Sstevel@tonic-gate #endif 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate cbasename = ptr = argv[0]; 1527c478bd9Sstevel@tonic-gate while (*ptr) { 1537c478bd9Sstevel@tonic-gate if (*ptr++ == '/') 1547c478bd9Sstevel@tonic-gate cbasename = ptr; 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate if (argc == 1) { 1597c478bd9Sstevel@tonic-gate for (c_ptr = cmd_data; ((c_ptr->c_basename != NULL) && 1607c478bd9Sstevel@tonic-gate (strcmp(c_ptr->c_basename, cbasename) != 0)); c_ptr++) 1617c478bd9Sstevel@tonic-gate ; 1627c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 1637c478bd9Sstevel@tonic-gate exit(2); 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate for (c_ptr = cmd_data; ((c_ptr->c_basename != NULL) && 1677c478bd9Sstevel@tonic-gate (strcmp(c_ptr->c_basename, cbasename) != 0)); c_ptr++) 1687c478bd9Sstevel@tonic-gate ; 1697c478bd9Sstevel@tonic-gate while ((arg = getopt(argc, argv, c_ptr->c_optstr)) != -1) { 1707c478bd9Sstevel@tonic-gate switch (arg) { 1717c478bd9Sstevel@tonic-gate case 'V': /* echo complete command line */ 1727c478bd9Sstevel@tonic-gate verbose = 1; 1737c478bd9Sstevel@tonic-gate break; 1747c478bd9Sstevel@tonic-gate case 'F': /* FSType specified */ 1757c478bd9Sstevel@tonic-gate F_flg++; 1767c478bd9Sstevel@tonic-gate fstype = optarg; 1777c478bd9Sstevel@tonic-gate break; 1787c478bd9Sstevel@tonic-gate case 'o': /* FSType specific arguments */ 1797c478bd9Sstevel@tonic-gate newargv[newargc++] = "-o"; 1807c478bd9Sstevel@tonic-gate newargv[newargc++] = optarg; 1817c478bd9Sstevel@tonic-gate oopts = optarg; 1823e1bd7a2Ssjelinek if (!Nflag) { 1833e1bd7a2Ssjelinek tmpopts = optarg; 1843e1bd7a2Ssjelinek Nflag = has_Nflag(tmpopts); 1853e1bd7a2Ssjelinek } 1867c478bd9Sstevel@tonic-gate break; 1877c478bd9Sstevel@tonic-gate case '?': /* print usage message */ 1887c478bd9Sstevel@tonic-gate newargv[newargc++] = "-?"; 1897c478bd9Sstevel@tonic-gate usgflag = 1; 1907c478bd9Sstevel@tonic-gate break; 1917c478bd9Sstevel@tonic-gate case 'm': /* FSType specific arguments */ 1927c478bd9Sstevel@tonic-gate mflag = 1; 1937c478bd9Sstevel@tonic-gate newargv[newargc] = (char *)malloc(3); 1947c478bd9Sstevel@tonic-gate sprintf(newargv[newargc++], "-%c", arg); 1957c478bd9Sstevel@tonic-gate if (optarg) 1967c478bd9Sstevel@tonic-gate newargv[newargc++] = optarg; 1977c478bd9Sstevel@tonic-gate break; 1987c478bd9Sstevel@tonic-gate case 'i': /* fssnap only */ 1997c478bd9Sstevel@tonic-gate iflag = 1; 2007c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 2017c478bd9Sstevel@tonic-gate default: 2027c478bd9Sstevel@tonic-gate newargv[newargc] = (char *)malloc(3); 2037c478bd9Sstevel@tonic-gate sprintf(newargv[newargc++], "-%c", arg); 2047c478bd9Sstevel@tonic-gate if (optarg) 2057c478bd9Sstevel@tonic-gate newargv[newargc++] = optarg; 2067c478bd9Sstevel@tonic-gate break; 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate optarg = NULL; 2097c478bd9Sstevel@tonic-gate } 2107c478bd9Sstevel@tonic-gate if (F_flg > 1) { 2113e1bd7a2Ssjelinek (void) fprintf(stderr, 2123e1bd7a2Ssjelinek gettext("%s: more than one FSType specified\n"), 2137c478bd9Sstevel@tonic-gate cbasename); 2147c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2157c478bd9Sstevel@tonic-gate exit(2); 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate if (fstype != NULL) { 2187c478bd9Sstevel@tonic-gate if (strlen(fstype) > FSTYPE_MAX) { 2193e1bd7a2Ssjelinek (void) fprintf(stderr, 2207c478bd9Sstevel@tonic-gate gettext("%s: FSType %s exceeds %d characters\n"), 2217c478bd9Sstevel@tonic-gate cbasename, fstype, FSTYPE_MAX); 2227c478bd9Sstevel@tonic-gate exit(2); 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate /* perform a lookup if fstype is not specified */ 2277c478bd9Sstevel@tonic-gate special = argv[optind]; 2287c478bd9Sstevel@tonic-gate optind++; 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate /* handle -i (fssnap command only) */ 2317c478bd9Sstevel@tonic-gate if (iflag) { 2327c478bd9Sstevel@tonic-gate int diff = argc - optind; 2337c478bd9Sstevel@tonic-gate /* 2347c478bd9Sstevel@tonic-gate * There is no reason to ever call a file system specific 2357c478bd9Sstevel@tonic-gate * version since its all in kstats. 2367c478bd9Sstevel@tonic-gate */ 2377c478bd9Sstevel@tonic-gate if (diff > 0) /* gave more than one mountpoint or device */ 2387c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2397c478bd9Sstevel@tonic-gate stat_snap(cbasename, diff == 0 ? argv[argc-1] : NULL, oopts); 2407c478bd9Sstevel@tonic-gate exit(0); 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate if ((special == NULL) && (!usgflag)) { 2443e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("%s: special not specified\n"), 2457c478bd9Sstevel@tonic-gate cbasename); 2467c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2477c478bd9Sstevel@tonic-gate exit(2); 2487c478bd9Sstevel@tonic-gate } 2493e1bd7a2Ssjelinek 2507c478bd9Sstevel@tonic-gate if ((fstype == NULL) && (usgflag)) 2517c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2527c478bd9Sstevel@tonic-gate if (fstype == NULL) 2537c478bd9Sstevel@tonic-gate lookup(); 2547c478bd9Sstevel@tonic-gate if (fstype == NULL) { 2553e1bd7a2Ssjelinek (void) fprintf(stderr, 2563e1bd7a2Ssjelinek gettext("%s: FSType cannot be identified\n"), cbasename); 2577c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2587c478bd9Sstevel@tonic-gate exit(2); 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate newargv[newargc++] = special; 2617c478bd9Sstevel@tonic-gate for (; optind < argc; optind++) 2627c478bd9Sstevel@tonic-gate newargv[newargc++] = argv[optind]; 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* build the full pathname of the fstype dependent command */ 2657c478bd9Sstevel@tonic-gate sprintf(full_path, "%s/%s/%s", vfs_path, fstype, cbasename); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate newargv[1] = cbasename; 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate if (verbose) { 2707c478bd9Sstevel@tonic-gate printf("%s -F %s ", cbasename, fstype); 2717c478bd9Sstevel@tonic-gate for (i = 2; newargv[i]; i++) 2727c478bd9Sstevel@tonic-gate printf("%s ", newargv[i]); 2737c478bd9Sstevel@tonic-gate printf("\n"); 2747c478bd9Sstevel@tonic-gate exit(0); 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate /* 2783e1bd7a2Ssjelinek * Prior to executing the command for mkfs check for device in use. 2793e1bd7a2Ssjelinek * If the mflag is set, user wants to see command that created 2803e1bd7a2Ssjelinek * an already existing filesystem. Do not check for in use in this 2813e1bd7a2Ssjelinek * case. If Nflag is set user wants to see what the parameters 2823e1bd7a2Ssjelinek * would be to create the filesystem. Do not check for in use in 2833e1bd7a2Ssjelinek * this case. 2843e1bd7a2Ssjelinek */ 2853e1bd7a2Ssjelinek if (strcmp(cbasename, "mkfs") == 0 && !mflag && !Nflag) { 2863e1bd7a2Ssjelinek if (dm_inuse(special, &msg, DM_WHO_MKFS, &error) || 2873e1bd7a2Ssjelinek error) { 2883e1bd7a2Ssjelinek if (error != 0) { 2893e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("Error occurred" 2903e1bd7a2Ssjelinek " with device in use checking: %s\n"), 2913e1bd7a2Ssjelinek strerror(error)); 2923e1bd7a2Ssjelinek } else { 2933e1bd7a2Ssjelinek (void) fprintf(stderr, "%s", msg); 2943e1bd7a2Ssjelinek free(msg); 2953e1bd7a2Ssjelinek exit(2); 2963e1bd7a2Ssjelinek } 2973e1bd7a2Ssjelinek } 2983e1bd7a2Ssjelinek } 2993e1bd7a2Ssjelinek 3003e1bd7a2Ssjelinek /* 3017c478bd9Sstevel@tonic-gate * Execute the FSType specific command. 3027c478bd9Sstevel@tonic-gate */ 3037c478bd9Sstevel@tonic-gate execv(full_path, &newargv[1]); 3047c478bd9Sstevel@tonic-gate if ((errno == ENOENT) || (errno == EACCES)) { 3057c478bd9Sstevel@tonic-gate /* build the alternate pathname */ 3067c478bd9Sstevel@tonic-gate sprintf(full_path, "%s/%s/%s", alt_path, fstype, cbasename); 3077c478bd9Sstevel@tonic-gate if (verbose) { 3087c478bd9Sstevel@tonic-gate printf("%s -F %s ", cbasename, fstype); 3097c478bd9Sstevel@tonic-gate for (i = 2; newargv[i]; i++) 3107c478bd9Sstevel@tonic-gate printf("%s ", newargv[i]); 3117c478bd9Sstevel@tonic-gate printf("\n"); 3127c478bd9Sstevel@tonic-gate exit(0); 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate execv(full_path, &newargv[1]); 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate if (errno == ENOEXEC) { 3177c478bd9Sstevel@tonic-gate newargv[0] = "sh"; 3187c478bd9Sstevel@tonic-gate newargv[1] = full_path; 3197c478bd9Sstevel@tonic-gate execv("/sbin/sh", &newargv[0]); 3207c478bd9Sstevel@tonic-gate } 3217c478bd9Sstevel@tonic-gate if (errno != ENOENT) { 3227c478bd9Sstevel@tonic-gate perror(cbasename); 3233e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("%s: cannot execute %s\n"), 3243e1bd7a2Ssjelinek cbasename, full_path); 3257c478bd9Sstevel@tonic-gate exit(2); 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate if (sysfs(GETFSIND, fstype) == (-1)) { 3293e1bd7a2Ssjelinek (void) fprintf(stderr, 3307c478bd9Sstevel@tonic-gate gettext("%s: FSType %s not installed in the kernel\n"), 3317c478bd9Sstevel@tonic-gate cbasename, fstype); 3327c478bd9Sstevel@tonic-gate exit(2); 3337c478bd9Sstevel@tonic-gate } 3343e1bd7a2Ssjelinek (void) fprintf(stderr, 3357c478bd9Sstevel@tonic-gate gettext("%s: Operation not applicable for FSType %s \n"), 3367c478bd9Sstevel@tonic-gate cbasename, fstype); 337*08190127Sdh145677 return (2); 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate 340*08190127Sdh145677 static void 341*08190127Sdh145677 usage(char *cmd, char **usg) 3427c478bd9Sstevel@tonic-gate { 3437c478bd9Sstevel@tonic-gate int i; 3443e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("Usage:\n")); 3457c478bd9Sstevel@tonic-gate for (i = 0; usg[i] != NULL; i++) 3463e1bd7a2Ssjelinek (void) fprintf(stderr, "%s %s\n", gettext(cmd), 3473e1bd7a2Ssjelinek gettext(usg[i])); 3487c478bd9Sstevel@tonic-gate exit(2); 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate /* 3537c478bd9Sstevel@tonic-gate * This looks up the /etc/vfstab entry given the device 'special'. 3547c478bd9Sstevel@tonic-gate * It is called when the fstype is not specified on the command line. 3557c478bd9Sstevel@tonic-gate * 3567c478bd9Sstevel@tonic-gate * The following global variables are used: 3577c478bd9Sstevel@tonic-gate * special, fstype 3587c478bd9Sstevel@tonic-gate */ 3597c478bd9Sstevel@tonic-gate 360*08190127Sdh145677 static void 361*08190127Sdh145677 lookup(void) 3627c478bd9Sstevel@tonic-gate { 3637c478bd9Sstevel@tonic-gate FILE *fd; 3647c478bd9Sstevel@tonic-gate int ret; 3657c478bd9Sstevel@tonic-gate struct vfstab vget, vref; 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate if ((fd = fopen(vfstab, "r")) == NULL) { 3683e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("%s: cannot open vfstab\n"), 3693e1bd7a2Ssjelinek cbasename); 3707c478bd9Sstevel@tonic-gate exit(1); 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate vfsnull(&vref); 3737c478bd9Sstevel@tonic-gate vref.vfs_special = special; 3747c478bd9Sstevel@tonic-gate ret = getvfsany(fd, &vget, &vref); 3757c478bd9Sstevel@tonic-gate if (ret == -1) { 3767c478bd9Sstevel@tonic-gate rewind(fd); 3777c478bd9Sstevel@tonic-gate vfsnull(&vref); 3787c478bd9Sstevel@tonic-gate vref.vfs_fsckdev = special; 3797c478bd9Sstevel@tonic-gate ret = getvfsany(fd, &vget, &vref); 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate fclose(fd); 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate switch (ret) { 3847c478bd9Sstevel@tonic-gate case -1: 3857c478bd9Sstevel@tonic-gate fstype = default_fstype(special); 3867c478bd9Sstevel@tonic-gate break; 3877c478bd9Sstevel@tonic-gate case 0: 3887c478bd9Sstevel@tonic-gate fstype = vget.vfs_fstype; 3897c478bd9Sstevel@tonic-gate break; 3907c478bd9Sstevel@tonic-gate case VFS_TOOLONG: 3913e1bd7a2Ssjelinek (void) fprintf(stderr, 3927c478bd9Sstevel@tonic-gate gettext("%s: line in vfstab exceeds %d characters\n"), 3937c478bd9Sstevel@tonic-gate cbasename, VFS_LINE_MAX-2); 3947c478bd9Sstevel@tonic-gate exit(1); 3957c478bd9Sstevel@tonic-gate break; 3967c478bd9Sstevel@tonic-gate case VFS_TOOFEW: 3973e1bd7a2Ssjelinek (void) fprintf(stderr, 3987c478bd9Sstevel@tonic-gate gettext("%s: line in vfstab has too few entries\n"), 3997c478bd9Sstevel@tonic-gate cbasename); 4007c478bd9Sstevel@tonic-gate exit(1); 4017c478bd9Sstevel@tonic-gate break; 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate void 406*08190127Sdh145677 stat_snap(char *cmd, char *mountpoint, char *opts) 4077c478bd9Sstevel@tonic-gate { 4087c478bd9Sstevel@tonic-gate int fd; /* check mount point if given */ 4097c478bd9Sstevel@tonic-gate int en; 4107c478bd9Sstevel@tonic-gate char *errstr; 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate if (mountpoint) { 4137c478bd9Sstevel@tonic-gate if ((fd = open(mountpoint, O_RDONLY)) < 0) { 4147c478bd9Sstevel@tonic-gate en = errno; 4157c478bd9Sstevel@tonic-gate errstr = strerror(errno); 4167c478bd9Sstevel@tonic-gate if (errstr == NULL) 4177c478bd9Sstevel@tonic-gate errstr = gettext("Unknown error"); 4187c478bd9Sstevel@tonic-gate 4193e1bd7a2Ssjelinek (void) fprintf(stderr, 4203e1bd7a2Ssjelinek gettext("%s: %s: error %d: %s\n"), 4217c478bd9Sstevel@tonic-gate cmd, mountpoint, en, errstr); 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate exit(2); 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate close(fd); 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate fssnap_show_status(mountpoint, opts, 1, (opts ? 0 : 1)); 4287c478bd9Sstevel@tonic-gate } 4293e1bd7a2Ssjelinek static int 4303e1bd7a2Ssjelinek has_Nflag(char *opts) 4313e1bd7a2Ssjelinek { 4323e1bd7a2Ssjelinek while (opts != NULL && *opts != '\0') { 4333e1bd7a2Ssjelinek if (match(&opts, "N")) { 4343e1bd7a2Ssjelinek return (1); 4353e1bd7a2Ssjelinek } 4363e1bd7a2Ssjelinek if (!opts) 4373e1bd7a2Ssjelinek break; 4383e1bd7a2Ssjelinek if (*opts == ',') 4393e1bd7a2Ssjelinek opts ++; 4403e1bd7a2Ssjelinek if (*opts == ' ') 4413e1bd7a2Ssjelinek opts ++; 4423e1bd7a2Ssjelinek } 4433e1bd7a2Ssjelinek return (0); 4443e1bd7a2Ssjelinek } 4453e1bd7a2Ssjelinek /* 4463e1bd7a2Ssjelinek * Parses the -o [fs specific options string] to search for the UFS -N flag. 4473e1bd7a2Ssjelinek * Return the opts string pointing to the next position in the string if 4483e1bd7a2Ssjelinek * match is not found. A delimiter of , or ' ' can be used depending on the 4493e1bd7a2Ssjelinek * caller, newfs or mkfs. 4503e1bd7a2Ssjelinek */ 4513e1bd7a2Ssjelinek static int 4523e1bd7a2Ssjelinek match(char **opts, char *s) 4533e1bd7a2Ssjelinek { 4543e1bd7a2Ssjelinek char *cs; 4553e1bd7a2Ssjelinek char *tmp_str; 4563e1bd7a2Ssjelinek 4573e1bd7a2Ssjelinek cs = *opts; 4583e1bd7a2Ssjelinek 4593e1bd7a2Ssjelinek while (*cs++ == *s) { 4603e1bd7a2Ssjelinek if (*s++ == '\0') { 4613e1bd7a2Ssjelinek goto true; 4623e1bd7a2Ssjelinek } 4633e1bd7a2Ssjelinek } 4643e1bd7a2Ssjelinek if (*s != '\0') { 4653e1bd7a2Ssjelinek /* 4663e1bd7a2Ssjelinek * If we cannot find the delimiter it means we 4673e1bd7a2Ssjelinek * have hit the end of the string. 4683e1bd7a2Ssjelinek */ 4693e1bd7a2Ssjelinek tmp_str = strchr(*opts, ','); 4703e1bd7a2Ssjelinek if (!tmp_str) 4713e1bd7a2Ssjelinek tmp_str = strchr(*opts, ' '); 4723e1bd7a2Ssjelinek 4733e1bd7a2Ssjelinek *opts = tmp_str; 4743e1bd7a2Ssjelinek return (0); 4753e1bd7a2Ssjelinek } 4763e1bd7a2Ssjelinek true: 4773e1bd7a2Ssjelinek cs--; 4783e1bd7a2Ssjelinek *opts = cs; 4793e1bd7a2Ssjelinek return (1); 4803e1bd7a2Ssjelinek } 481