qmail-newu.c
changeset 0 068428edee47
equal deleted inserted replaced
-1:000000000000 0:068428edee47
       
     1 #include "stralloc.h"
       
     2 #include "subfd.h"
       
     3 #include "getln.h"
       
     4 #include "substdio.h"
       
     5 #include "cdbmss.h"
       
     6 #include "exit.h"
       
     7 #include "readwrite.h"
       
     8 #include "open.h"
       
     9 #include "error.h"
       
    10 #include "case.h"
       
    11 #include "auto_qmail.h"
       
    12 
       
    13 void die_temp() { _exit(111); }
       
    14 
       
    15 void die_chdir()
       
    16 {
       
    17   substdio_putsflush(subfderr,"qmail-newu: fatal: unable to chdir\n");
       
    18   die_temp();
       
    19 }
       
    20 void die_nomem()
       
    21 {
       
    22   substdio_putsflush(subfderr,"qmail-newu: fatal: out of memory\n");
       
    23   die_temp();
       
    24 }
       
    25 void die_opena()
       
    26 {
       
    27   substdio_putsflush(subfderr,"qmail-newu: fatal: unable to open users/assign\n");
       
    28   die_temp();
       
    29 }
       
    30 void die_reada()
       
    31 {
       
    32   substdio_putsflush(subfderr,"qmail-newu: fatal: unable to read users/assign\n");
       
    33   die_temp();
       
    34 }
       
    35 void die_format()
       
    36 {
       
    37   substdio_putsflush(subfderr,"qmail-newu: fatal: bad format in users/assign\n");
       
    38   die_temp();
       
    39 }
       
    40 void die_opent()
       
    41 {
       
    42   substdio_putsflush(subfderr,"qmail-newu: fatal: unable to open users/cdb.tmp\n");
       
    43   die_temp();
       
    44 }
       
    45 void die_writet()
       
    46 {
       
    47   substdio_putsflush(subfderr,"qmail-newu: fatal: unable to write users/cdb.tmp\n");
       
    48   die_temp();
       
    49 }
       
    50 void die_rename()
       
    51 {
       
    52   substdio_putsflush(subfderr,"qmail-newu: fatal: unable to move users/cdb.tmp to users/cdb\n");
       
    53   die_temp();
       
    54 }
       
    55 
       
    56 struct cdbmss cdbmss;
       
    57 stralloc key = {0};
       
    58 stralloc data = {0};
       
    59 
       
    60 char inbuf[1024];
       
    61 substdio ssin;
       
    62 
       
    63 int fd;
       
    64 int fdtemp;
       
    65 
       
    66 stralloc line = {0};
       
    67 int match;
       
    68 
       
    69 stralloc wildchars = {0};
       
    70 
       
    71 void main()
       
    72 {
       
    73   int i;
       
    74   int numcolons;
       
    75 
       
    76   umask(033);
       
    77   if (chdir(auto_qmail) == -1) die_chdir();
       
    78 
       
    79   fd = open_read("users/assign");
       
    80   if (fd == -1) die_opena();
       
    81 
       
    82   substdio_fdbuf(&ssin,read,fd,inbuf,sizeof(inbuf));
       
    83 
       
    84   fdtemp = open_trunc("users/cdb.tmp");
       
    85   if (fdtemp == -1) die_opent();
       
    86 
       
    87   if (cdbmss_start(&cdbmss,fdtemp) == -1) die_writet();
       
    88 
       
    89   if (!stralloc_copys(&wildchars,"")) die_nomem();
       
    90 
       
    91   for (;;) {
       
    92     if (getln(&ssin,&line,&match,'\n') != 0) die_reada();
       
    93     if (line.len && (line.s[0] == '.')) break;
       
    94     if (!match) die_format();
       
    95 
       
    96     if (byte_chr(line.s,line.len,'\0') < line.len) die_format();
       
    97     i = byte_chr(line.s,line.len,':');
       
    98     if (i == line.len) die_format();
       
    99     if (i == 0) die_format();
       
   100     if (!stralloc_copys(&key,"!")) die_nomem();
       
   101     if (line.s[0] == '+') {
       
   102       if (!stralloc_catb(&key,line.s + 1,i - 1)) die_nomem();
       
   103       case_lowerb(key.s,key.len);
       
   104       if (i >= 2)
       
   105 	if (byte_chr(wildchars.s,wildchars.len,line.s[i - 1]) == wildchars.len)
       
   106 	  if (!stralloc_append(&wildchars,line.s + i - 1)) die_nomem();
       
   107     }
       
   108     else {
       
   109       if (!stralloc_catb(&key,line.s + 1,i - 1)) die_nomem();
       
   110       if (!stralloc_0(&key)) die_nomem();
       
   111       case_lowerb(key.s,key.len);
       
   112     }
       
   113 
       
   114     if (!stralloc_copyb(&data,line.s + i + 1,line.len - i - 1)) die_nomem();
       
   115 
       
   116     numcolons = 0;
       
   117     for (i = 0;i < data.len;++i)
       
   118       if (data.s[i] == ':') {
       
   119 	data.s[i] = 0;
       
   120 	if (++numcolons == 6)
       
   121 	  break;
       
   122       }
       
   123     if (numcolons < 6) die_format();
       
   124     data.len = i;
       
   125 
       
   126     if (cdbmss_add(&cdbmss,key.s,key.len,data.s,data.len) == -1) die_writet();
       
   127   }
       
   128 
       
   129   if (cdbmss_add(&cdbmss,"",0,wildchars.s,wildchars.len) == -1) die_writet();
       
   130 
       
   131   if (cdbmss_finish(&cdbmss) == -1) die_writet();
       
   132   if (fsync(fdtemp) == -1) die_writet();
       
   133   if (close(fdtemp) == -1) die_writet(); /* NFS stupidity */
       
   134   if (rename("users/cdb.tmp","users/cdb") == -1) die_rename();
       
   135 
       
   136   _exit(0);
       
   137 }