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