URI:
       tqer.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tqer.c (3179B)
       ---
            1 #include "common.h"
            2 
            3 typedef struct Qfile Qfile;
            4 struct Qfile
            5 {
            6         Qfile        *next;
            7         char        *name;
            8         char        *tname;
            9 } *files;
           10 
           11 char *user;
           12 int isnone;
           13 
           14 int        copy(Qfile*);
           15 
           16 void
           17 usage(void)
           18 {
           19         fprint(2, "usage: qer [-f file] [-q dir] q-root description reply-to arg-list\n");
           20         exits("usage");
           21 }
           22 
           23 void
           24 error(char *f, char *a)
           25 {
           26         char err[Errlen+1];
           27         char buf[256];
           28 
           29         rerrstr(err, sizeof(err));
           30         snprint(buf, sizeof(buf),  f, a);
           31         fprint(2, "qer: %s: %s\n", buf, err);
           32         exits(buf);
           33 }
           34 
           35 void
           36 main(int argc, char**argv)
           37 {
           38         Dir        *dir;
           39         String        *f, *c;
           40         int        fd;
           41         char        file[1024];
           42         char        buf[1024];
           43         long        n;
           44         char        *cp, *qdir;
           45         int        i;
           46         Qfile        *q, **l;
           47 
           48         l = &files;
           49         qdir = 0;
           50 
           51         ARGBEGIN {
           52         case 'f':
           53                 q = malloc(sizeof(Qfile));
           54                 q->name = ARGF();
           55                 q->next = *l;
           56                 *l = q;
           57                 break;
           58         case 'q':
           59                 qdir = ARGF();
           60                 if(qdir == 0)
           61                         usage();
           62                 break;
           63         default:
           64                 usage();
           65         } ARGEND;
           66 
           67         if(argc < 3)
           68                 usage();
           69         user = getuser();
           70         isnone = (qdir != 0) || (strcmp(user, "none") == 0);
           71 
           72         if(qdir == 0) {
           73                 qdir = user;
           74                 if(qdir == 0)
           75                         error("unknown user", 0);
           76         }
           77         snprint(file, sizeof(file), "%s/%s", argv[0], qdir);
           78 
           79         /*
           80          *  data file name
           81          */
           82         f = s_copy(file);
           83         s_append(f, "/D.XXXXXX");
           84         mktemp(s_to_c(f));
           85         cp = utfrrune(s_to_c(f), '/');
           86         cp++;
           87 
           88         /*
           89          *  create directory and data file.  once the data file
           90          *  exists, runq won't remove the directory
           91          */
           92         fd = -1;
           93         for(i = 0; i < 10; i++){
           94                 int perm;
           95 
           96                 dir = dirstat(file);
           97                 if(dir == nil){
           98                         perm = isnone?0777:0775;
           99                         if(sysmkdir(file, perm) < 0)
          100                                 continue;
          101                 } else {
          102                         if((dir->qid.type&QTDIR)==0)
          103                                 error("not a directory %s", file);
          104                 }
          105                 perm = isnone?0664:0660;
          106                 fd = create(s_to_c(f), OWRITE, perm);
          107                 if(fd >= 0)
          108                         break;
          109                 sleep(250);
          110         }
          111         if(fd < 0)
          112                 error("creating data file %s", s_to_c(f));
          113 
          114         /*
          115          *  copy over associated files
          116          */
          117         if(files){
          118                 *cp = 'F';
          119                 for(q = files; q; q = q->next){
          120                         q->tname = strdup(s_to_c(f));
          121                         if(copy(q) < 0)
          122                                 error("copying %s to queue", q->name);
          123                         (*cp)++;
          124                 }
          125         }
          126 
          127         /*
          128          *  copy in the data file
          129          */
          130         i = 0;
          131         while((n = read(0, buf, sizeof(buf)-1)) > 0){
          132                 if(i++ == 0 && strncmp(buf, "From", 4) != 0){
          133                         buf[n] = 0;
          134                         syslog(0, "smtp", "qer usys data starts with %-40.40s\n", buf);
          135                 }
          136                 if(write(fd, buf, n) != n)
          137                         error("writing data file %s", s_to_c(f));
          138         }
          139 /*        if(n < 0)
          140                 error("reading input"); */
          141         close(fd);
          142 
          143         /*
          144          *  create control file
          145          */
          146         *cp = 'C';
          147         fd = syscreatelocked(s_to_c(f), OWRITE, 0664);
          148         if(fd < 0)
          149                 error("creating control file %s", s_to_c(f));
          150         c = s_new();
          151         for(i = 1; i < argc; i++){
          152                 s_append(c, argv[i]);
          153                 s_append(c, " ");
          154         }
          155         for(q = files; q; q = q->next){
          156                 s_append(c, q->tname);
          157                 s_append(c, " ");
          158         }
          159         s_append(c, "\n");
          160         if(write(fd, s_to_c(c), strlen(s_to_c(c))) < 0) {
          161                 sysunlockfile(fd);
          162                 error("writing control file %s", s_to_c(f));
          163         }
          164         sysunlockfile(fd);
          165         exits(0);
          166 }
          167 
          168 int
          169 copy(Qfile *q)
          170 {
          171         int from, to, n;
          172         char buf[4096];
          173 
          174         from = open(q->name, OREAD);
          175         if(from < 0)
          176                 return -1;
          177         to = create(q->tname, OWRITE, 0660);
          178         if(to < 0){
          179                 close(from);
          180                 return -1;
          181         }
          182         for(;;){
          183                 n = read(from, buf, sizeof(buf));
          184                 if(n <= 0)
          185                         break;
          186                 n = write(to, buf, n);
          187                 if(n < 0)
          188                         break;
          189         }
          190         close(to);
          191         close(from);
          192         return n;
          193 }