xref: /plan9-contrib/sys/src/cmd/upas/q/qer.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include "../libString/String.h"
43e12c5d1SDavid du Colombier 
5*219b2ee8SDavid du Colombier typedef struct Qfile Qfile;
6*219b2ee8SDavid du Colombier struct Qfile
7*219b2ee8SDavid du Colombier {
8*219b2ee8SDavid du Colombier 	Qfile	*next;
9*219b2ee8SDavid du Colombier 	char	*name;
10*219b2ee8SDavid du Colombier 	char	*tname;
11*219b2ee8SDavid du Colombier } *files;
12*219b2ee8SDavid du Colombier 
13*219b2ee8SDavid du Colombier int	copy(Qfile*);
14*219b2ee8SDavid du Colombier 
153e12c5d1SDavid du Colombier void
163e12c5d1SDavid du Colombier usage(void)
173e12c5d1SDavid du Colombier {
18*219b2ee8SDavid du Colombier 	fprint(2, "usage: qer [-f file] q-root description reply-to arg-list\n");
193e12c5d1SDavid du Colombier 	exits("usage");
203e12c5d1SDavid du Colombier }
213e12c5d1SDavid du Colombier 
223e12c5d1SDavid du Colombier void
233e12c5d1SDavid du Colombier error(char *f, char *a)
243e12c5d1SDavid du Colombier {
253e12c5d1SDavid du Colombier 	char err[ERRLEN+1];
263e12c5d1SDavid du Colombier 	char buf[256];
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier 	errstr(err);
293e12c5d1SDavid du Colombier 	sprint(buf, f, a);
303e12c5d1SDavid du Colombier 	fprint(2, "qer: %s: %s\n", buf, err);
313e12c5d1SDavid du Colombier 	exits(buf);
323e12c5d1SDavid du Colombier }
333e12c5d1SDavid du Colombier 
343e12c5d1SDavid du Colombier void
35*219b2ee8SDavid du Colombier main(int argc, char**argv)
363e12c5d1SDavid du Colombier {
373e12c5d1SDavid du Colombier 	Dir	dir;
383e12c5d1SDavid du Colombier 	String	*f, *c;
393e12c5d1SDavid du Colombier 	int	fd;
403e12c5d1SDavid du Colombier 	char	file[1024];
413e12c5d1SDavid du Colombier 	char	buf[1024];
423e12c5d1SDavid du Colombier 	long	n;
433e12c5d1SDavid du Colombier 	char	*cp;
443e12c5d1SDavid du Colombier 	int	i;
45*219b2ee8SDavid du Colombier 	Qfile	*q, **l;
463e12c5d1SDavid du Colombier 
47*219b2ee8SDavid du Colombier 	l = &files;
48*219b2ee8SDavid du Colombier 
49*219b2ee8SDavid du Colombier 	ARGBEGIN {
50*219b2ee8SDavid du Colombier 	case 'f':
51*219b2ee8SDavid du Colombier 		q = malloc(sizeof(Qfile));
52*219b2ee8SDavid du Colombier 		q->name = ARGF();
53*219b2ee8SDavid du Colombier 		q->next = *l;
54*219b2ee8SDavid du Colombier 		*l = q;
55*219b2ee8SDavid du Colombier 		break;
56*219b2ee8SDavid du Colombier 	default:
57*219b2ee8SDavid du Colombier 		usage();
58*219b2ee8SDavid du Colombier 	} ARGEND;
59*219b2ee8SDavid du Colombier 
60*219b2ee8SDavid du Colombier 	if(argc < 3)
613e12c5d1SDavid du Colombier 		usage();
623e12c5d1SDavid du Colombier 
63*219b2ee8SDavid du Colombier 	sprint(file, "%s/%s", argv[0], getuser());
643e12c5d1SDavid du Colombier 
653e12c5d1SDavid du Colombier 	if(dirstat(file, &dir) < 0){
663e12c5d1SDavid du Colombier 		if((fd = create(file, OREAD, CHDIR|0774)) < 0)
673e12c5d1SDavid du Colombier 			error("can't create directory %s", file);
683e12c5d1SDavid du Colombier 		close(fd);
693e12c5d1SDavid du Colombier 	} else {
703e12c5d1SDavid du Colombier 		if((dir.qid.path&CHDIR)==0)
713e12c5d1SDavid du Colombier 			error("not a directory %s", file);
723e12c5d1SDavid du Colombier 	}
733e12c5d1SDavid du Colombier 
743e12c5d1SDavid du Colombier 	/*
753e12c5d1SDavid du Colombier 	 *  create data file
763e12c5d1SDavid du Colombier 	 */
773e12c5d1SDavid du Colombier 	f = s_copy(file);
783e12c5d1SDavid du Colombier 	s_append(f, "/D.XXXXXX");
793e12c5d1SDavid du Colombier 	mktemp(s_to_c(f));
80*219b2ee8SDavid du Colombier 
81*219b2ee8SDavid du Colombier 	/*
82*219b2ee8SDavid du Colombier 	 *  copy over associated files
83*219b2ee8SDavid du Colombier 	 */
84*219b2ee8SDavid du Colombier 	if(files){
85*219b2ee8SDavid du Colombier 		cp = utfrrune(s_to_c(f), '/');
86*219b2ee8SDavid du Colombier 		cp++;
87*219b2ee8SDavid du Colombier 		*cp = 'F';
88*219b2ee8SDavid du Colombier 		for(q = files; q; q = q->next){
89*219b2ee8SDavid du Colombier 			q->tname = strdup(s_to_c(f));
90*219b2ee8SDavid du Colombier 			if(copy(q) < 0)
91*219b2ee8SDavid du Colombier 				error("copying %s to queue", q->name);
92*219b2ee8SDavid du Colombier 			(*cp)++;
93*219b2ee8SDavid du Colombier 		}
94*219b2ee8SDavid du Colombier 		*cp = 'D';
95*219b2ee8SDavid du Colombier 	}
96*219b2ee8SDavid du Colombier 
97*219b2ee8SDavid du Colombier 	/*
98*219b2ee8SDavid du Colombier 	 *  copy in the data file
99*219b2ee8SDavid du Colombier 	 */
1003e12c5d1SDavid du Colombier 	fd = create(s_to_c(f), OWRITE, 0660);
1013e12c5d1SDavid du Colombier 	if(fd < 0)
1023e12c5d1SDavid du Colombier 		error("creating data file %s", s_to_c(f));
1033e12c5d1SDavid du Colombier 	while((n = read(0, buf, sizeof(buf))) > 0)
1043e12c5d1SDavid du Colombier 		if(write(fd, buf, n) != n)
1053e12c5d1SDavid du Colombier 			error("writing data file %s", s_to_c(f));
1063e12c5d1SDavid du Colombier /*	if(n < 0)
1073e12c5d1SDavid du Colombier 		error("reading input"); */
1083e12c5d1SDavid du Colombier 	close(fd);
1093e12c5d1SDavid du Colombier 
1103e12c5d1SDavid du Colombier 	/*
1113e12c5d1SDavid du Colombier 	 *  create control file
1123e12c5d1SDavid du Colombier 	 */
1133e12c5d1SDavid du Colombier 	cp = utfrrune(s_to_c(f), '/');
1143e12c5d1SDavid du Colombier 	cp++;
1153e12c5d1SDavid du Colombier 	*cp = 'C';
1163e12c5d1SDavid du Colombier 	fd = create(s_to_c(f), OWRITE, CHEXCL|0660);
1173e12c5d1SDavid du Colombier 	if(fd < 0)
1183e12c5d1SDavid du Colombier 		error("creating control file %s", s_to_c(f));
1193e12c5d1SDavid du Colombier 	c = s_new();
120*219b2ee8SDavid du Colombier 	for(i = 1; i < argc; i++){
121*219b2ee8SDavid du Colombier 		s_append(c, argv[i]);
122*219b2ee8SDavid du Colombier 		s_append(c, " ");
123*219b2ee8SDavid du Colombier 	}
124*219b2ee8SDavid du Colombier 	for(q = files; q; q = q->next){
125*219b2ee8SDavid du Colombier 		s_append(c, q->tname);
1263e12c5d1SDavid du Colombier 		s_append(c, " ");
1273e12c5d1SDavid du Colombier 	}
1283e12c5d1SDavid du Colombier 	s_append(c, "\n");
1293e12c5d1SDavid du Colombier 	if(write(fd, s_to_c(c), strlen(s_to_c(c))) < 0)
1303e12c5d1SDavid du Colombier 		error("writing control file %s", s_to_c(f));
1313e12c5d1SDavid du Colombier 	close(fd);
1323e12c5d1SDavid du Colombier 	exits(0);
1333e12c5d1SDavid du Colombier }
134*219b2ee8SDavid du Colombier 
135*219b2ee8SDavid du Colombier int
136*219b2ee8SDavid du Colombier copy(Qfile *q)
137*219b2ee8SDavid du Colombier {
138*219b2ee8SDavid du Colombier 	int from, to, n;
139*219b2ee8SDavid du Colombier 	char buf[4096];
140*219b2ee8SDavid du Colombier 
141*219b2ee8SDavid du Colombier 	from = open(q->name, OREAD);
142*219b2ee8SDavid du Colombier 	if(from < 0)
143*219b2ee8SDavid du Colombier 		return -1;
144*219b2ee8SDavid du Colombier 	to = create(q->tname, OWRITE, 0660);
145*219b2ee8SDavid du Colombier 	if(to < 0){
146*219b2ee8SDavid du Colombier 		close(from);
147*219b2ee8SDavid du Colombier 		return -1;
148*219b2ee8SDavid du Colombier 	}
149*219b2ee8SDavid du Colombier 	for(;;){
150*219b2ee8SDavid du Colombier 		n = read(from, buf, sizeof(buf));
151*219b2ee8SDavid du Colombier 		if(n <= 0)
152*219b2ee8SDavid du Colombier 			break;
153*219b2ee8SDavid du Colombier 		n = write(to, buf, n);
154*219b2ee8SDavid du Colombier 		if(n < 0)
155*219b2ee8SDavid du Colombier 			break;
156*219b2ee8SDavid du Colombier 	}
157*219b2ee8SDavid du Colombier 	close(to);
158*219b2ee8SDavid du Colombier 	close(from);
159*219b2ee8SDavid du Colombier 	return n;
160*219b2ee8SDavid du Colombier }
161