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