chiark / gitweb /
c215390af059863d29c5eae4bdf2a61ff3067720
[userv-utils.git] / ipif / utils.c
1 /*
2  */
3
4 #include <string.h>
5 #include <errno.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <assert.h>
9
10 #include "forwarder.h"
11
12 const char *const *argv;
13 char programid[SYS_NMLN+sizeof(PROGRAM)+3];
14
15 void arg_assert_fail(const char *msg) {
16   fprintf(stderr, PROGRAM ": argument error (!`%s')\n",msg);
17   exit(12);
18 }
19
20 void sysfail(const char *msg) {
21   fprintf(stderr, "%s: fatal system error: %s: %s\n", programid, msg, strerror(errno));
22   exit(8);
23 }
24
25 void fail(const char *msg) {
26   fprintf(stderr, "%s: fatal error: %s\n", programid, msg);
27   exit(4);
28 }
29
30 void sysdiag(const char *msg) {
31   fprintf(stderr, "%s: system/network error: %s: %s\n", programid, msg, strerror(errno));
32 }
33
34 void diag(const char *msg) {
35   fprintf(stderr, "%s: %s\n", programid, msg);
36 }
37
38 time_t now(void) {
39   time_t r;
40   if (time(&r) == (time_t)-1) sysfail("get time of day");
41   return r;
42 }
43
44 void *xmalloc(size_t sz) {
45   void *r;
46   r= malloc(sz);
47   if (!r) sysfail("allocate memory");
48   return r;
49 }
50
51 void write_must(int fd, const void *p_in, int sz, const char *what) {
52   const unsigned char *p= p_in;
53   int r;
54   
55   while (sz) {
56     r= write(fd,p,sz);
57     if (r<0) {
58       if (errno == EINTR) continue;
59       else sysfail(what);
60     }
61     assert(r && r <= sz);
62     p += r;
63     sz -= r;
64   }
65 }
66
67 void read_must(int fd, void *p_in, int sz, const char *what) {
68   unsigned char *p= p_in;
69   int r;
70   
71   while (sz) {
72     r= read(fd,p,sz);
73     if (r<0) {
74       if (errno == EINTR) continue;
75       else sysfail(what);
76     }
77     if (r==0) fail(what);
78     assert(r <= sz);
79     p += r;
80     sz -= r;
81   }
82 }
83
84 void get_random(void *ptr, size_t sz) {
85   static FILE *randfile;
86
87   size_t r;
88
89   if (!randfile) {
90     randfile= fopen("/dev/urandom","rb");
91     if (!randfile && errno==ENOENT) randfile= fopen("/dev/random","rb");
92     if (!randfile) sysfail("open random number generator");
93   }
94
95   r= fread(ptr,1,sz,randfile);
96   if (r == sz) return;
97   (ferror(randfile) ? sysfail : fail)("cannot read random number generator");
98 }
99
100 const char *getarg_string(void) {
101   const char *arg;
102   
103   arg= *++argv;
104   arg_assert(arg);
105   return arg;
106 }
107
108 unsigned long getarg_ulong(void) {
109   char *ep;
110   unsigned long ul;
111   
112   ul= strtoul(getarg_string(),&ep,0);
113   arg_assert(!*ep);
114   return ul;
115 }
116
117 void *buf_append(struct buffer *buf, size_t amount) {
118   void *p;
119
120   p= buf->start + buf->size;
121   buf->size += amount;
122   return p;
123 }
124   
125 void *buf_prepend(struct buffer *buf, size_t amount) {
126   buf->size += amount;
127   return buf->start -= amount;
128 }
129
130 void *buf_unappend(struct buffer *buf, size_t amount) {
131   if (buf->size < amount) return 0;
132   return buf->start + (buf->size -= amount);
133 }
134
135 void *buf_unprepend(struct buffer *buf, size_t amount) {
136   void *p;
137
138   p= buf->start;
139   buf->start += amount;
140   buf->size -= amount;
141   return p;
142 }