ref: 614e174dca25e4fa70b5a79be5e08a3b3ba3474a
parent: effe53dedb08022fc45652e44193ba43fb5fbef3
author: sirjofri <sirjofri@sirjofri.de>
date: Fri Oct 18 14:09:32 EDT 2024
first version of import. to import, write vcf file to import, then close the file
--- a/libvcard/mkfile
+++ b/libvcard/mkfile
@@ -6,7 +6,7 @@
vlex.$O\
vcard.$O\
-HFILES=vcard.h
+HFILES=vcard.h y.tab.h
YFILES=vcard.y
@@ -15,4 +15,4 @@
</sys/src/cmd/mklib
#y.tab.h y.tab.c: $YFILES
-# yacc -dv -D0 $YFLAGS $prereq
+# yacc -dv -D4 $YFLAGS $prereq
--- a/libvcard/vcard.c
+++ b/libvcard/vcard.c
@@ -9,8 +9,15 @@
static Vcard*
parse(char *s)
{
+ if (!s) {
+ werrstr("parse string is nil");
+ return nil;
+ }
+ /* todo: somewhat weird, but this works */
memset(&vcstate, sizeof vcstate, 0);
vcparsestr = s;
+ vcstate.str = s;
+ vcstate.s = nil;
vcparsecard = nil;
yyparse();
return vcparsecard;
@@ -21,6 +28,9 @@
{
char *s;
char *end;
+
+ if (!str)
+ return;
end = strchr(str, 0);
--- a/libvcard/vcard.y
+++ b/libvcard/vcard.y
@@ -108,8 +108,8 @@
%%
vclist:
- vcard { $$ = $1; enqueue($1, nil); }
- | vcard vclist { $$ = $1; enqueue($1, $2); }
+ vcard vclist { $$ = $1; enqueue($1, $2); }
+ | /* empty */ { $$ = nil; }
;
vcard:
--- a/libvcard/vlex.c
+++ b/libvcard/vlex.c
@@ -85,14 +85,19 @@
int n;
char *s, *t;
- if (!vcparsestr)
- return 0;
-
if (!vcstate.s) {
- vcstate.s = vcparsestr;
- vcstate.str = vcparsestr;
+ vcstate.s = vcstate.str;
}
+ /*
+ fprint(2, "vcstate:\n"
+ " str: %p\n"
+ " s: %c\n"
+ " invalue: %d\n"
+ " inquote: %d\n",
+ vcstate.str, *vcstate.s, vcstate.invalue, vcstate.inquote);
+ */
+
/* value string */
if (vcstate.invalue) {
s = strstr(vcstate.s, "\r\n");
@@ -108,7 +113,7 @@
return FWORD;
}
- /* TODO: quoted string */
+ /* quoted string */
if (vcstate.inquote == 1) {
s = strchr(vcstate.s, '"');
if (!s) {
--- a/vcardfs.c
+++ b/vcardfs.c
@@ -89,6 +89,7 @@
Vcard *cards = nil;
static char* getcardname(Vcard*);
+static void initcardfiles(Vcard *chain);
static Vfile*
emkvfile(int level, Vcard *c, Vline *l, Vparam *p, Vfile *cfile)
@@ -281,6 +282,36 @@
}
static void
+readimportdata(Req *r, Vfile *f)
+{
+ char *s;
+ long n, m;
+
+ if (f->serialized) {
+ m = strlen(f->serialized);
+ if (r->ifcall.offset + r->ifcall.count + 1 > m)
+ n = r->ifcall.offset + r->ifcall.count + 1;
+ else
+ n = m;
+ s = mallocz(n, 1);
+ if (!s)
+ sysfatal("%r");
+ strcpy(s, f->serialized);
+ memcpy(s + r->ifcall.offset, r->ifcall.data, r->ifcall.count);
+ free(f->serialized);
+ f->serialized = s;
+ } else {
+ s = mallocz(r->ifcall.count + 1, 1);
+ if (!s)
+ sysfatal("%r");
+ memcpy(s, r->ifcall.data, r->ifcall.count);
+ f->serialized = s;
+ }
+ r->ofcall.count = r->ifcall.count;
+ respond(r, nil);
+}
+
+static void
fswrite(Req *r)
{
Vfile *f;
@@ -288,6 +319,9 @@
switch (f->level) {
case Qctl:
break;
+ case Qimport:
+ readimportdata(r, f);
+ return;
case Qexport:
respond(r, "not a function");
return;
@@ -374,10 +408,53 @@
respond(r, "create prohibited");
}
+static void
+fsdestroyfid(Fid *fid)
+{
+ File *f;
+ Vfile *vf;
+ Vcard *ncards, *nc;
+
+ f = fid->file;
+ if (!f)
+ return;
+ vf = f->aux;
+ if (!vf)
+ return;
+
+ switch (vf->level) {
+ case Qimport:
+ break;
+ default:
+ return;
+ }
+
+ if (!vf->serialized)
+ return;
+
+ ncards = vcparse(vf->serialized);
+ if (!ncards) {
+ fprint(2, "error parsing import: %r");
+ return;
+ }
+ free(vf->serialized);
+ vf->serialized = nil;
+
+ fprint(2, "serialized:\n%p", ncards);
+
+ initcardfiles(ncards);
+
+ for (nc = cards; nc->next; nc = nc->next)
+ continue;
+
+ nc->next = ncards;
+}
+
Srv fs = {
.read = fsread,
.write = fswrite,
.create = fscreate,
+ .destroyfid = fsdestroyfid,
};
/* TODO: LOOKAT:
@@ -510,7 +587,7 @@
fs.tree = alloctree("vcf", "vcf", DMDIR|0555, nil);
createfile(fs.tree->root, "ctl", user, 0666,
emkvfile(Qctl, nil, nil, nil, nil));
- createfile(fs.tree->root, "import", user, 0666,
+ createfile(fs.tree->root, "import", user, 0222,
emkvfile(Qimport, nil, nil, nil, nil));
f = emkvfile(Qgexport, nil, nil, nil, nil);
f->cardfile = f;