5 #define _RPMEVR_INTERNAL
9 #define _RPMFC_INTERNAL
12 #define _RPMNS_INTERNAL
15 #define _RPMDS_INTERNAL
38 argv =
xrealloc(argv, (argc + ac + 1) *
sizeof(*argv));
40 for (i = 0; i < ac; i++)
42 argv[argc + ac] = NULL;
59 const char * writePtr,
int writeBytesLeft,
73 oldhandler = signal(SIGPIPE, SIG_IGN);
76 toProg[0] = toProg[1] = 0;
78 fromProg[0] = fromProg[1] = 0;
79 (void) pipe(fromProg);
81 if (!(child = fork())) {
82 (void) close(toProg[1]);
83 (void) close(fromProg[0]);
85 (void) dup2(toProg[0], STDIN_FILENO);
86 (void) dup2(fromProg[1], STDOUT_FILENO);
88 (void) close(toProg[0]);
89 (void) close(fromProg[1]);
96 argv[0], (
unsigned)getpid());
99 (void) execvp(argv[0], (
char *
const *)argv);
102 argv[0], strerror(
errno));
107 argv[0], strerror(
errno));
111 (void) close(toProg[0]);
112 (void) close(fromProg[1]);
115 (void) fcntl(fromProg[0], F_SETFL, O_NONBLOCK);
116 (void) fcntl(toProg[1], F_SETFL, O_NONBLOCK);
130 if (fromProg[0] >= 0) {
131 FD_SET(fromProg[0], &ibits);
133 if (toProg[1] >= 0) {
134 FD_SET(toProg[1], &obits);
139 nfd = ((fromProg[0] > toProg[1]) ? fromProg[0] : toProg[1]);
140 if ((rc = select(nfd, &ibits, &obits, NULL, &tv)) < 0) {
147 if (toProg[1] >= 0 && FD_ISSET(toProg[1], &obits)) {
148 if (writePtr && writeBytesLeft > 0) {
149 if ((nbw = write(toProg[1], writePtr,
150 (1024<writeBytesLeft) ? 1024 : writeBytesLeft)) < 0) {
151 if (
errno != EAGAIN) {
152 perror(
"getOutputFrom()");
157 writeBytesLeft -= nbw;
159 }
else if (toProg[1] >= 0) {
160 (void) close(toProg[1]);
167 {
char buf[BUFSIZ+1];
168 while ((nbr = read(fromProg[0], buf,
sizeof(buf)-1)) > 0) {
176 done = (nbr == 0 || (nbr < 0 &&
errno != EAGAIN));
182 (void) close(toProg[1]);
183 if (fromProg[0] >= 0)
184 (void) close(fromProg[0]);
186 (void) signal(SIGPIPE, oldhandler);
190 reaped = waitpid(child, &status, 0);
192 (
unsigned)child, (
unsigned)reaped, status);
194 if (failNonZero && (!WIFEXITED(status) || WEXITSTATUS(status))) {
196 int rc = (WIFEXITED(status) ? WEXITSTATUS(status) : -1);
202 if (writeBytesLeft) {
212 const char * s = NULL;
218 const char * buf_stdin = NULL;
219 int buf_stdin_len = 0;
234 xx = poptParseArgvString(s, &pac, (
const char ***)&pav);
235 if (!(xx == 0 && pac > 0 && pav != NULL))
246 if (sb_stdin != NULL) {
248 buf_stdin_len = strlen(buf_stdin);
252 sb =
getOutputFrom(NULL, xav, buf_stdin, buf_stdin_len, failnonzero);
255 if (sb_stdoutp != NULL) {
308 sprintf(buf,
"%08d%c %s %s 0x%08x", ix, deptype,
318 regex_t *compiled=NULL;
322 poptParseArgvString(s,count,(
const char ***)&patterns);
334 compiled=malloc(
sizeof(regex_t)*(*count));
336 for(i=0;i<*count;i++){
337 r=regcomp(&compiled[j],patterns[i],REG_NOSUB);
341 _(
"Compilation of regular expresion '%s'"
342 " (expanded from '%s') failed. Skipping it.\n"),
346 patterns=
_free(patterns);
348 compiled=
_free(compiled);
359 for(j = 0; j < count; j++) {
361 _(
"Checking %c: '%s' against _noauto expr. #%i\n"), deptype, str, j);
362 if (!regexec(®exps[j], str, 0, NULL, 0)) {
364 _(
"Skipping %c: '%s' as it matches _noauto expr. #%i\n"), deptype, str, j);
376 regfree(®exps[i]);
377 return _free(regexps);
391 const char * fn = fc->fn[fc->ix];
399 int_32 Flags, dsContext, tagN;
405 regex_t * noauto = NULL;
413 if (fc->skipProv || !fc->findprov)
415 noauto = fc->noautoprov;
416 noauto_c = fc->noautoprov_c;
417 xx =
snprintf(buf,
sizeof(buf),
"%%{?__%s_provides}", nsdep);
418 depsp = &fc->provides;
419 dsContext = RPMSENSE_FIND_PROVIDES;
423 if (fc->skipReq || !fc->findreq)
425 noauto = fc->noautoreq;
426 noauto_c = fc->noautoreq_c;
427 xx =
snprintf(buf,
sizeof(buf),
"%%{?__%s_requires}", nsdep);
428 depsp = &fc->requires;
429 dsContext = RPMSENSE_FIND_REQUIRES;
433 buf[
sizeof(buf)-1] =
'\0';
441 xx =
rpmfcExec(av, sb_stdin, &sb_stdout, 0);
445 if (xx == 0 && sb_stdout != NULL) {
450 for (i = 0; i < pac; i++) {
455 if (pav[i+1] && strchr(
"=<>", *pav[i+1])) {
457 for (s = pav[i]; *s; s++) {
486 if (!fc->tracked && deptype ==
'P' && *EVR !=
'\0') {
488 "rpmlib(VersionedDependencies)",
"3.0.3-1",
627 for (fct =
rpmfcTokens; fct->token != NULL; fct++) {
628 if (strstr(fmstr, fct->token) == NULL)
630 fcolor |= fct->colors;
648 if (fp == NULL) fp = stderr;
651 fprintf(fp,
"===================================== %s\n", msg);
657 for (fx = 0; fx < fc->nfiles; fx++) {
658 assert(fx < fc->fcdictx->nvals);
659 cx = fc->fcdictx->vals[fx];
660 assert(fx < fc->fcolor->nvals);
661 fcolor = fc->fcolor->vals[fx];
663 fprintf(fp,
"%3d %s", fx, fc->fn[fx]);
665 fprintf(fp,
"\t0x%x", fc->fcolor->vals[fx]);
667 fprintf(fp,
"\t%s", fc->cdict[cx]);
670 if (fc->fddictx == NULL || fc->fddictn == NULL)
673 assert(fx < fc->fddictx->nvals);
674 dx = fc->fddictx->vals[fx];
675 assert(fx < fc->fddictn->nvals);
676 ndx = fc->fddictn->vals[fx];
680 unsigned char deptype;
683 ix = fc->ddictx->vals[dx++];
684 deptype = ((ix >> 24) & 0xff);
689 assert(depval != NULL);
693 assert(ix < nprovides);
701 assert(ix < nrequires);
709 fprintf(fp,
"\t%s\n", depval);
719 fc->fcdictx =
argiFree(fc->fcdictx);
720 fc->fddictx =
argiFree(fc->fddictx);
721 fc->fddictn =
argiFree(fc->fddictn);
754 const char * fn = fc->fn[fc->ix];
765 {
struct stat sb, * st = &sb;
766 if (stat(fn, st) != 0)
768 is_executable = (st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH));
772 if (fp == NULL || ferror(fp)) {
773 if (fp) (void) fclose(fp);
779 for (i = 0; i < 10; i++) {
781 s = fgets(buf,
sizeof(buf) - 1, fp);
782 if (s == NULL || ferror(fp) || feof(fp))
784 s[
sizeof(buf)-1] =
'\0';
785 if (!(s[0] ==
'#' && s[1] ==
'!'))
789 while (*s && strchr(
" \t\n\r", *s) != NULL)
796 for (se = s+1; *se; se++) {
797 if (strchr(
" \t\n\r", *se) != NULL)
803 if (is_executable && fc->findreq && !
rpmfcMatchRegexps(fc->noautoreq, fc->noautoreq_c, s,
'R')) {
817 if (!strcmp(bn,
"perl"))
819 else if (!strncmp(bn,
"python",
sizeof(
"python")-1))
821 else if (!strncmp(bn,
"php",
sizeof(
"php")-1))
831 if (strncmp(fn,
"/usr/share/doc/",
sizeof(
"/usr/share/doc/")-1)) {
834 if (is_executable || (fc->fcolor->vals[fc->ix] &
RPMFC_MODULE))
866 if (fc->fcolor->vals[fc->ix] &
RPMFC_PHP) {
898 fprintf(stderr,
"*** %s(%p, %p) %s\n", __FUNCTION__, context, ds,
tagName(
rpmdsTagN(ds)));
904 if (fc->findprov && !
rpmfcMatchRegexps(fc->noautoprov, fc->noautoprov_c, ds->N[0],
'P')) {
915 if (fc->findreq && !
rpmfcMatchRegexps(fc->noautoreq, fc->noautoreq_c, ds->N[0],
'R')) {
938 const char * fn = fc->fn[fc->ix];
943 if (fp == NULL || ferror(fp)) {
944 if (fp) (void) fclose(fp);
965 const char * fn = fc->fn[fc->ix];
1003 unsigned char deptype;
1014 regex_t *noautoreqdep;
1025 for (i = 0; i < nddict; i++) {
1029 ix = strtol(s, &se, 10);
1034 while (*se && *se !=
' ')
1038 while (*se && *se !=
' ')
1041 Flags = strtol(se, NULL, 16);
1043 if (deptype!=
'R')
continue;
1046 if (EVR && EVR[0]) {
1050 for(j=0;j<noautoreqdep_c;j++)
1051 if (!regexec(&noautoreqdep[j],N,0,NULL,0)) {
1053 _(
"skipping %s requirement processing"
1054 " (matches noautoreqdep pattern #%i)\n"),N,j);
1057 if (j<noautoreqdep_c)
continue;
1077 if (!strcmp(hname,N)) {
1106 unsigned char deptype;
1116 regex_t *noautoprovfiles = NULL;
1117 int noautoprovfiles_c;
1118 regex_t *noautoreqfiles = NULL;
1119 int noautoreqfiles_c;
1120 const char *buildroot;
1123 fc->noautoprov = NULL;
1124 fc->noautoreq = NULL;
1126 buildroot =
rpmExpand(
"%{buildroot}",NULL);
1127 buildroot_l = strlen(buildroot);
1137 for (fc->ix = 0; fc->fn[fc->ix] != NULL; fc->ix++) {
1141 {
const char *fn = strstr(fc->fn[fc->ix],
"/usr/lib");
1143 fn +=
sizeof(
"/usr/lib")-1;
1144 if (fn[0] ==
'6' && fn[1] ==
'4')
1146 if (!strncmp(fn,
"/python",
sizeof(
"/python")-1))
1151 if (fc->fcolor->vals[fc->ix])
1152 for (fcat = rpmfcApplyTable; fcat->
func != NULL; fcat++) {
1153 if (!(fc->fcolor->vals[fc->ix] & fcat->
colormask))
1157 if (strncmp(fc->fn[fc->ix],buildroot,buildroot_l)==0) {
1158 for(j = 0; j < noautoprovfiles_c; j++) {
1159 if (!regexec(&noautoprovfiles[j],
1160 fc->fn[fc->ix] + buildroot_l, 0, NULL, 0)) {
1162 _(
"skipping %s provides detection"
1163 " (matches noautoprovfiles pattern #%i)\n"),
1169 for(j = 0; j < noautoreqfiles_c; j++) {
1170 if (!regexec(&noautoreqfiles[j],
1171 fc->fn[fc->ix] + buildroot_l, 0, NULL, 0)) {
1173 _(
"skipping %s requires detection"
1174 " (matches noautoreqfiles pattern #%i)\n"),
1182 xx = (*fcat->
func) (fc);
1189 #ifdef AUTODEP_PKGNAMES
1197 for (i = 0; i < nddict; i++) {
1201 ix = strtol(s, &se, 10);
1206 while (*se && *se !=
' ')
1210 while (*se && *se !=
' ')
1213 Flags = strtol(se, NULL, 16);
1221 skipping = fc->skipProv;
1227 skipping = fc->skipReq;
1242 val = (deptype << 24) | (dix & 0x00ffffff);
1243 xx =
argiAdd(&fc->ddictx, -1, val);
1249 if (fc->fddictn && fc->fddictn->vals && !skipping)
1250 fc->fddictn->vals[ix]++;
1261 const char * s, * se;
1265 const char * magicfile;
1266 int msflags = MAGIC_CHECK;
1269 if (fc == NULL || argv == NULL)
1272 magicfile =
rpmExpand(
"%{?_rpmfc_magic_path}", NULL);
1273 if (magicfile == NULL || *magicfile ==
'\0' || *magicfile ==
'%')
1279 xx =
argiAdd(&fc->fddictx, fc->nfiles-1, 0);
1280 xx =
argiAdd(&fc->fddictn, fc->nfiles-1, 0);
1284 xx =
argvAdd(&fc->cdict,
"directory");
1286 ms = magic_open(msflags);
1289 rpmError(xx,
_(
"magic_open(0x%x) failed: %s\n"),
1290 msflags, strerror(
errno));
1294 xx = magic_load(ms, magicfile);
1297 rpmError(xx,
_(
"magic_load(ms, \"%s\") failed: %s\n"),
1298 magicfile, magic_error(ms));
1302 for (fc->ix = 0; fc->ix < fc->nfiles; fc->ix++) {
1304 int_16 mode = (fmode ? fmode[fc->ix] : 0);
1307 urltype =
urlPath(argv[fc->ix], &s);
1308 assert(s != NULL && *s ==
'/');
1312 switch (mode & S_IFMT) {
1313 case S_IFCHR: ftype =
"character special";
break;
1314 case S_IFBLK: ftype =
"block special";
break;
1315 #if defined(S_IFIFO)
1316 case S_IFIFO: ftype =
"fifo (named pipe)";
break;
1318 #if defined(S_IFSOCK)
1320 case S_IFSOCK: ftype =
"socket";
break;
1328 #define _suffix(_s, _x) \
1329 (slen >= sizeof(_x) && !strcmp((_s)+slen-(sizeof(_x)-1), (_x)))
1333 ftype =
"Perl5 module source text";
1337 ftype =
"Java archive file";
1340 else if (
_suffix(s,
".class"))
1341 ftype =
"Java class file";
1345 ftype =
"libtool library file";
1349 ftype =
"pkgconfig file";
1353 ftype =
"PHP script text";
1356 else if (
_suffix(s,
".desktop"))
1357 ftype =
"Desktop Entry";
1360 else if (slen >= fc->brlen+
sizeof(
"/dev/") && !strncmp(s+fc->brlen,
"/dev/",
sizeof(
"/dev/")-1))
1363 char *old_ctype =
setlocale(LC_CTYPE, NULL);
1364 char *old_collate =
setlocale(LC_COLLATE, NULL);
1367 old_ctype =
xstrdup(old_ctype);
1371 old_collate =
xstrdup(old_collate);
1375 ftype = magic_file(ms, s);
1387 if (ftype == NULL) {
1389 rpmError(xx,
_(
"magic_file(ms, \"%s\") failed: mode %06o %s\n"),
1390 s, mode, magic_error(ms));
1391 assert(ftype != NULL);
1408 xx =
argiAdd(&fc->fcolor, fc->ix, fcolor);
1418 for (fc->ix = 0; fc->ix < fc->nfiles; fc->ix++) {
1424 xx =
argiAdd(&fc->fcdictx, fc->ix, (dav - fc->cdict));
1427 xx =
argiAdd(&fc->fcdictx, fc->ix, 0);
1438 magicfile =
_free(magicfile);
1465 {
"Provides", {
"%{?__find_provides}", NULL, NULL, NULL },
1468 {
"Requires(interp)", { NULL,
"interp", NULL, NULL },
1470 _notpre(RPMSENSE_INTERP), 0 },
1471 {
"Requires(rpmlib)", { NULL,
"rpmlib", NULL, NULL },
1473 _notpre(RPMSENSE_RPMLIB), 0 },
1474 {
"Requires(verify)", { NULL,
"verify", NULL, NULL },
1476 RPMSENSE_SCRIPT_VERIFY, 0 },
1477 {
"Requires(pre)", { NULL,
"pre", NULL, NULL },
1479 _notpre(RPMSENSE_SCRIPT_PRE), 0 },
1480 {
"Requires(post)", { NULL,
"post", NULL, NULL },
1482 _notpre(RPMSENSE_SCRIPT_POST), 0 },
1483 {
"Requires(preun)", { NULL,
"preun", NULL, NULL },
1485 _notpre(RPMSENSE_SCRIPT_PREUN), 0 },
1486 {
"Requires(postun)", { NULL,
"postun", NULL, NULL },
1488 _notpre(RPMSENSE_SCRIPT_POSTUN), 0 },
1489 {
"Requires", {
"%{?__find_requires}", NULL, NULL, NULL },
1491 RPMSENSE_FIND_REQUIRES|RPMSENSE_TRIGGERIN|RPMSENSE_TRIGGERUN|RPMSENSE_TRIGGERPOSTUN|RPMSENSE_TRIGGERPREIN, 0 },
1492 {
"Conflicts", {
"%{?__find_conflicts}", NULL, NULL, NULL },
1495 {
"Obsoletes", {
"%{?__find_obsoletes}", NULL, NULL, NULL },
1498 { NULL, { NULL, NULL, NULL, NULL }, 0, 0, 0, 0, 0 }
1519 for (dm = DepMsgs; dm->
msg != NULL; dm++) {
1520 if (dm->
ntag != -1) {
1536 if (!((Flags & dm->
mask) ^ dm->
xor))
1561 int failnonzero = 0;
1573 for (dm = DepMsgs; dm->
msg != NULL; dm++) {
1587 tagflags = RPMSENSE_FIND_PROVIDES;
1593 tagflags = RPMSENSE_FIND_REQUIRES;
1601 xx =
rpmfcExec(dm->
argv, sb_stdin, &sb_stdout, failnonzero);
1611 if (sb_stdout == NULL) {
1638 {
"Requires(pre)", {
"%{?__scriptlet_requires}", NULL, NULL, NULL },
1640 RPMSENSE_SCRIPT_PRE, 0 },
1641 {
"Requires(post)", {
"%{?__scriptlet_requires}", NULL, NULL, NULL },
1643 RPMSENSE_SCRIPT_POST, 0 },
1644 {
"Requires(preun)", {
"%{?__scriptlet_requires}", NULL, NULL, NULL },
1646 RPMSENSE_SCRIPT_PREUN, 0 },
1647 {
"Requires(postun)", {
"%{?__scriptlet_requires}", NULL, NULL, NULL },
1649 RPMSENSE_SCRIPT_POSTUN, 0 },
1650 { NULL, { NULL, NULL, NULL, NULL }, 0, 0, 0, 0, 0 }
1666 int failnonzero = 0;
1670 for (dm = ScriptMsgs; dm->
msg != NULL; dm++) {
1676 tagflags = RPMSENSE_FIND_REQUIRES | dm->
mask;
1680 if (!hge(pkg->
header, dm->
ntag, NULL, &s, NULL) || s == NULL)
1682 if (strcmp(s,
"/bin/sh") && strcmp(s,
"/bin/bash"))
1687 if (!hge(pkg->
header, dm->
vtag, NULL, &s, NULL) || s == NULL)
1694 xx =
rpmfcExec(dm->
argv, sb_stdin, &sb_stdout, failnonzero);
1701 if (s != NULL && *s !=
'\0') {
1704 while ((se = strstr(se,
"executable(/")) != NULL) {
1709 se = strchr(se,
')');
1715 rc = spec->
_parseRCPOT(spec, pkg, s, tag, 0, tagflags);
1729 const Spec spec = specp;
1742 int genConfigDeps, internaldeps;
1757 if (internaldeps == 0) {
1765 if (internaldeps > 1)
1769 av =
xcalloc(ac+1,
sizeof(*av));
1770 fmode =
xcalloc(ac+1,
sizeof(*fmode));
1794 {
const char * buildRootURL;
1795 const char * buildRoot;
1797 (void)
urlPath(buildRootURL, &buildRoot);
1798 if (buildRoot && !strcmp(buildRoot,
"/")) buildRoot = NULL;
1799 fc->brlen = (buildRoot ? strlen(buildRoot) : 0);
1800 buildRootURL =
_free(buildRootURL);
1804 if (!fc->skipProv) {
1813 if (genConfigDeps) {
1817 assert(EVR != NULL);
1818 sprintf(buf,
"config(%s)", N);
1835 if (genConfigDeps) {
1839 assert(EVR != NULL);
1840 sprintf(buf,
"config(%s)", N);
1855 p = (
const void **)
argiData(fc->fcolor);
1858 if (p != NULL && c > 0) {
1863 for (i = 0; i < c; i++)
1870 p = (
const void **)
argvData(fc->cdict);
1872 if (p != NULL && c > 0)
1877 p = (
const void **)
argiData(fc->fcdictx);
1880 if (p != NULL && c > 0)
1886 if (fc->provides != NULL && (c =
rpmdsCount(fc->provides)) > 0 && !fc->skipProv) {
1887 p = (
const void **) fc->provides->N;
1892 p = (
const void **) fc->provides->EVR;
1896 p = (
const void **) fc->provides->Flags;
1906 if (fc->requires != NULL && (c =
rpmdsCount(fc->requires)) > 0 && !fc->skipReq) {
1907 p = (
const void **) fc->requires->N;
1912 p = (
const void **) fc->requires->EVR;
1916 p = (
const void **) fc->requires->Flags;
1925 p = (
const void **)
argiData(fc->ddictx);
1932 p = (
const void **)
argiData(fc->fddictx);
1939 p = (
const void **)
argiData(fc->fddictn);
1950 sprintf(msg,
"final: files %d cdict[%d] %d%% ddictx[%d]", fc->nfiles,
argvCount(fc->cdict), ((100 * fc->fknown)/fc->nfiles),
argiCount(fc->ddictx));
1955 fmode =
_free(fmode);