ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/util.C
Revision: 1.23
Committed: Thu Aug 7 19:07:03 2008 UTC (15 years, 9 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.22: +17 -7 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 /*
2     util.C -- process management and other utility functions
3 pcg 1.22 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de>
4 pcg 1.1
5 pcg 1.3 Some of these are taken from tinc, see the AUTHORS file.
6 pcg 1.1
7 pcg 1.16 This file is part of GVPE.
8    
9 pcg 1.22 GVPE is free software; you can redistribute it and/or modify it
10     under the terms of the GNU General Public License as published by the
11     Free Software Foundation; either version 3 of the License, or (at your
12     option) any later version.
13    
14     This program is distributed in the hope that it will be useful, but
15     WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17     Public License for more details.
18    
19     You should have received a copy of the GNU General Public License along
20     with this program; if not, see <http://www.gnu.org/licenses/>.
21    
22     Additional permission under GNU GPL version 3 section 7
23    
24     If you modify this Program, or any covered work, by linking or
25     combining it with the OpenSSL project's OpenSSL library (or a modified
26     version of that library), containing parts covered by the terms of the
27     OpenSSL or SSLeay licenses, the licensors of this Program grant you
28     additional permission to convey the resulting work. Corresponding
29     Source for a non-source form of such a combination shall include the
30     source code for the parts of OpenSSL used as well as that of the
31     covered work.
32 pcg 1.1 */
33    
34     #include "config.h"
35    
36     #include <cstdio>
37 pcg 1.12 #include <cstdlib>
38 pcg 1.1 #include <cstring>
39    
40     #include <errno.h>
41     #include <signal.h>
42     #include <sys/types.h>
43 pcg 1.4 #include <sys/wait.h>
44 pcg 1.1 #include <unistd.h>
45     #include <time.h>
46    
47 pcg 1.8 #include "netcompat.h"
48 pcg 1.1
49 pcg 1.18 #include "gettext.h"
50 pcg 1.1 #include "pidfile.h"
51     #include "dropin.h"
52    
53     #include "global.h"
54     #include "conf.h"
55 pcg 1.5 #include "util.h"
56 pcg 1.1 #include "slog.h"
57    
58     int
59     write_pidfile (void)
60     {
61     int pid;
62    
63 pcg 1.13 pid = check_pid (conf.pidfilename);
64 pcg 1.1
65     if (pid)
66     {
67 pcg 1.15 fprintf (stderr, _("A gvpe daemon is already running with pid %d.\n"), pid);
68 pcg 1.1 return 1;
69     }
70    
71     /* if it's locked, write-protected, or whatever */
72 pcg 1.13 if (!write_pid (conf.pidfilename))
73 pcg 1.1 return 1;
74    
75     return 0;
76     }
77    
78     int
79     kill_other (int signal)
80     {
81     int pid;
82    
83 pcg 1.13 pid = read_pid (conf.pidfilename);
84 pcg 1.1
85     if (!pid)
86     {
87 pcg 1.15 fprintf (stderr, _("No other gvpe daemon is running.\n"));
88 pcg 1.1 return 1;
89     }
90    
91     errno = 0; /* No error, sometimes errno is only changed on error */
92    
93     /* ESRCH is returned when no process with that pid is found */
94     if (kill (pid, signal) && errno == ESRCH)
95     {
96 pcg 1.15 fprintf (stderr, _("The gvpe daemon is no longer running. "));
97 pcg 1.1
98     fprintf (stderr, _("Removing stale lock file.\n"));
99 pcg 1.13 remove_pid (conf.pidfilename);
100 pcg 1.1 }
101    
102     return 0;
103     }
104    
105     int
106     detach (int do_detach)
107     {
108     /* First check if we can open a fresh new pidfile */
109    
110     if (write_pidfile ())
111     return -1;
112    
113     /* If we succeeded in doing that, detach */
114    
115     log_to (0);
116    
117     if (do_detach)
118     {
119     if (daemon (0, 0) < 0)
120     {
121     log_to (LOGTO_SYSLOG | LOGTO_STDERR);
122    
123     slog (L_ERR, _("couldn't detach from terminal: %s"), strerror (errno));
124     return -1;
125     }
126    
127     /* Now UPDATE the pid in the pidfile, because we changed it... */
128    
129 pcg 1.13 if (!write_pid (conf.pidfilename))
130 pcg 1.1 return -1;
131    
132     log_to (LOGTO_SYSLOG);
133     }
134     else
135     log_to (LOGTO_SYSLOG | LOGTO_STDERR);
136    
137 pcg 1.15 slog (L_INFO, _("gvpe daemon %s (%s %s) starting"), VERSION, __DATE__, __TIME__);
138 pcg 1.1
139     return 0;
140     }
141    
142 pcg 1.23 pid_t
143     run_script (const run_script_cb &cb, bool wait)
144 pcg 1.4 {
145 pcg 1.23 sigset_t oldset;
146    
147 pcg 1.20 if (wait)
148 pcg 1.23 {
149     sigset_t sigchld;
150     sigemptyset (&sigchld);
151     sigaddset (&sigchld, SIGCHLD);
152     sigprocmask (SIG_BLOCK, &sigchld, &oldset);
153     }
154 pcg 1.4
155 pcg 1.23 pid_t pid = fork ();
156 pcg 1.20
157     if (pid == 0)
158 pcg 1.4 {
159 pcg 1.23 sigprocmask (SIG_SETMASK, &oldset, 0);
160    
161 pcg 1.19 execl ("/bin/sh", "/bin/sh", "-c", cb (), (char *) 0);
162     exit (EXIT_FAILURE);
163 pcg 1.4 }
164     else if (pid > 0)
165     {
166     if (wait)
167     {
168 pcg 1.19 int status;
169 pcg 1.20 int res = waitpid (pid, &status, 0);
170    
171 pcg 1.23 sigprocmask (SIG_SETMASK, &oldset, 0);
172 pcg 1.19
173 pcg 1.20 if (res < 0)
174 pcg 1.19 {
175     slog (L_WARN, _("waiting for an external command failed: %s."),
176     strerror (errno));
177 pcg 1.23 return 0;
178 pcg 1.19 }
179     else if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
180     {
181     slog (L_WARN, _("external command returned with exit status %d (%04x)."),
182     WEXITSTATUS (status), status);
183 pcg 1.23 return 0;
184 pcg 1.19 }
185 pcg 1.4 }
186     }
187 pcg 1.20 else
188     {
189     slog (L_ERR, _("unable to fork, exiting: %s"), strerror (errno));
190     exit (EXIT_FAILURE);
191     }
192 pcg 1.19
193 pcg 1.23 return pid;
194 pcg 1.4 }
195 pcg 1.7
196     #if ENABLE_HTTP_PROXY
197     // works like strdup
198     u8 *
199     base64_encode (const u8 *data, unsigned int len)
200     {
201     const static char base64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
202    
203     unsigned int t, i;
204     const u8 *end = data + len;
205     u8 *res = new u8 [4 * ((len + 2) / 3) + 1];
206     u8 *out = res;
207    
208     while (data <= end - 3)
209     {
210     t = (((data[0] << 8) | data[1]) << 8) | data[2];
211     data += 3;
212    
213     *out++ = base64[(t >> 18) & 0x3f];
214     *out++ = base64[(t >> 12) & 0x3f];
215     *out++ = base64[(t >> 6) & 0x3f];
216     *out++ = base64[(t ) & 0x3f];
217     }
218    
219     for (t = 0, i = 0; data < end; i++)
220     t = (t << 8) | *data++;
221    
222     switch (i)
223     {
224     case 2:
225     *out++ = base64[(t >> 10) & 0x3f];
226     *out++ = base64[(t >> 4) & 0x3f];
227     *out++ = base64[(t << 2) & 0x3f];
228     *out++ = '=';
229     break;
230     case 1:
231     *out++ = base64[(t >> 2) & 0x3f];
232     *out++ = base64[(t << 4) & 0x3f];
233     *out++ = '=';
234     *out++ = '=';
235     break;
236     }
237    
238     *out++ = 0;
239    
240     return res;
241     }
242     #endif
243    
244 pcg 1.10 void
245     id2mac (unsigned int id, void *m)
246     {
247     mac &p = *(mac *)m;
248    
249     if (id)
250     {
251     p[0] = 0xfe;
252     p[1] = 0xfd;
253     p[2] = 0x80;
254     p[3] = 0x00;
255     p[4] = id >> 8;
256     p[5] = id;
257     }
258     else
259     {
260     p[0] = 0xff;
261     p[1] = 0xff;
262     p[2] = 0xff;
263     p[3] = 0xff;
264     p[4] = 0xff;
265     p[5] = 0xff;
266     }
267     }
268