replace the hotplug2 fork handling hack with a better solution implemented in upstrea...
[openwrt.git] / package / hotplug2 / patches / 100-svn_update.patch
1 diff -urN -x.svn hotplug2-0.9/AUTHORS hotplug2/AUTHORS
2 --- hotplug2-0.9/AUTHORS        2006-10-08 18:13:50.000000000 +0200
3 +++ hotplug2/AUTHORS    2007-06-30 12:59:20.459674000 +0200
4 @@ -1,7 +1,11 @@
5   Authors:
6  ----------
7  iSteve <isteve@bofh.cz>
8 -Tomas Janousek <tomi@nomi.cz>
9 +
10 + Contributions:
11 +----------------
12 +nbd (rules override patch, various fixes, suggestions, testing etc.)
13 +Tomas Janousek <tomi@nomi.cz> (Makefiles, SVN hosting)
14  
15   Thanks to:
16  ------------
17 @@ -10,5 +14,9 @@
18  Randy Dunlap (help with isapnpmap)
19  Igor2 (provided testing machines)
20  yanek (provided testing machines)
21 +Zdenek Styblik (provided testing OpenWRT device)
22 +OpenWRT team (for trusting this project)
23 +mtu (debugging, testing, ideas)
24 +mnemoc (trivial sanity changes on makefiles, linux24 compat patches)
25  
26 -...anyone taking more than a short peek at the software.
27 \ No newline at end of file
28 +...anyone taking more than a short peek at the software.
29 diff -urN -x.svn hotplug2-0.9/Changelog hotplug2/Changelog
30 --- hotplug2-0.9/Changelog      2006-10-08 15:32:31.000000000 +0200
31 +++ hotplug2/Changelog  2007-06-28 14:51:00.009934640 +0200
32 @@ -1,3 +1,10 @@
33 +0.9 - 1.0:
34 +* Add --set-rules-file.
35 +* Allow any ACTION.
36 +* Add 'printdebug' rule.
37 +* Fix chmod, chown, chgrp.
38 +* Use octal for chmod and makedev.
39 +
40  0.8 - 0.9:
41  * Use signals to handle children.
42  * Separate info and debugging output.
43 @@ -44,4 +51,4 @@
44  * Add more actions.
45  * Significant cleanup of rules handling.
46  * Better error reporting.
47
48 \ No newline at end of file
49
50 diff -urN -x.svn hotplug2-0.9/common.mak hotplug2/common.mak
51 --- hotplug2-0.9/common.mak     2006-09-26 01:03:08.000000000 +0200
52 +++ hotplug2/common.mak 2007-06-28 14:54:56.013056712 +0200
53 @@ -10,7 +10,7 @@
54  .PHONY: all clean dep install install-recursive clean-recursive \
55         dep-recursive all-recursive
56  
57 -MAKEDEP=-gcc $(CFLAGS) -MM $(wildcard *.c *.cc) > .depend
58 +MAKEDEP=-$(CC) $(CFLAGS) -MM $(wildcard *.c *.cc) > .depend
59  dep: dep-recursive
60         $(MAKEDEP)
61  .depend:
62 diff -urN -x.svn hotplug2-0.9/docs/hotplug2.8 hotplug2/docs/hotplug2.8
63 --- hotplug2-0.9/docs/hotplug2.8        2006-09-26 09:23:36.000000000 +0200
64 +++ hotplug2/docs/hotplug2.8    2007-06-28 14:50:59.874955160 +0200
65 @@ -22,6 +22,8 @@
66  .TP 
67  \fB\-\-dumb\fR, \fB\-\-no\-dumb\fR
68  Run or do not run hotplug2 in dumb mode. Dumb mode means that rules are being ignored, the only action taken is mload modules to all devices whose uevent exports MODALIAS. Only available if compiled with HAVE_RULES.
69 +\fB\-\-override\fR, \fB\-\-no\-override\fR
70 +Allows hotplug2 behavior overriding for different rules, using various flags. See hotplug2 rules documentation for details. The default is not to allow overriding, the flags are therefore ignored.
71  .TP 
72  \fB\-\-max\-children <value>\fR
73  Set the value of maximum children hotplug2 may have running simultaneously. Default is 20.
74 @@ -31,6 +33,8 @@
75  .TP 
76  \fB\-\-set\-modprobe\-cmd <cmd>\fR
77  Sets the application used to perform modprobe. It only gets used in dumb mode. Default is to autodetect: if '/bin/modprobe' is from module\-init\-tools, use '/sbin/modprobe', otherwise use '/sbin/hotplug2\-modwrap'.
78 +\fB\-\-set\-rules\-file <file>\fR
79 +Sets the path to the file containing hotplug2 rules.
80  .SH "SIGNALS"
81  .TP 
82  \fBSIGUSR1\fR
83 diff -urN -x.svn hotplug2-0.9/docs/hotplug2.rules.doc hotplug2/docs/hotplug2.rules.doc
84 --- hotplug2-0.9/docs/hotplug2.rules.doc        2006-09-26 10:19:46.000000000 +0200
85 +++ hotplug2/docs/hotplug2.rules.doc    2007-06-28 14:50:59.872955464 +0200
86 @@ -11,12 +11,12 @@
87         [... [...]]
88  }
89  
90 -Comments are allowed, they are prefixed with '#', treating the whole rest of the
91 -line as comment. Please note that comments in place of action parameters are not
92 -supported.
93 +Comments are allowed, they are prefixed with '#', treating the whole rest of
94 +the line as comment. Please note that comments in place of action parameters
95 +are not supported.
96  
97 -The <key> is one of the environmental variables that have been obtained by the
98 -uevent netlink. 
99 +The <key> is one of the environmental variables that have been obtained by
100 +the uevent netlink. 
101  
102   COMMON KEYS
103   -----------
104 @@ -66,9 +66,9 @@
105    -------
106  
107   * run <...>
108 -       Execute an application using system();, takes one parameter. Note that
109 -       the application has set all environmental variables read by uevent
110 -       netlink.
111 +       Execute an application using system();, takes one parameter. Note
112 +       that the application has set all environmental variables read by 
113 +       uevent netlink.
114  
115   * break
116         Break the processing of the current block of actions.
117 @@ -86,23 +86,22 @@
118  
119   * exec <application [parameter [parameter [...]]]> ;
120         Execute an application. Takes variable number of parameters, but the
121 -       last parameter must be terminated with semicolon. Again, all variables
122 -       are set as environmental.
123 +       last parameter must be terminated with semicolon. Again, all
124 +       variables are set as environmental.
125         
126 -       If you need to escape the ';', use '\\;'. Only applies for actions with
127 -       variable number of parameters.
128 +       If you need to escape the ';', use '\\;'. Only applies for actions
129 +       with variable number of parameters.
130         
131   * makedev <path> <mode>
132 -       Create a device with given mode. The mode is not in octal unless it
133 -       starts with '0', eg. "0644" != "644".
134 +       Create a device with given mode. Mode is interpreted as octal.
135         
136         Major, minor and devpath must be set for makedev to be able to work.
137         Tests for these variables are also performed internally in makedev
138         function.
139  
140   * symlink <target> <linkname>
141 -       Create a symbolic link (symlink, also known as soft link) pointing at
142 -       target with name linkname.
143 +       Create a symbolic link (symlink, also known as soft link) pointing
144 +       at target with name linkname.
145         
146   * chown <path> <owner name>
147         Change owner of path to owner name.
148 @@ -111,12 +110,32 @@
149         Change group of path to group name.
150         
151   * chmod <path> <mode>
152 -       Change mode of path to given mode. Like with makedev, heading '0' is
153 -       necessary for the mode to be interpreted as octal.
154 +       Change mode of path to given mode. Mode is interpreted as octal.
155  
156   * setenv <key> <value>
157         Sets environmental variable key to the given value. If an env var
158         of the given name already exists, it gets overwritten.
159 +
160 + * printdebug
161 +       Prints all variables read from kernel.
162 +
163 + FLAGS
164 + -----
165 +
166 +Flags are, syntactically, just like actions; their semantical value is different however.
167 +Instead of doing something, they instead change the general behavior of the processing
168 +of the given rule.
169 +
170 +Note that for flags to work, you also have to invoke it with --override.
171 +
172 +Currently, only one flag is implemented:
173 +
174 + * nothrottle
175 +       Forcibly overrides hotplug2 throttling mechanism. If _all_ rules that match
176 +       the given kernel event have 'nothrottle' set, hotplug2 will not wait for
177 +       children count to get under max-children limit. That allows to throttle
178 +       eg. helper application execution or modprobes, but yet keep node devices
179 +       fast.
180         
181   ESCAPING
182   --------
183 @@ -136,8 +155,9 @@
184   SAMPLE CONFIG
185   -------------
186  
187 -Below is a sample hotplug2.rules file. It loads modules to all available devices
188 -quietly and creates device nodes for block devices.
189 +Below is a sample hotplug2.rules file. It loads modules to all available
190 +devices quietly and creates device nodes for block devices. Note that this
191 +sample is not very viable for real life usage.
192  ---------------------------------------------------------------------------------
193  MODALIAS is set {
194         exec modprobe -q %MODALIAS% ;
195 @@ -146,3 +166,33 @@
196  SUBSYSTEM == block, DEVPATH is set, MAJOR is set, MINOR is set {
197         makedev /dev/%DEVICENAME% 0644
198  }
199 +
200 +
201 +Please find also the more complex set of rules, dedicated to handling most
202 +common needs.
203 +---------------------------------------------------------------------------------
204 +#For debugging
205 +#ACTION is set {
206 +#      printdebug
207 +#}
208 +
209 +# Load modules (what old hotplug did)
210 +MODALIAS is set {
211 +       exec modprobe -q %MODALIAS% ;
212 +}
213 +
214 +# Create device nodes
215 +DEVPATH is set, MAJOR is set, MINOR is set {
216 +       makedev /dev/%DEVICENAME% 0644
217 +}
218 +
219 +# Mount a USB flashdisk
220 +ACTION == add, PHYSDEVPATH ~~ "/usb[0-9]*/", DEVICENAME ~~ "^sd[a-z][0-9]+$", DEVPATH is set, MAJOR is set, MINOR is set {
221 +       makedev /dev/%DEVICENAME% 0644
222 +       exec mount /dev/%DEVICENAME% /mnt/%DEVICENAME%
223 +}
224 +
225 +# Unmount a USB flashdisk
226 +ACTION == remove, PHYSDEVPATH ~~ "/usb[0-9]*/", DEVICENAME ~~ "^sd[a-z][0-9]+$", MAJOR is set, MINOR is set {
227 +       exec umount /mnt/%DEVICENAME%
228 +}
229 diff -urN -x.svn hotplug2-0.9/docs/Makefile hotplug2/docs/Makefile
230 --- hotplug2-0.9/docs/Makefile  2006-09-26 00:27:02.000000000 +0200
231 +++ hotplug2/docs/Makefile      2007-06-28 14:50:59.875955008 +0200
232 @@ -2,12 +2,13 @@
233  
234  BINS=
235  SUBDIRS=
236 -
237 +DESTDIR=
238 +MANDIR=/usr/share/man
239  
240  all:
241  
242  install:
243 -       $(INSTALL) $(wildcard *.8) /usr/share/man/man8/
244 +       $(INSTALL) $(wildcard *.8) $(DESTDIR)$(MANDIR)/man8/
245  
246  
247  include ../common.mak
248 diff -urN -x.svn hotplug2-0.9/examples/Makefile hotplug2/examples/Makefile
249 --- hotplug2-0.9/examples/Makefile      2006-09-26 01:03:08.000000000 +0200
250 +++ hotplug2/examples/Makefile  2007-06-28 14:50:59.991937376 +0200
251 @@ -2,19 +2,23 @@
252  
253  BINS=
254  SUBDIRS=
255 +DESTDIR=
256 +KERNELVER=`uname -r`
257  
258  
259  all:
260  
261  install:
262 -       case "`uname -r`" in \
263 -               2.6.*) \
264 -               $(INSTALL) hotplug2.rules-2.6kernel /etc/hotplug2.rules \
265 -               ;; \
266 -               *) \
267 -               $(INSTALL) hotplug2.rules-2.4kernel /etc/hotplug2.rules \
268 -               ;; \
269 -       esac
270 +       if ! [ -e "/etc/hotplug2.rules" ]; then \
271 +               case "$(KERNELVER)" in \
272 +                       2.6.*) \
273 +                       $(INSTALL) hotplug2.rules-2.6kernel $(DESTDIR)/etc/hotplug2.rules \
274 +                       ;; \
275 +                       *) \
276 +                       $(INSTALL) hotplug2.rules-2.4kernel $(DESTDIR)/etc/hotplug2.rules \
277 +                       ;; \
278 +               esac; \
279 +       fi;
280  
281  
282  include ../common.mak
283 diff -urN -x.svn hotplug2-0.9/hotplug2.c hotplug2/hotplug2.c
284 --- hotplug2-0.9/hotplug2.c     2006-10-08 15:18:23.000000000 +0200
285 +++ hotplug2/hotplug2.c 2007-06-30 12:59:20.459674000 +0200
286 @@ -36,6 +36,7 @@
287  pid_t coldplug_p;
288  int coldplug = 1;
289  int persistent = 0;
290 +int override = 0;
291  int max_child_c = 20;
292  int dumb = 0;
293  int terminate = 0;
294 @@ -324,6 +325,41 @@
295         
296         free_hotplug2_event(event);
297  }
298 +
299 +int flags_eval(struct hotplug2_event_t *event, struct rules_t *rules) {
300 +       int flags = FLAG_ALL;
301 +       int match = 0;
302 +       int i, j;
303 +
304 +       for (i = 0; i < rules->rules_c; i++) {
305 +               match = 1;
306 +
307 +               for (j = 0; j < rules->rules[i].conditions_c; j++) {
308 +                       if (rule_condition_eval(event, &rules->rules[i].conditions[j]) != EVAL_MATCH) {
309 +                               match = 0;
310 +                               break;
311 +                       }
312 +               }
313 +
314 +               /*
315 +                * Logical AND between flags we've got already and
316 +                * those we're adding.
317 +                */
318 +               if (match) {
319 +                       rule_flags(event, &rules->rules[i]);
320 +                       flags &= rules->rules[i].flags;
321 +               }
322 +       }
323 +
324 +       /*
325 +        * A little trick; if no rule matched, we return FLAG_ALL
326 +        * and have it skipped completely.
327 +        */
328 +
329 +       return flags;
330 +}
331 +#else
332 +#define perform_action(event, rules)
333  #endif
334  
335  void perform_dumb_action(struct hotplug2_event_t *event, char *modalias) {
336 @@ -390,7 +426,9 @@
337         int size;
338         int rv = 0;
339         int i;
340 +       int flags;
341         char *coldplug_command = NULL;
342 +       char *rules_file = HOTPLUG2_RULE_PATH;
343         sigset_t block_mask;
344         
345         struct rules_t *rules = NULL;
346 @@ -402,6 +440,7 @@
347                 {"persistent", &persistent},
348                 {"coldplug", &coldplug},
349                 {"udevtrigger", &coldplug},     /* compatibility */
350 +               {"override", &override},
351  #ifdef HAVE_RULES
352                 {"dumb", &dumb},
353  #endif
354 @@ -435,15 +474,31 @@
355                                                 break;
356                                         
357                                         modprobe_command = *argv;
358 +                               } else if (!strcmp(*argv, "--set-rules-file")) {
359 +                                       argv++;
360 +                                       argc--;
361 +                                       if (argc <= 0)
362 +                                               break;
363 +                                       
364 +                                       rules_file = *argv;
365                                 }
366                         }
367                 }
368         }
369         
370 -#ifdef HAVE_RULES
371 +#ifndef HAVE_RULES
372 +       /*
373 +        * We don't use rules, so we use dumb mode only.
374 +        */
375 +       dumb = 1;
376 +#else
377 +       /*
378 +        * We're not in dumb mode, parse the rules. If we fail,
379 +        * faillback to dumb mode.
380 +        */
381         if (!dumb) {
382                 filemap = MAP_FAILED;
383 -               rule_fd = open(HOTPLUG2_RULE_PATH, O_RDONLY | O_NOATIME);
384 +               rule_fd = open(rules_file, O_RDONLY | O_NOATIME);
385                 if (rule_fd == -1) {
386                         dumb = 1;
387                         ERROR("rules parse","Unable to open rules file: %s.", strerror(errno));
388 @@ -477,10 +532,12 @@
389                 
390                 if (dumb == 1)
391                         ERROR("rules parse","Parsing rules failed, switching to dumb mode.");
392 -       } else if (!modprobe_command)
393 -#else
394 -       if (dumb && !modprobe_command)
395 +       } else
396  #endif
397 +       /*
398 +        * No modprobe command specified, let's autodetect it.
399 +        */
400 +       if (!modprobe_command)
401         {
402                 if (get_modprobe_command()) {
403                         ERROR("modprobe_command","Unable to autodetect modprobe command.");
404 @@ -536,7 +593,7 @@
405                 
406                 modalias = get_hotplug2_value_by_key(tmpevent, "MODALIAS");
407                 seqnum = get_hotplug2_value_by_key(tmpevent, "SEQNUM");
408 -               
409 +
410                 if (seqnum == NULL) {
411                         free_hotplug2_event(tmpevent);
412                         ERROR("reading events", "Malformed event read (missing SEQNUM).");
413 @@ -547,13 +604,35 @@
414                 if (cur_seqnum > highest_seqnum)
415                         highest_seqnum = cur_seqnum;
416                 
417 -               if (tmpevent->action == ACTION_ADD && (!dumb || modalias != NULL)) {
418 +               if ((dumb && tmpevent->action == ACTION_ADD && modalias != NULL) || (!dumb)) {
419 +                       /*
420 +                        * Pre-evaluation
421 +                        */
422 +                       if (!dumb && override) {
423 +                               flags = flags_eval(tmpevent, rules);
424 +
425 +                               DBG("flags", "flag returned: %8x", flags);
426 +
427 +                               if (flags == FLAG_ALL)
428 +                                       continue;
429 +                       } else {
430 +                               flags = FLAG_UNSET;
431 +                       }
432 +
433                         /* 
434                          * We have more children than we want. Wait until SIGCHLD handler reduces
435                          * their numbers.
436 +                        *
437 +                        * Unless, of course, we've specified otherwise and no rules that match
438 +                        * need throttling.
439                          */
440 -                       while (child_c >= max_child_c) {
441 -                               usleep(HOTPLUG2_THROTTLE_INTERVAL);
442 +                       if (!flags & FLAG_NOTHROTTLE) {
443 +                               /*
444 +                                * Okay, throttle away!
445 +                                */
446 +                               while (child_c >= max_child_c) {
447 +                                       usleep(HOTPLUG2_THROTTLE_INTERVAL);
448 +                               }
449                         }
450                         
451                         sigemptyset(&block_mask);
452 @@ -562,17 +641,15 @@
453                         p = fork();
454                         switch (p) {
455                                 case -1:
456 -                                       ERROR("event","fork failed: %s.", strerror(errno));
457 +                                       ERROR("event", "fork failed: %s.", strerror(errno));
458                                         break;
459                                 case 0:
460                                         sigprocmask(SIG_UNBLOCK, &block_mask, 0);
461                                         signal(SIGCHLD, SIG_DFL);
462                                         signal(SIGUSR1, SIG_DFL);
463 -#ifdef HAVE_RULES
464                                         if (!dumb)
465                                                 perform_action(dup_hotplug2_event(tmpevent), rules);
466                                         else
467 -#endif
468                                                 perform_dumb_action(dup_hotplug2_event(tmpevent), modalias);
469                                         exit(0);
470                                         break;
471 @@ -593,12 +670,10 @@
472         signal(SIGINT, SIG_DFL);
473         signal(SIGCHLD, SIG_DFL);
474         
475 -#ifdef HAVE_RULES
476         if (!dumb) {
477                 rules_free(rules);
478                 free(rules);
479         }
480 -#endif
481  
482         cleanup();
483         
484 diff -urN -x.svn hotplug2-0.9/linux24_compat/hotplug2-modwrap.c hotplug2/linux24_compat/hotplug2-modwrap.c
485 --- hotplug2-0.9/linux24_compat/hotplug2-modwrap.c      2006-09-25 22:23:07.000000000 +0200
486 +++ hotplug2/linux24_compat/hotplug2-modwrap.c  2007-06-28 14:50:59.926947256 +0200
487 @@ -122,6 +122,12 @@
488                 free(module);
489                 free(line);
490         }
491 +
492 +       if (strcmp(argv[argc - 1], match_alias) == 0) {
493 +               if (execute(argv)) {
494 +                       ERROR("execute", "Unable to execute: `%s'.", argv[0]);
495 +               }
496 +       }       
497         
498         free(filename);
499         free(match_alias);
500 diff -urN -x.svn hotplug2-0.9/linux24_compat/Makefile hotplug2/linux24_compat/Makefile
501 --- hotplug2-0.9/linux24_compat/Makefile        2006-09-26 00:26:46.000000000 +0200
502 +++ hotplug2/linux24_compat/Makefile    2007-06-28 14:50:59.926947256 +0200
503 @@ -2,13 +2,14 @@
504  
505  BINS=generate_alias hotplug2-coldplug-2.4 hotplug2-modwrap
506  SUBDIRS=
507 +DESTDIR=
508  
509  
510  all: $(BINS)
511  
512  install:
513 -       $(INSTALL_BIN) hotplug2-coldplug-2.4 hotplug2-modwrap /sbin/
514 -       $(INSTALL_BIN) generate_alias /usr/sbin/
515 +       $(INSTALL_BIN) hotplug2-coldplug-2.4 hotplug2-modwrap $(DESTDIR)/sbin/
516 +       $(INSTALL_BIN) generate_alias $(DESTDIR)/usr/sbin/
517  
518  
519  hotplug2-coldplug-2.4: hotplug2-coldplug-2.4.o ../parser_utils.o ../filemap_utils.o ../mem_utils.o
520 diff -urN -x.svn hotplug2-0.9/Makefile hotplug2/Makefile
521 --- hotplug2-0.9/Makefile       2006-09-26 01:03:08.000000000 +0200
522 +++ hotplug2/Makefile   2007-06-28 14:51:00.014933880 +0200
523 @@ -2,12 +2,13 @@
524  
525  BINS=hotplug2 hotplug2-dnode
526  SUBDIRS=linux24_compat docs examples
527 +DESTDIR=
528  
529  
530  all: $(BINS)
531  
532  install:
533 -       $(INSTALL_BIN) $(BINS) /sbin/
534 +       $(INSTALL_BIN) $(BINS) $(DESTDIR)/sbin/
535  
536  
537  hotplug2: hotplug2.o childlist.o mem_utils.o rules.o
538 diff -urN -x.svn hotplug2-0.9/rules.c hotplug2/rules.c
539 --- hotplug2-0.9/rules.c        2006-09-29 22:19:31.000000000 +0200
540 +++ hotplug2/rules.c    2007-06-30 12:44:52.501430000 +0200
541 @@ -59,6 +59,24 @@
542         free(path);
543  }
544  
545 +static void rmdir_p(char *path) {
546 +       char *ptr;
547 +       
548 +       path = strdup(path);
549 +       ptr = path;
550 +       while (ptr != NULL) {
551 +               ptr = strrchr(path, '/');
552 +               if (ptr == NULL)
553 +                       break;
554 +               
555 +               *ptr = '\0';
556 +               
557 +               if (rmdir(path))
558 +                       break;
559 +       }
560 +       free(path);
561 +}
562 +
563  static char *replace_str(char *hay, char *needle, char *replacement) {
564          char *ptr, *start, *bptr, *buf;
565          int occurences, j;
566 @@ -128,7 +146,7 @@
567          return buf;
568  }
569  
570 -inline int isescaped(char *hay, char *ptr) {
571 +static inline int isescaped(char *hay, char *ptr) {
572         if (ptr <= hay)
573                 return 0;
574         
575 @@ -250,11 +268,30 @@
576         return rv;
577  }
578  
579 -static int chown_chgrp(int action, char *file, char *param) {
580 +static int chmod_file(struct hotplug2_event_t *event, char *file, char *value) {
581 +       int rv;
582 +
583 +       file = replace_key_by_value(strdup(file), event);
584 +       value = replace_key_by_value(strdup(value), event);
585 +
586 +       rv = chmod(file, strtoul(value, 0, 8));
587 +
588 +       free(file);
589 +       free(value);
590 +
591 +       return rv;
592 +}
593 +
594 +static int chown_chgrp(struct hotplug2_event_t *event, int action, char *file, char *param) {
595         struct group *grp;
596         struct passwd *pwd;
597         int rv;
598 -       
599 +
600 +       file = replace_key_by_value(strdup(file), event);
601 +       param = replace_key_by_value(strdup(param), event);
602 +
603 +       rv = -1;
604 +
605         switch (action) {
606                 case ACT_CHOWN:
607                         pwd = getpwnam(param);
608 @@ -265,11 +302,23 @@
609                         rv = chown(file, -1, grp->gr_gid);
610                         break;
611         }
612 +
613 +       free(file);
614 +       free(param);
615         
616 -       return -1;
617 +       return rv;
618 +}
619 +
620 +static int print_debug(struct hotplug2_event_t *event) {
621 +       int i;
622 +
623 +       for (i = 0; i < event->env_vars_c; i++)
624 +               printf("%s=%s\n", event->env_vars[i].key, event->env_vars[i].value);
625 +
626 +       return 0;
627  }
628  
629 -static int rule_condition_eval(struct hotplug2_event_t *event, struct condition_t *condition) {
630 +int rule_condition_eval(struct hotplug2_event_t *event, struct condition_t *condition) {
631         int rv;
632         char *event_value = NULL;
633         regex_t preg;
634 @@ -347,11 +396,11 @@
635                                 last_rv = make_dev_from_event(event, rule->actions[i].parameter[0], strtoul(rule->actions[i].parameter[1], NULL, 0));
636                                 break;
637                         case ACT_CHMOD:
638 -                               last_rv = chmod(rule->actions[i].parameter[0], strtoul(rule->actions[i].parameter[1], NULL, 0));
639 +                               last_rv = chmod_file(event, rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
640                                 break;
641                         case ACT_CHOWN:
642                         case ACT_CHGRP:
643 -                               last_rv = chown_chgrp(rule->actions[i].type, rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
644 +                               last_rv = chown_chgrp(event, rule->actions[i].type, rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
645                                 break;
646                         case ACT_SYMLINK:
647                                 last_rv = make_symlink(event, rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
648 @@ -365,6 +414,27 @@
649                         case ACT_SETENV:
650                                 last_rv = setenv(rule->actions[i].parameter[0], rule->actions[i].parameter[1], 1);
651                                 break;
652 +                       case ACT_REMOVE:
653 +                               last_rv = unlink(rule->actions[i].parameter[0]);
654 +                               rmdir_p(rule->actions[i].parameter[0]);
655 +                               break;
656 +                       case ACT_DEBUG:
657 +                               last_rv = print_debug(event);
658 +                               break;
659 +               }
660 +       }
661 +       
662 +       return 0;
663 +}
664 +
665 +int rule_flags(struct hotplug2_event_t *event, struct rule_t *rule) {
666 +       int i;
667 +
668 +       for (i = 0; i < rule->actions_c; i++) {
669 +               switch (rule->actions[i].type) {
670 +                       case ACT_FLAG_NOTHROTTLE:
671 +                               rule->flags |= FLAG_NOTHROTTLE;
672 +                               break;
673                 }
674         }
675         
676 @@ -518,6 +588,9 @@
677                 {"chmod", 2, ACT_CHMOD},
678                 {"chgrp", 2, ACT_CHGRP},
679                 {"setenv", 2, ACT_SETENV},
680 +               {"remove", 1, ACT_REMOVE},
681 +               {"nothrottle", 0, ACT_FLAG_NOTHROTTLE},
682 +               {"printdebug", 0, ACT_DEBUG},
683                 /*symlink*/
684                 {"symlink", 2, ACT_SYMLINK},
685                 {"softlink", 2, ACT_SYMLINK},
686 diff -urN -x.svn hotplug2-0.9/rules.h hotplug2/rules.h
687 --- hotplug2-0.9/rules.h        2006-09-25 13:42:22.000000000 +0200
688 +++ hotplug2/rules.h    2007-06-30 12:44:52.501430000 +0200
689 @@ -24,9 +24,12 @@
690  #define ACT_CHGRP                      6       /* chgrp <...> */
691  #define ACT_CHOWN                      7       /* chown <...> */
692  #define ACT_SYMLINK                    8       /* symlink <...> */
693 -#define ACT_NEXT_EVENT         9       /* next */
694 +#define ACT_NEXT_EVENT                 9       /* next */
695  #define ACT_NEXT_IF_FAILED             10      /* next_if_failed */
696  #define ACT_SETENV                     11      /* setenv <...> */
697 +#define ACT_REMOVE                     12      /* remove <...> */
698 +#define ACT_DEBUG                      13      /* debug */
699 +#define ACT_FLAG_NOTHROTTLE            14      /* sets 'nothrottle' flag */
700  
701  #define EVAL_MATCH                     1
702  #define EVAL_NOT_MATCH                 0
703 @@ -42,6 +45,11 @@
704  #define STATUS_INITIATOR               3       /* ',' for next cond, '{' for block*/
705  #define STATUS_ACTION                  4       /* viz ACT_* and '}' for end of block */
706  
707 +#define FLAG_UNSET                     0
708 +#define FLAG_ALL                       0xffffffff
709 +#define FLAG_NOTHROTTLE                        1       /* We want this rule to ignore max_children limit */
710 +
711 +
712  struct key_rec_t {
713         char *key;
714         int param;
715 @@ -65,6 +73,8 @@
716         
717         struct action_t *actions;
718         int actions_c;
719 +
720 +       int flags;
721  };
722  
723  struct rules_t {
724 @@ -72,7 +82,9 @@
725         int rules_c;
726  };
727  
728 +int rule_condition_eval(struct hotplug2_event_t *, struct condition_t *);
729  int rule_execute(struct hotplug2_event_t *, struct rule_t *);
730 +int rule_flags(struct hotplug2_event_t *, struct rule_t *);
731  void rules_free(struct rules_t *);
732  struct rules_t *rules_from_config(char *);
733  
734 diff -urN -x.svn hotplug2-0.9/TODO hotplug2/TODO
735 --- hotplug2-0.9/TODO   1970-01-01 01:00:00.000000000 +0100
736 +++ hotplug2/TODO       2007-06-28 14:51:00.012934184 +0200
737 @@ -0,0 +1 @@
738 + - live rules update (via inotify)