17dd7cddfSDavid du Colombier #include <u.h> 27dd7cddfSDavid du Colombier #include <libc.h> 37dd7cddfSDavid du Colombier #include <bio.h> 4*9a747e4fSDavid du Colombier #include <auth.h> 57dd7cddfSDavid du Colombier #include "imap4d.h" 67dd7cddfSDavid du Colombier 77dd7cddfSDavid du Colombier /* 87dd7cddfSDavid du Colombier * reverse string [s:e) in place 97dd7cddfSDavid du Colombier */ 107dd7cddfSDavid du Colombier void 117dd7cddfSDavid du Colombier strrev(char *s, char *e) 127dd7cddfSDavid du Colombier { 137dd7cddfSDavid du Colombier int c; 147dd7cddfSDavid du Colombier 157dd7cddfSDavid du Colombier while(--e > s){ 167dd7cddfSDavid du Colombier c = *s; 177dd7cddfSDavid du Colombier *s++ = *e; 187dd7cddfSDavid du Colombier *e = c; 197dd7cddfSDavid du Colombier } 207dd7cddfSDavid du Colombier } 217dd7cddfSDavid du Colombier 227dd7cddfSDavid du Colombier int 237dd7cddfSDavid du Colombier isdotdot(char *s) 247dd7cddfSDavid du Colombier { 257dd7cddfSDavid du Colombier return s[0] == '.' && s[1] == '.' && (s[2] == '/' || s[2] == '\0'); 267dd7cddfSDavid du Colombier } 277dd7cddfSDavid du Colombier 287dd7cddfSDavid du Colombier int 297dd7cddfSDavid du Colombier issuffix(char *suf, char *s) 307dd7cddfSDavid du Colombier { 317dd7cddfSDavid du Colombier int n; 327dd7cddfSDavid du Colombier 337dd7cddfSDavid du Colombier n = strlen(s) - strlen(suf); 347dd7cddfSDavid du Colombier if(n < 0) 357dd7cddfSDavid du Colombier return 0; 367dd7cddfSDavid du Colombier return strcmp(s + n, suf) == 0; 377dd7cddfSDavid du Colombier } 387dd7cddfSDavid du Colombier 397dd7cddfSDavid du Colombier int 407dd7cddfSDavid du Colombier isprefix(char *pre, char *s) 417dd7cddfSDavid du Colombier { 427dd7cddfSDavid du Colombier return strncmp(pre, s, strlen(pre)) == 0; 437dd7cddfSDavid du Colombier } 447dd7cddfSDavid du Colombier 457dd7cddfSDavid du Colombier int 467dd7cddfSDavid du Colombier ciisprefix(char *pre, char *s) 477dd7cddfSDavid du Colombier { 487dd7cddfSDavid du Colombier return cistrncmp(pre, s, strlen(pre)) == 0; 497dd7cddfSDavid du Colombier } 507dd7cddfSDavid du Colombier 517dd7cddfSDavid du Colombier char* 527dd7cddfSDavid du Colombier readFile(int fd) 537dd7cddfSDavid du Colombier { 54*9a747e4fSDavid du Colombier Dir *d; 55*9a747e4fSDavid du Colombier long length; 567dd7cddfSDavid du Colombier char *s; 577dd7cddfSDavid du Colombier 58*9a747e4fSDavid du Colombier d = dirfstat(fd); 59*9a747e4fSDavid du Colombier if(d == nil) 607dd7cddfSDavid du Colombier return nil; 61*9a747e4fSDavid du Colombier length = d->length; 62*9a747e4fSDavid du Colombier free(d); 63*9a747e4fSDavid du Colombier s = binalloc(&parseBin, length + 1, 0); 64*9a747e4fSDavid du Colombier if(s == nil || read(fd, s, length) != length) 657dd7cddfSDavid du Colombier return nil; 66*9a747e4fSDavid du Colombier s[length] = '\0'; 677dd7cddfSDavid du Colombier return s; 687dd7cddfSDavid du Colombier } 697dd7cddfSDavid du Colombier 707dd7cddfSDavid du Colombier /* 7180ee5cbfSDavid du Colombier * create the imap tmp file. 7280ee5cbfSDavid du Colombier * it just happens that we don't need multiple temporary files. 737dd7cddfSDavid du Colombier */ 747dd7cddfSDavid du Colombier int 757dd7cddfSDavid du Colombier imapTmp(void) 767dd7cddfSDavid du Colombier { 77*9a747e4fSDavid du Colombier char buf[ERRMAX], name[MboxNameLen]; 787dd7cddfSDavid du Colombier int tries, fd; 797dd7cddfSDavid du Colombier 807dd7cddfSDavid du Colombier snprint(name, sizeof(name), "/mail/box/%s/mbox.tmp.imp", username); 817dd7cddfSDavid du Colombier for(tries = 0; tries < LockSecs*2; tries++){ 82*9a747e4fSDavid du Colombier fd = create(name, ORDWR|ORCLOSE|OCEXEC, DMEXCL|0600); 837dd7cddfSDavid du Colombier if(fd >= 0) 847dd7cddfSDavid du Colombier return fd; 85*9a747e4fSDavid du Colombier errstr(buf, sizeof buf); 867dd7cddfSDavid du Colombier if(cistrstr(buf, "locked") == nil) 877dd7cddfSDavid du Colombier break; 887dd7cddfSDavid du Colombier sleep(500); 897dd7cddfSDavid du Colombier } 907dd7cddfSDavid du Colombier return -1; 917dd7cddfSDavid du Colombier } 927dd7cddfSDavid du Colombier 937dd7cddfSDavid du Colombier /* 947dd7cddfSDavid du Colombier * open a file which might be locked. 957dd7cddfSDavid du Colombier * if it is, spin until available 967dd7cddfSDavid du Colombier */ 977dd7cddfSDavid du Colombier int 987dd7cddfSDavid du Colombier openLocked(char *dir, char *file, int mode) 997dd7cddfSDavid du Colombier { 100*9a747e4fSDavid du Colombier char buf[ERRMAX]; 1017dd7cddfSDavid du Colombier int tries, fd; 1027dd7cddfSDavid du Colombier 1037dd7cddfSDavid du Colombier for(tries = 0; tries < LockSecs*2; tries++){ 1047dd7cddfSDavid du Colombier fd = cdOpen(dir, file, mode); 1057dd7cddfSDavid du Colombier if(fd >= 0) 1067dd7cddfSDavid du Colombier return fd; 107*9a747e4fSDavid du Colombier errstr(buf, sizeof buf); 1087dd7cddfSDavid du Colombier if(cistrstr(buf, "locked") == nil) 1097dd7cddfSDavid du Colombier break; 1107dd7cddfSDavid du Colombier sleep(500); 1117dd7cddfSDavid du Colombier } 1127dd7cddfSDavid du Colombier return -1; 1137dd7cddfSDavid du Colombier } 1147dd7cddfSDavid du Colombier 115*9a747e4fSDavid du Colombier int 116*9a747e4fSDavid du Colombier fqid(int fd, Qid *qid) 117*9a747e4fSDavid du Colombier { 118*9a747e4fSDavid du Colombier Dir *d; 119*9a747e4fSDavid du Colombier 120*9a747e4fSDavid du Colombier d = dirfstat(fd); 121*9a747e4fSDavid du Colombier if(d == nil) 122*9a747e4fSDavid du Colombier return -1; 123*9a747e4fSDavid du Colombier *qid = d->qid; 124*9a747e4fSDavid du Colombier free(d); 125*9a747e4fSDavid du Colombier return 0; 126*9a747e4fSDavid du Colombier } 127*9a747e4fSDavid du Colombier 1287dd7cddfSDavid du Colombier ulong 1297dd7cddfSDavid du Colombier mapInt(NamedInt *map, char *name) 1307dd7cddfSDavid du Colombier { 1317dd7cddfSDavid du Colombier int i; 1327dd7cddfSDavid du Colombier 1337dd7cddfSDavid du Colombier for(i = 0; map[i].name != nil; i++) 1347dd7cddfSDavid du Colombier if(cistrcmp(map[i].name, name) == 0) 1357dd7cddfSDavid du Colombier break; 1367dd7cddfSDavid du Colombier return map[i].v; 1377dd7cddfSDavid du Colombier } 1387dd7cddfSDavid du Colombier 1397dd7cddfSDavid du Colombier char* 1407dd7cddfSDavid du Colombier estrdup(char *s) 1417dd7cddfSDavid du Colombier { 1427dd7cddfSDavid du Colombier char *t; 1437dd7cddfSDavid du Colombier 1447dd7cddfSDavid du Colombier t = emalloc(strlen(s) + 1); 1457dd7cddfSDavid du Colombier strcpy(t, s); 1467dd7cddfSDavid du Colombier return t; 1477dd7cddfSDavid du Colombier } 1487dd7cddfSDavid du Colombier 1497dd7cddfSDavid du Colombier void* 1507dd7cddfSDavid du Colombier emalloc(ulong n) 1517dd7cddfSDavid du Colombier { 1527dd7cddfSDavid du Colombier void *p; 1537dd7cddfSDavid du Colombier 1547dd7cddfSDavid du Colombier p = malloc(n); 1557dd7cddfSDavid du Colombier if(p == nil) 1567dd7cddfSDavid du Colombier bye("server out of memory"); 1577dd7cddfSDavid du Colombier return p; 1587dd7cddfSDavid du Colombier } 1597dd7cddfSDavid du Colombier 1607dd7cddfSDavid du Colombier void* 1617dd7cddfSDavid du Colombier ezmalloc(ulong n) 1627dd7cddfSDavid du Colombier { 1637dd7cddfSDavid du Colombier void *p; 1647dd7cddfSDavid du Colombier 1657dd7cddfSDavid du Colombier p = malloc(n); 1667dd7cddfSDavid du Colombier if(p == nil) 1677dd7cddfSDavid du Colombier bye("server out of memory"); 1687dd7cddfSDavid du Colombier memset(p, 0, n); 1697dd7cddfSDavid du Colombier return p; 1707dd7cddfSDavid du Colombier } 1717dd7cddfSDavid du Colombier 1727dd7cddfSDavid du Colombier void* 1737dd7cddfSDavid du Colombier erealloc(void *p, ulong n) 1747dd7cddfSDavid du Colombier { 1757dd7cddfSDavid du Colombier p = realloc(p, n); 1767dd7cddfSDavid du Colombier if(p == nil) 1777dd7cddfSDavid du Colombier bye("server out of memory"); 1787dd7cddfSDavid du Colombier return p; 1797dd7cddfSDavid du Colombier } 180