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