source: rtems-libbsd/dhcpcd/control.c @ 7e52ab9

55-freebsd-126-freebsd-12
Last change on this file since 7e52ab9 was f2ed769, checked in by Sebastian Huber <sebastian.huber@…>, on 01/30/14 at 12:29:46

DHCPCD(8): Import

Import DHCPCD(8) from:

http://roy.marples.name/projects/dhcpcd/

The upstream sources can be obtained via:

fossil clone http://roy.marples.name/projects/dhcpcd

The imported version is 2014-01-29 19:46:44 [6b209507bb].

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2012 Roy Marples <roy@marples.name>
4 * All rights reserved
5
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/stat.h>
29#include <sys/un.h>
30
31#include <errno.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <time.h>
36#include <unistd.h>
37
38#include "config.h"
39#include "common.h"
40#include "dhcpcd.h"
41#include "control.h"
42#include "eloop.h"
43
44static int fd = -1;
45static char buffer[1024];
46static char *argvp[255];
47
48static struct sockaddr_un sun;
49struct fd_list *control_fds = NULL;
50
51#ifdef DEBUG_MEMORY
52static void
53cleanup(void)
54{
55        struct fd_list *f;
56
57        f = control_fds;
58        while (f) {
59                control_fds = f->next;
60                free(f);
61                f = control_fds;
62        }
63}
64#endif
65
66static void
67control_remove(void *arg)
68{
69        struct fd_list *l, *n, *last = NULL;
70
71        l = control_fds;
72        while (l) {
73                n = l->next;
74                if (l == arg) {
75                        close(l->fd);
76                        eloop_event_delete(l->fd);
77                        if (last == NULL)
78                                control_fds = l->next;
79                        else
80                                last->next = l->next;
81                        free(l);
82                        break;
83                }
84                last = l;
85                l = n;
86        }
87}
88
89static void
90control_handle_data(void *arg)
91{
92        struct fd_list *l = arg;
93        ssize_t bytes;
94        int argc;
95        char *e, *p;
96        char **ap;
97
98        bytes = read(l->fd, buffer, sizeof(buffer) - 1);
99        if (bytes == -1 || bytes == 0) {
100                control_remove(l);
101                return;
102        }
103        buffer[bytes] = '\0';
104        p = buffer;
105        e = buffer + bytes;
106        argc = 0;
107        ap = argvp;
108        while (p < e && (size_t)argc < sizeof(argvp)) {
109                argc++;
110                *ap++ = p;
111                p += strlen(p) + 1;
112        }
113        handle_args(l, argc, argvp);
114}
115
116/* ARGSUSED */
117static void
118control_handle(__unused void *arg)
119{
120        struct sockaddr_un run;
121        socklen_t len;
122        struct fd_list *l;
123        int f;
124
125        len = sizeof(run);
126        if ((f = accept(fd, (struct sockaddr *)&run, &len)) == -1)
127                return;
128        set_cloexec(f);
129        l = malloc(sizeof(*l));
130        if (l) {
131                l->fd = f;
132                l->listener = 0;
133                l->next = control_fds;
134                control_fds = l;
135                eloop_event_add(l->fd, control_handle_data, l);
136        }
137}
138
139static int
140make_sock(void)
141{
142        if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
143                return -1;
144        memset(&sun, 0, sizeof(sun));
145        sun.sun_family = AF_UNIX;
146        strlcpy(sun.sun_path, CONTROLSOCKET, sizeof(sun.sun_path));
147        return sizeof(sun.sun_family) + strlen(sun.sun_path) + 1;
148}
149
150int
151control_start(void)
152{
153        int len;
154
155        if ((len = make_sock()) == -1)
156                return -1;
157        unlink(CONTROLSOCKET);
158        if (bind(fd, (struct sockaddr *)&sun, len) == -1 ||
159            chmod(CONTROLSOCKET,
160                S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) == -1 ||
161            set_cloexec(fd) == -1 ||
162            set_nonblock(fd) == -1 ||
163            listen(fd, sizeof(control_fds)) == -1)
164        {
165                close(fd);
166                return -1;
167        }
168        eloop_event_add(fd, control_handle, NULL);
169        return fd;
170}
171
172int
173control_stop(void)
174{
175        int retval = 0;
176        struct fd_list *l;
177
178        eloop_event_delete(fd);
179        if (shutdown(fd, SHUT_RDWR) == -1)
180                retval = 1;
181        fd = -1;
182        if (unlink(CONTROLSOCKET) == -1)
183                retval = -1;
184
185        l = control_fds;
186        while (l != NULL) {
187                control_fds = l->next;
188                eloop_event_delete(l->fd);
189                shutdown(l->fd, SHUT_RDWR);
190                free(l);
191                l = control_fds;
192        }
193
194        return retval;
195}
196
197int
198control_open(void)
199{
200        int len;
201
202        if ((len = make_sock()) == -1)
203                return -1;
204#ifdef DEBUG_MEMORY
205        atexit(cleanup);
206#endif
207        return connect(fd, (struct sockaddr *)&sun, len);
208}
209
210int
211control_send(int argc, char * const *argv)
212{
213        char *p = buffer;
214        int i;
215        size_t len;
216
217        if (argc > 255) {
218                errno = ENOBUFS;
219                return -1;
220        }
221        for (i = 0; i < argc; i++) {
222                len = strlen(argv[i]) + 1;
223                if ((p - buffer) + len > sizeof(buffer)) {
224                        errno = ENOBUFS;
225                        return -1;
226                }
227                memcpy(p, argv[i], len);
228                p += len;
229        }
230        return write(fd, buffer, p - buffer);
231}
Note: See TracBrowser for help on using the repository browser.