aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--Makefile44
-rw-r--r--dircond.c1062
-rw-r--r--dlist.c35
4 files changed, 1146 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ef072ec
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
1dircond
2*~
3*.o
4*.tar.*
5.emacs*
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5651d93
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,44 @@
1CFLAGS=-ggdb -Wall
2PREFIX=/usr/local
3BINDIR=$(PREFIX)/bin
4MANDIR=$(PREFIX)/share/man
5PACKAGE=upev
6VERSION=1.0
7DISTFILES=Makefile dircond.c dlist.c
8
9dircond: dircond.c dlist.c
10 cc -odircond $(CFLAGS) dircond.c
11
12install-bin: dircond
13 mkdir -p $(DESTDIR)$(BINDIR)
14 cp dircond $(DESTDIR)$(BINDIR)
15
16install-man:;
17#install-man: dircond.1
18# mkdir -p $(DESTDIR)$(MANDIR)/man1
19# cp dircond.1 $(DESTDIR)$(MANDIR)/man1
20
21install: install-bin install-man
22
23distdir = $(PACKAGE)-$(VERSION)
24
25distdir:
26 rm -rf $(distdir)
27 mkdir $(distdir)
28 cp $(DISTFILES) $(distdir)
29
30dist: distdir
31 tar cfz $(distdir).tar.gz $(distdir)
32 rm -rf $(distdir)
33
34distcheck: distdir
35 mkdir $(distdir)/_inst; \
36 cd $(distdir) || exit 2;\
37 make || exit 2; \
38 make DESTDIR=`pwd`/_inst install || exit 2
39 (cd $(distdir)/_inst; find . -type f)|sort|cut -c2- | \
40 cmp - instlist
41 make dist
42
43clean:
44 rm -f dircond
diff --git a/dircond.c b/dircond.c
new file mode 100644
index 0000000..682e1c3
--- /dev/null
+++ b/dircond.c
@@ -0,0 +1,1062 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <stdarg.h>
4#include <fcntl.h>
5#include <syslog.h>
6#include <unistd.h>
7#include <getopt.h>
8#include <string.h>
9#include <errno.h>
10#include <pwd.h>
11#include <signal.h>
12#include <time.h>
13#include <sys/inotify.h>
14#include <sys/wait.h>
15#include <sys/stat.h>
16
17/* Configuration settings */
18const char *program_name; /* This program name */
19int foreground; /* Remain in the foreground */
20int facility = -1; /* Use this syslog facility for logging.
21 -1 means log to stderr */
22int debug_level; /* Debug verbosity level */
23unsigned handler_timeout = 5; /* Timeout for handler program (seconds) */
24int autowatch; /* Automatically add directories created
25 under watchpoints to the watcher. If set
26 to -1, nesting level is not limited. If
27 set to a positive value, this value limits
28 the nesting depth. */
29
30/* Event codes */
31enum {
32 evt_create, /* file has been created */
33 evt_delete, /* file has been deleted */
34 evt_close, /* file has been modified and closed */
35 evt_max /* number of handled events */
36};
37
38/* Handler flags. */
39#define HF_NOWAIT 0x01 /* Don't wait for termination */
40#define HF_STDOUT 0x02 /* Capture stdout */
41#define HF_STDERR 0x04 /* Capture stderr */
42
43/* Handler structure */
44struct handler {
45 int flags; /* Handler flags */
46 const char *prog; /* Handler program (no arguments allowed) */
47};
48
49/* Array of handlers for each event */
50struct handler handler[evt_max];
51
52/* Process list */
53
54/* Redirector codes */
55#define REDIR_OUT 0
56#define REDIR_ERR 1
57
58/* A running process is described by this structure */
59struct process {
60 struct process *next, *prev;
61 int master; /* Master process or redirector */
62 pid_t pid; /* PID */
63 time_t start; /* Time when the process started */
64 pid_t redir[2]; /* If master==1, holds PIDs of redirector
65 processes (0 if no redirector) */
66};
67
68/* List of running processes */
69struct process *proc_list;
70/* List of available process slots */
71struct process *proc_avail;
72/* Declare functions for handling process lists */
73#define LIST process
74#define LIST_PUSH proc_push
75#define LIST_POP proc_pop
76#define LIST_UNLINK proc_unlink
77#include "dlist.c"
78
79/* Diagnostic functions */
80const char *
81severity(int prio)
82{
83 switch (prio) {
84 case LOG_EMERG:
85 return "EMERG";
86 case LOG_ALERT:
87 return "ALERT";
88 case LOG_CRIT:
89 return "CRIT";
90 case LOG_ERR:
91 return "ERROR";
92 case LOG_WARNING:
93 return "WARNING";
94 case LOG_NOTICE:
95 return "NOTICE";
96 case LOG_INFO:
97 return "INFO";
98 case LOG_DEBUG:
99 return "DEBUG";
100 }
101 return NULL;
102}
103
104void
105vdiag(int prio, const char *fmt, va_list ap)
106{
107 const char *s;
108
109 if (facility <= 0) {
110 fprintf(stderr, "%s: ", program_name);
111 s = severity(prio);
112 if (s)
113 fprintf(stderr, "[%s] ", s);
114 vfprintf(stderr, fmt, ap);
115 fputc('\n', stderr);
116 } else {
117 vsyslog(prio, fmt, ap);
118 }
119}
120
121void
122diag(int prio, const char *fmt, ...)
123{
124 va_list ap;
125
126 va_start(ap, fmt);
127 vdiag(prio, fmt, ap);
128 va_end(ap);
129}
130
131static void
132debugprt(const char *fmt, ...)
133{
134 va_list ap;
135
136 va_start(ap, fmt);
137 vdiag(LOG_DEBUG, fmt, ap);
138 va_end(ap);
139}
140
141#define debug(l, c) do { if (debug_level>=(l)) debugprt c; } while(0)
142
143/* Command line processing and auxiliary functions */
144
145static void
146set_program_name(const char *arg)
147{
148 char *p = strrchr(arg, '/');
149 if (p)
150 program_name = p + 1;
151 else
152 program_name = arg;
153}
154
155static int
156read_facility(const char *arg)
157{
158 static struct transtab { int f; char *s; } ftab[] = {
159 { LOG_AUTH, "auth" },
160 { LOG_AUTHPRIV, "authpriv" },
161 { LOG_CRON, "cron" },
162 { LOG_DAEMON, "daemon" },
163 { LOG_FTP, "ftp" },
164 { LOG_LOCAL0, "local0" },
165 { LOG_LOCAL1, "local1" },
166 { LOG_LOCAL2, "local2" },
167 { LOG_LOCAL3, "local3" },
168 { LOG_LOCAL4, "local4" },
169 { LOG_LOCAL5, "local5" },
170 { LOG_LOCAL6, "local6" },
171 { LOG_LOCAL7, "local7" },
172 { LOG_LPR, "lpr" },
173 { LOG_MAIL, "mail" },
174 { LOG_NEWS, "news" },
175 { LOG_USER, "user" },
176 { LOG_UUCP, "uucp" },
177 { 0, NULL }
178 };
179 struct transtab *p;
180 char *s;
181 unsigned long n;
182
183 for (p = ftab; p->s; p++) {
184 if (strcmp(p->s, arg) == 0)
185 return p->f;
186 }
187 n = strtoul(arg, &s, 10);
188 if (*s) {
189 diag(LOG_CRIT, "unknown facility: %s", arg);
190 exit(1);
191 }
192 if (n > 256) {
193 diag(LOG_CRIT, "facility out of range: %s", arg);
194 exit(1);
195 }
196 return n;
197}
198
199void