chiark / gitweb /
ipif: service-wrap: implementation, does not work yet
[userv-utils.git] / ipif / utils.c
1 /*
2  * General utility functions for udp tunnel
3  */
4 /*
5  * Copyright 1996-2013 Ian Jackson <ijackson@chiark.greenend.org.uk>
6  * Copyright 1998 David Damerell <damerell@chiark.greenend.org.uk>
7  * Copyright 1999,2003
8  *    Chancellor Masters and Scholars of the University of Cambridge
9  * Copyright 2010 Tony Finch <fanf@dotat.at>
10  *
11  * This is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with userv-utils; if not, see http://www.gnu.org/licenses/.
23  */
24
25 #include <string.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <assert.h>
30
31 #include "forwarder.h"
32
33 const char *const *argv;
34 char programid[SYS_NMLN+sizeof(PROGRAM)+3];
35
36 void arg_assert_fail(const char *msg) {
37   fprintf(stderr, PROGRAM ": argument error (!`%s')\n",msg);
38   exit(12);
39 }
40
41 void sysfail(const char *msg) {
42   fprintf(stderr, "%s: fatal system error: %s: %s\n", programid, msg, strerror(errno));
43   exit(8);
44 }
45
46 void fail(const char *msg) {
47   fprintf(stderr, "%s: fatal error: %s\n", programid, msg);
48   exit(4);
49 }
50
51 void sysdiag(const char *msg) {
52   fprintf(stderr, "%s: system/network error: %s: %s\n", programid, msg, strerror(errno));
53 }
54
55 void diag(const char *msg) {
56   fprintf(stderr, "%s: %s\n", programid, msg);
57 }
58
59 time_t now(void) {
60   time_t r;
61   if (time(&r) == (time_t)-1) sysfail("get time of day");
62   return r;
63 }
64
65 void *xmalloc(size_t sz) {
66   void *r;
67   r= malloc(sz);
68   if (!r) sysfail("allocate memory");
69   return r;
70 }
71
72 void write_must(int fd, const void *p_in, int sz, const char *what) {
73   const unsigned char *p= p_in;
74   int r;
75   
76   while (sz) {
77     r= write(fd,p,sz);
78     if (r<0) {
79       if (errno == EINTR) continue;
80       else sysfail(what);
81     }
82     assert(r && r <= sz);
83     p += r;
84     sz -= r;
85   }
86 }
87
88 void read_must(int fd, void *p_in, int sz, const char *what) {
89   unsigned char *p= p_in;
90   int r;
91   
92   while (sz) {
93     r= read(fd,p,sz);
94     if (r<0) {
95       if (errno == EINTR) continue;
96       else sysfail(what);
97     }
98     if (r==0) fail(what);
99     assert(r <= sz);
100     p += r;
101     sz -= r;
102   }
103 }
104
105 const char *getarg_string(void) {
106   const char *arg;
107   
108   arg= *++argv;
109   arg_assert(arg);
110   return arg;
111 }
112
113 unsigned long getarg_ulong(void) {
114   char *ep;
115   unsigned long ul;
116   
117   ul= strtoul(getarg_string(),&ep,0);
118   arg_assert(!*ep);
119   return ul;
120 }
121
122 void *buf_append(struct buffer *buf, size_t amount) {
123   void *p;
124
125   p= buf->start + buf->size;
126   buf->size += amount;
127   return p;
128 }
129   
130 void *buf_prepend(struct buffer *buf, size_t amount) {
131   buf->size += amount;
132   return buf->start -= amount;
133 }
134
135 void *buf_unappend(struct buffer *buf, size_t amount) {
136   if (buf->size < amount) return 0;
137   return buf->start + (buf->size -= amount);
138 }
139
140 void *buf_unprepend(struct buffer *buf, size_t amount) {
141   void *p;
142
143   p= buf->start;
144   buf->start += amount;
145   buf->size -= amount;
146   return p;
147 }