xref: /plan9-contrib/sys/src/cmd/ip/imap4d/utils.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
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