3 #if defined(RPM_VENDOR_MANDRIVA)
18 #define _FILES_AWAITING_FILETRIGGERS "/var/lib/rpm/files-awaiting-filetriggers"
21 static const char * files_awaiting_filetriggers = _FILES_AWAITING_FILETRIGGERS;
23 #define FILTER_EXTENSION ".filter"
26 static const char * _filetriggers_dir;
29 static const char * filetriggers_dir(
void)
33 if (_filetriggers_dir == NULL)
34 _filetriggers_dir =
rpmExpand(
"%{?_filetriggers_dir}", NULL);
35 return (_filetriggers_dir != NULL && _filetriggers_dir[0] !=
'\0')
36 ? _filetriggers_dir : NULL;
40 static char * get_filter_name(
const char * fn)
43 char * p = strrchr(fn,
'/');
46 #if defined(HAVE_STRNDUP) && !defined(__LCLINT__)
47 p = strndup(p+1, strlen(p+1) - strlen(FILTER_EXTENSION));
50 size_t p_len = strlen(p_src+1) - strlen(FILTER_EXTENSION);
52 strncpy(p, p_src+1, p_len);
58 int mayAddToFilesAwaitingFiletriggers(
const char * rootDir,
rpmfi fi,
66 if (filetriggers_dir() == NULL)
69 fn =
rpmGetPath(rootDir ? rootDir :
"/", files_awaiting_filetriggers, NULL);
80 xx = fputc(install_or_erase ?
'+' :
'-', fp);
92 struct filetrigger_raw {
105 static int getFiletriggers_raw(
const char * rootDir,
int * nftp,
106 struct filetrigger_raw ** list_raw)
110 const char * dn = filetriggers_dir();
111 const char * globstr = NULL;
120 globstr =
rpmGetPath(rootDir ? rootDir :
"/", dn,
"/*" FILTER_EXTENSION, NULL);
121 xx =
rpmGlob(globstr, &ac, &av);
125 *list_raw = (
struct filetrigger_raw *)
xcalloc(ac,
sizeof(**list_raw));
127 for (i = 0; i < ac; i++) {
128 const char * fn = av[
i];
129 int fdno = open(fn, O_RDONLY);
137 if (fstat(fdno, &sb) == 0 && sb.st_size > 0) {
138 size_t bn = sb.st_size;
139 char *
b = (
char *)
xmalloc(bn + 1);
141 if (read(fdno, b, bn) != (ssize_t)bn) {
148 if ((be = strchr(b,
'\n')) != NULL) {
150 while (be > b &&
xisspace((
int)be[-1]))
153 (*list_raw)[
i].regexp =
b;
154 (*list_raw)[
i].name = get_filter_name(fn);
164 globstr =
_free(globstr);
168 static char * computeMatchesAnyFilter(
size_t nb,
169 struct filetrigger_raw * list_raw)
174 size_t regexp_str_size = 0;
177 for (i = 0; i < (int)nb; i++)
178 regexp_str_size += strlen(list_raw[i].regexp) + 1;
180 matches_any = (
char *)
xmalloc(regexp_str_size);
181 p =
stpcpy(matches_any, list_raw[0].regexp);
183 for (i = 1; i < (int)nb; i++) {
185 p =
stpcpy(p, list_raw[i].regexp);
192 static void compileFiletriggersRegexp(
char * raw,
miRE mire)
195 static int options = REG_NOSUB | REG_EXTENDED | REG_NEWLINE;
207 static void getFiletriggers(
const char * rootDir,
miRE matches_any,
208 int * nftp,
struct filetrigger ** list)
212 struct filetrigger_raw * list_raw = NULL;
216 xx = getFiletriggers_raw(rootDir, nftp, &list_raw);
217 if (*nftp == 0)
return;
219 compileFiletriggersRegexp(computeMatchesAnyFilter(*nftp, list_raw), matches_any);
221 *list = (
struct filetrigger *)
xcalloc(*nftp,
sizeof(**list));
222 for (i = 0; i < *nftp; i++) {
223 (*list)[
i].name = list_raw[
i].name;
225 compileFiletriggersRegexp(list_raw[i].regexp, (*list)[i].mire);
227 list_raw =
_free(list_raw);
230 static void freeFiletriggers(
miRE matches_any,
231 int nft,
struct filetrigger * list)
236 matches_any =
mireFree(matches_any);
237 for (i = 0; i < nft; i++) {
244 static int is_regexp_matching(
miRE mire,
const char * s)
250 static int popen_with_root(
const char * rootDir,
const char *
cmd,
258 if (pipe(pipes) != 0)
263 const char * argv[2];
265 xx = close(pipes[1]);
266 xx = dup2(pipes[0], STDIN_FILENO);
267 xx = close(pipes[0]);
269 if (rootDir != NULL && strcmp(rootDir,
"/") && *rootDir ==
'/') {
271 if (
Chroot(rootDir) != 0) {
280 xx = execv(argv[0], (
char *
const *) argv);
284 xx = close(pipes[0]);
289 static void mayStartFiletrigger(
const char * rootDir,
290 struct filetrigger * trigger)
294 if (!trigger->command_pipe) {
295 const char * dn = filetriggers_dir();
301 cmd =
rpmGetPath(dn,
"/", trigger->name,
".script", NULL);
304 trigger->command_pipe = popen_with_root(rootDir, cmd,
305 &trigger->command_pid);
314 struct filetrigger *list = NULL;
315 const char * fn = NULL;
322 fn =
rpmGenPath(rootDir, files_awaiting_filetriggers, NULL);
324 if (!filetriggers_dir())
327 getFiletriggers(rootDir, matches_any, &nft, &list);
331 fd =
Fopen(fn,
"r.fpio");
338 void (*oldhandler)(int) = signal(SIGPIPE, SIG_IGN);
343 D_(
"[filetriggers] testing files from list: %s\n"), fn);
345 while (fgets(tmp, (
int)
sizeof(tmp), fp)) {
346 size_t tmplen = strlen(tmp);
348 if (tmplen > 0 && tmp[tmplen-1] ==
'\n')
349 tmp[--tmplen] =
'\0';
351 if (!is_regexp_matching(matches_any, tmp))
355 D_(
"[filetriggers] matches-any regexp found %s\n"),
358 for (i = 0; i < nft; i++) {
360 if (!is_regexp_matching(list[i].mire, tmp))
364 D_(
"[filetriggers] file name '%s' matches pattern '%s'\n"),
365 tmp, list[i].mire->pattern);
367 mayStartFiletrigger(rootDir, &list[i]);
368 nw = write(list[i].command_pipe, tmp, tmplen);
369 nw = write(list[i].command_pipe,
"\n", 1);
377 for (i = 0; i < nft; i++) {
379 if (list[i].command_pipe) {
381 xx = close(list[i].command_pipe);
383 D_(
"[filetriggers] waiting for %s to end\n"),
385 pid = waitpid(list[i].command_pid, &status, 0);
386 list[
i].command_pipe = 0;
390 oldhandler = signal(SIGPIPE, oldhandler);
394 freeFiletriggers(matches_any, nft, list);
miRE mireNew(rpmMireMode mode, int tag)
Create pattern container.
const char const char * cmd
int Chroot(const char *path)
chroot(2) clone.
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
char * rpmGetPath(const char *path,...)
Return (malloc'ed) expanded, canonicalized, file path.
Structure(s) used for file info tag sets.
int mireRegcomp(miRE mire, const char *pattern)
Compile pattern match.
int mireSetCOptions(miRE mire, rpmMireMode mode, int tag, int options, const unsigned char *table)
Initialize pattern compile options.
const char * rpmfiFN(rpmfi fi)
Return current file name from file info set.
static void rpmlog(int code, const char *fmt,...)
Yet Another syslog(3) API clone.
int rpmGlob(const char *patterns, int *argcPtr, const char ***argvPtr)
Return URL path(s) from a (URL prefixed) pattern glob.
miRE mireFree(miRE mire)
Free pattern container.
void * xcalloc(size_t nmemb, size_t size)
struct rpmfi_s * rpmfi
File info tag sets from a header, so that a header can be discarded early.
static int xisspace(int c)
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
The FD_t File Handle data structure.
const char * rpmGenPath(const char *urlroot, const char *urlmdir, const char *urlfile)
Merge 3 args into path, any or all of which may be a url.
int mireRegexec(miRE mire, const char *val, size_t vallen)
Execute pattern match.
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
int Fclose(FD_t fd)
fclose(3) clone.
int rpmfiNext(rpmfi fi)
Return next file iterator index.
rpmfi rpmfiInit(rpmfi fi, int fx)
Initialize file iterator index.
char * stpcpy(char *dest, const char *src)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
rpmfi int install_or_erase
void rpmRunFileTriggers(const char *rootDir)
const char const bson const bson int int int options