1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include "imap4d.h" 5 6 int 7 cistrcmp(char *s1, char *s2) 8 { 9 int c1, c2; 10 11 while(*s1){ 12 c1 = *s1++; 13 c2 = *s2++; 14 15 if(c1 >= 'A' && c1 <= 'Z') 16 c1 -= 'A' - 'a'; 17 18 if(c2 >= 'A' && c2 <= 'Z') 19 c2 -= 'A' - 'a'; 20 21 if(c1 != c2) 22 return c1 - c2; 23 } 24 return -*s2; 25 } 26 27 int 28 cistrncmp(char *s1, char *s2, int n) 29 { 30 int c1, c2; 31 32 while(*s1 && n-- > 0){ 33 c1 = *s1++; 34 c2 = *s2++; 35 36 if(c1 >= 'A' && c1 <= 'Z') 37 c1 -= 'A' - 'a'; 38 39 if(c2 >= 'A' && c2 <= 'Z') 40 c2 -= 'A' - 'a'; 41 42 if(c1 != c2) 43 return c1 - c2; 44 } 45 if(n == 0) 46 return 0; 47 return -*s2; 48 } 49 50 char* 51 cistrstr(char *s, char *sub) 52 { 53 int c, csub, n; 54 55 csub = *sub; 56 if(csub == '\0') 57 return s; 58 if(csub >= 'A' && csub <= 'Z') 59 csub -= 'A' - 'a'; 60 sub++; 61 n = strlen(sub); 62 for(; c = *s; s++){ 63 if(c >= 'A' && c <= 'Z') 64 c -= 'A' - 'a'; 65 if(c == csub && cistrncmp(s+1, sub, n) == 0) 66 return s; 67 } 68 return nil; 69 } 70 71 /* 72 * reverse string [s:e) in place 73 */ 74 void 75 strrev(char *s, char *e) 76 { 77 int c; 78 79 while(--e > s){ 80 c = *s; 81 *s++ = *e; 82 *e = c; 83 } 84 } 85 86 int 87 isdotdot(char *s) 88 { 89 return s[0] == '.' && s[1] == '.' && (s[2] == '/' || s[2] == '\0'); 90 } 91 92 int 93 issuffix(char *suf, char *s) 94 { 95 int n; 96 97 n = strlen(s) - strlen(suf); 98 if(n < 0) 99 return 0; 100 return strcmp(s + n, suf) == 0; 101 } 102 103 int 104 isprefix(char *pre, char *s) 105 { 106 return strncmp(pre, s, strlen(pre)) == 0; 107 } 108 109 int 110 ciisprefix(char *pre, char *s) 111 { 112 return cistrncmp(pre, s, strlen(pre)) == 0; 113 } 114 115 char* 116 readFile(int fd) 117 { 118 Dir d; 119 char *s; 120 121 if(dirfstat(fd, &d) < 0) 122 return nil; 123 s = canAlloc(&parseCan, d.length + 1, 0); 124 if(s == nil) 125 return nil; 126 if(read(fd, s, d.length) != d.length) 127 return 0; 128 s[d.length] = '\0'; 129 return s; 130 } 131 132 /* 133 * create the imap tmp file 134 */ 135 int 136 imapTmp(void) 137 { 138 char buf[ERRLEN], name[5*NAMELEN]; 139 int tries, fd; 140 141 snprint(name, sizeof(name), "/mail/box/%s/mbox.tmp.imp", username); 142 for(tries = 0; tries < LockSecs*2; tries++){ 143 fd = create(name, ORDWR|ORCLOSE|OCEXEC, CHEXCL|0600); 144 if(fd >= 0) 145 return fd; 146 errstr(buf); 147 if(cistrstr(buf, "locked") == nil) 148 break; 149 sleep(500); 150 } 151 return -1; 152 } 153 154 /* 155 * open a file which might be locked. 156 * if it is, spin until available 157 */ 158 int 159 openLocked(char *dir, char *file, int mode) 160 { 161 char buf[ERRLEN]; 162 int tries, fd; 163 164 for(tries = 0; tries < LockSecs*2; tries++){ 165 fd = cdOpen(dir, file, mode); 166 if(fd >= 0) 167 return fd; 168 errstr(buf); 169 if(cistrstr(buf, "locked") == nil) 170 break; 171 sleep(500); 172 } 173 return -1; 174 } 175 176 ulong 177 mapInt(NamedInt *map, char *name) 178 { 179 int i; 180 181 for(i = 0; map[i].name != nil; i++) 182 if(cistrcmp(map[i].name, name) == 0) 183 break; 184 return map[i].v; 185 } 186 187 char* 188 estrdup(char *s) 189 { 190 char *t; 191 192 t = emalloc(strlen(s) + 1); 193 strcpy(t, s); 194 return t; 195 } 196 197 void* 198 emalloc(ulong n) 199 { 200 void *p; 201 202 p = malloc(n); 203 if(p == nil) 204 bye("server out of memory"); 205 return p; 206 } 207 208 void* 209 ezmalloc(ulong n) 210 { 211 void *p; 212 213 p = malloc(n); 214 if(p == nil) 215 bye("server out of memory"); 216 memset(p, 0, n); 217 return p; 218 } 219 220 void* 221 erealloc(void *p, ulong n) 222 { 223 p = realloc(p, n); 224 if(p == nil) 225 bye("server out of memory"); 226 return p; 227 } 228