1 /*
2  * cpio - copy file archives in and out
3  *
4  * Gunnar Ritter, Freiburg i. Br., Germany, April 2003.
5  */
6 /*
7  * Copyright (c) 2003 Gunnar Ritter
8  *
9  * This software is provided 'as-is', without any express or implied
10  * warranty. In no event will the authors be held liable for any damages
11  * arising from the use of this software.
12  *
13  * Permission is granted to anyone to use this software for any purpose,
14  * including commercial applications, and to alter it and redistribute
15  * it freely, subject to the following restrictions:
16  *
17  * 1. The origin of this software must not be misrepresented; you must not
18  *    claim that you wrote the original software. If you use this software
19  *    in a product, an acknowledgment in the product documentation would be
20  *    appreciated but is not required.
21  *
22  * 2. Altered source versions must be plainly marked as such, and must not be
23  *    misrepresented as being the original software.
24  *
25  * 3. This notice may not be removed or altered from any source distribution.
26  */
27 
28 /*	Sccsid @(#)flags.c	1.6 (gritter) 3/26/07	*/
29 
30 #include <unistd.h>
31 #include <stdio.h>
32 #include <stdarg.h>
33 #include <stdlib.h>
34 
35 #include "cpio.h"
36 
37 void
flags(int ac,char ** av)38 flags(int ac, char **av)
39 {
40 	const char	optstring[] =
41 		"iopaAbBcC:dDeE:fH:I:kKlLmM:O:PrR:sStTuvV6";
42 	int	i, illegal = 0;
43 
44 	if (getenv("SYSV3") != NULL)
45 		sysv3 = printsev = 1;
46 	while ((i = getopt(ac, av, optstring)) != EOF) {
47 		switch (i) {
48 		case 'i':
49 		case 'o':
50 		case 'p':
51 			if (action && action != i)
52 				illegal = 1;
53 			action = i;
54 			break;
55 		case 'a':
56 			aflag = 1;
57 			break;
58 		case 'A':
59 			Aflag = 1;
60 			break;
61 		case 'b':
62 			bflag = 1;
63 			break;
64 		case 'B':
65 			blksiz = 5120;
66 			Bflag = 1;
67 			break;
68 		case 'c':
69 			fmttype = sysv3 ? FMT_ODC : FMT_ASC;
70 			cflag = 1;
71 			break;
72 		case 'C':
73 			if ((blksiz = atol(optarg)) <= 0)
74 				msg(4, -2,
75 					"Illegal size given for -C option.\n");
76 			Cflag = 1;
77 			break;
78 		case 'd':
79 			dflag = 1;
80 			break;
81 		case 'D':
82 			Dflag = 1;
83 			break;
84 		case 'e':
85 			/*
86 			 * This option is accepted for compatibility only,
87 			 * -Hdec should be used instead.
88 			 */
89 			fmttype = FMT_DEC;
90 			eflag = 1;
91 			break;
92 		case 'E':
93 			Eflag = optarg;
94 			break;
95 		case 'f':
96 			fflag = 1;
97 			break;
98 		case 'H':
99 			if (setfmt(optarg) < 0)
100 				illegal = 1;
101 			Hflag = 1;
102 			break;
103 		case 'I':
104 			Iflag = optarg;
105 			break;
106 		case 'k':
107 			kflag = 1;
108 			break;
109 		case 'K':
110 			/*
111 			 * This option is accepted for compatibility only,
112 			 * -Hsgi should be used instead.
113 			 */
114 			fmttype = FMT_SGIBE;
115 			Kflag = 1;
116 			break;
117 		case 'l':
118 			lflag = 1;
119 			break;
120 		case 'L':
121 			Lflag = 1;
122 			break;
123 		case 'm':
124 			mflag = 1;
125 			break;
126 		case 'M':
127 			Mflag = oneintfmt(optarg);
128 			break;
129 		case 'O':
130 			Oflag = optarg;
131 			break;
132 		case 'P':
133 			Pflag = 1;
134 			break;
135 		case 'r':
136 			rflag = 1;
137 			break;
138 		case 'R':
139 			if (setreassign(Rflag = optarg) < 0)
140 				illegal = 1;
141 			break;
142 		case 's':
143 			sflag = 1;
144 			break;
145 		case 'S':
146 			Sflag = 1;
147 			break;
148 		case 't':
149 			tflag = 1;
150 			break;
151 		case 'u':
152 			uflag = 1;
153 			break;
154 		case 'v':
155 			vflag++;
156 			break;
157 		case 'V':
158 			Vflag = 1;
159 			break;
160 		case '6':
161 			sixflag = 1;
162 			fmttype = FMT_BINLE;
163 			break;
164 		default:
165 			if (sysv3)
166 				usage();
167 			illegal = 1;
168 		}
169 	}
170 	switch (action) {
171 	case 'i':
172 		if (Oflag || Kflag || eflag || Lflag || lflag || aflag ||
173 				Aflag || Pflag)
174 			illegal = 1;
175 		for (i = optind; i < ac; i++)
176 			addg(av[i], 0);
177 		break;
178 	case 'o':
179 		if (Iflag || dflag || fflag || kflag || mflag ||
180 				rflag || tflag || uflag ||
181 				sixflag || Eflag || Rflag)
182 			illegal = 1;
183 		if (optind != ac)
184 			illegal = 1;
185 		break;
186 	case 'p':
187 		if (Iflag || Oflag || blksiz || Eflag || fmttype != FMT_NONE ||
188 				Mflag || bflag || fflag || kflag || sflag ||
189 				tflag || Sflag || sixflag)
190 			illegal = 1;
191 		if (optind + 1 != ac)
192 			illegal = 1;
193 		break;
194 	default:
195 		if (sysv3 == 0)
196 			msg(3, 0, "One of -i, -o or -p must be specified.\n");
197 		else if (ac > 1)
198 			msg(3, -2, "Options must include one: -o, -i, -p.\n");
199 		illegal = 1;
200 	}
201 	/*
202 	 * Sanity checks. No check for multiple occurences of options
203 	 * since they can make sense, behave as other programs and use
204 	 * the latter one.
205 	 */
206 	/*if (aflag && mflag) {
207 		msg(3, 0, "-a and -m are mutually exclusive.\n");
208 		illegal = 1;
209 	} why? */
210 	/*if (cflag && (Hflag || Kflag || eflag)) {
211 		msg(3, 0, "-c and -H are mutually exclusive.\n");
212 		illegal = 1;
213 	} allow overriding -c with -H and vice versa */
214 	if ((vflag || tflag) && Vflag) {
215 		msg(3, 0, "-v and -V are mutually exclusive.\n");
216 		illegal = 1;
217 	}
218 	/*if (Bflag && Cflag) {
219 		msg(3, 0, "-B and -C are mutually exclusive.\n");
220 		illegal = 1;
221 	} allow overriding of block sizes */
222 	if ((Hflag || cflag || Kflag || eflag) && sixflag) {
223 		msg(3, 0, "-H and -6 are mutually exclusive.\n");
224 		illegal = 1;
225 	}
226 	if (!sysv3 && Mflag && Oflag == NULL && Iflag == NULL) {
227 		msg(3, 0, "-M not meaningful without -O or -I.\n");
228 		illegal = 1;
229 	}
230 	if (!sysv3 && Aflag && Oflag == NULL) {
231 		msg(3, 0, "-A requires the -O option\n");
232 		illegal = 1;
233 	}
234 	if (illegal)
235 		usage();
236 }
237 
238 void
usage(void)239 usage(void)
240 {
241 	if (sysv3)
242 		fprintf(stderr, "\
243 Usage:  %s -o[acvVABL] [-Csize] [-Hhdr] [-Mmsg] <name-list >collection\n\
244 \t%s -o[acvVABL] -Ocollection [-Csize] [-Hhdr] [-Mmsg] <name-list\n\
245 \t%s -i[bcdkmrsStuvVfB6] [-Csize] [-Efile] [-Hhdr] [-Mmsg] [-Rid] [pattern ...] <collection\n\
246 \t%s -i[bcdkmrsStuvVfB6] -Icollection [-Csize] [-Efile] [-Hhdr] [-Mmsg] [-Rid] [pattern ...]\n\
247 \t%s -p[adlmruvVL] [-Rid] directory <name-list\n",
248 			progname, progname, progname, progname, progname);
249 	else
250 		fprintf(stderr, "USAGE:\n\
251 \t%s -i[bcdfkmrstuvBSV6] [-C size] [-E file] [-H hdr] [[-I file] [-M msg]] \
252 [-R id] [patterns]\n\
253 \t%s -o[acvABLV] [-C size] [-H hdr] [[-M msg] [-O file]]\n\
254 \t%s -p[adlmuvLV] [-R id] directory\n",
255 			progname, progname, progname);
256 	exit(1);
257 }
258