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