xref: /plan9/sys/src/ape/9src/tar.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
17dd7cddfSDavid du Colombier /*
27dd7cddfSDavid du Colombier  * Attempt at emulation of Unix tar by calling Plan 9 tar.
37dd7cddfSDavid du Colombier  *
47dd7cddfSDavid du Colombier  * The differences from Plan 9 tar are:
57dd7cddfSDavid du Colombier  *	In the absence of an "f" flag, the file /dev/tape is used.
67dd7cddfSDavid du Colombier  *	An "f" flag with argument "-" causes use of stdin/stdout
77dd7cddfSDavid du Colombier  *		by passing no "f" flag (nor argument) to Plan 9 tar.
87dd7cddfSDavid du Colombier  *	By default, the "T" flag is passed to Plan 9 tar.
97dd7cddfSDavid du Colombier  *		The "m" flag to this tar inhibits this behavior.
107dd7cddfSDavid du Colombier  */
117dd7cddfSDavid du Colombier 
127dd7cddfSDavid du Colombier #include <u.h>
137dd7cddfSDavid du Colombier #include <libc.h>
147dd7cddfSDavid du Colombier 
157dd7cddfSDavid du Colombier void
usage(void)167dd7cddfSDavid du Colombier usage(void)
177dd7cddfSDavid du Colombier {
187dd7cddfSDavid du Colombier 	fprint(2, "usage: ape/tar [crtx][vfm] [args...] [file...]\n");
197dd7cddfSDavid du Colombier 	exits("usage");
207dd7cddfSDavid du Colombier }
217dd7cddfSDavid du Colombier 
227dd7cddfSDavid du Colombier void
main(int argc,char ** argv)237dd7cddfSDavid du Colombier main(int argc, char **argv)
247dd7cddfSDavid du Colombier {
257dd7cddfSDavid du Colombier 	int i, j, verb, vflag, fflag, Tflag, nargc;
267dd7cddfSDavid du Colombier 	char *p, *file, **nargv, *cpu, flagbuf[10], execbuf[128];
27*9a747e4fSDavid du Colombier 	Waitmsg *w;
287dd7cddfSDavid du Colombier 
297dd7cddfSDavid du Colombier 	argv++, argc--;
307dd7cddfSDavid du Colombier 	if(argc < 1)
317dd7cddfSDavid du Colombier 		usage();
327dd7cddfSDavid du Colombier 
337dd7cddfSDavid du Colombier 	p = argv[0];
347dd7cddfSDavid du Colombier 	argv++, argc--;
357dd7cddfSDavid du Colombier 
367dd7cddfSDavid du Colombier 	if(*p == '-')
377dd7cddfSDavid du Colombier 		p++;
387dd7cddfSDavid du Colombier 
397dd7cddfSDavid du Colombier 	if(strchr("crtx", *p) == nil)
407dd7cddfSDavid du Colombier 		usage();
417dd7cddfSDavid du Colombier 	verb = *p++;
427dd7cddfSDavid du Colombier 
437dd7cddfSDavid du Colombier 	/* unix defaults */
447dd7cddfSDavid du Colombier 	fflag = 1;
457dd7cddfSDavid du Colombier 	file = "/dev/tape";
467dd7cddfSDavid du Colombier 	Tflag = 1;
477dd7cddfSDavid du Colombier 	vflag = 0;
487dd7cddfSDavid du Colombier 
497dd7cddfSDavid du Colombier 	for(; *p; p++) {
507dd7cddfSDavid du Colombier 		switch(*p) {
517dd7cddfSDavid du Colombier 		default:
527dd7cddfSDavid du Colombier 			usage();
537dd7cddfSDavid du Colombier 		case 'v':
547dd7cddfSDavid du Colombier 			vflag = 1;
557dd7cddfSDavid du Colombier 			break;
567dd7cddfSDavid du Colombier 		case 'f':
577dd7cddfSDavid du Colombier 			if(argc <= 0)
587dd7cddfSDavid du Colombier 				usage();
597dd7cddfSDavid du Colombier 
607dd7cddfSDavid du Colombier 			fflag = 1;
617dd7cddfSDavid du Colombier 			file = argv[0];
627dd7cddfSDavid du Colombier 			argv++, argc--;
637dd7cddfSDavid du Colombier 			if(strcmp(file, "-") == 0) {
647dd7cddfSDavid du Colombier 				/*
657dd7cddfSDavid du Colombier 				 * plan9 doesn't know about "-" meaning stdin/stdout,
667dd7cddfSDavid du Colombier 				 * but it's the default,
677dd7cddfSDavid du Colombier 				 * so rewrite to not use f flag at all.
687dd7cddfSDavid du Colombier 				 */
697dd7cddfSDavid du Colombier 				file = nil;
707dd7cddfSDavid du Colombier 				fflag = 0;
717dd7cddfSDavid du Colombier 			}
727dd7cddfSDavid du Colombier 			break;
737dd7cddfSDavid du Colombier 		case 'm':
747dd7cddfSDavid du Colombier 			Tflag = 0;
757dd7cddfSDavid du Colombier 			break;
76*9a747e4fSDavid du Colombier 		case 'p':		/* pretend nothing's wrong */
77*9a747e4fSDavid du Colombier 			break;
787dd7cddfSDavid du Colombier 		}
797dd7cddfSDavid du Colombier 	}
807dd7cddfSDavid du Colombier 
817dd7cddfSDavid du Colombier 	nargc = 1 + 1 + fflag + argc + 1;
827dd7cddfSDavid du Colombier 	nargv = malloc(sizeof(char*) * nargc);
837dd7cddfSDavid du Colombier 	if(nargv == nil) {
847dd7cddfSDavid du Colombier 		fprint(2, "ape/tar: out of memory\n");
857dd7cddfSDavid du Colombier 		exits("memory");
867dd7cddfSDavid du Colombier 	}
877dd7cddfSDavid du Colombier 
887dd7cddfSDavid du Colombier 	cpu = getenv("cputype");
897dd7cddfSDavid du Colombier 	if(cpu == nil) {
907dd7cddfSDavid du Colombier 		fprint(2, "ape/tar: need cputype environment variable set\n");
917dd7cddfSDavid du Colombier 		exits("cputype");
927dd7cddfSDavid du Colombier 	}
937dd7cddfSDavid du Colombier 	snprint(execbuf, sizeof execbuf, "/%s/bin/tar", cpu);
947dd7cddfSDavid du Colombier 
957dd7cddfSDavid du Colombier 	nargv[0] = "tar";
967dd7cddfSDavid du Colombier 	sprint(flagbuf, "%c%s%s%s", verb, vflag ? "v" : "", Tflag ? "T" : "", fflag ? "f" : "");
977dd7cddfSDavid du Colombier 	nargv[1] = flagbuf;
987dd7cddfSDavid du Colombier 
997dd7cddfSDavid du Colombier 	i = 2;
1007dd7cddfSDavid du Colombier 	if(fflag)
1017dd7cddfSDavid du Colombier 		nargv[i++] = file;
1027dd7cddfSDavid du Colombier 
1037dd7cddfSDavid du Colombier 	for(j=0; j<argc; j++, i++)
1047dd7cddfSDavid du Colombier 		nargv[i] = argv[j];
1057dd7cddfSDavid du Colombier 
1067dd7cddfSDavid du Colombier 	nargv[i++] = nil;
1077dd7cddfSDavid du Colombier 	assert(i == nargc);
1087dd7cddfSDavid du Colombier 
1097dd7cddfSDavid du Colombier 	switch(fork()){
1107dd7cddfSDavid du Colombier 	case -1:
1117dd7cddfSDavid du Colombier 		fprint(2, "ape/tar: fork failed: %r\n");
1127dd7cddfSDavid du Colombier 		exits("fork");
1137dd7cddfSDavid du Colombier 	case 0:
1147dd7cddfSDavid du Colombier 		exec(execbuf, nargv);
1157dd7cddfSDavid du Colombier 		fprint(2, "exec %s fails: %r\n", execbuf);
1167dd7cddfSDavid du Colombier 		_exits("exec");
1177dd7cddfSDavid du Colombier 	default:
118*9a747e4fSDavid du Colombier 		w = wait();
119*9a747e4fSDavid du Colombier 		if(w == nil)
120*9a747e4fSDavid du Colombier 			exits("wait failed");
121*9a747e4fSDavid du Colombier 		if(w->msg[0] == '\0')
1227dd7cddfSDavid du Colombier 			exits(nil);
1237dd7cddfSDavid du Colombier 		else
124*9a747e4fSDavid du Colombier 			exits(w->msg);
1257dd7cddfSDavid du Colombier 	}
1267dd7cddfSDavid du Colombier 	assert(0);
1277dd7cddfSDavid du Colombier }
128