Add period and count to #alarm
[akaros.git] / kern / drivers / dev / version.c
1 /* Copyright (c) 2015 Google Inc
2  * Davide Libenzi <dlibenzi@google.com>
3  * See LICENSE for details.
4  */
5
6 #include <ros/common.h>
7 #include <ros/errno.h>
8 #include <smp.h>
9 #include <ns.h>
10 #include <kmalloc.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <assert.h>
14 #include <err.h>
15 #include <build_info.h>
16
17 enum {
18         Kverdirqid = 0,
19         Kverkernelpath,
20         Kverdate,
21         Kverhost,
22         Kvercommitid,
23         Kverversion,
24         Kverversionname,
25 };
26
27 struct dev verdevtab;
28 static struct dirtab vertab[] = {
29         {".",                           {Kverdirqid,            0, QTDIR}, 0,   DMDIR|0550},
30         {"kernel_path",         {Kverkernelpath},       0,      0444},
31         {"date",                        {Kverdate},                     0,      0444},
32         {"host",                        {Kverhost},                     0,      0444},
33         {"commitid",            {Kvercommitid},         0,      0444},
34         {"version",                     {Kverversion},          0,      0444},
35         {"version_name",        {Kverversionname},      0,      0444},
36 };
37
38 static long ver_emit_nlstr(char *dest, const char *src, long size,
39                                                    long offset)
40 {
41         long n, slen = strlen(src);
42         char *buf = kmalloc(slen + 2, MEM_WAIT);
43
44         snprintf(buf, slen + 2, "%s\n", src);
45         n = readmem(offset, dest, size, buf, slen + 2);
46         kfree(buf);
47
48         return n;
49 }
50
51 static struct chan *ver_attach(char *spec)
52 {
53         return devattach(verdevtab.name, spec);
54 }
55
56 static void ver_init(void)
57 {
58
59 }
60
61 static void ver_shutdown(void)
62 {
63
64 }
65
66 static struct walkqid *ver_walk(struct chan *c, struct chan *nc, char **name,
67                                                                  int nname)
68 {
69         return devwalk(c, nc, name, nname, vertab, ARRAY_SIZE(vertab), devgen);
70 }
71
72 static int ver_stat(struct chan *c, uint8_t *db, int n)
73 {
74         return devstat(c, db, n, vertab, ARRAY_SIZE(vertab), devgen);
75 }
76
77 static struct chan *ver_open(struct chan *c, int omode)
78 {
79         if (c->qid.type & QTDIR) {
80                 if (openmode(omode) != O_READ)
81                         error(EPERM, ERROR_FIXME);
82         }
83         c->mode = openmode(omode);
84         c->flag |= COPEN;
85         c->offset = 0;
86         return c;
87 }
88
89 static void ver_close(struct chan *c)
90 {
91
92 }
93
94 static long ver_read(struct chan *c, void *va, long n, int64_t off)
95 {
96         switch ((int) c->qid.path) {
97         case Kverdirqid:
98                 return devdirread(c, va, n, vertab, ARRAY_SIZE(vertab), devgen);
99         case Kverkernelpath:
100                 if (build_info_kernel_path)
101                         return ver_emit_nlstr(va, build_info_kernel_path, n, (long) off);
102                 break;
103         case Kverdate:
104                 if (build_info_date)
105                         return ver_emit_nlstr(va, build_info_date, n, (long) off);
106                 break;
107         case Kverhost:
108                 if (build_info_host)
109                         return ver_emit_nlstr(va, build_info_host, n, (long) off);
110                 break;
111         case Kvercommitid:
112                 if (build_info_commitid)
113                         return ver_emit_nlstr(va, build_info_commitid, n, (long) off);
114                 break;
115         case Kverversion:
116                 if (build_info_version)
117                         return ver_emit_nlstr(va, build_info_version, n, (long) off);
118                 break;
119         case Kverversionname:
120                 if (build_info_version_name)
121                         return ver_emit_nlstr(va, build_info_version_name, n, (long) off);
122                 break;
123         default:
124                 error(EINVAL, ERROR_FIXME);
125         }
126
127         return 0;
128 }
129
130 static long ver_write(struct chan *c, void *a, long n, int64_t unused)
131 {
132         error(ENOTSUP, ERROR_FIXME);
133         return -1;
134 }
135
136 struct dev verdevtab __devtab = {
137         .name = "version",
138
139         .reset = devreset,
140         .init = ver_init,
141         .shutdown = ver_shutdown,
142         .attach = ver_attach,
143         .walk = ver_walk,
144         .stat = ver_stat,
145         .open = ver_open,
146         .create = devcreate,
147         .close = ver_close,
148         .read = ver_read,
149         .bread = devbread,
150         .write = ver_write,
151         .bwrite = devbwrite,
152         .remove = devremove,
153         .wstat = devwstat,
154 };