ref: 3f6f039bf673f3ecaba6aa26abd3b89d363facfb
dir: /fs.c/
#include <u.h> #include <libc.h> #include <fcall.h> #include <thread.h> #include <9p.h> #include "cuefs.h" typedef struct { Cuesheet* sheet; int outfmt; } Fsprops; void wavserve(Entry*, Req*); void (*servefmt[])(Entry*, Req*) = { [WAVE] = wavserve, [UNKNOWN] = nil }; char *decoder[] = { [MP3] = "audio/mp3dec", [FLAC] = "audio/flacdec", [WAVE] = "audio/wavedec" }; int pipedec(AFile *f, Timestamp t) { int fd[2]; double sec; char *dec; dec = decoder[f->actual]; sec = t2sec(t); if(pipe(fd) < 0) sysfatal("pipedec: can't decode: pipe: %r"); switch(rfork(RFFDG|RFPROC|RFMEM|RFNAMEG|RFNOTEG|RFREND)) { case 0: close(0); close(1); dup(f->fd, 0); dup(fd[1], 1); close(f->fd); close(fd[1]); dec = strdup(dec); { char *argv[] = { dec }; if(argv[2] == nil) sysfatal("pipedec: can't decode: smprint: %r"); exec(dec, argv); dec = smprint("/bin/%s", dec); if(dec == nil) sysfatal("pipedec: can't decode: smprint: %r"); exec(dec, argv); sysfatal("pipedec: can't decode: exec: %r"); } break; case -1: sysfatal("pipedec: can't decode: rfork: %r"); } return fd[0]; } void wavserve(Entry *e, Req *r) { int dec; dec = pipedec(e->file, e->starts[0]); r->ofcall.count = readn(dec, r->ofcall.data, r->ifcall.count); respond(r, Estub); } void fsopen(Req *r) { respond(r, nil); } void fsread(Req *r) { void (*func)(Entry*, Req*); extern Srv fs; Fsprops *p; p = fs.aux; func = servefmt[p->outfmt]; if(func != nil) func(r->fid->file->aux, r); else respond(r, Eunsupported); } void fsend(Srv *s) { Fsprops *p; p = s->aux; freesheet(p->sheet); free(p); } Srv fs = { .open = fsopen, .read = fsread, .end = fsend }; void cuefsinit(Cuesheet *sheet, char *mtpt) { Fsprops *p; char *s; p = emalloc(sizeof(*p)); p->sheet = sheet; p->outfmt = WAVE; /* STUB */ fs.aux = p; fs.tree = alloctree(nil, nil, DMDIR | 0444, nil); for(AFile *f = sheet->files; f != nil; f = f->next) if(f->fd = open(f->name, OREAD) < 0) sysfatal("open: %r"); for(Entry *e = sheet->entries; e != nil; e = e->next) { s = smprint("%02d - %s.%s", e->index, e->title, formatext(e->file)); strreplace(s, '/', '-'); createfile(fs.tree->root, s, nil, 0444, e); free(s); } postmountsrv(&fs, nil, mtpt, MREPL); }