#define MYALLPERMS 07777
#include <regex.h>
-#include <signal.h> /* getOutputFrom() */
#include <rpmio_internal.h>
#include <fts.h>
#include "cpio.h"
+#include "argv.h"
+#include "rpmfc.h"
+
#define _RPMFI_INTERNAL
#include "rpmfi.h"
return fl.processingFailed;
}
-/*@-boundswrite@*/
-StringBuf getOutputFrom(const char * dir, char * argv[],
- const char * writePtr, int writeBytesLeft,
- int failNonZero)
- /*@globals fileSystem, internalState@*/
- /*@modifies fileSystem, internalState@*/
-{
- int progPID;
- int toProg[2];
- int fromProg[2];
- int status;
- void *oldhandler;
- StringBuf readBuff;
- int done;
-
- /*@-type@*/ /* FIX: cast? */
- oldhandler = signal(SIGPIPE, SIG_IGN);
- /*@=type@*/
-
- toProg[0] = toProg[1] = 0;
- (void) pipe(toProg);
- fromProg[0] = fromProg[1] = 0;
- (void) pipe(fromProg);
-
- if (!(progPID = fork())) {
- (void) close(toProg[1]);
- (void) close(fromProg[0]);
-
- (void) dup2(toProg[0], STDIN_FILENO); /* Make stdin the in pipe */
- (void) dup2(fromProg[1], STDOUT_FILENO); /* Make stdout the out pipe */
-
- (void) close(toProg[0]);
- (void) close(fromProg[1]);
-
- if (dir) {
- (void) chdir(dir);
- }
-
- unsetenv("MALLOC_CHECK_");
- (void) execvp(argv[0], argv);
- /* XXX this error message is probably not seen. */
- rpmError(RPMERR_EXEC, _("Couldn't exec %s: %s\n"),
- argv[0], strerror(errno));
- _exit(RPMERR_EXEC);
- }
- if (progPID < 0) {
- rpmError(RPMERR_FORK, _("Couldn't fork %s: %s\n"),
- argv[0], strerror(errno));
- return NULL;
- }
-
- (void) close(toProg[0]);
- (void) close(fromProg[1]);
-
- /* Do not block reading or writing from/to prog. */
- (void) fcntl(fromProg[0], F_SETFL, O_NONBLOCK);
- (void) fcntl(toProg[1], F_SETFL, O_NONBLOCK);
-
- readBuff = newStringBuf();
-
- do {
- fd_set ibits, obits;
- struct timeval tv;
- int nfd, nbw, nbr;
- int rc;
-
- done = 0;
-top:
- /* XXX the select is mainly a timer since all I/O is non-blocking */
- FD_ZERO(&ibits);
- FD_ZERO(&obits);
- if (fromProg[0] >= 0) {
- FD_SET(fromProg[0], &ibits);
- }
- if (toProg[1] >= 0) {
- FD_SET(toProg[1], &obits);
- }
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- nfd = ((fromProg[0] > toProg[1]) ? fromProg[0] : toProg[1]);
- if ((rc = select(nfd, &ibits, &obits, NULL, &tv)) < 0) {
- if (errno == EINTR)
- goto top;
- break;
- }
-
- /* Write any data to program */
- if (toProg[1] >= 0 && FD_ISSET(toProg[1], &obits)) {
- if (writePtr && writeBytesLeft > 0) {
- if ((nbw = write(toProg[1], writePtr,
- (1024<writeBytesLeft) ? 1024 : writeBytesLeft)) < 0) {
- if (errno != EAGAIN) {
- perror("getOutputFrom()");
- exit(EXIT_FAILURE);
- }
- nbw = 0;
- }
- writeBytesLeft -= nbw;
- writePtr += nbw;
- } else if (toProg[1] >= 0) { /* close write fd */
- (void) close(toProg[1]);
- toProg[1] = -1;
- }
- }
-
- /* Read any data from prog */
- { char buf[BUFSIZ+1];
- while ((nbr = read(fromProg[0], buf, sizeof(buf)-1)) > 0) {
- buf[nbr] = '\0';
- appendStringBuf(readBuff, buf);
- }
- }
-
- /* terminate on (non-blocking) EOF or error */
- done = (nbr == 0 || (nbr < 0 && errno != EAGAIN));
-
- } while (!done);
-
- /* Clean up */
- if (toProg[1] >= 0)
- (void) close(toProg[1]);
- if (fromProg[0] >= 0)
- (void) close(fromProg[0]);
- /*@-type@*/ /* FIX: cast? */
- (void) signal(SIGPIPE, oldhandler);
- /*@=type@*/
-
- /* Collect status from prog */
- (void)waitpid(progPID, &status, 0);
- if (failNonZero && (!WIFEXITED(status) || WEXITSTATUS(status))) {
- rpmError(RPMERR_EXEC, _("%s failed\n"), argv[0]);
- return NULL;
- }
- if (writeBytesLeft) {
- rpmError(RPMERR_EXEC, _("failed to write all data to %s\n"), argv[0]);
- return NULL;
- }
- return readBuff;
-}
-/*@=boundswrite@*/
-
/**
*/
typedef struct {
/*@-exportlocal -exportheadervar@*/
/*@unchecked@*/
DepMsg_t depMsgs[] = {
- { "Provides", { "%{__find_provides}", NULL, NULL, NULL },
+ { "Provides", { "%{?__find_provides}", NULL, NULL, NULL },
RPMTAG_PROVIDENAME, RPMTAG_PROVIDEVERSION, RPMTAG_PROVIDEFLAGS,
0, -1 },
{ "PreReq", { NULL, NULL, NULL, NULL },
{ "Requires(postun)", { NULL, "postun", NULL, NULL },
-1, -1, RPMTAG_REQUIREFLAGS,
_notpre(RPMSENSE_SCRIPT_POSTUN), 0 },
- { "Requires", { "%{__find_requires}", NULL, NULL, NULL },
+ { "Requires", { "%{?__find_requires}", NULL, NULL, NULL },
-1, -1, RPMTAG_REQUIREFLAGS, /* XXX inherit name/version arrays */
RPMSENSE_PREREQ, RPMSENSE_PREREQ },
- { "Conflicts", { "%{__find_conflicts}", NULL, NULL, NULL },
+ { "Conflicts", { "%{?__find_conflicts}", NULL, NULL, NULL },
RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTVERSION, RPMTAG_CONFLICTFLAGS,
0, -1 },
- { "Obsoletes", { "%{__find_obsoletes}", NULL, NULL, NULL },
+ { "Obsoletes", { "%{?__find_obsoletes}", NULL, NULL, NULL },
RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEVERSION, RPMTAG_OBSOLETEFLAGS,
0, -1 },
{ NULL, { NULL, NULL, NULL, NULL }, 0, 0, 0, 0, 0 }
fileSystem, internalState @*/
{
rpmfi fi = cpioList;
- StringBuf writeBuf;
- int writeBytes;
- StringBuf readBuf;
- DepMsg_t *dm;
- char ** myargv;
+ StringBuf sb_stdin;
+ StringBuf sb_stdout;
+ DepMsg_t * dm;
int failnonzero = 0;
int rc = 0;
- int ac;
int i;
- myargv = xcalloc(5, sizeof(*myargv));
-
if (!(fi && fi->fc > 0))
return 0;
if (! (pkg->autoReq || pkg->autoProv))
return 0;
-
- writeBuf = newStringBuf();
/*
* Create file manifest buffer to deliver to dependency finder.
*/
- for (i = 0, writeBytes = 0; i < fi->fc; i++) {
+ sb_stdin = newStringBuf();
+ for (i = 0; i < fi->fc; i++) {
/*
* On 2nd dependency pass for multilib, skip files already processed.
fi->fmapflags[i] &= ~CPIO_MULTILIB;
}
- appendStringBuf(writeBuf, fi->dnl[fi->dil[i]]);
- writeBytes += strlen(fi->dnl[fi->dil[i]]);
- appendLineStringBuf(writeBuf, fi->bnl[i]);
- writeBytes += strlen(fi->bnl[i]) + 1;
+ appendStringBuf(sb_stdin, fi->dnl[fi->dil[i]]);
+ appendLineStringBuf(sb_stdin, fi->bnl[i]);
}
for (dm = depMsgs; dm->msg != NULL; dm++) {
int tag, tagflags;
char * s;
+ int xx;
tag = (dm->ftag > 0) ? dm->ftag : dm->ntag;
tagflags = 0;
/*@notreached@*/ /*@switchbreak@*/ break;
}
- /* Get the script name (and possible args) to run */
-/*@-branchstate@*/
- if (dm->argv[0] != NULL) {
- const char ** av;
-
- /*@-nullderef@*/ /* FIX: double indirection. @*/
- s = rpmExpand(dm->argv[0], NULL);
- /*@=nullderef@*/
- if (!(s != NULL && *s != '%' && *s != '\0')) {
- s = _free(s);
- continue;
- }
-
- if (!(i = poptParseArgvString(s, &ac, (const char ***)&av))
- && ac > 0 && av != NULL)
- {
- myargv = xrealloc(myargv, (ac + 5) * sizeof(*myargv));
- for (i = 0; i < ac; i++)
- myargv[i] = xstrdup(av[i]);
- }
- av = _free(av);
- }
-/*@=branchstate@*/
-
- if (myargv[0] == NULL)
+ xx = rpmfcExec(dm->argv, sb_stdin, &sb_stdout, failnonzero);
+ if (xx == -1)
continue;
+ s = rpmExpand(dm->argv[0], NULL);
rpmMessage(RPMMESS_NORMAL, _("Finding %s: %s\n"), dm->msg,
(s ? s : ""));
s = _free(s);
-#if 0
- if (*myargv[0] != '/') { /* XXX FIXME: stat script here */
- myargv[0] = _free(myargv[0]);
- continue;
- }
-#endif
-
- /* Expand rest of script arguments (if any) */
- for (i = 1; i < 4; i++) {
- if (dm->argv[i] == NULL)
- /*@innerbreak@*/ break;
- /*@-nullderef@*/ /* FIX: double indirection. @*/
- myargv[ac++] = rpmExpand(dm->argv[i], NULL);
- /*@=nullderef@*/
- }
-
- myargv[ac] = NULL;
- readBuf = getOutputFrom(NULL, myargv,
- getStringBuf(writeBuf), writeBytes, failnonzero);
-
- /* Free expanded args */
- for (i = 0; i < ac; i++)
- myargv[i] = _free(myargv[i]);
-
- if (readBuf == NULL) {
+ if (sb_stdout == NULL) {
rc = RPMERR_EXEC;
rpmError(rc, _("Failed to find %s:\n"), dm->msg);
break;
tagflags &= ~RPMSENSE_MULTILIB;
if (multiLibPass > 1)
tagflags |= RPMSENSE_MULTILIB;
- rc = parseRCPOT(spec, pkg, getStringBuf(readBuf), tag, 0, tagflags);
- readBuf = freeStringBuf(readBuf);
+
+ rc = parseRCPOT(spec, pkg, getStringBuf(sb_stdout), tag, 0, tagflags);
+ sb_stdout = freeStringBuf(sb_stdout);
if (rc) {
rpmError(rc, _("Failed to find %s:\n"), dm->msg);
}
}
- writeBuf = freeStringBuf(writeBuf);
- myargv = _free(myargv);
+ sb_stdin = freeStringBuf(sb_stdin);
return rc;
}
/*@=bounds@*/
/*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
/*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
{
- StringBuf readBuf = NULL;
- const char * s = NULL;
- char ** av = NULL;
- int ac = 0;
- int rc = 0;
- char *buf;
+ static const char * av_ckfile[] = { "%{?__check_files}", NULL };
+ StringBuf sb_stdout = NULL;
+ const char * s;
+ int rc;
- s = rpmExpand("%{?__check_files}", NULL);
- if (!(s && *s)) {
- rc = -1;
- goto exit;
- }
- if (!((rc = poptParseArgvString(s, &ac, (const char ***)&av)) == 0
- && ac > 0 && av != NULL))
- {
+ s = rpmExpand(av_ckfile[0], NULL);
+ rc = (s && *s) ? 0 : -1;
+ if (rc != 0)
goto exit;
- }
-
+
rpmMessage(RPMMESS_NORMAL, _("Checking for unpackaged file(s): %s\n"), s);
-
- readBuf = getOutputFrom(NULL, av, getStringBuf(fileList), fileListLen, 0);
+
+ rc = rpmfcExec(av_ckfile, fileList, &sb_stdout, 0);
+ if (rc < 0)
+ goto exit;
- if (readBuf) {
+ if (sb_stdout) {
static int _unpackaged_files_terminate_build = 0;
static int oneshot = 0;
+ const char * t;
if (!oneshot) {
_unpackaged_files_terminate_build =
oneshot = 1;
}
- buf = getStringBuf(readBuf);
- if ((*buf != '\0') && (*buf != '\n')) {
+ t = getStringBuf(sb_stdout);
+ if ((*t != '\0') && (*t != '\n')) {
rc = (_unpackaged_files_terminate_build) ? 1 : 0;
rpmMessage((rc ? RPMMESS_ERROR : RPMMESS_WARNING),
- _("Installed (but unpackaged) file(s) found:\n%s"), buf);
+ _("Installed (but unpackaged) file(s) found:\n%s"), t);
}
}
exit:
- readBuf = freeStringBuf(readBuf);
+ sb_stdout = freeStringBuf(sb_stdout);
s = _free(s);
- av = _free(av);
return rc;
}
rpmGlobalMacroContext, fileSystem, internalState @*/;
/** \ingroup rpmbuild
- * Return output from helper script.
- * @param dir directory to run in (or NULL)
- * @param argv program and arguments to run
- * @param writePtr bytes to feed to script on stdin (or NULL)
- * @param writeBytesLeft no. of bytes to feed to script on stdin
- * @param failNonZero is script failure an error?
- * @return buffered stdout from script, NULL on error
- */
-/*@null@*/
-StringBuf getOutputFrom(/*@null@*/ const char * dir, char * argv[],
- const char * writePtr, int writeBytesLeft,
- int failNonZero)
- /*@globals fileSystem, internalState@*/
- /*@modifies fileSystem, internalState@*/;
-
-/** \ingroup rpmbuild
* Parse spec file into spec control structure.
* @retval specp spec file control structure
* @param specFile
/*@-bounds@*/
#include "system.h"
+#include <signal.h> /* getOutputFrom() */
+
#include <rpmbuild.h>
#include <argv.h>
#include <rpmfc.h>
/*@notchecked@*/
int _rpmfc_debug;
+static int rpmfcExpandAppend(/*@out@*/ ARGV_t * argvp, const ARGV_t av)
+{
+ ARGV_t argv = *argvp;
+ int argc = argvCount(argv);
+ int ac = argvCount(av);
+ int i;
+
+ argv = xrealloc(argv, (argc + ac + 1) * sizeof(*argv));
+ for (i = 0; i < ac; i++)
+ argv[argc + i] = rpmExpand(av[i], NULL);
+ argv[argc + ac] = NULL;
+ *argvp = argv;
+ return 0;
+}
+
+
+/*@-boundswrite@*/
+/** \ingroup rpmbuild
+ * Return output from helper script.
+ * @param dir directory to run in (or NULL)
+ * @param argv program and arguments to run
+ * @param writePtr bytes to feed to script on stdin (or NULL)
+ * @param writeBytesLeft no. of bytes to feed to script on stdin
+ * @param failNonZero is script failure an error?
+ * @return buffered stdout from script, NULL on error
+ */
+/*@null@*/
+static StringBuf getOutputFrom(/*@null@*/ const char * dir, char * argv[],
+ const char * writePtr, int writeBytesLeft,
+ int failNonZero)
+ /*@globals fileSystem, internalState@*/
+ /*@modifies fileSystem, internalState@*/
+{
+ int progPID;
+ int toProg[2];
+ int fromProg[2];
+ int status;
+ void *oldhandler;
+ StringBuf readBuff;
+ int done;
+
+ /*@-type@*/ /* FIX: cast? */
+ oldhandler = signal(SIGPIPE, SIG_IGN);
+ /*@=type@*/
+
+ toProg[0] = toProg[1] = 0;
+ (void) pipe(toProg);
+ fromProg[0] = fromProg[1] = 0;
+ (void) pipe(fromProg);
+
+ if (!(progPID = fork())) {
+ (void) close(toProg[1]);
+ (void) close(fromProg[0]);
+
+ (void) dup2(toProg[0], STDIN_FILENO); /* Make stdin the in pipe */
+ (void) dup2(fromProg[1], STDOUT_FILENO); /* Make stdout the out pipe */
+
+ (void) close(toProg[0]);
+ (void) close(fromProg[1]);
+
+ if (dir) {
+ (void) chdir(dir);
+ }
+
+ unsetenv("MALLOC_CHECK_");
+ (void) execvp(argv[0], argv);
+ /* XXX this error message is probably not seen. */
+ rpmError(RPMERR_EXEC, _("Couldn't exec %s: %s\n"),
+ argv[0], strerror(errno));
+ _exit(RPMERR_EXEC);
+ }
+ if (progPID < 0) {
+ rpmError(RPMERR_FORK, _("Couldn't fork %s: %s\n"),
+ argv[0], strerror(errno));
+ return NULL;
+ }
+
+ (void) close(toProg[0]);
+ (void) close(fromProg[1]);
+
+ /* Do not block reading or writing from/to prog. */
+ (void) fcntl(fromProg[0], F_SETFL, O_NONBLOCK);
+ (void) fcntl(toProg[1], F_SETFL, O_NONBLOCK);
+
+ readBuff = newStringBuf();
+
+ do {
+ fd_set ibits, obits;
+ struct timeval tv;
+ int nfd, nbw, nbr;
+ int rc;
+
+ done = 0;
+top:
+ /* XXX the select is mainly a timer since all I/O is non-blocking */
+ FD_ZERO(&ibits);
+ FD_ZERO(&obits);
+ if (fromProg[0] >= 0) {
+ FD_SET(fromProg[0], &ibits);
+ }
+ if (toProg[1] >= 0) {
+ FD_SET(toProg[1], &obits);
+ }
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ nfd = ((fromProg[0] > toProg[1]) ? fromProg[0] : toProg[1]);
+ if ((rc = select(nfd, &ibits, &obits, NULL, &tv)) < 0) {
+ if (errno == EINTR)
+ goto top;
+ break;
+ }
+
+ /* Write any data to program */
+ if (toProg[1] >= 0 && FD_ISSET(toProg[1], &obits)) {
+ if (writePtr && writeBytesLeft > 0) {
+ if ((nbw = write(toProg[1], writePtr,
+ (1024<writeBytesLeft) ? 1024 : writeBytesLeft)) < 0) {
+ if (errno != EAGAIN) {
+ perror("getOutputFrom()");
+ exit(EXIT_FAILURE);
+ }
+ nbw = 0;
+ }
+ writeBytesLeft -= nbw;
+ writePtr += nbw;
+ } else if (toProg[1] >= 0) { /* close write fd */
+ (void) close(toProg[1]);
+ toProg[1] = -1;
+ }
+ }
+
+ /* Read any data from prog */
+ { char buf[BUFSIZ+1];
+ while ((nbr = read(fromProg[0], buf, sizeof(buf)-1)) > 0) {
+ buf[nbr] = '\0';
+ appendStringBuf(readBuff, buf);
+ }
+ }
+
+ /* terminate on (non-blocking) EOF or error */
+ done = (nbr == 0 || (nbr < 0 && errno != EAGAIN));
+
+ } while (!done);
+
+ /* Clean up */
+ if (toProg[1] >= 0)
+ (void) close(toProg[1]);
+ if (fromProg[0] >= 0)
+ (void) close(fromProg[0]);
+ /*@-type@*/ /* FIX: cast? */
+ (void) signal(SIGPIPE, oldhandler);
+ /*@=type@*/
+
+ /* Collect status from prog */
+ (void)waitpid(progPID, &status, 0);
+ if (failNonZero && (!WIFEXITED(status) || WEXITSTATUS(status))) {
+ rpmError(RPMERR_EXEC, _("%s failed\n"), argv[0]);
+ return NULL;
+ }
+ if (writeBytesLeft) {
+ rpmError(RPMERR_EXEC, _("failed to write all data to %s\n"), argv[0]);
+ return NULL;
+ }
+ return readBuff;
+}
+/*@=boundswrite@*/
+
+int rpmfcExec(ARGV_t av, StringBuf sb_stdin, StringBuf * sb_stdoutp,
+ int failnonzero)
+{
+ const char * s = NULL;
+ ARGV_t xav = NULL;
+ ARGV_t pav = NULL;
+ int pac = 0;
+ int ec = -1;
+ StringBuf sb = NULL;
+ const char * buf_stdin = NULL;
+ int buf_stdin_len = 0;
+ int xx;
+
+ if (sb_stdoutp)
+ *sb_stdoutp = NULL;
+ if (!(av && *av))
+ goto exit;
+
+ /* Find path to executable with (possible) args. */
+ s = rpmExpand(av[0], NULL);
+ if (!(s && *s))
+ goto exit;
+
+ /* Parse args buried within expanded exacutable. */
+ pac = 0;
+ xx = poptParseArgvString(s, &pac, (const char ***)&pav);
+ if (!(xx == 0 && pac > 0 && pav != NULL))
+ goto exit;
+
+ /* Build argv, appending args to the executable args. */
+ xav = NULL;
+ xx = argvAppend(&xav, pav);
+ if (av[1])
+ xx = rpmfcExpandAppend(&xav, av + 1);
+
+ if (sb_stdin) {
+ buf_stdin = getStringBuf(sb_stdin);
+ buf_stdin_len = strlen(buf_stdin);
+ }
+
+ /* Read output from exec'd helper. */
+ sb = getOutputFrom(NULL, xav, buf_stdin, buf_stdin_len, failnonzero);
+
+ if (sb_stdoutp) {
+ *sb_stdoutp = sb;
+ sb = NULL; /* XXX don't free */
+ }
+
+ ec = 0;
+
+exit:
+ sb = freeStringBuf(sb);
+ xav = argvFree(xav);
+ pav = _free(pav); /* XXX popt mallocs in single blob. */
+ s = _free(s);
+ return ec;
+}
+
/**
*/
/*@unchecked@*/ /*@observer@*/
fc->ddictx = argiFree(fc->ddictx);
fc->provides = argvFree(fc->provides);
fc->requires = argvFree(fc->requires);
+
+ fc->sb_java = freeStringBuf(fc->sb_java);
+ fc->sb_perl = freeStringBuf(fc->sb_perl);
+ fc->sb_python = freeStringBuf(fc->sb_python);
+
}
fc = _free(fc);
return NULL;
static int rpmfcSCRIPT(rpmfc fc)
{
- const char * fn = fc->fn[fc->ix];;
+ const char * fn = fc->fn[fc->ix];
+ const char * bn;
char deptype;
char buf[BUFSIZ];
FILE * fp;
if (!(s[0] == '#' && s[1] == '!'))
continue;
s += 2;
+
while (*s && strchr(" \t\n\r", *s) != NULL)
s++;
if (*s == '\0')
}
*se = '\0';
+ /* Set color based on interpreter name. */
+ bn = basename(s);
+ if (!strcmp(bn, "perl")) {
+ fc->fcolor->vals[fc->ix] |= RPMFC_PERL;
+ if (fc->sb_perl == NULL)
+ fc->sb_perl = newStringBuf();
+ appendLineStringBuf(fc->sb_perl, fn);
+ }
+ if (!strcmp(bn, "python")) {
+ fc->fcolor->vals[fc->ix] |= RPMFC_PYTHON;
+ if (fc->sb_python == NULL)
+ fc->sb_python = newStringBuf();
+ appendLineStringBuf(fc->sb_python, fn);
+ }
+
/* Add to package requires. */
if (argvSearch(fc->requires, s, NULL) == NULL) {
xx = argvAdd(&fc->requires, s);
}
(void) fclose(fp);
+
return 0;
}
fcolor = rpmfcColoring(se);
xx = argiAdd(&fc->fcolor, fc->ix, fcolor);
-#ifdef DYING
- if (fcolor & RPMFC_ELF) {
- xx = rpmfcELF(fc);
- } else if (fcolor & RPMFC_SCRIPT) {
- xx = rpmfcSCRIPT(fc);
- }
-#endif
-
fc->ix++;
}
ARGV_t dav, davbase;
rpmfcApplyTbl fcat;
char deptype;
- int fcolor;
int nddict;
int previx;
unsigned int val;
int ix;
int i;
int xx;
+char buf[BUFSIZ];
/* Generate package and per-file dependencies. */
for (fc->ix = 0; fc->fn[fc->ix] != NULL; fc->ix++) {
- fcolor = fc->fcolor->vals[fc->ix];
for (fcat = rpmfcApplyTable; fcat->func != NULL; fcat++) {
- if (!(fcolor & fcat->colormask))
+ if (!(fc->fcolor->vals[fc->ix] & fcat->colormask))
continue;
xx = (*fcat->func) (fc);
}
}
+ /* Generate perl(foo) dependencies. */
+ if (fc->sb_perl) {
+ static const char * av_perl_provides[] = { "%{?__perl_provides}", NULL };
+ static const char * av_perl_requires[] = { "%{?__perl_requires}", NULL };
+ StringBuf sb_stdout;
+ ARGV_t pav;
+ int pac;
+
+ sb_stdout = NULL;
+ xx = rpmfcExec(av_perl_provides, fc->sb_perl, &sb_stdout, 0);
+ if (xx == 0 && sb_stdout != NULL) {
+ xx = argvSplit(&pav, getStringBuf(sb_stdout), " \t\n\r");
+ pac = argvCount(pav);
+ if (pav)
+ for (i = 0; i < pac; i++) {
+ se = buf;
+ *se = '\0';
+ se = stpcpy(se, pav[i]);
+ if (pav[i+1] && strchr("!=<>", *pav[i+1])) {
+ i++;
+ *se++ = ' ';
+ se = stpcpy(se, pav[i]);
+ if (pav[i+1]) {
+ i++;
+ *se++ = ' ';
+ se = stpcpy(se, pav[i]);
+ }
+ }
+
+ /* Add to package provides. */
+ if (argvSearch(fc->provides, buf, NULL) == NULL) {
+ xx = argvAdd(&fc->provides, buf);
+ xx = argvSort(fc->provides, NULL);
+ }
+ /* XXX attach to per-file dependencies. */
+ }
+ pav = argvFree(pav);
+ sb_stdout = freeStringBuf(sb_stdout);
+ }
+
+ sb_stdout = NULL;
+ xx = rpmfcExec(av_perl_requires, fc->sb_perl, &sb_stdout, 0);
+ if (xx == 0 && sb_stdout != NULL) {
+ xx = argvSplit(&pav, getStringBuf(sb_stdout), " \t\n\r");
+ pac = argvCount(pav);
+ if (pav)
+ for (i = 0; i < pac; i++) {
+ se = buf;
+ *se = '\0';
+ se = stpcpy(se, pav[i]);
+ if (pav[i+1] && strchr("!=<>", *pav[i+1])) {
+ i++;
+ *se++ = ' ';
+ se = stpcpy(se, pav[i]);
+ if (pav[i+1]) {
+ i++;
+ *se++ = ' ';
+ se = stpcpy(se, pav[i]);
+ }
+ }
+
+ /* Add to package requires. */
+ if (argvSearch(fc->requires, buf, NULL) == NULL) {
+ xx = argvAdd(&fc->requires, buf);
+ xx = argvSort(fc->requires, NULL);
+ }
+ /* XXX attach to per-file dependencies. */
+ }
+ pav = argvFree(pav);
+ sb_stdout = freeStringBuf(sb_stdout);
+ }
+ }
+
/* Generate per-file indices into package dependencies. */
nddict = argvCount(fc->ddict);
previx = -1;
int fknown; /*!< no. of classified files */
int fwhite; /*!< no. of "white" files */
int ix; /*!< current file index */
+
ARGV_t fn; /*!< (#files) file names */
ARGI_t fcolor; /*!< (#files) file colors */
ARGI_t fcdictx; /*!< (#files) file class dictionary indices */
ARGV_t cdict; /*!< (#classes) file class dictionary */
ARGV_t ddict; /*!< (#dependencies) file depends dictionary */
ARGI_t ddictx; /*!< (#dependencies) file->dependency mapping */
+
ARGV_t provides; /*!< (#provides) package provides */
ARGV_t requires; /*!< (#requires) package requires */
+
+ StringBuf sb_java; /*!< concatenated list of java colored files. */
+ StringBuf sb_perl; /*!< concatenated list of perl colored files. */
+ StringBuf sb_python;/*!< concatenated list of python colored files. */
+
};
enum FCOLOR_e {
/**
*/
+int rpmfcExec(ARGV_t av, StringBuf sb_stdin, StringBuf * sb_stdoutp,
+ int failnonzero)
+ /*@*/;
+
+/**
+ */
int rpmfcColoring(const char * fmstr)
/*@*/;
int
main(int argc, char *const argv[])
{
+ static const char * av_file[] = { "%{?__file}", NULL };
poptContext optCon;
StringBuf sb;
- ARGV_t pav;
- int pac = 0;
ARGV_t xav;
ARGV_t av = NULL;
rpmfc fc;
int ac = 0;
- const char * s;
int ec = 1;
int xx;
char buf[BUFSIZ];
av = poptGetArgs(optCon);
ac = argvCount(av);
- /* Find path to file(1). */
- s = rpmExpand("%{?__file}", NULL);
- if (!(s && *s))
- goto exit;
-
- /* Build argv, merging tokens from expansion with CLI args. */
- xx = poptParseArgvString(s, &pac, (const char ***)&pav);
- if (!(xx == 0 && pac > 0 && pav != NULL))
- goto exit;
-
xav = NULL;
- xx = argvAppend(&xav, pav);
+ xx = argvAppend(&xav, av_file);
xx = argvAppend(&xav, av);
- pav = _free(pav); /* XXX popt mallocs in single blob. */
- s = _free(s);
- /* Read file(1) output. */
- sb = getOutputFrom(NULL, xav, NULL, 0, 1);
+ sb = NULL;
+ xx = rpmfcExec(xav, NULL, &sb, 1);
+
xav = argvFree(xav);
xx = argvSplit(&xav, getStringBuf(sb), "\n");