1 /* 2 * Copyright (c) 2010 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Alex Hornung <ahornung@gmail.com> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/queue.h> 36 #include <libprop/proplib.h> 37 38 #define UDEV_DEVICE_PATH "/dev/udev" 39 #define LOCAL_BACKLOG 5 40 41 #define UDEV_DEVICE_FD_IDX 0 42 #define UDEV_SOCKET_FD_IDX 1 43 #define NFDS 2 44 45 46 struct pdev_array_entry { 47 int32_t refs; 48 int64_t generation; 49 prop_array_t pdev_array; 50 TAILQ_ENTRY(pdev_array_entry) link; 51 }; 52 53 struct event_filter { 54 int id; 55 int neg; 56 int type; 57 char *key; 58 char *wildcard_match; 59 regex_t regex_match; 60 61 TAILQ_ENTRY(event_filter) link; 62 }; 63 64 struct udev_monitor; 65 66 struct client_info { 67 pthread_t tid; 68 int fd; 69 struct udev_monitor *udm; 70 struct event_filter ev_filt; 71 }; 72 73 struct udev_monitor_event { 74 prop_dictionary_t ev_dict; 75 TAILQ_ENTRY(udev_monitor_event) link; 76 }; 77 78 struct udev_monitor { 79 pthread_mutex_t q_lock; 80 pthread_cond_t cond; 81 struct client_info *cli; 82 TAILQ_HEAD(, event_filter) ev_filt; 83 TAILQ_HEAD(, udev_monitor_event) ev_queue; 84 TAILQ_ENTRY(udev_monitor) link; 85 }; 86 87 struct cmd_function { 88 const char *cmd; 89 int (*fn)(struct client_info *, prop_dictionary_t); 90 }; 91 92 /* From udevd_socket.c */ 93 int init_local_server(const char *sockfile, int socktype, int nonblock); 94 int block_descriptor(int s); 95 int unblock_descriptor(int s); 96 int read_xml(int s, char **buf); 97 int send_xml(int s, char *xml); 98 99 /* From udevd_pdev.c */ 100 void pdev_array_entry_ref(struct pdev_array_entry *pae); 101 void pdev_array_entry_unref(struct pdev_array_entry *pae); 102 void pdev_array_entry_insert(prop_array_t pa); 103 void pdev_array_clean(void); 104 struct pdev_array_entry *pdev_array_entry_get(int64_t generation); 105 struct pdev_array_entry *pdev_array_entry_get_last(void); 106 107 /* From udevd_client.c */ 108 void handle_new_connection(int s); 109 int client_cmd_getdevs(struct client_info *cli, prop_dictionary_t dict); 110 111 112 /* From udevd_monitor.c */ 113 void monitor_queue_event(prop_dictionary_t ev_dict); 114 int client_cmd_monitor(struct client_info *cli, prop_dictionary_t dict); 115 int match_event_filter(struct udev_monitor *udm, prop_dictionary_t ev_dict); 116 struct udev_monitor *udev_monitor_init(struct client_info *cli, prop_array_t filters); 117 void udev_monitor_free(struct udev_monitor *udm); 118 119 /* From udevd.c */ 120 int ignore_signal(int signum); 121