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