1 /* @(#)pax.c	1.43 20/05/24 Copyright 1989, 2003-2020 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	const char _p_sccsid[] =
5 	"@(#)pax.c	1.43 20/05/24 Copyright 1989, 2003-2020 J. Schilling";
6 #endif
7 /*
8  *	PAX specific routines for star main program.
9  *
10  *	Copyright (c) 1989, 2003-2020 J. Schilling
11  */
12 /*
13  * The contents of this file are subject to the terms of the
14  * Common Development and Distribution License, Version 1.0 only
15  * (the "License").  You may not use this file except in compliance
16  * with the License.
17  *
18  * See the file CDDL.Schily.txt in this distribution for details.
19  * A copy of the CDDL is also available via the Internet at
20  * http://www.opensource.org/licenses/cddl1.txt
21  *
22  * When distributing Covered Code, include this CDDL HEADER in each
23  * file and include the License file CDDL.Schily.txt from this distribution.
24  */
25 
26 #ifdef	STAR_MAIN
27 /*
28  * We have been included from star.c
29  */
30 #define	opts		pax_opts
31 #define	_opts		_pax_opts
32 #define	gargs		pax_gargs
33 #define	susage		pax_susage
34 #define	usage		pax_usage
35 #define	xusage		pax_xusage
36 #else
37 #define	NO_STAR_MAIN
38 #define	PAX_MAIN
39 #define	PTYPE_DEFAULT	P_PAX
40 
41 #include "star.c"
42 #endif
43 
44 LOCAL	void	gargs		__PR((int ac, char *const *av));
45 LOCAL	void	susage		__PR((int ret));
46 LOCAL	void	usage		__PR((int ret));
47 LOCAL	void	xusage		__PR((int ret));
48 #ifdef	STAR_MAIN
49 LOCAL	void	pax_setopts	__PR((char *o));
50 #endif
51 
52 /*
53  *	-r	Read					tar x
54  *	-w	Write					tar c
55  *	-a	Append -w -a				tar r
56  *		Update -w -a -u				tar u
57  *
58  *	-b	Blocksize in Bytes
59  *	-c	Invert match for pattern and files
60  *	-d	Do not descend dirs
61  *	-f	Archive File
62  *	-i	Interactive Rename
63  *	-k	Noklobber
64  *	-l	Create hard links in copy mode
65  *	-n	Select first archive member per pattern only
66  *	-o	Future Options
67  *	-p	Privilleges:
68  *		e	everything
69  *		a	Do NOT preserve access	time
70  *		m	Do NOT preserve mod	time
71  *		o	Preserve UID/GID
72  *		p	Preserve perm
73  *	-s	Substitution
74  *	-t	Reset access time
75  *	-u	Gegenteil von -U
76  *	-v	List Verbose
77  *	-x	Archive Format
78  *	-X	Wie star -M
79  *
80  *	-H	SUSv3
81  *	-L	SUSv3
82  */
83 
84 /*
85  * PAX related options
86  *
87  * The official POSIX options start after the -bz/-lzo/-7z/-xz/-lzip/-zstd option.
88  */
89 /* BEGIN CSTYLED */
90 char	_opts[] = "help,xhelp,version,debug,xdebug#,xd#,time,no-statistics,do-statistics,fifostats,numeric,no-fifo,no-fsync,do-fsync%0,bs&,fs&,/,..,secure-links,no-secure-links%0,acl,xfflags,z,bz,lzo,7z,xz,lzip,zstd,r,w,a,b&,c,d,f&,H,i,k,L,l,n,o*,p&,s&,t,u,v+,x&,artype&,X";
91 /* END CSTYLED */
92 char	*opts = _opts;
93 #ifdef	NO_STAR_MAIN
94 struct ga_props	gaprops;
95 #endif
96 
97 LOCAL	void	pax_info	__PR((void));
98 
99 LOCAL void
gargs(ac,av)100 gargs(ac, av)
101 	int		ac;
102 	char	*const *av;
103 {
104 	int	files	 = 0;
105 	BOOL	help	 = FALSE;
106 	BOOL	xhelp	 = FALSE;
107 	BOOL	prvers	 = FALSE;
108 	BOOL	no_fifo	 = FALSE;
109 	BOOL	paxrflag = FALSE;
110 	BOOL	paxwflag = FALSE;
111 	BOOL	paxaflag = FALSE;
112 	BOOL	paxtflag = FALSE;
113 	BOOL	paxdflag = FALSE;
114 	BOOL	paxiflag = FALSE;
115 	BOOL	paxlflag = FALSE;
116 	char	*paxopts = NULL;
117 	BOOL	paxuflag = FALSE;
118 	BOOL	do_stats = FALSE;
119 
120 	/*
121 	 * Current default archive format in all other cases is USTAR.
122 	 * We may change this to PAX in the future.
123 	 */
124 	hdrtype = H_USTAR;
125 #ifdef	STAR_MAIN
126 	pax_setopts(opts);			/* set up opts for getfiles */
127 #endif
128 	getarginit(&gaprops, GAF_SINGLEARG);	/* POSIX combined args	  */
129 
130 	iftype		= I_PAX;		/* command line interface */
131 	ptype		= P_PAX;		/* program interface type */
132 	paxls		= TRUE;
133 	paxmatch	= TRUE;
134 	nopflag		= TRUE;			/* pax default */
135 	no_fsync	= TRUE;			/* -no-fsync		   */
136 	no_stats	= TRUE;			/* -no-statitstics	   */
137 	nochown		= TRUE;			/* chown only with -po / -pe */
138 
139 	if (pname) {				/* cli=xxx seen as argv[1] */
140 		--ac, av++;
141 	}
142 	--ac, ++av;
143 	files = getfilecount(ac, av, opts);
144 	if (getlallargs(&ac, &av, &gaprops, opts,
145 				&help, &xhelp, &prvers, &debug, &xdebug, &xdebug,
146 #ifndef	__old__lint
147 				&showtime, &no_stats, & do_stats, &do_fifostats,
148 				&numeric,  &no_fifo, &no_fsync, &no_fsync,
149 				getenum, &bs,
150 				getenum, &fs,
151 				&abs_path, &allow_dotdot,
152 				&secure_links, &secure_links,
153 				&doacl, &dofflags,
154 				&zflag, &bzflag, &lzoflag,
155 				&p7zflag, &xzflag, &lzipflag, &zstdflag,
156 				&paxrflag,
157 				&paxwflag,
158 				&paxaflag,
159 				getenum, &bs,
160 				&notarg,		/* -c */
161 				&paxdflag,		/* -d */
162 				addtarfile, NULL,	/* -f */
163 				&paxHflag,		/* -H */
164 				&paxiflag,		/* -i */
165 				&keep_old,		/* -k */
166 				&paxfollow,		/* -L */
167 				&paxlflag,		/* -l */
168 				&paxnflag,		/* -n */
169 				&paxopts,		/* -o */
170 				getpaxpriv, NULL,	/* -p */
171 				paxpsubst, &do_subst,	/* -s */
172 				&paxtflag,		/* -t */
173 				&paxuflag,		/* -u */
174 				&verbose,		/* -v */
175 				gethdr, &chdrtype,	/* -x */
176 				gethdr, &chdrtype,	/* artype= */
177 #endif /* __old__lint */
178 				&nomount) < 0) {
179 		errmsgno(EX_BAD, "Bad Option: %s.\n", av[0]);
180 		susage(EX_BAD);
181 	}
182 	star_helpvers("spax", help, xhelp, prvers);
183 
184 	if (!paxrflag && !paxwflag) {
185 		tflag = TRUE;
186 	} else if (paxrflag && paxwflag) {
187 		copyflag = TRUE;
188 		if (files == 1)
189 			listfile = "-";
190 	} else if (paxwflag && paxaflag) {
191 		if (paxuflag)
192 			uflag = TRUE;
193 		else
194 			rflag = TRUE;
195 	} else if (paxwflag) {
196 		cflag = TRUE;
197 		if (files == 0)
198 			listfile = "-";
199 	} else {
200 		xflag = TRUE;
201 	}
202 
203 	if ((cflag || uflag || rflag || copyflag) && paxtflag)
204 		acctime = TRUE;
205 
206 	if (paxdflag) {
207 		/* XXX nodesc aber mit pattern match bei extract */
208 		nodesc = TRUE;
209 	}
210 	if (paxiflag) {
211 		interactive = TRUE;
212 		paxinteract = TRUE;
213 	}
214 	if (paxlflag) {
215 		/* link bei -copy */
216 		errmsgno(EX_BAD, "Unsupported option -l.\n");
217 		susage(EX_BAD);
218 	}
219 	uncond = !paxuflag;
220 
221 	if (do_stats)
222 		no_stats = FALSE;
223 
224 	star_checkopts(/* oldtar */ FALSE, /* dodesc */ TRUE,
225 				/* usetape */ FALSE,
226 				/* archive */ -1, no_fifo,
227 				paxopts,
228 				/* llbs */ 0);
229 
230 	nolinkerr = FALSE;
231 }
232 
233 LOCAL void
pax_info()234 pax_info()
235 {
236 	const	char	*n = pname ? pname : get_progname();
237 
238 	error("\nFor a more complete user interface use the tar type command interface.\n");
239 	error("See 'man star'. The %s command is more or less limited to the\n", n);
240 	error("POSIX standard pax command line interface.\n");
241 }
242 
243 /*
244  * Short usage
245  */
246 LOCAL void
susage(ret)247 susage(ret)
248 	int	ret;
249 {
250 	const	char	*n = pname ? pname : get_progname();
251 
252 	error("Usage:\t%s cmd [options] file1 ... filen\n", n);
253 	error("\nUse\t%s -help\n", n);
254 	error("and\t%s -xhelp\n", n);
255 	error("to get a list of valid cmds and options.\n");
256 	error("\nUse\t%s -x help\n", n);
257 	error("to get a list of valid archive header formats.\n");
258 	pax_info();
259 	exit(ret);
260 	/* NOTREACHED */
261 }
262 
263 LOCAL void
usage(ret)264 usage(ret)
265 	int	ret;
266 {
267 	const	char	*n = pname ? pname : get_progname();
268 
269 	error("Usage:\t%s cmd [options] file1 ... filen\n", n);
270 	error("Cmd:\n");
271 	error("\t<none>\t\tlist named files from tape\n");
272 	error("\t-r\t\textract named files from tape\n");
273 	error("\t-w\t\twrite archive with named files to tape\n");
274 	error("\t-w -a\t\tupdate/replace named files to tape\n");
275 	error("\t-r -w\t\tcopy named files to destination directory\n");
276 	error("Options:\n");
277 	error("\t-help\t\t(*) print this help\n");
278 	error("\t-xhelp\t\t(*) print extended help\n");
279 	error("\t-version\t(*) print version information and exit\n");
280 	error("\t-b #\t\tset blocking factor to # Bytes (default 10240)\n");
281 	error("\t-c\t\tinvert matching rules\n");
282 	error("\t-d\t\tdo not descend directories\n");
283 	error("\t-f nm\t\tuse 'nm' as tape instead of stdin/stdout\n");
284 	error("\t-H\t\tfollow symbolic links from cmdline as if they were files\n");
285 	error("\t-i\t\tdo interactive creation/extraction/renaming\n");
286 	error("\t-k\t\tkeep existing files\n");
287 	error("\t-l\t\tlink files rather than copying them\n");
288 	error("\t-L\t\tfollow symbolic links as if they were files\n");
289 	error("\t-n\t\tone match per pattern only\n");
290 	error("\t-o\t\toptions (none specified with SUSv2 / UNIX-98)\n");
291 	error("\t-p string\tset privileges\n");
292 	error("\t-s replstr\tApply ed like pattern substitution -s /old/new/gp on filenames\n");
293 	error("\t-t\t\trestore atime after reading files\n");
294 	error("\t-u\t\treplace/restore files only if they are newer\n");
295 	error("\t-v\t\tincrement verbose level\n");
296 	error("\t-x header\tgenerate 'header' type archive (see -x help)\n");
297 	error("\tartype=header\t(*) generate 'header' type archive (see artype=help)\n");
298 	error("\t-X\t\tdo not descend mounting points\n");
299 	error("\t-z\t\t(*) pipe input/output through gzip, does not work on tapes\n");
300 	error("\t-bz\t\t(*) pipe input/output through bzip2, does not work on tapes\n");
301 	error("\t-lzo\t\t(*) pipe input/output through lzop, does not work on tapes\n");
302 	error("\t-7z\t\t(*) pipe input/output through p7zip, does not work on tapes\n");
303 	error("\t-xz\t\t(*) pipe input/output through xz, does not work on tapes\n");
304 	error("\t-lzip\t\t(*) pipe input/output through lzip, does not work on tapes\n");
305 	error("\t-zstd\t\t(*) pipe input/output through zstd, does not work on tapes\n");
306 #ifdef	FIFO
307 	error("\t-no-fifo\t(*) don't use a fifo to optimize data flow from/to tape\n");
308 #endif
309 	error("\nAll options marked with (*) are not defined by POSIX.\n");
310 	pax_info();
311 	exit(ret);
312 	/* NOTREACHED */
313 }
314 
315 LOCAL void
xusage(ret)316 xusage(ret)
317 	int	ret;
318 {
319 	const	char	*n = pname ? pname : get_progname();
320 
321 	error("Usage:\t%s cmd [options] file1 ... filen\n", n);
322 	error("Extended options:\n");
323 	error("\t-debug\t\tprint additional debug messages\n");
324 	error("\txdebug=#,xd=#\tset extended debug level\n");
325 	error("\t-/\t\tdon't strip leading '/'s from file names\n");
326 	error("\t-..\t\tdon't skip filenames that contain '..' in non-interactive extract\n");
327 	error("\t-secure-links\tdon't extract links that start with '/' or contain '..' (default)\n");
328 	error("\t-no-secure-links\textract links that start with '/' or contain '..'\n");
329 	error("\t-acl\t\thandle access control lists\n");
330 	error("\t-xfflags\thandle extended file flags\n");
331 	error("\tbs=#\t\tset (output) block size to #\n");
332 #ifdef	FIFO
333 	error("\tfs=#\t\tset fifo size to #\n");
334 #endif
335 	error("\t-no-fsync\tdo not call fsync() for each extracted file (may be dangerous)\n");
336 	error("\t-do-fsync\tcall fsync() for each extracted file\n");
337 	error("\t-time\t\tprint timing info\n");
338 	error("\t-no-statistics\tdo not print statistics\n");
339 	error("\t-do-statistics\tprint statistics\n");
340 #ifdef	FIFO
341 	error("\t-fifostats\tprint fifo statistics\n");
342 #endif
343 	error("\t-numeric\tdon't use user/group name from tape\n");
344 	error("\nAll options above are not defined by POSIX.\n");
345 	exit(ret);
346 	/* NOTREACHED */
347 }
348 
349 #ifdef	STAR_MAIN
350 #undef	opts
351 #undef	_opts
352 #undef	gargs
353 #undef	susage
354 #undef	usage
355 #undef	xusage
356 
357 LOCAL void
pax_setopts(o)358 pax_setopts(o)
359 	char	*o;
360 {
361 extern	char	*opts;
362 	opts = o;
363 }
364 #endif
365