ref: a5b091764d98d99ac86694bb11e4f674fd681506
parent: bb10512127f96aeb40f9f1e8f32768032c6425fe
author: sirjofri <[email protected]>
date: Fri Oct 18 06:11:17 EDT 2024
makes export work
--- a/libvcard/vcard.c
+++ b/libvcard/vcard.c
@@ -80,4 +80,114 @@
vc = vcparse(s);
free(s);
return vc;
-}
\ No newline at end of file
+}
+
+static char*
+serializeparams(Vparam *param)
+{
+ Vparam *p;
+ char *s, *ns, *ps;
+
+ if (!param)
+ return strdup("");
+
+ s = nil;
+ for (p = param; p; p = p->next) {
+ // TODO: only quote if needed
+ ps = smprint(";%s=\"%s\"", p->name, p->value);
+ if (!ps)
+ return nil;
+
+ if (!s)
+ s = ps;
+ else {
+ ns = smprint("%s%s", s, ps);
+ free(s);
+ free(ps);
+ s = ns;
+ }
+ }
+ return s;
+}
+
+static char*
+serializelines(Vline *line)
+{
+ Vline *l;
+ char *s, *ns, *ls, *ps;
+
+ s = nil;
+ for (l = line; l; l = l->next) {
+ ps = serializeparams(l->params);
+ if (!ps) {
+ if (s) free(s);
+ return nil;
+ }
+ ls = smprint(
+ "%s%s" /* group string */
+ "%s%s:%s\r\n", /* name, param, value */
+ (l->group ? l->group : ""), /* group string */
+ (l->group ? "." : ""), /* group dot */
+ l->name, ps, l->value);
+ if (!ls) {
+ if (s) free(s);
+ return nil;
+ }
+ if (!s) {
+ s = ls;
+ free(ps);
+ } else {
+ ns = smprint("%s%s", s, ls);
+ free(s);
+ free(ls);
+ free(ps);
+ s = ns;
+ if (!s)
+ return nil;
+ }
+ }
+ return s;
+}
+
+char*
+vcmserialize(Vcard *card)
+{
+ Vcard *c;
+ char *s, *ns, *cs, *ls;
+
+ s = nil;
+ for (c = card; c; c = c->next) {
+ if (!c->content)
+ continue;
+ ls = serializelines(c->content);
+ if (!ls) {
+ if (s) free(s);
+ return nil;
+ }
+ cs = smprint(
+ "BEGIN:VCARD\r\n"
+ "VERSION:4.0\r\n"
+ "%s"
+ "END:VCARD\r\n",
+ ls);
+ if (!cs) {
+ free(ls);
+ if (s) free(s);
+ return nil;
+ }
+
+ if (!s) {
+ s = cs;
+ free(ls);
+ } else {
+ ns = smprint("%s%s", s, cs);
+ free(s);
+ free(ls);
+ free(cs);
+ s = ns;
+ if (!s)
+ return nil;
+ }
+ }
+ return s;
+}
--- a/libvcard/vcard.h
+++ b/libvcard/vcard.h
@@ -33,3 +33,4 @@
Vcard* vcparse(char*);
Vcard* vcparsefile(char*);
+char* vcmserialize(Vcard*);
--- a/vcardfs.c
+++ b/vcardfs.c
@@ -73,6 +73,7 @@
Vcard *card;
Vline *line;
Vparam *param;
+ char *serialized;
};
char *user = nil;
@@ -97,6 +98,34 @@
}
static void
+readserialized(Req *r, Vfile *f)
+{
+ int n;
+ char *s;
+ Vcard *tmp;
+
+ if (f->serialized)
+ goto Readin;
+
+ tmp = f->card->next;
+ f->card->next = nil;
+ f->serialized = vcmserialize(f->card);
+ f->card->next = tmp;
+
+ if (!f->serialized) {
+ respond(r, "unable to serialize");
+ return;
+ }
+
+Readin:
+ s = f->serialized + r->ifcall.offset;
+ n = strlen(s);
+ n = n < r->ifcall.count ? n : r->ifcall.count;
+ readbuf(r, s, n);
+ respond(r, nil);
+}
+
+static void
fsread(Req *r)
{
Vfile *f;
@@ -107,6 +136,9 @@
return;
case Qimport:
respond(r, nil);
+ return;
+ case Qexport:
+ readserialized(r, f);
return;
case Qdata:
readstr(r, f->line->value);