00001
00007 #include "system.h"
00008
00009 #define MYALLPERMS 07777
00010
00011 #include <regex.h>
00012
00013 #include <rpmio_internal.h>
00014 #include <fts.h>
00015
00016 #include <rpmbuild.h>
00017
00018 #include "cpio.h"
00019
00020 #include "argv.h"
00021 #include "rpmfc.h"
00022
00023 #define _RPMFI_INTERNAL
00024 #include "rpmfi.h"
00025
00026 #include "rpmsx.h"
00027
00028 #define _RPMTE_INTERNAL
00029 #include "rpmte.h"
00030
00031 #include "buildio.h"
00032
00033 #include "legacy.h"
00034 #include "misc.h"
00035 #include "debug.h"
00036
00037
00038
00039
00040
00041
00042
00043 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
00044 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
00045
00046 #define MAXDOCDIR 1024
00047
00050 typedef enum specdFlags_e {
00051 SPECD_DEFFILEMODE = (1 << 0),
00052 SPECD_DEFDIRMODE = (1 << 1),
00053 SPECD_DEFUID = (1 << 2),
00054 SPECD_DEFGID = (1 << 3),
00055 SPECD_DEFVERIFY = (1 << 4),
00056
00057 SPECD_FILEMODE = (1 << 8),
00058 SPECD_DIRMODE = (1 << 9),
00059 SPECD_UID = (1 << 10),
00060 SPECD_GID = (1 << 11),
00061 SPECD_VERIFY = (1 << 12)
00062 } specdFlags;
00063
00066 typedef struct FileListRec_s {
00067 struct stat fl_st;
00068 #define fl_dev fl_st.st_dev
00069 #define fl_ino fl_st.st_ino
00070 #define fl_mode fl_st.st_mode
00071 #define fl_nlink fl_st.st_nlink
00072 #define fl_uid fl_st.st_uid
00073 #define fl_gid fl_st.st_gid
00074 #define fl_rdev fl_st.st_rdev
00075 #define fl_size fl_st.st_size
00076 #define fl_mtime fl_st.st_mtime
00077
00078
00079 const char *diskURL;
00080
00081 const char *fileURL;
00082
00083 const char *uname;
00084
00085 const char *gname;
00086 unsigned flags;
00087 specdFlags specdFlags;
00088 unsigned verifyFlags;
00089
00090 const char *langs;
00091 } * FileListRec;
00092
00095 typedef struct AttrRec_s {
00096 const char *ar_fmodestr;
00097 const char *ar_dmodestr;
00098 const char *ar_user;
00099 const char *ar_group;
00100 mode_t ar_fmode;
00101 mode_t ar_dmode;
00102 } * AttrRec;
00103
00104
00105
00106 static StringBuf check_fileList = NULL;
00107
00111 typedef struct FileList_s {
00112
00113 const char * buildRootURL;
00114
00115 const char * prefix;
00116
00117 int fileCount;
00118 int totalFileSize;
00119 int processingFailed;
00120
00121 int passedSpecialDoc;
00122 int isSpecialDoc;
00123
00124 int noGlob;
00125 unsigned devtype;
00126 unsigned devmajor;
00127 int devminor;
00128
00129 int isDir;
00130 int inFtw;
00131 int currentFlags;
00132 specdFlags currentSpecdFlags;
00133 int currentVerifyFlags;
00134 struct AttrRec_s cur_ar;
00135 struct AttrRec_s def_ar;
00136 specdFlags defSpecdFlags;
00137 int defVerifyFlags;
00138 int nLangs;
00139
00140 const char ** currentLangs;
00141
00142
00143
00144 const char * docDirs[MAXDOCDIR];
00145 int docDirCount;
00146
00147
00148 FileListRec fileList;
00149 int fileListRecsAlloced;
00150 int fileListRecsUsed;
00151 } * FileList;
00152
00155 static void nullAttrRec( AttrRec ar)
00156 {
00157 ar->ar_fmodestr = NULL;
00158 ar->ar_dmodestr = NULL;
00159 ar->ar_user = NULL;
00160 ar->ar_group = NULL;
00161 ar->ar_fmode = 0;
00162 ar->ar_dmode = 0;
00163 }
00164
00167 static void freeAttrRec(AttrRec ar)
00168 {
00169 ar->ar_fmodestr = _free(ar->ar_fmodestr);
00170 ar->ar_dmodestr = _free(ar->ar_dmodestr);
00171 ar->ar_user = _free(ar->ar_user);
00172 ar->ar_group = _free(ar->ar_group);
00173
00174
00175 return;
00176
00177 }
00178
00181 static void dupAttrRec(const AttrRec oar, AttrRec nar)
00182
00183 {
00184 if (oar == nar)
00185 return;
00186 freeAttrRec(nar);
00187 nar->ar_fmodestr = (oar->ar_fmodestr ? xstrdup(oar->ar_fmodestr) : NULL);
00188 nar->ar_dmodestr = (oar->ar_dmodestr ? xstrdup(oar->ar_dmodestr) : NULL);
00189 nar->ar_user = (oar->ar_user ? xstrdup(oar->ar_user) : NULL);
00190 nar->ar_group = (oar->ar_group ? xstrdup(oar->ar_group) : NULL);
00191 nar->ar_fmode = oar->ar_fmode;
00192 nar->ar_dmode = oar->ar_dmode;
00193 }
00194
00195 #if 0
00196
00198 static void dumpAttrRec(const char * msg, AttrRec ar)
00199
00200
00201 {
00202 if (msg)
00203 fprintf(stderr, "%s:\t", msg);
00204 fprintf(stderr, "(%s, %s, %s, %s)\n",
00205 ar->ar_fmodestr,
00206 ar->ar_user,
00207 ar->ar_group,
00208 ar->ar_dmodestr);
00209 }
00210 #endif
00211
00216
00217
00218 static char *strtokWithQuotes( char *s, char *delim)
00219
00220 {
00221 static char *olds = NULL;
00222 char *token;
00223
00224 if (s == NULL)
00225 s = olds;
00226 if (s == NULL)
00227 return NULL;
00228
00229
00230 s += strspn(s, delim);
00231 if (*s == '\0')
00232 return NULL;
00233
00234
00235 token = s;
00236 if (*token == '"') {
00237 token++;
00238
00239 s = strchr(token, '"');
00240 } else {
00241 s = strpbrk(token, delim);
00242 }
00243
00244
00245 if (s == NULL) {
00246
00247 olds = strchr(token, '\0');
00248 } else {
00249
00250 *s = '\0';
00251 olds = s+1;
00252 }
00253
00254
00255 return token;
00256
00257 }
00258
00259
00262 static void timeCheck(int tc, Header h)
00263
00264
00265 {
00266 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00267 HFD_t hfd = headerFreeData;
00268 int * mtime;
00269 const char ** files;
00270 rpmTagType fnt;
00271 int count, x;
00272 time_t currentTime = time(NULL);
00273
00274 x = hge(h, RPMTAG_OLDFILENAMES, &fnt, (void **) &files, &count);
00275 x = hge(h, RPMTAG_FILEMTIMES, NULL, (void **) &mtime, NULL);
00276
00277
00278 for (x = 0; x < count; x++) {
00279 if ((currentTime - mtime[x]) > tc)
00280 rpmMessage(RPMMESS_WARNING, _("TIMECHECK failure: %s\n"), files[x]);
00281 }
00282 files = hfd(files, fnt);
00283
00284 }
00285
00288 typedef struct VFA {
00289 const char * attribute;
00290 int not;
00291 int flag;
00292 } VFA_t;
00293
00296
00297
00298 VFA_t verifyAttrs[] = {
00299 { "md5", 0, RPMVERIFY_MD5 },
00300 { "size", 0, RPMVERIFY_FILESIZE },
00301 { "link", 0, RPMVERIFY_LINKTO },
00302 { "user", 0, RPMVERIFY_USER },
00303 { "group", 0, RPMVERIFY_GROUP },
00304 { "mtime", 0, RPMVERIFY_MTIME },
00305 { "mode", 0, RPMVERIFY_MODE },
00306 { "rdev", 0, RPMVERIFY_RDEV },
00307 { NULL, 0, 0 }
00308 };
00309
00310
00317
00318 static int parseForVerify(char * buf, FileList fl)
00319
00320
00321
00322 {
00323 char *p, *pe, *q;
00324 const char *name;
00325 int *resultVerify;
00326 int negated;
00327 int verifyFlags;
00328 specdFlags * specdFlags;
00329
00330 if ((p = strstr(buf, (name = "%verify"))) != NULL) {
00331 resultVerify = &(fl->currentVerifyFlags);
00332 specdFlags = &fl->currentSpecdFlags;
00333 } else if ((p = strstr(buf, (name = "%defverify"))) != NULL) {
00334 resultVerify = &(fl->defVerifyFlags);
00335 specdFlags = &fl->defSpecdFlags;
00336 } else
00337 return 0;
00338
00339 for (pe = p; (pe-p) < strlen(name); pe++)
00340 *pe = ' ';
00341
00342 SKIPSPACE(pe);
00343
00344 if (*pe != '(') {
00345 rpmError(RPMERR_BADSPEC, _("Missing '(' in %s %s\n"), name, pe);
00346 fl->processingFailed = 1;
00347 return RPMERR_BADSPEC;
00348 }
00349
00350
00351 *pe++ = ' ';
00352 for (p = pe; *pe && *pe != ')'; pe++)
00353 {};
00354
00355 if (*pe == '\0') {
00356 rpmError(RPMERR_BADSPEC, _("Missing ')' in %s(%s\n"), name, p);
00357 fl->processingFailed = 1;
00358 return RPMERR_BADSPEC;
00359 }
00360
00361
00362 q = alloca((pe-p) + 1);
00363 strncpy(q, p, pe-p);
00364 q[pe-p] = '\0';
00365 while (p <= pe)
00366 *p++ = ' ';
00367
00368 negated = 0;
00369 verifyFlags = RPMVERIFY_NONE;
00370
00371 for (p = q; *p != '\0'; p = pe) {
00372 SKIPWHITE(p);
00373 if (*p == '\0')
00374 break;
00375 pe = p;
00376 SKIPNONWHITE(pe);
00377 if (*pe != '\0')
00378 *pe++ = '\0';
00379
00380 { VFA_t *vfa;
00381 for (vfa = verifyAttrs; vfa->attribute != NULL; vfa++) {
00382 if (strcmp(p, vfa->attribute))
00383 continue;
00384 verifyFlags |= vfa->flag;
00385 break;
00386 }
00387 if (vfa->attribute)
00388 continue;
00389 }
00390
00391 if (!strcmp(p, "not")) {
00392 negated ^= 1;
00393 } else {
00394 rpmError(RPMERR_BADSPEC, _("Invalid %s token: %s\n"), name, p);
00395 fl->processingFailed = 1;
00396 return RPMERR_BADSPEC;
00397 }
00398 }
00399
00400 *resultVerify = negated ? ~(verifyFlags) : verifyFlags;
00401 *specdFlags |= SPECD_VERIFY;
00402
00403 return 0;
00404 }
00405
00406
00407 #define isAttrDefault(_ars) ((_ars)[0] == '-' && (_ars)[1] == '\0')
00408
00415
00416 static int parseForDev(char * buf, FileList fl)
00417
00418
00419 {
00420 const char * name;
00421 const char * errstr = NULL;
00422 char *p, *pe, *q;
00423 int rc = RPMERR_BADSPEC;
00424
00425 if ((p = strstr(buf, (name = "%dev"))) == NULL)
00426 return 0;
00427
00428 for (pe = p; (pe-p) < strlen(name); pe++)
00429 *pe = ' ';
00430 SKIPSPACE(pe);
00431
00432 if (*pe != '(') {
00433 errstr = "'('";
00434 goto exit;
00435 }
00436
00437
00438 *pe++ = ' ';
00439 for (p = pe; *pe && *pe != ')'; pe++)
00440 {};
00441 if (*pe != ')') {
00442 errstr = "')'";
00443 goto exit;
00444 }
00445
00446
00447 q = alloca((pe-p) + 1);
00448 strncpy(q, p, pe-p);
00449 q[pe-p] = '\0';
00450 while (p <= pe)
00451 *p++ = ' ';
00452
00453 p = q; SKIPWHITE(p);
00454 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00455 if (*p == 'b')
00456 fl->devtype = 'b';
00457 else if (*p == 'c')
00458 fl->devtype = 'c';
00459 else {
00460 errstr = "devtype";
00461 goto exit;
00462 }
00463
00464 p = pe; SKIPWHITE(p);
00465 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00466 for (pe = p; *pe && xisdigit(*pe); pe++)
00467 {} ;
00468 if (*pe == '\0') {
00469 fl->devmajor = atoi(p);
00470
00471 if (!(fl->devmajor >= 0 && fl->devmajor < 256)) {
00472 errstr = "devmajor";
00473 goto exit;
00474 }
00475
00476 pe++;
00477 } else {
00478 errstr = "devmajor";
00479 goto exit;
00480 }
00481
00482 p = pe; SKIPWHITE(p);
00483 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00484 for (pe = p; *pe && xisdigit(*pe); pe++)
00485 {} ;
00486 if (*pe == '\0') {
00487 fl->devminor = atoi(p);
00488 if (!(fl->devminor >= 0 && fl->devminor < 256)) {
00489 errstr = "devminor";
00490 goto exit;
00491 }
00492 pe++;
00493 } else {
00494 errstr = "devminor";
00495 goto exit;
00496 }
00497
00498 fl->noGlob = 1;
00499
00500 rc = 0;
00501
00502 exit:
00503 if (rc) {
00504 rpmError(RPMERR_BADSPEC, _("Missing %s in %s %s\n"), errstr, name, p);
00505 fl->processingFailed = 1;
00506 }
00507 return rc;
00508 }
00509
00510
00517
00518 static int parseForAttr(char * buf, FileList fl)
00519
00520
00521
00522 {
00523 const char *name;
00524 char *p, *pe, *q;
00525 int x;
00526 struct AttrRec_s arbuf;
00527 AttrRec ar = &arbuf, ret_ar;
00528 specdFlags * specdFlags;
00529
00530 if ((p = strstr(buf, (name = "%attr"))) != NULL) {
00531 ret_ar = &(fl->cur_ar);
00532 specdFlags = &fl->currentSpecdFlags;
00533 } else if ((p = strstr(buf, (name = "%defattr"))) != NULL) {
00534 ret_ar = &(fl->def_ar);
00535 specdFlags = &fl->defSpecdFlags;
00536 } else
00537 return 0;
00538
00539 for (pe = p; (pe-p) < strlen(name); pe++)
00540 *pe = ' ';
00541
00542 SKIPSPACE(pe);
00543
00544 if (*pe != '(') {
00545 rpmError(RPMERR_BADSPEC, _("Missing '(' in %s %s\n"), name, pe);
00546 fl->processingFailed = 1;
00547 return RPMERR_BADSPEC;
00548 }
00549
00550
00551 *pe++ = ' ';
00552 for (p = pe; *pe && *pe != ')'; pe++)
00553 {};
00554
00555 if (ret_ar == &(fl->def_ar)) {
00556 q = pe;
00557 q++;
00558 SKIPSPACE(q);
00559 if (*q != '\0') {
00560 rpmError(RPMERR_BADSPEC,
00561 _("Non-white space follows %s(): %s\n"), name, q);
00562 fl->processingFailed = 1;
00563 return RPMERR_BADSPEC;
00564 }
00565 }
00566
00567
00568 q = alloca((pe-p) + 1);
00569 strncpy(q, p, pe-p);
00570 q[pe-p] = '\0';
00571 while (p <= pe)
00572 *p++ = ' ';
00573
00574 nullAttrRec(ar);
00575
00576 p = q; SKIPWHITE(p);
00577 if (*p != '\0') {
00578 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00579 ar->ar_fmodestr = p;
00580 p = pe; SKIPWHITE(p);
00581 }
00582 if (*p != '\0') {
00583 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00584 ar->ar_user = p;
00585 p = pe; SKIPWHITE(p);
00586 }
00587 if (*p != '\0') {
00588 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00589 ar->ar_group = p;
00590 p = pe; SKIPWHITE(p);
00591 }
00592 if (*p != '\0' && ret_ar == &(fl->def_ar)) {
00593 pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
00594 ar->ar_dmodestr = p;
00595 p = pe; SKIPWHITE(p);
00596 }
00597
00598 if (!(ar->ar_fmodestr && ar->ar_user && ar->ar_group) || *p != '\0') {
00599 rpmError(RPMERR_BADSPEC, _("Bad syntax: %s(%s)\n"), name, q);
00600 fl->processingFailed = 1;
00601 return RPMERR_BADSPEC;
00602 }
00603
00604
00605 if (ar->ar_fmodestr && !isAttrDefault(ar->ar_fmodestr)) {
00606 unsigned int ui;
00607 x = sscanf(ar->ar_fmodestr, "%o", &ui);
00608 if ((x == 0) || (ar->ar_fmode & ~MYALLPERMS)) {
00609 rpmError(RPMERR_BADSPEC, _("Bad mode spec: %s(%s)\n"), name, q);
00610 fl->processingFailed = 1;
00611 return RPMERR_BADSPEC;
00612 }
00613 ar->ar_fmode = ui;
00614 } else
00615 ar->ar_fmodestr = NULL;
00616
00617 if (ar->ar_dmodestr && !isAttrDefault(ar->ar_dmodestr)) {
00618 unsigned int ui;
00619 x = sscanf(ar->ar_dmodestr, "%o", &ui);
00620 if ((x == 0) || (ar->ar_dmode & ~MYALLPERMS)) {
00621 rpmError(RPMERR_BADSPEC, _("Bad dirmode spec: %s(%s)\n"), name, q);
00622 fl->processingFailed = 1;
00623 return RPMERR_BADSPEC;
00624 }
00625 ar->ar_dmode = ui;
00626 } else
00627 ar->ar_dmodestr = NULL;
00628
00629 if (!(ar->ar_user && !isAttrDefault(ar->ar_user)))
00630 ar->ar_user = NULL;
00631
00632 if (!(ar->ar_group && !isAttrDefault(ar->ar_group)))
00633 ar->ar_group = NULL;
00634
00635 dupAttrRec(ar, ret_ar);
00636
00637
00638 *specdFlags |= SPECD_UID | SPECD_GID | SPECD_FILEMODE | SPECD_DIRMODE;
00639
00640 return 0;
00641 }
00642
00643
00650
00651 static int parseForConfig(char * buf, FileList fl)
00652
00653 {
00654 char *p, *pe, *q;
00655 const char *name;
00656
00657 if ((p = strstr(buf, (name = "%config"))) == NULL)
00658 return 0;
00659
00660 fl->currentFlags |= RPMFILE_CONFIG;
00661
00662
00663 for (pe = p; (pe-p) < strlen(name); pe++)
00664 *pe = ' ';
00665 SKIPSPACE(pe);
00666 if (*pe != '(')
00667 return 0;
00668
00669
00670 *pe++ = ' ';
00671 for (p = pe; *pe && *pe != ')'; pe++)
00672 {};
00673
00674 if (*pe == '\0') {
00675 rpmError(RPMERR_BADSPEC, _("Missing ')' in %s(%s\n"), name, p);
00676 fl->processingFailed = 1;
00677 return RPMERR_BADSPEC;
00678 }
00679
00680
00681 q = alloca((pe-p) + 1);
00682 strncpy(q, p, pe-p);
00683 q[pe-p] = '\0';
00684 while (p <= pe)
00685 *p++ = ' ';
00686
00687 for (p = q; *p != '\0'; p = pe) {
00688 SKIPWHITE(p);
00689 if (*p == '\0')
00690 break;
00691 pe = p;
00692 SKIPNONWHITE(pe);
00693 if (*pe != '\0')
00694 *pe++ = '\0';
00695 if (!strcmp(p, "missingok")) {
00696 fl->currentFlags |= RPMFILE_MISSINGOK;
00697 } else if (!strcmp(p, "noreplace")) {
00698 fl->currentFlags |= RPMFILE_NOREPLACE;
00699 } else {
00700 rpmError(RPMERR_BADSPEC, _("Invalid %s token: %s\n"), name, p);
00701 fl->processingFailed = 1;
00702 return RPMERR_BADSPEC;
00703 }
00704 }
00705
00706 return 0;
00707 }
00708
00709
00712 static int langCmp(const void * ap, const void * bp)
00713
00714 {
00715
00716 return strcmp(*(const char **)ap, *(const char **)bp);
00717
00718 }
00719
00726
00727 static int parseForLang(char * buf, FileList fl)
00728
00729
00730 {
00731 char *p, *pe, *q;
00732 const char *name;
00733
00734 while ((p = strstr(buf, (name = "%lang"))) != NULL) {
00735
00736 for (pe = p; (pe-p) < strlen(name); pe++)
00737 *pe = ' ';
00738 SKIPSPACE(pe);
00739
00740 if (*pe != '(') {
00741 rpmError(RPMERR_BADSPEC, _("Missing '(' in %s %s\n"), name, pe);
00742 fl->processingFailed = 1;
00743 return RPMERR_BADSPEC;
00744 }
00745
00746
00747 *pe++ = ' ';
00748 for (pe = p; *pe && *pe != ')'; pe++)
00749 {};
00750
00751 if (*pe == '\0') {
00752 rpmError(RPMERR_BADSPEC, _("Missing ')' in %s(%s\n"), name, p);
00753 fl->processingFailed = 1;
00754 return RPMERR_BADSPEC;
00755 }
00756
00757
00758 q = alloca((pe-p) + 1);
00759 strncpy(q, p, pe-p);
00760 q[pe-p] = '\0';
00761 while (p <= pe)
00762 *p++ = ' ';
00763
00764
00765 for (p = q; *p != '\0'; p = pe) {
00766 char *newp;
00767 size_t np;
00768 int i;
00769
00770 SKIPWHITE(p);
00771 pe = p;
00772 SKIPNONWHITE(pe);
00773
00774 np = pe - p;
00775
00776
00777 if (np < 1 || (np == 1 && *p != 'C') || np >= 32) {
00778 rpmError(RPMERR_BADSPEC,
00779 _("Unusual locale length: \"%.*s\" in %%lang(%s)\n"),
00780 (int)np, p, q);
00781 fl->processingFailed = 1;
00782 return RPMERR_BADSPEC;
00783 }
00784
00785
00786 if (fl->currentLangs != NULL)
00787 for (i = 0; i < fl->nLangs; i++) {
00788 if (strncmp(fl->currentLangs[i], p, np))
00789 continue;
00790 rpmError(RPMERR_BADSPEC, _("Duplicate locale %.*s in %%lang(%s)\n"),
00791 (int)np, p, q);
00792 fl->processingFailed = 1;
00793 return RPMERR_BADSPEC;
00794 }
00795
00796
00797 fl->currentLangs = xrealloc(fl->currentLangs,
00798 (fl->nLangs + 1) * sizeof(*fl->currentLangs));
00799 newp = xmalloc( np+1 );
00800 strncpy(newp, p, np);
00801 newp[np] = '\0';
00802 fl->currentLangs[fl->nLangs++] = newp;
00803 if (*pe == ',') pe++;
00804 }
00805 }
00806
00807
00808 if (fl->currentLangs)
00809 qsort(fl->currentLangs, fl->nLangs, sizeof(*fl->currentLangs), langCmp);
00810
00811 return 0;
00812 }
00813
00814
00817
00818 static int parseForRegexLang(const char * fileName, char ** lang)
00819
00820
00821 {
00822 static int initialized = 0;
00823 static int hasRegex = 0;
00824 static regex_t compiledPatt;
00825 static char buf[BUFSIZ];
00826 int x;
00827 regmatch_t matches[2];
00828 const char *s;
00829
00830 if (! initialized) {
00831 const char *patt = rpmExpand("%{?_langpatt}", NULL);
00832 int rc = 0;
00833 if (!(patt && *patt != '\0'))
00834 rc = 1;
00835 else if (regcomp(&compiledPatt, patt, REG_EXTENDED))
00836 rc = -1;
00837 patt = _free(patt);
00838 if (rc)
00839 return rc;
00840 hasRegex = 1;
00841 initialized = 1;
00842 }
00843
00844 memset(matches, 0, sizeof(matches));
00845 if (! hasRegex || regexec(&compiledPatt, fileName, 2, matches, REG_NOTEOL))
00846 return 1;
00847
00848
00849 s = fileName + matches[1].rm_eo - 1;
00850 x = matches[1].rm_eo - matches[1].rm_so;
00851 buf[x] = '\0';
00852 while (x) {
00853 buf[--x] = *s--;
00854 }
00855 if (lang)
00856 *lang = buf;
00857 return 0;
00858 }
00859
00860
00863
00864
00865 VFA_t virtualFileAttributes[] = {
00866 { "%dir", 0, 0 },
00867 { "%doc", 0, RPMFILE_DOC },
00868 { "%ghost", 0, RPMFILE_GHOST },
00869 { "%exclude", 0, RPMFILE_EXCLUDE },
00870 { "%readme", 0, RPMFILE_README },
00871 { "%license", 0, RPMFILE_LICENSE },
00872 { "%pubkey", 0, RPMFILE_PUBKEY },
00873 { "%policy", 0, RPMFILE_POLICY },
00874
00875 #if WHY_NOT
00876 { "%icon", 0, RPMFILE_ICON },
00877 { "%spec", 0, RPMFILE_SPEC },
00878 { "%config", 0, RPMFILE_CONFIG },
00879 { "%missingok", 0, RPMFILE_CONFIG|RPMFILE_MISSINGOK },
00880 { "%noreplace", 0, RPMFILE_CONFIG|RPMFILE_NOREPLACE },
00881 #endif
00882
00883 { NULL, 0, 0 }
00884 };
00885
00886
00896
00897 static int parseForSimple(Spec spec, Package pkg, char * buf,
00898 FileList fl, const char ** fileName)
00899
00900
00901
00902
00903
00904
00905 {
00906 char *s, *t;
00907 int res, specialDoc = 0;
00908 char specialDocBuf[BUFSIZ];
00909
00910 specialDocBuf[0] = '\0';
00911 *fileName = NULL;
00912 res = 0;
00913
00914 t = buf;
00915 while ((s = strtokWithQuotes(t, " \t\n")) != NULL) {
00916 t = NULL;
00917 if (!strcmp(s, "%docdir")) {
00918 s = strtokWithQuotes(NULL, " \t\n");
00919 if (fl->docDirCount == MAXDOCDIR) {
00920 rpmError(RPMERR_INTERNAL, _("Hit limit for %%docdir\n"));
00921 fl->processingFailed = 1;
00922 res = 1;
00923 }
00924
00925 if (s != NULL)
00926 fl->docDirs[fl->docDirCount++] = xstrdup(s);
00927 if (s == NULL || strtokWithQuotes(NULL, " \t\n")) {
00928 rpmError(RPMERR_INTERNAL, _("Only one arg for %%docdir\n"));
00929 fl->processingFailed = 1;
00930 res = 1;
00931 }
00932 break;
00933 }
00934 #if defined(__LCLINT__)
00935 assert(s != NULL);
00936 #endif
00937
00938
00939 { VFA_t *vfa;
00940 for (vfa = virtualFileAttributes; vfa->attribute != NULL; vfa++) {
00941 if (strcmp(s, vfa->attribute))
00942 continue;
00943 if (!vfa->flag) {
00944 if (!strcmp(s, "%dir"))
00945 fl->isDir = 1;
00946 } else {
00947 if (vfa->not)
00948 fl->currentFlags &= ~vfa->flag;
00949 else
00950 fl->currentFlags |= vfa->flag;
00951 }
00952
00953 break;
00954 }
00955
00956 if (vfa->attribute != NULL)
00957 continue;
00958 }
00959
00960 if (*fileName) {
00961
00962 rpmError(RPMERR_BADSPEC, _("Two files on one line: %s\n"),
00963 *fileName);
00964 fl->processingFailed = 1;
00965 res = 1;
00966 }
00967
00968
00969 if (*s != '/') {
00970 if (fl->currentFlags & RPMFILE_DOC) {
00971 specialDoc = 1;
00972 strcat(specialDocBuf, " ");
00973 strcat(specialDocBuf, s);
00974 } else
00975 if (fl->currentFlags & (RPMFILE_POLICY|RPMFILE_PUBKEY|RPMFILE_ICON))
00976 {
00977 *fileName = s;
00978 } else {
00979
00980 rpmError(RPMERR_BADSPEC,
00981 _("File must begin with \"/\": %s\n"), s);
00982 fl->processingFailed = 1;
00983 res = 1;
00984 }
00985 } else {
00986 *fileName = s;
00987 }
00988
00989 }
00990
00991 if (specialDoc) {
00992 if (*fileName || (fl->currentFlags & ~(RPMFILE_DOC))) {
00993 rpmError(RPMERR_BADSPEC,
00994 _("Can't mix special %%doc with other forms: %s\n"),
00995 (*fileName ? *fileName : ""));
00996 fl->processingFailed = 1;
00997 res = 1;
00998 } else {
00999
01000 { const char *ddir, *n, *v;
01001
01002 (void) headerNVR(pkg->header, &n, &v, NULL);
01003
01004 ddir = rpmGetPath("%{_docdir}/", n, "-", v, NULL);
01005 strcpy(buf, ddir);
01006 ddir = _free(ddir);
01007 }
01008
01009
01010
01011 if (! fl->passedSpecialDoc) {
01012 pkg->specialDoc = newStringBuf();
01013 appendStringBuf(pkg->specialDoc, "DOCDIR=$RPM_BUILD_ROOT");
01014 appendLineStringBuf(pkg->specialDoc, buf);
01015 appendLineStringBuf(pkg->specialDoc, "export DOCDIR");
01016 appendLineStringBuf(pkg->specialDoc, "rm -rf $DOCDIR");
01017 appendLineStringBuf(pkg->specialDoc, MKDIR_P " $DOCDIR");
01018
01019
01020 *fileName = buf;
01021
01022 fl->passedSpecialDoc = 1;
01023 fl->isSpecialDoc = 1;
01024 }
01025
01026 appendStringBuf(pkg->specialDoc, "cp -pr ");
01027 appendStringBuf(pkg->specialDoc, specialDocBuf);
01028 appendLineStringBuf(pkg->specialDoc, " $DOCDIR");
01029 }
01030 }
01031
01032 return res;
01033 }
01034
01035
01038 static int compareFileListRecs(const void * ap, const void * bp)
01039 {
01040 const char *a = ((FileListRec)ap)->fileURL;
01041 const char *b = ((FileListRec)bp)->fileURL;
01042 return strcmp(a, b);
01043 }
01044
01052 static int isDoc(FileList fl, const char * fileName)
01053 {
01054 int x = fl->docDirCount;
01055
01056 while (x--) {
01057 if (strstr(fileName, fl->docDirs[x]) == fileName)
01058 return 1;
01059 }
01060 return 0;
01061 }
01062
01069 static int checkHardLinks(FileList fl)
01070
01071 {
01072 FileListRec ilp, jlp;
01073 int i, j;
01074
01075 for (i = 0; i < fl->fileListRecsUsed; i++) {
01076 ilp = fl->fileList + i;
01077 if (!(S_ISREG(ilp->fl_mode) && ilp->fl_nlink > 1))
01078 continue;
01079
01080 for (j = i + 1; j < fl->fileListRecsUsed; j++) {
01081 jlp = fl->fileList + j;
01082 if (!S_ISREG(jlp->fl_mode))
01083 continue;
01084 if (ilp->fl_nlink != jlp->fl_nlink)
01085 continue;
01086 if (ilp->fl_ino != jlp->fl_ino)
01087 continue;
01088 if (ilp->fl_dev != jlp->fl_dev)
01089 continue;
01090 return 1;
01091 }
01092 }
01093 return 0;
01094 }
01095
01105
01106 static void genCpioListAndHeader( FileList fl,
01107 rpmfi * fip, Header h, int isSrc)
01108
01109
01110
01111 {
01112 int _addDotSlash = !(isSrc || rpmExpandNumeric("%{_noPayloadPrefix}"));
01113 int apathlen = 0;
01114 int dpathlen = 0;
01115 int skipLen = 0;
01116 rpmsx sx = NULL;
01117 const char * sxfn;
01118 size_t fnlen;
01119 FileListRec flp;
01120 char buf[BUFSIZ];
01121 int i;
01122
01123
01124 qsort(fl->fileList, fl->fileListRecsUsed,
01125 sizeof(*(fl->fileList)), compareFileListRecs);
01126
01127
01128 if (! isSrc) {
01129 skipLen = 1;
01130 if (fl->prefix)
01131 skipLen += strlen(fl->prefix);
01132 }
01133
01134 sxfn = rpmGetPath("%{?_build_file_context_path}", NULL);
01135 if (sxfn != NULL && *sxfn != '\0')
01136 sx = rpmsxNew(sxfn);
01137
01138 for (i = 0, flp = fl->fileList; i < fl->fileListRecsUsed; i++, flp++) {
01139 const char *s;
01140
01141
01142 while (i < (fl->fileListRecsUsed - 1) &&
01143 !strcmp(flp->fileURL, flp[1].fileURL)) {
01144
01145
01146
01147
01148
01149 flp[1].flags |= flp->flags;
01150
01151 if (!(flp[1].flags & RPMFILE_EXCLUDE))
01152 rpmMessage(RPMMESS_WARNING, _("File listed twice: %s\n"),
01153 flp->fileURL);
01154
01155
01156 if (S_ISDIR(flp->fl_mode)) {
01157 if ((flp[1].specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)) <
01158 (flp->specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)))
01159 flp[1].fl_mode = flp->fl_mode;
01160 } else {
01161 if ((flp[1].specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)) <
01162 (flp->specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)))
01163 flp[1].fl_mode = flp->fl_mode;
01164 }
01165
01166
01167 if ((flp[1].specdFlags & (SPECD_UID | SPECD_DEFUID)) <
01168 (flp->specdFlags & (SPECD_UID | SPECD_DEFUID)))
01169 {
01170 flp[1].fl_uid = flp->fl_uid;
01171 flp[1].uname = flp->uname;
01172 }
01173
01174
01175 if ((flp[1].specdFlags & (SPECD_GID | SPECD_DEFGID)) <
01176 (flp->specdFlags & (SPECD_GID | SPECD_DEFGID)))
01177 {
01178 flp[1].fl_gid = flp->fl_gid;
01179 flp[1].gname = flp->gname;
01180 }
01181
01182
01183 if ((flp[1].specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)) <
01184 (flp->specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)))
01185 flp[1].verifyFlags = flp->verifyFlags;
01186
01187
01188
01189 flp++; i++;
01190 }
01191
01192
01193 if (flp->flags & RPMFILE_EXCLUDE) continue;
01194
01195
01196 apathlen += (strlen(flp->fileURL) - skipLen + (_addDotSlash ? 3 : 1));
01197
01198
01199 dpathlen += (strlen(flp->diskURL) + 2);
01200
01201
01202
01203
01204
01205
01206 (void) headerAddOrAppendEntry(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE,
01207 &(flp->fileURL), 1);
01208
01209
01210 if (sizeof(flp->fl_size) != sizeof(uint_32)) {
01211 uint_32 psize = (uint_32)flp->fl_size;
01212 (void) headerAddOrAppendEntry(h, RPMTAG_FILESIZES, RPM_INT32_TYPE,
01213 &(psize), 1);
01214 } else {
01215 (void) headerAddOrAppendEntry(h, RPMTAG_FILESIZES, RPM_INT32_TYPE,
01216 &(flp->fl_size), 1);
01217 }
01218 (void) headerAddOrAppendEntry(h, RPMTAG_FILEUSERNAME, RPM_STRING_ARRAY_TYPE,
01219 &(flp->uname), 1);
01220 (void) headerAddOrAppendEntry(h, RPMTAG_FILEGROUPNAME, RPM_STRING_ARRAY_TYPE,
01221 &(flp->gname), 1);
01222 if (sizeof(flp->fl_mtime) != sizeof(uint_32)) {
01223 uint_32 mtime = (uint_32)flp->fl_mtime;
01224 (void) headerAddOrAppendEntry(h, RPMTAG_FILEMTIMES, RPM_INT32_TYPE,
01225 &(mtime), 1);
01226 } else {
01227 (void) headerAddOrAppendEntry(h, RPMTAG_FILEMTIMES, RPM_INT32_TYPE,
01228 &(flp->fl_mtime), 1);
01229 }
01230 if (sizeof(flp->fl_mode) != sizeof(uint_16)) {
01231 uint_16 pmode = (uint_16)flp->fl_mode;
01232 (void) headerAddOrAppendEntry(h, RPMTAG_FILEMODES, RPM_INT16_TYPE,
01233 &(pmode), 1);
01234 } else {
01235 (void) headerAddOrAppendEntry(h, RPMTAG_FILEMODES, RPM_INT16_TYPE,
01236 &(flp->fl_mode), 1);
01237 }
01238 if (sizeof(flp->fl_rdev) != sizeof(uint_16)) {
01239 uint_16 prdev = (uint_16)flp->fl_rdev;
01240 (void) headerAddOrAppendEntry(h, RPMTAG_FILERDEVS, RPM_INT16_TYPE,
01241 &(prdev), 1);
01242 } else {
01243 (void) headerAddOrAppendEntry(h, RPMTAG_FILERDEVS, RPM_INT16_TYPE,
01244 &(flp->fl_rdev), 1);
01245 }
01246 if (sizeof(flp->fl_dev) != sizeof(uint_32)) {
01247 uint_32 pdevice = (uint_32)flp->fl_dev;
01248 (void) headerAddOrAppendEntry(h, RPMTAG_FILEDEVICES, RPM_INT32_TYPE,
01249 &(pdevice), 1);
01250 } else {
01251 (void) headerAddOrAppendEntry(h, RPMTAG_FILEDEVICES, RPM_INT32_TYPE,
01252 &(flp->fl_dev), 1);
01253 }
01254 if (sizeof(flp->fl_ino) != sizeof(uint_32)) {
01255 uint_32 ino = (uint_32)flp->fl_ino;
01256 (void) headerAddOrAppendEntry(h, RPMTAG_FILEINODES, RPM_INT32_TYPE,
01257 &(ino), 1);
01258 } else {
01259 (void) headerAddOrAppendEntry(h, RPMTAG_FILEINODES, RPM_INT32_TYPE,
01260 &(flp->fl_ino), 1);
01261 }
01262
01263
01264 (void) headerAddOrAppendEntry(h, RPMTAG_FILELANGS, RPM_STRING_ARRAY_TYPE,
01265 &(flp->langs), 1);
01266
01267
01268
01269
01270
01271
01272
01273
01274 buf[0] = '\0';
01275 if (S_ISREG(flp->fl_mode))
01276 (void) domd5(flp->diskURL, buf, 1, NULL);
01277 s = buf;
01278 (void) headerAddOrAppendEntry(h, RPMTAG_FILEMD5S, RPM_STRING_ARRAY_TYPE,
01279 &s, 1);
01280
01281 buf[0] = '\0';
01282 if (S_ISLNK(flp->fl_mode)) {
01283 buf[Readlink(flp->diskURL, buf, BUFSIZ)] = '\0';
01284 if (fl->buildRootURL) {
01285 const char * buildRoot;
01286 (void) urlPath(fl->buildRootURL, &buildRoot);
01287
01288 if (buf[0] == '/' && strcmp(buildRoot, "/") &&
01289 !strncmp(buf, buildRoot, strlen(buildRoot))) {
01290 rpmError(RPMERR_BADSPEC,
01291 _("Symlink points to BuildRoot: %s -> %s\n"),
01292 flp->fileURL, buf);
01293 fl->processingFailed = 1;
01294 }
01295 }
01296 }
01297 s = buf;
01298 (void) headerAddOrAppendEntry(h, RPMTAG_FILELINKTOS, RPM_STRING_ARRAY_TYPE,
01299 &s, 1);
01300
01301 if (flp->flags & RPMFILE_GHOST) {
01302 flp->verifyFlags &= ~(RPMVERIFY_MD5 | RPMVERIFY_FILESIZE |
01303 RPMVERIFY_LINKTO | RPMVERIFY_MTIME);
01304 }
01305 (void) headerAddOrAppendEntry(h, RPMTAG_FILEVERIFYFLAGS, RPM_INT32_TYPE,
01306 &(flp->verifyFlags), 1);
01307
01308 if (!isSrc && isDoc(fl, flp->fileURL))
01309 flp->flags |= RPMFILE_DOC;
01310
01311 if (S_ISDIR(flp->fl_mode))
01312 flp->flags &= ~(RPMFILE_CONFIG|RPMFILE_DOC);
01313
01314 (void) headerAddOrAppendEntry(h, RPMTAG_FILEFLAGS, RPM_INT32_TYPE,
01315 &(flp->flags), 1);
01316
01317
01318
01319 if (sx != NULL) {
01320 mode_t fmode = (uint_16)flp->fl_mode;
01321 s = rpmsxFContext(sx, flp->fileURL, fmode);
01322 if (s == NULL) s = "";
01323 (void) headerAddOrAppendEntry(h, RPMTAG_FILECONTEXTS, RPM_STRING_ARRAY_TYPE,
01324 &s, 1);
01325 }
01326
01327
01328 }
01329 sx = rpmsxFree(sx);
01330 sxfn = _free(sxfn);
01331
01332 (void) headerAddEntry(h, RPMTAG_SIZE, RPM_INT32_TYPE,
01333 &(fl->totalFileSize), 1);
01334
01335 if (_addDotSlash)
01336 (void) rpmlibNeedsFeature(h, "PayloadFilesHavePrefix", "4.0-1");
01337
01338
01339 if (_noDirTokens)
01340 expandFilelist(h);
01341 else {
01342 compressFilelist(h);
01343
01344 (void) rpmlibNeedsFeature(h, "CompressedFileNames", "3.0.4-1");
01345 }
01346
01347 { int scareMem = 0;
01348 rpmts ts = NULL;
01349 rpmfi fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
01350 char * a, * d;
01351
01352 if (fi == NULL) return;
01353
01354
01355 fi->te = xcalloc(1, sizeof(*fi->te));
01356
01357 fi->te->type = TR_ADDED;
01358
01359 fi->dnl = _free(fi->dnl);
01360 fi->bnl = _free(fi->bnl);
01361 if (!scareMem) fi->dil = _free(fi->dil);
01362
01363 fi->dnl = xmalloc(fi->fc * sizeof(*fi->dnl) + dpathlen);
01364 d = (char *)(fi->dnl + fi->fc);
01365 *d = '\0';
01366
01367 fi->bnl = xmalloc(fi->fc * (sizeof(*fi->bnl) + sizeof(*fi->dil)));
01368
01369 fi->dil = (!scareMem)
01370 ? xcalloc(sizeof(*fi->dil), fi->fc)
01371 : (int *)(fi->bnl + fi->fc);
01372
01373
01374 fi->apath = xmalloc(fi->fc * sizeof(*fi->apath) + apathlen);
01375 a = (char *)(fi->apath + fi->fc);
01376 *a = '\0';
01377
01378 fi->actions = xcalloc(sizeof(*fi->actions), fi->fc);
01379 fi->fmapflags = xcalloc(sizeof(*fi->fmapflags), fi->fc);
01380 fi->astriplen = 0;
01381 if (fl->buildRootURL)
01382 fi->astriplen = strlen(fl->buildRootURL);
01383 fi->striplen = 0;
01384 fi->fuser = NULL;
01385 fi->fgroup = NULL;
01386
01387
01388 if (fi->dil != NULL)
01389 for (i = 0, flp = fl->fileList; i < fi->fc; i++, flp++) {
01390 char * b;
01391
01392
01393 while (((flp - fl->fileList) < (fl->fileListRecsUsed - 1)) &&
01394 !strcmp(flp->fileURL, flp[1].fileURL))
01395 flp++;
01396
01397 if (flp->flags & RPMFILE_EXCLUDE) {
01398 i--;
01399 continue;
01400 }
01401
01402 if ((fnlen = strlen(flp->diskURL) + 1) > fi->fnlen)
01403 fi->fnlen = fnlen;
01404
01405
01406 fi->dil[i] = i;
01407
01408 fi->dnl[fi->dil[i]] = d;
01409
01410 d = stpcpy(d, flp->diskURL);
01411
01412
01413 for (b = d; b > fi->dnl[fi->dil[i]] && *b != '/'; b--)
01414 b[1] = b[0];
01415 b++;
01416 *b++ = '\0';
01417 fi->bnl[i] = b;
01418 d += 2;
01419
01420
01421
01422 fi->apath[i] = a;
01423
01424 if (_addDotSlash)
01425 a = stpcpy(a, "./");
01426 a = stpcpy(a, (flp->fileURL + skipLen));
01427 a++;
01428
01429 if (flp->flags & RPMFILE_GHOST) {
01430 fi->actions[i] = FA_SKIP;
01431 continue;
01432 }
01433 fi->actions[i] = FA_COPYOUT;
01434 fi->fmapflags[i] = CPIO_MAP_PATH |
01435 CPIO_MAP_TYPE | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
01436 if (isSrc)
01437 fi->fmapflags[i] |= CPIO_FOLLOW_SYMLINKS;
01438
01439 }
01440
01441 if (fip)
01442 *fip = fi;
01443 else
01444 fi = rpmfiFree(fi);
01445
01446 }
01447 }
01448
01449
01452
01453 static FileListRec freeFileList( FileListRec fileList,
01454 int count)
01455
01456 {
01457 while (count--) {
01458 fileList[count].diskURL = _free(fileList[count].diskURL);
01459 fileList[count].fileURL = _free(fileList[count].fileURL);
01460 fileList[count].langs = _free(fileList[count].langs);
01461 }
01462 fileList = _free(fileList);
01463 return NULL;
01464 }
01465
01466
01467
01468 static int recurseDir(FileList fl, const char * diskURL)
01469
01470
01471
01472
01473
01474
01475 ;
01476
01484
01485 static int addFile(FileList fl, const char * diskURL,
01486 struct stat * statp)
01487
01488
01489
01490
01491
01492
01493
01494 {
01495 const char *fileURL = diskURL;
01496 struct stat statbuf;
01497 mode_t fileMode;
01498 uid_t fileUid;
01499 gid_t fileGid;
01500 const char *fileUname;
01501 const char *fileGname;
01502 char *lang;
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515 { const char *fileName;
01516 (void) urlPath(fileURL, &fileName);
01517 if (fl->buildRootURL && strcmp(fl->buildRootURL, "/"))
01518 fileURL += strlen(fl->buildRootURL);
01519 }
01520
01521
01522
01523 if (*fileURL == '\0')
01524 fileURL = "/";
01525
01526
01527
01528 if (!fl->inFtw && fl->prefix) {
01529 const char *prefixTest;
01530 const char *prefixPtr = fl->prefix;
01531
01532 (void) urlPath(fileURL, &prefixTest);
01533 while (*prefixPtr && *prefixTest && (*prefixTest == *prefixPtr)) {
01534 prefixPtr++;
01535 prefixTest++;
01536 }
01537 if (*prefixPtr || (*prefixTest && *prefixTest != '/')) {
01538 rpmError(RPMERR_BADSPEC, _("File doesn't match prefix (%s): %s\n"),
01539 fl->prefix, fileURL);
01540 fl->processingFailed = 1;
01541 return RPMERR_BADSPEC;
01542 }
01543 }
01544
01545 if (statp == NULL) {
01546 statp = &statbuf;
01547 memset(statp, 0, sizeof(*statp));
01548 if (fl->devtype) {
01549 time_t now = time(NULL);
01550
01551
01552 statp->st_nlink = 1;
01553 statp->st_rdev =
01554 ((fl->devmajor & 0xff) << 8) | (fl->devminor & 0xff);
01555 statp->st_dev = statp->st_rdev;
01556 statp->st_mode = (fl->devtype == 'b' ? S_IFBLK : S_IFCHR);
01557 statp->st_mode |= (fl->cur_ar.ar_fmode & 0777);
01558 statp->st_atime = now;
01559 statp->st_mtime = now;
01560 statp->st_ctime = now;
01561 } else if (Lstat(diskURL, statp)) {
01562 rpmError(RPMERR_BADSPEC, _("File not found: %s\n"), diskURL);
01563 fl->processingFailed = 1;
01564 return RPMERR_BADSPEC;
01565 }
01566 }
01567
01568 if ((! fl->isDir) && S_ISDIR(statp->st_mode)) {
01569
01570 return recurseDir(fl, diskURL);
01571
01572 }
01573
01574 fileMode = statp->st_mode;
01575 fileUid = statp->st_uid;
01576 fileGid = statp->st_gid;
01577
01578 if (S_ISDIR(fileMode) && fl->cur_ar.ar_dmodestr) {
01579 fileMode &= S_IFMT;
01580 fileMode |= fl->cur_ar.ar_dmode;
01581 } else if (fl->cur_ar.ar_fmodestr != NULL) {
01582 fileMode &= S_IFMT;
01583 fileMode |= fl->cur_ar.ar_fmode;
01584 }
01585 if (fl->cur_ar.ar_user) {
01586 fileUname = getUnameS(fl->cur_ar.ar_user);
01587 } else {
01588 fileUname = getUname(fileUid);
01589 }
01590 if (fl->cur_ar.ar_group) {
01591 fileGname = getGnameS(fl->cur_ar.ar_group);
01592 } else {
01593 fileGname = getGname(fileGid);
01594 }
01595
01596
01597 if (fileUname == NULL)
01598 fileUname = getUname(getuid());
01599 if (fileGname == NULL)
01600 fileGname = getGname(getgid());
01601
01602
01603 if (check_fileList && S_ISREG(fileMode)) {
01604 appendStringBuf(check_fileList, diskURL);
01605 appendStringBuf(check_fileList, "\n");
01606 }
01607
01608
01609 if (fl->fileListRecsUsed == fl->fileListRecsAlloced) {
01610 fl->fileListRecsAlloced += 128;
01611 fl->fileList = xrealloc(fl->fileList,
01612 fl->fileListRecsAlloced * sizeof(*(fl->fileList)));
01613 }
01614
01615 { FileListRec flp = &fl->fileList[fl->fileListRecsUsed];
01616 int i;
01617
01618 flp->fl_st = *statp;
01619 flp->fl_mode = fileMode;
01620 flp->fl_uid = fileUid;
01621 flp->fl_gid = fileGid;
01622
01623 flp->fileURL = xstrdup(fileURL);
01624 flp->diskURL = xstrdup(diskURL);
01625 flp->uname = fileUname;
01626 flp->gname = fileGname;
01627
01628 if (fl->currentLangs && fl->nLangs > 0) {
01629 char * ncl;
01630 size_t nl = 0;
01631
01632 for (i = 0; i < fl->nLangs; i++)
01633 nl += strlen(fl->currentLangs[i]) + 1;
01634
01635 flp->langs = ncl = xmalloc(nl);
01636 for (i = 0; i < fl->nLangs; i++) {
01637 const char *ocl;
01638 if (i) *ncl++ = '|';
01639 for (ocl = fl->currentLangs[i]; *ocl != '\0'; ocl++)
01640 *ncl++ = *ocl;
01641 *ncl = '\0';
01642 }
01643 } else if (! parseForRegexLang(fileURL, &lang)) {
01644 flp->langs = xstrdup(lang);
01645 } else {
01646 flp->langs = xstrdup("");
01647 }
01648
01649 flp->flags = fl->currentFlags;
01650 flp->specdFlags = fl->currentSpecdFlags;
01651 flp->verifyFlags = fl->currentVerifyFlags;
01652
01653
01654 if (S_ISREG(flp->fl_mode) && flp->fl_nlink > 1) {
01655 FileListRec ilp;
01656 for (i = 0; i < fl->fileListRecsUsed; i++) {
01657 ilp = fl->fileList + i;
01658 if (!S_ISREG(ilp->fl_mode))
01659 continue;
01660 if (flp->fl_nlink != ilp->fl_nlink)
01661 continue;
01662 if (flp->fl_ino != ilp->fl_ino)
01663 continue;
01664 if (flp->fl_dev != ilp->fl_dev)
01665 continue;
01666 break;
01667 }
01668 } else
01669 i = fl->fileListRecsUsed;
01670
01671 if (S_ISREG(flp->fl_mode) && i >= fl->fileListRecsUsed)
01672 fl->totalFileSize += flp->fl_size;
01673 }
01674
01675 fl->fileListRecsUsed++;
01676 fl->fileCount++;
01677
01678 return 0;
01679 }
01680
01681
01688 static int recurseDir(FileList fl, const char * diskURL)
01689 {
01690 char * ftsSet[2];
01691 FTS * ftsp;
01692 FTSENT * fts;
01693 int ftsOpts = (FTS_COMFOLLOW | FTS_NOCHDIR | FTS_PHYSICAL);
01694 int rc = RPMERR_BADSPEC;
01695
01696 fl->inFtw = 1;
01697 fl->isDir = 1;
01698
01699 ftsSet[0] = (char *) diskURL;
01700 ftsSet[1] = NULL;
01701 ftsp = Fts_open(ftsSet, ftsOpts, NULL);
01702 while ((fts = Fts_read(ftsp)) != NULL) {
01703 switch (fts->fts_info) {
01704 case FTS_D:
01705 case FTS_F:
01706 case FTS_SL:
01707 case FTS_SLNONE:
01708 case FTS_DEFAULT:
01709 rc = addFile(fl, fts->fts_accpath, fts->fts_statp);
01710 break;
01711 case FTS_DOT:
01712 case FTS_DP:
01713 rc = 0;
01714 break;
01715 case FTS_NS:
01716 case FTS_DNR:
01717 case FTS_ERR:
01718 case FTS_DC:
01719 case FTS_NSOK:
01720 case FTS_INIT:
01721 case FTS_W:
01722 default:
01723 rc = RPMERR_BADSPEC;
01724 break;
01725 }
01726 if (rc)
01727 break;
01728 }
01729 (void) Fts_close(ftsp);
01730
01731 fl->isDir = 0;
01732 fl->inFtw = 0;
01733
01734 return rc;
01735 }
01736
01744 static int processMetadataFile(Package pkg, FileList fl, const char * fileURL,
01745 rpmTag tag)
01746
01747
01748
01749
01750
01751
01752
01753 {
01754 const char * buildURL = "%{_builddir}/%{?buildsubdir}/";
01755 const char * fn = NULL;
01756 const char * apkt = NULL;
01757 const unsigned char * pkt = NULL;
01758 ssize_t pktlen = 0;
01759 int absolute = 0;
01760 int rc = 1;
01761 int xx;
01762
01763 (void) urlPath(fileURL, &fn);
01764 if (*fn == '/') {
01765 fn = rpmGenPath(fl->buildRootURL, NULL, fn);
01766 absolute = 1;
01767 } else
01768 fn = rpmGenPath(buildURL, NULL, fn);
01769
01770 switch (tag) {
01771 default:
01772 rpmError(RPMERR_BADSPEC, _("%s: can't load unknown tag (%d).\n"),
01773 fn, tag);
01774 goto exit;
01775
01776 case RPMTAG_PUBKEYS:
01777 if ((rc = pgpReadPkts(fn, &pkt, &pktlen)) <= 0) {
01778 rpmError(RPMERR_BADSPEC, _("%s: public key read failed.\n"), fn);
01779 goto exit;
01780 }
01781 if (rc != PGPARMOR_PUBKEY) {
01782 rpmError(RPMERR_BADSPEC, _("%s: not an armored public key.\n"), fn);
01783 goto exit;
01784 }
01785 apkt = pgpArmorWrap(PGPARMOR_PUBKEY, pkt, pktlen);
01786 break;
01787 case RPMTAG_POLICIES:
01788 if ((rc = rpmioSlurp(fn, &pkt, &pktlen)) != 0) {
01789 rpmError(RPMERR_BADSPEC, _("%s: *.te policy read failed.\n"), fn);
01790 goto exit;
01791 }
01792 apkt = (const char *) pkt;
01793 pkt = NULL;
01794 break;
01795 }
01796
01797 xx = headerAddOrAppendEntry(pkg->header, tag,
01798 RPM_STRING_ARRAY_TYPE, &apkt, 1);
01799
01800 rc = 0;
01801 if (absolute)
01802 rc = addFile(fl, fn, NULL);
01803
01804 exit:
01805 apkt = _free(apkt);
01806 pkt = _free(pkt);
01807 fn = _free(fn);
01808 if (rc) {
01809 fl->processingFailed = 1;
01810 rc = RPMERR_BADSPEC;
01811 }
01812 return rc;
01813 }
01814
01822 static int processBinaryFile( Package pkg, FileList fl,
01823 const char * fileURL)
01824
01825
01826
01827
01828
01829 {
01830 int quote = 1;
01831 int doGlob;
01832 const char *diskURL = NULL;
01833 int rc = 0;
01834
01835 doGlob = Glob_pattern_p(fileURL, quote);
01836
01837
01838 { const char * fileName;
01839 (void) urlPath(fileURL, &fileName);
01840 if (*fileName != '/') {
01841 rpmError(RPMERR_BADSPEC, _("File needs leading \"/\": %s\n"),
01842 fileName);
01843 rc = 1;
01844 goto exit;
01845 }
01846 }
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856 diskURL = rpmGenPath(fl->buildRootURL, NULL, fileURL);
01857
01858 if (doGlob) {
01859 const char ** argv = NULL;
01860 int argc = 0;
01861 int i;
01862
01863
01864 if (fl->noGlob) {
01865 rpmError(RPMERR_BADSPEC, _("Glob not permitted: %s\n"),
01866 diskURL);
01867 rc = 1;
01868 goto exit;
01869 }
01870
01871
01872 rc = rpmGlob(diskURL, &argc, &argv);
01873 if (rc == 0 && argc >= 1 && !Glob_pattern_p(argv[0], quote)) {
01874 for (i = 0; i < argc; i++) {
01875 rc = addFile(fl, argv[i], NULL);
01876
01877 argv[i] = _free(argv[i]);
01878
01879 }
01880 argv = _free(argv);
01881 } else {
01882 rpmError(RPMERR_BADSPEC, _("File not found by glob: %s\n"),
01883 diskURL);
01884 rc = 1;
01885 goto exit;
01886 }
01887
01888 } else {
01889 rc = addFile(fl, diskURL, NULL);
01890 }
01891
01892 exit:
01893 diskURL = _free(diskURL);
01894 if (rc) {
01895 fl->processingFailed = 1;
01896 rc = RPMERR_BADSPEC;
01897 }
01898 return rc;
01899 }
01900
01903
01904 static int processPackageFiles(Spec spec, Package pkg,
01905 int installSpecialDoc, int test)
01906
01907
01908
01909
01910
01911 {
01912 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
01913 struct FileList_s fl;
01914 char *s, **files, **fp;
01915 const char *fileName;
01916 char buf[BUFSIZ];
01917 struct AttrRec_s arbuf;
01918 AttrRec specialDocAttrRec = &arbuf;
01919 char *specialDoc = NULL;
01920
01921 nullAttrRec(specialDocAttrRec);
01922 pkg->cpioList = NULL;
01923
01924 if (pkg->fileFile) {
01925 const char *ffn;
01926 FILE * f;
01927 FD_t fd;
01928
01929
01930 if (*pkg->fileFile == '/') {
01931 ffn = rpmGetPath(pkg->fileFile, NULL);
01932 } else {
01933
01934 ffn = rpmGetPath("%{_builddir}/",
01935 (spec->buildSubdir ? spec->buildSubdir : "") ,
01936 "/", pkg->fileFile, NULL);
01937 }
01938 fd = Fopen(ffn, "r.fpio");
01939
01940 if (fd == NULL || Ferror(fd)) {
01941 rpmError(RPMERR_BADFILENAME,
01942 _("Could not open %%files file %s: %s\n"),
01943 ffn, Fstrerror(fd));
01944 return RPMERR_BADFILENAME;
01945 }
01946 ffn = _free(ffn);
01947
01948 f = fdGetFp(fd);
01949 if (f != NULL)
01950 while (fgets(buf, sizeof(buf), f)) {
01951 handleComments(buf);
01952 if (expandMacros(spec, spec->macros, buf, sizeof(buf))) {
01953 rpmError(RPMERR_BADSPEC, _("line: %s\n"), buf);
01954 return RPMERR_BADSPEC;
01955 }
01956 appendStringBuf(pkg->fileList, buf);
01957 }
01958 (void) Fclose(fd);
01959 }
01960
01961
01962 memset(&fl, 0, sizeof(fl));
01963
01964
01965 fl.buildRootURL = rpmGenPath(spec->rootURL, spec->buildRootURL, NULL);
01966
01967 if (hge(pkg->header, RPMTAG_DEFAULTPREFIX, NULL, (void **)&fl.prefix, NULL))
01968 fl.prefix = xstrdup(fl.prefix);
01969 else
01970 fl.prefix = NULL;
01971
01972 fl.fileCount = 0;
01973 fl.totalFileSize = 0;
01974 fl.processingFailed = 0;
01975
01976 fl.passedSpecialDoc = 0;
01977 fl.isSpecialDoc = 0;
01978
01979 fl.isDir = 0;
01980 fl.inFtw = 0;
01981 fl.currentFlags = 0;
01982 fl.currentVerifyFlags = 0;
01983
01984 fl.noGlob = 0;
01985 fl.devtype = 0;
01986 fl.devmajor = 0;
01987 fl.devminor = 0;
01988
01989 nullAttrRec(&fl.cur_ar);
01990 nullAttrRec(&fl.def_ar);
01991
01992 fl.defVerifyFlags = RPMVERIFY_ALL;
01993 fl.nLangs = 0;
01994 fl.currentLangs = NULL;
01995
01996 fl.currentSpecdFlags = 0;
01997 fl.defSpecdFlags = 0;
01998
01999 fl.docDirCount = 0;
02000 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/doc");
02001 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/man");
02002 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/info");
02003 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/X11R6/man");
02004 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/share/doc");
02005 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/share/man");
02006 fl.docDirs[fl.docDirCount++] = xstrdup("/usr/share/info");
02007 fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_docdir}", NULL);
02008 fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_mandir}", NULL);
02009 fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_infodir}", NULL);
02010 fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_javadocdir}", NULL);
02011
02012 fl.fileList = NULL;
02013 fl.fileListRecsAlloced = 0;
02014 fl.fileListRecsUsed = 0;
02015
02016 s = getStringBuf(pkg->fileList);
02017 files = splitString(s, strlen(s), '\n');
02018
02019 for (fp = files; *fp != NULL; fp++) {
02020 s = *fp;
02021 SKIPSPACE(s);
02022 if (*s == '\0')
02023 continue;
02024 fileName = NULL;
02025
02026 strcpy(buf, s);
02027
02028
02029
02030 fl.isDir = 0;
02031 fl.inFtw = 0;
02032 fl.currentFlags = 0;
02033
02034 fl.currentSpecdFlags = ((unsigned)fl.defSpecdFlags) >> 8;
02035 fl.currentVerifyFlags = fl.defVerifyFlags;
02036 fl.isSpecialDoc = 0;
02037
02038 fl.noGlob = 0;
02039 fl.devtype = 0;
02040 fl.devmajor = 0;
02041 fl.devminor = 0;
02042
02043
02044 if (fl.currentLangs) {
02045 int i;
02046 for (i = 0; i < fl.nLangs; i++)
02047
02048 fl.currentLangs[i] = _free(fl.currentLangs[i]);
02049
02050 fl.currentLangs = _free(fl.currentLangs);
02051 }
02052 fl.nLangs = 0;
02053
02054 dupAttrRec(&fl.def_ar, &fl.cur_ar);
02055
02056
02057 if (parseForVerify(buf, &fl))
02058 continue;
02059 if (parseForAttr(buf, &fl))
02060 continue;
02061 if (parseForDev(buf, &fl))
02062 continue;
02063 if (parseForConfig(buf, &fl))
02064 continue;
02065 if (parseForLang(buf, &fl))
02066 continue;
02067
02068 if (parseForSimple(spec, pkg, buf, &fl, &fileName))
02069
02070 continue;
02071
02072 if (fileName == NULL)
02073 continue;
02074
02075
02076 if (fl.isSpecialDoc) {
02077
02078 specialDoc = _free(specialDoc);
02079 specialDoc = xstrdup(fileName);
02080 dupAttrRec(&fl.cur_ar, specialDocAttrRec);
02081 } else if (fl.currentFlags & RPMFILE_PUBKEY) {
02082
02083 (void) processMetadataFile(pkg, &fl, fileName, RPMTAG_PUBKEYS);
02084
02085 } else if (fl.currentFlags & RPMFILE_POLICY) {
02086
02087 (void) processMetadataFile(pkg, &fl, fileName, RPMTAG_POLICIES);
02088
02089 } else {
02090
02091 (void) processBinaryFile(pkg, &fl, fileName);
02092
02093 }
02094
02095 }
02096
02097
02098 if (specialDoc) {
02099 if (installSpecialDoc) {
02100 static int _missing_doc_files_terminate_build = 0;
02101 static int oneshot = 0;
02102 int rc;
02103
02104 if (!oneshot) {
02105 _missing_doc_files_terminate_build =
02106 rpmExpandNumeric("%{?_missing_doc_files_terminate_build}");
02107 oneshot = 1;
02108 }
02109 rc = doScript(spec, RPMBUILD_STRINGBUF, "%doc", pkg->specialDoc, test);
02110 if (rc && _missing_doc_files_terminate_build)
02111 fl.processingFailed = rc;
02112 }
02113
02114
02115 fl.isDir = 0;
02116 fl.inFtw = 0;
02117 fl.currentFlags = 0;
02118 fl.currentVerifyFlags = 0;
02119
02120 fl.noGlob = 0;
02121 fl.devtype = 0;
02122 fl.devmajor = 0;
02123 fl.devminor = 0;
02124
02125
02126 if (fl.currentLangs) {
02127 int i;
02128 for (i = 0; i < fl.nLangs; i++)
02129
02130 fl.currentLangs[i] = _free(fl.currentLangs[i]);
02131
02132 fl.currentLangs = _free(fl.currentLangs);
02133 }
02134 fl.nLangs = 0;
02135
02136 dupAttrRec(specialDocAttrRec, &fl.cur_ar);
02137 freeAttrRec(specialDocAttrRec);
02138
02139
02140 (void) processBinaryFile(pkg, &fl, specialDoc);
02141
02142
02143 specialDoc = _free(specialDoc);
02144 }
02145
02146 freeSplitString(files);
02147
02148 if (fl.processingFailed)
02149 goto exit;
02150
02151
02152 if (checkHardLinks(&fl))
02153 (void) rpmlibNeedsFeature(pkg->header,
02154 "PartialHardlinkSets", "4.0.4-1");
02155
02156 genCpioListAndHeader(&fl, &pkg->cpioList, pkg->header, 0);
02157
02158 if (spec->timeCheck)
02159 timeCheck(spec->timeCheck, pkg->header);
02160
02161 exit:
02162 fl.buildRootURL = _free(fl.buildRootURL);
02163 fl.prefix = _free(fl.prefix);
02164
02165 freeAttrRec(&fl.cur_ar);
02166 freeAttrRec(&fl.def_ar);
02167
02168 if (fl.currentLangs) {
02169 int i;
02170 for (i = 0; i < fl.nLangs; i++)
02171
02172 fl.currentLangs[i] = _free(fl.currentLangs[i]);
02173
02174 fl.currentLangs = _free(fl.currentLangs);
02175 }
02176
02177 fl.fileList = freeFileList(fl.fileList, fl.fileListRecsUsed);
02178 while (fl.docDirCount--)
02179 fl.docDirs[fl.docDirCount] = _free(fl.docDirs[fl.docDirCount]);
02180 return fl.processingFailed;
02181 }
02182
02183
02184 void initSourceHeader(Spec spec)
02185 {
02186 HeaderIterator hi;
02187 int_32 tag, type, count;
02188 const void * ptr;
02189
02190 spec->sourceHeader = headerNew();
02191
02192
02193 for (hi = headerInitIterator(spec->packages->header);
02194 headerNextIterator(hi, &tag, &type, &ptr, &count);
02195 ptr = headerFreeData(ptr, type))
02196 {
02197 switch (tag) {
02198 case RPMTAG_NAME:
02199 case RPMTAG_VERSION:
02200 case RPMTAG_RELEASE:
02201 case RPMTAG_EPOCH:
02202 case RPMTAG_SUMMARY:
02203 case RPMTAG_DESCRIPTION:
02204 case RPMTAG_PACKAGER:
02205 case RPMTAG_DISTRIBUTION:
02206 case RPMTAG_DISTURL:
02207 case RPMTAG_VENDOR:
02208 case RPMTAG_LICENSE:
02209 case RPMTAG_GROUP:
02210 case RPMTAG_OS:
02211 case RPMTAG_ARCH:
02212 case RPMTAG_CHANGELOGTIME:
02213 case RPMTAG_CHANGELOGNAME:
02214 case RPMTAG_CHANGELOGTEXT:
02215 case RPMTAG_URL:
02216 case HEADER_I18NTABLE:
02217 if (ptr)
02218 (void)headerAddEntry(spec->sourceHeader, tag, type, ptr, count);
02219 break;
02220 default:
02221
02222 break;
02223 }
02224 }
02225 hi = headerFreeIterator(hi);
02226
02227
02228
02229
02230 for (hi = headerInitIterator(spec->buildRestrictions);
02231 headerNextIterator(hi, &tag, &type, &ptr, &count);
02232 ptr = headerFreeData(ptr, type))
02233 {
02234 if (ptr)
02235 (void) headerAddEntry(spec->sourceHeader, tag, type, ptr, count);
02236 }
02237 hi = headerFreeIterator(hi);
02238
02239
02240 if (spec->BANames && spec->BACount > 0) {
02241 (void) headerAddEntry(spec->sourceHeader, RPMTAG_BUILDARCHS,
02242 RPM_STRING_ARRAY_TYPE,
02243 spec->BANames, spec->BACount);
02244 }
02245 }
02246
02247 int processSourceFiles(Spec spec)
02248 {
02249 struct Source *srcPtr;
02250 StringBuf sourceFiles;
02251 int x, isSpec = 1;
02252 struct FileList_s fl;
02253 char *s, **files, **fp;
02254 Package pkg;
02255
02256 sourceFiles = newStringBuf();
02257
02258
02259
02260
02261
02262 if (spec->sourceHeader == NULL)
02263 initSourceHeader(spec);
02264
02265
02266 appendLineStringBuf(sourceFiles, spec->specFile);
02267 if (spec->sourceHeader != NULL)
02268 for (srcPtr = spec->sources; srcPtr != NULL; srcPtr = srcPtr->next) {
02269 if (srcPtr->flags & RPMBUILD_ISSOURCE) {
02270 (void) headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_SOURCE,
02271 RPM_STRING_ARRAY_TYPE, &srcPtr->source, 1);
02272 if (srcPtr->flags & RPMBUILD_ISNO) {
02273 (void) headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_NOSOURCE,
02274 RPM_INT32_TYPE, &srcPtr->num, 1);
02275 }
02276 }
02277 if (srcPtr->flags & RPMBUILD_ISPATCH) {
02278 (void) headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_PATCH,
02279 RPM_STRING_ARRAY_TYPE, &srcPtr->source, 1);
02280 if (srcPtr->flags & RPMBUILD_ISNO) {
02281 (void) headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_NOPATCH,
02282 RPM_INT32_TYPE, &srcPtr->num, 1);
02283 }
02284 }
02285
02286 { const char * sfn;
02287 sfn = rpmGetPath( ((srcPtr->flags & RPMBUILD_ISNO) ? "!" : ""),
02288 "%{_sourcedir}/", srcPtr->source, NULL);
02289 appendLineStringBuf(sourceFiles, sfn);
02290 sfn = _free(sfn);
02291 }
02292 }
02293
02294 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
02295 for (srcPtr = pkg->icon; srcPtr != NULL; srcPtr = srcPtr->next) {
02296 const char * sfn;
02297 sfn = rpmGetPath( ((srcPtr->flags & RPMBUILD_ISNO) ? "!" : ""),
02298 "%{_sourcedir}/", srcPtr->source, NULL);
02299 appendLineStringBuf(sourceFiles, sfn);
02300 sfn = _free(sfn);
02301 }
02302 }
02303
02304 spec->sourceCpioList = NULL;
02305
02306 fl.fileList = xcalloc((spec->numSources + 1), sizeof(*fl.fileList));
02307 fl.processingFailed = 0;
02308 fl.fileListRecsUsed = 0;
02309 fl.totalFileSize = 0;
02310 fl.prefix = NULL;
02311 fl.buildRootURL = NULL;
02312
02313 s = getStringBuf(sourceFiles);
02314 files = splitString(s, strlen(s), '\n');
02315
02316
02317 x = 0;
02318 for (fp = files; *fp != NULL; fp++) {
02319 const char * diskURL, *diskPath;
02320 FileListRec flp;
02321
02322 diskURL = *fp;
02323 SKIPSPACE(diskURL);
02324 if (! *diskURL)
02325 continue;
02326
02327 flp = &fl.fileList[x];
02328
02329 flp->flags = isSpec ? RPMFILE_SPECFILE : 0;
02330
02331 if (*diskURL == '!') {
02332 flp->flags |= RPMFILE_GHOST;
02333 diskURL++;
02334 }
02335
02336 (void) urlPath(diskURL, &diskPath);
02337
02338 flp->diskURL = xstrdup(diskURL);
02339 diskPath = strrchr(diskPath, '/');
02340 if (diskPath)
02341 diskPath++;
02342 else
02343 diskPath = diskURL;
02344
02345 flp->fileURL = xstrdup(diskPath);
02346 flp->verifyFlags = RPMVERIFY_ALL;
02347
02348 if (Stat(diskURL, &flp->fl_st)) {
02349 rpmError(RPMERR_BADSPEC, _("Bad file: %s: %s\n"),
02350 diskURL, strerror(errno));
02351 fl.processingFailed = 1;
02352 }
02353
02354 flp->uname = getUname(flp->fl_uid);
02355 flp->gname = getGname(flp->fl_gid);
02356 flp->langs = xstrdup("");
02357
02358 fl.totalFileSize += flp->fl_size;
02359
02360 if (! (flp->uname && flp->gname)) {
02361 rpmError(RPMERR_BADSPEC, _("Bad owner/group: %s\n"), diskURL);
02362 fl.processingFailed = 1;
02363 }
02364
02365 isSpec = 0;
02366 x++;
02367 }
02368 fl.fileListRecsUsed = x;
02369 freeSplitString(files);
02370
02371 if (! fl.processingFailed) {
02372 if (spec->sourceHeader != NULL)
02373 genCpioListAndHeader(&fl, &spec->sourceCpioList,
02374 spec->sourceHeader, 1);
02375 }
02376
02377 sourceFiles = freeStringBuf(sourceFiles);
02378 fl.fileList = freeFileList(fl.fileList, fl.fileListRecsUsed);
02379 return fl.processingFailed;
02380 }
02381
02387 static int checkFiles(StringBuf fileList)
02388
02389
02390 {
02391
02392 static const char * av_ckfile[] = { "%{?__check_files}", NULL };
02393
02394 StringBuf sb_stdout = NULL;
02395 const char * s;
02396 int rc;
02397
02398 s = rpmExpand(av_ckfile[0], NULL);
02399 if (!(s && *s)) {
02400 rc = -1;
02401 goto exit;
02402 }
02403 rc = 0;
02404
02405 rpmMessage(RPMMESS_NORMAL, _("Checking for unpackaged file(s): %s\n"), s);
02406
02407
02408 rc = rpmfcExec(av_ckfile, fileList, &sb_stdout, 0);
02409
02410 if (rc < 0)
02411 goto exit;
02412
02413 if (sb_stdout) {
02414 static int _unpackaged_files_terminate_build = 0;
02415 static int oneshot = 0;
02416 const char * t;
02417
02418 if (!oneshot) {
02419 _unpackaged_files_terminate_build =
02420 rpmExpandNumeric("%{?_unpackaged_files_terminate_build}");
02421 oneshot = 1;
02422 }
02423
02424 t = getStringBuf(sb_stdout);
02425 if ((*t != '\0') && (*t != '\n')) {
02426 rc = (_unpackaged_files_terminate_build) ? 1 : 0;
02427 rpmMessage((rc ? RPMMESS_ERROR : RPMMESS_WARNING),
02428 _("Installed (but unpackaged) file(s) found:\n%s"), t);
02429 }
02430 }
02431
02432 exit:
02433 sb_stdout = freeStringBuf(sb_stdout);
02434 s = _free(s);
02435 return rc;
02436 }
02437
02438
02439 int processBinaryFiles(Spec spec, int installSpecialDoc, int test)
02440
02441
02442 {
02443 Package pkg;
02444 int res = 0;
02445
02446 check_fileList = newStringBuf();
02447
02448 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
02449 const char *n, *v, *r;
02450 int rc;
02451
02452 if (pkg->fileList == NULL)
02453 continue;
02454
02455 (void) headerNVR(pkg->header, &n, &v, &r);
02456 rpmMessage(RPMMESS_NORMAL, _("Processing files: %s-%s-%s\n"), n, v, r);
02457
02458 if ((rc = processPackageFiles(spec, pkg, installSpecialDoc, test)))
02459 res = rc;
02460
02461 (void) rpmfcGenerateDepends(spec, pkg);
02462
02463 }
02464
02465
02466
02467
02468
02469
02470 if (res == 0) {
02471 if (checkFiles(check_fileList) > 0)
02472 res = 1;
02473 }
02474
02475 check_fileList = freeStringBuf(check_fileList);
02476
02477 return res;
02478 }
02479