shithub: vcardfs

Download patch

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);