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