10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate /* 23*821Sdh145677 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 280Sstevel@tonic-gate /* All Rights Reserved */ 290Sstevel@tonic-gate 300Sstevel@tonic-gate 310Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 320Sstevel@tonic-gate 330Sstevel@tonic-gate #include <stdio.h> 340Sstevel@tonic-gate #include <limits.h> 350Sstevel@tonic-gate #include <errno.h> 360Sstevel@tonic-gate #include <stdarg.h> 370Sstevel@tonic-gate #include <sys/vfstab.h> 380Sstevel@tonic-gate 390Sstevel@tonic-gate #include <locale.h> 400Sstevel@tonic-gate 410Sstevel@tonic-gate static int perr(const char *fmt, ...); 420Sstevel@tonic-gate 430Sstevel@tonic-gate #define ARGV_MAX 1024 440Sstevel@tonic-gate #define FSTYPE_MAX 8 450Sstevel@tonic-gate 460Sstevel@tonic-gate #define VFS_PATH "/usr/lib/fs" 470Sstevel@tonic-gate 48*821Sdh145677 #define EQ(X, Y, Z) !strncmp(X, Y, Z) 490Sstevel@tonic-gate #define NEWARG()\ 500Sstevel@tonic-gate (nargv[nargc++] = &argv[1][0],\ 51*821Sdh145677 nargc == ARGV_MAX ? perr("volcopy: too many arguments.\n") : 1) 520Sstevel@tonic-gate 530Sstevel@tonic-gate extern char *default_fstype(); 540Sstevel@tonic-gate 550Sstevel@tonic-gate char *nargv[ARGV_MAX]; 560Sstevel@tonic-gate int nargc = 2; 570Sstevel@tonic-gate 580Sstevel@tonic-gate char vfstab[] = VFSTAB; 590Sstevel@tonic-gate 60*821Sdh145677 static void doexec(char *fstype, char *nargv[]); 61*821Sdh145677 62*821Sdh145677 int 63*821Sdh145677 main(int argc, char **argv) 640Sstevel@tonic-gate { 65*821Sdh145677 char cc; 66*821Sdh145677 int ii, Vflg = 0, Fflg = 0; 67*821Sdh145677 char *fstype = NULL; 68*821Sdh145677 FILE *fd; 690Sstevel@tonic-gate struct vfstab vget, vref; 700Sstevel@tonic-gate 71*821Sdh145677 (void) setlocale(LC_ALL, ""); 720Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 73*821Sdh145677 #define TEXT_DOMAIN "SYS_TEST" 740Sstevel@tonic-gate #endif 750Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 760Sstevel@tonic-gate 770Sstevel@tonic-gate while (argc > 1 && argv[1][0] == '-') { 780Sstevel@tonic-gate if (EQ(argv[1], "-a", 2)) { 790Sstevel@tonic-gate NEWARG(); 800Sstevel@tonic-gate } else if (EQ(argv[1], "-e", 2)) { 810Sstevel@tonic-gate NEWARG(); 820Sstevel@tonic-gate } else if (EQ(argv[1], "-s", 2)) { 830Sstevel@tonic-gate NEWARG(); 840Sstevel@tonic-gate } else if (EQ(argv[1], "-y", 2)) { 850Sstevel@tonic-gate NEWARG(); 860Sstevel@tonic-gate } else if (EQ(argv[1], "-buf", 4)) { 870Sstevel@tonic-gate NEWARG(); 880Sstevel@tonic-gate } else if (EQ(argv[1], "-bpi", 4)) { 890Sstevel@tonic-gate NEWARG(); 900Sstevel@tonic-gate if ((cc = argv[1][4]) < '0' || cc > '9') { 910Sstevel@tonic-gate ++argv; 920Sstevel@tonic-gate --argc; 930Sstevel@tonic-gate NEWARG(); 940Sstevel@tonic-gate } 950Sstevel@tonic-gate } else if (EQ(argv[1], "-feet", 5)) { 960Sstevel@tonic-gate NEWARG(); 970Sstevel@tonic-gate if ((cc = argv[1][5]) < '0' || cc > '9') { 980Sstevel@tonic-gate ++argv; 990Sstevel@tonic-gate --argc; 1000Sstevel@tonic-gate NEWARG(); 1010Sstevel@tonic-gate } 1020Sstevel@tonic-gate } else if (EQ(argv[1], "-reel", 5)) { 1030Sstevel@tonic-gate NEWARG(); 1040Sstevel@tonic-gate if ((cc = argv[1][5]) < '0' || cc > '9') { 1050Sstevel@tonic-gate ++argv; 1060Sstevel@tonic-gate --argc; 1070Sstevel@tonic-gate NEWARG(); 1080Sstevel@tonic-gate } 1090Sstevel@tonic-gate } else if (EQ(argv[1], "-r", 2)) { /* 3b15 only */ 1100Sstevel@tonic-gate NEWARG(); 1110Sstevel@tonic-gate if ((cc = argv[1][2]) < '0' || cc > '9') { 1120Sstevel@tonic-gate ++argv; 1130Sstevel@tonic-gate --argc; 1140Sstevel@tonic-gate NEWARG(); 1150Sstevel@tonic-gate } 1160Sstevel@tonic-gate } else if (EQ(argv[1], "-block", 6)) { /* 3b15 only */ 1170Sstevel@tonic-gate NEWARG(); 1180Sstevel@tonic-gate if ((cc = argv[1][6]) < '0' || cc > '9') { 1190Sstevel@tonic-gate ++argv; 1200Sstevel@tonic-gate --argc; 1210Sstevel@tonic-gate NEWARG(); 1220Sstevel@tonic-gate } 1230Sstevel@tonic-gate } else if (EQ(argv[1], "-V", 2)) { 1240Sstevel@tonic-gate Vflg++; 1250Sstevel@tonic-gate } else if (EQ(argv[1], "-F", 2)) { 1260Sstevel@tonic-gate if (Fflg) 127*821Sdh145677 perr("volcopy: More than one" 128*821Sdh145677 "FSType specified.\n" 129*821Sdh145677 "Usage:\nvolcopy [-F FSType] [-V]" 130*821Sdh145677 " [current_options] [-o " 131*821Sdh145677 "specific_options] operands\n"); 1320Sstevel@tonic-gate Fflg++; 1330Sstevel@tonic-gate if (argv[1][2] == '\0') { 1340Sstevel@tonic-gate ++argv; 1350Sstevel@tonic-gate --argc; 1360Sstevel@tonic-gate if (argc == 1) 137*821Sdh145677 perr("Usage:\nvolcopy [-F FSType] [-V]" 138*821Sdh145677 " [current_options] [-o " 139*821Sdh145677 "specific_options] operands\n"); 1400Sstevel@tonic-gate fstype = &argv[1][0]; 1410Sstevel@tonic-gate } else 1420Sstevel@tonic-gate fstype = &argv[1][2]; 1430Sstevel@tonic-gate if (strlen(fstype) > FSTYPE_MAX) 144*821Sdh145677 perr("volcopy: FSType %s exceeds %d" 145*821Sdh145677 " characters\n", fstype, FSTYPE_MAX); 1460Sstevel@tonic-gate } else if (EQ(argv[1], "-o", 2)) { 1470Sstevel@tonic-gate NEWARG(); 1480Sstevel@tonic-gate if (argv[1][2] == '\0') { 1490Sstevel@tonic-gate ++argv; 1500Sstevel@tonic-gate --argc; 1510Sstevel@tonic-gate NEWARG(); 1520Sstevel@tonic-gate } 1530Sstevel@tonic-gate if (Fflg && strlen(fstype) > FSTYPE_MAX) 154*821Sdh145677 perr("volcopy: FSType %s exceeds %d " 155*821Sdh145677 "characters.\nUsage:\nvolcopy " 156*821Sdh145677 "[-F FSType] [-V] [current_options] " 157*821Sdh145677 "[-o specific_options] " 158*821Sdh145677 "operands\n", fstype, FSTYPE_MAX); 1590Sstevel@tonic-gate } else if (EQ(argv[1], "-nosh", 5)) { /* 3b15 only */ 1600Sstevel@tonic-gate NEWARG(); 161*821Sdh145677 } else if (EQ(argv[1], "-?", 2)) { 1620Sstevel@tonic-gate if (Fflg) { 1630Sstevel@tonic-gate nargv[2] = "-?"; 1640Sstevel@tonic-gate doexec(fstype, nargv); 165*821Sdh145677 } else { 166*821Sdh145677 perr("Usage:\nvolcopy [-F FSType] [-V] " 167*821Sdh145677 "[current_options] [-o " 168*821Sdh145677 "specific_options] operands\n"); 1690Sstevel@tonic-gate } 1700Sstevel@tonic-gate } else 171*821Sdh145677 perr("<%s> invalid option\nUsage:\n" 172*821Sdh145677 "volcopy [-F FSType] [-V] " 173*821Sdh145677 "[current_options] [-o " 174*821Sdh145677 "specific_options] operands\n", argv[1]); 1750Sstevel@tonic-gate ++argv; 1760Sstevel@tonic-gate --argc; 1770Sstevel@tonic-gate } /* argv[1][0] == '-' */ 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate if (argc != 6) /* if mandatory fields not present */ 180*821Sdh145677 perr("Usage:\nvolcopy [-F FSType] [-V] " 181*821Sdh145677 "[current_options] [-o " 182*821Sdh145677 "specific_options] operands\n"); 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate if (nargc + 5 >= ARGV_MAX) 1850Sstevel@tonic-gate perr("volcopy: too many arguments.\n"); 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate for (ii = 0; ii < 5; ii++) 1880Sstevel@tonic-gate nargv[nargc++] = argv[ii+1]; 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate if (fstype == NULL) { 1910Sstevel@tonic-gate if ((fd = fopen(vfstab, "r")) == NULL) 1920Sstevel@tonic-gate perr("volcopy: cannot open %s.\n", vfstab); 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate vfsnull(&vref); 1950Sstevel@tonic-gate vref.vfs_special = argv[2]; 1960Sstevel@tonic-gate ii = getvfsany(fd, &vget, &vref); 1970Sstevel@tonic-gate if (ii == -1) { 1980Sstevel@tonic-gate rewind(fd); 1990Sstevel@tonic-gate vfsnull(&vref); 2000Sstevel@tonic-gate vref.vfs_fsckdev = argv[2]; 2010Sstevel@tonic-gate ii = getvfsany(fd, &vget, &vref); 2020Sstevel@tonic-gate } 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate fclose(fd); 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate switch (ii) { 2070Sstevel@tonic-gate case -1: 2080Sstevel@tonic-gate fstype = default_fstype(argv[2]); 2090Sstevel@tonic-gate break; 2100Sstevel@tonic-gate case 0: 2110Sstevel@tonic-gate fstype = vget.vfs_fstype; 2120Sstevel@tonic-gate break; 2130Sstevel@tonic-gate case VFS_TOOLONG: 214*821Sdh145677 perr("volcopy: line in vfstab exceeds " 215*821Sdh145677 "%d characters\n", VFS_LINE_MAX-2); 2160Sstevel@tonic-gate break; 2170Sstevel@tonic-gate case VFS_TOOFEW: 2180Sstevel@tonic-gate perr("volcopy: line in vfstab has too few entries\n"); 2190Sstevel@tonic-gate break; 2200Sstevel@tonic-gate case VFS_TOOMANY: 2210Sstevel@tonic-gate perr("volcopy: line in vfstab has too many entries\n"); 2220Sstevel@tonic-gate break; 223*821Sdh145677 default: 224*821Sdh145677 break; 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate } 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate if (Vflg) { 2290Sstevel@tonic-gate printf("volcopy -F %s", fstype); 2300Sstevel@tonic-gate for (ii = 2; nargv[ii]; ii++) 2310Sstevel@tonic-gate printf(" %s", nargv[ii]); 2320Sstevel@tonic-gate printf("\n"); 2330Sstevel@tonic-gate exit(0); 2340Sstevel@tonic-gate } 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate doexec(fstype, nargv); 237*821Sdh145677 return (0); 2380Sstevel@tonic-gate } 2390Sstevel@tonic-gate 240*821Sdh145677 static void 241*821Sdh145677 doexec(char *fstype, char *nargv[]) 2420Sstevel@tonic-gate { 2430Sstevel@tonic-gate char full_path[PATH_MAX]; 2440Sstevel@tonic-gate char *vfs_path = VFS_PATH; 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate /* build the full pathname of the fstype dependent command. */ 2470Sstevel@tonic-gate sprintf(full_path, "%s/%s/volcopy", vfs_path, fstype); 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate /* set the new argv[0] to the filename */ 2500Sstevel@tonic-gate nargv[1] = "volcopy"; 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate /* Try to exec the fstype dependent portion of the mount. */ 2530Sstevel@tonic-gate execv(full_path, &nargv[1]); 2540Sstevel@tonic-gate if (errno == EACCES) { 255*821Sdh145677 perr("volcopy: cannot execute %s" 256*821Sdh145677 " - permission denied\n", full_path); 2570Sstevel@tonic-gate exit(1); 2580Sstevel@tonic-gate } 2590Sstevel@tonic-gate if (errno == ENOEXEC) { 2600Sstevel@tonic-gate nargv[0] = "sh"; 2610Sstevel@tonic-gate nargv[1] = full_path; 2620Sstevel@tonic-gate execv("/sbin/sh", &nargv[0]); 2630Sstevel@tonic-gate } 2640Sstevel@tonic-gate perr("volcopy: Operation not applicable for FSType %s\n", fstype); 2650Sstevel@tonic-gate exit(1); 2660Sstevel@tonic-gate } 2670Sstevel@tonic-gate 2680Sstevel@tonic-gate /* 2690Sstevel@tonic-gate * perr: Print error messages. 2700Sstevel@tonic-gate */ 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate static int 2730Sstevel@tonic-gate perr(const char *fmt, ...) 2740Sstevel@tonic-gate { 2750Sstevel@tonic-gate va_list ap; 2760Sstevel@tonic-gate 2770Sstevel@tonic-gate va_start(ap, fmt); 278*821Sdh145677 (void) vfprintf(stderr, gettext(fmt), ap); 2790Sstevel@tonic-gate va_end(ap); 2800Sstevel@tonic-gate exit(1); 2810Sstevel@tonic-gate return (0); 2820Sstevel@tonic-gate } 283