11 #define _MIRE_INTERNAL
15 #define _RPMEVR_INTERNAL
18 #define _RPMNS_INTERNAL
21 #define _RPMFC_INTERNAL
24 #define _RPMDS_INTERNAL
50 argv =
xrealloc(argv, (argc + ac + 1) *
sizeof(*argv));
51 for (i = 0; i < ac; i++)
53 argv[argc + ac] = NULL;
70 const char * writePtr,
size_t writeBytesLeft,
84 oldhandler = signal(SIGPIPE, SIG_IGN);
87 toProg[0] = toProg[1] = 0;
88 fromProg[0] = fromProg[1] = 0;
89 if (pipe(toProg) < 0 || pipe(fromProg) < 0) {
94 if (!(child = fork())) {
95 (void) close(toProg[1]);
96 (void) close(fromProg[0]);
98 (void) dup2(toProg[0], STDIN_FILENO);
99 (void) dup2(fromProg[1], STDOUT_FILENO);
101 (void) close(toProg[0]);
102 (void) close(fromProg[1]);
109 argv[0], (
unsigned)getpid());
112 (void) execvp(argv[0], (
char *
const *)argv);
115 argv[0], strerror(
errno));
120 argv[0], strerror(
errno));
124 (void) close(toProg[0]);
125 (void) close(fromProg[1]);
128 (void) fcntl(fromProg[0], F_SETFL, O_NONBLOCK);
129 (void) fcntl(toProg[1], F_SETFL, O_NONBLOCK);
145 if (fromProg[0] >= 0) {
146 FD_SET(fromProg[0], &ibits);
148 if (toProg[1] >= 0) {
149 FD_SET(toProg[1], &obits);
154 nfd = ((fromProg[0] > toProg[1]) ? fromProg[0] : toProg[1]);
155 if ((rc = select(nfd, &ibits, &obits, NULL, &tv)) < 0) {
162 if (toProg[1] >= 0 && FD_ISSET(toProg[1], &obits)) {
163 if (writePtr && writeBytesLeft > 0) {
164 if ((nbw = write(toProg[1], writePtr,
165 ((
size_t)1024<writeBytesLeft) ? (
size_t)1024 : writeBytesLeft)) < 0)
167 if (
errno != EAGAIN) {
168 perror(
"getOutputFrom()");
173 writeBytesLeft -= nbw;
175 }
else if (toProg[1] >= 0) {
176 (void) close(toProg[1]);
182 {
char buf[BUFSIZ+1];
183 while ((nbr = read(fromProg[0], buf,
sizeof(buf)-1)) > 0) {
190 done = (nbr == 0 || (nbr < 0 &&
errno != EAGAIN));
196 (void) close(toProg[1]);
197 if (fromProg[0] >= 0)
198 (void) close(fromProg[0]);
200 (void) signal(SIGPIPE, oldhandler);
204 reaped = waitpid(child, &status, 0);
206 (
unsigned)child, (
unsigned)reaped, status);
208 if (failNonZero && (!WIFEXITED(status) || WEXITSTATUS(status))) {
210 int rc = (WIFEXITED(status) ? WEXITSTATUS(status) : -1);
217 if (writeBytesLeft) {
228 const char * s = NULL;
234 const char * buf_stdin = NULL;
235 size_t buf_stdin_len = 0;
250 xx = poptParseArgvString(s, &pac, (
const char ***)&pav);
251 if (!(xx == 0 && pac > 0 && pav != NULL))
260 if (iob_stdin != NULL) {
266 iob =
getOutputFrom(NULL, xav, buf_stdin, buf_stdin_len, failnonzero);
268 if (iob_stdoutp != NULL) {
323 sprintf(buf,
"%08u%c %s %s 0x%08x", (
unsigned)ix, deptype,
344 xx = poptParseArgvString(s, &ac, (
const char ***)&av);
347 if (ac == 0 || av == NULL || *av == NULL)
350 for (i = 0; i < ac; i++) {
355 _(
"Compilation of pattern '%s'"
356 " (expanded from '%s') failed. Skipping ...\n"),
372 const char * str,
char deptype)
379 for (i = 0; i < nmire; i++) {
412 const char * fn = fc->fn[fc->ix];
436 xx =
snprintf(buf,
sizeof(buf),
"%%{?__%s_provides}", nsdep);
437 depsp = &fc->provides;
438 dsContext = RPMSENSE_FIND_PROVIDES;
446 xx =
snprintf(buf,
sizeof(buf),
"%%{?__%s_requires}", nsdep);
447 depsp = &fc->requires;
448 dsContext = RPMSENSE_FIND_REQUIRES;
454 buf[
sizeof(buf)-1] =
'\0';
461 xx =
rpmfcExec(av, iob_stdin, &iob_stdout, 0);
464 if (xx == 0 && iob_stdout != NULL) {
469 for (i = 0; i < pac; i++) {
473 if (pav[i+1] && strchr(
"=<>", *pav[i+1])) {
475 for (s = pav[i]; *s; s++) {
500 if (!fc->tracked && deptype ==
'P' && *EVR !=
'\0') {
502 "rpmlib(VersionedDependencies)",
"3.0.3-1",
638 for (fct =
rpmfcTokens; fct->token != NULL; fct++) {
639 if (strstr(fmstr, fct->token) == NULL)
641 fcolor |= fct->colors;
659 if (fp == NULL) fp = stderr;
662 fprintf(fp,
"===================================== %s\n", msg);
668 for (fx = 0; fx < fc->nfiles; fx++) {
669 assert(fx < fc->fcdictx->nvals);
670 cx = fc->fcdictx->vals[fx];
671 assert(fx < fc->fcolor->nvals);
672 fcolor = fc->fcolor->vals[fx];
674 fprintf(fp,
"%3d %s", (
int)fx, fc->fn[fx]);
676 fprintf(fp,
"\t0x%x", fc->fcolor->vals[fx]);
678 fprintf(fp,
"\t%s", fc->cdict[cx]);
681 if (fc->fddictx == NULL || fc->fddictn == NULL)
684 assert(fx < fc->fddictx->nvals);
685 dx = fc->fddictx->vals[fx];
686 assert(fx < fc->fddictn->nvals);
687 ndx = fc->fddictn->vals[fx];
691 unsigned char deptype;
694 ix = fc->ddictx->vals[dx++];
695 deptype = ((ix >> 24) & 0xff);
700 assert(depval != NULL);
704 assert(ix < nprovides);
712 assert(ix < nrequires);
720 fprintf(fp,
"\t%s\n", depval);
734 const char * fn = fc->fn[fc->ix];
745 {
struct stat sb, * st = &sb;
746 if (stat(fn, st) != 0)
748 is_executable = (int)(st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH));
752 if (fp == NULL || ferror(fp)) {
753 if (fp) (void) fclose(fp);
758 for (i = 0; i < 10; i++) {
760 s = fgets(buf,
sizeof(buf) - 1, fp);
761 if (s == NULL || ferror(fp) || feof(fp))
763 s[
sizeof(buf)-1] =
'\0';
764 if (!(s[0] ==
'#' && s[1] ==
'!'))
768 while (*s && strchr(
" \t\n\r", *s) != NULL)
775 for (se = s+1; *se; se++) {
776 if (strchr(
" \t\n\r", *se) != NULL)
802 if (!strcmp(bn,
"perl"))
804 else if (!strncmp(bn,
"python",
sizeof(
"python")-1))
806 else if (!strncmp(bn,
"php",
sizeof(
"php")-1))
815 if (strncmp(fn,
"/usr/share/doc/",
sizeof(
"/usr/share/doc/")-1)) {
818 if (is_executable || (fc->fcolor->vals[fc->ix] &
RPMFC_MODULE))
850 if (fc->fcolor->vals[fc->ix] &
RPMFC_PHP) {
878 fprintf(stderr,
"*** rpmfcMergePR(%p, %p) %s\n", context, ds,
tagName(
rpmdsTagN(ds)));
922 const char * fn = fc->fn[fc->ix];
960 unsigned char deptype;
971 int skipProv = fc->skipProv;
972 int skipReq = fc->skipReq;
990 assert(fc->fn != NULL);
992 for (fc->ix = 0; fc->fn[fc->ix] != NULL; fc->ix++) {
996 { fn = strstr(fc->fn[fc->ix],
"/usr/lib");
998 fn +=
sizeof(
"/usr/lib")-1;
999 if ((fn[0] ==
'3' && fn[1] ==
'2') ||
1000 (fn[0] ==
'6' && fn[1] ==
'4'))
1002 if (!strncmp(fn,
"/python",
sizeof(
"/python")-1))
1007 if (fc->fcolor->vals[fc->ix])
1008 for (fcat = rpmfcApplyTable; fcat->
func != NULL; fcat++) {
1009 if (!(fc->fcolor->vals[fc->ix] & fcat->
colormask))
1013 fc->skipProv = skipProv;
1014 fc->skipReq = skipReq;
1015 if ((mire = fc->PFmires) != NULL)
1016 for (j = 0; j < fc->PFnmire; j++, mire++) {
1017 fn = fc->fn[fc->ix] + fc->brlen;
1025 if ((mire = fc->RFmires) != NULL)
1026 for (j = 0; j < fc->RFnmire; j++, mire++) {
1027 fn = fc->fn[fc->ix] + fc->brlen;
1037 xx = (*fcat->
func) (fc);
1047 fc->skipProv = skipProv;
1048 fc->skipReq = skipReq;
1053 for (i = 0; i < nddict; i++) {
1057 ix = strtol(s, &se, 10);
1062 while (*se && *se !=
' ')
1066 while (*se && *se !=
' ')
1069 Flags = strtol(se, NULL, 16);
1077 skipping = fc->skipProv;
1084 skipping = fc->skipReq;
1100 val = (deptype << 24) | (dix & 0x00ffffff);
1101 xx =
argiAdd(&fc->ddictx, -1, val);
1107 if (fc->fddictn && fc->fddictn->vals && !skipping)
1108 fc->fddictn->vals[ix]++;
1119 const char * s, * se;
1123 const char * magicfile = NULL;
1125 if (fc == NULL || argv == NULL)
1128 magicfile =
rpmExpand(
"%{?_rpmfc_magic_path}", NULL);
1129 if (magicfile == NULL || *magicfile ==
'\0')
1130 magicfile =
_free(magicfile);
1137 xx =
argiAdd(&fc->fddictx, fc->nfiles-1, 0);
1138 xx =
argiAdd(&fc->fddictn, fc->nfiles-1, 0);
1142 xx =
argvAdd(&fc->cdict,
"directory");
1144 for (fc->ix = 0; fc->ix < fc->nfiles; fc->ix++) {
1150 ftype =
""; freeftype = 0;
1151 urltype =
urlPath(argv[fc->ix], &s);
1152 assert(s != NULL && *s ==
'/');
1155 switch (mode & S_IFMT) {
1156 case S_IFCHR: ftype =
"character special";
break;
1157 case S_IFBLK: ftype =
"block special";
break;
1158 #if defined(S_IFIFO)
1159 case S_IFIFO: ftype =
"fifo (named pipe)";
break;
1161 #if defined(S_IFSOCK)
1163 case S_IFSOCK: ftype =
"socket";
break;
1171 #define _suffix(_s, _x) \
1172 (slen >= sizeof(_x) && !strcmp((_s)+slen-(sizeof(_x)-1), (_x)))
1176 ftype =
"Perl5 module source text";
1180 ftype =
"Java archive file";
1183 else if (
_suffix(s,
".class"))
1184 ftype =
"Java class file";
1188 ftype =
"libtool library file";
1192 ftype =
"pkgconfig file";
1196 ftype =
"PHP script text";
1199 else if (slen >= fc->brlen+
sizeof(
"/dev/") && !strncmp(s+fc->brlen,
"/dev/",
sizeof(
"/dev/")-1))
1201 else if (magicfile) {
1203 assert(ftype != NULL);
1222 xx =
argiAdd(&fc->fcolor, (
int)fc->ix, fcolor);
1229 ftype =
_free(ftype);
1235 for (fc->ix = 0; fc->ix < fc->nfiles; fc->ix++) {
1241 xx =
argiAdd(&fc->fcdictx, (
int)fc->ix, (dav - fc->cdict));
1244 xx =
argiAdd(&fc->fcdictx, (
int)fc->ix, 0);
1253 D_(
"categorized %d files into %d classes (using %s).\n"),
1254 fc->nfiles,
argvCount(fc->cdict), magicfile);
1255 magicfile =
_free(magicfile);
1283 {
"Provides", {
"%{?__find_provides}", NULL, NULL, NULL },
1286 {
"Requires(interp)", { NULL,
"interp", NULL, NULL },
1288 _notpre(RPMSENSE_INTERP), 0 },
1289 {
"Requires(rpmlib)", { NULL,
"rpmlib", NULL, NULL },
1291 _notpre(RPMSENSE_RPMLIB), 0 },
1292 {
"Requires(verify)", { NULL,
"verify", NULL, NULL },
1294 RPMSENSE_SCRIPT_VERIFY, 0 },
1295 {
"Requires(pre)", { NULL,
"pre", NULL, NULL },
1297 _notpre(RPMSENSE_SCRIPT_PRE), 0 },
1298 {
"Requires(post)", { NULL,
"post", NULL, NULL },
1300 _notpre(RPMSENSE_SCRIPT_POST), 0 },
1301 {
"Requires(preun)", { NULL,
"preun", NULL, NULL },
1303 _notpre(RPMSENSE_SCRIPT_PREUN), 0 },
1304 {
"Requires(postun)", { NULL,
"postun", NULL, NULL },
1306 _notpre(RPMSENSE_SCRIPT_POSTUN), 0 },
1307 {
"Requires", {
"%{?__find_requires}", NULL, NULL, NULL },
1309 RPMSENSE_FIND_REQUIRES|RPMSENSE_TRIGGERIN|RPMSENSE_TRIGGERUN|RPMSENSE_TRIGGERPOSTUN|RPMSENSE_TRIGGERPREIN, 0 },
1310 {
"Conflicts", {
"%{?__find_conflicts}", NULL, NULL, NULL },
1313 {
"Obsoletes", {
"%{?__find_obsoletes}", NULL, NULL, NULL },
1316 { NULL, { NULL, NULL, NULL, NULL }, 0, 0, 0, 0, 0 }
1338 for (dm = DepMsgs; dm->
msg != NULL; dm++) {
1339 if ((
int)dm->
ntag != -1) {
1356 if (!((Flags & dm->
mask) ^ dm->
xor))
1382 int failnonzero = 0;
1394 for (dm = DepMsgs; dm->
msg != NULL; dm++) {
1409 tagflags = RPMSENSE_FIND_PROVIDES;
1415 tagflags = RPMSENSE_FIND_REQUIRES;
1422 xx =
rpmfcExec(dm->
argv, iob_stdin, &iob_stdout, failnonzero);
1431 if (iob_stdout == NULL) {
1459 {
"Requires(pre)", {
"%{?__scriptlet_requires}", NULL, NULL, NULL },
1461 RPMSENSE_SCRIPT_PRE, 0 },
1462 {
"Requires(post)", {
"%{?__scriptlet_requires}", NULL, NULL, NULL },
1464 RPMSENSE_SCRIPT_POST, 0 },
1465 {
"Requires(preun)", {
"%{?__scriptlet_requires}", NULL, NULL, NULL },
1467 RPMSENSE_SCRIPT_PREUN, 0 },
1468 {
"Requires(postun)", {
"%{?__scriptlet_requires}", NULL, NULL, NULL },
1470 RPMSENSE_SCRIPT_POSTUN, 0 },
1471 { NULL, { NULL, NULL, NULL, NULL }, 0, 0, 0, 0, 0 }
1484 HE_t he = memset(
alloca(
sizeof(*he)), 0,
sizeof(*he));
1486 rpmiob iob_stdout = NULL;
1488 int failnonzero = 0;
1492 for (dm = ScriptMsgs; dm->
msg != NULL; dm++) {
1497 tagflags = RPMSENSE_FIND_REQUIRES | dm->
mask;
1502 if (!xx || he->
p.
str == NULL)
1504 xx = strcmp(he->
p.
str,
"/bin/sh") && strcmp(he->
p.
str,
"/bin/bash");
1512 if (!xx || he->
p.
str == NULL)
1519 xx =
rpmfcExec(dm->
argv, iob_stdin, &iob_stdout, failnonzero);
1525 if (s != NULL && *s !=
'\0') {
1528 while ((se = strstr(se,
"executable(/")) != NULL) {
1533 se = strchr(se,
')');
1539 rc = spec->
_parseRCPOT(spec, pkg, s, tag, 0, tagflags);
1552 HE_t he = memset(
alloca(
sizeof(*he)), 0,
sizeof(*he));
1553 const Spec spec = specp;
1565 int genConfigDeps, internaldeps;
1580 if (internaldeps == 0) {
1588 if (internaldeps > 1)
1593 av =
xcalloc(ac+1,
sizeof(*av));
1594 fmode =
xcalloc(ac+1,
sizeof(*fmode));
1616 {
const char * buildRootURL;
1617 const char * buildRoot;
1619 (void)
urlPath(buildRootURL, &buildRoot);
1620 if (buildRoot && !strcmp(buildRoot,
"/")) buildRoot = NULL;
1621 fc->brlen = (buildRoot ? strlen(buildRoot) : 0);
1622 buildRootURL =
_free(buildRootURL);
1626 if (!fc->skipProv) {
1639 if (genConfigDeps) {
1643 assert(EVR != NULL);
1644 sprintf(buf,
"config(%s)", N);
1666 if (genConfigDeps) {
1670 assert(EVR != NULL);
1671 sprintf(buf,
"config(%s)", N);
1691 assert(ac == (
int)he->
c);
1692 if (he->
p.
ptr != NULL && he->
c > 0) {
1696 for (i = 0; i < (int)he->
c; i++)
1707 if (he->
p.
ptr != NULL && he->
c > 0) {
1716 assert(ac == (
int)he->
c);
1717 if (he->
p.
ptr != NULL && he->
c > 0) {
1722 if (fc->provides != NULL && (he->
c =
rpmdsCount(fc->provides)) > 0
1727 he->
p.
argv = fc->provides->N;
1734 he->
p.
argv = fc->provides->EVR;
1735 assert(he->
p.
ptr != NULL);
1741 assert(he->
p.
ptr != NULL);
1747 if (fc->requires != NULL && (he->
c =
rpmdsCount(fc->requires)) > 0
1752 he->
p.
argv = fc->requires->N;
1753 assert(he->
p.
ptr != NULL);
1760 he->
p.
argv = fc->requires->EVR;
1761 assert(he->
p.
ptr != NULL);
1767 assert(he->
p.
ptr != NULL);
1777 if (he->
p.
ptr != NULL) {
1786 assert(ac == (
int)he->
c);
1787 if (he->
p.
ptr != NULL) {
1795 assert(ac == (
int)he->
c);
1796 if (he->
p.
ptr != NULL) {
1804 sprintf(msg,
"final: files %u cdict[%d] %u%% ddictx[%d]", (
unsigned int)fc->nfiles,
argvCount(fc->cdict), (
unsigned int)((100 * fc->fknown)/fc->nfiles),
argiCount(fc->ddictx));
1809 fmode =
_free(fmode);
1824 fc->fcdictx =
argiFree(fc->fcdictx);
1825 fc->fddictx =
argiFree(fc->fddictx);
1826 fc->fddictn =
argiFree(fc->fddictn);
1832 fc->provides = NULL;
1834 fc->requires = NULL;
1852 if (_rpmfcPool == NULL) {