Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
16
usage(void)
17
{
18
	fprint(2, "usage: ape/tar [crtx][vfm] [args...] [file...]\n");
19
	exits("usage");
20
}
21
 
22
void
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
}