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