ref: 8604a6db811e57e632a6e416fcc944e9884ddff5
parent: f43b5b9a6d055938ad4f497e7e556a1e3ad5365c
author: sirjofri <sirjofri@sirjofri.de>
date: Thu Oct 17 09:17:56 EDT 2024
rename vcffs -> vcardfs
--- a/README.md
+++ b/README.md
@@ -3,13 +3,13 @@
## Contents
- `libvcard`: library for parsing and writing vcard data
-- `vcffs`: vcard filesystem (vcf fs); name might change in the future
+- `vcardfs`: vcard filesystem
## Usage
-### vcffs
+### vcardfs
-Usage: vcffs [-m mtpt] [-s srv] database.vcf
+Usage: vcardfs [-m mtpt] [-s srv] database.vcf
/mnt/vcf/
ctl
--- a/mkfile
+++ b/mkfile
@@ -1,7 +1,7 @@
</$objtype/mkfile
TARG=pim\
- vcffs\
+ vcardfs\
LIB=libvcard/libvcard.a$O
--- /dev/null
+++ b/vcardfs.c
@@ -1,0 +1,278 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+#include "libvcard/vcard.h"
+
+/* rough structure
+
+/john-doe/
+ /fn/
+ /data (line value)
+ /group (line group)
+ /param (param value)
+ /tel/
+ /data (line value)
+ /group (line group)
+ /param (param value)
+/ctl
+ - "write" (save file)
+/import
+ - write new vcf file to import
+
+*/
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s [-s srv] [-m mtpt] file\n", argv0);
+ exits("usage");
+}
+
+static void*
+emalloc(long n)
+{
+ void *p;
+ p = mallocz(n, 1);
+ if (!p)
+ sysfatal("emalloc: %r");
+ return p;
+}
+
+static char*
+estrdup(char *s)
+{
+ void *t;
+ t = strdup(s);
+ if (!t)
+ sysfatal("estrdup: %r");
+ return t;
+}
+
+enum {
+ Qroot,
+ Qctl,
+ Qimport,
+ Qcard,
+ Qline,
+ Qdata,
+ Qgroup,
+ Qparams,
+ Qparamdata,
+};
+
+typedef struct Vfile Vfile;
+struct Vfile {
+ int level;
+ Vcard *card;
+ Vline *line;
+ Vparam *param;
+};
+
+char *user = nil;
+char *mtpt = "/mnt/vcf";
+char *service = nil;
+
+char *file = nil;
+Vcard *cards = nil;
+
+static Vfile*
+emkvfile(int level, Vcard *c, Vline *l, Vparam *p)
+{
+ Vfile *f;
+ f = mallocz(sizeof(Vfile), 1);
+ if (!f)
+ sysfatal("%r");
+ f->level = level;
+ f->card = c;
+ f->line = l;
+ f->param = p;
+ return f;
+}
+
+static void
+fsread(Req *r)
+{
+ Vfile *f;
+ f = r->fid->file->aux;
+ switch (f->level) {
+ case Qctl:
+ respond(r, nil);
+ return;
+ case Qimport:
+ respond(r, nil);
+ return;
+ case Qdata:
+ readstr(r, f->line->value);
+ respond(r, nil);
+ return;
+ case Qgroup:
+ if (!f->line->group) {
+ respond(r, "file not found");
+ return;
+ }
+ readstr(r, f->line->group);
+ respond(r, nil);
+ return;
+ case Qparamdata:
+ readstr(r, f->param->value);
+ respond(r, nil);
+ return;
+ }
+ respond(r, "not implemented");
+}
+
+static void
+fswrite(Req *r)
+{
+ Vfile *f;
+ f = r->fid->file->aux;
+ switch (f->level) {
+ case Qctl:
+ break;
+ }
+ respond(r, "not implemented");
+}
+
+Srv fs = {
+ .read = fsread,
+ .write = fswrite,
+};
+
+/* TODO: LOOKAT:
+ /sys/src/cmd/webcookies.c:/createfile
+ /sys/src/cmd/aux/gps/gpsfs.c:/createfile
+*/
+static char*
+safename(char *n)
+{
+ char *s;
+
+ s = estrdup(n);
+ n = s;
+ while (*n) {
+ switch (*n) {
+ case ' ':
+ *n = '_';
+ break;
+ case '\t':
+ *n = '_';
+ break;
+ }
+ n++;
+ }
+ return s;
+}
+
+static char*
+getcardname(Vcard *c)
+{
+ Vline *l;
+ Vline *fn = nil, *n = nil;
+
+ for (l = c->content; l; l = l->next) {
+ if (cistrcmp(l->name, "fn") == 0)
+ fn = l;
+ else if (cistrcmp(l->name, "n") == 0)
+ n = l;
+ if (fn && n)
+ break;
+ }
+
+ if (fn)
+ return safename(fn->value);
+ if (n)
+ return safename(n->value);
+ return nil;
+}
+
+static void
+initcardfiles(Vcard *chain)
+{
+ File *fc, *fl, *fp, *f;
+ Vcard *c;
+ Vline *l;
+ Vparam *p;
+ Vfile *vf;
+ char *s;
+
+ // TODO: fill with Vfile structure, which points to card data
+
+ for (c = chain; c; c = c->next) {
+ s = getcardname(c);
+ if (!s)
+ continue;
+ vf = emkvfile(Qcard, c, nil, nil);
+ fc = createfile(fs.tree->root, s, user, DMDIR|0555, vf);
+ free(s);
+ if (!fc)
+ sysfatal("%r");
+
+ for (l = c->content; l; l = l->next) {
+ vf = emkvfile(Qline, c, l, nil);
+ fl = createfile(fc, l->name, user, DMDIR|0555, vf);
+ vf = emkvfile(Qdata, c, l, nil);
+ f = createfile(fl, "data", user, 0666, vf);
+ // closefile(f);
+ if (l->group) {
+ vf = emkvfile(Qgroup, c, l, nil);
+ f = createfile(fl, "group", user, 0666, vf);
+ // closefile(f);
+ }
+ vf = emkvfile(Qparams, c, l, nil);
+ f = createfile(fl, "params", user, DMDIR|0555, vf);
+ // closefile(f);
+
+ for (p = l->params; p; p = p->next) {
+ vf = emkvfile(Qparamdata, c, l, p);
+ fp = createfile(f, p->name, user, 0666, vf);
+ // closefile(fp);
+ }
+ // closefile(fl);
+ }
+ // closefile(fc);
+ }
+}
+
+void
+main(int argc, char **argv)
+{
+ ARGBEGIN{
+ case 'D':
+ chatty9p++;
+ break;
+ case 'm':
+ mtpt = EARGF(usage());
+ break;
+ case 's':
+ service = EARGF(usage());
+ break;
+ default:
+ usage();
+ break;
+ }ARGEND;
+
+ rfork(RFNOTEG);
+
+ if (argc != 1)
+ usage();
+
+ file = argv[0];
+ cards = vcparsefile(file);
+
+ if (!cards)
+ sysfatal("%r");
+
+ user = getuser();
+
+ fs.tree = alloctree("vcf", "vcf", DMDIR|0555, nil);
+ createfile(fs.tree->root, "ctl", user, 0666,
+ emkvfile(Qctl, nil, nil, nil));
+ createfile(fs.tree->root, "import", user, 0666,
+ emkvfile(Qimport, nil, nil, nil));
+ initcardfiles(cards);
+
+ postmountsrv(&fs, service, mtpt, MREPL);
+ exits(nil);
+}
--- a/vcffs.c
+++ /dev/null
@@ -1,278 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <thread.h>
-#include <9p.h>
-#include "libvcard/vcard.h"
-
-/* rough structure
-
-/john-doe/
- /fn/
- /data (line value)
- /group (line group)
- /param (param value)
- /tel/
- /data (line value)
- /group (line group)
- /param (param value)
-/ctl
- - "write" (save file)
-/import
- - write new vcf file to import
-
-*/
-
-void
-usage(void)
-{
- fprint(2, "usage: %s [-s srv] [-m mtpt] file\n", argv0);
- exits("usage");
-}
-
-static void*
-emalloc(long n)
-{
- void *p;
- p = mallocz(n, 1);
- if (!p)
- sysfatal("emalloc: %r");
- return p;
-}
-
-static char*
-estrdup(char *s)
-{
- void *t;
- t = strdup(s);
- if (!t)
- sysfatal("estrdup: %r");
- return t;
-}
-
-enum {
- Qroot,
- Qctl,
- Qimport,
- Qcard,
- Qline,
- Qdata,
- Qgroup,
- Qparams,
- Qparamdata,
-};
-
-typedef struct Vfile Vfile;
-struct Vfile {
- int level;
- Vcard *card;
- Vline *line;
- Vparam *param;
-};
-
-char *user = nil;
-char *mtpt = "/mnt/vcf";
-char *service = nil;
-
-char *file = nil;
-Vcard *cards = nil;
-
-static Vfile*
-emkvfile(int level, Vcard *c, Vline *l, Vparam *p)
-{
- Vfile *f;
- f = mallocz(sizeof(Vfile), 1);
- if (!f)
- sysfatal("%r");
- f->level = level;
- f->card = c;
- f->line = l;
- f->param = p;
- return f;
-}
-
-static void
-fsread(Req *r)
-{
- Vfile *f;
- f = r->fid->file->aux;
- switch (f->level) {
- case Qctl:
- respond(r, nil);
- return;
- case Qimport:
- respond(r, nil);
- return;
- case Qdata:
- readstr(r, f->line->value);
- respond(r, nil);
- return;
- case Qgroup:
- if (!f->line->group) {
- respond(r, "file not found");
- return;
- }
- readstr(r, f->line->group);
- respond(r, nil);
- return;
- case Qparamdata:
- readstr(r, f->param->value);
- respond(r, nil);
- return;
- }
- respond(r, "not implemented");
-}
-
-static void
-fswrite(Req *r)
-{
- Vfile *f;
- f = r->fid->file->aux;
- switch (f->level) {
- case Qctl:
- break;
- }
- respond(r, "not implemented");
-}
-
-Srv fs = {
- .read = fsread,
- .write = fswrite,
-};
-
-/* TODO: LOOKAT:
- /sys/src/cmd/webcookies.c:/createfile
- /sys/src/cmd/aux/gps/gpsfs.c:/createfile
-*/
-static char*
-safename(char *n)
-{
- char *s;
-
- s = estrdup(n);
- n = s;
- while (*n) {
- switch (*n) {
- case ' ':
- *n = '_';
- break;
- case '\t':
- *n = '_';
- break;
- }
- n++;
- }
- return s;
-}
-
-static char*
-getcardname(Vcard *c)
-{
- Vline *l;
- Vline *fn = nil, *n = nil;
-
- for (l = c->content; l; l = l->next) {
- if (cistrcmp(l->name, "fn") == 0)
- fn = l;
- else if (cistrcmp(l->name, "n") == 0)
- n = l;
- if (fn && n)
- break;
- }
-
- if (fn)
- return safename(fn->value);
- if (n)
- return safename(n->value);
- return nil;
-}
-
-static void
-initcardfiles(Vcard *chain)
-{
- File *fc, *fl, *fp, *f;
- Vcard *c;
- Vline *l;
- Vparam *p;
- Vfile *vf;
- char *s;
-
- // TODO: fill with Vfile structure, which points to card data
-
- for (c = chain; c; c = c->next) {
- s = getcardname(c);
- if (!s)
- continue;
- vf = emkvfile(Qcard, c, nil, nil);
- fc = createfile(fs.tree->root, s, user, DMDIR|0555, vf);
- free(s);
- if (!fc)
- sysfatal("%r");
-
- for (l = c->content; l; l = l->next) {
- vf = emkvfile(Qline, c, l, nil);
- fl = createfile(fc, l->name, user, DMDIR|0555, vf);
- vf = emkvfile(Qdata, c, l, nil);
- f = createfile(fl, "data", user, 0666, vf);
- // closefile(f);
- if (l->group) {
- vf = emkvfile(Qgroup, c, l, nil);
- f = createfile(fl, "group", user, 0666, vf);
- // closefile(f);
- }
- vf = emkvfile(Qparams, c, l, nil);
- f = createfile(fl, "params", user, DMDIR|0555, vf);
- // closefile(f);
-
- for (p = l->params; p; p = p->next) {
- vf = emkvfile(Qparamdata, c, l, p);
- fp = createfile(f, p->name, user, 0666, vf);
- // closefile(fp);
- }
- // closefile(fl);
- }
- // closefile(fc);
- }
-}
-
-void
-main(int argc, char **argv)
-{
- ARGBEGIN{
- case 'D':
- chatty9p++;
- break;
- case 'm':
- mtpt = EARGF(usage());
- break;
- case 's':
- service = EARGF(usage());
- break;
- default:
- usage();
- break;
- }ARGEND;
-
- rfork(RFNOTEG);
-
- if (argc != 1)
- usage();
-
- file = argv[0];
- cards = vcparsefile(file);
-
- if (!cards)
- sysfatal("%r");
-
- user = getuser();
-
- fs.tree = alloctree("vcf", "vcf", DMDIR|0555, nil);
- createfile(fs.tree->root, "ctl", user, 0666,
- emkvfile(Qctl, nil, nil, nil));
- createfile(fs.tree->root, "import", user, 0666,
- emkvfile(Qimport, nil, nil, nil));
- initcardfiles(cards);
-
- postmountsrv(&fs, service, mtpt, MREPL);
- exits(nil);
-}