shithub: vcardfs

Download patch

ref: 5cc3bea8aa3d93571b40c4ce687e8fe5c610ecf9
parent: 071b196a37e0e88ee005c68f84d90753d2a98a5b
author: sirjofri <sirjofri@sirjofri.de>
date: Mon Oct 21 12:41:25 EDT 2024

fixes parsing, allows removal of params

--- a/libvcard/vcard.c
+++ b/libvcard/vcard.c
@@ -227,3 +227,50 @@
 	}
 	return s;
 }
+
+void
+vcfreeparams(Vparam *params)
+{
+	Vparam *p, *np;
+	
+	for (p = params; p; p = np) {
+		np = p->next;
+		if (p->name)
+			free(p->name);
+		if (p->value)
+			free(p->value);
+		free(p);
+	}
+}
+
+void
+vcfreelines(Vline *lines)
+{
+	Vline *l, *nl;
+	
+	for (l = lines; l; l = nl) {
+		nl = l->next;
+		if (l->name)
+			free(l->name);
+		if (l->value)
+			free(l->value);
+		if (l->group)
+			free(l->group);
+		if (l->params)
+			vcfreeparams(l->params);
+		free(l);
+	}
+}
+
+void
+vcfreecards(Vcard *cards)
+{
+	Vcard *c, *nc;
+	
+	for (c = cards; c; c = nc) {
+		nc = c->next;
+		if (c->content)
+			vcfreelines(c->content);
+		free(c);
+	}
+}
--- a/libvcard/vcard.h
+++ b/libvcard/vcard.h
@@ -35,3 +35,7 @@
 Vcard* vcparse(char*);
 Vcard* vcparsefile(char*);
 char* vcmserialize(Vcard*);
+
+void vcfreeparams(Vparam*);
+void vcfreelines(Vline*);
+void vcfreecards(Vcard*);
--- a/libvcard/vcard.y
+++ b/libvcard/vcard.y
@@ -3,6 +3,16 @@
 #include <libc.h>
 #include "vcard.h"
 
+static void
+iltolower(char *s)
+{
+	while (*s) {
+		if (*s >= 'A' && *s <= 'Z')
+			*s = *s - 'A' + 'a';
+		s++;
+	}
+}
+
 Vcard *vcparsecard;
 
 extern int yylex(void);
@@ -47,6 +57,7 @@
 	Vline *vl;
 	vl = mallocz(sizeof(Vline), 1);
 	vl->name = name;
+	iltolower(vl->name);
 	vl->value = value;
 	vl->params = params;
 	vl->group = group;
@@ -70,15 +81,6 @@
 	return vp;
 }
 
-static char*
-xname(char *s)
-{
-	char *n;
-	n = smprint("x-%s", s);
-	free(s);
-	return n;
-}
-
 %}
 
 %union {
@@ -92,7 +94,6 @@
 %token	<i> 	BEGIN END CRLF
 
 %token	<s> 	WORD SWORD FWORD
-%token	<s> 	PROPNAME
 
 %type	<s> 	pvalue
 
@@ -139,6 +140,6 @@
 	;
 
 group: SWORD;
-name: PROPNAME;
+name: SWORD;
 
 value: WORD | SWORD | FWORD;
--- a/libvcard/vlex.c
+++ b/libvcard/vlex.c
@@ -3,6 +3,8 @@
 #include "vcard.h"
 #include "y.tab.h"
 
+//#define DEBUG
+
 static void
 iltolower(char *s)
 {
@@ -31,15 +33,17 @@
 		vcstate.s = vcstate.str;
 	}
 	
-	/*
+#ifdef DEBUG
 	fprint(2, "vcstate:\n"
 		"  str: %p\n"
 		"  s: %c\n"
 		"  invalue: %d\n"
-		"  inquote: %d\n",
-		vcstate.str, *vcstate.s, vcstate.invalue, vcstate.inquote);
-	*/
+		"  inquote: %d\n"
+		"  haspropname: %d\n",
+		vcstate.str, *vcstate.s, vcstate.invalue, vcstate.inquote, vcstate.haspropname);
+#endif
 	
+	
 	/* value string */
 	if (vcstate.invalue) {
 		s = strstr(vcstate.s, "\r\n");
@@ -53,6 +57,9 @@
 		vcstate.s = s;
 		vcstate.invalue = 0;
 		vcstate.haspropname = 0;
+#ifdef DEBUG
+		fprint(2, "  FWORD: %s\n", yylval.s);
+#endif
 		return FWORD;
 	}
 	
@@ -67,6 +74,9 @@
 		memcpy(yylval.s, vcstate.s, s - vcstate.s);
 		vcstate.s = s;
 		vcstate.inquote = 2;
+#ifdef DEBUG
+		fprint(2, "  FWORD: %s\n", yylval.s);
+#endif
 		return FWORD;
 	}
 	
@@ -86,6 +96,9 @@
 		}
 		n = *vcstate.s;
 		vcstate.s++;
+#ifdef DEBUG
+		fprint(2, "  VERBCHAR: '%c'\n", n);
+#endif
 		return n;
 	}
 	
@@ -96,6 +109,9 @@
 		while (cistrncmp(vcstate.s, "\r\n", 2) == 0) {
 			vcstate.s += 2;
 		}
+#ifdef DEBUG
+		fprint(2, "  CRLF\n");
+#endif
 		return CRLF;
 	}
 	
@@ -103,6 +119,9 @@
 	n = strlen(beginstr);
 	if (cistrncmp(vcstate.s, beginstr, n) == 0) {
 		vcstate.s += n;
+#ifdef DEBUG
+		fprint(2, "  BEGIN\n");
+#endif
 		return BEGIN;
 	}
 	
@@ -110,28 +129,26 @@
 	n = strlen(endstr);
 	if (cistrncmp(vcstate.s, endstr, n) == 0) {
 		vcstate.s += n;
+#ifdef DEBUG
+		fprint(2, "  END\n");
+#endif
 		return END;
 	}
 	
-	if (!vcstate.haspropname) {
-		s = strchr(vcstate.s, ':');
-		t = strchr(vcstate.s, ';');
-		s = s < t ? s : t;
-		n = s - vcstate.s;
-		yylval.s = mallocz(n + 1, 1);
-		memcpy(yylval.s, vcstate.s, n);
-		vcstate.s += n;
-		vcstate.haspropname++;
-		return PROPNAME;
-	}
-	
-	/* assume SWORD string (unquoted param value) */
+	/* assume SWORD string (unquoted param value or param name) */
 	s = strchr(vcstate.s, ':');
 	t = strchr(vcstate.s, ';');
-	s = s < t ? s : t;
+	if (t)
+		s = s < t ? s : t;
+	t = strchr(vcstate.s, '=');
+	if (t)
+		s = s < t ? s : t;
 	n = s - vcstate.s;
 	yylval.s = mallocz(n + 1, 1);
 	memcpy(yylval.s, vcstate.s, n);
 	vcstate.s += n;
+#ifdef DEBUG
+	fprint(2, "  SWORD: %s\n", yylval.s);
+#endif
 	return SWORD;
 }
--- a/mkfile
+++ b/mkfile
@@ -9,4 +9,4 @@
 
 $LIB:V:
 	cd libvcard
-	mk
+	mk $MKFLAGS
--- a/vcardfs.c
+++ b/vcardfs.c
@@ -655,10 +655,63 @@
 	nc->next = ncards;
 }
 
+static void
+rmparam(Req *r, Vfile *f)
+{
+	Vline *l = f->line;
+	Vparam *p = f->param;
+	Vparam *cp;
+	
+	if (l->params == p) {
+		l->params = p->next;
+		p->next = nil;
+		vcfreeparams(p);
+		f->param = nil;
+		respond(r, nil);
+		return;
+	}
+	
+	for (cp = l->params; cp; cp = cp->next)
+		if (cp->next == p)
+			break;
+	
+	if (!cp) {
+		respond(r, "param not found");
+		return;
+	}
+	cp->next = p->next;
+	p->next = nil;
+	vcfreeparams(p);
+	f->param = nil;
+	respond(r, nil);
+}
+
+static void
+fsremove(Req *r)
+{
+	Vfile *vf;
+	
+	vf = r->fid->file->aux;
+	switch (vf->level) {
+	case Qcard:
+	case Qline:
+	case Qgroup:
+		break;
+	case Qparamdata:
+		rmparam(r, vf);
+		return;
+	default:
+		respond(r, "remove prohibited");
+		return;
+	}
+	respond(r, nil);
+}
+
 Srv fs = {
 	.read = fsread,
 	.write = fswrite,
 	.create = fscreate,
+	.remove = fsremove,
 	.destroyfid = fsdestroyfid,
 };