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); 49*82d71480Ssjelinek static int has_Nflag(char *opts); 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate #define FSTYPE_MAX 8 527c478bd9Sstevel@tonic-gate #define ARGV_MAX 1024 537c478bd9Sstevel@tonic-gate #define VFS_PATH "/usr/lib/fs" 547c478bd9Sstevel@tonic-gate #define ALT_PATH "/etc/fs" 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate extern char *default_fstype(); 577c478bd9Sstevel@tonic-gate void stat_snap(char *, char *, char *); 587c478bd9Sstevel@tonic-gate char *special = NULL; /* device special name */ 597c478bd9Sstevel@tonic-gate char *fstype = NULL; /* fstype name is filled in here */ 607c478bd9Sstevel@tonic-gate char *cbasename; /* name of command */ 617c478bd9Sstevel@tonic-gate char *newargv[ARGV_MAX]; /* args for the fstype specific command */ 627c478bd9Sstevel@tonic-gate char vfstab[] = VFSTAB; 637c478bd9Sstevel@tonic-gate int newargc = 2; 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate /* 667c478bd9Sstevel@tonic-gate * TRANSLATION_NOTE - the usage strings in the c_usgstr[] of the 677c478bd9Sstevel@tonic-gate * following structures should be given a translation; the call to gettext 687c478bd9Sstevel@tonic-gate * is in the usage() function. The strings are the ones containing 697c478bd9Sstevel@tonic-gate * "[-F FSType]". 707c478bd9Sstevel@tonic-gate */ 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate struct commands { 737c478bd9Sstevel@tonic-gate char *c_basename; 747c478bd9Sstevel@tonic-gate char *c_optstr; 757c478bd9Sstevel@tonic-gate char *c_usgstr[4]; /* make sure as large as largest array size */ 767c478bd9Sstevel@tonic-gate } cmd_data[] = { 777c478bd9Sstevel@tonic-gate "clri", "F:o:?V", 787c478bd9Sstevel@tonic-gate { 797c478bd9Sstevel@tonic-gate "[-F FSType] [-V] special inumber ...", 807c478bd9Sstevel@tonic-gate NULL 817c478bd9Sstevel@tonic-gate }, 827c478bd9Sstevel@tonic-gate "mkfs", "F:o:mb:?V", 837c478bd9Sstevel@tonic-gate { 847c478bd9Sstevel@tonic-gate "[-F FSType] [-V] [-m] [-o specific_options] special ", 857c478bd9Sstevel@tonic-gate "[operands]", NULL 867c478bd9Sstevel@tonic-gate }, 877c478bd9Sstevel@tonic-gate "dcopy", "F:o:?V", 887c478bd9Sstevel@tonic-gate { 897c478bd9Sstevel@tonic-gate "[-F FSType] [-V] special inumber ...", 907c478bd9Sstevel@tonic-gate NULL 917c478bd9Sstevel@tonic-gate }, 927c478bd9Sstevel@tonic-gate "fsdb", "F:o:z:?V", 937c478bd9Sstevel@tonic-gate { 947c478bd9Sstevel@tonic-gate "[-F FSType] [-V] [-o specific_options] special", 957c478bd9Sstevel@tonic-gate NULL 967c478bd9Sstevel@tonic-gate }, 977c478bd9Sstevel@tonic-gate "fssnap", "F:dio:?V", 987c478bd9Sstevel@tonic-gate { 997c478bd9Sstevel@tonic-gate "[-F FSType] [-V] -o special_options /mount/point", 1007c478bd9Sstevel@tonic-gate "-d [-F FSType] [-V] /mount/point | dev", 1017c478bd9Sstevel@tonic-gate "-i [-F FSType] [-V] [-o special-options] [/mount/point | dev]", 1027c478bd9Sstevel@tonic-gate NULL 1037c478bd9Sstevel@tonic-gate }, 1047c478bd9Sstevel@tonic-gate "labelit", "F:o:?nV", 1057c478bd9Sstevel@tonic-gate { 1067c478bd9Sstevel@tonic-gate "[-F FSType] [-V] [-o specific_options] special [operands]", 1077c478bd9Sstevel@tonic-gate NULL 1087c478bd9Sstevel@tonic-gate }, 1097c478bd9Sstevel@tonic-gate NULL, "F:o:?V", 1107c478bd9Sstevel@tonic-gate { 1117c478bd9Sstevel@tonic-gate "[-F FSType] [-V] [-o specific_options] special [operands]", 1127c478bd9Sstevel@tonic-gate NULL 1137c478bd9Sstevel@tonic-gate } 1147c478bd9Sstevel@tonic-gate }; 1157c478bd9Sstevel@tonic-gate struct commands *c_ptr; 1167c478bd9Sstevel@tonic-gate 11708190127Sdh145677 static void usage(char *cmd, char **usg); 11808190127Sdh145677 static void lookup(void); 11908190127Sdh145677 12008190127Sdh145677 int 12108190127Sdh145677 main(int argc, char *argv[]) 1227c478bd9Sstevel@tonic-gate { 12308190127Sdh145677 char *ptr; 1247c478bd9Sstevel@tonic-gate char full_path[PATH_MAX]; 1257c478bd9Sstevel@tonic-gate char *vfs_path = VFS_PATH; 1267c478bd9Sstevel@tonic-gate char *alt_path = ALT_PATH; 1277c478bd9Sstevel@tonic-gate int i; 1283e1bd7a2Ssjelinek int j; 1297c478bd9Sstevel@tonic-gate int verbose = 0; /* set if -V is specified */ 1307c478bd9Sstevel@tonic-gate int F_flg = 0; 1317c478bd9Sstevel@tonic-gate int mflag = 0; 1323e1bd7a2Ssjelinek int Nflag = 0; 1337c478bd9Sstevel@tonic-gate char *oopts = NULL; 1343e1bd7a2Ssjelinek char *tmpopts = NULL; /* used for in use checking */ 1357c478bd9Sstevel@tonic-gate int iflag = 0; 1367c478bd9Sstevel@tonic-gate int usgflag = 0; 1377c478bd9Sstevel@tonic-gate int arg; /* argument from getopt() */ 1383e1bd7a2Ssjelinek char *msg; 1393e1bd7a2Ssjelinek int error; 1407c478bd9Sstevel@tonic-gate extern char *optarg; /* getopt specific */ 1417c478bd9Sstevel@tonic-gate extern int optind; 1427c478bd9Sstevel@tonic-gate extern int opterr; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 1477c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 1487c478bd9Sstevel@tonic-gate #endif 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate cbasename = ptr = argv[0]; 1537c478bd9Sstevel@tonic-gate while (*ptr) { 1547c478bd9Sstevel@tonic-gate if (*ptr++ == '/') 1557c478bd9Sstevel@tonic-gate cbasename = ptr; 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate if (argc == 1) { 1607c478bd9Sstevel@tonic-gate for (c_ptr = cmd_data; ((c_ptr->c_basename != NULL) && 1617c478bd9Sstevel@tonic-gate (strcmp(c_ptr->c_basename, cbasename) != 0)); c_ptr++) 1627c478bd9Sstevel@tonic-gate ; 1637c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 1647c478bd9Sstevel@tonic-gate exit(2); 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate for (c_ptr = cmd_data; ((c_ptr->c_basename != NULL) && 1687c478bd9Sstevel@tonic-gate (strcmp(c_ptr->c_basename, cbasename) != 0)); c_ptr++) 1697c478bd9Sstevel@tonic-gate ; 1707c478bd9Sstevel@tonic-gate while ((arg = getopt(argc, argv, c_ptr->c_optstr)) != -1) { 1717c478bd9Sstevel@tonic-gate switch (arg) { 1727c478bd9Sstevel@tonic-gate case 'V': /* echo complete command line */ 1737c478bd9Sstevel@tonic-gate verbose = 1; 1747c478bd9Sstevel@tonic-gate break; 1757c478bd9Sstevel@tonic-gate case 'F': /* FSType specified */ 1767c478bd9Sstevel@tonic-gate F_flg++; 1777c478bd9Sstevel@tonic-gate fstype = optarg; 1787c478bd9Sstevel@tonic-gate break; 1797c478bd9Sstevel@tonic-gate case 'o': /* FSType specific arguments */ 1807c478bd9Sstevel@tonic-gate newargv[newargc++] = "-o"; 1817c478bd9Sstevel@tonic-gate newargv[newargc++] = optarg; 1827c478bd9Sstevel@tonic-gate oopts = optarg; 1833e1bd7a2Ssjelinek if (!Nflag) { 1843e1bd7a2Ssjelinek tmpopts = optarg; 1853e1bd7a2Ssjelinek Nflag = has_Nflag(tmpopts); 1863e1bd7a2Ssjelinek } 1877c478bd9Sstevel@tonic-gate break; 1887c478bd9Sstevel@tonic-gate case '?': /* print usage message */ 1897c478bd9Sstevel@tonic-gate newargv[newargc++] = "-?"; 1907c478bd9Sstevel@tonic-gate usgflag = 1; 1917c478bd9Sstevel@tonic-gate break; 1927c478bd9Sstevel@tonic-gate case 'm': /* FSType specific arguments */ 1937c478bd9Sstevel@tonic-gate mflag = 1; 1947c478bd9Sstevel@tonic-gate newargv[newargc] = (char *)malloc(3); 1957c478bd9Sstevel@tonic-gate sprintf(newargv[newargc++], "-%c", arg); 1967c478bd9Sstevel@tonic-gate if (optarg) 1977c478bd9Sstevel@tonic-gate newargv[newargc++] = optarg; 1987c478bd9Sstevel@tonic-gate break; 1997c478bd9Sstevel@tonic-gate case 'i': /* fssnap only */ 2007c478bd9Sstevel@tonic-gate iflag = 1; 2017c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 2027c478bd9Sstevel@tonic-gate default: 2037c478bd9Sstevel@tonic-gate newargv[newargc] = (char *)malloc(3); 2047c478bd9Sstevel@tonic-gate sprintf(newargv[newargc++], "-%c", arg); 2057c478bd9Sstevel@tonic-gate if (optarg) 2067c478bd9Sstevel@tonic-gate newargv[newargc++] = optarg; 2077c478bd9Sstevel@tonic-gate break; 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate optarg = NULL; 2107c478bd9Sstevel@tonic-gate } 2117c478bd9Sstevel@tonic-gate if (F_flg > 1) { 2123e1bd7a2Ssjelinek (void) fprintf(stderr, 2133e1bd7a2Ssjelinek gettext("%s: more than one FSType specified\n"), 2147c478bd9Sstevel@tonic-gate cbasename); 2157c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2167c478bd9Sstevel@tonic-gate exit(2); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate if (fstype != NULL) { 2197c478bd9Sstevel@tonic-gate if (strlen(fstype) > FSTYPE_MAX) { 2203e1bd7a2Ssjelinek (void) fprintf(stderr, 2217c478bd9Sstevel@tonic-gate gettext("%s: FSType %s exceeds %d characters\n"), 2227c478bd9Sstevel@tonic-gate cbasename, fstype, FSTYPE_MAX); 2237c478bd9Sstevel@tonic-gate exit(2); 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate /* perform a lookup if fstype is not specified */ 2287c478bd9Sstevel@tonic-gate special = argv[optind]; 2297c478bd9Sstevel@tonic-gate optind++; 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate /* handle -i (fssnap command only) */ 2327c478bd9Sstevel@tonic-gate if (iflag) { 2337c478bd9Sstevel@tonic-gate int diff = argc - optind; 2347c478bd9Sstevel@tonic-gate /* 2357c478bd9Sstevel@tonic-gate * There is no reason to ever call a file system specific 2367c478bd9Sstevel@tonic-gate * version since its all in kstats. 2377c478bd9Sstevel@tonic-gate */ 2387c478bd9Sstevel@tonic-gate if (diff > 0) /* gave more than one mountpoint or device */ 2397c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2407c478bd9Sstevel@tonic-gate stat_snap(cbasename, diff == 0 ? argv[argc-1] : NULL, oopts); 2417c478bd9Sstevel@tonic-gate exit(0); 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate if ((special == NULL) && (!usgflag)) { 2453e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("%s: special not specified\n"), 2467c478bd9Sstevel@tonic-gate cbasename); 2477c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2487c478bd9Sstevel@tonic-gate exit(2); 2497c478bd9Sstevel@tonic-gate } 2503e1bd7a2Ssjelinek 2517c478bd9Sstevel@tonic-gate if ((fstype == NULL) && (usgflag)) 2527c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2537c478bd9Sstevel@tonic-gate if (fstype == NULL) 2547c478bd9Sstevel@tonic-gate lookup(); 2557c478bd9Sstevel@tonic-gate if (fstype == NULL) { 2563e1bd7a2Ssjelinek (void) fprintf(stderr, 2573e1bd7a2Ssjelinek gettext("%s: FSType cannot be identified\n"), cbasename); 2587c478bd9Sstevel@tonic-gate usage(cbasename, c_ptr->c_usgstr); 2597c478bd9Sstevel@tonic-gate exit(2); 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate newargv[newargc++] = special; 2627c478bd9Sstevel@tonic-gate for (; optind < argc; optind++) 2637c478bd9Sstevel@tonic-gate newargv[newargc++] = argv[optind]; 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate /* build the full pathname of the fstype dependent command */ 2667c478bd9Sstevel@tonic-gate sprintf(full_path, "%s/%s/%s", vfs_path, fstype, cbasename); 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate newargv[1] = cbasename; 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate if (verbose) { 2717c478bd9Sstevel@tonic-gate printf("%s -F %s ", cbasename, fstype); 2727c478bd9Sstevel@tonic-gate for (i = 2; newargv[i]; i++) 2737c478bd9Sstevel@tonic-gate printf("%s ", newargv[i]); 2747c478bd9Sstevel@tonic-gate printf("\n"); 2757c478bd9Sstevel@tonic-gate exit(0); 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate /* 2793e1bd7a2Ssjelinek * Prior to executing the command for mkfs check for device in use. 2803e1bd7a2Ssjelinek * If the mflag is set, user wants to see command that created 2813e1bd7a2Ssjelinek * an already existing filesystem. Do not check for in use in this 2823e1bd7a2Ssjelinek * case. If Nflag is set user wants to see what the parameters 2833e1bd7a2Ssjelinek * would be to create the filesystem. Do not check for in use in 2843e1bd7a2Ssjelinek * this case. 2853e1bd7a2Ssjelinek */ 2863e1bd7a2Ssjelinek if (strcmp(cbasename, "mkfs") == 0 && !mflag && !Nflag) { 2873e1bd7a2Ssjelinek if (dm_inuse(special, &msg, DM_WHO_MKFS, &error) || 2883e1bd7a2Ssjelinek error) { 2893e1bd7a2Ssjelinek if (error != 0) { 2903e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("Error occurred" 2913e1bd7a2Ssjelinek " with device in use checking: %s\n"), 2923e1bd7a2Ssjelinek strerror(error)); 2933e1bd7a2Ssjelinek } else { 2943e1bd7a2Ssjelinek (void) fprintf(stderr, "%s", msg); 2953e1bd7a2Ssjelinek free(msg); 2963e1bd7a2Ssjelinek exit(2); 2973e1bd7a2Ssjelinek } 2983e1bd7a2Ssjelinek } 2993e1bd7a2Ssjelinek } 3003e1bd7a2Ssjelinek 3013e1bd7a2Ssjelinek /* 3027c478bd9Sstevel@tonic-gate * Execute the FSType specific command. 3037c478bd9Sstevel@tonic-gate */ 3047c478bd9Sstevel@tonic-gate execv(full_path, &newargv[1]); 3057c478bd9Sstevel@tonic-gate if ((errno == ENOENT) || (errno == EACCES)) { 3067c478bd9Sstevel@tonic-gate /* build the alternate pathname */ 3077c478bd9Sstevel@tonic-gate sprintf(full_path, "%s/%s/%s", alt_path, fstype, cbasename); 3087c478bd9Sstevel@tonic-gate if (verbose) { 3097c478bd9Sstevel@tonic-gate printf("%s -F %s ", cbasename, fstype); 3107c478bd9Sstevel@tonic-gate for (i = 2; newargv[i]; i++) 3117c478bd9Sstevel@tonic-gate printf("%s ", newargv[i]); 3127c478bd9Sstevel@tonic-gate printf("\n"); 3137c478bd9Sstevel@tonic-gate exit(0); 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate execv(full_path, &newargv[1]); 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate if (errno == ENOEXEC) { 3187c478bd9Sstevel@tonic-gate newargv[0] = "sh"; 3197c478bd9Sstevel@tonic-gate newargv[1] = full_path; 3207c478bd9Sstevel@tonic-gate execv("/sbin/sh", &newargv[0]); 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate if (errno != ENOENT) { 3237c478bd9Sstevel@tonic-gate perror(cbasename); 3243e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("%s: cannot execute %s\n"), 3253e1bd7a2Ssjelinek cbasename, full_path); 3267c478bd9Sstevel@tonic-gate exit(2); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate if (sysfs(GETFSIND, fstype) == (-1)) { 3303e1bd7a2Ssjelinek (void) fprintf(stderr, 3317c478bd9Sstevel@tonic-gate gettext("%s: FSType %s not installed in the kernel\n"), 3327c478bd9Sstevel@tonic-gate cbasename, fstype); 3337c478bd9Sstevel@tonic-gate exit(2); 3347c478bd9Sstevel@tonic-gate } 3353e1bd7a2Ssjelinek (void) fprintf(stderr, 3367c478bd9Sstevel@tonic-gate gettext("%s: Operation not applicable for FSType %s \n"), 3377c478bd9Sstevel@tonic-gate cbasename, fstype); 33808190127Sdh145677 return (2); 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate 34108190127Sdh145677 static void 34208190127Sdh145677 usage(char *cmd, char **usg) 3437c478bd9Sstevel@tonic-gate { 3447c478bd9Sstevel@tonic-gate int i; 3453e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("Usage:\n")); 3467c478bd9Sstevel@tonic-gate for (i = 0; usg[i] != NULL; i++) 3473e1bd7a2Ssjelinek (void) fprintf(stderr, "%s %s\n", gettext(cmd), 3483e1bd7a2Ssjelinek gettext(usg[i])); 3497c478bd9Sstevel@tonic-gate exit(2); 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate /* 3547c478bd9Sstevel@tonic-gate * This looks up the /etc/vfstab entry given the device 'special'. 3557c478bd9Sstevel@tonic-gate * It is called when the fstype is not specified on the command line. 3567c478bd9Sstevel@tonic-gate * 3577c478bd9Sstevel@tonic-gate * The following global variables are used: 3587c478bd9Sstevel@tonic-gate * special, fstype 3597c478bd9Sstevel@tonic-gate */ 3607c478bd9Sstevel@tonic-gate 36108190127Sdh145677 static void 36208190127Sdh145677 lookup(void) 3637c478bd9Sstevel@tonic-gate { 3647c478bd9Sstevel@tonic-gate FILE *fd; 3657c478bd9Sstevel@tonic-gate int ret; 3667c478bd9Sstevel@tonic-gate struct vfstab vget, vref; 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate if ((fd = fopen(vfstab, "r")) == NULL) { 3693e1bd7a2Ssjelinek (void) fprintf(stderr, gettext("%s: cannot open vfstab\n"), 3703e1bd7a2Ssjelinek cbasename); 3717c478bd9Sstevel@tonic-gate exit(1); 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate vfsnull(&vref); 3747c478bd9Sstevel@tonic-gate vref.vfs_special = special; 3757c478bd9Sstevel@tonic-gate ret = getvfsany(fd, &vget, &vref); 3767c478bd9Sstevel@tonic-gate if (ret == -1) { 3777c478bd9Sstevel@tonic-gate rewind(fd); 3787c478bd9Sstevel@tonic-gate vfsnull(&vref); 3797c478bd9Sstevel@tonic-gate vref.vfs_fsckdev = special; 3807c478bd9Sstevel@tonic-gate ret = getvfsany(fd, &vget, &vref); 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate fclose(fd); 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate switch (ret) { 3857c478bd9Sstevel@tonic-gate case -1: 3867c478bd9Sstevel@tonic-gate fstype = default_fstype(special); 3877c478bd9Sstevel@tonic-gate break; 3887c478bd9Sstevel@tonic-gate case 0: 3897c478bd9Sstevel@tonic-gate fstype = vget.vfs_fstype; 3907c478bd9Sstevel@tonic-gate break; 3917c478bd9Sstevel@tonic-gate case VFS_TOOLONG: 3923e1bd7a2Ssjelinek (void) fprintf(stderr, 3937c478bd9Sstevel@tonic-gate gettext("%s: line in vfstab exceeds %d characters\n"), 3947c478bd9Sstevel@tonic-gate cbasename, VFS_LINE_MAX-2); 3957c478bd9Sstevel@tonic-gate exit(1); 3967c478bd9Sstevel@tonic-gate break; 3977c478bd9Sstevel@tonic-gate case VFS_TOOFEW: 3983e1bd7a2Ssjelinek (void) fprintf(stderr, 3997c478bd9Sstevel@tonic-gate gettext("%s: line in vfstab has too few entries\n"), 4007c478bd9Sstevel@tonic-gate cbasename); 4017c478bd9Sstevel@tonic-gate exit(1); 4027c478bd9Sstevel@tonic-gate break; 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate } 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate void 40708190127Sdh145677 stat_snap(char *cmd, char *mountpoint, 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 4203e1bd7a2Ssjelinek (void) fprintf(stderr, 4213e1bd7a2Ssjelinek 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 } 4303e1bd7a2Ssjelinek static int 4313e1bd7a2Ssjelinek has_Nflag(char *opts) 4323e1bd7a2Ssjelinek { 4333e1bd7a2Ssjelinek while (opts != NULL && *opts != '\0') { 4343e1bd7a2Ssjelinek if (match(&opts, "N")) { 4353e1bd7a2Ssjelinek return (1); 4363e1bd7a2Ssjelinek } 4373e1bd7a2Ssjelinek if (!opts) 4383e1bd7a2Ssjelinek break; 4393e1bd7a2Ssjelinek if (*opts == ',') 4403e1bd7a2Ssjelinek opts ++; 4413e1bd7a2Ssjelinek if (*opts == ' ') 4423e1bd7a2Ssjelinek opts ++; 4433e1bd7a2Ssjelinek } 4443e1bd7a2Ssjelinek return (0); 4453e1bd7a2Ssjelinek } 4463e1bd7a2Ssjelinek /* 4473e1bd7a2Ssjelinek * Parses the -o [fs specific options string] to search for the UFS -N flag. 4483e1bd7a2Ssjelinek * Return the opts string pointing to the next position in the string if 4493e1bd7a2Ssjelinek * match is not found. A delimiter of , or ' ' can be used depending on the 4503e1bd7a2Ssjelinek * caller, newfs or mkfs. 4513e1bd7a2Ssjelinek */ 4523e1bd7a2Ssjelinek static int 4533e1bd7a2Ssjelinek match(char **opts, char *s) 4543e1bd7a2Ssjelinek { 4553e1bd7a2Ssjelinek char *cs; 4563e1bd7a2Ssjelinek char *tmp_str; 4573e1bd7a2Ssjelinek 4583e1bd7a2Ssjelinek cs = *opts; 4593e1bd7a2Ssjelinek 4603e1bd7a2Ssjelinek while (*cs++ == *s) { 4613e1bd7a2Ssjelinek if (*s++ == '\0') { 4623e1bd7a2Ssjelinek goto true; 4633e1bd7a2Ssjelinek } 4643e1bd7a2Ssjelinek } 4653e1bd7a2Ssjelinek if (*s != '\0') { 4663e1bd7a2Ssjelinek /* 4673e1bd7a2Ssjelinek * If we cannot find the delimiter it means we 4683e1bd7a2Ssjelinek * have hit the end of the string. 4693e1bd7a2Ssjelinek */ 4703e1bd7a2Ssjelinek tmp_str = strchr(*opts, ','); 4713e1bd7a2Ssjelinek if (!tmp_str) 4723e1bd7a2Ssjelinek tmp_str = strchr(*opts, ' '); 4733e1bd7a2Ssjelinek 4743e1bd7a2Ssjelinek *opts = tmp_str; 4753e1bd7a2Ssjelinek return (0); 4763e1bd7a2Ssjelinek } 4773e1bd7a2Ssjelinek true: 4783e1bd7a2Ssjelinek cs--; 4793e1bd7a2Ssjelinek *opts = cs; 4803e1bd7a2Ssjelinek return (1); 4813e1bd7a2Ssjelinek } 482