/* * Write out the quota entry 'quota' */ EXPORTED int quota_write(struct quota *quota, struct txn **tid) { int r; int qrlen; int res; struct buf buf = BUF_INITIALIZER; struct dlist *dl = NULL; if (!quota->root) return IMAP_QUOTAROOT_NONEXISTENT; qrlen = strlen(quota->root); if (!qrlen) return IMAP_QUOTAROOT_NONEXISTENT; dl = dlist_newkvlist(NULL, NULL); for (res = 0; res < QUOTA_NUMRESOURCES; res++) { struct dlist *item = dlist_newlist(dl, quota_db_names[res]); dlist_setnum64(item, NULL, quota->useds[res]); if (quota->limits[res] != QUOTA_UNLIMITED) dlist_setnum64(item, NULL, quota->limits[res]); } if (quota->scanmbox) { struct dlist *scan = dlist_newkvlist(dl, "SCAN"); dlist_setatom(scan, "MBOX", quota->scanmbox); for (res = 0; res < QUOTA_NUMRESOURCES; res++) dlist_setnum64(scan, quota_db_names[res], quota->scanuseds[res]); } dlist_printbuf(dl, 0, &buf); r = cyrusdb_store(qdb, quota->root, qrlen, buf.s, buf.len, tid); switch (r) { case CYRUSDB_OK: r = 0; break; case CYRUSDB_AGAIN: r = IMAP_AGAIN; break; default: syslog(LOG_ERR, "DBERROR: error storing %s: %s", quota->root, cyrusdb_strerror(r)); r = IMAP_IOERROR; break; } dlist_free(&dl); buf_free(&buf); return r; }
strcat(buf+*buflen, myarg); *buflen += len; return 0; } static void notify_dlist(const char *sockpath, const char *method, const char *class, const char *priority, const char *user, const char *mailbox, int nopt, const char **options, const char *message, const char *fname) { struct sockaddr_un sun_data; struct protstream *in = NULL, *out = NULL; struct dlist *dl = dlist_newkvlist(NULL, "NOTIFY"); struct dlist *res = NULL; struct dlist *il; int c; int soc = -1; int i; dlist_setatom(dl, "METHOD", method); dlist_setatom(dl, "CLASS", class); dlist_setatom(dl, "PRIORITY", priority); dlist_setatom(dl, "USER", user); dlist_setatom(dl, "MAILBOX", mailbox); il = dlist_newlist(dl, "OPTIONS"); for (i = 0; i < nopt; i++) dlist_setatom(il, NULL, options[i]); dlist_setatom(dl, "MESSAGE", message);
EXPORTED int dlist_parse(struct dlist **dlp, int parsekey, struct protstream *in, const char *alt_reserve_base) { struct dlist *dl = NULL; static struct buf kbuf; static struct buf vbuf; int c; /* handle the key if wanted */ if (parsekey) { c = getastring(in, NULL, &kbuf); c = next_nonspace(in, c); } else { buf_setcstr(&kbuf, ""); c = prot_getc(in); } /* connection dropped? */ if (c == EOF) goto fail; /* check what sort of value we have */ if (c == '(') { dl = dlist_newlist(NULL, kbuf.s); c = next_nonspace(in, ' '); while (c != ')') { struct dlist *di = NULL; prot_ungetc(c, in); c = dlist_parse(&di, 0, in, alt_reserve_base); if (di) dlist_stitch(dl, di); c = next_nonspace(in, c); if (c == EOF) goto fail; } c = prot_getc(in); } else if (c == '%') { /* no whitespace allowed here */ c = prot_getc(in); if (c == '(') { dl = dlist_newkvlist(NULL, kbuf.s); c = next_nonspace(in, ' '); while (c != ')') { struct dlist *di = NULL; prot_ungetc(c, in); c = dlist_parse(&di, 1, in, alt_reserve_base); if (di) dlist_stitch(dl, di); c = next_nonspace(in, c); if (c == EOF) goto fail; } } else if (c == '{') { struct message_guid tmp_guid; static struct buf pbuf, gbuf; unsigned size = 0; const char *fname; const char *part; c = getastring(in, NULL, &pbuf); if (c != ' ') goto fail; c = getastring(in, NULL, &gbuf); if (c != ' ') goto fail; c = getuint32(in, &size); if (c != '}') goto fail; c = prot_getc(in); if (c == '\r') c = prot_getc(in); if (c != '\n') goto fail; if (!message_guid_decode(&tmp_guid, gbuf.s)) goto fail; part = alt_reserve_base ? alt_reserve_base : pbuf.s; if (reservefile(in, part, &tmp_guid, size, &fname)) goto fail; dl = dlist_setfile(NULL, kbuf.s, pbuf.s, &tmp_guid, size, fname); /* file literal */ } else { /* unknown percent type */ goto fail; } c = prot_getc(in); } else if (c == '{') { prot_ungetc(c, in); /* could be binary in a literal */ c = getbastring(in, NULL, &vbuf); dl = dlist_setmap(NULL, kbuf.s, vbuf.s, vbuf.len); } else if (c == '\\') { /* special case for flags */ prot_ungetc(c, in); c = getastring(in, NULL, &vbuf); dl = dlist_setflag(NULL, kbuf.s, vbuf.s); } else { prot_ungetc(c, in); c = getnastring(in, NULL, &vbuf); dl = dlist_setatom(NULL, kbuf.s, vbuf.s); } /* success */ *dlp = dl; return c; fail: dlist_free(&dl); return EOF; }