summaryrefslogtreecommitdiff
path: root/sys/src/cmd/upas/imap4d/utils.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2017-03-12 17:15:03 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2017-03-12 17:15:03 +0100
commit963cfc9a6f6e721f52aa949e6d1af0c3e8dc2ecc (patch)
tree749b74875dbc49bcf6ed0776648b8f0ef9417407 /sys/src/cmd/upas/imap4d/utils.c
parent8177d20fb2709ba9290dfd41308b8e5bee4e00f8 (diff)
merging erik quanstros nupas
Diffstat (limited to 'sys/src/cmd/upas/imap4d/utils.c')
-rw-r--r--sys/src/cmd/upas/imap4d/utils.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/sys/src/cmd/upas/imap4d/utils.c b/sys/src/cmd/upas/imap4d/utils.c
new file mode 100644
index 000000000..b2a8bb046
--- /dev/null
+++ b/sys/src/cmd/upas/imap4d/utils.c
@@ -0,0 +1,209 @@
+#include "imap4d.h"
+
+/*
+ * reverse string [s:e) in place
+ */
+void
+strrev(char *s, char *e)
+{
+ int c;
+
+ while(--e > s){
+ c = *s;
+ *s++ = *e;
+ *e = c;
+ }
+}
+
+int
+isdotdot(char *s)
+{
+ return s[0] == '.' && s[1] == '.' && (s[2] == '/' || s[2] == 0);
+}
+
+int
+issuffix(char *suf, char *s)
+{
+ int n;
+
+ n = strlen(s) - strlen(suf);
+ if(n < 0)
+ return 0;
+ return strcmp(s + n, suf) == 0;
+}
+
+int
+isprefix(char *pre, char *s)
+{
+ return strncmp(pre, s, strlen(pre)) == 0;
+}
+
+char*
+readfile(int fd)
+{
+ char *s;
+ long length;
+ Dir *d;
+
+ d = dirfstat(fd);
+ if(d == nil)
+ return nil;
+ length = d->length;
+ free(d);
+ s = binalloc(&parsebin, length + 1, 0);
+ if(s == nil || readn(fd, s, length) != length)
+ return nil;
+ s[length] = 0;
+ return s;
+}
+
+/*
+ * create the imap tmp file.
+ * it just happens that we don't need multiple temporary files.
+ */
+int
+imaptmp(void)
+{
+ char buf[ERRMAX], name[Pathlen];
+ int tries, fd;
+
+ snprint(name, sizeof name, "/mail/box/%s/mbox.tmp.imp", username);
+ for(tries = 0; tries < Locksecs*2; tries++){
+ fd = create(name, ORDWR|ORCLOSE|OCEXEC, DMEXCL|0600);
+ if(fd >= 0)
+ return fd;
+ errstr(buf, sizeof buf);
+ if(cistrstr(buf, "locked") == nil)
+ break;
+ sleep(500);
+ }
+ return -1;
+}
+
+/*
+ * open a file which might be locked.
+ * if it is, spin until available
+ */
+static char *etab[] = {
+ "not found",
+ "does not exist",
+ "file is locked",
+ "exclusive lock",
+ "already exists",
+};
+
+static int
+bad(int idx)
+{
+ char buf[ERRMAX];
+ int i;
+
+ rerrstr(buf, sizeof buf);
+ for(i = idx; i < nelem(etab); i++)
+ if(strstr(buf, etab[i]))
+ return 0;
+ return 1;
+}
+
+int
+openlocked(char *dir, char *file, int mode)
+{
+ int i, fd;
+
+ for(i = 0; i < 30; i++){
+ if((fd = cdopen(dir, file, mode)) >= 0 || bad(0))
+ return fd;
+ if((fd = cdcreate(dir, file, mode|OEXCL, DMEXCL|0600)) >= 0 || bad(2))
+ return fd;
+ sleep(1000);
+ }
+ werrstr("lock timeout");
+ return -1;
+}
+
+int
+fqid(int fd, Qid *qid)
+{
+ Dir *d;
+
+ d = dirfstat(fd);
+ if(d == nil)
+ return -1;
+ *qid = d->qid;
+ free(d);
+ return 0;
+}
+
+uint
+mapint(Namedint *map, char *name)
+{
+ int i;
+
+ for(i = 0; map[i].name != nil; i++)
+ if(cistrcmp(map[i].name, name) == 0)
+ break;
+ return map[i].v;
+}
+
+char*
+estrdup(char *s)
+{
+ char *t;
+
+ t = emalloc(strlen(s) + 1);
+ strcpy(t, s);
+ return t;
+}
+
+void*
+emalloc(ulong n)
+{
+ void *p;
+
+ p = malloc(n);
+ if(p == nil)
+ bye("server out of memory");
+ setmalloctag(p, getcallerpc(&n));
+ return p;
+}
+
+void*
+ezmalloc(ulong n)
+{
+ void *p;
+
+ p = malloc(n);
+ if(p == nil)
+ bye("server out of memory");
+ setmalloctag(p, getcallerpc(&n));
+ memset(p, 0, n);
+ return p;
+}
+
+void*
+erealloc(void *p, ulong n)
+{
+ p = realloc(p, n);
+ if(p == nil)
+ bye("server out of memory");
+ setrealloctag(p, getcallerpc(&p));
+ return p;
+}
+
+void
+setname(char *fmt, ...)
+{
+ char buf[128], buf2[32], *p;
+ int fd;
+ va_list arg;
+
+ va_start(arg, fmt);
+ p = vseprint(buf, buf + sizeof buf, fmt, arg);
+ va_end(arg);
+
+ snprint(buf2, sizeof buf2, "#p/%d/args", getpid());
+ if((fd = open(buf2, OWRITE)) >= 0){
+ write(fd, buf, p - buf);
+ close(fd);
+ }
+}