static rpmRC tagValidate(Spec spec, rpmTag tag, const char * value) /*@*/ { const char * tagN = tagName(tag); const char * pattern = rpmExpand("%{?pattern_", tagN, "}", NULL); rpmRC ec = RPMRC_OK; if (pattern && *pattern) { miRE mire; int xx; mire = mireNew(RPMMIRE_REGEX, tag); xx = mireSetCOptions(mire, RPMMIRE_REGEX, 0, 0, NULL); if (!xx) xx = mireRegcomp(mire, pattern); if (!xx) xx = mireRegexec(mire, value, strlen(value)); if (!xx) ec = RPMRC_OK; else { rpmlog(RPMLOG_ERR, _("line %d: invalid tag value(\"%s\") %s: %s\n"), spec->lineNum, pattern, tagN, spec->line); ec = RPMRC_FAIL; } mire = mireFree(mire); } pattern = _free(pattern); return ec; }
static void getFiletriggers(const char * rootDir, miRE matches_any, int * nftp, struct filetrigger ** list) /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ /*@modifies matches_any, *nftp, *list, rpmGlobalMacroContext, fileSystem, internalState @*/ { struct filetrigger_raw * list_raw = NULL; int xx; int i; xx = getFiletriggers_raw(rootDir, nftp, &list_raw); if (*nftp == 0) return; compileFiletriggersRegexp(computeMatchesAnyFilter(*nftp, list_raw), matches_any); *list = xcalloc(*nftp, sizeof(**list)); for (i = 0; i < *nftp; i++) { (*list)[i].name = list_raw[i].name; (*list)[i].mire = mireNew(0, 0); compileFiletriggersRegexp(list_raw[i].regexp, (*list)[i].mire); } list_raw = _free(list_raw); }
void rpmRunFileTriggers(const char * rootDir) { miRE matches_any = mireNew(RPMMIRE_DEFAULT, 0); int nft = 0; struct filetrigger *list = NULL; const char * fn = NULL; FD_t fd = NULL; FILE * fp = NULL; int xx; rpmlog(RPMLOG_DEBUG, D_("[filetriggers] starting\n")); fn = rpmGenPath(rootDir, files_awaiting_filetriggers, NULL); if (!filetriggers_dir()) goto exit; getFiletriggers(rootDir, matches_any, &nft, &list); if (nft <= 0) goto exit; fd = Fopen(fn, "r.fpio"); if (fd == NULL) goto exit; fp = fdGetFILE(fd); if (fp != NULL) { void (*oldhandler)(int) = signal(SIGPIPE, SIG_IGN); char tmp[BUFSIZ]; int i; rpmlog(RPMLOG_DEBUG, D_("[filetriggers] testing files from list: %s\n"), fn); while (fgets(tmp, (int)sizeof(tmp), fp)) { size_t tmplen = strlen(tmp); if (tmplen > 0 && tmp[tmplen-1] == '\n') tmp[--tmplen] = '\0'; if (!is_regexp_matching(matches_any, tmp)) continue; rpmlog(RPMLOG_DEBUG, D_("[filetriggers] matches-any regexp found %s\n"), tmp); for (i = 0; i < nft; i++) { ssize_t nw; if (!is_regexp_matching(list[i].mire, tmp)) /*@innercontinue@*/ continue; rpmlog(RPMLOG_DEBUG, D_("[filetriggers] file name '%s' matches pattern '%s'\n"), tmp, list[i].mire->pattern); mayStartFiletrigger(rootDir, &list[i]); nw = write(list[i].command_pipe, tmp, tmplen); } } xx = Fclose(fd); fd = NULL; fp = NULL; for (i = 0; i < nft; i++) { int status; if (list[i].command_pipe) { pid_t pid; xx = close(list[i].command_pipe); rpmlog(RPMLOG_DEBUG, D_("[filetriggers] waiting for %s to end\n"), list[i].name); pid = waitpid(list[i].command_pid, &status, 0); list[i].command_pipe = 0; } } freeFiletriggers(matches_any, nft, list); oldhandler = signal(SIGPIPE, oldhandler); } exit: if (fn != NULL) xx = unlink(fn); fn = _free(fn); }