00001
00007 #include "system.h"
00008
00009 #define MYALLPERMS 07777
00010
00011 #if defined(WITH_PCRE) && defined(WITH_PCRE_POSIX)
00012 #include <pcreposix.h>
00013 #else
00014 #include <regex.h>
00015 #endif
00016
00017 #include <rpmio_internal.h>
00018 #include <fts.h>
00019
00020 #define _RPMTAG_INTERNAL
00021 #define _RPMFI_INTERNAL
00022 #define _RPMTE_INTERNAL
00023 #include <rpmbuild.h>
00024
00025 #include "cpio.h"
00026
00027 #include "argv.h"
00028 #include "rpmfc.h"
00029
00030 #include "buildio.h"
00031
00032 #include "legacy.h"
00033 #include "misc.h"
00034 #include "debug.h"
00035
00036
00037
00038
00039
00040
00041
00042 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
00043 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
00044
00045 #define MAXDOCDIR 1024
00046
00049 typedef enum specdFlags_e {
00050 SPECD_DEFFILEMODE = (1 << 0),
00051 SPECD_DEFDIRMODE = (1 << 1),
00052 SPECD_DEFUID = (1 << 2),
00053 SPECD_DEFGID = (1 << 3),
00054 SPECD_DEFVERIFY = (1 << 4),
00055
00056 SPECD_FILEMODE = (1 << 8),
00057 SPECD_DIRMODE = (1 << 9),
00058 SPECD_UID = (1 << 10),
00059 SPECD_GID = (1 << 11),
00060 SPECD_VERIFY = (1 << 12)
00061 } specdFlags;
00062
00065 typedef struct FileListRec_s {
00066 struct stat fl_st;
00067 #define fl_dev fl_st.st_dev
00068 #define fl_ino fl_st.st_ino
00069 #define fl_mode fl_st.st_mode
00070 #define fl_nlink fl_st.st_nlink
00071 #define fl_uid fl_st.st_uid
00072 #define fl_gid fl_st.st_gid
00073 #define fl_rdev fl_st.st_rdev
00074 #define fl_size fl_st.st_size
00075 #define fl_mtime fl_st.st_mtime
00076
00077
00078 const char *diskURL;
00079
00080 const char *fileURL;
00081
00082 const char *uname;
00083
00084 const char *gname;
00085 unsigned flags;
00086 specdFlags specdFlags;
00087 unsigned verifyFlags;
00088
00089 const char *langs;
00090 } * FileListRec;
00091
00094 typedef struct AttrRec_s {
00095
00096 const char *ar_fmodestr;
00097
00098 const char *ar_dmodestr;
00099
00100 const char *ar_user;
00101
00102 const char *ar_group;
00103 mode_t ar_fmode;
00104 mode_t ar_dmode;
00105 } * AttrRec;
00106
00107
00108
00109 static struct AttrRec_s root_ar = { NULL, NULL, "root", "root", 0, 0 };
00110
00111
00112
00113
00114 static StringBuf check_fileList = NULL;
00115
00119 typedef struct FileList_s {
00120
00121 const char * buildRootURL;
00122
00123 const char * prefix;
00124
00125 int fileCount;
00126 int totalFileSize;
00127 int processingFailed;
00128
00129 int passedSpecialDoc;
00130 int isSpecialDoc;
00131
00132 int noGlob;
00133 unsigned devtype;
00134 unsigned devmajor;
00135 int devminor;
00136
00137 int isDir;
00138 int inFtw;
00139 int currentFlags;
00140 specdFlags currentSpecdFlags;
00141 int currentVerifyFlags;
00142 struct AttrRec_s cur_ar;
00143 struct AttrRec_s def_ar;
00144 specdFlags defSpecdFlags;
00145 int defVerifyFlags;
00146 int nLangs;
00147
00148 const char ** currentLangs;
00149
00150
00151
00152 const char * docDirs[MAXDOCDIR];
00153 int docDirCount;
00154
00155
00156 FileListRec fileList;
00157 int fileListRecsAlloced;
00158 int fileListRecsUsed;
00159 } * FileList;
00160
00163 static void nullAttrRec( AttrRec ar)
00164 {
00165 ar->ar_fmodestr = NULL;
00166 ar->ar_dmodestr = NULL;
00167 ar->ar_user = NULL;
00168 ar->ar_group = NULL;
00169 ar->ar_fmode = 0;
00170 ar->ar_dmode = 0;
00171 }
00172
00175 static void freeAttrRec(AttrRec ar)
00176 {
00177 ar->ar_fmodestr = _free(ar->ar_fmodestr);
00178 ar->ar_dmodestr = _free(ar->ar_dmodestr);
00179 ar->ar_user = _free(ar->ar_user);
00180 ar->ar_group = _free(ar->ar_group);
00181
00182
00183 return;
00184
00185 }
00186
00189 static void dupAttrRec(const AttrRec oar, AttrRec nar)
00190
00191 {
00192 if (oar == nar)
00193 return;
00194 freeAttrRec(nar);
00195 nar->ar_fmodestr = (oar->ar_fmodestr ? xstrdup(oar->ar_fmodestr) : NULL);
00196 nar->ar_dmodestr = (oar->ar_dmodestr ? xstrdup(oar->ar_dmodestr) : NULL);
00197 nar->ar_user = (oar->ar_user ? xstrdup(oar->ar_user) : NULL);
00198 nar->ar_group = (oar->ar_group ? xstrdup(oar->ar_group) : NULL);
00199 nar->ar_fmode = oar->ar_fmode;
00200 nar->ar_dmode = oar->ar_dmode;
00201 }
00202
00203 #if 0
00204
00206 static void dumpAttrRec(const char * msg, AttrRec ar)
00207
00208
00209 {
00210 if (msg)
00211 fprintf(stderr, "%s:\t", msg);
00212 fprintf(stderr, "(%s, %s, %s, %s)\n",
00213 ar->ar_fmodestr,
00214 ar->ar_user,
00215 ar->ar_group,
00216 ar->ar_dmodestr);
00217 }
00218 #endif
00219
00225
00226 static char *strtokWithQuotes( char *s, const char *delim)
00227
00228 {
00229 static char *olds = NULL;
00230 char *token;
00231
00232 if (s == NULL)
00233 s = olds;
00234 if (s == NULL)
00235 return NULL;
00236
00237
00238 s += strspn(s, delim);
00239 if (*s == '\0')
00240 return NULL;
00241
00242
00243 token = s;
00244 if (*token == '"') {
00245 token++;
00246
00247 s = strchr(token, '"');
00248 } else {
00249 s = strpbrk(token, delim);
00250 }
00251
00252
00253 if (s == NULL) {
00254
00255 olds = strchr(token, '\0');
00256 } else {
00257
00258 *s = '\0';
00259 olds = s+1;
00260 }
00261
00262
00263 return token;
00264
00265 }
00266
00269 static void timeCheck(int tc, Header h)
00270
00271
00272 {
00273 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00274 uint32_t currentTime = time(NULL);
00275 uint32_t * mtime;
00276 int xx;
00277 int i;
00278
00279 he->tag = RPMTAG_FILEMTIMES;
00280 xx = headerGet(h, he, 0);
00281 mtime = he->p.ui32p;
00282 he->tag = RPMTAG_OLDFILENAMES;
00283 xx = headerGet(h, he, 0);
00284
00285 for (i = 0; i < he->c; i++) {
00286 xx = currentTime - mtime[i];
00287 if (xx < 0) xx = -xx;
00288 if (xx > tc)
00289 rpmlog(RPMLOG_WARNING, _("TIMECHECK failure: %s\n"), he->p.argv[i]);
00290 }
00291 he->p.ptr = _free(he->p.ptr);
00292 mtime = _free(mtime);
00293 }
00294
00297 typedef struct VFA {
00298 const char * attribute;
00299 int not;
00300 int flag;
00301 } VFA_t;
00302
00305
00306
00307 VFA_t verifyAttrs[] = {
00308 { "md5", 0, RPMVERIFY_MD5 },
00309 { "size", 0, RPMVERIFY_FILESIZE },
00310 { "link", 0, RPMVERIFY_LINKTO },
00311 { "user", 0, RPMVERIFY_USER },
00312 { "group", 0, RPMVERIFY_GROUP },
00313 { "mtime", 0, RPMVERIFY_MTIME },
00314 { "mode", 0, RPMVERIFY_MODE },
00315 { "rdev", 0, RPMVERIFY_RDEV },
00316 { NULL, 0, 0 }
00317 };
00318
00319
00326 static rpmRC parseForVerify(char * buf, FileList fl)
00327
00328
00329
00330 {
00331 char *p, *pe, *q;
00332 const char *name;
00333 int *resultVerify;
00334 int negated;
00335 int verifyFlags;
00336 specdFlags * specdFlags;
00337
00338 if ((p = strstr(buf, (name = "%verify"))) != NULL) {
00339 resultVerify = &(fl->currentVerifyFlags);
00340 specdFlags = &fl->currentSpecdFlags;
00341 } else if ((p = strstr(buf, (name = "%defverify"))) != NULL) {
00342 resultVerify = &(fl->defVerifyFlags);
00343 specdFlags = &fl->defSpecdFlags;
00344 } else
00345 return RPMRC_OK;
00346
00347 for (pe = p; (pe-p) < strlen(name); pe++)
00348 *pe = ' ';
00349
00350 SKIPSPACE(pe);
00351
00352 if (*pe != '(') {
00353 rpmlog(RPMLOG_ERR, _("Missing '(' in %s %s\n"), name, pe);
00354 fl->processingFailed = 1;
00355 return RPMRC_FAIL;
00356 }
00357
00358
00359 *pe++ = ' ';
00360 for (p = pe; *pe && *pe != ')'; pe++)
00361 {};
00362
00363 if (*pe == '\0') {
00364 rpmlog(RPMLOG_ERR, _("Missing ')' in %s(%s\n"), name, p);
00365 fl->processingFailed = 1;
00366 return RPMRC_FAIL;
00367 }
00368
00369
00370 q = alloca((pe-p) + 1);
00371 strncpy(q, p, pe-p);
00372 q[pe-p] = '\0';
00373 while (p <= pe)
00374 *p++ = ' ';
00375
00376 negated = 0;
00377 verifyFlags = RPMVERIFY_NONE;
00378
00379 for (p = q; *p != '\0'; p = pe) {
00380 SKIPWHITE(p);
00381 if (*p == '\0')
00382 break;
00383 pe = p;
00384 SKIPNONWHITE(pe);
00385 if (*pe != '\0')
00386 *pe++ = '\0';
00387
00388 { VFA_t *vfa;
00389 for (vfa = verifyAttrs; vfa->attribute != NULL; vfa++) {
00390 if (strcmp(p, vfa->attribute))
00391 continue;
00392 verifyFlags |= vfa->flag;
00393 break;
00394 }
00395 if (vfa->attribute)
00396 continue;
00397 }
00398
00399 if (!strcmp(p, "not")) {
00400 negated ^= 1;
00401 } else {
00402 rpmlog(RPMLOG_ERR, _("Invalid %s token: %s\n"), name, p);
00403 fl->processingFailed = 1;
00404 return RPMRC_FAIL;
00405 }
00406 }
00407
00408 *resultVerify = negated ? ~(verifyFlags) : verifyFlags;
00409 *specdFlags |= SPECD_VERIFY;
00410
00411 return RPMRC_OK;
00412 }
00413
00414 #define isAttrDefault(_ars) ((_ars)[0] == '-' && (_ars)[1] == '\0')
00415
00422 static rpmRC parseForDev(char * buf, FileList fl)
00423
00424
00425 {
00426 const char * name;
00427 const char * errstr = NULL;
00428 char *p, *pe, *q;
00429 rpmRC rc = RPMRC_FAIL;
00430
00431 if ((p = strstr(buf, (name = "%dev"))) == NULL)
00432 return RPMRC_OK;
00433
00434 for (pe = p; (pe-p) < strlen(name); pe++)
00435 *pe = ' ';
00436 SKIPSPACE(pe);
00437
00438 if (*pe != '(') {
00439 errstr = "'('";
00440 goto exit;
00441 }
00442
00443
00444 *pe++ = ' ';
00445 for (p = pe; *pe && *pe != ')'; pe++)
00446 {};
00447 if (*pe != ')') {
00448 errstr = "')'";
00449 goto exit;
00450 }
00451
00452
00453 q = alloca((pe-p) + 1);
00454 strncpy(q, p, pe-p);
00455 q[pe-p] = '\0';
00456 while (p <= pe)
00457 *p++ = ' ';
00458
00459 p = q; SKIPWHITE(p);
00460 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00461 if (*p == 'b')
00462 fl->devtype = 'b';
00463 else if (*p == 'c')
00464 fl->devtype = 'c';
00465 else {
00466 errstr = "devtype";
00467 goto exit;
00468 }
00469
00470 p = pe; SKIPWHITE(p);
00471 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00472 for (pe = p; *pe && xisdigit(*pe); pe++)
00473 {} ;
00474 if (*pe == '\0') {
00475 fl->devmajor = atoi(p);
00476
00477 if (!(fl->devmajor >= 0 && fl->devmajor < 256)) {
00478 errstr = "devmajor";
00479 goto exit;
00480 }
00481
00482 pe++;
00483 } else {
00484 errstr = "devmajor";
00485 goto exit;
00486 }
00487
00488 p = pe; SKIPWHITE(p);
00489 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00490 for (pe = p; *pe && xisdigit(*pe); pe++)
00491 {} ;
00492 if (*pe == '\0') {
00493 fl->devminor = atoi(p);
00494 if (!(fl->devminor >= 0 && fl->devminor < 256)) {
00495 errstr = "devminor";
00496 goto exit;
00497 }
00498 pe++;
00499 } else {
00500 errstr = "devminor";
00501 goto exit;
00502 }
00503
00504 fl->noGlob = 1;
00505
00506 rc = 0;
00507
00508 exit:
00509 if (rc) {
00510 rpmlog(RPMLOG_ERR, _("Missing %s in %s %s\n"), errstr, name, p);
00511 fl->processingFailed = 1;
00512 }
00513 return rc;
00514 }
00515
00522 static rpmRC parseForAttr(char * buf, FileList fl)
00523
00524
00525
00526 {
00527 const char *name;
00528 char *p, *pe, *q;
00529 int x;
00530 struct AttrRec_s arbuf;
00531 AttrRec ar = &arbuf, ret_ar;
00532 specdFlags * specdFlags;
00533
00534 if ((p = strstr(buf, (name = "%attr"))) != NULL) {
00535 ret_ar = &(fl->cur_ar);
00536 specdFlags = &fl->currentSpecdFlags;
00537 } else if ((p = strstr(buf, (name = "%defattr"))) != NULL) {
00538 ret_ar = &(fl->def_ar);
00539 specdFlags = &fl->defSpecdFlags;
00540 } else
00541 return RPMRC_OK;
00542
00543 for (pe = p; (pe-p) < strlen(name); pe++)
00544 *pe = ' ';
00545
00546 SKIPSPACE(pe);
00547
00548 if (*pe != '(') {
00549 rpmlog(RPMLOG_ERR, _("Missing '(' in %s %s\n"), name, pe);
00550 fl->processingFailed = 1;
00551 return RPMRC_FAIL;
00552 }
00553
00554
00555 *pe++ = ' ';
00556 for (p = pe; *pe && *pe != ')'; pe++)
00557 {};
00558
00559 if (ret_ar == &(fl->def_ar)) {
00560 q = pe;
00561 q++;
00562 SKIPSPACE(q);
00563 if (*q != '\0') {
00564 rpmlog(RPMLOG_ERR,
00565 _("Non-white space follows %s(): %s\n"), name, q);
00566 fl->processingFailed = 1;
00567 return RPMRC_FAIL;
00568 }
00569 }
00570
00571
00572 q = alloca((pe-p) + 1);
00573 strncpy(q, p, pe-p);
00574 q[pe-p] = '\0';
00575 while (p <= pe)
00576 *p++ = ' ';
00577
00578 nullAttrRec(ar);
00579
00580 p = q; SKIPWHITE(p);
00581 if (*p != '\0') {
00582 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00583 ar->ar_fmodestr = p;
00584 p = pe; SKIPWHITE(p);
00585 }
00586 if (*p != '\0') {
00587 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00588 ar->ar_user = p;
00589 p = pe; SKIPWHITE(p);
00590 }
00591 if (*p != '\0') {
00592 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00593 ar->ar_group = p;
00594 p = pe; SKIPWHITE(p);
00595 }
00596 if (*p != '\0' && ret_ar == &(fl->def_ar)) {
00597 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00598 ar->ar_dmodestr = p;
00599 p = pe; SKIPWHITE(p);
00600 }
00601
00602 if (!(ar->ar_fmodestr && ar->ar_user && ar->ar_group) || *p != '\0') {
00603 rpmlog(RPMLOG_ERR, _("Bad syntax: %s(%s)\n"), name, q);
00604 fl->processingFailed = 1;
00605 return RPMRC_FAIL;
00606 }
00607
00608
00609 if (ar->ar_fmodestr && !isAttrDefault(ar->ar_fmodestr)) {
00610 unsigned int ui;
00611 x = sscanf(ar->ar_fmodestr, "%o", &ui);
00612 if ((x == 0) || (ar->ar_fmode & ~MYALLPERMS)) {
00613 rpmlog(RPMLOG_ERR, _("Bad mode spec: %s(%s)\n"), name, q);
00614 fl->processingFailed = 1;
00615 return RPMRC_FAIL;
00616 }
00617 ar->ar_fmode = ui;
00618 } else
00619 ar->ar_fmodestr = NULL;
00620
00621 if (ar->ar_dmodestr && !isAttrDefault(ar->ar_dmodestr)) {
00622 unsigned int ui;
00623 x = sscanf(ar->ar_dmodestr, "%o", &ui);
00624 if ((x == 0) || (ar->ar_dmode & ~MYALLPERMS)) {
00625 rpmlog(RPMLOG_ERR, _("Bad dirmode spec: %s(%s)\n"), name, q);
00626 fl->processingFailed = 1;
00627 return RPMRC_FAIL;
00628 }
00629 ar->ar_dmode = ui;
00630 } else
00631 ar->ar_dmodestr = NULL;
00632
00633 if (!(ar->ar_user && !isAttrDefault(ar->ar_user)))
00634 ar->ar_user = NULL;
00635
00636 if (!(ar->ar_group && !isAttrDefault(ar->ar_group)))
00637 ar->ar_group = NULL;
00638
00639 dupAttrRec(ar, ret_ar);
00640
00641
00642 *specdFlags |= SPECD_UID | SPECD_GID | SPECD_FILEMODE | SPECD_DIRMODE;
00643
00644 return RPMRC_OK;
00645 }
00646
00653 static rpmRC parseForConfig(char * buf, FileList fl)
00654
00655 {
00656 char *p, *pe, *q;
00657 const char *name;
00658
00659 if ((p = strstr(buf, (name = "%config"))) == NULL)
00660 return RPMRC_OK;
00661
00662 fl->currentFlags |= RPMFILE_CONFIG;
00663
00664
00665 for (pe = p; (pe-p) < strlen(name); pe++)
00666 *pe = ' ';
00667 SKIPSPACE(pe);
00668 if (*pe != '(')
00669 return RPMRC_OK;
00670
00671
00672 *pe++ = ' ';
00673 for (p = pe; *pe && *pe != ')'; pe++)
00674 {};
00675
00676 if (*pe == '\0') {
00677 rpmlog(RPMLOG_ERR, _("Missing ')' in %s(%s\n"), name, p);
00678 fl->processingFailed = 1;
00679 return RPMRC_FAIL;
00680 }
00681
00682
00683 q = alloca((pe-p) + 1);
00684 strncpy(q, p, pe-p);
00685 q[pe-p] = '\0';
00686 while (p <= pe)
00687 *p++ = ' ';
00688
00689 for (p = q; *p != '\0'; p = pe) {
00690 SKIPWHITE(p);
00691 if (*p == '\0')
00692 break;
00693 pe = p;
00694 SKIPNONWHITE(pe);
00695 if (*pe != '\0')
00696 *pe++ = '\0';
00697 if (!strcmp(p, "missingok")) {
00698 fl->currentFlags |= RPMFILE_MISSINGOK;
00699 } else if (!strcmp(p, "noreplace")) {
00700 fl->currentFlags |= RPMFILE_NOREPLACE;
00701 } else {
00702 rpmlog(RPMLOG_ERR, _("Invalid %s token: %s\n"), name, p);
00703 fl->processingFailed = 1;
00704 return RPMRC_FAIL;
00705 }
00706 }
00707
00708 return RPMRC_OK;
00709 }
00710
00713 static int langCmp(const void * ap, const void * bp)
00714
00715 {
00716 return strcmp(*(const char **)ap, *(const char **)bp);
00717 }
00718
00725 static rpmRC parseForLang(char * buf, FileList fl)
00726
00727
00728 {
00729 char *p, *pe, *q;
00730 const char *name;
00731
00732 while ((p = strstr(buf, (name = "%lang"))) != NULL) {
00733
00734 for (pe = p; (pe-p) < strlen(name); pe++)
00735 *pe = ' ';
00736 SKIPSPACE(pe);
00737
00738 if (*pe != '(') {
00739 rpmlog(RPMLOG_ERR, _("Missing '(' in %s %s\n"), name, pe);
00740 fl->processingFailed = 1;
00741 return RPMRC_FAIL;
00742 }
00743
00744
00745 *pe++ = ' ';
00746 for (pe = p; *pe && *pe != ')'; pe++)
00747 {};
00748
00749 if (*pe == '\0') {
00750 rpmlog(RPMLOG_ERR, _("Missing ')' in %s(%s\n"), name, p);
00751 fl->processingFailed = 1;
00752 return RPMRC_FAIL;
00753 }
00754
00755
00756 q = alloca((pe-p) + 1);
00757 strncpy(q, p, pe-p);
00758 q[pe-p] = '\0';
00759 while (p <= pe)
00760 *p++ = ' ';
00761
00762
00763 for (p = q; *p != '\0'; p = pe) {
00764 char *newp;
00765 size_t np;
00766 int i;
00767
00768 SKIPWHITE(p);
00769 pe = p;
00770 SKIPNONWHITE(pe);
00771
00772 np = pe - p;
00773
00774
00775 if (np < 1 || (np == 1 && *p != 'C') || np >= 32) {
00776 rpmlog(RPMLOG_ERR,
00777 _("Unusual locale length: \"%.*s\" in %%lang(%s)\n"),
00778 (int)np, p, q);
00779 fl->processingFailed = 1;
00780 return RPMRC_FAIL;
00781 }
00782
00783
00784 if (fl->currentLangs != NULL)
00785 for (i = 0; i < fl->nLangs; i++) {
00786 if (strncmp(fl->currentLangs[i], p, np))
00787 continue;
00788 rpmlog(RPMLOG_ERR, _("Duplicate locale %.*s in %%lang(%s)\n"),
00789 (int)np, p, q);
00790 fl->processingFailed = 1;
00791 return RPMRC_FAIL;
00792 }
00793
00794
00795 fl->currentLangs = xrealloc(fl->currentLangs,
00796 (fl->nLangs + 1) * sizeof(*fl->currentLangs));
00797 newp = xmalloc( np+1 );
00798 strncpy(newp, p, np);
00799 newp[np] = '\0';
00800 fl->currentLangs[fl->nLangs++] = newp;
00801 if (*pe == ',') pe++;
00802 }
00803 }
00804
00805
00806 if (fl->currentLangs)
00807 qsort(fl->currentLangs, fl->nLangs, sizeof(*fl->currentLangs), langCmp);
00808
00809 return RPMRC_OK;
00810 }
00811
00814 static int parseForRegexLang(const char * fileName, char ** lang)
00815
00816
00817 {
00818 static int initialized = 0;
00819 static int hasRegex = 0;
00820 static regex_t compiledPatt;
00821 static char buf[BUFSIZ];
00822 int x;
00823 regmatch_t matches[2];
00824 const char *s;
00825
00826 if (! initialized) {
00827 const char *patt = rpmExpand("%{?_langpatt}", NULL);
00828 int rc = 0;
00829 if (!(patt && *patt != '\0'))
00830 rc = 1;
00831 else if (regcomp(&compiledPatt, patt, REG_EXTENDED))
00832 rc = -1;
00833 patt = _free(patt);
00834 if (rc)
00835 return rc;
00836 hasRegex = 1;
00837 initialized = 1;
00838 }
00839
00840 memset(matches, 0, sizeof(matches));
00841 if (! hasRegex || regexec(&compiledPatt, fileName, 2, matches, REG_NOTEOL))
00842 return 1;
00843
00844
00845 s = fileName + matches[1].rm_eo - 1;
00846 x = matches[1].rm_eo - matches[1].rm_so;
00847 buf[x] = '\0';
00848 while (x) {
00849 buf[--x] = *s--;
00850 }
00851 if (lang)
00852 *lang = buf;
00853 return 0;
00854 }
00855
00858
00859
00860 VFA_t virtualFileAttributes[] = {
00861 { "%dir", 0, 0 },
00862 { "%doc", 0, RPMFILE_DOC },
00863 { "%ghost", 0, RPMFILE_GHOST },
00864 { "%exclude", 0, RPMFILE_EXCLUDE },
00865 { "%readme", 0, RPMFILE_README },
00866 { "%license", 0, RPMFILE_LICENSE },
00867 { "%pubkey", 0, RPMFILE_PUBKEY },
00868 { "%policy", 0, RPMFILE_POLICY },
00869 { "%optional", 0, RPMFILE_OPTIONAL },
00870
00871 #if WHY_NOT
00872 { "%icon", 0, RPMFILE_ICON },
00873 { "%spec", 0, RPMFILE_SPEC },
00874 { "%config", 0, RPMFILE_CONFIG },
00875 { "%missingok", 0, RPMFILE_CONFIG|RPMFILE_MISSINGOK },
00876 { "%noreplace", 0, RPMFILE_CONFIG|RPMFILE_NOREPLACE },
00877 #endif
00878
00879 { NULL, 0, 0 }
00880 };
00881
00882
00892 static rpmRC parseForSimple(Spec spec, Package pkg, char * buf,
00893 FileList fl, const char ** fileName)
00894
00895
00896
00897
00898
00899
00900 {
00901 char *s, *t;
00902 int specialDoc = 0;
00903 char specialDocBuf[BUFSIZ];
00904 rpmRC res = RPMRC_OK;
00905
00906 specialDocBuf[0] = '\0';
00907 *fileName = NULL;
00908
00909 t = buf;
00910 while ((s = strtokWithQuotes(t, " \t\n")) != NULL) {
00911 t = NULL;
00912 if (!strcmp(s, "%docdir")) {
00913 s = strtokWithQuotes(NULL, " \t\n");
00914 if (fl->docDirCount == MAXDOCDIR) {
00915 rpmlog(RPMLOG_CRIT, _("Hit limit for %%docdir\n"));
00916 fl->processingFailed = 1;
00917 res = RPMRC_FAIL;
00918 }
00919
00920 if (s != NULL)
00921 fl->docDirs[fl->docDirCount++] = xstrdup(s);
00922 if (s == NULL || strtokWithQuotes(NULL, " \t\n")) {
00923 rpmlog(RPMLOG_CRIT, _("Only one arg for %%docdir\n"));
00924 fl->processingFailed = 1;
00925 res = RPMRC_FAIL;
00926 }
00927 break;
00928 }
00929 #if defined(__LCLINT__)
00930 assert(s != NULL);
00931 #endif
00932
00933
00934 { VFA_t *vfa;
00935 for (vfa = virtualFileAttributes; vfa->attribute != NULL; vfa++) {
00936 if (strcmp(s, vfa->attribute))
00937 continue;
00938 if (!vfa->flag) {
00939 if (!strcmp(s, "%dir"))
00940 fl->isDir = 1;
00941 } else {
00942 if (vfa->not)
00943 fl->currentFlags &= ~vfa->flag;
00944 else
00945 fl->currentFlags |= vfa->flag;
00946 }
00947
00948 break;
00949 }
00950
00951 if (vfa->attribute != NULL)
00952 continue;
00953 }
00954
00955 if (*fileName) {
00956
00957 rpmlog(RPMLOG_ERR, _("Two files on one line: %s\n"),
00958 *fileName);
00959 fl->processingFailed = 1;
00960 res = RPMRC_FAIL;
00961 }
00962
00963 if (*s != '/') {
00964 if (fl->currentFlags & RPMFILE_DOC) {
00965 specialDoc = 1;
00966 strcat(specialDocBuf, " ");
00967 strcat(specialDocBuf, s);
00968 } else
00969 if (fl->currentFlags & (RPMFILE_POLICY|RPMFILE_PUBKEY|RPMFILE_ICON))
00970 {
00971 *fileName = s;
00972 } else {
00973 const char * sfn = NULL;
00974 int urltype = urlPath(s, &sfn);
00975 switch (urltype) {
00976 default:
00977 rpmlog(RPMLOG_ERR,
00978 _("File must begin with \"/\": %s\n"), s);
00979 fl->processingFailed = 1;
00980 res = RPMRC_FAIL;
00981 break;
00982 case URL_IS_PATH:
00983 *fileName = s;
00984 break;
00985 }
00986 }
00987 } else {
00988 *fileName = s;
00989 }
00990 }
00991
00992 if (specialDoc) {
00993 if (*fileName || (fl->currentFlags & ~(RPMFILE_DOC))) {
00994 rpmlog(RPMLOG_ERR,
00995 _("Can't mix special %%doc with other forms: %s\n"),
00996 (*fileName ? *fileName : ""));
00997 fl->processingFailed = 1;
00998 res = RPMRC_FAIL;
00999 } else {
01000
01001 {
01002
01003 static char *_docdir_fmt = NULL;
01004 static int oneshot = 0;
01005 const char *ddir, *fmt, *errstr;
01006 if (!oneshot) {
01007 _docdir_fmt = rpmExpand("%{?_docdir_fmt}", NULL);
01008 if (!(_docdir_fmt && *_docdir_fmt))
01009 _docdir_fmt = _free(_docdir_fmt);
01010 oneshot = 1;
01011 }
01012 if (_docdir_fmt == NULL)
01013 _docdir_fmt = xstrdup("%{NAME}-%{VERSION}");
01014 fmt = headerSprintf(pkg->header, _docdir_fmt, NULL, rpmHeaderFormats, &errstr);
01015 if (fmt == NULL) {
01016 rpmlog(RPMLOG_ERR, _("illegal _docdir_fmt: %s\n"), errstr);
01017 fl->processingFailed = 1;
01018 res = RPMRC_FAIL;
01019 } else {
01020 ddir = rpmGetPath("%{_docdir}/", fmt, NULL);
01021 strcpy(buf, ddir);
01022 ddir = _free(ddir);
01023 fmt = _free(fmt);
01024 }
01025 }
01026
01027
01028
01029 if (! fl->passedSpecialDoc) {
01030 char *compress_doc;
01031 char *mkdir_p;
01032
01033 pkg->specialDoc = newStringBuf();
01034 appendStringBuf(pkg->specialDoc, "DOCDIR=\"$RPM_BUILD_ROOT\"");
01035 appendLineStringBuf(pkg->specialDoc, buf);
01036 appendLineStringBuf(pkg->specialDoc, "export DOCDIR");
01037 appendLineStringBuf(pkg->specialDoc, "rm -rf \"$DOCDIR\"");
01038 mkdir_p = rpmExpand("%{?__mkdir_p}%{!?__mkdir_p:mkdir -p}", NULL);
01039 if (!mkdir_p)
01040 mkdir_p = xstrdup("mkdir -p");
01041 appendStringBuf(pkg->specialDoc, mkdir_p);
01042 mkdir_p = _free(mkdir_p);
01043 appendLineStringBuf(pkg->specialDoc, " \"$DOCDIR\"");
01044
01045 compress_doc = rpmExpand("%{__compress_doc}", NULL);
01046 if (compress_doc && *compress_doc != '%')
01047 appendLineStringBuf(pkg->specialDoc, compress_doc);
01048 compress_doc = _free(compress_doc);
01049
01050
01051 *fileName = buf;
01052
01053 fl->passedSpecialDoc = 1;
01054 fl->isSpecialDoc = 1;
01055 }
01056
01057 appendStringBuf(pkg->specialDoc, "cp -pr ");
01058 appendStringBuf(pkg->specialDoc, specialDocBuf);
01059 appendLineStringBuf(pkg->specialDoc, " \"$DOCDIR\"");
01060 }
01061 }
01062
01063 return res;
01064 }
01065
01068 static int compareFileListRecs(const void * ap, const void * bp)
01069 {
01070 const char *aurl = ((FileListRec)ap)->fileURL;
01071 const char *a = NULL;
01072 const char *burl = ((FileListRec)bp)->fileURL;
01073 const char *b = NULL;
01074 (void) urlPath(aurl, &a);
01075 (void) urlPath(burl, &b);
01076 return strcmp(a, b);
01077 }
01078
01085 static int isDoc(FileList fl, const char * fileName)
01086 {
01087 int x = fl->docDirCount;
01088 size_t k, l;
01089
01090 k = strlen(fileName);
01091 while (x--) {
01092 l = strlen(fl->docDirs[x]);
01093 if (l < k && strncmp(fileName, fl->docDirs[x], l) == 0 && fileName[l] == '/')
01094 return 1;
01095 }
01096 return 0;
01097 }
01098
01105 static int checkHardLinks(FileList fl)
01106
01107 {
01108 FileListRec ilp, jlp;
01109 int i, j;
01110
01111 for (i = 0; i < fl->fileListRecsUsed; i++) {
01112 ilp = fl->fileList + i;
01113 if (!(S_ISREG(ilp->fl_mode) && ilp->fl_nlink > 1))
01114 continue;
01115
01116 for (j = i + 1; j < fl->fileListRecsUsed; j++) {
01117 jlp = fl->fileList + j;
01118 if (!S_ISREG(jlp->fl_mode))
01119 continue;
01120 if (ilp->fl_nlink != jlp->fl_nlink)
01121 continue;
01122 if (ilp->fl_ino != jlp->fl_ino)
01123 continue;
01124 if (ilp->fl_dev != jlp->fl_dev)
01125 continue;
01126 return 1;
01127 }
01128 }
01129 return 0;
01130 }
01131
01132 static int dncmp(const void * a, const void * b)
01133
01134 {
01135 const char ** aurlp = (const char **)a;
01136 const char ** burlp = (const char **)b;
01137 const char * adn;
01138 const char * bdn;
01139 (void) urlPath(*aurlp, &adn);
01140 (void) urlPath(*burlp, &bdn);
01141 return strcmp(adn, bdn);
01142 }
01143
01148 static void compressFilelist(Header h)
01149
01150 {
01151 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
01152 const char ** fileNames;
01153 const char * fn;
01154 const char ** dirNames;
01155 const char ** baseNames;
01156 uint32_t * dirIndexes;
01157 int count;
01158 int dirIndex = -1;
01159 int xx;
01160 int i;
01161
01162
01163
01164
01165
01166
01167
01168 if (headerIsEntry(h, RPMTAG_DIRNAMES)) {
01169 he->tag = RPMTAG_OLDFILENAMES;
01170 xx = headerDel(h, he, 0);
01171 return;
01172 }
01173
01174 he->tag = RPMTAG_OLDFILENAMES;
01175 xx = headerGet(h, he, 0);
01176 fileNames = he->p.argv;
01177 count = he->c;
01178 if (!xx || fileNames == NULL || count <= 0)
01179 return;
01180
01181 dirNames = alloca(sizeof(*dirNames) * count);
01182 baseNames = alloca(sizeof(*dirNames) * count);
01183 dirIndexes = alloca(sizeof(*dirIndexes) * count);
01184
01185 (void) urlPath(fileNames[0], &fn);
01186 if (fn[0] != '/') {
01187
01188 dirIndex = 0;
01189 dirNames[dirIndex] = "";
01190 for (i = 0; i < count; i++) {
01191 dirIndexes[i] = dirIndex;
01192 baseNames[i] = fileNames[i];
01193 }
01194 goto exit;
01195 }
01196
01197 for (i = 0; i < count; i++) {
01198 const char ** needle;
01199 char savechar;
01200 char * baseName;
01201 size_t len;
01202
01203 if (fileNames[i] == NULL)
01204 continue;
01205 baseName = strrchr(fileNames[i], '/') + 1;
01206 len = baseName - fileNames[i];
01207 needle = dirNames;
01208 savechar = *baseName;
01209 *baseName = '\0';
01210
01211 if (dirIndex < 0 ||
01212 (needle = bsearch(&fileNames[i], dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) {
01213 char *s = alloca(len + 1);
01214 memcpy(s, fileNames[i], len + 1);
01215 s[len] = '\0';
01216 dirIndexes[i] = ++dirIndex;
01217 dirNames[dirIndex] = s;
01218 } else
01219 dirIndexes[i] = needle - dirNames;
01220
01221
01222 *baseName = savechar;
01223 baseNames[i] = baseName;
01224 }
01225
01226 exit:
01227 if (count > 0) {
01228 he->tag = RPMTAG_DIRINDEXES;
01229 he->t = RPM_UINT32_TYPE;
01230 he->p.ui32p = dirIndexes;
01231 he->c = count;
01232 xx = headerPut(h, he, 0);
01233
01234 he->tag = RPMTAG_BASENAMES;
01235 he->t = RPM_STRING_ARRAY_TYPE;
01236 he->p.argv = baseNames;
01237 he->c = count;
01238 xx = headerPut(h, he, 0);
01239
01240 he->tag = RPMTAG_DIRNAMES;
01241 he->t = RPM_STRING_ARRAY_TYPE;
01242 he->p.argv = dirNames;
01243 he->c = dirIndex + 1;
01244 xx = headerPut(h, he, 0);
01245 }
01246
01247 fileNames = _free(fileNames);
01248
01249 he->tag = RPMTAG_OLDFILENAMES;
01250 xx = headerDel(h, he, 0);
01251 }
01252
01262 static void genCpioListAndHeader( FileList fl,
01263 rpmfi * fip, Header h, int isSrc)
01264
01265
01266
01267 {
01268 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
01269 const char * apath;
01270 uint16_t ui16;
01271 uint32_t ui32;
01272 int _addDotSlash = !isSrc;
01273 int apathlen = 0;
01274 int dpathlen = 0;
01275 int skipLen = 0;
01276 security_context_t scon = NULL;
01277 const char * sxfn;
01278 size_t fnlen;
01279 FileListRec flp;
01280 char buf[BUFSIZ];
01281 int i, xx;
01282
01283
01284 qsort(fl->fileList, fl->fileListRecsUsed,
01285 sizeof(*(fl->fileList)), compareFileListRecs);
01286
01287
01288 if (! isSrc) {
01289 skipLen = 1;
01290 if (fl->prefix)
01291 skipLen += strlen(fl->prefix);
01292 }
01293
01294 sxfn = rpmGetPath("%{?_build_file_context_path}", NULL);
01295
01296 if (sxfn != NULL && *sxfn != '\0')
01297 xx = matchpathcon_init(sxfn);
01298
01299
01300 for (i = 0, flp = fl->fileList; i < fl->fileListRecsUsed; i++, flp++) {
01301 const char *s;
01302
01303
01304 while (i < (fl->fileListRecsUsed - 1) &&
01305 !strcmp(flp->fileURL, flp[1].fileURL)) {
01306
01307
01308
01309
01310
01311 flp[1].flags |= flp->flags;
01312
01313 if (!(flp[1].flags & RPMFILE_EXCLUDE))
01314 rpmlog(RPMLOG_WARNING, _("File listed twice: %s\n"),
01315 flp->fileURL);
01316
01317
01318 if (S_ISDIR(flp->fl_mode)) {
01319 if ((flp[1].specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)) <
01320 (flp->specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)))
01321 flp[1].fl_mode = flp->fl_mode;
01322 } else {
01323 if ((flp[1].specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)) <
01324 (flp->specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)))
01325 flp[1].fl_mode = flp->fl_mode;
01326 }
01327
01328
01329 if ((flp[1].specdFlags & (SPECD_UID | SPECD_DEFUID)) <
01330 (flp->specdFlags & (SPECD_UID | SPECD_DEFUID)))
01331 {
01332 flp[1].fl_uid = flp->fl_uid;
01333 flp[1].uname = flp->uname;
01334 }
01335
01336
01337 if ((flp[1].specdFlags & (SPECD_GID | SPECD_DEFGID)) <
01338 (flp->specdFlags & (SPECD_GID | SPECD_DEFGID)))
01339 {
01340 flp[1].fl_gid = flp->fl_gid;
01341 flp[1].gname = flp->gname;
01342 }
01343
01344
01345 if ((flp[1].specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)) <
01346 (flp->specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)))
01347 flp[1].verifyFlags = flp->verifyFlags;
01348
01349
01350
01351 flp++; i++;
01352 }
01353
01354
01355 if (flp->flags & RPMFILE_EXCLUDE) continue;
01356
01357
01358 (void) urlPath(flp->fileURL, &apath);
01359 apathlen += (strlen(apath) - skipLen + (_addDotSlash ? 3 : 1));
01360
01361
01362 dpathlen += (strlen(flp->diskURL) + 2);
01363
01364
01365
01366
01367
01368
01369 he->tag = RPMTAG_OLDFILENAMES;
01370 he->t = RPM_STRING_ARRAY_TYPE;
01371 he->p.argv = &flp->fileURL;
01372 he->c = 1;
01373 he->append = 1;
01374 xx = headerPut(h, he, 0);
01375 he->append = 0;
01376
01377
01378 ui32 = flp->fl_size;
01379 he->tag = RPMTAG_FILESIZES;
01380 he->t = RPM_UINT32_TYPE;
01381 he->p.ui32p = &ui32;
01382 he->c = 1;
01383 he->append = 1;
01384 xx = headerPut(h, he, 0);
01385 he->append = 0;
01386
01387 he->tag = RPMTAG_FILEUSERNAME;
01388 he->t = RPM_STRING_ARRAY_TYPE;
01389 he->p.argv = &flp->uname;
01390 he->c = 1;
01391 he->append = 1;
01392 xx = headerPut(h, he, 0);
01393 he->append = 0;
01394
01395 he->tag = RPMTAG_FILEGROUPNAME;
01396 he->t = RPM_STRING_ARRAY_TYPE;
01397 he->p.argv = &flp->gname;
01398 he->c = 1;
01399 he->append = 1;
01400 xx = headerPut(h, he, 0);
01401 he->append = 0;
01402
01403 ui32 = flp->fl_mtime;
01404 he->tag = RPMTAG_FILEMTIMES;
01405 he->t = RPM_UINT32_TYPE;
01406 he->p.ui32p = &ui32;
01407 he->c = 1;
01408 he->append = 1;
01409 xx = headerPut(h, he, 0);
01410 he->append = 0;
01411
01412 ui16 = flp->fl_mode;
01413 he->tag = RPMTAG_FILEMODES;
01414 he->t = RPM_UINT16_TYPE;
01415 he->p.ui16p = &ui16;
01416 he->c = 1;
01417 he->append = 1;
01418 xx = headerPut(h, he, 0);
01419 he->append = 0;
01420
01421 ui16 = flp->fl_rdev;
01422 he->tag = RPMTAG_FILERDEVS;
01423 he->t = RPM_UINT16_TYPE;
01424 he->p.ui16p = &ui16;
01425 he->c = 1;
01426 he->append = 1;
01427 xx = headerPut(h, he, 0);
01428 he->append = 0;
01429
01430 ui32 = flp->fl_dev;
01431 he->tag = RPMTAG_FILEDEVICES;
01432 he->t = RPM_UINT32_TYPE;
01433 he->p.ui32p = &ui32;
01434 he->c = 1;
01435 he->append = 1;
01436 xx = headerPut(h, he, 0);
01437 he->append = 0;
01438
01439 ui32 = flp->fl_ino;
01440 he->tag = RPMTAG_FILEINODES;
01441 he->t = RPM_UINT32_TYPE;
01442 he->p.ui32p = &ui32;
01443 he->c = 1;
01444 he->append = 1;
01445 xx = headerPut(h, he, 0);
01446 he->append = 0;
01447
01448
01449
01450 he->tag = RPMTAG_FILELANGS;
01451 he->t = RPM_STRING_ARRAY_TYPE;
01452 he->p.argv = &flp->langs;
01453 he->c = 1;
01454 he->append = 1;
01455 xx = headerPut(h, he, 0);
01456 he->append = 0;
01457
01458 { static uint32_t source_file_dalgo = 0;
01459 static uint32_t binary_file_dalgo = 0;
01460 static int oneshot = 0;
01461 uint32_t dalgo = 0;
01462
01463 if (!oneshot) {
01464 source_file_dalgo =
01465 rpmExpandNumeric("%{?_build_source_file_digest_algo}");
01466 binary_file_dalgo =
01467 rpmExpandNumeric("%{?_build_binary_file_digest_algo}");
01468 oneshot++;
01469 }
01470
01471 dalgo = (isSrc ? source_file_dalgo : binary_file_dalgo);
01472 switch (dalgo) {
01473 case PGPHASHALGO_SHA1:
01474 case PGPHASHALGO_RIPEMD160:
01475 case PGPHASHALGO_MD2:
01476 case PGPHASHALGO_TIGER192:
01477 case PGPHASHALGO_SHA256:
01478 case PGPHASHALGO_SHA384:
01479 case PGPHASHALGO_SHA512:
01480 case PGPHASHALGO_MD4:
01481 case PGPHASHALGO_RIPEMD128:
01482 case PGPHASHALGO_CRC32:
01483 case PGPHASHALGO_ADLER32:
01484 case PGPHASHALGO_CRC64:
01485 (void) rpmlibNeedsFeature(h, "FileDigestParameterized", "4.4.6-1");
01486 break;
01487 case PGPHASHALGO_MD5:
01488 case PGPHASHALGO_HAVAL_5_160:
01489 default:
01490 dalgo = PGPHASHALGO_MD5;
01491 break;
01492 }
01493
01494 buf[0] = '\0';
01495 if (S_ISREG(flp->fl_mode))
01496 (void) dodigest(dalgo, flp->diskURL, (unsigned char *)buf, 1, NULL);
01497 s = buf;
01498
01499 he->tag = RPMTAG_FILEDIGESTS;
01500 he->t = RPM_STRING_ARRAY_TYPE;
01501 he->p.argv = &s;
01502 he->c = 1;
01503 he->append = 1;
01504 xx = headerPut(h, he, 0);
01505 he->append = 0;
01506
01507 if (!(_rpmbuildFlags & 4)) {
01508 ui32 = dalgo;
01509 he->tag = RPMTAG_FILEDIGESTALGOS;
01510 he->t = RPM_UINT32_TYPE;
01511 he->p.ui32p = &ui32;
01512 he->c = 1;
01513 he->append = 1;
01514 xx = headerPut(h, he, 0);
01515 he->append = 0;
01516 }
01517 }
01518
01519 buf[0] = '\0';
01520 if (S_ISLNK(flp->fl_mode)) {
01521 xx = Readlink(flp->diskURL, buf, BUFSIZ);
01522 if (xx >= 0)
01523 buf[xx] = '\0';
01524 if (fl->buildRootURL) {
01525 const char * buildRoot;
01526 (void) urlPath(fl->buildRootURL, &buildRoot);
01527
01528 if (buf[0] == '/' && strcmp(buildRoot, "/") &&
01529 !strncmp(buf, buildRoot, strlen(buildRoot))) {
01530 rpmlog(RPMLOG_ERR,
01531 _("Symlink points to BuildRoot: %s -> %s\n"),
01532 flp->fileURL, buf);
01533 fl->processingFailed = 1;
01534 }
01535 }
01536 }
01537 s = buf;
01538 he->tag = RPMTAG_FILELINKTOS;
01539 he->t = RPM_STRING_ARRAY_TYPE;
01540 he->p.argv = &s;
01541 he->c = 1;
01542 he->append = 1;
01543 xx = headerPut(h, he, 0);
01544 he->append = 0;
01545
01546 if (flp->flags & RPMFILE_GHOST) {
01547 flp->verifyFlags &= ~(RPMVERIFY_MD5 | RPMVERIFY_FILESIZE |
01548 RPMVERIFY_LINKTO | RPMVERIFY_MTIME);
01549 }
01550 ui32 = flp->verifyFlags;
01551 he->tag = RPMTAG_FILEVERIFYFLAGS;
01552 he->t = RPM_UINT32_TYPE;
01553 he->p.ui32p = &ui32;
01554 he->c = 1;
01555 he->append = 1;
01556 xx = headerPut(h, he, 0);
01557 he->append = 0;
01558
01559 if (!isSrc && isDoc(fl, flp->fileURL))
01560 flp->flags |= RPMFILE_DOC;
01561
01562 if (S_ISDIR(flp->fl_mode))
01563 flp->flags &= ~(RPMFILE_CONFIG|RPMFILE_DOC);
01564
01565 ui32 = flp->flags;
01566 he->tag = RPMTAG_FILEFLAGS;
01567 he->t = RPM_UINT32_TYPE;
01568 he->p.ui32p = &ui32;
01569 he->c = 1;
01570 he->append = 1;
01571 xx = headerPut(h, he, 0);
01572 he->append = 0;
01573
01574
01575 if (!(_rpmbuildFlags & 4))
01576 {
01577 static char *nocon = "";
01578
01579 if (matchpathcon(flp->fileURL, flp->fl_mode, &scon) || scon == NULL)
01580 scon = nocon;
01581
01582
01583 he->tag = RPMTAG_FILECONTEXTS;
01584 he->t = RPM_STRING_ARRAY_TYPE;
01585 he->p.argv = (const char **)&scon;
01586 he->c = 1;
01587 he->append = 1;
01588 xx = headerPut(h, he, 0);
01589 he->append = 0;
01590
01591
01592 if (scon != nocon)
01593 freecon(scon);
01594
01595 }
01596 }
01597
01598 if (sxfn != NULL && *sxfn != '\0')
01599 matchpathcon_fini();
01600
01601 sxfn = _free(sxfn);
01602
01603 ui32 = fl->totalFileSize;
01604 he->tag = RPMTAG_SIZE;
01605 he->t = RPM_UINT32_TYPE;
01606 he->p.ui32p = &ui32;
01607 he->c = 1;
01608 he->append = 1;
01609 xx = headerPut(h, he, 0);
01610 he->append = 0;
01611
01612 if (_rpmbuildFlags & 4) {
01613 (void) rpmlibNeedsFeature(h, "PayloadFilesHavePrefix", "4.0-1");
01614 (void) rpmlibNeedsFeature(h, "CompressedFileNames", "3.0.4-1");
01615 }
01616
01617 compressFilelist(h);
01618
01619 { int scareMem = 0;
01620 rpmts ts = NULL;
01621 rpmfi fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
01622 char * a, * d;
01623
01624 if (fi == NULL) return;
01625
01626
01627 fi->te = xcalloc(1, sizeof(*fi->te));
01628
01629 fi->te->type = TR_ADDED;
01630
01631 fi->dnl = _free(fi->dnl);
01632 fi->bnl = _free(fi->bnl);
01633 if (!scareMem) fi->dil = _free(fi->dil);
01634
01635
01636 fi->dnl = xmalloc(fi->fc * sizeof(*fi->dnl) + dpathlen + 1);
01637 d = (char *)(fi->dnl + fi->fc);
01638 *d = '\0';
01639
01640 fi->bnl = xmalloc(fi->fc * (sizeof(*fi->bnl) + sizeof(*fi->dil)));
01641
01642 fi->dil = (!scareMem)
01643 ? xcalloc(sizeof(*fi->dil), fi->fc)
01644 : (uint32_t *)(fi->bnl + fi->fc);
01645
01646
01647
01648 fi->apath = xmalloc(fi->fc * sizeof(*fi->apath) + apathlen + 1);
01649 a = (char *)(fi->apath + fi->fc);
01650 *a = '\0';
01651
01652 fi->actions = _free(fi->actions);
01653 fi->actions = xcalloc(sizeof(*fi->actions), fi->fc);
01654 fi->fmapflags = xcalloc(sizeof(*fi->fmapflags), fi->fc);
01655 fi->astriplen = 0;
01656 if (fl->buildRootURL)
01657 fi->astriplen = strlen(fl->buildRootURL);
01658 fi->striplen = 0;
01659 fi->fuser = _free(fi->fuser);
01660 fi->fgroup = _free(fi->fgroup);
01661
01662
01663 if (fi->dil != NULL)
01664 for (i = 0, flp = fl->fileList; i < fi->fc; i++, flp++) {
01665 char * b;
01666
01667
01668 while (((flp - fl->fileList) < (fl->fileListRecsUsed - 1)) &&
01669 !strcmp(flp->fileURL, flp[1].fileURL))
01670 flp++;
01671
01672 if (flp->flags & RPMFILE_EXCLUDE) {
01673 i--;
01674 continue;
01675 }
01676
01677 if ((fnlen = strlen(flp->diskURL) + 1) > fi->fnlen)
01678 fi->fnlen = fnlen;
01679
01680
01681 fi->dil[i] = i;
01682
01683 fi->dnl[fi->dil[i]] = d;
01684
01685 d = stpcpy(d, flp->diskURL);
01686
01687
01688 for (b = d; b > fi->dnl[fi->dil[i]] && *b != '/'; b--)
01689 b[1] = b[0];
01690 b++;
01691 *b++ = '\0';
01692 fi->bnl[i] = b;
01693 d += 2;
01694
01695
01696
01697 fi->apath[i] = a;
01698
01699 if (_addDotSlash)
01700 a = stpcpy(a, "./");
01701 (void) urlPath(flp->fileURL, &apath);
01702 a = stpcpy(a, (apath + skipLen));
01703 a++;
01704
01705 if (flp->flags & RPMFILE_GHOST) {
01706 fi->actions[i] = FA_SKIP;
01707 continue;
01708 }
01709 fi->actions[i] = FA_COPYOUT;
01710 fi->fmapflags[i] = CPIO_MAP_PATH |
01711 CPIO_MAP_TYPE | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
01712 if (isSrc)
01713 fi->fmapflags[i] |= CPIO_FOLLOW_SYMLINKS;
01714
01715 }
01716
01717 if (fip)
01718 *fip = fi;
01719 else
01720 fi = rpmfiFree(fi);
01721
01722 }
01723 }
01724
01727 static FileListRec freeFileList( FileListRec fileList,
01728 int count)
01729
01730 {
01731 while (count--) {
01732 fileList[count].diskURL = _free(fileList[count].diskURL);
01733 fileList[count].fileURL = _free(fileList[count].fileURL);
01734 fileList[count].langs = _free(fileList[count].langs);
01735 }
01736 fileList = _free(fileList);
01737 return NULL;
01738 }
01739
01740
01741 static rpmRC recurseDir(FileList fl, const char * diskURL)
01742
01743
01744
01745
01746
01747
01748 ;
01749
01757 static int addFile(FileList fl, const char * diskURL,
01758 struct stat * statp)
01759
01760
01761
01762
01763
01764
01765
01766 {
01767 const char *fn = xstrdup(diskURL);
01768 const char *fileURL = fn;
01769 struct stat statbuf;
01770 mode_t fileMode;
01771 uid_t fileUid;
01772 gid_t fileGid;
01773 const char *fileUname;
01774 const char *fileGname;
01775 char *lang;
01776 rpmRC rc = RPMRC_OK;
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789 { const char *fileName;
01790 int urltype = urlPath(fileURL, &fileName);
01791 switch (urltype) {
01792 case URL_IS_PATH:
01793 fileURL += (fileName - fileURL);
01794 if (fl->buildRootURL && strcmp(fl->buildRootURL, "/")) {
01795 size_t nb = strlen(fl->buildRootURL);
01796 const char * s = fileURL + nb;
01797 char * t = (char *) fileURL;
01798 (void) memmove(t, s, nb);
01799 }
01800 fileURL = fn;
01801 break;
01802 default:
01803 if (fl->buildRootURL && strcmp(fl->buildRootURL, "/"))
01804 fileURL += strlen(fl->buildRootURL);
01805 break;
01806 }
01807 }
01808
01809
01810 if (*fileURL == '\0')
01811 fileURL = "/";
01812
01813
01814 if (!fl->inFtw && fl->prefix) {
01815 const char *prefixTest;
01816 const char *prefixPtr = fl->prefix;
01817
01818 (void) urlPath(fileURL, &prefixTest);
01819 while (*prefixPtr && *prefixTest && (*prefixTest == *prefixPtr)) {
01820 prefixPtr++;
01821 prefixTest++;
01822 }
01823 if (*prefixPtr || (*prefixTest && *prefixTest != '/')) {
01824 rpmlog(RPMLOG_ERR, _("File doesn't match prefix (%s): %s\n"),
01825 fl->prefix, fileURL);
01826 fl->processingFailed = 1;
01827 rc = RPMRC_FAIL;
01828 goto exit;
01829 }
01830 }
01831
01832 if (statp == NULL) {
01833 statp = &statbuf;
01834 memset(statp, 0, sizeof(*statp));
01835 if (fl->devtype) {
01836 time_t now = time(NULL);
01837
01838
01839 statp->st_nlink = 1;
01840 statp->st_rdev =
01841 ((fl->devmajor & 0xff) << 8) | (fl->devminor & 0xff);
01842 statp->st_dev = statp->st_rdev;
01843 statp->st_mode = (fl->devtype == 'b' ? S_IFBLK : S_IFCHR);
01844 statp->st_mode |= (fl->cur_ar.ar_fmode & 0777);
01845 statp->st_atime = now;
01846 statp->st_mtime = now;
01847 statp->st_ctime = now;
01848 } else if (Lstat(diskURL, statp)) {
01849 if (fl->currentFlags & RPMFILE_OPTIONAL) {
01850 rpmlog(RPMLOG_WARNING, _("Optional file not found: %s\n"), diskURL);
01851 rc = RPMRC_OK;
01852 } else {
01853 rpmlog(RPMLOG_ERR, _("File not found: %s\n"), diskURL);
01854 fl->processingFailed = 1;
01855 rc = RPMRC_FAIL;
01856 }
01857 goto exit;
01858 }
01859 }
01860
01861 if ((! fl->isDir) && S_ISDIR(statp->st_mode)) {
01862
01863 rc = recurseDir(fl, diskURL);
01864 goto exit;
01865
01866 }
01867
01868 fileMode = statp->st_mode;
01869 fileUid = statp->st_uid;
01870 fileGid = statp->st_gid;
01871
01872 if (S_ISDIR(fileMode) && fl->cur_ar.ar_dmodestr) {
01873 fileMode &= S_IFMT;
01874 fileMode |= fl->cur_ar.ar_dmode;
01875 } else if (fl->cur_ar.ar_fmodestr != NULL) {
01876 fileMode &= S_IFMT;
01877 fileMode |= fl->cur_ar.ar_fmode;
01878 }
01879 if (fl->cur_ar.ar_user) {
01880 fileUname = getUnameS(fl->cur_ar.ar_user);
01881 } else {
01882 fileUname = getUname(fileUid);
01883 }
01884 if (fl->cur_ar.ar_group) {
01885 fileGname = getGnameS(fl->cur_ar.ar_group);
01886 } else {
01887 fileGname = getGname(fileGid);
01888 }
01889
01890
01891 if (fileUname == NULL)
01892 fileUname = getUname(getuid());
01893 if (fileGname == NULL)
01894 fileGname = getGname(getgid());
01895
01896
01897 if (check_fileList && (S_ISREG(fileMode) || S_ISLNK(fileMode))) {
01898 const char * diskfn = NULL;
01899 (void) urlPath(diskURL, &diskfn);
01900 appendStringBuf(check_fileList, diskfn);
01901 appendStringBuf(check_fileList, "\n");
01902 }
01903
01904
01905 if (fl->fileListRecsUsed == fl->fileListRecsAlloced) {
01906 fl->fileListRecsAlloced += 128;
01907 fl->fileList = xrealloc(fl->fileList,
01908 fl->fileListRecsAlloced * sizeof(*(fl->fileList)));
01909 }
01910
01911 { FileListRec flp = &fl->fileList[fl->fileListRecsUsed];
01912 int i;
01913
01914 flp->fl_st = *statp;
01915 flp->fl_mode = fileMode;
01916 flp->fl_uid = fileUid;
01917 flp->fl_gid = fileGid;
01918
01919 flp->fileURL = xstrdup(fileURL);
01920 flp->diskURL = xstrdup(diskURL);
01921 flp->uname = fileUname;
01922 flp->gname = fileGname;
01923
01924 if (fl->currentLangs && fl->nLangs > 0) {
01925 char * ncl;
01926 size_t nl = 0;
01927
01928 for (i = 0; i < fl->nLangs; i++)
01929 nl += strlen(fl->currentLangs[i]) + 1;
01930
01931 flp->langs = ncl = xmalloc(nl);
01932 for (i = 0; i < fl->nLangs; i++) {
01933 const char *ocl;
01934 if (i) *ncl++ = '|';
01935 for (ocl = fl->currentLangs[i]; *ocl != '\0'; ocl++)
01936 *ncl++ = *ocl;
01937 *ncl = '\0';
01938 }
01939 } else if (! parseForRegexLang(fileURL, &lang)) {
01940 flp->langs = xstrdup(lang);
01941 } else {
01942 flp->langs = xstrdup("");
01943 }
01944
01945 flp->flags = fl->currentFlags;
01946 flp->specdFlags = fl->currentSpecdFlags;
01947 flp->verifyFlags = fl->currentVerifyFlags;
01948
01949
01950 if (S_ISREG(flp->fl_mode) && flp->fl_nlink > 1) {
01951 FileListRec ilp;
01952 for (i = 0; i < fl->fileListRecsUsed; i++) {
01953 ilp = fl->fileList + i;
01954 if (!S_ISREG(ilp->fl_mode))
01955 continue;
01956 if (flp->fl_nlink != ilp->fl_nlink)
01957 continue;
01958 if (flp->fl_ino != ilp->fl_ino)
01959 continue;
01960 if (flp->fl_dev != ilp->fl_dev)
01961 continue;
01962 break;
01963 }
01964 } else
01965 i = fl->fileListRecsUsed;
01966
01967 if (!(flp->flags & RPMFILE_EXCLUDE) && S_ISREG(flp->fl_mode) && i >= fl->fileListRecsUsed)
01968 fl->totalFileSize += flp->fl_size;
01969 }
01970
01971 fl->fileListRecsUsed++;
01972 fl->fileCount++;
01973
01974 exit:
01975 fn = _free(fn);
01976 return rc;
01977 }
01978
01985 static rpmRC recurseDir(FileList fl, const char * diskURL)
01986 {
01987 char * ftsSet[2];
01988 FTS * ftsp;
01989 FTSENT * fts;
01990 int myFtsOpts = (FTS_COMFOLLOW | FTS_NOCHDIR | FTS_PHYSICAL);
01991 rpmRC rc = RPMRC_FAIL;
01992
01993 fl->inFtw = 1;
01994 fl->isDir = 1;
01995
01996 ftsSet[0] = (char *) diskURL;
01997 ftsSet[1] = NULL;
01998 ftsp = Fts_open(ftsSet, myFtsOpts, NULL);
01999 while ((fts = Fts_read(ftsp)) != NULL) {
02000 switch (fts->fts_info) {
02001 case FTS_D:
02002 case FTS_F:
02003 case FTS_SL:
02004 case FTS_SLNONE:
02005 case FTS_DEFAULT:
02006 rc = addFile(fl, fts->fts_accpath, fts->fts_statp);
02007 break;
02008 case FTS_DOT:
02009 case FTS_DP:
02010 rc = 0;
02011 break;
02012 case FTS_NS:
02013 case FTS_DNR:
02014 case FTS_ERR:
02015 case FTS_DC:
02016 case FTS_NSOK:
02017 case FTS_INIT:
02018 case FTS_W:
02019 default:
02020 rc = RPMRC_FAIL;
02021 break;
02022 }
02023 if (rc != RPMRC_OK)
02024 break;
02025 }
02026 (void) Fts_close(ftsp);
02027
02028 fl->isDir = 0;
02029 fl->inFtw = 0;
02030
02031 return rc;
02032 }
02033
02042 static rpmRC processMetadataFile(Package pkg, FileList fl, const char * fileURL,
02043 rpmTag tag)
02044
02045
02046
02047
02048
02049
02050
02051 {
02052 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
02053 const char * buildURL = "%{_builddir}/%{?buildsubdir}/";
02054 const char * fn = NULL;
02055 const char * apkt = NULL;
02056 uint8_t * pkt = NULL;
02057 ssize_t pktlen = 0;
02058 int absolute = 0;
02059 rpmRC rc = RPMRC_FAIL;
02060 int xx;
02061
02062 (void) urlPath(fileURL, &fn);
02063 if (*fn == '/') {
02064 fn = rpmGenPath(fl->buildRootURL, NULL, fn);
02065 absolute = 1;
02066 } else
02067 fn = rpmGenPath(buildURL, NULL, fn);
02068
02069 switch (tag) {
02070 default:
02071 rpmlog(RPMLOG_ERR, _("%s: can't load unknown tag (%d).\n"),
02072 fn, tag);
02073 goto exit;
02074 break;
02075 case RPMTAG_PUBKEYS:
02076 if ((xx = pgpReadPkts(fn, (const uint8_t **)&pkt, (size_t *)&pktlen)) <= 0) {
02077 rpmlog(RPMLOG_ERR, _("%s: public key read failed.\n"), fn);
02078 goto exit;
02079 }
02080 if (xx != PGPARMOR_PUBKEY) {
02081 rpmlog(RPMLOG_ERR, _("%s: not an armored public key.\n"), fn);
02082 goto exit;
02083 }
02084 apkt = pgpArmorWrap(PGPARMOR_PUBKEY, pkt, pktlen);
02085 break;
02086 case RPMTAG_POLICIES:
02087 if ((xx = rpmioSlurp(fn, &pkt, &pktlen)) != 0) {
02088 rpmlog(RPMLOG_ERR, _("%s: *.te policy read failed.\n"), fn);
02089 goto exit;
02090 }
02091 apkt = (const char *) pkt;
02092 pkt = NULL;
02093 break;
02094 }
02095
02096 he->tag = tag;
02097 he->t = RPM_STRING_ARRAY_TYPE;
02098 he->p.argv = &apkt;
02099 he->c = 1;
02100 he->append = 1;
02101 xx = headerPut(pkg->header, he, 0);
02102 he->append = 0;
02103
02104 rc = RPMRC_OK;
02105 if (absolute)
02106 rc = addFile(fl, fn, NULL);
02107
02108 exit:
02109 apkt = _free(apkt);
02110 pkt = _free(pkt);
02111 fn = _free(fn);
02112 if (rc != RPMRC_OK)
02113 fl->processingFailed = 1;
02114 return rc;
02115 }
02116
02124 static rpmRC processBinaryFile( Package pkg, FileList fl,
02125 const char * fileURL)
02126
02127
02128
02129
02130
02131 {
02132 int quote = 1;
02133 int doGlob;
02134 const char *diskURL = NULL;
02135 rpmRC rc = RPMRC_OK;
02136 int xx;
02137
02138 doGlob = Glob_pattern_p(fileURL, quote);
02139
02140
02141 { const char * fileName;
02142 (void) urlPath(fileURL, &fileName);
02143 if (*fileName != '/') {
02144 rpmlog(RPMLOG_ERR, _("File needs leading \"/\": %s\n"),
02145 fileName);
02146 rc = RPMRC_FAIL;
02147 goto exit;
02148 }
02149 }
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159 diskURL = rpmGenPath(fl->buildRootURL, NULL, fileURL);
02160
02161 if (doGlob) {
02162 const char ** argv = NULL;
02163 int argc = 0;
02164 int i;
02165
02166
02167 if (fl->noGlob) {
02168 rpmlog(RPMLOG_ERR, _("Glob not permitted: %s\n"),
02169 diskURL);
02170 rc = RPMRC_FAIL;
02171 goto exit;
02172 }
02173
02174 xx = rpmGlob(diskURL, &argc, &argv);
02175 if (xx == 0 && argc >= 1) {
02176 for (i = 0; i < argc; i++) {
02177 rc = addFile(fl, argv[i], NULL);
02178 argv[i] = _free(argv[i]);
02179 }
02180 argv = _free(argv);
02181 } else {
02182 if (fl->currentFlags & RPMFILE_OPTIONAL) {
02183 rpmlog(RPMLOG_WARNING, _("Optional file not found by glob: %s\n"),
02184 diskURL);
02185 rc = RPMRC_OK;
02186 } else {
02187 rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"),
02188 diskURL);
02189 rc = RPMRC_FAIL;
02190 }
02191 goto exit;
02192 }
02193 } else
02194 rc = addFile(fl, diskURL, NULL);
02195
02196 exit:
02197 diskURL = _free(diskURL);
02198 if (rc != RPMRC_OK)
02199 fl->processingFailed = 1;
02200 return rc;
02201 }
02202
02205 static rpmRC processPackageFiles(Spec spec, Package pkg,
02206 int installSpecialDoc, int test)
02207
02208
02209
02210
02211
02212 {
02213 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
02214 struct FileList_s fl;
02215 char *s, **files, **fp;
02216 const char *fileName;
02217 char buf[BUFSIZ];
02218 struct AttrRec_s arbuf;
02219 AttrRec specialDocAttrRec = &arbuf;
02220 char *specialDoc = NULL;
02221 int xx;
02222
02223 nullAttrRec(specialDocAttrRec);
02224 pkg->cpioList = NULL;
02225
02226 if (pkg->fileFile) {
02227 char *saveptr;
02228 char *filesFiles = xstrdup(pkg->fileFile);
02229
02230 char *token = strtok_r(filesFiles, ",", &saveptr);
02231
02232 do {
02233 const char *ffn;
02234 FILE * f;
02235 FD_t fd;
02236
02237
02238 if (*token == '/') {
02239 ffn = rpmGetPath(token, NULL);
02240 } else {
02241
02242 ffn = rpmGetPath("%{_builddir}/",
02243 (spec->buildSubdir ? spec->buildSubdir : "") ,
02244 "/", token, NULL);
02245 }
02246
02247 fd = Fopen(ffn, "r.fpio");
02248
02249 if (fd == NULL || Ferror(fd)) {
02250 rpmlog(RPMLOG_ERR,
02251 _("Could not open %%files file %s: %s\n"),
02252 ffn, Fstrerror(fd));
02253 return RPMRC_FAIL;
02254 }
02255 ffn = _free(ffn);
02256
02257 f = fdGetFp(fd);
02258 if (f != NULL) {
02259 while (fgets(buf, sizeof(buf), f)) {
02260 handleComments(buf);
02261 if (expandMacros(spec, spec->macros, buf, sizeof(buf))) {
02262 rpmlog(RPMLOG_ERR, _("line: %s\n"), buf);
02263 return RPMRC_FAIL;
02264 }
02265 appendStringBuf(pkg->fileList, buf);
02266 }
02267 }
02268 (void) Fclose(fd);
02269 } while((token = strtok_r(NULL, ",", &saveptr)) != NULL);
02270 filesFiles = _free(filesFiles);
02271 }
02272
02273
02274 memset(&fl, 0, sizeof(fl));
02275
02276 fl.buildRootURL = rpmGenPath(spec->rootURL, "%{?buildroot}", NULL);
02277
02278 he->tag = RPMTAG_DEFAULTPREFIX;
02279 xx = headerGet(pkg->header, he, 0);
02280 fl.prefix = he->p.str;
02281
02282 fl.fileCount = 0;
02283 fl.totalFileSize = 0;
02284 fl.processingFailed = 0;
02285
02286 fl.passedSpecialDoc = 0;
02287 fl.isSpecialDoc = 0;
02288
02289 fl.isDir = 0;
02290 fl.inFtw = 0;
02291 fl.currentFlags = 0;
02292 fl.currentVerifyFlags = 0;
02293
02294 fl.noGlob = 0;
02295 fl.devtype = 0;
02296 fl.devmajor = 0;
02297 fl.devminor = 0;
02298
02299 nullAttrRec(&fl.cur_ar);
02300 nullAttrRec(&fl.def_ar);
02301 dupAttrRec(&root_ar, &fl.def_ar);
02302
02303 fl.defVerifyFlags = RPMVERIFY_ALL;
02304 fl.nLangs = 0;
02305 fl.currentLangs = NULL;
02306
02307 fl.currentSpecdFlags = 0;
02308 fl.defSpecdFlags = 0;
02309
02310 fl.docDirCount = 0;
02311 #if defined(RPM_VENDOR_OPENPKG)
02312
02313 #else
02314 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/doc");
02315 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/man");
02316 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/info");
02317 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/X11R6/man");
02318 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/share/doc");
02319 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/share/man");
02320 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/share/info");
02321 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/src/examples");
02322 fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_docdir}", NULL);
02323 fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_mandir}", NULL);
02324 fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_infodir}", NULL);
02325 fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_javadocdir}", NULL);
02326 fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_examplesdir}", NULL);
02327 #endif
02328
02329 fl.fileList = NULL;
02330 fl.fileListRecsAlloced = 0;
02331 fl.fileListRecsUsed = 0;
02332
02333 s = getStringBuf(pkg->fileList);
02334 files = splitString(s, strlen(s), '\n');
02335
02336 for (fp = files; *fp != NULL; fp++) {
02337 s = *fp;
02338 SKIPSPACE(s);
02339 if (*s == '\0')
02340 continue;
02341 fileName = NULL;
02342
02343 strcpy(buf, s);
02344
02345
02346
02347 fl.isDir = 0;
02348 fl.inFtw = 0;
02349 fl.currentFlags = 0;
02350
02351 fl.currentSpecdFlags = ((unsigned)fl.defSpecdFlags) >> 8;
02352 fl.currentVerifyFlags = fl.defVerifyFlags;
02353 fl.isSpecialDoc = 0;
02354
02355 fl.noGlob = 0;
02356 fl.devtype = 0;
02357 fl.devmajor = 0;
02358 fl.devminor = 0;
02359
02360
02361 if (fl.currentLangs) {
02362 int i;
02363 for (i = 0; i < fl.nLangs; i++)
02364
02365 fl.currentLangs[i] = _free(fl.currentLangs[i]);
02366
02367 fl.currentLangs = _free(fl.currentLangs);
02368 }
02369 fl.nLangs = 0;
02370
02371 dupAttrRec(&fl.def_ar, &fl.cur_ar);
02372
02373
02374 if (parseForVerify(buf, &fl) != RPMRC_OK)
02375 continue;
02376 if (parseForAttr(buf, &fl) != RPMRC_OK)
02377 continue;
02378 if (parseForDev(buf, &fl) != RPMRC_OK)
02379 continue;
02380 if (parseForConfig(buf, &fl) != RPMRC_OK)
02381 continue;
02382 if (parseForLang(buf, &fl) != RPMRC_OK)
02383 continue;
02384
02385 if (parseForSimple(spec, pkg, buf, &fl, &fileName) != RPMRC_OK)
02386
02387 continue;
02388
02389 if (fileName == NULL)
02390 continue;
02391
02392 if (fl.isSpecialDoc) {
02393
02394 specialDoc = _free(specialDoc);
02395 specialDoc = xstrdup(fileName);
02396 dupAttrRec(&fl.cur_ar, specialDocAttrRec);
02397 } else if (fl.currentFlags & RPMFILE_PUBKEY) {
02398
02399 (void) processMetadataFile(pkg, &fl, fileName, RPMTAG_PUBKEYS);
02400
02401 } else if (fl.currentFlags & RPMFILE_POLICY) {
02402
02403 (void) processMetadataFile(pkg, &fl, fileName, RPMTAG_POLICIES);
02404
02405 } else {
02406
02407 (void) processBinaryFile(pkg, &fl, fileName);
02408
02409 }
02410 }
02411
02412
02413 if (specialDoc) {
02414 if (installSpecialDoc) {
02415 int _missing_doc_files_terminate_build =
02416 rpmExpandNumeric("%{?_missing_doc_files_terminate_build}");
02417 rpmRC rc;
02418
02419 rc = doScript(spec, RPMBUILD_STRINGBUF, "%doc", pkg->specialDoc, test);
02420 if (rc != RPMRC_OK && _missing_doc_files_terminate_build)
02421 fl.processingFailed = 1;
02422 }
02423
02424
02425 fl.isDir = 0;
02426 fl.inFtw = 0;
02427 fl.currentFlags = 0;
02428 fl.currentVerifyFlags = fl.defVerifyFlags;
02429
02430 fl.noGlob = 0;
02431 fl.devtype = 0;
02432 fl.devmajor = 0;
02433 fl.devminor = 0;
02434
02435
02436 if (fl.currentLangs) {
02437 int i;
02438 for (i = 0; i < fl.nLangs; i++)
02439
02440 fl.currentLangs[i] = _free(fl.currentLangs[i]);
02441
02442 fl.currentLangs = _free(fl.currentLangs);
02443 }
02444 fl.nLangs = 0;
02445
02446 dupAttrRec(specialDocAttrRec, &fl.cur_ar);
02447 freeAttrRec(specialDocAttrRec);
02448
02449
02450 (void) processBinaryFile(pkg, &fl, specialDoc);
02451
02452
02453 specialDoc = _free(specialDoc);
02454 }
02455
02456 freeSplitString(files);
02457
02458 if (fl.processingFailed)
02459 goto exit;
02460
02461
02462 if (checkHardLinks(&fl))
02463 (void) rpmlibNeedsFeature(pkg->header,
02464 "PartialHardlinkSets", "4.0.4-1");
02465
02466 genCpioListAndHeader(&fl, &pkg->cpioList, pkg->header, 0);
02467
02468 if (spec->timeCheck)
02469 timeCheck(spec->timeCheck, pkg->header);
02470
02471 exit:
02472 fl.buildRootURL = _free(fl.buildRootURL);
02473 fl.prefix = _free(fl.prefix);
02474
02475 freeAttrRec(&fl.cur_ar);
02476 freeAttrRec(&fl.def_ar);
02477
02478 if (fl.currentLangs) {
02479 int i;
02480 for (i = 0; i < fl.nLangs; i++)
02481
02482 fl.currentLangs[i] = _free(fl.currentLangs[i]);
02483
02484 fl.currentLangs = _free(fl.currentLangs);
02485 }
02486
02487 fl.fileList = freeFileList(fl.fileList, fl.fileListRecsUsed);
02488 while (fl.docDirCount--)
02489 fl.docDirs[fl.docDirCount] = _free(fl.docDirs[fl.docDirCount]);
02490 return (fl.processingFailed ? RPMRC_FAIL : RPMRC_OK);
02491 }
02492
02493 int initSourceHeader(Spec spec, StringBuf *sfp)
02494 {
02495 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
02496 HeaderIterator hi;
02497 StringBuf sourceFiles;
02498 struct Source *srcPtr;
02499 static rpmTag classTag = 0xffffffff;
02500 int xx;
02501 int i;
02502
02503 if (classTag == 0xffffffff)
02504 classTag = tagValue("Class");
02505
02506
02507 if (!spec->sourceHdrInit) {
02508 for (hi = headerInit(spec->packages->header);
02509 headerNext(hi, he, 0);
02510 he->p.ptr = _free(he->p.ptr))
02511 {
02512 switch (he->tag) {
02513 case RPMTAG_NAME:
02514 case RPMTAG_VERSION:
02515 case RPMTAG_RELEASE:
02516 case RPMTAG_EPOCH:
02517 case RPMTAG_SUMMARY:
02518 case RPMTAG_DESCRIPTION:
02519 case RPMTAG_PACKAGER:
02520 case RPMTAG_DISTRIBUTION:
02521 case RPMTAG_DISTURL:
02522 case RPMTAG_VENDOR:
02523 case RPMTAG_LICENSE:
02524 case RPMTAG_GROUP:
02525 case RPMTAG_OS:
02526 case RPMTAG_ARCH:
02527 case RPMTAG_CHANGELOGTIME:
02528 case RPMTAG_CHANGELOGNAME:
02529 case RPMTAG_CHANGELOGTEXT:
02530 case RPMTAG_URL:
02531 case RPMTAG_ICON:
02532 case RPMTAG_GIF:
02533 case RPMTAG_XPM:
02534 case HEADER_I18NTABLE:
02535 #if defined(RPM_VENDOR_OPENPKG)
02536
02537 case RPMTAG_PROVIDENAME:
02538 case RPMTAG_PROVIDEVERSION:
02539 case RPMTAG_PROVIDEFLAGS:
02540 #endif
02541 if (he->p.ptr)
02542 xx = headerPut(spec->sourceHeader, he, 0);
02543 break;
02544 default:
02545 if (classTag == he->tag && he->p.ptr != NULL)
02546 xx = headerPut(spec->sourceHeader, he, 0);
02547 break;
02548 }
02549 }
02550 hi = headerFini(hi);
02551
02552 if (spec->BANames && spec->BACount > 0) {
02553 he->tag = RPMTAG_BUILDARCHS;
02554 he->t = RPM_STRING_ARRAY_TYPE;
02555 he->p.argv = spec->BANames;
02556 he->c = spec->BACount;
02557 xx = headerPut(spec->sourceHeader, he, 0);
02558 }
02559
02560
02561 if (spec->foo)
02562 for (i = 0; i < spec->nfoo; i++) {
02563 const char * str = spec->foo[i].str;
02564 rpmTag tag = spec->foo[i].tag;
02565 StringBuf sb = spec->foo[i].val;
02566 char * s;
02567
02568 if (str == NULL || sb == NULL)
02569 continue;
02570
02571
02572 if (!xstrcasecmp(str, "track")) {
02573 he->p.str = rpmExpand("%{?__vcheck}", NULL);
02574 if (!(he->p.str != NULL && he->p.str[0] != '\0')) {
02575 he->p.str = _free(he->p.str);
02576 continue;
02577 }
02578 he->tag = tagValue("Trackprog");
02579 he->t = RPM_STRING_TYPE;
02580 he->c = 1;
02581 xx = headerPut(spec->sourceHeader, he, 0);
02582 he->p.str = _free(he->p.str);
02583 }
02584
02585 s = getStringBuf(sb);
02586 he->tag = tag;
02587 he->append = headerIsEntry(spec->sourceHeader, tag);
02588 if (he->append) {
02589 he->t = RPM_STRING_ARRAY_TYPE;
02590 he->p.argv = (const char **) &s;
02591 he->c = 1;
02592 } else {
02593 he->t = RPM_STRING_TYPE;
02594 he->p.str = s;
02595 he->c = 1;
02596 }
02597 xx = headerPut(spec->sourceHeader, he, 0);
02598 he->append = 0;
02599 }
02600 }
02601
02602 if (sfp != NULL && *sfp != NULL)
02603 sourceFiles = *sfp;
02604 else
02605 sourceFiles = newStringBuf();
02606
02607
02608 appendLineStringBuf(sourceFiles, spec->specFile);
02609 if (spec->sourceHeader != NULL)
02610 for (srcPtr = spec->sources; srcPtr != NULL; srcPtr = srcPtr->next) {
02611 { const char * sfn;
02612
02613 sfn = rpmGetPath( ((srcPtr->flags & RPMFILE_GHOST) ? "!" : ""),
02614 #if defined(RPM_VENDOR_OPENPKG)
02615 getSourceDir(srcPtr->flags, srcPtr->source), srcPtr->source, NULL);
02616 #else
02617 getSourceDir(srcPtr->flags), srcPtr->source, NULL);
02618 #endif
02619
02620 appendLineStringBuf(sourceFiles, sfn);
02621 sfn = _free(sfn);
02622 }
02623
02624 if (spec->sourceHdrInit)
02625 continue;
02626
02627 if (srcPtr->flags & RPMFILE_SOURCE) {
02628 he->tag = RPMTAG_SOURCE;
02629 he->t = RPM_STRING_ARRAY_TYPE;
02630 he->p.argv = &srcPtr->source;
02631 he->c = 1;
02632 he->append = 1;
02633 xx = headerPut(spec->sourceHeader, he, 0);
02634 he->append = 0;
02635 if (srcPtr->flags & RPMFILE_GHOST) {
02636 he->tag = RPMTAG_NOSOURCE;
02637 he->t = RPM_UINT32_TYPE;
02638 he->p.ui32p = &srcPtr->num;
02639 he->c = 1;
02640 he->append = 1;
02641 xx = headerPut(spec->sourceHeader, he, 0);
02642 he->append = 0;
02643 }
02644 }
02645 if (srcPtr->flags & RPMFILE_PATCH) {
02646 he->tag = RPMTAG_PATCH;
02647 he->t = RPM_STRING_ARRAY_TYPE;
02648 he->p.argv = &srcPtr->source;
02649 he->c = 1;
02650 he->append = 1;
02651 xx = headerPut(spec->sourceHeader, he, 0);
02652 he->append = 0;
02653 if (srcPtr->flags & RPMFILE_GHOST) {
02654 he->tag = RPMTAG_NOPATCH;
02655 he->t = RPM_UINT32_TYPE;
02656 he->p.ui32p = &srcPtr->num;
02657 he->c = 1;
02658 he->append = 1;
02659 xx = headerPut(spec->sourceHeader, he, 0);
02660 he->append = 0;
02661 }
02662 }
02663 }
02664
02665 if (sfp == NULL)
02666 sourceFiles = freeStringBuf(sourceFiles);
02667
02668 spec->sourceHdrInit = 1;
02669
02670 return 0;
02671 }
02672
02673 int processSourceFiles(Spec spec)
02674 {
02675 StringBuf sourceFiles, *sfp = &sourceFiles;
02676 int x, isSpec = 1;
02677 struct FileList_s fl;
02678 char **files, **fp;
02679 int rc;
02680 #if defined(RPM_VENDOR_OPENPKG)
02681
02682 char _srcdefattr_buf[BUFSIZ];
02683 char *_srcdefattr;
02684 #endif
02685
02686 #if defined(RPM_VENDOR_OPENPKG)
02687 _srcdefattr = rpmExpand("%{?_srcdefattr}", NULL);
02688 #endif
02689
02690 *sfp = newStringBuf();
02691 x = initSourceHeader(spec, sfp);
02692
02693 #if defined(RPM_VENDOR_OPENPKG)
02694
02695 memset(&fl, 0, sizeof(fl));
02696 if (_srcdefattr && *_srcdefattr) {
02697 snprintf(_srcdefattr_buf, sizeof(_srcdefattr_buf), "%%defattr %s", _srcdefattr);
02698 parseForAttr(_srcdefattr_buf, &fl);
02699 }
02700 #endif
02701
02702
02703 fl.fileList = xcalloc((spec->numSources + 1), sizeof(*fl.fileList));
02704 rc = fl.processingFailed = 0;
02705 fl.fileListRecsUsed = 0;
02706 fl.totalFileSize = 0;
02707 fl.prefix = NULL;
02708 fl.buildRootURL = NULL;
02709
02710 { const char *s = getStringBuf(*sfp);
02711 files = splitString(s, strlen(s), '\n');
02712 }
02713
02714
02715 x = 0;
02716 for (fp = files; *fp != NULL; fp++) {
02717 const char * diskURL, *diskPath;
02718 FileListRec flp;
02719
02720 diskURL = *fp;
02721 SKIPSPACE(diskURL);
02722 if (! *diskURL)
02723 continue;
02724
02725 flp = &fl.fileList[x];
02726
02727 flp->flags = isSpec ? RPMFILE_SPECFILE : 0;
02728
02729 if (*diskURL == '!') {
02730 flp->flags |= RPMFILE_GHOST;
02731 diskURL++;
02732 }
02733
02734 (void) urlPath(diskURL, &diskPath);
02735
02736 flp->diskURL = xstrdup(diskURL);
02737 diskPath = strrchr(diskPath, '/');
02738 if (diskPath)
02739 diskPath++;
02740 else
02741 diskPath = diskURL;
02742
02743 flp->fileURL = xstrdup(diskPath);
02744 flp->verifyFlags = RPMVERIFY_ALL;
02745
02746 if (Stat(diskURL, &flp->fl_st)) {
02747 rpmlog(RPMLOG_ERR, _("Bad file: %s: %s\n"),
02748 diskURL, strerror(errno));
02749 rc = fl.processingFailed = 1;
02750 }
02751
02752 #if defined(RPM_VENDOR_OPENPKG)
02753
02754 if (fl.def_ar.ar_fmodestr) {
02755 flp->fl_mode &= S_IFMT;
02756 flp->fl_mode |= fl.def_ar.ar_fmode;
02757 }
02758 flp->uname = fl.def_ar.ar_user ? getUnameS(fl.def_ar.ar_user) : getUname(flp->fl_uid);
02759 flp->gname = fl.def_ar.ar_group ? getGnameS(fl.def_ar.ar_group) : getGname(flp->fl_gid);
02760 #else
02761 flp->uname = getUname(flp->fl_uid);
02762 flp->gname = getGname(flp->fl_gid);
02763 #endif
02764 flp->langs = xstrdup("");
02765
02766 fl.totalFileSize += flp->fl_size;
02767
02768 if (! (flp->uname && flp->gname)) {
02769 rpmlog(RPMLOG_ERR, _("Bad owner/group: %s\n"), diskURL);
02770 rc = fl.processingFailed = 1;
02771 }
02772
02773 isSpec = 0;
02774 x++;
02775 }
02776 fl.fileListRecsUsed = x;
02777 freeSplitString(files);
02778
02779 if (rc)
02780 goto exit;
02781
02782 spec->sourceCpioList = NULL;
02783 genCpioListAndHeader(&fl, &spec->sourceCpioList, spec->sourceHeader, 1);
02784
02785 exit:
02786 *sfp = freeStringBuf(*sfp);
02787 fl.fileList = freeFileList(fl.fileList, fl.fileListRecsUsed);
02788 return rc;
02789 }
02790
02796 static int checkFiles(StringBuf fileList)
02797
02798
02799 {
02800
02801 static const char * av_ckfile[] = { "%{?__check_files}", NULL };
02802
02803 StringBuf sb_stdout = NULL;
02804 const char * s;
02805 int rc;
02806
02807 s = rpmExpand(av_ckfile[0], NULL);
02808 if (!(s && *s)) {
02809 rc = -1;
02810 goto exit;
02811 }
02812 rc = 0;
02813
02814 rpmlog(RPMLOG_NOTICE, _("Checking for unpackaged file(s): %s\n"), s);
02815
02816 rc = rpmfcExec(av_ckfile, fileList, &sb_stdout, 0);
02817 if (rc < 0)
02818 goto exit;
02819
02820 if (sb_stdout) {
02821 int _unpackaged_files_terminate_build =
02822 rpmExpandNumeric("%{?_unpackaged_files_terminate_build}");
02823 const char * t;
02824
02825 t = getStringBuf(sb_stdout);
02826 if ((*t != '\0') && (*t != '\n')) {
02827 rc = (_unpackaged_files_terminate_build) ? 1 : 0;
02828 rpmlog((rc ? RPMLOG_ERR : RPMLOG_WARNING),
02829 _("Installed (but unpackaged) file(s) found:\n%s"), t);
02830 }
02831 }
02832
02833 exit:
02834 sb_stdout = freeStringBuf(sb_stdout);
02835 s = _free(s);
02836 return rc;
02837 }
02838
02839
02840 rpmRC processBinaryFiles(Spec spec, int installSpecialDoc, int test)
02841
02842
02843 {
02844 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
02845 Package pkg;
02846 rpmRC res = RPMRC_OK;
02847 int xx;
02848
02849 check_fileList = newStringBuf();
02850
02851 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
02852 int rc;
02853
02854 if (pkg->fileList == NULL)
02855 continue;
02856
02857 (void) headerMacrosLoad(pkg->header);
02858
02859 he->tag = RPMTAG_NVRA;
02860 xx = headerGet(pkg->header, he, 0);
02861 rpmlog(RPMLOG_NOTICE, _("Processing files: %s\n"), he->p.str);
02862 he->p.ptr = _free(he->p.ptr);
02863
02864 if ((xx = processPackageFiles(spec, pkg, installSpecialDoc, test)))
02865 res = RPMRC_FAIL;
02866
02867
02868 if ((rc = processScriptFiles(spec, pkg)))
02869 res = rc;
02870
02871 if ((xx = rpmfcGenerateDepends(spec, pkg)))
02872 res = RPMRC_FAIL;
02873
02874
02875 providePackageNVR(pkg->header);
02876
02877 (void) headerMacrosUnload(pkg->header);
02878 }
02879
02880
02881
02882
02883
02884
02885 if (checkFiles(check_fileList) > 0) {
02886 if (res == RPMRC_OK)
02887 res = RPMRC_FAIL;
02888 }
02889
02890 check_fileList = freeStringBuf(check_fileList);
02891
02892 return res;
02893 }
02894