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