chiark / gitweb /
[PATCH] spilt udev into pieces
[elogind.git] / udevsend.c
1 /*
2  * udevsend.c
3  *
4  * Userspace devfs
5  *
6  * Copyright (C) 2004 Ling, Xiaofeng <xiaofeng.ling@intel.com>
7  * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
8  *
9  *
10  *      This program is free software; you can redistribute it and/or modify it
11  *      under the terms of the GNU General Public License as published by the
12  *      Free Software Foundation version 2 of the License.
13  * 
14  *      This program is distributed in the hope that it will be useful, but
15  *      WITHOUT ANY WARRANTY; without even the implied warranty of
16  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *      General Public License for more details.
18  * 
19  *      You should have received a copy of the GNU General Public License along
20  *      with this program; if not, write to the Free Software Foundation, Inc.,
21  *      675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  */
24
25 #include <sys/types.h>
26 #include <sys/ipc.h>
27 #include <sys/msg.h>
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "udev.h"
34 #include "udevd.h"
35 #include "logging.h"
36
37 static inline char *get_action(void)
38 {
39         char *action;
40
41         action = getenv("ACTION");
42         return action;
43 }
44
45 static inline char *get_devpath(void)
46 {
47         char *devpath;
48
49         devpath = getenv("DEVPATH");
50         return devpath;
51 }
52
53 static inline char *get_seqnum(void)
54 {
55         char *seqnum;
56
57         seqnum = getenv("SEQNUM");
58         return seqnum;
59 }
60
61 static int build_hotplugmsg(struct hotplug_msg **ppmsg, char *action,
62                             char *devpath, char *subsystem, int seqnum)
63 {
64         struct hotplug_msg *pmsg;
65
66         pmsg = malloc(sizeof(struct hotplug_msg));
67         pmsg->mtype = HOTPLUGMSGTYPE;
68         pmsg->seqnum = seqnum;
69         strncpy(pmsg->action, action, 8);
70         strncpy(pmsg->devpath, devpath, 128);
71         strncpy(pmsg->subsystem, subsystem, 16);
72         *ppmsg = pmsg;
73         return sizeof(struct hotplug_msg);
74 }
75
76 static void free_hotplugmsg(struct hotplug_msg *pmsg)
77 {
78         free(pmsg);
79 }
80
81 int main(int argc, char* argv[])
82 {
83         int msgid;
84         key_t key;
85         struct msqid_ds  msg_queue;
86         struct msgbuf *pmsg;
87         char *action;
88         char *devpath;
89         char *subsystem;
90         char *seqnum;
91         int seq;
92         int retval = -EINVAL;
93         int size;
94
95         subsystem = argv[1];
96         if (subsystem == NULL) {
97                 dbg("no subsystem");
98                 goto exit;
99         }
100
101         devpath = get_devpath();
102         if (devpath == NULL) {
103                 dbg("no devpath");
104                 goto exit;
105         }
106
107         action = get_action();
108         if (action == NULL) {
109                 dbg("no action");
110                 goto exit;
111         }
112
113         seqnum = get_seqnum();
114         if (seqnum == NULL) {
115                 dbg("no seqnum");
116                 goto exit;
117         }
118
119         seq = atoi(seqnum);
120         key = ftok(DEFAULT_EXEC_PROGRAM, IPC_KEY_ID);
121         size =  build_hotplugmsg( (struct hotplug_msg**) &pmsg, action, devpath, subsystem, seq);
122         msgid = msgget(key, IPC_CREAT);
123         if (msgid == -1)
124         {
125                 dbg("open ipc queue error");
126                 goto exit;
127         }
128
129         /* get state of queue */
130         retval = msgctl(msgid, IPC_STAT, &msg_queue);
131         if (retval == -1) {
132                 dbg("error getting info on ipc queue");
133                 goto exit;
134         }
135         if (msg_queue.msg_qnum > 0)
136                 dbg("%li messages already in the ipc queue", msg_queue.msg_qnum);
137
138         retval = msgsnd(msgid, pmsg, size, 0);
139         free_hotplugmsg( (struct hotplug_msg*) pmsg);
140         if (retval == -1)
141         {
142                 dbg("send ipc message error");
143                 goto exit;
144         }
145         return 0;
146
147 exit:
148         if (retval > 0)
149                 retval = 0;
150
151         return retval;
152 }