1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <auth.h> 5 #include "imap4d.h" 6 7 /* 8 * reverse string [s:e) in place 9 */ 10 void 11 strrev(char *s, char *e) 12 { 13 int c; 14 15 while(--e > s){ 16 c = *s; 17 *s++ = *e; 18 *e = c; 19 } 20 } 21 22 int 23 isdotdot(char *s) 24 { 25 return s[0] == '.' && s[1] == '.' && (s[2] == '/' || s[2] == '\0'); 26 } 27 28 int 29 issuffix(char *suf, char *s) 30 { 31 int n; 32 33 n = strlen(s) - strlen(suf); 34 if(n < 0) 35 return 0; 36 return strcmp(s + n, suf) == 0; 37 } 38 39 int 40 isprefix(char *pre, char *s) 41 { 42 return strncmp(pre, s, strlen(pre)) == 0; 43 } 44 45 int 46 ciisprefix(char *pre, char *s) 47 { 48 return cistrncmp(pre, s, strlen(pre)) == 0; 49 } 50 51 char* 52 readFile(int fd) 53 { 54 Dir *d; 55 long length; 56 char *s; 57 58 d = dirfstat(fd); 59 if(d == nil) 60 return nil; 61 length = d->length; 62 free(d); 63 s = binalloc(&parseBin, length + 1, 0); 64 if(s == nil || read(fd, s, length) != length) 65 return nil; 66 s[length] = '\0'; 67 return s; 68 } 69 70 /* 71 * create the imap tmp file. 72 * it just happens that we don't need multiple temporary files. 73 */ 74 int 75 imapTmp(void) 76 { 77 char buf[ERRMAX], name[MboxNameLen]; 78 int tries, fd; 79 80 snprint(name, sizeof(name), "/mail/box/%s/mbox.tmp.imp", username); 81 for(tries = 0; tries < LockSecs*2; tries++){ 82 fd = create(name, ORDWR|ORCLOSE|OCEXEC, DMEXCL|0600); 83 if(fd >= 0) 84 return fd; 85 errstr(buf, sizeof buf); 86 if(cistrstr(buf, "locked") == nil) 87 break; 88 sleep(500); 89 } 90 return -1; 91 } 92 93 /* 94 * open a file which might be locked. 95 * if it is, spin until available 96 */ 97 int 98 openLocked(char *dir, char *file, int mode) 99 { 100 char buf[ERRMAX]; 101 int tries, fd; 102 103 for(tries = 0; tries < LockSecs*2; tries++){ 104 fd = cdOpen(dir, file, mode); 105 if(fd >= 0) 106 return fd; 107 errstr(buf, sizeof buf); 108 if(cistrstr(buf, "locked") == nil) 109 break; 110 sleep(500); 111 } 112 return -1; 113 } 114 115 int 116 fqid(int fd, Qid *qid) 117 { 118 Dir *d; 119 120 d = dirfstat(fd); 121 if(d == nil) 122 return -1; 123 *qid = d->qid; 124 free(d); 125 return 0; 126 } 127 128 ulong 129 mapInt(NamedInt *map, char *name) 130 { 131 int i; 132 133 for(i = 0; map[i].name != nil; i++) 134 if(cistrcmp(map[i].name, name) == 0) 135 break; 136 return map[i].v; 137 } 138 139 char* 140 estrdup(char *s) 141 { 142 char *t; 143 144 t = emalloc(strlen(s) + 1); 145 strcpy(t, s); 146 return t; 147 } 148 149 void* 150 emalloc(ulong n) 151 { 152 void *p; 153 154 p = malloc(n); 155 if(p == nil) 156 bye("server out of memory"); 157 setmalloctag(p, getcallerpc(&n)); 158 return p; 159 } 160 161 void* 162 ezmalloc(ulong n) 163 { 164 void *p; 165 166 p = malloc(n); 167 if(p == nil) 168 bye("server out of memory"); 169 setmalloctag(p, getcallerpc(&n)); 170 memset(p, 0, n); 171 return p; 172 } 173 174 void* 175 erealloc(void *p, ulong n) 176 { 177 p = realloc(p, n); 178 if(p == nil) 179 bye("server out of memory"); 180 setrealloctag(p, getcallerpc(&p)); 181 return p; 182 } 183