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