udev-event.c revision cdae488a3fbca5a61b3f8ea0651730cfa2da9cb0
fb0951b02ebf51a93acf12721d8857d31ce57ba3Lennart Poettering/*
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * Copyright (C) 2003-2009 Kay Sievers <kay.sievers@vrfy.org>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering *
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers * This program is free software: you can redistribute it and/or modify
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers * it under the terms of the GNU General Public License as published by
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * the Free Software Foundation, either version 2 of the License, or
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * (at your option) any later version.
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering *
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * This program is distributed in the hope that it will be useful,
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * but WITHOUT ANY WARRANTY; without even the implied warranty of
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * GNU General Public License for more details.
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering *
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * You should have received a copy of the GNU General Public License
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * along with this program. If not, see <http://www.gnu.org/licenses/>.
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering */
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <stdlib.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <stdio.h>
4e949c11a1df4547d5f102e4131e07b026369cd7Javier Jardón#include <stddef.h>
4e949c11a1df4547d5f102e4131e07b026369cd7Javier Jardón#include <unistd.h>
4e949c11a1df4547d5f102e4131e07b026369cd7Javier Jardón#include <fcntl.h>
44f169accf61df2f81cf41aef7a55553055795adDaniel Mack#include <errno.h>
1a435084b7f55bc24042f9bc47c18e4e2381f667Kay Sievers#include <ctype.h>
4e949c11a1df4547d5f102e4131e07b026369cd7Javier Jardón#include <string.h>
4e949c11a1df4547d5f102e4131e07b026369cd7Javier Jardón#include <time.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <net/if.h>
78a825f216d39ee0295b00647b059d45467e1d02Kay Sievers#include <sys/ioctl.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <sys/socket.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <linux/sockios.h>
a80db8bd5f7f15859e8891aab9fc3694ce4cd0bdJavier Jardón
a80db8bd5f7f15859e8891aab9fc3694ce4cd0bdJavier Jardón#include "udev.h"
4db6d587c37c0357d20c79bf1a7c9afd4c7ced61Kay Sievers
907dd1953b7517534d646f5b2777780020c896e2Kay Sieversstruct udev_event *udev_event_new(struct udev_device *dev)
eb7bbee6cd182d5c4eb1e1180631c35158f59379Kay Sievers{
6aad7f2cd75c88f990c7857bb173b3e8d0faee0fUmut Tezduyar Lindskog struct udev_event *event;
91ca5bf0b6f3b487a16cc262527c9de6744db624Martin Pitt
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers event = calloc(1, sizeof(struct udev_event));
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering if (event == NULL)
22be093ffb403a1c474037939ca9b88b1ee39f77Lennart Poettering return NULL;
4fecbe59dadaed314b792ed35ef5dc24c7047a18Jan Alexander Steffens (heftig) event->dev = dev;
0e3b0a95cc57cf8c51b20b5b94af7e51c5e424f3Jan Alexander Steffens (heftig) event->udev = udev_device_get_udev(dev);
0e3b0a95cc57cf8c51b20b5b94af7e51c5e424f3Jan Alexander Steffens (heftig) udev_list_init(&event->run_list);
0e3b0a95cc57cf8c51b20b5b94af7e51c5e424f3Jan Alexander Steffens (heftig) event->mode = 0660;
0e3b0a95cc57cf8c51b20b5b94af7e51c5e424f3Jan Alexander Steffens (heftig) dbg(event->udev, "allocated event %p\n", event);
0e3b0a95cc57cf8c51b20b5b94af7e51c5e424f3Jan Alexander Steffens (heftig) return event;
0e3b0a95cc57cf8c51b20b5b94af7e51c5e424f3Jan Alexander Steffens (heftig)}
0e3b0a95cc57cf8c51b20b5b94af7e51c5e424f3Jan Alexander Steffens (heftig)
0e3b0a95cc57cf8c51b20b5b94af7e51c5e424f3Jan Alexander Steffens (heftig)void udev_event_unref(struct udev_event *event)
4fecbe59dadaed314b792ed35ef5dc24c7047a18Jan Alexander Steffens (heftig){
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers if (event == NULL)
8666abb452db73d9a11ead61251eec42bc531cceKay Sievers return;
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering udev_list_cleanup_entries(event->udev, &event->run_list);
5e63ce78b5018ba612e794a610a6f13c5eefade7Cristian Rodríguez free(event->tmp_node);
3d585edbb14b9705c80183aeb16dfd0a28df0ac9Lennart Poettering free(event->program_result);
5e63ce78b5018ba612e794a610a6f13c5eefade7Cristian Rodríguez free(event->name);
0fa2cac4f0cdefaf1addd7f1fe0fd8113db9360bKay Sievers dbg(event->udev, "free event %p\n", event);
0fa2cac4f0cdefaf1addd7f1fe0fd8113db9360bKay Sievers free(event);
0fa2cac4f0cdefaf1addd7f1fe0fd8113db9360bKay Sievers}
4c6abc93c708762ae3f377eab8dbd357262cc432Koen Kooi
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburgersize_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size)
0fa2cac4f0cdefaf1addd7f1fe0fd8113db9360bKay Sievers{
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger struct udev_device *dev = event->dev;
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger enum subst_type {
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger SUBST_UNKNOWN,
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger SUBST_TEMP_NODE,
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger SUBST_ATTR,
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger SUBST_ENV,
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger SUBST_KERNEL,
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger SUBST_KERNEL_NUMBER,
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger SUBST_DRIVER,
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger SUBST_DEVPATH,
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger SUBST_ID,
a59f16ce4a11c440cb2136ad3d5e3184714c545eRobert Schiele SUBST_MAJOR,
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger SUBST_MINOR,
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera SUBST_RESULT,
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger SUBST_PARENT,
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger SUBST_NAME,
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger SUBST_LINKS,
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger SUBST_ROOT,
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger SUBST_SYS,
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger };
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger static const struct subst_map {
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera char *name;
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera char fmt;
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera enum subst_type type;
20f56fddcd58c84fa73597486e905c652667214fDidier Roche } map[] = {
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera { .name = "tempnode", .fmt = 'N', .type = SUBST_TEMP_NODE },
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering { .name = "attr", .fmt = 's', .type = SUBST_ATTR },
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering { .name = "sysfs", .fmt = 's', .type = SUBST_ATTR },
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering { .name = "env", .fmt = 'E', .type = SUBST_ENV },
3ce4fad8f548db9edb19869ea540e3192d2123f4Kay Sievers { .name = "kernel", .fmt = 'k', .type = SUBST_KERNEL },
f975e971accc4d50c73ae53167db3df7a7099cf2Lennart Poettering { .name = "number", .fmt = 'n', .type = SUBST_KERNEL_NUMBER },
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering { .name = "driver", .fmt = 'd', .type = SUBST_DRIVER },
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers { .name = "devpath", .fmt = 'p', .type = SUBST_DEVPATH },
92ec4495f76a7a2a6c31f5bb2a5240f78dcfe1d2Javier Jardón { .name = "id", .fmt = 'b', .type = SUBST_ID },
2d0efdf1af5ff77441228854343c61d42a89840cSamuli Suominen { .name = "major", .fmt = 'M', .type = SUBST_MAJOR },
2d0efdf1af5ff77441228854343c61d42a89840cSamuli Suominen { .name = "minor", .fmt = 'm', .type = SUBST_MINOR },
b51fc639f01ee6194af3e7e944a79accce474fe1Dave Reisner { .name = "result", .fmt = 'c', .type = SUBST_RESULT },
dd5ae4c36c89da5dbe8d1628939b26c00db98753Przemyslaw Kedzierski { .name = "parent", .fmt = 'P', .type = SUBST_PARENT },
dd5ae4c36c89da5dbe8d1628939b26c00db98753Przemyslaw Kedzierski { .name = "name", .fmt = 'D', .type = SUBST_NAME },
2d0efdf1af5ff77441228854343c61d42a89840cSamuli Suominen { .name = "links", .fmt = 'L', .type = SUBST_LINKS },
96ede2601f27cd5fe52eed96b873bef55cd0ce23Lennart Poettering { .name = "root", .fmt = 'r', .type = SUBST_ROOT },
2d0efdf1af5ff77441228854343c61d42a89840cSamuli Suominen { .name = "sys", .fmt = 'S', .type = SUBST_SYS },
edeb68c53f1cdc452016b4c8512586a70b1262e3Tom Gundersen };
2d0efdf1af5ff77441228854343c61d42a89840cSamuli Suominen const char *from;
7801356442578ff6e1c65844eb9e65c819af4660Zbigniew Jędrzejewski-Szmek char *s;
66b0e0e0e3652227fe107ab9d09fa14fd4bc4dfaCristian Rodríguez size_t l;
66b0e0e0e3652227fe107ab9d09fa14fd4bc4dfaCristian Rodríguez
f00929ad622c978f8ad83590a15a765b4beecac9Dimitri John Ledkov from = src;
f00929ad622c978f8ad83590a15a765b4beecac9Dimitri John Ledkov s = dest;
f00929ad622c978f8ad83590a15a765b4beecac9Dimitri John Ledkov l = size;
446883528524429283626208928b51f49f28f810Lennart Poettering
446883528524429283626208928b51f49f28f810Lennart Poettering while (1) {
4acbce79798347cddf1e1d42e9be571e0a041873Zbigniew Jędrzejewski-Szmek enum subst_type type = SUBST_UNKNOWN;
4acbce79798347cddf1e1d42e9be571e0a041873Zbigniew Jędrzejewski-Szmek char attrbuf[UTIL_PATH_SIZE];
c4a77bcb9a50f152557e25c90837d8bfef858729Marc-Antoine Perennou char *attr = NULL;
ac714a78fdca481488d88f84b6332d28083a4511Martin Jansa
ac714a78fdca481488d88f84b6332d28083a4511Martin Jansa while (from[0] != '\0') {
b62cfcea00862ccbf0e5e297f8a339f70987edefMichael Biebl if (from[0] == '$') {
b62cfcea00862ccbf0e5e297f8a339f70987edefMichael Biebl /* substitute named variable */
b62cfcea00862ccbf0e5e297f8a339f70987edefMichael Biebl unsigned int i;
9a60da2834074d970ca063c210fe9d2f05c70532Thierry Reding
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek if (from[1] == '$') {
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek from++;
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek goto copy;
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek }
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek for (i = 0; i < ARRAY_SIZE(map); i++) {
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek if (strncmp(&from[1], map[i].name, strlen(map[i].name)) == 0) {
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek type = map[i].type;
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek from += strlen(map[i].name)+1;
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek dbg(event->udev, "will substitute format name '%s'\n", map[i].name);
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek goto subst;
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek }
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek }
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek } else if (from[0] == '%') {
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek /* substitute format char */
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek unsigned int i;
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek if (from[1] == '%') {
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek from++;
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek goto copy;
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek }
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek for (i = 0; i < ARRAY_SIZE(map); i++) {
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek if (from[1] == map[i].fmt) {
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek type = map[i].type;
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek from += 2;
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek dbg(event->udev, "will substitute format char '%c'\n", map[i].fmt);
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek goto subst;
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek }
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek }
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek }
eb2e280f9c59b66965c9316eadc4c113a13ca744Lucas De Marchicopy:
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering /* copy char */
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (l == 0)
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering goto out;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering s[0] = from[0];
780040dc2a4b08a2c1fe5bd8db3a70e966c2acb3Kay Sievers from++;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering s++;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering l--;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering }
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering goto out;
03930e48636e86ad84946253ca2bf4f91deeb645Lennart Poetteringsubst:
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering /* extract possible $format{attr} */
693eb9a2d42d71445dad273a76e2470199d1dc5aLennart Poettering if (from[0] == '{') {
8dc31a63981267f257583ef82ceb79859ff243f8Daniel Mack unsigned int i;
8dc31a63981267f257583ef82ceb79859ff243f8Daniel Mack
8dc31a63981267f257583ef82ceb79859ff243f8Daniel Mack from++;
8dc31a63981267f257583ef82ceb79859ff243f8Daniel Mack for (i = 0; from[i] != '}'; i++) {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (from[i] == '\0') {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering err(event->udev, "missing closing brace for format '%s'\n", src);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering goto out;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering }
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering }
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (i >= sizeof(attrbuf))
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering goto out;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering memcpy(attrbuf, from, i);
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering attrbuf[i] = '\0';
f73fb7b742f294b6d2126afa16001bd2ff6ab461Filipe Brandenburger from += i+1;
0a98d66159e474915afd6597d3aa444a698fdd2dDavid Herrmann attr = attrbuf;
d200735e13c52dcfe36c0e066f9f6c2fbfb85a9cMichal Schmidt } else {
213298fb822258bb69c6b85b7c8d7f019fd2306aLennart Poettering attr = NULL;
693eb9a2d42d71445dad273a76e2470199d1dc5aLennart Poettering }
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering switch (type) {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering case SUBST_DEVPATH:
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieri l = util_strpcpy(&s, l, udev_device_get_devpath(dev));
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieri dbg(event->udev, "substitute devpath '%s'\n", udev_device_get_devpath(dev));
c1663b9daf5a43425e54bbe3daf6b10e64578f80Lennart Poettering break;
aca33b078cd32c5416a7fa3d5020a5d461c130eeCristian Rodríguez case SUBST_KERNEL:
2a4d1ec1520c926b0160efe14142634e164ddc30Cristian Rodríguez l = util_strpcpy(&s, l, udev_device_get_sysname(dev));
c1663b9daf5a43425e54bbe3daf6b10e64578f80Lennart Poettering dbg(event->udev, "substitute kernel name '%s'\n", udev_device_get_sysname(dev));
4f47bb8c5e5f234c614dc14532a9483328e61002Zbigniew Jędrzejewski-Szmek break;
a01a4517e16c532fbd5203fbfe2571255e2cd312Filipe Brandenburger case SUBST_KERNEL_NUMBER:
a01a4517e16c532fbd5203fbfe2571255e2cd312Filipe Brandenburger if (udev_device_get_sysnum(dev) == NULL)
a01a4517e16c532fbd5203fbfe2571255e2cd312Filipe Brandenburger break;
a01a4517e16c532fbd5203fbfe2571255e2cd312Filipe Brandenburger l = util_strpcpy(&s, l, udev_device_get_sysnum(dev));
a01a4517e16c532fbd5203fbfe2571255e2cd312Filipe Brandenburger dbg(event->udev, "substitute kernel number '%s'\n", udev_device_get_sysnum(dev));
a01a4517e16c532fbd5203fbfe2571255e2cd312Filipe Brandenburger break;
a01a4517e16c532fbd5203fbfe2571255e2cd312Filipe Brandenburger case SUBST_ID:
a01a4517e16c532fbd5203fbfe2571255e2cd312Filipe Brandenburger if (event->dev_parent == NULL)
a01a4517e16c532fbd5203fbfe2571255e2cd312Filipe Brandenburger break;
a01a4517e16c532fbd5203fbfe2571255e2cd312Filipe Brandenburger l = util_strpcpy(&s, l, udev_device_get_sysname(event->dev_parent));
a01a4517e16c532fbd5203fbfe2571255e2cd312Filipe Brandenburger dbg(event->udev, "substitute id '%s'\n", udev_device_get_sysname(event->dev_parent));
4f47bb8c5e5f234c614dc14532a9483328e61002Zbigniew Jędrzejewski-Szmek break;
4f47bb8c5e5f234c614dc14532a9483328e61002Zbigniew Jędrzejewski-Szmek case SUBST_DRIVER: {
65e3a2cf7c3b399853dd309f702ca5078b7d16eaZbigniew Jędrzejewski-Szmek const char *driver;
65e3a2cf7c3b399853dd309f702ca5078b7d16eaZbigniew Jędrzejewski-Szmek
65e3a2cf7c3b399853dd309f702ca5078b7d16eaZbigniew Jędrzejewski-Szmek if (event->dev_parent == NULL)
4f47bb8c5e5f234c614dc14532a9483328e61002Zbigniew Jędrzejewski-Szmek break;
0289f2fb2a64df53b589b771f69c43126b029590Zbigniew Jędrzejewski-Szmek
b850b06e1efcc7e27cfd785759a3a913ac9ed196Kay Sievers driver = udev_device_get_driver(event->dev_parent);
4fecbe59dadaed314b792ed35ef5dc24c7047a18Jan Alexander Steffens (heftig) if (driver == NULL)
b850b06e1efcc7e27cfd785759a3a913ac9ed196Kay Sievers break;
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek l = util_strpcpy(&s, l, driver);
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering dbg(event->udev, "substitute driver '%s'\n", driver);
0289f2fb2a64df53b589b771f69c43126b029590Zbigniew Jędrzejewski-Szmek break;
a6c0b31d509f76023d8efbcd5e912863c8fb254cZbigniew Jędrzejewski-Szmek }
a6c0b31d509f76023d8efbcd5e912863c8fb254cZbigniew Jędrzejewski-Szmek case SUBST_MAJOR: {
a6c0b31d509f76023d8efbcd5e912863c8fb254cZbigniew Jędrzejewski-Szmek char num[UTIL_PATH_SIZE];
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek
9e7adc3ae1133fa08a468768a490812299fad030Lucas De Marchi sprintf(num, "%d", major(udev_device_get_devnum(dev)));
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers l = util_strpcpy(&s, l, num);
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers dbg(event->udev, "substitute major number '%s'\n", num);
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers break;
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers }
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers case SUBST_MINOR: {
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers char num[UTIL_PATH_SIZE];
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers sprintf(num, "%d", minor(udev_device_get_devnum(dev)));
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers l = util_strpcpy(&s, l, num);
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers dbg(event->udev, "substitute minor number '%s'\n", num);
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers break;
2b4919a68cf826efbe939291e6dc4f08e824dc41Kay Sievers }
9e7adc3ae1133fa08a468768a490812299fad030Lucas De Marchi case SUBST_RESULT: {
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieri char *rest;
9d2d0fe1e3f28a639c26b62391f79cfd1450d91bEvangelos Foutras int i;
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering
39c4ead2323b45bbe9866e0f97fd8dcfb8a0bedeZbigniew Jędrzejewski-Szmek if (event->program_result == NULL)
2a4d1ec1520c926b0160efe14142634e164ddc30Cristian Rodríguez break;
39c4ead2323b45bbe9866e0f97fd8dcfb8a0bedeZbigniew Jędrzejewski-Szmek /* get part part of the result string */
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek i = 0;
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering if (attr != NULL)
ccd06097c79218f7d5ea4c21721bbcbc7c467dcaZbigniew Jędrzejewski-Szmek i = strtoul(attr, &rest, 10);
ccd06097c79218f7d5ea4c21721bbcbc7c467dcaZbigniew Jędrzejewski-Szmek if (i > 0) {
1c231f56482546725c4dbd3303f70300bd3c63e9Lennart Poettering char result[UTIL_PATH_SIZE];
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek char tmp[UTIL_PATH_SIZE];
de99c9dcbaf6e474551266d8f0b519bf2d8d0522Lennart Poettering char *cpos;
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek dbg(event->udev, "request part #%d of result string\n", i);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek util_strscpy(result, sizeof(result), event->program_result);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek cpos = result;
ccd06097c79218f7d5ea4c21721bbcbc7c467dcaZbigniew Jędrzejewski-Szmek while (--i) {
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek while (cpos[0] != '\0' && !isspace(cpos[0]))
2799e519cabb6dfa99341b9a56ebd4dc2a4ec22aZbigniew Jędrzejewski-Szmek cpos++;
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek while (isspace(cpos[0]))
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek cpos++;
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek }
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek if (i > 0) {
32dcef3ab1eb91ee469c3246ef859578dccd8a45Zbigniew Jędrzejewski-Szmek err(event->udev, "requested part of result string not found\n");
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek break;
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek }
be8737ae386166d2f279767ac87b226204c0de7eFilipe Brandenburger util_strscpy(tmp, sizeof(tmp), cpos);
be8737ae386166d2f279767ac87b226204c0de7eFilipe Brandenburger /* %{2+}c copies the whole string from the second part on */
be8737ae386166d2f279767ac87b226204c0de7eFilipe Brandenburger if (rest[0] != '+') {
be8737ae386166d2f279767ac87b226204c0de7eFilipe Brandenburger cpos = strchr(tmp, ' ');
be8737ae386166d2f279767ac87b226204c0de7eFilipe Brandenburger if (cpos)
be8737ae386166d2f279767ac87b226204c0de7eFilipe Brandenburger cpos[0] = '\0';
be8737ae386166d2f279767ac87b226204c0de7eFilipe Brandenburger }
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek l = util_strpcpy(&s, l, tmp);
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek dbg(event->udev, "substitute part of result string '%s'\n", tmp);
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek } else {
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek l = util_strpcpy(&s, l, event->program_result);
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek dbg(event->udev, "substitute result string '%s'\n", event->program_result);
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek }
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek break;
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek }
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek case SUBST_ATTR: {
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek const char *value = NULL;
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek char vbuf[UTIL_NAME_SIZE];
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers size_t len;
4b357e15876b730343db08719c877fdb45b6ad42Michael Marineau int count;
27c64db6dff88ebe9761dfe3b0c073d2a9bf2e41Zbigniew Jędrzejewski-Szmek
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers if (attr == NULL) {
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers err(event->udev, "missing file parameter for attr\n");
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers break;
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl }
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl /* try to read the value specified by "[dmi/id]product_name" */
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0)
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl value = vbuf;
5fd2e2284323304ad28f8ab80041f3cf6632dc72Michal Schmidt
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers /* try to read the attribute the device */
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers if (value == NULL)
27c64db6dff88ebe9761dfe3b0c073d2a9bf2e41Zbigniew Jędrzejewski-Szmek value = udev_device_get_sysattr_value(event->dev, attr);
4db17f291c627c885de668200ff8cce2e57c933fZbigniew Jędrzejewski-Szmek
e287086b8aa2558356af225a12d9bfea8e7d61caLennart Poettering /* try to read the attribute of the parent device, other matches have selected */
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev)
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek value = udev_device_get_sysattr_value(event->dev_parent, attr);
a8348796c0d39435b1c3d85ce6e95dad1ac85fecLennart Poettering
9388e99e208a6487b26dcbda86005ee9eba8d93dMichael Olbrich if (value == NULL)
3b794314149e40afaf3c456285e1e529747b6560Holger Schurig break;
5f381b355a95b953654e46ba3ccdc81bdec165eaLennart Poettering
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek /* strip trailing whitespace, and replace unwanted characters */
539618a0ddc2dc7f0fbe28de2ae0e07b34c81e60Lennart Poettering if (value != vbuf)
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek util_strscpy(vbuf, sizeof(vbuf), value);
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek len = strlen(vbuf);
84dd59b51c0db34f0334e90a5da2a45abcc9a52aDjalal Harouni while (len > 0 && isspace(vbuf[--len]))
84dd59b51c0db34f0334e90a5da2a45abcc9a52aDjalal Harouni vbuf[len] = '\0';
c4a5ddc9f29cf910fac9d814cd898b4cc2bd79b1Tom Gundersen count = udev_util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
6589d0dba2b1ccf2406db527c2c1b51c7143e117Jean-André Santoni if (count > 0)
75616a1332aff00d27db713cda3bd93c508a5b59Zbigniew Jędrzejewski-Szmek info(event->udev, "%i character(s) replaced\n" , count);
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek l = util_strpcpy(&s, l, vbuf);
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek dbg(event->udev, "substitute sysfs value '%s'\n", vbuf);
583c14fc04a089e9af70a3fa0b8c0a8c27c06ec0Michael Olbrich break;
56bf3853b4aefad31edf8631668446007e2347cbSusant Sahani }
66f4bc7795eb8ba1259db7fbdc567306eec89df7Susant Sahani case SUBST_PARENT: {
8ecec322fe6b34b64868d8cc3808b5613f09e8d3Zbigniew Jędrzejewski-Szmek struct udev_device *dev_parent;
38a0245fb2248744f3c38f451231c4f45bffdc42Susant Sahani const char *devnode;
c3eae485bb639352122ac0fbf30490e887f3bc44Susant Sahani
34f7b9f98facbf3431c6849622104cee992f2b7dLennart Poettering dev_parent = udev_device_get_parent(event->dev);
34f7b9f98facbf3431c6849622104cee992f2b7dLennart Poettering if (dev_parent == NULL)
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek break;
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek devnode = udev_device_get_devnode(dev_parent);
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek if (devnode != NULL) {
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek l = util_strpcpy(&s, l, &devnode[devlen]);
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek dbg(event->udev, "found parent '%s', got node name '%s'\n",
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek udev_device_get_syspath(dev_parent), &devnode[devlen]);
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek }
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek break;
34f7b9f98facbf3431c6849622104cee992f2b7dLennart Poettering }
cf1755bac0426132c21fdca519a336ce7d920277Michael Olbrich case SUBST_TEMP_NODE: {
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek dev_t devnum;
a8348796c0d39435b1c3d85ce6e95dad1ac85fecLennart Poettering struct stat statbuf;
b237ef2cfac7ab0b33170809e8cb64628606207dTollef Fog Heen char filename[UTIL_PATH_SIZE];
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer const char *devtype;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering
2270309471213a3c960543e523130627e9cb10e2Kay Sievers if (event->tmp_node != NULL) {
ac6b760ceedd4b21921b6a682cf1479af3d3024fZbigniew Jędrzejewski-Szmek l = util_strpcpy(&s, l, event->tmp_node);
ac6b760ceedd4b21921b6a682cf1479af3d3024fZbigniew Jędrzejewski-Szmek dbg(event->udev, "tempnode: return earlier created one\n");
8114dedc5910d9a9cec702f6b6658551a0cd9edeChengwei Yang break;
ac6b760ceedd4b21921b6a682cf1479af3d3024fZbigniew Jędrzejewski-Szmek }
ac6b760ceedd4b21921b6a682cf1479af3d3024fZbigniew Jędrzejewski-Szmek devnum = udev_device_get_devnum(dev);
ac6b760ceedd4b21921b6a682cf1479af3d3024fZbigniew Jędrzejewski-Szmek if (major(devnum) == 0)
ac6b760ceedd4b21921b6a682cf1479af3d3024fZbigniew Jędrzejewski-Szmek break;
ac6b760ceedd4b21921b6a682cf1479af3d3024fZbigniew Jędrzejewski-Szmek /* lookup kernel provided node */
2270309471213a3c960543e523130627e9cb10e2Kay Sievers if (udev_device_get_knodename(dev) != NULL) {
4b357e15876b730343db08719c877fdb45b6ad42Michael Marineau util_strscpyl(filename, sizeof(filename),
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing udev_get_dev_path(event->udev), "/", udev_device_get_knodename(dev), NULL);
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing if (stat(filename, &statbuf) == 0 && statbuf.st_rdev == devnum) {
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing l = util_strpcpy(&s, l, filename);
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing dbg(event->udev, "tempnode: return kernel node\n");
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing break;
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing }
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing }
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing /* lookup /dev/{char,block}/<maj>:<min> */
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing if (strcmp(udev_device_get_subsystem(dev), "block") == 0)
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing devtype = "block";
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek else
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek devtype = "char";
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek snprintf(filename, sizeof(filename), "%s/%s/%u:%u",
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek udev_get_dev_path(event->udev), devtype,
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek major(udev_device_get_devnum(dev)),
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek minor(udev_device_get_devnum(dev)));
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek if (stat(filename, &statbuf) == 0 && statbuf.st_rdev == devnum) {
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek l = util_strpcpy(&s, l, filename);
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek dbg(event->udev, "tempnode: return maj:min node\n");
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek break;
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek }
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen /* create temporary node */
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen dbg(event->udev, "tempnode: create temp node\n");
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen asprintf(&event->tmp_node, "%s/.tmp-%s-%u:%u",
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen udev_get_dev_path(event->udev), devtype,
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen major(udev_device_get_devnum(dev)),
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen minor(udev_device_get_devnum(dev)));
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen if (event->tmp_node == NULL)
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen break;
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen udev_node_mknod(dev, event->tmp_node, makedev(0, 0), 0600, 0, 0);
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen l = util_strpcpy(&s, l, event->tmp_node);
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen break;
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen }
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen case SUBST_NAME:
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen if (event->name != NULL) {
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen l = util_strpcpy(&s, l, event->name);
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen dbg(event->udev, "substitute name '%s'\n", event->name);
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen } else {
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen l = util_strpcpy(&s, l, udev_device_get_sysname(dev));
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen dbg(event->udev, "substitute sysname '%s'\n", udev_device_get_sysname(dev));
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen }
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen break;
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen case SUBST_LINKS: {
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen struct udev_list_entry *list_entry;
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen list_entry = udev_device_get_devlinks_list_entry(dev);
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen if (list_entry == NULL)
e2ca86cf78f911a8be51f0224796e24883019139Dave Reisner break;
e2ca86cf78f911a8be51f0224796e24883019139Dave Reisner l = util_strpcpy(&s, l, &udev_list_entry_get_name(list_entry)[devlen]);
a18535d9e138c525d0443ec9f30a90b3e2184686Tom Gundersen udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
e2ca86cf78f911a8be51f0224796e24883019139Dave Reisner l = util_strpcpyl(&s, l, " ", &udev_list_entry_get_name(list_entry)[devlen], NULL);
70d8320978dcbce022d9acbb953a10a7aca049abDavid Strauss break;
e2ca86cf78f911a8be51f0224796e24883019139Dave Reisner }
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen case SUBST_ROOT:
c4955740969d7ba8ba43b024bca1a0a5b56eb8e8Tom Gundersen l = util_strpcpy(&s, l, udev_get_dev_path(event->udev));
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen dbg(event->udev, "substitute udev_root '%s'\n", udev_get_dev_path(event->udev));
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen break;
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen case SUBST_SYS:
f553b3b1074151200187df916427a1468186435eAnders Olofsson l = util_strpcpy(&s, l, udev_get_sys_path(event->udev));
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann dbg(event->udev, "substitute sys_path '%s'\n", udev_get_sys_path(event->udev));
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann break;
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann case SUBST_ENV:
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann if (attr == NULL) {
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann dbg(event->udev, "missing attribute\n");
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann break;
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann } else {
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann const char *value;
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann value = udev_device_get_property_value(event->dev, attr);
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann if (value == NULL)
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmann break;
f553b3b1074151200187df916427a1468186435eAnders Olofsson dbg(event->udev, "substitute env '%s=%s'\n", attr, value);
f553b3b1074151200187df916427a1468186435eAnders Olofsson l = util_strpcpy(&s, l, value);
f553b3b1074151200187df916427a1468186435eAnders Olofsson break;
f553b3b1074151200187df916427a1468186435eAnders Olofsson }
d47f6ca5f9b7a0b400d8bdb050151a0284fb4bdbGabriel de Perthuis default:
f553b3b1074151200187df916427a1468186435eAnders Olofsson err(event->udev, "unknown substitution type=%i\n", type);
f553b3b1074151200187df916427a1468186435eAnders Olofsson break;
f553b3b1074151200187df916427a1468186435eAnders Olofsson }
f553b3b1074151200187df916427a1468186435eAnders Olofsson }
f553b3b1074151200187df916427a1468186435eAnders Olofsson
f553b3b1074151200187df916427a1468186435eAnders Olofssonout:
728beb28a713709f521d374c9f8f3da781969d26Tom Gundersen s[0] = '\0';
8d3ae2bd4c9bf9fc2e57f7b3776325a1c750ca30Chris Leech dbg(event->udev, "'%s' -> '%s' (%zu)\n", src, dest, l);
8d3ae2bd4c9bf9fc2e57f7b3776325a1c750ca30Chris Leech return l;
8218743e1eda6d279d6366739f196703640c8c39Martin Pitt}
8d3ae2bd4c9bf9fc2e57f7b3776325a1c750ca30Chris Leech
8d3ae2bd4c9bf9fc2e57f7b3776325a1c750ca30Chris Leechstatic void rename_netif_kernel_log(struct ifreq ifr)
8d3ae2bd4c9bf9fc2e57f7b3776325a1c750ca30Chris Leech{
8d3ae2bd4c9bf9fc2e57f7b3776325a1c750ca30Chris Leech int klog;
8d3ae2bd4c9bf9fc2e57f7b3776325a1c750ca30Chris Leech FILE *f;
8d3ae2bd4c9bf9fc2e57f7b3776325a1c750ca30Chris Leech
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier klog = open("/dev/kmsg", O_WRONLY);
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier if (klog < 0)
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier return;
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier f = fdopen(klog, "w");
17df7223be064b1542dbe868e3b35cca977ee639Lennart Poettering if (f == NULL) {
17df7223be064b1542dbe868e3b35cca977ee639Lennart Poettering close(klog);
17df7223be064b1542dbe868e3b35cca977ee639Lennart Poettering return;
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier }
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier fprintf(f, "<6>udev: renamed network interface %s to %s\n",
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier ifr.ifr_name, ifr.ifr_newname);
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier fclose(f);
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier}
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sieversstatic int rename_netif(struct udev_event *event)
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu{
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu struct udev_device *dev = event->dev;
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu int sk;
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu struct ifreq ifr;
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu int err;
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu info(event->udev, "changing net interface name from '%s' to '%s'\n",
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu udev_device_get_sysname(dev), event->name);
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu sk = socket(PF_INET, SOCK_DGRAM, 0);
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu if (sk < 0) {
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu err(event->udev, "error opening socket: %m\n");
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu return -1;
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers }
591622d7efbc828f00f190d91b6608148b967ff5Lennart Poettering
591622d7efbc828f00f190d91b6608148b967ff5Lennart Poettering memset(&ifr, 0x00, sizeof(struct ifreq));
591622d7efbc828f00f190d91b6608148b967ff5Lennart Poettering util_strscpy(ifr.ifr_name, IFNAMSIZ, udev_device_get_sysname(dev));
3f8cc098d218525710e5cbad9adf37001d3b6060Jan Engelhardt util_strscpy(ifr.ifr_newname, IFNAMSIZ, event->name);
6a6751fe24bf456cf5c1efad785a4d11e78b42d0Lennart Poettering err = ioctl(sk, SIOCSIFNAME, &ifr);
6a6751fe24bf456cf5c1efad785a4d11e78b42d0Lennart Poettering if (err == 0)
6a6751fe24bf456cf5c1efad785a4d11e78b42d0Lennart Poettering rename_netif_kernel_log(ifr);
6a6751fe24bf456cf5c1efad785a4d11e78b42d0Lennart Poettering else {
591622d7efbc828f00f190d91b6608148b967ff5Lennart Poettering int loop;
591622d7efbc828f00f190d91b6608148b967ff5Lennart Poettering
591622d7efbc828f00f190d91b6608148b967ff5Lennart Poettering /* see if the destination interface name already exists */
56cf987fe74270bde4e16c7ec9e0414a9030723bDaniel J Walsh if (errno != EEXIST) {
591622d7efbc828f00f190d91b6608148b967ff5Lennart Poettering err(event->udev, "error changing netif name %s to %s: %m\n",
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez ifr.ifr_name, ifr.ifr_newname);
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer goto exit;
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer }
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer /* free our own name, another process may wait for us */
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer util_strscpyl(ifr.ifr_newname, IFNAMSIZ, udev_device_get_sysname(dev), "_rename", NULL);
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer err = ioctl(sk, SIOCSIFNAME, &ifr);
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer if (err != 0) {
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer err(event->udev, "error changing netif name %s to %s: %m\n",
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer ifr.ifr_name, ifr.ifr_newname);
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer goto exit;
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer }
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer /* wait 90 seconds for our target to become available */
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer util_strscpy(ifr.ifr_name, IFNAMSIZ, ifr.ifr_newname);
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer util_strscpy(ifr.ifr_newname, IFNAMSIZ, event->name);
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez loop = 90 * 20;
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez while (loop--) {
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez const struct timespec duration = { 0, 1000 * 1000 * 1000 / 20 };
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez err = ioctl(sk, SIOCSIFNAME, &ifr);
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez if (err == 0) {
5ec6b15b65304d94dc1c8cbad05c8b996b470d3aKay Sievers rename_netif_kernel_log(ifr);
56cf987fe74270bde4e16c7ec9e0414a9030723bDaniel J Walsh break;
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez }
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez if (errno != EEXIST) {
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez err(event->udev, "error changing net interface name %s to %s: %m\n",
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez ifr.ifr_name, ifr.ifr_newname);
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez break;
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez }
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez dbg(event->udev, "wait for netif '%s' to become free, loop=%i\n",
ad95fd1d2b9c6344864857c2ba7634fd87753f8eZbigniew Jędrzejewski-Szmek event->name, (90 * 20) - loop);
ad95fd1d2b9c6344864857c2ba7634fd87753f8eZbigniew Jędrzejewski-Szmek nanosleep(&duration, NULL);
ad95fd1d2b9c6344864857c2ba7634fd87753f8eZbigniew Jędrzejewski-Szmek }
ad95fd1d2b9c6344864857c2ba7634fd87753f8eZbigniew Jędrzejewski-Szmek }
ad95fd1d2b9c6344864857c2ba7634fd87753f8eZbigniew Jędrzejewski-Szmekexit:
ad95fd1d2b9c6344864857c2ba7634fd87753f8eZbigniew Jędrzejewski-Szmek close(sk);
ad95fd1d2b9c6344864857c2ba7634fd87753f8eZbigniew Jędrzejewski-Szmek return err;
ad95fd1d2b9c6344864857c2ba7634fd87753f8eZbigniew Jędrzejewski-Szmek}
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers
807e17f05e217b474af39503efb9503d81b12596Lennart Poetteringint udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules)
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering{
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek struct udev_device *dev = event->dev;
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering int err = 0;
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek if (udev_device_get_sysname_old(dev) != NULL &&
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek strcmp(udev_device_get_sysname_old(dev), udev_device_get_sysname(dev)) != 0) {
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek udev_device_rename_db(dev);
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek info(event->udev, "moved database from '%s:%s' to '%s:%s'\n",
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek udev_device_get_subsystem(dev), udev_device_get_sysname_old(dev),
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering udev_device_get_subsystem(dev), udev_device_get_sysname(dev));
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering }
edce2aed3aa93b84f7b4c70412bdb665da2977b0Lennart Poettering
edce2aed3aa93b84f7b4c70412bdb665da2977b0Lennart Poettering /* add device node */
edce2aed3aa93b84f7b4c70412bdb665da2977b0Lennart Poettering if (major(udev_device_get_devnum(dev)) != 0 &&
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek (strcmp(udev_device_get_action(dev), "add") == 0 || strcmp(udev_device_get_action(dev), "change") == 0)) {
edce2aed3aa93b84f7b4c70412bdb665da2977b0Lennart Poettering char filename[UTIL_PATH_SIZE];
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek struct udev_device *dev_old;
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek int delete_kdevnode = 0;
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek dbg(event->udev, "device node add '%s'\n", udev_device_get_devpath(dev));
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek /* read old database entry */
edce2aed3aa93b84f7b4c70412bdb665da2977b0Lennart Poettering dev_old = udev_device_new_from_syspath(event->udev, udev_device_get_syspath(dev));
edce2aed3aa93b84f7b4c70412bdb665da2977b0Lennart Poettering if (dev_old != NULL) {
8af3cf74df03f7528f9e2605ec7896a5daf0f711Lennart Poettering udev_device_read_db(dev_old);
8af3cf74df03f7528f9e2605ec7896a5daf0f711Lennart Poettering udev_device_set_info_loaded(dev_old);
831f18cbf3f250207fcde15ea736639898317d77Lennart Poettering
8af3cf74df03f7528f9e2605ec7896a5daf0f711Lennart Poettering /* disable watch during event processing */
8af3cf74df03f7528f9e2605ec7896a5daf0f711Lennart Poettering udev_watch_end(event->udev, dev_old);
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek }
831f18cbf3f250207fcde15ea736639898317d77Lennart Poettering
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek udev_rules_apply_to_event(rules, event);
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek if (event->tmp_node != NULL) {
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek dbg(event->udev, "cleanup temporary device node\n");
8af3cf74df03f7528f9e2605ec7896a5daf0f711Lennart Poettering util_unlink_secure(event->udev, event->tmp_node);
8af3cf74df03f7528f9e2605ec7896a5daf0f711Lennart Poettering free(event->tmp_node);
8af3cf74df03f7528f9e2605ec7896a5daf0f711Lennart Poettering event->tmp_node = NULL;
d89c8fdf48c7bad5816b9f2e77e8361721f22517Zbigniew Jędrzejewski-Szmek }
d89c8fdf48c7bad5816b9f2e77e8361721f22517Zbigniew Jędrzejewski-Szmek
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek if (event->name != NULL && event->name[0] == '\0') {
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek info(event->udev, "device node creation suppressed\n");
898d5660eba688c566e90d0a15050dfeb8b8265dZbigniew Jędrzejewski-Szmek delete_kdevnode = 1;
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek goto exit_add;
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek }
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek /* if rule given name disagrees with kernel node name, delete kernel node */
1a2a0ac53bbe724caf41c2bcf22ab9ea32b63d4eZbigniew Jędrzejewski-Szmek if (event->name != NULL && udev_device_get_knodename(dev) != NULL) {
d89c8fdf48c7bad5816b9f2e77e8361721f22517Zbigniew Jędrzejewski-Szmek if (strcmp(event->name, udev_device_get_knodename(dev)) != 0)
d89c8fdf48c7bad5816b9f2e77e8361721f22517Zbigniew Jędrzejewski-Szmek delete_kdevnode = 1;
d89c8fdf48c7bad5816b9f2e77e8361721f22517Zbigniew Jędrzejewski-Szmek }
3b1a55e110ab387a8d213581983e20c0a63d7894Zbigniew Jędrzejewski-Szmek
3b1a55e110ab387a8d213581983e20c0a63d7894Zbigniew Jędrzejewski-Szmek /* no rule, use kernel provided name */
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers if (event->name == NULL) {
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering if (udev_device_get_knodename(dev) != NULL) {
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering event->name = strdup(udev_device_get_knodename(dev));
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering info(event->udev, "no node name set, will use kernel supplied name '%s'\n", event->name);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering } else {
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering event->name = strdup(udev_device_get_sysname(event->dev));
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering info(event->udev, "no node name set, will use device name '%s'\n", event->name);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering }
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering }
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering /* something went wrong */
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering if (event->name == NULL) {
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering err(event->udev, "no node name for '%s'\n", udev_device_get_sysname(event->dev));
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering goto exit_add;
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering }
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering /* set device node name */
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", event->name, NULL);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering udev_device_set_devnode(dev, filename);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering /* write current database entry */
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering udev_device_update_db(dev);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering /* remove/update possible left-over symlinks from old database entry */
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering if (dev_old != NULL)
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering udev_node_update_old_links(dev, dev_old);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering /* create new node and symlinks */
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering err = udev_node_add(dev, event->mode, event->uid, event->gid);
6a6751fe24bf456cf5c1efad785a4d11e78b42d0Lennart Poetteringexit_add:
812cce323db081634f37e4ec6d29f2b9328a3f52Lennart Poettering if (delete_kdevnode && udev_device_get_knodename(dev) != NULL) {
812cce323db081634f37e4ec6d29f2b9328a3f52Lennart Poettering struct stat stats;
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering util_strscpyl(filename, sizeof(filename),
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering udev_get_dev_path(event->udev), "/", udev_device_get_knodename(dev), NULL);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering if (stat(filename, &stats) == 0 && stats.st_rdev == udev_device_get_devnum(dev)) {
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering unlink(filename);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering util_delete_path(event->udev, filename);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering info(event->udev, "removed kernel created node '%s'\n", filename);
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers }
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering }
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering udev_device_unref(dev_old);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering goto exit;
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering }
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering /* add netif */
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (strcmp(udev_device_get_subsystem(dev), "net") == 0 && strcmp(udev_device_get_action(dev), "add") == 0) {
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering dbg(event->udev, "netif add '%s'\n", udev_device_get_devpath(dev));
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering udev_device_delete_db(dev);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering udev_rules_apply_to_event(rules, event);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (event->name == NULL)
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering goto exit;
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering /* look if we want to change the name of the netif */
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (strcmp(event->name, udev_device_get_sysname(dev)) != 0) {
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering char syspath[UTIL_PATH_SIZE];
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering char *pos;
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering err = rename_netif(event);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (err != 0)
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering goto exit;
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering info(event->udev, "renamed netif to '%s'\n", event->name);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering /* remember old name */
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering udev_device_add_property(dev, "INTERFACE_OLD", udev_device_get_sysname(dev));
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering /* now change the devpath, because the kernel device name has changed */
a48a62a1af02aec4473c9deed98dd5b89d210f93Zbigniew Jędrzejewski-Szmek util_strscpy(syspath, sizeof(syspath), udev_device_get_syspath(dev));
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering pos = strrchr(syspath, '/');
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (pos != NULL) {
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering pos++;
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering util_strscpy(pos, sizeof(syspath) - (pos - syspath), event->name);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering udev_device_set_syspath(event->dev, syspath);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering udev_device_add_property(dev, "INTERFACE", udev_device_get_sysname(dev));
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering info(event->udev, "changed devpath to '%s'\n", udev_device_get_devpath(dev));
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering }
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering }
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski udev_device_update_db(dev);
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski goto exit;
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski }
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski /* remove device node */
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski if (major(udev_device_get_devnum(dev)) != 0 && strcmp(udev_device_get_action(dev), "remove") == 0) {
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski /* import database entry and delete it */
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski udev_device_read_db(dev);
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski udev_device_set_info_loaded(dev);
d2edfae0f9bdbecf6a8518e2a5bcf06f470e0d9eKay Sievers udev_device_delete_db(dev);
d2edfae0f9bdbecf6a8518e2a5bcf06f470e0d9eKay Sievers
d2edfae0f9bdbecf6a8518e2a5bcf06f470e0d9eKay Sievers /* remove watch */
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski udev_watch_end(event->udev, dev);
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski
1fab0cbafcb67cff912d0e45de9677135550f924Sangjung Woo if (udev_device_get_devnode(dev) == NULL) {
8b197c3a8a57c3f7c231b39e5660856fd9580c80Auke Kok char devnode[UTIL_PATH_SIZE];
8b197c3a8a57c3f7c231b39e5660856fd9580c80Auke Kok
e174dce27173396ed8034c9cfda87eb210365126WaLyong Cho info(event->udev, "'%s' not found in database, using kernel name '%s'\n",
1fab0cbafcb67cff912d0e45de9677135550f924Sangjung Woo udev_device_get_syspath(dev), udev_device_get_knodename(dev));
e174dce27173396ed8034c9cfda87eb210365126WaLyong Cho util_strscpyl(devnode, sizeof(devnode),
e174dce27173396ed8034c9cfda87eb210365126WaLyong Cho udev_get_dev_path(event->udev), "/", udev_device_get_knodename(dev), NULL);
1fab0cbafcb67cff912d0e45de9677135550f924Sangjung Woo udev_device_set_devnode(dev, devnode);
1fab0cbafcb67cff912d0e45de9677135550f924Sangjung Woo }
1fab0cbafcb67cff912d0e45de9677135550f924Sangjung Woo
1fab0cbafcb67cff912d0e45de9677135550f924Sangjung Woo udev_rules_apply_to_event(rules, event);
e174dce27173396ed8034c9cfda87eb210365126WaLyong Cho
e174dce27173396ed8034c9cfda87eb210365126WaLyong Cho if (udev_device_get_ignore_remove(dev)) {
e174dce27173396ed8034c9cfda87eb210365126WaLyong Cho info(event->udev, "ignore_remove for '%s'\n", udev_device_get_devnode(dev));
e174dce27173396ed8034c9cfda87eb210365126WaLyong Cho goto exit;
8b197c3a8a57c3f7c231b39e5660856fd9580c80Auke Kok }
8b197c3a8a57c3f7c231b39e5660856fd9580c80Auke Kok
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski err = udev_node_remove(dev);
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski goto exit;
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski }
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski
dd5ae4c36c89da5dbe8d1628939b26c00db98753Przemyslaw Kedzierski /* default devices */
dd5ae4c36c89da5dbe8d1628939b26c00db98753Przemyslaw Kedzierski udev_rules_apply_to_event(rules, event);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering if (strcmp(udev_device_get_action(dev), "remove") != 0)
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering udev_device_update_db(dev);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering else
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering udev_device_delete_db(dev);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poetteringexit:
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering return err;
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering}
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poetteringint udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering{
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson struct udev_list_entry *list_entry;
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson int err = 0;
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson dbg(event->udev, "executing run list\n");
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson const char *cmd = udev_list_entry_get_name(list_entry);
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson if (strncmp(cmd, "socket:", strlen("socket:")) == 0) {
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson struct udev_monitor *monitor;
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson monitor = udev_monitor_new_from_socket(event->udev, &cmd[strlen("socket:")]);
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson if (monitor == NULL)
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson continue;
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson udev_monitor_send_device(monitor, NULL, event->dev);
79e8bde40da4d18c553b64299ebb69f409260df4Olof Johansson udev_monitor_unref(monitor);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering } else {
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering char program[UTIL_PATH_SIZE];
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering char **envp;
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering udev_event_apply_format(event, cmd, program, sizeof(program));
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering envp = udev_device_get_properties_envp(event->dev);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering if (util_run_program(event->udev, program, envp, NULL, 0, NULL, sigmask) != 0) {
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering if (udev_list_entry_get_flag(list_entry))
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering err = -1;
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering }
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering }
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering }
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering return err;
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering}
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering