ref: 3cd1ee7c4f5d66a1f2bc1f0a1df429d9829c28df
dir: /calfs.c/
#include "a.h" int debug = 0; Event **events; usize nevents; usize eventsz; void fsread(Req *r) { File *f; Event *e; f = r->fid->file; e = f->aux; if(strcmp(f->name, "uid") == 0) readstr(r, e->uid); else if(strcmp(f->name, "summary") == 0) readstr(r, e->summary); else if(strcmp(f->name, "description") == 0) readstr(r, e->description); else if(strcmp(f->name, "location") == 0) readstr(r, e->location); else if(strcmp(f->name, "start") == 0) readtm(r, &e->start); else if(strcmp(f->name, "end") == 0) readtm(r, &e->end); else if(strcmp(f->name, "last-modified") == 0) readtm(r, &e->lastmod); else if(strcmp(f->name, "created") == 0) readtm(r, &e->created); else{ respond(r, "no such file or directory"); return; } respond(r, nil); } Srv fs = { .read = fsread, }; void createevtfiles(File *p, Event *e) { const char *filenames[] = { "uid", "summary", "description", "location", "start", "end", "last-modified", "created", }; int i; for(i = 0; i < nelem(filenames); i++) createfile(p, filenames[i], nil, 0644, e); } enum { Cnone, Cyear, Cmonth, Cday }; int change(Event *e, int y, int m, int d) { if(e->start.year != y) return Cyear; else if(e->start.mon != m) return Cmonth; else if(e->start.mday != d) return Cday; return Cnone; } Tree* buildtree(void) { Tree *tree; int i, n, y, m, d; File *yd, *md, *dd, *nd; Event *e; char buf[16] = {0}; tree = alloctree(nil, nil, DMDIR|0555, nil); y = m = d = -1; yd = md = dd = nil; n = 1; for(i = 0; i < nevents; i++){ e = events[i]; switch(change(e, y, m, d)){ case Cyear: y = e->start.year; snprint(buf, sizeof buf, "%d", y+1900); yd = ecreatefile(tree->root, buf, nil, DMDIR|0555, nil); case Cmonth: m = e->start.mon; snprint(buf, sizeof buf, "%02d", m+1); md = ecreatefile(yd, buf, nil, DMDIR|0555, nil); case Cday: d = e->start.mday; n = 1; snprint(buf, sizeof buf, "%02d", d); dd = ecreatefile(md, buf, nil, DMDIR|0555, nil); } snprint(buf, sizeof buf, "%d", n); nd = createfile(dd, buf, nil, DMDIR|0555, nil); createevtfiles(nd, e); n += 1; } return tree; } void usage(void) { fprint(2, "usage: %s <filename>...\n", argv0); exits("usage"); } void main(int argc, char **argv) { char *mtpt; int i; mtpt = "/mnt/cal"; ARGBEGIN{ case 'D': chatty9p++; break; case 'd': debug++; break; case 'm': mtpt = ARGF(); break; }ARGEND; tmfmtinstall(); if(argc < 1) usage(); for(i = 0; i < argc; i++){ if(readical(argv[i]) < 0) sysfatal("unable to read ical file '%s': %r", argv[i]); } qsort(events, nevents, sizeof(Event*), cmpevent); fs.tree = buildtree(); postmountsrv(&fs, nil, mtpt, 0); exits(0); }