1 /* 2 * CDDL HEADER START 3 * 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 7 * with the License. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #include <stdio.h> 34 #include <limits.h> 35 #include <errno.h> 36 #include <stdarg.h> 37 #include <sys/vfstab.h> 38 39 #include <locale.h> 40 41 static int perr(const char *fmt, ...); 42 43 #define ARGV_MAX 1024 44 #define FSTYPE_MAX 8 45 46 #define VFS_PATH "/usr/lib/fs" 47 48 #define EQ(X, Y, Z) !strncmp(X, Y, Z) 49 #define NEWARG()\ 50 (nargv[nargc++] = &argv[1][0],\ 51 nargc == ARGV_MAX ? perr("volcopy: too many arguments.\n") : 1) 52 53 extern char *default_fstype(); 54 55 char *nargv[ARGV_MAX]; 56 int nargc = 2; 57 58 char vfstab[] = VFSTAB; 59 60 static void doexec(char *fstype, char *nargv[]); 61 62 int 63 main(int argc, char **argv) 64 { 65 char cc; 66 int ii, Vflg = 0, Fflg = 0; 67 char *fstype = NULL; 68 FILE *fd; 69 struct vfstab vget, vref; 70 71 (void) setlocale(LC_ALL, ""); 72 #if !defined(TEXT_DOMAIN) 73 #define TEXT_DOMAIN "SYS_TEST" 74 #endif 75 (void) textdomain(TEXT_DOMAIN); 76 77 while (argc > 1 && argv[1][0] == '-') { 78 if (EQ(argv[1], "-a", 2)) { 79 NEWARG(); 80 } else if (EQ(argv[1], "-e", 2)) { 81 NEWARG(); 82 } else if (EQ(argv[1], "-s", 2)) { 83 NEWARG(); 84 } else if (EQ(argv[1], "-y", 2)) { 85 NEWARG(); 86 } else if (EQ(argv[1], "-buf", 4)) { 87 NEWARG(); 88 } else if (EQ(argv[1], "-bpi", 4)) { 89 NEWARG(); 90 if ((cc = argv[1][4]) < '0' || cc > '9') { 91 ++argv; 92 --argc; 93 NEWARG(); 94 } 95 } else if (EQ(argv[1], "-feet", 5)) { 96 NEWARG(); 97 if ((cc = argv[1][5]) < '0' || cc > '9') { 98 ++argv; 99 --argc; 100 NEWARG(); 101 } 102 } else if (EQ(argv[1], "-reel", 5)) { 103 NEWARG(); 104 if ((cc = argv[1][5]) < '0' || cc > '9') { 105 ++argv; 106 --argc; 107 NEWARG(); 108 } 109 } else if (EQ(argv[1], "-r", 2)) { /* 3b15 only */ 110 NEWARG(); 111 if ((cc = argv[1][2]) < '0' || cc > '9') { 112 ++argv; 113 --argc; 114 NEWARG(); 115 } 116 } else if (EQ(argv[1], "-block", 6)) { /* 3b15 only */ 117 NEWARG(); 118 if ((cc = argv[1][6]) < '0' || cc > '9') { 119 ++argv; 120 --argc; 121 NEWARG(); 122 } 123 } else if (EQ(argv[1], "-V", 2)) { 124 Vflg++; 125 } else if (EQ(argv[1], "-F", 2)) { 126 if (Fflg) 127 perr("volcopy: More than one" 128 "FSType specified.\n" 129 "Usage:\nvolcopy [-F FSType] [-V]" 130 " [current_options] [-o " 131 "specific_options] operands\n"); 132 Fflg++; 133 if (argv[1][2] == '\0') { 134 ++argv; 135 --argc; 136 if (argc == 1) 137 perr("Usage:\nvolcopy [-F FSType] [-V]" 138 " [current_options] [-o " 139 "specific_options] operands\n"); 140 fstype = &argv[1][0]; 141 } else 142 fstype = &argv[1][2]; 143 if (strlen(fstype) > FSTYPE_MAX) 144 perr("volcopy: FSType %s exceeds %d" 145 " characters\n", fstype, FSTYPE_MAX); 146 } else if (EQ(argv[1], "-o", 2)) { 147 NEWARG(); 148 if (argv[1][2] == '\0') { 149 ++argv; 150 --argc; 151 NEWARG(); 152 } 153 if (Fflg && strlen(fstype) > FSTYPE_MAX) 154 perr("volcopy: FSType %s exceeds %d " 155 "characters.\nUsage:\nvolcopy " 156 "[-F FSType] [-V] [current_options] " 157 "[-o specific_options] " 158 "operands\n", fstype, FSTYPE_MAX); 159 } else if (EQ(argv[1], "-nosh", 5)) { /* 3b15 only */ 160 NEWARG(); 161 } else if (EQ(argv[1], "-?", 2)) { 162 if (Fflg) { 163 nargv[2] = "-?"; 164 doexec(fstype, nargv); 165 } else { 166 perr("Usage:\nvolcopy [-F FSType] [-V] " 167 "[current_options] [-o " 168 "specific_options] operands\n"); 169 } 170 } else 171 perr("<%s> invalid option\nUsage:\n" 172 "volcopy [-F FSType] [-V] " 173 "[current_options] [-o " 174 "specific_options] operands\n", argv[1]); 175 ++argv; 176 --argc; 177 } /* argv[1][0] == '-' */ 178 179 if (argc != 6) /* if mandatory fields not present */ 180 perr("Usage:\nvolcopy [-F FSType] [-V] " 181 "[current_options] [-o " 182 "specific_options] operands\n"); 183 184 if (nargc + 5 >= ARGV_MAX) 185 perr("volcopy: too many arguments.\n"); 186 187 for (ii = 0; ii < 5; ii++) 188 nargv[nargc++] = argv[ii+1]; 189 190 if (fstype == NULL) { 191 if ((fd = fopen(vfstab, "r")) == NULL) 192 perr("volcopy: cannot open %s.\n", vfstab); 193 194 vfsnull(&vref); 195 vref.vfs_special = argv[2]; 196 ii = getvfsany(fd, &vget, &vref); 197 if (ii == -1) { 198 rewind(fd); 199 vfsnull(&vref); 200 vref.vfs_fsckdev = argv[2]; 201 ii = getvfsany(fd, &vget, &vref); 202 } 203 204 fclose(fd); 205 206 switch (ii) { 207 case -1: 208 fstype = default_fstype(argv[2]); 209 break; 210 case 0: 211 fstype = vget.vfs_fstype; 212 break; 213 case VFS_TOOLONG: 214 perr("volcopy: line in vfstab exceeds " 215 "%d characters\n", VFS_LINE_MAX-2); 216 break; 217 case VFS_TOOFEW: 218 perr("volcopy: line in vfstab has too few entries\n"); 219 break; 220 case VFS_TOOMANY: 221 perr("volcopy: line in vfstab has too many entries\n"); 222 break; 223 default: 224 break; 225 } 226 } 227 228 if (Vflg) { 229 printf("volcopy -F %s", fstype); 230 for (ii = 2; nargv[ii]; ii++) 231 printf(" %s", nargv[ii]); 232 printf("\n"); 233 exit(0); 234 } 235 236 doexec(fstype, nargv); 237 return (0); 238 } 239 240 static void 241 doexec(char *fstype, char *nargv[]) 242 { 243 char full_path[PATH_MAX]; 244 char *vfs_path = VFS_PATH; 245 246 /* build the full pathname of the fstype dependent command. */ 247 sprintf(full_path, "%s/%s/volcopy", vfs_path, fstype); 248 249 /* set the new argv[0] to the filename */ 250 nargv[1] = "volcopy"; 251 252 /* Try to exec the fstype dependent portion of the mount. */ 253 execv(full_path, &nargv[1]); 254 if (errno == EACCES) { 255 perr("volcopy: cannot execute %s" 256 " - permission denied\n", full_path); 257 exit(1); 258 } 259 if (errno == ENOEXEC) { 260 nargv[0] = "sh"; 261 nargv[1] = full_path; 262 execv("/sbin/sh", &nargv[0]); 263 } 264 perr("volcopy: Operation not applicable for FSType %s\n", fstype); 265 exit(1); 266 } 267 268 /* 269 * perr: Print error messages. 270 */ 271 272 static int 273 perr(const char *fmt, ...) 274 { 275 va_list ap; 276 277 va_start(ap, fmt); 278 (void) vfprintf(stderr, gettext(fmt), ap); 279 va_end(ap); 280 exit(1); 281 return (0); 282 } 283