Initial commit.
[statserve.git] / fssrc.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
8 #include <ashd/utils.h>
9 #include <ashd/mtio.h>
10 #include <ashd/log.h>
11
12 #include "statserve.h"
13
14 struct fssrc {
15     char *path;
16 };
17
18 static struct fileinfo fsserve(struct source *src, char *nm)
19 {
20     struct fssrc *d = src->pdata;
21     struct stat sb;
22     char *p;
23     struct charbuf rb;
24     int fd, ret;
25     
26     if((nm[0] == '.') || strchr(nm, '/'))
27         return((struct fileinfo){});
28     p = sprintf2("%s/%s", d->path, nm);
29     if(stat(p, &sb)) {
30         if(errno != ENOENT)
31             flog(LOG_WARNING, "fssrc: %s: %s", p, strerror(errno));
32         free(p);
33         return((struct fileinfo){});
34     }
35     if(!S_ISREG(sb.st_mode)) {
36         free(p);
37         return((struct fileinfo){});
38     }
39     if((fd = open(p, O_RDONLY)) < 0) {
40         flog(LOG_WARNING, "fssrc: %s: %s", p, strerror(errno));
41         free(p);
42         return((struct fileinfo){});
43     }
44     bufinit(rb);
45     sizebuf(rb, sb.st_size);
46     while(1) {
47         sizebuf(rb, 4096);
48         if((ret = read(fd, rb.b + rb.d, rb.s - rb.d)) < 0) {
49             flog(LOG_ERR, "fssrc: %s: %s", p, strerror(errno));
50             free(p);
51             buffree(rb);
52             return((struct fileinfo){});
53         }
54         if(ret == 0)
55             break;
56         rb.d += ret;
57     }
58     return((struct fileinfo){.mtime = sb.st_mtime, .sz = rb.d, .data = rb.b, .ctype = "image/png"});
59 }
60
61 struct source *mkfssrc(char *path)
62 {
63     struct source *src;
64     struct fssrc *d;
65     
66     omalloc(src);
67     src->serve = fsserve;
68     src->pdata = omalloc(d);
69     d->path = sstrdup(path);
70     return(src);
71 }