shithub: vcardfs

Download patch

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;