xref: /plan9/sys/src/ape/9src/tar.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1 /*
2  * Attempt at emulation of Unix tar by calling Plan 9 tar.
3  *
4  * The differences from Plan 9 tar are:
5  *	In the absence of an "f" flag, the file /dev/tape is used.
6  *	An "f" flag with argument "-" causes use of stdin/stdout
7  *		by passing no "f" flag (nor argument) to Plan 9 tar.
8  *	By default, the "T" flag is passed to Plan 9 tar.
9  *		The "m" flag to this tar inhibits this behavior.
10  */
11 
12 #include <u.h>
13 #include <libc.h>
14 
15 void
usage(void)16 usage(void)
17 {
18 	fprint(2, "usage: ape/tar [crtx][vfm] [args...] [file...]\n");
19 	exits("usage");
20 }
21 
22 void
main(int argc,char ** argv)23 main(int argc, char **argv)
24 {
25 	int i, j, verb, vflag, fflag, Tflag, nargc;
26 	char *p, *file, **nargv, *cpu, flagbuf[10], execbuf[128];
27 	Waitmsg *w;
28 
29 	argv++, argc--;
30 	if(argc < 1)
31 		usage();
32 
33 	p = argv[0];
34 	argv++, argc--;
35 
36 	if(*p == '-')
37 		p++;
38 
39 	if(strchr("crtx", *p) == nil)
40 		usage();
41 	verb = *p++;
42 
43 	/* unix defaults */
44 	fflag = 1;
45 	file = "/dev/tape";
46 	Tflag = 1;
47 	vflag = 0;
48 
49 	for(; *p; p++) {
50 		switch(*p) {
51 		default:
52 			usage();
53 		case 'v':
54 			vflag = 1;
55 			break;
56 		case 'f':
57 			if(argc <= 0)
58 				usage();
59 
60 			fflag = 1;
61 			file = argv[0];
62 			argv++, argc--;
63 			if(strcmp(file, "-") == 0) {
64 				/*
65 				 * plan9 doesn't know about "-" meaning stdin/stdout,
66 				 * but it's the default,
67 				 * so rewrite to not use f flag at all.
68 				 */
69 				file = nil;
70 				fflag = 0;
71 			}
72 			break;
73 		case 'm':
74 			Tflag = 0;
75 			break;
76 		case 'p':		/* pretend nothing's wrong */
77 			break;
78 		}
79 	}
80 
81 	nargc = 1 + 1 + fflag + argc + 1;
82 	nargv = malloc(sizeof(char*) * nargc);
83 	if(nargv == nil) {
84 		fprint(2, "ape/tar: out of memory\n");
85 		exits("memory");
86 	}
87 
88 	cpu = getenv("cputype");
89 	if(cpu == nil) {
90 		fprint(2, "ape/tar: need cputype environment variable set\n");
91 		exits("cputype");
92 	}
93 	snprint(execbuf, sizeof execbuf, "/%s/bin/tar", cpu);
94 
95 	nargv[0] = "tar";
96 	sprint(flagbuf, "%c%s%s%s", verb, vflag ? "v" : "", Tflag ? "T" : "", fflag ? "f" : "");
97 	nargv[1] = flagbuf;
98 
99 	i = 2;
100 	if(fflag)
101 		nargv[i++] = file;
102 
103 	for(j=0; j<argc; j++, i++)
104 		nargv[i] = argv[j];
105 
106 	nargv[i++] = nil;
107 	assert(i == nargc);
108 
109 	switch(fork()){
110 	case -1:
111 		fprint(2, "ape/tar: fork failed: %r\n");
112 		exits("fork");
113 	case 0:
114 		exec(execbuf, nargv);
115 		fprint(2, "exec %s fails: %r\n", execbuf);
116 		_exits("exec");
117 	default:
118 		w = wait();
119 		if(w == nil)
120 			exits("wait failed");
121 		if(w->msg[0] == '\0')
122 			exits(nil);
123 		else
124 			exits(w->msg);
125 	}
126 	assert(0);
127 }
128