1 5cdb1798 2005-10-29 devnull #include "common.h"
3 5cdb1798 2005-10-29 devnull typedef struct Qfile Qfile;
4 5cdb1798 2005-10-29 devnull struct Qfile
6 5cdb1798 2005-10-29 devnull Qfile *next;
7 5cdb1798 2005-10-29 devnull char *name;
8 5cdb1798 2005-10-29 devnull char *tname;
11 5cdb1798 2005-10-29 devnull char *user;
12 5cdb1798 2005-10-29 devnull int isnone;
14 5cdb1798 2005-10-29 devnull int copy(Qfile*);
17 5cdb1798 2005-10-29 devnull usage(void)
19 5cdb1798 2005-10-29 devnull fprint(2, "usage: qer [-f file] [-q dir] q-root description reply-to arg-list\n");
20 5cdb1798 2005-10-29 devnull exits("usage");
24 5cdb1798 2005-10-29 devnull error(char *f, char *a)
26 5cdb1798 2005-10-29 devnull char err[Errlen+1];
27 5cdb1798 2005-10-29 devnull char buf[256];
29 5cdb1798 2005-10-29 devnull rerrstr(err, sizeof(err));
30 5cdb1798 2005-10-29 devnull snprint(buf, sizeof(buf), f, a);
31 5cdb1798 2005-10-29 devnull fprint(2, "qer: %s: %s\n", buf, err);
32 5cdb1798 2005-10-29 devnull exits(buf);
36 5cdb1798 2005-10-29 devnull main(int argc, char**argv)
38 5cdb1798 2005-10-29 devnull Dir *dir;
39 5cdb1798 2005-10-29 devnull String *f, *c;
41 5cdb1798 2005-10-29 devnull char file[1024];
42 5cdb1798 2005-10-29 devnull char buf[1024];
44 5cdb1798 2005-10-29 devnull char *cp, *qdir;
46 5cdb1798 2005-10-29 devnull Qfile *q, **l;
48 5cdb1798 2005-10-29 devnull l = &files;
49 5cdb1798 2005-10-29 devnull qdir = 0;
51 5cdb1798 2005-10-29 devnull ARGBEGIN {
52 5cdb1798 2005-10-29 devnull case 'f':
53 5cdb1798 2005-10-29 devnull q = malloc(sizeof(Qfile));
54 5cdb1798 2005-10-29 devnull q->name = ARGF();
55 5cdb1798 2005-10-29 devnull q->next = *l;
58 5cdb1798 2005-10-29 devnull case 'q':
59 5cdb1798 2005-10-29 devnull qdir = ARGF();
60 5cdb1798 2005-10-29 devnull if(qdir == 0)
65 5cdb1798 2005-10-29 devnull } ARGEND;
67 5cdb1798 2005-10-29 devnull if(argc < 3)
69 5cdb1798 2005-10-29 devnull user = getuser();
70 5cdb1798 2005-10-29 devnull isnone = (qdir != 0) || (strcmp(user, "none") == 0);
72 5cdb1798 2005-10-29 devnull if(qdir == 0) {
73 5cdb1798 2005-10-29 devnull qdir = user;
74 5cdb1798 2005-10-29 devnull if(qdir == 0)
75 5cdb1798 2005-10-29 devnull error("unknown user", 0);
77 5cdb1798 2005-10-29 devnull snprint(file, sizeof(file), "%s/%s", argv[0], qdir);
80 5cdb1798 2005-10-29 devnull * data file name
82 5cdb1798 2005-10-29 devnull f = s_copy(file);
83 5cdb1798 2005-10-29 devnull s_append(f, "/D.XXXXXX");
84 5cdb1798 2005-10-29 devnull mktemp(s_to_c(f));
85 5cdb1798 2005-10-29 devnull cp = utfrrune(s_to_c(f), '/');
89 5cdb1798 2005-10-29 devnull * create directory and data file. once the data file
90 5cdb1798 2005-10-29 devnull * exists, runq won't remove the directory
93 5cdb1798 2005-10-29 devnull for(i = 0; i < 10; i++){
94 5cdb1798 2005-10-29 devnull int perm;
96 5cdb1798 2005-10-29 devnull dir = dirstat(file);
97 5cdb1798 2005-10-29 devnull if(dir == nil){
98 5cdb1798 2005-10-29 devnull perm = isnone?0777:0775;
99 5cdb1798 2005-10-29 devnull if(sysmkdir(file, perm) < 0)
100 5cdb1798 2005-10-29 devnull continue;
101 5cdb1798 2005-10-29 devnull } else {
102 5cdb1798 2005-10-29 devnull if((dir->qid.type&QTDIR)==0)
103 5cdb1798 2005-10-29 devnull error("not a directory %s", file);
105 5cdb1798 2005-10-29 devnull perm = isnone?0664:0660;
106 5cdb1798 2005-10-29 devnull fd = create(s_to_c(f), OWRITE, perm);
107 5cdb1798 2005-10-29 devnull if(fd >= 0)
109 5cdb1798 2005-10-29 devnull sleep(250);
111 5cdb1798 2005-10-29 devnull if(fd < 0)
112 5cdb1798 2005-10-29 devnull error("creating data file %s", s_to_c(f));
115 5cdb1798 2005-10-29 devnull * copy over associated files
117 5cdb1798 2005-10-29 devnull if(files){
118 5cdb1798 2005-10-29 devnull *cp = 'F';
119 5cdb1798 2005-10-29 devnull for(q = files; q; q = q->next){
120 5cdb1798 2005-10-29 devnull q->tname = strdup(s_to_c(f));
121 5cdb1798 2005-10-29 devnull if(copy(q) < 0)
122 5cdb1798 2005-10-29 devnull error("copying %s to queue", q->name);
123 5cdb1798 2005-10-29 devnull (*cp)++;
128 5cdb1798 2005-10-29 devnull * copy in the data file
131 5cdb1798 2005-10-29 devnull while((n = read(0, buf, sizeof(buf)-1)) > 0){
132 5cdb1798 2005-10-29 devnull if(i++ == 0 && strncmp(buf, "From", 4) != 0){
133 5cdb1798 2005-10-29 devnull buf[n] = 0;
134 5cdb1798 2005-10-29 devnull syslog(0, "smtp", "qer usys data starts with %-40.40s\n", buf);
136 5cdb1798 2005-10-29 devnull if(write(fd, buf, n) != n)
137 5cdb1798 2005-10-29 devnull error("writing data file %s", s_to_c(f));
139 5cdb1798 2005-10-29 devnull /* if(n < 0)
140 5cdb1798 2005-10-29 devnull error("reading input"); */
141 5cdb1798 2005-10-29 devnull close(fd);
144 5cdb1798 2005-10-29 devnull * create control file
146 5cdb1798 2005-10-29 devnull *cp = 'C';
147 5cdb1798 2005-10-29 devnull fd = syscreatelocked(s_to_c(f), OWRITE, 0664);
148 5cdb1798 2005-10-29 devnull if(fd < 0)
149 5cdb1798 2005-10-29 devnull error("creating control file %s", s_to_c(f));
150 5cdb1798 2005-10-29 devnull c = s_new();
151 5cdb1798 2005-10-29 devnull for(i = 1; i < argc; i++){
152 5cdb1798 2005-10-29 devnull s_append(c, argv[i]);
153 5cdb1798 2005-10-29 devnull s_append(c, " ");
155 5cdb1798 2005-10-29 devnull for(q = files; q; q = q->next){
156 5cdb1798 2005-10-29 devnull s_append(c, q->tname);
157 5cdb1798 2005-10-29 devnull s_append(c, " ");
159 5cdb1798 2005-10-29 devnull s_append(c, "\n");
160 5cdb1798 2005-10-29 devnull if(write(fd, s_to_c(c), strlen(s_to_c(c))) < 0) {
161 5cdb1798 2005-10-29 devnull sysunlockfile(fd);
162 5cdb1798 2005-10-29 devnull error("writing control file %s", s_to_c(f));
164 5cdb1798 2005-10-29 devnull sysunlockfile(fd);
165 5cdb1798 2005-10-29 devnull exits(0);
169 5cdb1798 2005-10-29 devnull copy(Qfile *q)
171 5cdb1798 2005-10-29 devnull int from, to, n;
172 5cdb1798 2005-10-29 devnull char buf[4096];
174 5cdb1798 2005-10-29 devnull from = open(q->name, OREAD);
175 5cdb1798 2005-10-29 devnull if(from < 0)
176 5cdb1798 2005-10-29 devnull return -1;
177 5cdb1798 2005-10-29 devnull to = create(q->tname, OWRITE, 0660);
178 5cdb1798 2005-10-29 devnull if(to < 0){
179 5cdb1798 2005-10-29 devnull close(from);
180 5cdb1798 2005-10-29 devnull return -1;
182 5cdb1798 2005-10-29 devnull for(;;){
183 5cdb1798 2005-10-29 devnull n = read(from, buf, sizeof(buf));
184 5cdb1798 2005-10-29 devnull if(n <= 0)
186 5cdb1798 2005-10-29 devnull n = write(to, buf, n);
187 5cdb1798 2005-10-29 devnull if(n < 0)
190 5cdb1798 2005-10-29 devnull close(to);
191 5cdb1798 2005-10-29 devnull close(from);
192 5cdb1798 2005-10-29 devnull return n;