xref: /plan9/sys/src/cmd/upas/q/qer.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier #include "common.h"
23e12c5d1SDavid du Colombier 
3219b2ee8SDavid du Colombier typedef struct Qfile Qfile;
4219b2ee8SDavid du Colombier struct Qfile
5219b2ee8SDavid du Colombier {
6219b2ee8SDavid du Colombier 	Qfile	*next;
7219b2ee8SDavid du Colombier 	char	*name;
8219b2ee8SDavid du Colombier 	char	*tname;
9219b2ee8SDavid du Colombier } *files;
10219b2ee8SDavid du Colombier 
11*7dd7cddfSDavid du Colombier char *user;
12*7dd7cddfSDavid du Colombier int isnone;
13*7dd7cddfSDavid du Colombier 
14219b2ee8SDavid du Colombier int	copy(Qfile*);
15219b2ee8SDavid du Colombier 
163e12c5d1SDavid du Colombier void
173e12c5d1SDavid du Colombier usage(void)
183e12c5d1SDavid du Colombier {
19*7dd7cddfSDavid du Colombier 	fprint(2, "usage: qer [-f file] [-q dir] q-root description reply-to arg-list\n");
203e12c5d1SDavid du Colombier 	exits("usage");
213e12c5d1SDavid du Colombier }
223e12c5d1SDavid du Colombier 
233e12c5d1SDavid du Colombier void
243e12c5d1SDavid du Colombier error(char *f, char *a)
253e12c5d1SDavid du Colombier {
263e12c5d1SDavid du Colombier 	char err[ERRLEN+1];
273e12c5d1SDavid du Colombier 	char buf[256];
283e12c5d1SDavid du Colombier 
293e12c5d1SDavid du Colombier 	errstr(err);
30*7dd7cddfSDavid du Colombier 	snprint(buf, sizeof(buf),  f, a);
313e12c5d1SDavid du Colombier 	fprint(2, "qer: %s: %s\n", buf, err);
323e12c5d1SDavid du Colombier 	exits(buf);
333e12c5d1SDavid du Colombier }
343e12c5d1SDavid du Colombier 
353e12c5d1SDavid du Colombier void
36219b2ee8SDavid du Colombier main(int argc, char**argv)
373e12c5d1SDavid du Colombier {
383e12c5d1SDavid du Colombier 	Dir	dir;
393e12c5d1SDavid du Colombier 	String	*f, *c;
403e12c5d1SDavid du Colombier 	int	fd;
413e12c5d1SDavid du Colombier 	char	file[1024];
423e12c5d1SDavid du Colombier 	char	buf[1024];
433e12c5d1SDavid du Colombier 	long	n;
44*7dd7cddfSDavid du Colombier 	char	*cp, *qdir;
453e12c5d1SDavid du Colombier 	int	i;
46219b2ee8SDavid du Colombier 	Qfile	*q, **l;
473e12c5d1SDavid du Colombier 
48219b2ee8SDavid du Colombier 	l = &files;
49*7dd7cddfSDavid du Colombier 	qdir = 0;
50219b2ee8SDavid du Colombier 
51219b2ee8SDavid du Colombier 	ARGBEGIN {
52219b2ee8SDavid du Colombier 	case 'f':
53219b2ee8SDavid du Colombier 		q = malloc(sizeof(Qfile));
54219b2ee8SDavid du Colombier 		q->name = ARGF();
55219b2ee8SDavid du Colombier 		q->next = *l;
56219b2ee8SDavid du Colombier 		*l = q;
57219b2ee8SDavid du Colombier 		break;
58*7dd7cddfSDavid du Colombier 	case 'q':
59*7dd7cddfSDavid du Colombier 		qdir = ARGF();
60*7dd7cddfSDavid du Colombier 		if(qdir == 0)
61*7dd7cddfSDavid du Colombier 			usage();
62*7dd7cddfSDavid du Colombier 		break;
63219b2ee8SDavid du Colombier 	default:
64219b2ee8SDavid du Colombier 		usage();
65219b2ee8SDavid du Colombier 	} ARGEND;
66219b2ee8SDavid du Colombier 
67219b2ee8SDavid du Colombier 	if(argc < 3)
683e12c5d1SDavid du Colombier 		usage();
69*7dd7cddfSDavid du Colombier 	user = getuser();
70*7dd7cddfSDavid du Colombier 	isnone = (qdir != 0) || (strcmp(user, "none") == 0);
713e12c5d1SDavid du Colombier 
72*7dd7cddfSDavid du Colombier 	if(qdir == 0) {
73*7dd7cddfSDavid du Colombier 		qdir = user;
74*7dd7cddfSDavid du Colombier 		if(qdir == 0)
75*7dd7cddfSDavid du Colombier 			error("unknown user", 0);
763e12c5d1SDavid du Colombier 	}
77*7dd7cddfSDavid du Colombier 	snprint(file, sizeof(file), "%s/%s", argv[0], qdir);
783e12c5d1SDavid du Colombier 
793e12c5d1SDavid du Colombier 	/*
80*7dd7cddfSDavid du Colombier 	 *  data file name
813e12c5d1SDavid du Colombier 	 */
823e12c5d1SDavid du Colombier 	f = s_copy(file);
833e12c5d1SDavid du Colombier 	s_append(f, "/D.XXXXXX");
843e12c5d1SDavid du Colombier 	mktemp(s_to_c(f));
85*7dd7cddfSDavid du Colombier 	cp = utfrrune(s_to_c(f), '/');
86*7dd7cddfSDavid du Colombier 	cp++;
87*7dd7cddfSDavid du Colombier 
88*7dd7cddfSDavid du Colombier 	/*
89*7dd7cddfSDavid du Colombier 	 *  create directory and data file.  once the data file
90*7dd7cddfSDavid du Colombier 	 *  exists, runq won't remove the directory
91*7dd7cddfSDavid du Colombier 	 */
92*7dd7cddfSDavid du Colombier 	fd = -1;
93*7dd7cddfSDavid du Colombier 	for(i = 0; i < 10; i++){
94*7dd7cddfSDavid du Colombier 		int perm;
95*7dd7cddfSDavid du Colombier 
96*7dd7cddfSDavid du Colombier 		if(dirstat(file, &dir) < 0){
97*7dd7cddfSDavid du Colombier 			perm = isnone?0777:0775;
98*7dd7cddfSDavid du Colombier 			if(sysmkdir(file, perm) < 0)
99*7dd7cddfSDavid du Colombier 				continue;
100*7dd7cddfSDavid du Colombier 		} else {
101*7dd7cddfSDavid du Colombier 			if((dir.qid.path&CHDIR)==0)
102*7dd7cddfSDavid du Colombier 				error("not a directory %s", file);
103*7dd7cddfSDavid du Colombier 		}
104*7dd7cddfSDavid du Colombier 		perm = isnone?0664:0660;
105*7dd7cddfSDavid du Colombier 		fd = create(s_to_c(f), OWRITE, perm);
106*7dd7cddfSDavid du Colombier 		if(fd >= 0)
107*7dd7cddfSDavid du Colombier 			break;
108*7dd7cddfSDavid du Colombier 		sleep(250);
109*7dd7cddfSDavid du Colombier 	}
110*7dd7cddfSDavid du Colombier 	if(fd < 0)
111*7dd7cddfSDavid du Colombier 		error("creating data file %s", s_to_c(f));
112219b2ee8SDavid du Colombier 
113219b2ee8SDavid du Colombier 	/*
114219b2ee8SDavid du Colombier 	 *  copy over associated files
115219b2ee8SDavid du Colombier 	 */
116219b2ee8SDavid du Colombier 	if(files){
117219b2ee8SDavid du Colombier 		*cp = 'F';
118219b2ee8SDavid du Colombier 		for(q = files; q; q = q->next){
119219b2ee8SDavid du Colombier 			q->tname = strdup(s_to_c(f));
120219b2ee8SDavid du Colombier 			if(copy(q) < 0)
121219b2ee8SDavid du Colombier 				error("copying %s to queue", q->name);
122219b2ee8SDavid du Colombier 			(*cp)++;
123219b2ee8SDavid du Colombier 		}
124219b2ee8SDavid du Colombier 	}
125219b2ee8SDavid du Colombier 
126219b2ee8SDavid du Colombier 	/*
127219b2ee8SDavid du Colombier 	 *  copy in the data file
128219b2ee8SDavid du Colombier 	 */
129*7dd7cddfSDavid du Colombier 	i = 0;
130*7dd7cddfSDavid du Colombier 	while((n = read(0, buf, sizeof(buf)-1)) > 0){
131*7dd7cddfSDavid du Colombier 		if(i++ == 0 && strncmp(buf, "From", 4) != 0){
132*7dd7cddfSDavid du Colombier 			buf[n] = 0;
133*7dd7cddfSDavid du Colombier 			syslog(0, "smtp", "qer usys data starts with %-40.40s\n", buf);
134*7dd7cddfSDavid du Colombier 		}
1353e12c5d1SDavid du Colombier 		if(write(fd, buf, n) != n)
1363e12c5d1SDavid du Colombier 			error("writing data file %s", s_to_c(f));
137*7dd7cddfSDavid du Colombier 	}
1383e12c5d1SDavid du Colombier /*	if(n < 0)
1393e12c5d1SDavid du Colombier 		error("reading input"); */
1403e12c5d1SDavid du Colombier 	close(fd);
1413e12c5d1SDavid du Colombier 
1423e12c5d1SDavid du Colombier 	/*
1433e12c5d1SDavid du Colombier 	 *  create control file
1443e12c5d1SDavid du Colombier 	 */
1453e12c5d1SDavid du Colombier 	*cp = 'C';
146*7dd7cddfSDavid du Colombier 	fd = syscreatelocked(s_to_c(f), OWRITE, 0664);
1473e12c5d1SDavid du Colombier 	if(fd < 0)
1483e12c5d1SDavid du Colombier 		error("creating control file %s", s_to_c(f));
1493e12c5d1SDavid du Colombier 	c = s_new();
150219b2ee8SDavid du Colombier 	for(i = 1; i < argc; i++){
151219b2ee8SDavid du Colombier 		s_append(c, argv[i]);
152219b2ee8SDavid du Colombier 		s_append(c, " ");
153219b2ee8SDavid du Colombier 	}
154219b2ee8SDavid du Colombier 	for(q = files; q; q = q->next){
155219b2ee8SDavid du Colombier 		s_append(c, q->tname);
1563e12c5d1SDavid du Colombier 		s_append(c, " ");
1573e12c5d1SDavid du Colombier 	}
1583e12c5d1SDavid du Colombier 	s_append(c, "\n");
159*7dd7cddfSDavid du Colombier 	if(write(fd, s_to_c(c), strlen(s_to_c(c))) < 0) {
160*7dd7cddfSDavid du Colombier 		sysunlockfile(fd);
1613e12c5d1SDavid du Colombier 		error("writing control file %s", s_to_c(f));
162*7dd7cddfSDavid du Colombier 	}
163*7dd7cddfSDavid du Colombier 	sysunlockfile(fd);
1643e12c5d1SDavid du Colombier 	exits(0);
1653e12c5d1SDavid du Colombier }
166219b2ee8SDavid du Colombier 
167219b2ee8SDavid du Colombier int
168219b2ee8SDavid du Colombier copy(Qfile *q)
169219b2ee8SDavid du Colombier {
170219b2ee8SDavid du Colombier 	int from, to, n;
171219b2ee8SDavid du Colombier 	char buf[4096];
172219b2ee8SDavid du Colombier 
173219b2ee8SDavid du Colombier 	from = open(q->name, OREAD);
174219b2ee8SDavid du Colombier 	if(from < 0)
175219b2ee8SDavid du Colombier 		return -1;
176219b2ee8SDavid du Colombier 	to = create(q->tname, OWRITE, 0660);
177219b2ee8SDavid du Colombier 	if(to < 0){
178219b2ee8SDavid du Colombier 		close(from);
179219b2ee8SDavid du Colombier 		return -1;
180219b2ee8SDavid du Colombier 	}
181219b2ee8SDavid du Colombier 	for(;;){
182219b2ee8SDavid du Colombier 		n = read(from, buf, sizeof(buf));
183219b2ee8SDavid du Colombier 		if(n <= 0)
184219b2ee8SDavid du Colombier 			break;
185219b2ee8SDavid du Colombier 		n = write(to, buf, n);
186219b2ee8SDavid du Colombier 		if(n < 0)
187219b2ee8SDavid du Colombier 			break;
188219b2ee8SDavid du Colombier 	}
189219b2ee8SDavid du Colombier 	close(to);
190219b2ee8SDavid du Colombier 	close(from);
191219b2ee8SDavid du Colombier 	return n;
192219b2ee8SDavid du Colombier }
193