chiark / gitweb /
Import release 0.08
[secnet.git] / random.c
1 /* $Log$
2  */
3
4 #include "secnet.h"
5 #include <stdio.h>
6 #include <fcntl.h>
7 #include <string.h>
8 #include <sys/stat.h>
9 #include <unistd.h>
10
11 struct rgen_data {
12     closure_t cl;
13     struct random_if ops;
14     struct cloc loc;
15     int fd;
16 };
17
18 static random_fn random_generate;
19 static bool_t random_generate(void *data, uint32_t bytes, uint8_t *buff)
20 {
21     struct rgen_data *st=data;
22
23     /* XXX XXX error checking */
24     read(st->fd,buff,bytes);
25
26     return True;
27 }
28
29 static list_t *random_apply(closure_t *self, struct cloc loc,
30                             dict_t *context, list_t *args)
31 {
32     struct rgen_data *st;
33     item_t *arg1, *arg2;
34     string_t filename=NULL;
35
36     st=safe_malloc(sizeof(*st),"random_apply");
37
38     st->cl.description="randomsource";
39     st->cl.type=CL_RANDOMSRC;
40     st->cl.apply=NULL;
41     st->cl.interface=&st->ops;
42     st->ops.st=st;
43     st->ops.blocking=False;
44     st->ops.generate=random_generate;
45     st->loc=loc;
46
47     arg1=list_elem(args,0);
48     arg2=list_elem(args,1);
49
50     if (!arg1) {
51         fatal("randomsource: requires a filename\n");
52     }
53     if (arg1->type != t_string) {
54         cfgfatal(arg1->loc,"randomsource",
55                  "filename (arg1) must be a string\n");
56     }
57     filename=arg1->data.string;
58
59     if (arg2) {
60         if (arg2->type != t_bool) {
61             cfgfatal(arg2->loc,"randomsource",
62                      "blocking parameter (arg2) must be bool\n");
63         }
64         st->ops.blocking=arg2->data.bool;
65     }
66
67     if (!filename) {
68         fatal("randomsource requires a filename");
69     }
70     st->fd=open(filename,O_RDONLY);
71     if (st->fd<0) {
72         fatal_perror("randomsource (%s:%d): cannot open %s",arg1->loc.file,
73                      arg1->loc.line,filename);
74     }
75     return new_closure(&st->cl);
76 }
77
78 void random_module(dict_t *d)
79 {
80     add_closure(d,"randomfile",random_apply);
81 }