"Fossies" - the Fresh Open Source Software Archive 
Member "dhcpcd-9.4.1/src/dev.c" (22 Oct 2021, 4721 Bytes) of package /linux/misc/dhcpcd-9.4.1.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "dev.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
9.4.0_vs_9.4.1.
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * dhcpcd - DHCP client daemon
4 * Copyright (c) 2006-2021 Roy Marples <roy@marples.name>
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 <dirent.h>
29 #include <dlfcn.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #define _INDEV
35 #include "common.h"
36 #include "dev.h"
37 #include "eloop.h"
38 #include "dhcpcd.h"
39 #include "logerr.h"
40
41 int
42 dev_initialised(struct dhcpcd_ctx *ctx, const char *ifname)
43 {
44
45 #ifdef PRIVSEP
46 if (ctx->options & DHCPCD_PRIVSEP &&
47 !(ctx->options & DHCPCD_PRIVSEPROOT))
48 return ps_root_dev_initialised(ctx, ifname);
49 #endif
50
51 if (ctx->dev == NULL)
52 return 1;
53 return ctx->dev->initialised(ifname);
54 }
55
56 int
57 dev_listening(struct dhcpcd_ctx *ctx)
58 {
59
60 #ifdef PRIVSEP
61 if (ctx->options & DHCPCD_PRIVSEP &&
62 !(ctx->options & DHCPCD_PRIVSEPROOT))
63 return ps_root_dev_listening(ctx);
64 #endif
65
66 if (ctx->dev == NULL)
67 return 0;
68 return ctx->dev->listening();
69 }
70
71 static void
72 dev_stop1(struct dhcpcd_ctx *ctx, int stop)
73 {
74
75 if (ctx->dev) {
76 if (stop)
77 logdebugx("dev: unloaded %s", ctx->dev->name);
78 eloop_event_delete(ctx->eloop, ctx->dev_fd);
79 ctx->dev->stop();
80 free(ctx->dev);
81 ctx->dev = NULL;
82 ctx->dev_fd = -1;
83 }
84 if (ctx->dev_handle) {
85 dlclose(ctx->dev_handle);
86 ctx->dev_handle = NULL;
87 }
88 }
89
90 void
91 dev_stop(struct dhcpcd_ctx *ctx)
92 {
93
94 dev_stop1(ctx, !(ctx->options & DHCPCD_FORKED));
95 }
96
97 static int
98 dev_start2(struct dhcpcd_ctx *ctx, const struct dev_dhcpcd *dev_dhcpcd,
99 const char *name)
100 {
101 char file[PATH_MAX];
102 void *h;
103 void (*fptr)(struct dev *, const struct dev_dhcpcd *);
104 int r;
105
106 snprintf(file, sizeof(file), DEVDIR "/%s", name);
107 h = dlopen(file, RTLD_LAZY);
108 if (h == NULL) {
109 logerrx("dlopen: %s", dlerror());
110 return -1;
111 }
112 fptr = dlsym(h, "dev_init");
113 if (fptr == NULL) {
114 logerrx("dlsym: %s", dlerror());
115 dlclose(h);
116 return -1;
117 }
118 if ((ctx->dev = calloc(1, sizeof(*ctx->dev))) == NULL) {
119 logerr("%s: calloc", __func__);
120 dlclose(h);
121 return -1;
122 }
123 fptr(ctx->dev, dev_dhcpcd);
124 if (ctx->dev->start == NULL || (r = ctx->dev->start()) == -1) {
125 free(ctx->dev);
126 ctx->dev = NULL;
127 dlclose(h);
128 return -1;
129 }
130 loginfox("dev: loaded %s", ctx->dev->name);
131 ctx->dev_handle = h;
132 return r;
133 }
134
135 static int
136 dev_start1(struct dhcpcd_ctx *ctx, const struct dev_dhcpcd *dev_dhcpcd)
137 {
138 DIR *dp;
139 struct dirent *d;
140 int r;
141
142 if (ctx->dev) {
143 logerrx("dev: already started %s", ctx->dev->name);
144 return -1;
145 }
146
147 if (ctx->dev_load)
148 return dev_start2(ctx, dev_dhcpcd, ctx->dev_load);
149
150 dp = opendir(DEVDIR);
151 if (dp == NULL) {
152 logdebug("dev: %s", DEVDIR);
153 return 0;
154 }
155
156 r = 0;
157 while ((d = readdir(dp))) {
158 if (d->d_name[0] == '.')
159 continue;
160
161 r = dev_start2(ctx, dev_dhcpcd, d->d_name);
162 if (r != -1)
163 break;
164 }
165 closedir(dp);
166 return r;
167 }
168
169 static void
170 dev_handle_data(void *arg)
171 {
172 struct dhcpcd_ctx *ctx;
173
174 ctx = arg;
175 if (ctx->dev->handle_device(arg) == -1) {
176 /* XXX: an error occured. should we restart dev? */
177 }
178 }
179
180 int
181 dev_start(struct dhcpcd_ctx *ctx, int (*handler)(void *, int, const char *))
182 {
183 struct dev_dhcpcd dev_dhcpcd = {
184 .handle_interface = handler,
185 };
186
187 if (ctx->dev_fd != -1) {
188 logerrx("%s: already started on fd %d", __func__, ctx->dev_fd);
189 return ctx->dev_fd;
190 }
191
192 ctx->dev_fd = dev_start1(ctx, &dev_dhcpcd);
193 if (ctx->dev_fd != -1) {
194 if (eloop_event_add(ctx->eloop, ctx->dev_fd,
195 dev_handle_data, ctx) == -1)
196 {
197 logerr(__func__);
198 dev_stop1(ctx, 1);
199 return -1;
200 }
201 }
202
203 return ctx->dev_fd;
204 }