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,
};