xref: /illumos-gate/usr/src/cmd/fs.d/volcopy.c (revision fe4627ef755b7c263f91a0e6f07cdca5d7083501)
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