xref: /plan9-contrib/sys/src/cmd/upas/q/qer.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include "../libString/String.h"
4 
5 typedef struct Qfile Qfile;
6 struct Qfile
7 {
8 	Qfile	*next;
9 	char	*name;
10 	char	*tname;
11 } *files;
12 
13 int	copy(Qfile*);
14 
15 void
16 usage(void)
17 {
18 	fprint(2, "usage: qer [-f file] q-root description reply-to arg-list\n");
19 	exits("usage");
20 }
21 
22 void
23 error(char *f, char *a)
24 {
25 	char err[ERRLEN+1];
26 	char buf[256];
27 
28 	errstr(err);
29 	sprint(buf, f, a);
30 	fprint(2, "qer: %s: %s\n", buf, err);
31 	exits(buf);
32 }
33 
34 void
35 main(int argc, char**argv)
36 {
37 	Dir	dir;
38 	String	*f, *c;
39 	int	fd;
40 	char	file[1024];
41 	char	buf[1024];
42 	long	n;
43 	char	*cp;
44 	int	i;
45 	Qfile	*q, **l;
46 
47 	l = &files;
48 
49 	ARGBEGIN {
50 	case 'f':
51 		q = malloc(sizeof(Qfile));
52 		q->name = ARGF();
53 		q->next = *l;
54 		*l = q;
55 		break;
56 	default:
57 		usage();
58 	} ARGEND;
59 
60 	if(argc < 3)
61 		usage();
62 
63 	sprint(file, "%s/%s", argv[0], getuser());
64 
65 	if(dirstat(file, &dir) < 0){
66 		if((fd = create(file, OREAD, CHDIR|0774)) < 0)
67 			error("can't create directory %s", file);
68 		close(fd);
69 	} else {
70 		if((dir.qid.path&CHDIR)==0)
71 			error("not a directory %s", file);
72 	}
73 
74 	/*
75 	 *  create data file
76 	 */
77 	f = s_copy(file);
78 	s_append(f, "/D.XXXXXX");
79 	mktemp(s_to_c(f));
80 
81 	/*
82 	 *  copy over associated files
83 	 */
84 	if(files){
85 		cp = utfrrune(s_to_c(f), '/');
86 		cp++;
87 		*cp = 'F';
88 		for(q = files; q; q = q->next){
89 			q->tname = strdup(s_to_c(f));
90 			if(copy(q) < 0)
91 				error("copying %s to queue", q->name);
92 			(*cp)++;
93 		}
94 		*cp = 'D';
95 	}
96 
97 	/*
98 	 *  copy in the data file
99 	 */
100 	fd = create(s_to_c(f), OWRITE, 0660);
101 	if(fd < 0)
102 		error("creating data file %s", s_to_c(f));
103 	while((n = read(0, buf, sizeof(buf))) > 0)
104 		if(write(fd, buf, n) != n)
105 			error("writing data file %s", s_to_c(f));
106 /*	if(n < 0)
107 		error("reading input"); */
108 	close(fd);
109 
110 	/*
111 	 *  create control file
112 	 */
113 	cp = utfrrune(s_to_c(f), '/');
114 	cp++;
115 	*cp = 'C';
116 	fd = create(s_to_c(f), OWRITE, CHEXCL|0660);
117 	if(fd < 0)
118 		error("creating control file %s", s_to_c(f));
119 	c = s_new();
120 	for(i = 1; i < argc; i++){
121 		s_append(c, argv[i]);
122 		s_append(c, " ");
123 	}
124 	for(q = files; q; q = q->next){
125 		s_append(c, q->tname);
126 		s_append(c, " ");
127 	}
128 	s_append(c, "\n");
129 	if(write(fd, s_to_c(c), strlen(s_to_c(c))) < 0)
130 		error("writing control file %s", s_to_c(f));
131 	close(fd);
132 	exits(0);
133 }
134 
135 int
136 copy(Qfile *q)
137 {
138 	int from, to, n;
139 	char buf[4096];
140 
141 	from = open(q->name, OREAD);
142 	if(from < 0)
143 		return -1;
144 	to = create(q->tname, OWRITE, 0660);
145 	if(to < 0){
146 		close(from);
147 		return -1;
148 	}
149 	for(;;){
150 		n = read(from, buf, sizeof(buf));
151 		if(n <= 0)
152 			break;
153 		n = write(to, buf, n);
154 		if(n < 0)
155 			break;
156 	}
157 	close(to);
158 	close(from);
159 	return n;
160 }
161