9 #define isblank(_c) ((char)(_c) == ' ' || (char)(_c) == '\t')
11 #define iseol(_c) ((char)(_c) == '\n' || (char)(_c) == '\r')
13 #define STREQ(_t, _f, _fn) ((_fn) == (sizeof(_t)-1) && !strncmp((_t), (_f), (_fn)))
17 #include <sys/types.h>
27 #define rpmlog fprintf
28 #define RPMLOG_ERR stderr
29 #define RPMLOG_WARNING stderr
33 #define vmefail(_nb) (exit(1), NULL)
36 #define urlPath(_xr, _r) (*(_r) = (_xr), URL_IS_PATH)
37 #define xisalnum(_c) isalnum(_c)
38 #define xisalpha(_c) isalpha(_c)
39 #define xisdigit(_c) isdigit(_c)
40 #define xisspace(_c) isspace(_c)
43 #define Fopen(_path, _fmode) fopen(_path, "r");
45 #define Fstrerror(_fd) strerror(errno)
49 #define fdGetFILE(_fd) (_fd)
52 _free(
const void * p)
55 if (p != NULL) free((
void *)p);
69 #define _RPMLUA_INTERNAL
76 #include <rpmpython.h>
84 #define _MACRO_INTERNAL
90 #if defined(WITH_FICL) || defined(WITH_JS) || defined(WITH_PERLEMBED) || defined(WITH_PYTHONEMBED) || defined(WITH_RUBYEMBED) || defined(WITH_TCL)
91 static int _globalI = 1;
94 #if defined(__LCLINT__)
96 extern const unsigned short int **__ctype_b_loc (
void) ;
135 #define SAVECHAR(_mb, _c) { *(_mb)->t = (char) (_c), (_mb)->t++, (_mb)->nb--; }
139 #define _MAX_MACRO_DEPTH 16
143 #define _PRINT_MACRO_TRACE 0
147 #define _PRINT_EXPAND_TRACE 0
152 #define MACRO_CHUNK_SIZE 16
182 if (ame == NULL && bme == NULL)
188 return strcmp(ame->name, bme->name);
199 if (mc->macroTable == NULL) {
202 xmalloc(
sizeof(*(mc->macroTable)) * mc->macrosAllocated);
207 xrealloc(mc->macroTable,
sizeof(*(mc->macroTable)) *
208 mc->macrosAllocated);
210 memset(&mc->macroTable[mc->firstFree], 0,
MACRO_CHUNK_SIZE *
sizeof(*(mc->macroTable)));
223 if (mc == NULL || mc->macroTable == NULL)
226 qsort(mc->macroTable, mc->firstFree,
sizeof(mc->macroTable[0]),
230 for (i = 0; i < mc->firstFree; i++) {
231 if (mc->macroTable[i] != NULL)
238 #if !defined(DEBUG_MACROS)
247 nb = strlen(me->name) +
sizeof(
"%") - 1;
249 nb += strlen(me->opts) +
sizeof(
"()") - 1;
251 nb += strlen(me->body) +
sizeof(
"\t") - 1;
274 if (fp == NULL) fp = stderr;
276 fprintf(fp,
"========================\n");
277 if (mc->macroTable != NULL) {
279 for (i = 0; i < mc->firstFree; i++) {
281 if ((me = mc->macroTable[i]) == NULL) {
286 fprintf(fp,
"%3d%c %s", me->level,
287 (me->used > 0 ?
'=' :
':'), me->name);
288 if (me->opts && *me->opts)
289 fprintf(fp,
"(%s)", me->opts);
290 if (me->body && *me->body)
291 fprintf(fp,
"\t%s", me->body);
296 fprintf(fp,
_(
"======================== active %d empty %d\n"),
300 #if !defined(DEBUG_MACROS)
316 return mc->firstFree;
318 av =
xcalloc( (mc->firstFree+1),
sizeof(mc->macroTable[0]));
319 if (mc->macroTable != NULL)
320 for (i = 0; i < mc->firstFree; i++) {
322 me = mc->macroTable[i];
323 if (used > 0 && me->used < used)
325 if (used == 0 && me->used != 0)
327 #if !defined(DEBUG_MACROS)
328 if (mire != NULL &&
mireRegexec(mire, me->name, 0) < 0)
334 *avp = av =
xrealloc(av, (ac+1) *
sizeof(*av));
357 if (mc->macroTable == NULL || mc->firstFree == 0)
361 char * t = strncpy(
alloca(namelen + 1), name, namelen);
366 key = memset(
alloca(
sizeof(*key)), 0,
sizeof(*key));
368 key->name = (
char *)name;
370 ret = (
MacroEntry *) bsearch(&key, mc->macroTable, mc->firstFree,
401 if (fgets(q, (
int)size, f) == NULL)
405 for (q += nb - 1; nb > 0 &&
iseol(*q); q--)
407 for (; p <= q; p++) {
419 case '{': p++, bc++;
break;
420 case '(': p++, pc++;
break;
421 case '%': p++;
break;
424 case '{':
if (bc > 0) bc++;
break;
425 case '}':
if (bc > 0) bc--;
break;
426 case '(':
if (pc > 0) pc++;
break;
427 case ')':
if (pc > 0) pc--;
break;
430 if (nb == 0 || (*q !=
'\\' && !bc && !pc) || *(q+1) ==
'\0') {
439 return (nread > 0 ? buf : NULL);
457 while ((c = *p++) !=
'\0') {
463 if (--lvl <= 0)
return --p;
467 return (
const char *)NULL;
482 const char *ellipsis;
486 fprintf(stderr,
_(
"%3d>%*s(empty)"), mb->
depth,
487 (2 * mb->
depth + 1),
"");
495 for (senl = se; *senl && !
iseol(*senl); senl++)
499 choplen = 61 - (2 * mb->
depth);
500 if ((senl - s) > choplen) {
507 fprintf(stderr,
"%3d>%*s%%%.*s^", mb->
depth,
508 (2 * mb->
depth + 1),
"", (
int)(se - s), s);
509 if (se[1] !=
'\0' && (senl - (se+1)) > 0)
510 fprintf(stderr,
"%-.*s%s", (
int)(senl - (se+1)), se+1, ellipsis);
511 fprintf(stderr,
"\n");
525 const char *ellipsis;
529 fprintf(stderr,
_(
"%3d<%*s(empty)\n"), mb->
depth, (2 * mb->
depth + 1),
"");
534 while (te > t &&
iseol(te[-1]))
541 while ((tenl = strchr(t,
'\n')) && tenl < te)
545 choplen = 61 - (2 * mb->
depth);
546 if ((te - t) > choplen) {
552 fprintf(stderr,
"%3d<%*s", mb->
depth, (2 * mb->
depth + 1),
"");
554 fprintf(stderr,
"%.*s%s", (
int)(te - t), t, ellipsis);
555 fprintf(stderr,
"\n");
558 #define SKIPBLANK(_s, _c) \
560 while (((_c) = (int) *(_s)) && isblank(_c)) \
564 #define SKIPNONBLANK(_s, _c) \
566 while (((_c) = (int) *(_s)) && !(isblank(_c) || iseol(_c))) \
570 #define COPYNAME(_ne, _s, _c) \
571 { SKIPBLANK(_s,_c); \
572 while(((_c) = (int) *(_s)) && (xisalnum(_c) || (_c) == (int) '_')) \
573 *(_ne)++ = *(_s)++; \
577 #define COPYOPTS(_oe, _s, _c) \
578 { while(((_c) = (int) *(_s)) && (_c) != (int) ')') \
579 *(_oe)++ = *(_s)++; \
596 const char *s = mb->
s;
600 memset(sbuf, 0, (flen + 1));
602 strncpy(sbuf, f, flen);
619 expandS(
MacroBuf mb,
char * tbuf,
size_t tbuflen)
623 const char *t = mb->
t;
648 const char *s = mb->
s;
655 memset(tbuf, 0, (ulen + 1));
664 strncpy(u, tbuf, (ulen - mb->
nb + 1));
686 char * buf =
alloca(bufn);
691 strncpy(buf, cmd, clen);
697 if ((shf = popen(buf,
"r")) == NULL)
699 while(mb->
nb > 0 && (c = fgetc(shf)) != EOF)
704 while (
iseol(mb->
t[-1])) {
755 if (c == (
int)
'{') {
756 if ((se =
matchchar(s, (
char) c,
'}')) == NULL) {
758 _(
"Macro %%%s has unterminated body\n"), n);
763 strncpy(b, s, (se - s));
770 while (*s && (bc || pc || !
iseol(*s))) {
780 case '{': *be++ = *s++; bc++;
break;
781 case '(': *be++ = *s++; pc++;
break;
782 case '%': *be++ = *s++;
break;
785 case '{':
if (bc > 0) bc++;
break;
786 case '}':
if (bc > 0) bc--;
break;
787 case '(':
if (pc > 0) pc++;
break;
788 case ')':
if (pc > 0) pc--;
break;
796 _(
"Macro %%%s has unterminated body\n"), n);
803 while (--be >= b && (c = (
int) *be) && (
isblank(c) ||
iseol(c)))
815 if (!((c = (
int) *n) && (
xisalpha(c) || c == (
int)
'_') && (ne - n) > 2)) {
817 _(
"Macro %%%s has illegal name (%%define)\n"), n);
822 if (o && oc != (
int)
')') {
833 if (expandbody &&
expandU(mb, b, (&buf[bufn] - b))) {
861 char *n = buf, *ne = n;
872 if (!((c = (
int) *n) && (
xisalpha(c) || c == (
int)
'_') && (ne - n) > 2)) {
874 _(
"Macro %%%s has illegal name (%%undefine)\n"), n);
890 fprintf(stderr,
"%s", msg);
891 fprintf(stderr,
"\tme %p", me);
893 fprintf(stderr,
"\tname %p(%s) prev %p",
894 me->name, me->name, me->prev);
895 fprintf(stderr,
"\n");
909 const char * b,
int level)
912 MacroEntry prev = (mep && *mep ? *mep : NULL);
914 const char *
name = n;
925 me->opts = (o ?
xstrdup(o) : NULL);
926 me->body =
xstrdup(b ? b :
"");
929 me->flags = (name != n);
949 if ((*mep = me->prev) == NULL)
950 me->name =
_free(me->name);
951 me->opts =
_free(me->opts);
952 me->body =
_free(me->body);
970 if (mc == NULL || mc->macroTable == NULL)
974 for (i = 0; i < mc->firstFree; i++) {
977 mep = &mc->macroTable[i];
982 if (me->level < mb->
depth)
984 if (strlen(me->name) == 1 && strchr(
"#*0", *me->name)) {
985 if (*me->name ==
'*' && me->used > 0)
987 }
else if (!skiptest && me->used <= 0) {
990 _(
"Macro %%%s (%s) was not used below level %d\n"),
991 me->name, me->body, me->level);
1020 struct poptOption *optTbl;
1022 char *buf =
alloca(bufn);
1029 unsigned int popt_flags;
1033 b = be =
stpcpy(buf, me->name);
1041 while ((c = (
int) *se++) != (
int)
'\0' && (se-1) != lastc) {
1055 if (c == (
int)
'\0') se--;
1078 argv = (
const char **)
alloca((argc + 1) *
sizeof(*argv));
1083 for (c = 0; c < argc; c++) {
1094 popt_flags = POPT_CONTEXT_NO_EXEC;
1095 #if defined(RPM_VENDOR_OPENPKG)
1096 popt_flags |= POPT_CONTEXT_POSIXMEHARDER;
1098 if (me->opts[0] ==
'+') popt_flags |= POPT_CONTEXT_POSIXMEHARDER;
1102 if (*opts ==
'+') opts++;
1103 for (c = 0; *opts !=
'\0'; opts++)
1104 if (*opts !=
':') c++;
1107 optTbl =
xcalloc(
sizeof(*optTbl), (c + 1));
1109 if (*opts ==
'+') opts++;
1110 for (c = 0; *opts !=
'\0'; opts++) {
1111 if (*opts ==
':')
continue;
1112 optTbl[c].shortName = opts[0];
1113 optTbl[c].val = (int) opts[0];
1115 optTbl[c].argInfo = POPT_ARG_STRING;
1121 optCon = poptGetContext(argv[0], argc, argv, optTbl, popt_flags);
1123 while ((c = poptGetNextOpt(optCon)) > 0) {
1124 const char * optArg = poptGetOptArg(optCon);
1127 if (optArg != NULL) {
1132 aname[0] =
'-'; aname[1] = (char)c; aname[2] =
'\0';
1134 if (optArg != NULL) {
1135 aname[0] =
'-'; aname[1] = (char)c; aname[2] =
'*'; aname[3] =
'\0';
1140 optArg =
_free(optArg);
1146 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(c));
1150 argv = poptGetArgs(optCon);
1153 for (c = 0; argv[c] != NULL; c++)
1157 sprintf(aname,
"%d", argc);
1164 for (c = 0; c < argc; c++) {
1165 sprintf(aname,
"%d", (c + 1));
1167 if (be != b) *be++ =
' ';
1168 be =
stpcpy(be, argv[c]);
1176 optCon = poptFreeContext(optCon);
1177 optTbl =
_free(optTbl);
1194 char *buf =
alloca(bufn);
1196 strncpy(buf, msg, msglen);
1198 (void)
expandU(mb, buf, bufn);
1202 fprintf(stderr,
"%s", buf);
1216 const char * g,
size_t gn)
1221 char * buf =
alloca(bufn);
1222 char *b = NULL, *be;
1227 strncpy(buf, g, gn);
1229 (void)
expandU(mb, buf, bufn);
1231 if (fn > 5 &&
STREQ(
"patch", f, 5) &&
xisdigit((
int)f[5])) {
1233 for (c = 5; c < (int)(fn-1) && f[c] ==
'0' &&
xisdigit((
int)f[c+1]);)
1239 if (
STREQ(
"basename", f, fn)) {
1240 if ((b = strrchr(buf,
'/')) == NULL)
1244 }
else if (
STREQ(
"dirname", f, fn)) {
1245 if ((b = strrchr(buf,
'/')) != NULL)
1248 #if !defined(__LCLINT__)
1249 }
else if (
STREQ(
"realpath", f, fn)) {
1253 if ((cp =
realpath(buf, rp)) != NULL) {
1255 if ((
size_t)(l+1) <= bufn) {
1256 memcpy(buf, cp, l+1);
1261 }
else if (
STREQ(
"getenv", f, fn)) {
1263 if ((cp =
getenv(buf)) != NULL)
1265 }
else if (
STREQ(
"shrink", f, fn)) {
1270 int i, j, k, was_space = 0;
1271 for (i = 0, j = 0, k = (
int)strlen(buf); i < k; ) {
1277 else if (was_space) {
1283 buf[j++] = buf[i++];
1287 }
else if (
STREQ(
"suffix", f, fn)) {
1288 if ((b = strrchr(buf,
'.')) != NULL)
1290 }
else if (
STREQ(
"expand", f, fn)) {
1292 }
else if (
STREQ(
"verbose", f, fn)) {
1293 #if defined(RPMLOG_MASK)
1300 b = (negate) ? NULL : buf;
1302 }
else if (
STREQ(
"url2path", f, fn) ||
STREQ(
"u2p", f, fn)) {
1303 int ut =
urlPath(buf, (
const char **)&b);
1305 if (*b ==
'\0') b =
"/";
1306 }
else if (
STREQ(
"uncompress", f, fn)) {
1309 for (b = buf; (c = (int)*b) &&
isblank(c);)
1312 for (be = b; (c = (int)*be) && !
isblank(c);)
1317 switch(compressed) {
1320 sprintf(be,
"%%__cat %s", b);
1323 sprintf(be,
"%%__gzip -dc '%s'", b);
1326 sprintf(be,
"%%__bzip2 -dc '%s'", b);
1329 sprintf(be,
"%%__unzip -qq '%s'", b);
1332 sprintf(be,
"%%__lzop -dc '%s'", b);
1335 sprintf(be,
"%%__lzma -dc '%s'", b);
1338 sprintf(be,
"%%__xz -dc '%s'", b);
1342 }
else if (
STREQ(
"mkstemp", f, fn)) {
1344 for (b = buf; (c = (int)*b) &&
isblank(c);)
1347 for (be = b; (c = (int)*be) && !
isblank(c);)
1350 #if defined(HAVE_MKSTEMP)
1351 (void) close(mkstemp(b));
1355 }
else if (
STREQ(
"mkdtemp", f, fn)) {
1357 for (b = buf; (c = (int)*b) &&
isblank(c);)
1360 for (be = b; (c = (int)*be) && !
isblank(c);)
1363 #if defined(HAVE_MKDTEMP) && !defined(__LCLINT__)
1364 if (mkdtemp(b) == NULL)
1367 if ((b = tmpnam(b)) != NULL)
1368 (
void) mkdir(b, 0700);
1370 }
else if (
STREQ(
"uuid", f, fn)) {
1373 const char *uuid_data;
1381 if ((n = strspn(cp,
" \t\n")) > 0)
1383 if ((n = strcspn(cp,
" \t\n")) > 0) {
1384 uuid_version = (int)strtol(cp, (
char **)NULL, 10);
1386 if ((n = strspn(cp,
" \t\n")) > 0)
1388 if ((n = strcspn(cp,
" \t\n")) > 0) {
1392 if ((n = strspn(cp,
" \t\n")) > 0)
1394 if ((n = strcspn(cp,
" \t\n")) > 0) {
1402 if (
rpmuuidMake(uuid_version, uuid_ns, uuid_data, buf, NULL))
1407 }
else if (
STREQ(
"S", f, fn)) {
1408 for (b = buf; (c = (int)*b) &&
xisdigit(c);)
1412 sprintf(b,
"%%SOURCE%s", buf);
1415 }
else if (
STREQ(
"P", f, fn)) {
1416 for (b = buf; (c = (int) *b) &&
xisdigit(c);)
1420 sprintf(b,
"%%PATCH%s", buf);
1423 }
else if (
STREQ(
"F", f, fn)) {
1424 b = buf + strlen(buf) + 1;
1425 sprintf(b,
"file%s.file", buf);
1429 (void)
expandT(mb, b, strlen(b));
1444 rc =
expandT(mb, me->body, strlen(me->body));
1449 #if !defined(DEBUG_MACROS)
1453 #define POPT_ERROR_NOARG -10
1454 #define POPT_ERROR_BADQUOTE -15
1455 #define POPT_ERROR_MALLOC -21
1457 #define POPT_ARGV_ARRAY_GROW_DELTA 5
1460 int * argcPtr,
const char *** argvPtr)
1463 size_t nb = (argc + 1) *
sizeof(*argv);
1464 const char ** argv2;
1468 if (argc <= 0 || argv == NULL)
1470 for (i = 0; i < argc; i++) {
1471 if (argv[i] == NULL)
1473 nb += strlen(argv[i]) + 1;
1479 argv2 = (
void *) dst;
1480 dst += (argc + 1) *
sizeof(*argv);
1482 for (i = 0; i < argc; i++) {
1484 dst += strlen(strcpy(dst, argv[i])) + 1;
1505 const char ** argv =
xmalloc(
sizeof(*argv) * argvAlloced);
1507 size_t buflen = strlen(s) + 1;
1508 char * buf = memset(
alloca(buflen), 0, buflen);
1511 if (argv == NULL)
return rc;
1514 for (src = s; *src !=
'\0'; src++) {
1515 if (quote == *src) {
1517 }
else if (quote !=
'\0') {
1524 if (*src != quote) *buf++ =
'\\';
1527 }
else if (isspace(*src)) {
1528 if (*argv[argc] !=
'\0') {
1530 if (argc == argvAlloced) {
1532 argv = realloc(argv,
sizeof(*argv) * argvAlloced);
1533 if (argv == NULL)
goto exit;
1537 }
else switch (*src) {
1555 if (strlen(argv[argc])) {
1562 if (argv) free(argv);
1574 #if defined(WITH_FICL) || defined(WITH_JS) || defined(WITH_PERLEMBED) || defined(WITH_PYTHONEMBED) || defined(WITH_RUBYEMBED) || defined(WITH_TCL)
1575 static char * parseEmbedded(
const char * s,
size_t nb,
const char *** avp)
1578 char * script = NULL;
1582 for (se = s + 1; se < (s+nb); se++)
1584 default:
continue;
break;
1585 case ':':
goto bingo;
break;
1589 {
size_t na = (size_t)(se-s-1);
1594 args = memcpy(
xmalloc(na+1), s+1, na);
1604 script = memcpy(
xmalloc(nb+1), se+1, nb+1);
1627 const char *s = mb->
s, *se;
1641 _(
"Recursion depth(%d) greater than max(%d)\n"),
1648 while (rc == 0 && mb->
nb > 0 && (c = (
int)*s) != (
int)
'\0') {
1670 stackarray = chkexist = negate = 0;
1672 switch ((c = (
int) *s)) {
1674 while (*s !=
'\0' && strchr(
"!?@", *s) != NULL) {
1677 stackarray = ((stackarray + 1) % 2);
1680 negate = ((negate + 1) % 2);
1690 while((c = (
int) *se) && (
xisalnum(c) || c == (int)
'_'))
1696 if (*se ==
'*') se++;
1707 if ((c = (
int) *fe) &&
isblank(c))
1708 if ((lastc = strchr(fe,
'\n')) == NULL)
1709 lastc = strchr(fe,
'\0');
1713 if ((se =
matchchar(s, (
char)c,
')')) == NULL) {
1715 _(
"Unterminated %c: %s\n"), (
char)c, s);
1730 if ((se =
matchchar(s, (
char)c,
'}')) == NULL) {
1732 _(
"Unterminated %c: %s\n"), (
char)c, s);
1738 while (strchr(
"!?@", *f) != NULL) {
1741 stackarray = ((stackarray + 1) % 2);
1744 negate = ((negate + 1) % 2);
1752 for (fe = f; (c = (int) *fe) && !strchr(
" :}", c);)
1771 if ((fe - f) <= 0) {
1777 _(
"A %% is followed by an unparseable macro\n"));
1787 if (
STREQ(
"load", f, fn)) {
1789 char * mfn = strncpy(
alloca(gn + 1), g, gn);
1794 if (xx != 0 && chkexist == negate)
1800 if (
STREQ(
"global", f, fn)) {
1804 if (
STREQ(
"define", f, fn)) {
1808 if (
STREQ(
"undefine", f, fn)) {
1813 if (
STREQ(
"echo", f, fn) ||
1814 STREQ(
"warn", f, fn) ||
1815 STREQ(
"error", f, fn)) {
1817 if (
STREQ(
"error", f, fn))
1818 waserror = 1, rc = 1;
1819 if (g != NULL && g < ge)
1827 if (
STREQ(
"trace", f, fn)) {
1830 if (mb->
depth == 1) {
1838 if (
STREQ(
"dump", f, fn)) {
1847 if (
STREQ(
"lua", f, fn)) {
1849 rpmlua olua = memcpy(
alloca(
sizeof(*olua)), lua,
sizeof(*olua));
1850 const char *ls = s+
sizeof(
"{lua:")-1;
1851 const char *lse = se-
sizeof(
"}")+1;
1852 char *scriptbuf = (
char *)
xmalloc((lse-ls)+1);
1853 const char *printbuf;
1856 lua->storeprint = 1;
1857 lua->printbuf = NULL;
1858 lua->printbufsize = 0;
1859 lua->printbufused = 0;
1861 memcpy(scriptbuf, ls, lse-ls);
1862 scriptbuf[lse-ls] =
'\0';
1867 size_t len = strlen(printbuf);
1870 memcpy(mb->
t, printbuf, len);
1876 lua->storeprint = olua->storeprint;
1877 lua->printbuf = olua->printbuf;
1878 lua->printbufsize = olua->printbufsize;
1879 lua->printbufused = olua->printbufused;
1888 if (
STREQ(
"ficl", f, fn)) {
1889 const char ** av = NULL;
1890 char * script = parseEmbedded(s, (
size_t)(se-s), &av);
1891 rpmficl ficl = rpmficlNew(av, _globalI);
1892 const char * result = NULL;
1894 if (rpmficlRun(ficl, script, &result) !=
RPMRC_OK)
1897 if (result == NULL) result =
"FIXME";
1898 if (result != NULL && *result !=
'\0') {
1899 size_t len = strlen(result);
1902 memcpy(mb->
t, result, len);
1907 ficl = rpmficlFree(ficl);
1909 script =
_free(script);
1916 if (
STREQ(
"js", f, fn)) {
1917 const char ** av = NULL;
1918 char * script = parseEmbedded(s, (
size_t)(se-s), &av);
1919 rpmjs js = rpmjsNew(av, _globalI);
1920 const char * result = NULL;
1922 if (rpmjsRun(js, script, &result) !=
RPMRC_OK)
1925 if (result == NULL) result =
"FIXME";
1926 if (result != NULL && *result !=
'\0') {
1927 size_t len = strlen(result);
1930 memcpy(mb->
t, result, len);
1937 script =
_free(script);
1943 #ifdef WITH_PERLEMBED
1944 if (
STREQ(
"perl", f, fn)) {
1945 const char ** av = NULL;
1946 char * script = parseEmbedded(s, (
size_t)(se-s), &av);
1947 rpmperl perl = rpmperlNew(av, _globalI);
1948 const char * result = NULL;
1950 if (rpmperlRun(perl, script, &result) !=
RPMRC_OK)
1953 if (result == NULL) result =
"FIXME";
1954 if (result != NULL && *result !=
'\0') {
1955 size_t len = strlen(result);
1958 memcpy(mb->
t, result, len);
1963 perl = rpmperlFree(perl);
1965 script =
_free(script);
1971 #ifdef WITH_PYTHONEMBED
1972 if (
STREQ(
"python", f, fn)) {
1973 const char ** av = NULL;
1974 char * script = parseEmbedded(s, (
size_t)(se-s), &av);
1975 rpmpython python = rpmpythonNew(av, _globalI);
1976 const char * result = NULL;
1978 if (rpmpythonRun(python, script, &result) !=
RPMRC_OK)
1981 if (result == NULL) result =
"FIXME";
1982 if (result != NULL && *result !=
'\0') {
1983 size_t len = strlen(result);
1986 memcpy(mb->
t, result, len);
1991 python = rpmpythonFree(python);
1993 script =
_free(script);
1999 #ifdef WITH_RUBYEMBED
2000 if (
STREQ(
"ruby", f, fn)) {
2001 const char ** av = NULL;
2002 char * script = parseEmbedded(s, (
size_t)(se-s), &av);
2003 rpmruby ruby = rpmrubyNew(av, _globalI);
2004 const char * result = NULL;
2006 if (rpmrubyRun(ruby, script, &result) !=
RPMRC_OK)
2009 if (result == NULL) result =
"FIXME";
2010 if (result != NULL && *result !=
'\0') {
2011 size_t len = strlen(result);
2014 memcpy(mb->
t, result, len);
2019 ruby = rpmrubyFree(ruby);
2021 script =
_free(script);
2028 if (
STREQ(
"tcl", f, fn)) {
2029 const char ** av = NULL;
2030 char * script = parseEmbedded(s, (
size_t)(se-s), &av);
2031 rpmtcl tcl = rpmtclNew(av, _globalI);
2032 const char * result = NULL;
2034 if (rpmtclRun(tcl, script, &result) !=
RPMRC_OK)
2036 else if (result != NULL && *result !=
'\0') {
2037 size_t len = strlen(result);
2040 memcpy(mb->
t, result, len);
2044 tcl = rpmtclFree(tcl);
2046 script =
_free(script);
2053 if (lastc && fn > 5 &&
STREQ(
"patch", f, 5) &&
xisdigit((
int)f[5])) {
2055 doFoo(mb, negate, f, (lastc - f), NULL, 0);
2062 if (
STREQ(
"basename", f, fn) ||
2063 STREQ(
"dirname", f, fn) ||
2064 STREQ(
"realpath", f, fn) ||
2065 STREQ(
"getenv", f, fn) ||
2066 STREQ(
"shrink", f, fn) ||
2067 STREQ(
"suffix", f, fn) ||
2068 STREQ(
"expand", f, fn) ||
2069 STREQ(
"verbose", f, fn) ||
2070 STREQ(
"uncompress", f, fn) ||
2071 STREQ(
"mkstemp", f, fn) ||
2072 STREQ(
"mkdtemp", f, fn) ||
2073 STREQ(
"uuid", f, fn) ||
2074 STREQ(
"url2path", f, fn) ||
2075 STREQ(
"u2p", f, fn) ||
2076 STREQ(
"S", f, fn) ||
2077 STREQ(
"P", f, fn) ||
2078 STREQ(
"F", f, fn)) {
2080 doFoo(mb, negate, f, fn, g, gn);
2088 me = (mep ? *mep : NULL);
2094 if ((me == NULL && !negate) ||
2095 (me != NULL && negate)) {
2103 if (me && me->body && *me->body) {
2104 rc =
expandT(mb, me->body, strlen(me->body));
2112 if ((me == NULL && !negate) ||
2113 (me != NULL && negate)) {
2120 if (me && me->body && *me->body) {
2121 rc =
expandT(mb, me->body, strlen(me->body));
2128 #if !defined(RPM_VENDOR_WINDRIVER_DEBUG)
2131 if (fn == 1 && *f ==
'*') {
2140 if (!strncmp(f,
"if", fn) ||
2141 !strncmp(f,
"else", fn) ||
2142 !strncmp(f,
"endif", fn)) {
2147 _(
"Macro %%%.*s not found, skipping\n"), fn, f);
2156 if (!(g && g < ge)) {
2166 if (me && me->opts != NULL) {
2167 if (lastc != NULL) {
2178 if (me->body && *me->body) {
2186 if (me->opts != NULL)
2200 #if defined(RPM_VENDOR_OPENPKG) || \
2201 !defined(POPT_ERROR_BADCONFIG)
2207 if (stat(filename, &sb) == -1)
2210 if (sb.st_uid != uid)
2212 if (!S_ISREG(sb.st_mode))
2214 if (sb.st_mode & (S_IWGRP|S_IWOTH))
2220 #if !defined(DEBUG_MACROS)
2225 int rpmGlob(
const char * patterns,
int * argcPtr,
const char *** argvPtr)
2228 const char ** av = NULL;
2230 const char ** argv = NULL;
2231 char * globRoot = NULL;
2233 const char * old_collate = NULL;
2234 const char * old_ctype = NULL;
2257 for (j = 0; j < ac; j++) {
2258 const char * globURL;
2260 int ut =
urlPath(av[j], &path);
2264 argv =
xrealloc(argv, (argc+2) *
sizeof(*argv));
2267 fprintf(stderr,
"*** rpmGlob argv[%d] \"%s\"\n", argc, argv[argc]);
2280 for (i = 0; i < gl.
gl_pathc; i++) {
2281 if ((nb = strlen(&(gl.
gl_pathv[i][0]))) > maxb)
2288 globURL = globRoot =
xmalloc(maxb);
2293 strncpy(globRoot, av[j], nb);
2306 fprintf(stderr,
"*** GLOB maxb %d diskURL %d %*s globURL %p %s\n", (
int)maxb, (
int)nb, (
int)nb, av[j], globURL, globURL);
2311 for (i = 0; i < gl.
gl_pathc; i++) {
2312 const char * globFile = &(gl.
gl_pathv[i][0]);
2313 if (globRoot > globURL && globRoot[-1] ==
'/')
2314 while (*globFile ==
'/') globFile++;
2315 strcpy(globRoot, globFile);
2317 fprintf(stderr,
"*** rpmGlob argv[%d] \"%s\"\n", argc, globURL);
2318 argv[argc++] =
xstrdup(globURL);
2323 globURL =
_free(globURL);
2326 if (argv != NULL && argc > 0) {
2340 (void)
setlocale(LC_COLLATE, old_collate);
2341 old_collate =
_free(old_collate);
2345 old_ctype =
_free(old_ctype);
2349 if (rc || argvPtr == NULL) {
2352 for (j = 0; j < argc; j++)
2353 argv[j] =
_free(argv[j]);
2370 if (sbuf == NULL || slen == 0)
2393 strncpy(sbuf, tbuf, (slen - mb->
nb + 1));
2400 const char * n,
const char * o,
const char * b,
int level)
2403 const char *
name = n;
2413 if ((mep =
findEntry(mc, name, 0)) == NULL) {
2414 if (mc->firstFree == mc->macrosAllocated)
2416 if (mc->macroTable != NULL)
2417 mep = mc->macroTable + mc->firstFree++;
2422 if (*mep && (*mep)->flags && !(n[0] ==
'.' && n[1] ==
'.')) {
2424 if (strcmp((*mep)->name,
"buildroot"))
2432 if ((*mep)->prev == NULL)
2444 if ((mep =
findEntry(mc, n, 0)) != NULL) {
2458 memset(mb, 0,
sizeof(*mb));
2461 (void)
doDefine(mb, macro, level, 0);
2482 if (mc->macroTable != NULL) {
2484 for (i = 0; i < mc->firstFree; i++) {
2486 mep = &mc->macroTable[i];
2491 addMacro(NULL, me->name, me->opts, me->body, (level - 1));
2496 #if defined(RPM_VENDOR_OPENPKG)
2497 static void expand_macrosfile_macro(
const char *file_name,
const char *buf,
size_t bufn)
2501 static const char *macro_name =
"%{macrosfile}";
2503 l = strlen(macro_name);
2504 k = strlen(file_name);
2505 while ((cp = strstr(buf, macro_name)) != NULL) {
2506 if (((strlen(buf) - l) + k) < bufn) {
2507 memmove(cp+k, cp+l, strlen(cp+l)+1);
2508 memcpy(cp, file_name, k);
2521 char *buf =
alloca(bufn);
2524 if (fd == NULL ||
Ferror(fd)) {
2525 if (fd) (void)
Fclose(fd);
2535 while(
rdcl(buf, bufn, fd) != NULL) {
2545 #if defined(RPM_VENDOR_OPENPKG)
2546 expand_macrosfile_macro(fn, buf, bufn);
2557 char *mfiles, *m, *me;
2559 if (macrofiles == NULL)
2566 for (m = mfiles; m && *m !=
'\0'; m = me) {
2571 for (me = m; (me = strchr(me,
':')) != NULL; me++) {
2573 if (!(me[1] ==
'/' && me[2] ==
'/'))
2577 if (me && *me ==
':')
2585 #if defined(DEBUG_MACROS)
2587 av =
xmalloc((ac + 1) *
sizeof(*av));
2598 for (i = 0; i < ac; i++) {
2599 size_t slen = strlen(av[i]);
2600 const char *fn = av[i];
2602 if (fn[0] ==
'@' ) {
2604 #if defined(RPM_VENDOR_OPENPKG) || \
2605 !defined(POPT_ERROR_BADCONFIG)
2608 if (!poptSaneFile(fn))
2611 rpmlog(
RPMLOG_WARNING,
"existing RPM macros file \"%s\" considered INSECURE -- not loaded\n", fn);
2617 #define _suffix(_s, _x) \
2618 (slen >= sizeof(_x) && !strcmp((_s)+slen-(sizeof(_x)-1), (_x)))
2627 av[i] =
_free(av[i]);
2631 mfiles =
_free(mfiles);
2646 if (mc->macroTable != NULL) {
2648 for (i = 0; i < mc->firstFree; i++) {
2650 while ((me = mc->macroTable[i]) != NULL) {
2653 if ((mc->macroTable[i] = me->prev) == NULL)
2654 me->name =
_free(me->name);
2656 me->opts =
_free(me->opts);
2657 me->body =
_free(me->body);
2661 mc->macroTable =
_free(mc->macroTable);
2663 memset(mc, 0,
sizeof(*mc));
2673 unsigned char magic[13];
2674 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_FEDORA) || defined(RPM_VENDOR_MANDRIVA)
2680 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_FEDORA) || defined(RPM_VENDOR_MANDRIVA)
2681 file_len = strlen(file);
2682 if ((file_len > 4 && strcasecmp(file+file_len-4,
".tbz") == 0)
2683 || (file_len > 4 && strcasecmp(file+file_len-4,
".bz2") == 0)) {
2687 if (file_len > 4 && strcasecmp(file+file_len-4,
".zip") == 0) {
2691 if ((file_len > 4 && strcasecmp(file+file_len-4,
".tlz") == 0)
2692 || (file_len > 5 && strcasecmp(file+file_len-5,
".lzma") == 0)) {
2696 if (file_len > 4 && strcasecmp(file+file_len-3,
".xz") == 0) {
2700 if ((file_len > 4 && strcasecmp(file+file_len-4,
".tgz") == 0)
2701 || (file_len > 3 && strcasecmp(file+file_len-3,
".gz") == 0)
2702 || (file_len > 2 && strcasecmp(file+file_len-2,
".Z") == 0)) {
2706 if (file_len > 5 && strcasecmp(file+file_len-5,
".cpio") == 0) {
2710 if (file_len > 4 && strcasecmp(file+file_len-4,
".tar") == 0) {
2716 fd =
Fopen(file,
"r");
2717 if (fd == NULL ||
Ferror(fd)) {
2720 if (fd) (void)
Fclose(fd);
2723 nb =
Fread(magic,
sizeof(magic[0]),
sizeof(magic), fd);
2724 if (nb < (ssize_t)0) {
2727 }
else if (nb < (ssize_t)
sizeof(magic)) {
2729 file, (
unsigned)
sizeof(magic));
2738 if (magic[0] ==
'B' && magic[1] ==
'Z')
2741 if (magic[0] == (
unsigned char) 0120 && magic[1] == (
unsigned char) 0113
2742 && magic[2] == (
unsigned char) 0003 && magic[3] == (
unsigned char) 0004)
2745 if (magic[0] == (
unsigned char) 0x89 && magic[1] ==
'L'
2746 && magic[2] ==
'Z' && magic[3] ==
'O')
2749 #if !defined(RPM_VENDOR_OPENPKG) && !defined(RPM_VENDOR_FEDORA) && !defined(RPM_VENDOR_MANDRIVA)
2751 if (magic[ 9] == (
unsigned char) 0x00 && magic[10] == (
unsigned char) 0x00 &&
2752 magic[11] == (
unsigned char) 0x00 && magic[12] == (
unsigned char) 0x00)
2756 #if defined(RPM_VENDOR_OPENSUSE)
2757 if (magic[0] == 0135 && magic[1] == 0 && magic[2] == 0) {
2761 if (magic[0] == (
unsigned char) 0xFD && magic[1] == 0x37 && magic[2] == 0x7A
2762 && magic[3] == 0x58 && magic[4] == 0x5A && magic[5] == 0x00)
2765 if ((magic[0] == (
unsigned char) 0037 && magic[1] == (
unsigned char) 0213)
2766 || (magic[0] == (
unsigned char) 0037 && magic[1] == (
unsigned char) 0236)
2767 || (magic[0] == (
unsigned char) 0037 && magic[1] == (
unsigned char) 0036)
2768 || (magic[0] == (
unsigned char) 0037 && magic[1] == (
unsigned char) 0240)
2769 || (magic[0] == (
unsigned char) 0037 && magic[1] == (
unsigned char) 0235))
2793 t =
xmalloc(bufn + strlen(arg) + 1);
2798 while ((s = va_arg(ap,
const char *)) != NULL) {
2801 t =
xrealloc(t, tn + sn + bufn + 1);
2810 t[tn + bufn] =
'\0';
2829 t =
xmalloc(bufn + strlen(arg) + 1);
2834 while ((s = va_arg(ap,
const char *)) != NULL) {
2837 t =
xrealloc(t, tn + sn + bufn + 1);
2846 t[tn + bufn] =
'\0';
2863 if (!(val && *val !=
'%'))
2865 else if (*val ==
'Y' || *val ==
'y')
2867 else if (*val ==
'N' || *val ==
'n')
2871 rc = strtol(val, &end, 0);
2872 if (!(end && *end ==
'\0'))
2892 while (*s !=
'\0') {
2896 if (s[1] ==
'/' && s[2] ==
'/') {
2900 if (s[0] ==
'/') *t++ = *s++;
2908 for (se = te + 1; se < t && *se !=
'/'; se++)
2910 if (se < t && *se ==
'/') {
2916 while (t > te && t[-1] ==
'/')
2926 if (begin && s[1] ==
'.' && (s[2] ==
'/' || s[2] ==
'\0')) {
2932 if (begin && s[1] ==
'\0') {
2935 if (t > path && t[-1] ==
'/')
2938 case '\0': s++;
continue;
2942 if (!begin && t > path && t[-1] ==
'/' && s[1] ==
'.' && (s[2] ==
'/' || s[2] ==
'\0')) {
2946 for (--te; te > path && *te !=
'/'; te--)
2962 if (t > &path[1] && t[-1] ==
'/')
2976 char *buf =
alloca(bufn);
2990 while ((s = va_arg(ap,
const char *)) != NULL) {
3005 const char *
rpmGenPath(
const char * urlroot,
const char * urlmdir,
3006 const char *urlfile)
3008 const char * xroot =
rpmGetPath(urlroot, NULL);
3009 const char * root = xroot;
3010 const char * xmdir =
rpmGetPath(urlmdir, NULL);
3011 const char * mdir = xmdir;
3012 const char * xfile =
rpmGetPath(urlfile, NULL);
3013 const char * file = xfile;
3014 const char * result;
3015 const char * url = NULL;
3020 if (_debug) fprintf(stderr,
"*** RGP xroot %s xmdir %s xfile %s\n", xroot, xmdir, xfile);
3025 nurl = root - xroot;
3027 if (_debug) fprintf(stderr,
"*** RGP ut %d root %s nurl %d\n", ut, root, nurl);
3030 if (root == NULL || *root ==
'\0') root =
"/";
3035 nurl = mdir - xmdir;
3037 if (_debug) fprintf(stderr,
"*** RGP ut %d mdir %s nurl %d\n", ut, mdir, nurl);
3040 if (mdir == NULL || *mdir ==
'\0') mdir =
"/";
3045 nurl = file - xfile;
3047 if (_debug) fprintf(stderr,
"*** RGP ut %d file %s nurl %d\n", ut, file, nurl);
3051 if (url && nurl > 0) {
3052 char *t = strncpy(
alloca(nurl+1), url, nurl);
3058 result =
rpmGetPath(url, root,
"/", mdir,
"/", file, NULL);
3060 xroot =
_free(xroot);
3061 xmdir =
_free(xmdir);
3062 xfile =
_free(xfile);
3064 if (_debug) fprintf(stderr,
"*** RGP result %s\n", result);
3071 #if defined(DEBUG_MACROS)
3073 #if defined(EVAL_MACROS)
3078 main(
int argc,
char *argv[])
3082 extern char *optarg;
3085 while ((c = getopt(argc, argv,
"f:")) != EOF ) {
3088 rpmMacrofiles = optarg;
3096 if (errflg || optind >= argc) {
3097 fprintf(stderr,
"Usage: %s [-f macropath ] macro ...\n", argv[0]);
3103 for ( ; optind < argc; optind++) {
3108 fprintf(stdout,
"%s:\t%s\n", argv[optind], val);
3118 const char *rpmMacrofiles =
"../macros:./testmacros";
3119 const char *testfile =
"./test";
3122 main(
int argc,
char *argv[])
3125 char *buf =
alloca(bufn);
3131 if ((fp = fopen(testfile,
"r")) != NULL) {
3132 while(
rdcl(buf, bufn, fp)) {
3134 fprintf(stderr,
"%d->%s\n", x, buf);
3135 memset(buf, 0, bufn);
3140 while(
rdcl(buf, bufn, stdin)) {
3142 fprintf(stderr,
"%d->%s\n <-\n", x, buf);
3143 memset(buf, 0, bufn);