00001
00005 #include "system.h"
00006
00007 static int _debug = 0;
00008
00009
00010 const char * RPMVERSION = VERSION;
00011
00012 #include "rpmio_internal.h"
00013 #include <rpmlib.h>
00014 #include <rpmurl.h>
00015 #include <rpmmacro.h>
00016
00017 #include "misc.h"
00018 #include "debug.h"
00019
00020
00021
00022
00023 char ** splitString(const char * str, int length, char sep)
00024 {
00025 const char * source;
00026 char * s, * dest;
00027 char ** list;
00028 int i;
00029 int fields;
00030
00031 s = xmalloc(length + 1);
00032
00033 fields = 1;
00034 for (source = str, dest = s, i = 0; i < length; i++, source++, dest++) {
00035 *dest = *source;
00036 if (*dest == sep) fields++;
00037 }
00038
00039 *dest = '\0';
00040
00041 list = xmalloc(sizeof(*list) * (fields + 1));
00042
00043 dest = s;
00044 list[0] = dest;
00045 i = 1;
00046 while (i < fields) {
00047 if (*dest == sep) {
00048 list[i++] = dest + 1;
00049 *dest = 0;
00050 }
00051 dest++;
00052 }
00053
00054 list[i] = NULL;
00055
00056 return list;
00057 }
00058
00059 void freeSplitString(char ** list)
00060 {
00061
00062 list[0] = _free(list[0]);
00063
00064 list = _free(list);
00065 }
00066
00067 #ifdef DYING
00068 int rpmfileexists(const char * urlfn)
00069 {
00070 const char *fn;
00071 int urltype = urlPath(urlfn, &fn);
00072 struct stat buf;
00073
00074 if (*fn == '\0') fn = "/";
00075 switch (urltype) {
00076 case URL_IS_FTP:
00077 case URL_IS_HTTP:
00078 case URL_IS_PATH:
00079 case URL_IS_UNKNOWN:
00080 if (Stat(fn, &buf)) {
00081 switch(errno) {
00082 case ENOENT:
00083 case EINVAL:
00084 return 0;
00085 }
00086 }
00087 break;
00088 case URL_IS_DASH:
00089 default:
00090 return 0;
00091 break;
00092 }
00093
00094 return 1;
00095 }
00096 #endif
00097
00098 int doputenv(const char *str)
00099 {
00100 char * a;
00101
00102
00103 a = xmalloc(strlen(str) + 1);
00104 strcpy(a, str);
00105 return putenv(a);
00106 }
00107
00108 int dosetenv(const char * name, const char * value, int overwrite)
00109 {
00110 char * a;
00111
00112 if (!overwrite && getenv(name)) return 0;
00113
00114
00115 a = xmalloc(strlen(name) + strlen(value) + sizeof("="));
00116 (void) stpcpy( stpcpy( stpcpy( a, name), "="), value);
00117 return putenv(a);
00118 }
00119
00120 static int rpmMkpath(const char * path, mode_t mode, uid_t uid, gid_t gid)
00121
00122
00123 {
00124 char * d, * de;
00125 int created = 0;
00126 int rc;
00127
00128 if (path == NULL)
00129 return -1;
00130 d = alloca(strlen(path)+2);
00131 de = stpcpy(d, path);
00132 de[1] = '\0';
00133 for (de = d; *de != '\0'; de++) {
00134 struct stat st;
00135 char savec;
00136
00137 while (*de && *de != '/') de++;
00138 savec = de[1];
00139 de[1] = '\0';
00140
00141 rc = stat(d, &st);
00142 if (rc) {
00143 switch(errno) {
00144 default:
00145 return errno;
00146 break;
00147 case ENOENT:
00148 break;
00149 }
00150 rc = mkdir(d, mode);
00151 if (rc)
00152 return errno;
00153 created = 1;
00154 if (!(uid == (uid_t) -1 && gid == (gid_t) -1)) {
00155 rc = chown(d, uid, gid);
00156 if (rc)
00157 return errno;
00158 }
00159 } else if (!S_ISDIR(st.st_mode)) {
00160 return ENOTDIR;
00161 }
00162 de[1] = savec;
00163 }
00164 rc = 0;
00165 if (created)
00166 rpmMessage(RPMMESS_WARNING, "created %%_tmppath directory %s\n", path);
00167 return rc;
00168 }
00169
00170 int makeTempFile(const char * prefix, const char ** fnptr, FD_t * fdptr)
00171 {
00172 const char * tpmacro = "%{?_tmppath:%{_tmppath}}%{!?_tmppath:/var/tmp}";
00173 const char * tempfn = NULL;
00174 const char * tfn = NULL;
00175 static int _initialized = 0;
00176 int temput;
00177 FD_t fd = NULL;
00178 int ran;
00179
00180
00181 if (!prefix) prefix = "";
00182
00183
00184
00185
00186 if (!_initialized) {
00187 _initialized = 1;
00188 tempfn = rpmGenPath(prefix, tpmacro, NULL);
00189 if (rpmMkpath(tempfn, 0755, (uid_t) -1, (gid_t) -1))
00190 goto errxit;
00191 }
00192
00193
00194
00195 srand(time(NULL));
00196 ran = rand() % 100000;
00197
00198
00199
00200 do {
00201 char tfnbuf[64];
00202 #ifndef NOTYET
00203 sprintf(tfnbuf, "rpm-tmp.%d", ran++);
00204 tempfn = _free(tempfn);
00205 tempfn = rpmGenPath(prefix, tpmacro, tfnbuf);
00206 #else
00207 strcpy(tfnbuf, "rpm-tmp.XXXXXX");
00208 tempfn = _free(tempfn);
00209 tempfn = rpmGenPath(prefix, tpmacro, mktemp(tfnbuf));
00210 #endif
00211
00212 temput = urlPath(tempfn, &tfn);
00213 if (*tfn == '\0') goto errxit;
00214
00215 switch (temput) {
00216 case URL_IS_HTTP:
00217 case URL_IS_DASH:
00218 goto errxit;
00219 break;
00220 default:
00221 break;
00222 }
00223
00224 fd = Fopen(tempfn, "w+x.ufdio");
00225
00226 } while ((fd == NULL || Ferror(fd)) && errno == EEXIST);
00227
00228 if (fd == NULL || Ferror(fd))
00229 goto errxit;
00230
00231 switch(temput) {
00232 case URL_IS_PATH:
00233 case URL_IS_UNKNOWN:
00234 { struct stat sb, sb2;
00235 if (!stat(tfn, &sb) && S_ISLNK(sb.st_mode)) {
00236 rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
00237 goto errxit;
00238 }
00239
00240 if (sb.st_nlink != 1) {
00241 rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
00242 goto errxit;
00243 }
00244
00245 if (fstat(Fileno(fd), &sb2) == 0) {
00246 if (sb2.st_ino != sb.st_ino || sb2.st_dev != sb.st_dev) {
00247 rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
00248 goto errxit;
00249 }
00250 }
00251 } break;
00252 default:
00253 break;
00254 }
00255
00256
00257 if (fnptr)
00258 *fnptr = tempfn;
00259 else
00260 tempfn = _free(tempfn);
00261
00262 *fdptr = fd;
00263
00264 return 0;
00265
00266 errxit:
00267 tempfn = _free(tempfn);
00268
00269 if (fd) (void) Fclose(fd);
00270
00271 return 1;
00272 }
00273
00274 char * currentDirectory(void)
00275 {
00276 int currDirLen;
00277 char * currDir;
00278
00279 currDirLen = 50;
00280 currDir = xmalloc(currDirLen);
00281 while (!getcwd(currDir, currDirLen) && errno == ERANGE) {
00282 currDirLen += 50;
00283 currDir = xrealloc(currDir, currDirLen);
00284 }
00285
00286 return currDir;
00287 }
00288
00289 int _noDirTokens = 0;
00290
00291 static int dncmp(const void * a, const void * b)
00292 {
00293 const char *const * first = a;
00294 const char *const * second = b;
00295 return strcmp(*first, *second);
00296 }
00297
00298 void compressFilelist(Header h)
00299 {
00300 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00301 HAE_t hae = (HAE_t)headerAddEntry;
00302 HRE_t hre = (HRE_t)headerRemoveEntry;
00303 HFD_t hfd = headerFreeData;
00304 char ** fileNames;
00305 const char ** dirNames;
00306 const char ** baseNames;
00307 int_32 * dirIndexes;
00308 rpmTagType fnt;
00309 int count;
00310 int i;
00311 int dirIndex = -1;
00312
00313
00314
00315
00316
00317
00318
00319 if (headerIsEntry(h, RPMTAG_DIRNAMES)) {
00320 (void) hre(h, RPMTAG_OLDFILENAMES);
00321 return;
00322 }
00323
00324 if (!hge(h, RPMTAG_OLDFILENAMES, &fnt, (void **) &fileNames, &count))
00325 return;
00326 if (fileNames == NULL || count <= 0)
00327 return;
00328
00329 dirNames = alloca(sizeof(*dirNames) * count);
00330 baseNames = alloca(sizeof(*dirNames) * count);
00331 dirIndexes = alloca(sizeof(*dirIndexes) * count);
00332
00333 if (fileNames[0][0] != '/') {
00334
00335 dirIndex = 0;
00336 dirNames[dirIndex] = "";
00337 for (i = 0; i < count; i++) {
00338 dirIndexes[i] = dirIndex;
00339 baseNames[i] = fileNames[i];
00340 }
00341 goto exit;
00342 }
00343
00344 for (i = 0; i < count; i++) {
00345 const char ** needle;
00346 char savechar;
00347 char * baseName;
00348 int len;
00349
00350 if (fileNames[i] == NULL)
00351 continue;
00352 baseName = strrchr(fileNames[i], '/') + 1;
00353 len = baseName - fileNames[i];
00354 needle = dirNames;
00355 savechar = *baseName;
00356 *baseName = '\0';
00357 if (dirIndex < 0 ||
00358 (needle = bsearch(&fileNames[i], dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) {
00359 char *s = alloca(len + 1);
00360 memcpy(s, fileNames[i], len + 1);
00361 s[len] = '\0';
00362 dirIndexes[i] = ++dirIndex;
00363 dirNames[dirIndex] = s;
00364 } else
00365 dirIndexes[i] = needle - dirNames;
00366
00367 *baseName = savechar;
00368 baseNames[i] = baseName;
00369 }
00370
00371 exit:
00372 if (count > 0) {
00373 (void) hae(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, dirIndexes, count);
00374 (void) hae(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
00375 baseNames, count);
00376 (void) hae(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
00377 dirNames, dirIndex + 1);
00378 }
00379
00380 fileNames = hfd(fileNames, fnt);
00381
00382 (void) hre(h, RPMTAG_OLDFILENAMES);
00383 }
00384
00385
00386
00387
00388
00389 static void doBuildFileList(Header h, const char *** fileListPtr,
00390 int * fileCountPtr, rpmTag baseNameTag,
00391 rpmTag dirNameTag, rpmTag dirIndexesTag)
00392
00393 {
00394 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00395 HFD_t hfd = headerFreeData;
00396 const char ** baseNames;
00397 const char ** dirNames;
00398 int * dirIndexes;
00399 int count;
00400 const char ** fileNames;
00401 int size;
00402 rpmTagType bnt, dnt;
00403 char * data;
00404 int i;
00405
00406 if (!hge(h, baseNameTag, &bnt, (void **) &baseNames, &count)) {
00407 if (fileListPtr) *fileListPtr = NULL;
00408 if (fileCountPtr) *fileCountPtr = 0;
00409 return;
00410 }
00411
00412 (void) hge(h, dirNameTag, &dnt, (void **) &dirNames, NULL);
00413 (void) hge(h, dirIndexesTag, NULL, (void **) &dirIndexes, &count);
00414
00415 size = sizeof(*fileNames) * count;
00416 for (i = 0; i < count; i++)
00417 size += strlen(baseNames[i]) + strlen(dirNames[dirIndexes[i]]) + 1;
00418
00419 fileNames = xmalloc(size);
00420 data = ((char *) fileNames) + (sizeof(*fileNames) * count);
00421 for (i = 0; i < count; i++) {
00422 fileNames[i] = data;
00423 data = stpcpy( stpcpy(data, dirNames[dirIndexes[i]]), baseNames[i]);
00424 *data++ = '\0';
00425 }
00426 baseNames = hfd(baseNames, bnt);
00427 dirNames = hfd(dirNames, dnt);
00428
00429 if (fileListPtr)
00430 *fileListPtr = fileNames;
00431 else
00432 fileNames = _free(fileNames);
00433 if (fileCountPtr) *fileCountPtr = count;
00434 }
00435
00436 void expandFilelist(Header h)
00437 {
00438 HAE_t hae = (HAE_t)headerAddEntry;
00439 HRE_t hre = (HRE_t)headerRemoveEntry;
00440 const char ** fileNames = NULL;
00441 int count = 0;
00442
00443 if (!headerIsEntry(h, RPMTAG_OLDFILENAMES)) {
00444 doBuildFileList(h, &fileNames, &count, RPMTAG_BASENAMES,
00445 RPMTAG_DIRNAMES, RPMTAG_DIRINDEXES);
00446 if (fileNames == NULL || count <= 0)
00447 return;
00448 (void) hae(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE,
00449 fileNames, count);
00450 fileNames = _free(fileNames);
00451 }
00452
00453 (void) hre(h, RPMTAG_DIRNAMES);
00454 (void) hre(h, RPMTAG_BASENAMES);
00455 (void) hre(h, RPMTAG_DIRINDEXES);
00456 }
00457
00458
00459 void rpmBuildFileList(Header h, const char *** fileListPtr, int * fileCountPtr)
00460 {
00461 doBuildFileList(h, fileListPtr, fileCountPtr, RPMTAG_BASENAMES,
00462 RPMTAG_DIRNAMES, RPMTAG_DIRINDEXES);
00463 }
00464
00465 void buildOrigFileList(Header h, const char *** fileListPtr, int * fileCountPtr)
00466 {
00467 doBuildFileList(h, fileListPtr, fileCountPtr, RPMTAG_ORIGBASENAMES,
00468 RPMTAG_ORIGDIRNAMES, RPMTAG_ORIGDIRINDEXES);
00469 }
00470
00471
00472
00473
00474
00475
00476 int myGlobPatternP (const char *patternURL)
00477 {
00478 const char *p;
00479 char c;
00480 int open = 0;
00481
00482 (void) urlPath(patternURL, &p);
00483 while ((c = *p++) != '\0')
00484 switch (c) {
00485 case '?':
00486 case '*':
00487 return (1);
00488 case '[':
00489 open++;
00490 continue;
00491 case ']':
00492 if (open)
00493 return (1);
00494 continue;
00495 case '\\':
00496 if (*p++ == '\0')
00497 return (0);
00498 }
00499
00500 return (0);
00501 }
00502
00503 static int glob_error(const char *foo, int bar)
00504 {
00505 return 1;
00506 }
00507
00508 int rpmGlob(const char * patterns, int * argcPtr, const char *** argvPtr)
00509 {
00510 int ac = 0;
00511 const char ** av = NULL;
00512 int argc = 0;
00513 const char ** argv = NULL;
00514 const char * path;
00515 const char * globURL;
00516 char * globRoot = NULL;
00517 size_t maxb, nb;
00518 glob_t gl;
00519 int ut;
00520 int i, j;
00521 int rc;
00522
00523 rc = poptParseArgvString(patterns, &ac, &av);
00524 if (rc)
00525 return rc;
00526
00527 for (j = 0; j < ac; j++) {
00528 if (!myGlobPatternP(av[j])) {
00529 if (argc == 0)
00530 argv = xmalloc((argc+2) * sizeof(*argv));
00531 else
00532 argv = xrealloc(argv, (argc+2) * sizeof(*argv));
00533 argv[argc] = xstrdup(av[j]);
00534
00535 if (_debug)
00536 fprintf(stderr, "*** rpmGlob argv[%d] \"%s\"\n", argc, argv[argc]);
00537
00538 argc++;
00539 continue;
00540 }
00541
00542 gl.gl_pathc = 0;
00543 gl.gl_pathv = NULL;
00544 rc = Glob(av[j], 0, glob_error, &gl);
00545 if (rc)
00546 goto exit;
00547
00548
00549 maxb = 0;
00550 for (i = 0; i < gl.gl_pathc; i++) {
00551 if ((nb = strlen(&(gl.gl_pathv[i][0]))) > maxb)
00552 maxb = nb;
00553 }
00554
00555 ut = urlPath(av[j], &path);
00556 nb = ((ut > URL_IS_DASH) ? (path - av[j]) : 0);
00557 maxb += nb;
00558 maxb += 1;
00559 globURL = globRoot = xmalloc(maxb);
00560
00561 switch (ut) {
00562 case URL_IS_HTTP:
00563 case URL_IS_FTP:
00564 case URL_IS_PATH:
00565 case URL_IS_DASH:
00566 strncpy(globRoot, av[j], nb);
00567 break;
00568 case URL_IS_UNKNOWN:
00569 break;
00570 }
00571 globRoot += nb;
00572 *globRoot = '\0';
00573
00574 if (_debug)
00575 fprintf(stderr, "*** GLOB maxb %d diskURL %d %*s globURL %p %s\n", (int)maxb, (int)nb, (int)nb, av[j], globURL, globURL);
00576
00577
00578
00579 if (argc == 0)
00580 argv = xmalloc((gl.gl_pathc+1) * sizeof(*argv));
00581 else if (gl.gl_pathc > 0)
00582 argv = xrealloc(argv, (argc+gl.gl_pathc+1) * sizeof(*argv));
00583
00584 for (i = 0; i < gl.gl_pathc; i++) {
00585 const char * globFile = &(gl.gl_pathv[i][0]);
00586 if (globRoot > globURL && globRoot[-1] == '/')
00587 while (*globFile == '/') globFile++;
00588 strcpy(globRoot, globFile);
00589
00590 if (_debug)
00591 fprintf(stderr, "*** rpmGlob argv[%d] \"%s\"\n", argc, globURL);
00592
00593 argv[argc++] = xstrdup(globURL);
00594 }
00595
00596 Globfree(&gl);
00597
00598 globURL = _free(globURL);
00599 }
00600 if (argv != NULL && argc > 0) {
00601 argv[argc] = NULL;
00602 if (argvPtr)
00603 *argvPtr = argv;
00604 if (argcPtr)
00605 *argcPtr = argc;
00606 rc = 0;
00607 } else
00608 rc = 1;
00609
00610
00611 exit:
00612 av = _free(av);
00613 if (rc || argvPtr == NULL) {
00614 if (argv != NULL)
00615 for (i = 0; i < argc; i++)
00616 argv[i] = _free(argv[i]);
00617 argv = _free(argv);
00618 }
00619 return rc;
00620 }
00621
00622
00623
00624
00625
00626
00627 int rpmHeaderGetEntry(Header h, int_32 tag, int_32 *type,
00628 void **p, int_32 *c)
00629 {
00630 switch (tag) {
00631 case RPMTAG_OLDFILENAMES:
00632 { const char ** fl = NULL;
00633 int count;
00634 rpmBuildFileList(h, &fl, &count);
00635 if (count > 0) {
00636 *p = fl;
00637 if (c) *c = count;
00638 if (type) *type = RPM_STRING_ARRAY_TYPE;
00639 return 1;
00640 }
00641 if (c) *c = 0;
00642 return 0;
00643 } break;
00644
00645 case RPMTAG_GROUP:
00646 case RPMTAG_DESCRIPTION:
00647 case RPMTAG_SUMMARY:
00648 { char fmt[128];
00649 const char * msgstr;
00650 const char * errstr;
00651
00652 fmt[0] = '\0';
00653 (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tagName(tag)), "}\n");
00654
00655
00656 msgstr = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr);
00657 if (msgstr) {
00658 *p = (void *) msgstr;
00659 if (type) *type = RPM_STRING_TYPE;
00660 if (c) *c = 1;
00661 return 1;
00662 } else {
00663 if (c) *c = 0;
00664 return 0;
00665 }
00666 } break;
00667
00668 default:
00669 return headerGetEntry(h, tag, type, p, c);
00670 break;
00671 }
00672
00673 }
00674
00675
00676
00677
00678 int rpmPackageGetEntry( void *leadp, Header sigs, Header h,
00679 int_32 tag, int_32 *type, void **p, int_32 *c)
00680 {
00681 int_32 sigtag;
00682
00683 switch (tag) {
00684 case RPMTAG_SIGSIZE: sigtag = RPMSIGTAG_SIZE; break;
00685 case RPMTAG_SIGLEMD5_1: sigtag = RPMSIGTAG_LEMD5_1; break;
00686 case RPMTAG_SIGPGP: sigtag = RPMSIGTAG_PGP; break;
00687 case RPMTAG_SIGLEMD5_2: sigtag = RPMSIGTAG_LEMD5_2; break;
00688 case RPMTAG_SIGMD5: sigtag = RPMSIGTAG_MD5; break;
00689 case RPMTAG_SIGGPG: sigtag = RPMSIGTAG_GPG; break;
00690 case RPMTAG_SIGPGP5: sigtag = RPMSIGTAG_GPG; break;
00691
00692 default:
00693 return rpmHeaderGetEntry(h, tag, type, p, c);
00694 break;
00695 }
00696
00697 if (headerIsEntry(h, tag))
00698 return rpmHeaderGetEntry(h, tag, type, p, c);
00699
00700 if (sigs == NULL) {
00701 if (c) *c = 0;
00702 return 0;
00703 }
00704
00705 return headerGetEntry(sigs, sigtag, type, p, c);
00706 }
00707
00708
00709
00710
00711
00712 void providePackageNVR(Header h)
00713 {
00714 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00715 HFD_t hfd = headerFreeData;
00716 const char *name, *version, *release;
00717 int_32 * epoch;
00718 const char *pEVR;
00719 char *p;
00720 int_32 pFlags = RPMSENSE_EQUAL;
00721 const char ** provides = NULL;
00722 const char ** providesEVR = NULL;
00723 rpmTagType pnt, pvt;
00724 int_32 * provideFlags = NULL;
00725 int providesCount;
00726 int i;
00727 int bingo = 1;
00728
00729
00730 (void) headerNVR(h, &name, &version, &release);
00731 if (!(name && version && release))
00732 return;
00733 pEVR = p = alloca(21 + strlen(version) + 1 + strlen(release) + 1);
00734 *p = '\0';
00735 if (hge(h, RPMTAG_EPOCH, NULL, (void **) &epoch, NULL)) {
00736 sprintf(p, "%d:", *epoch);
00737 while (*p != '\0')
00738 p++;
00739 }
00740 (void) stpcpy( stpcpy( stpcpy(p, version) , "-") , release);
00741
00742
00743
00744
00745
00746 if (!hge(h, RPMTAG_PROVIDENAME, &pnt, (void **) &provides, &providesCount))
00747 goto exit;
00748
00749
00750
00751
00752 if (!hge(h, RPMTAG_PROVIDEVERSION, &pvt, (void **) &providesEVR, NULL)) {
00753 for (i = 0; i < providesCount; i++) {
00754 char * vdummy = "";
00755 int_32 fdummy = RPMSENSE_ANY;
00756 (void) headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
00757 &vdummy, 1);
00758 (void) headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
00759 &fdummy, 1);
00760 }
00761 goto exit;
00762 }
00763
00764 (void) hge(h, RPMTAG_PROVIDEFLAGS, NULL, (void **) &provideFlags, NULL);
00765
00766 if (provides && providesEVR && provideFlags)
00767 for (i = 0; i < providesCount; i++) {
00768 if (!(provides[i] && providesEVR[i]))
00769 continue;
00770 if (!(provideFlags[i] == RPMSENSE_EQUAL &&
00771 !strcmp(name, provides[i]) && !strcmp(pEVR, providesEVR[i])))
00772 continue;
00773 bingo = 0;
00774 break;
00775 }
00776
00777 exit:
00778 provides = hfd(provides, pnt);
00779 providesEVR = hfd(providesEVR, pvt);
00780
00781 if (bingo) {
00782 (void) headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME, RPM_STRING_ARRAY_TYPE,
00783 &name, 1);
00784 (void) headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
00785 &pFlags, 1);
00786 (void) headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
00787 &pEVR, 1);
00788 }
00789 }
00790
00791 int domd5(const char * fn, unsigned char * digest, int asAscii)
00792
00793 {
00794 int rc;
00795 FD_t fd = Fopen(fn, "r.ufdio");
00796 unsigned char buf[BUFSIZ];
00797 unsigned char * md5sum = NULL;
00798 size_t md5len;
00799
00800 if (fd == NULL || Ferror(fd)) {
00801 if (fd)
00802 (void) Fclose(fd);
00803 return 1;
00804 }
00805
00806 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
00807 while ((rc = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
00808 {};
00809 fdFiniDigest(fd, PGPHASHALGO_MD5, (void **)&md5sum, &md5len, asAscii);
00810
00811 if (Ferror(fd))
00812 rc = 1;
00813 (void) Fclose(fd);
00814
00815 if (!rc)
00816 memcpy(digest, md5sum, md5len);
00817 md5sum = _free(md5sum);
00818
00819 return rc;
00820 }