]>
git.ipfire.org Git - thirdparty/systemd.git/blob - udev.c
6 * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
9 * This program 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 version 2 of the License.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include "udev_version.h"
36 static char *get_action(void)
40 action
= getenv("ACTION");
45 static char *get_device(void)
47 static char device
[255];
50 temp
= getenv("DEVPATH");
54 // strcpy(device, SYSFS_ROOT);
61 * Right now the major/minor of a device is stored in a file called
63 * The number is stored as:
67 * The value is in hex.
68 * Yes, this will probably change when we go to a bigger major/minor
69 * range, and will have to be changed at that time.
71 static int get_major_minor (char *dev
, int *major
, int *minor
)
79 /* add the dev file to the directory and see if it's present */
80 strncpy(filename
, dev
, sizeof(filename
));
81 strncat(filename
, DEV_FILE
, sizeof(filename
));
82 fd
= open(filename
, O_RDONLY
);
84 dbg("Can't open %s", filename
);
88 /* get the major/minor */
89 retval
= read(fd
, line
, sizeof(line
));
91 dbg("read error on %s", dev
);
98 *major
= (int)strtol(&temp
[0], NULL
, 16);
103 *minor
= (int)strtol(&temp
[0], NULL
, 16);
105 dbg("found major = %d, minor = %d", *major
, *minor
);
114 * Here would go a call to the naming deamon, to get the name we want to have
115 * for this device. But for now, let's just default to whatever the kernel is
116 * calling the device as that will keep the "old-style" naming policy
118 static char *get_name(char *dev
, int major
, int minor
)
120 static char name
[100];
123 temp
= strrchr(dev
, '/');
126 strncpy(name
, &temp
[1], sizeof(name
));
128 dbg("name is %s", name
);
134 * Again, this will live in the naming deamon
136 static int get_mode(char *name
, char *dev
, int major
, int minor
)
138 /* just default everyone to rw for the world! */
143 * We also want to add some permissions here, and possibly some symlinks
145 static int create_node(char *name
, char type
, int major
, int minor
, int mode
)
148 char mode_string
[100];
150 char major_string
[20];
151 char minor_string
[20];
155 strncpy(filename
, UDEV_ROOT
, sizeof(filename
));
156 strncat(filename
, name
, sizeof(filename
));
158 snprintf(mode_string
, sizeof(mode_string
), "--mode=%#o", mode
);
159 snprintf(type_string
, sizeof(type_string
), "%c", type
);
160 snprintf(major_string
, sizeof(major_string
), "%d", major
);
161 snprintf(minor_string
, sizeof(minor_string
), "%d", minor
);
164 argv
[1] = mode_string
;
166 argv
[3] = type_string
;
167 argv
[4] = major_string
;
168 argv
[5] = minor_string
;
170 dbg ("executing %s %s %s %s %s %s",
171 argv
[0], argv
[1], argv
[2], argv
[3], argv
[4], argv
[5]);
174 /* we are the child, so lets run the program */
179 dbg ("fork failed.");
189 * We also want to clean up any symlinks that were created in create_node()
191 static int delete_node(char *name
)
195 strncpy(filename
, UDEV_ROOT
, sizeof(filename
));
196 strncat(filename
, name
, sizeof(filename
));
198 dbg("unlinking %s", filename
);
199 return unlink(filename
);
202 static int add_device(char *device
, char type
, struct device_attr
*attr
)
208 int retval
= -EINVAL
;
210 retval
= get_major_minor(device
, &major
, &minor
);
212 dbg ("get_major_minor failed");
216 name
= get_name(device
, major
, minor
);
218 dbg ("get_name failed");
223 mode
= get_mode(name
, device
, major
, minor
);
225 dbg ("get_mode failed");
230 return create_node(attr
->name
, type
, attr
->major
, attr
->minor
, attr
->mode
);
236 static int remove_device(char *device
)
241 name
= get_name(device
, 0, 0);
243 dbg ("get_name failed");
248 return delete_node(name
);
254 int main(int argc
, char *argv
[])
256 struct device_attr attr
;
261 int retval
= -EINVAL
;
264 dbg ("unknown number of arguments");
270 /* sleep for a second or two to give the kernel a chance to
271 * create the dev file
275 /* for now, the block layer is the only place where block devices are */
277 if (strcmp(subsystem
, "block") == 0)
282 action
= get_action();
288 device
= get_device();
293 dbg("looking at %s", device
);
295 retval
= namedev_name_device(device
, &attr
);
299 if (strcmp(action
, "add") == 0)
300 return add_device(device
, type
, &attr
);
302 if (strcmp(action
, "remove") == 0)
303 return remove_device(device
);
305 dbg("Unknown action: %s", action
);