]> git.ipfire.org Git - thirdparty/systemd.git/blame - udev_lib.c
[PATCH] Shut up wait_for_sysfs class/net failure messages, as it's not possible
[thirdparty/systemd.git] / udev_lib.c
CommitLineData
c81b35c0
KS
1/*
2 * udev_lib - generic stuff used by udev
3 *
4 * Copyright (C) 2004 Kay Sievers <kay@vrfy.org>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 */
20
21
22#include <stdlib.h>
23#include <stdio.h>
4a539daf 24#include <stddef.h>
c81b35c0
KS
25#include <unistd.h>
26#include <fcntl.h>
4a539daf
KS
27#include <errno.h>
28#include <dirent.h>
c81b35c0
KS
29#include <sys/stat.h>
30#include <sys/mman.h>
31
c81b35c0 32#include "udev.h"
4a539daf 33#include "logging.h"
c81b35c0 34#include "udev_lib.h"
4a539daf 35#include "list.h"
c81b35c0
KS
36
37
38char *get_action(void)
39{
40 char *action;
41
42 action = getenv("ACTION");
43 if (action != NULL && strlen(action) > ACTION_SIZE)
44 action[ACTION_SIZE-1] = '\0';
45
46 return action;
47}
48
49char *get_devpath(void)
50{
51 char *devpath;
52
53 devpath = getenv("DEVPATH");
54 if (devpath != NULL && strlen(devpath) > DEVPATH_SIZE)
55 devpath[DEVPATH_SIZE-1] = '\0';
56
57 return devpath;
58}
59
4b06c852 60char *get_devname(void)
89fe4e00 61{
4b06c852 62 char *devname;
89fe4e00 63
4b06c852 64 devname = getenv("DEVNAME");
65 if (devname != NULL && strlen(devname) > NAME_SIZE)
66 devname[NAME_SIZE-1] = '\0';
89fe4e00 67
4b06c852 68 return devname;
89fe4e00
GKH
69}
70
c81b35c0
KS
71char *get_seqnum(void)
72{
73 char *seqnum;
74
75 seqnum = getenv("SEQNUM");
76
77 return seqnum;
78}
79
80char *get_subsystem(char *subsystem)
81{
82 if (subsystem != NULL && strlen(subsystem) > SUBSYSTEM_SIZE)
83 subsystem[SUBSYSTEM_SIZE-1] = '\0';
84
85 return subsystem;
86}
87
7b9b1839
KS
88#define BLOCK_PATH "/block/"
89#define CLASS_PATH "/class/"
90#define NET_PATH "/class/net/"
91
f61d732a
KS
92char get_device_type(const char *path, const char *subsystem)
93{
7b9b1839
KS
94 if (strcmp(subsystem, "block") == 0)
95 return 'b';
96
97 if (strcmp(subsystem, "net") == 0)
98 return 'n';
99
100 if (strncmp(path, BLOCK_PATH, strlen(BLOCK_PATH)) == 0 &&
101 strlen(path) > strlen(BLOCK_PATH))
f61d732a
KS
102 return 'b';
103
7b9b1839
KS
104 if (strncmp(path, NET_PATH, strlen(NET_PATH)) == 0 &&
105 strlen(path) > strlen(NET_PATH))
f61d732a
KS
106 return 'n';
107
7b9b1839
KS
108 if (strncmp(path, CLASS_PATH, strlen(CLASS_PATH)) == 0 &&
109 strlen(path) > strlen(CLASS_PATH))
f61d732a
KS
110 return 'c';
111
112 return '\0';
113}
114
7a947ce5
KS
115void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem)
116{
117 memset(udev, 0x00, sizeof(struct udevice));
118 strfieldcpy(udev->devpath, devpath);
119 strfieldcpy(udev->subsystem, subsystem);
120 udev->type = get_device_type(devpath, subsystem);
121}
122
c81b35c0
KS
123int file_map(const char *filename, char **buf, size_t *bufsize)
124{
125 struct stat stats;
126 int fd;
127
128 fd = open(filename, O_RDONLY);
129 if (fd < 0) {
130 return -1;
131 }
132
133 if (fstat(fd, &stats) < 0) {
686cecf2 134 close(fd);
c81b35c0
KS
135 return -1;
136 }
137
138 *buf = mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0);
139 if (*buf == MAP_FAILED) {
686cecf2 140 close(fd);
c81b35c0
KS
141 return -1;
142 }
143 *bufsize = stats.st_size;
144
145 close(fd);
146
147 return 0;
148}
149
150void file_unmap(char *buf, size_t bufsize)
151{
152 munmap(buf, bufsize);
153}
154
155size_t buf_get_line(char *buf, size_t buflen, size_t cur)
156{
157 size_t count = 0;
158
159 for (count = cur; count < buflen && buf[count] != '\n'; count++);
160
161 return count - cur;
162}
163
aef6bb13
KS
164void leading_slash(char *path)
165{
166 int len;
167
168 len = strlen(path);
169 if (len > 0 && path[len-1] != '/') {
170 path[len] = '/';
171 path[len+1] = '\0';
172 }
173}
174
175void no_leading_slash(char *path)
176{
177 int len;
178
179 len = strlen(path);
180 if (len > 0 && path[len-1] == '/')
181 path[len-1] = '\0';
182}
183
4a539daf
KS
184struct files {
185 struct list_head list;
186 char name[NAME_SIZE];
187};
188
189/* sort files in lexical order */
190static int file_list_insert(char *filename, struct list_head *file_list)
191{
192 struct files *loop_file;
193 struct files *new_file;
194
195 list_for_each_entry(loop_file, file_list, list) {
196 if (strcmp(loop_file->name, filename) > 0) {
197 break;
198 }
199 }
200
201 new_file = malloc(sizeof(struct files));
202 if (new_file == NULL) {
203 dbg("error malloc");
204 return -ENOMEM;
205 }
206
207 strfieldcpy(new_file->name, filename);
208 list_add_tail(&new_file->list, &loop_file->list);
209 return 0;
210}
211
aef6bb13 212/* calls function for every file found in specified directory */
4a539daf
KS
213int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix)
214{
215 struct dirent *ent;
216 DIR *dir;
217 char *ext;
218 char file[NAME_SIZE];
219 struct files *loop_file;
220 struct files *tmp_file;
221 LIST_HEAD(file_list);
222
223 dbg("open directory '%s'", dirname);
224 dir = opendir(dirname);
225 if (dir == NULL) {
226 dbg("unable to open '%s'", dirname);
227 return -1;
228 }
229
230 while (1) {
231 ent = readdir(dir);
232 if (ent == NULL || ent->d_name[0] == '\0')
233 break;
234
235 if ((ent->d_name[0] == '.') || (ent->d_name[0] == COMMENT_CHARACTER))
236 continue;
237
238 /* look for file with specified suffix */
239 ext = strrchr(ent->d_name, '.');
240 if (ext == NULL)
241 continue;
242
243 if (strcmp(ext, suffix) != 0)
244 continue;
245
246 dbg("put file '%s/%s' in list", dirname, ent->d_name);
247 file_list_insert(ent->d_name, &file_list);
248 }
249
250 /* call function for every file in the list */
251 list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) {
252 strfieldcpy(file, dirname);
253 strfieldcat(file, "/");
254 strfieldcat(file, loop_file->name);
255
256 fnct(file);
257
258 list_del(&loop_file->list);
259 free(loop_file);
260 }
261
262 closedir(dir);
263 return 0;
264}
6e3e3c34
HH
265
266/* Set the FD_CLOEXEC flag of desc if value is nonzero,
267 or clear the flag if value is 0.
268 Return 0 on success, or -1 on error with errno set. */
269
270int set_cloexec_flag (int desc, int value)
271{
272 int oldflags = fcntl (desc, F_GETFD, 0);
273 /* If reading the flags failed, return error indication now. */
274 if (oldflags < 0)
275 return oldflags;
276 /* Set just the flag we want to set. */
277 if (value != 0)
278 oldflags |= FD_CLOEXEC;
279 else
280 oldflags &= ~FD_CLOEXEC;
281 /* Store modified flag word in the descriptor. */
282 return fcntl (desc, F_SETFD, oldflags);
283}