00001
00006 #include "system.h"
00007
00008 #include <rpmio_internal.h>
00009 #include <rpmcb.h>
00010 #include <ugid.h>
00011
00012 #include <rpmsq.h>
00013 #include <rpmsw.h>
00014
00015 #include "../rpmdb/rpmtag.h"
00016
00017 typedef struct rpmts_s * rpmts;
00018 typedef struct rpmte_s * rpmte;
00019
00020 #define _IOSM_INTERNAL
00021 #include <iosm.h>
00022 #define iosmUNSAFE iosmStage
00023
00024 #include "cpio.h"
00025 #include "tar.h"
00026 #include "ar.h"
00027
00028 typedef iosmMapFlags cpioMapFlags;
00029 #define _RPMFI_INTERNAL
00030 #define _RPMFI_NOMETHODS
00031 #include "../lib/rpmfi.h"
00032
00033 typedef struct rpmds_s * rpmds;
00034 typedef struct rpmRelocation_s * rpmRelocation;
00035 #undef _USE_RPMTE
00036 #if defined(_USE_RPMTE)
00037 typedef void * alKey;
00038 #include "rpmte.h"
00039 #endif
00040
00041 #undef _USE_RPMSX
00042 #if defined(_USE_RPMSX)
00043 #include "../lib/rpmsx.h"
00044 #endif
00045
00046 typedef struct rpmdb_s * rpmdb;
00047 typedef struct rpmmi_s * rpmmi;
00048 typedef struct rpmPRCO_s * rpmPRCO;
00049 typedef struct Spec_s * Spec;
00050 #undef _USE_RPMTS
00051 #if defined(_USE_RPMTS)
00052 #include "rpmts.h"
00053 #endif
00054
00055 #include "debug.h"
00056
00057
00058
00059
00060
00061
00062
00063 #define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
00064
00065 #define _IOSM_DEBUG 0
00066
00067 int _iosm_debug = _IOSM_DEBUG;
00068
00069
00070
00071 int _iosm_threads = 0;
00072
00073
00074
00075 int (*_iosmNext) (IOSM_t iosm, iosmFileStage nstage)
00076 = &iosmNext;
00077
00078
00079 #if defined(_USE_RPMTS)
00080 void * iosmGetTs(const IOSM_t iosm)
00081 {
00082 const IOSMI_t iter = iosm->iter;
00083
00084 return (iter ? iter->ts : NULL);
00085
00086 }
00087 #endif
00088
00089 void * iosmGetFi(const IOSM_t iosm)
00090 {
00091 const IOSMI_t iter = iosm->iter;
00092
00093 return (iter ? iter->fi : NULL);
00094
00095 }
00096
00097 #define SUFFIX_RPMORIG ".rpmorig"
00098 #define SUFFIX_RPMSAVE ".rpmsave"
00099 #define SUFFIX_RPMNEW ".rpmnew"
00100
00109 static
00110 const char * iosmFsPath( const IOSM_t iosm,
00111 const struct stat * st,
00112 const char * subdir,
00113 const char * suffix)
00114
00115
00116 {
00117 const char * s = NULL;
00118
00119 if (iosm) {
00120 char * t;
00121 int nb;
00122 nb = strlen(iosm->dirName) +
00123 (st && !S_ISDIR(st->st_mode) ? (subdir ? strlen(subdir) : 0) : 0) +
00124 (st && !S_ISDIR(st->st_mode) ? (suffix ? strlen(suffix) : 0) : 0) +
00125 strlen(iosm->baseName) + 1;
00126 s = t = xmalloc(nb);
00127 t = stpcpy(t, iosm->dirName);
00128 if (st && !S_ISDIR(st->st_mode))
00129 if (subdir) t = stpcpy(t, subdir);
00130 t = stpcpy(t, iosm->baseName);
00131 if (st && !S_ISDIR(st->st_mode))
00132 if (suffix) t = stpcpy(t, suffix);
00133 }
00134 return s;
00135 }
00136
00142 static void * mapFreeIterator( void * p)
00143
00144 {
00145 IOSMI_t iter = p;
00146 if (iter) {
00147 #if !defined(_RPMFI_NOMETHODS)
00148 iter->fi = rpmfiUnlink(iter->fi, "mapIterator");
00149 #endif
00150 iter->fi = NULL;
00151 }
00152 return _free(p);
00153 }
00154
00161
00162 static void *
00163 mapInitIterator(rpmfi fi, int reverse)
00164
00165 {
00166 IOSMI_t iter = NULL;
00167
00168 iter = xcalloc(1, sizeof(*iter));
00169 #if !defined(_RPMFI_NOMETHODS)
00170 iter->fi = rpmfiLink(fi, "mapIterator");
00171 #else
00172 iter->fi = fi;
00173 #endif
00174 iter->reverse = reverse;
00175 iter->i = (iter->reverse ? (fi->fc - 1) : 0);
00176 iter->isave = iter->i;
00177 return iter;
00178 }
00179
00180
00186 static int mapNextIterator( void * a)
00187
00188 {
00189 IOSMI_t iter = a;
00190 int i = -1;
00191
00192 if (iter) {
00193 if (iter->reverse) {
00194 if (iter->i >= 0) i = iter->i--;
00195 } else {
00196 if (iter->i < (int) ((rpmfi)iter->fi)->fc) i = iter->i++;
00197 }
00198 iter->isave = i;
00199 }
00200 return i;
00201 }
00202
00205 static int iosmStrCmp(const void * a, const void * b)
00206
00207 {
00208 const char * aurl = *(const char **)a;
00209 const char * burl = *(const char **)b;
00210 const char * afn = NULL;
00211 const char * bfn = NULL;
00212
00213 (void) urlPath(aurl, &afn);
00214 (void) urlPath(burl, &bfn);
00215
00216 #ifdef VERY_OLD_BUGGY_RPM_PACKAGES
00217
00218 if (strchr(afn, '/') == NULL)
00219 bfn = strrchr(bfn, '/') + 1;
00220 #endif
00221
00222
00223 if (afn[0] == '.' && afn[1] == '/') afn += 2;
00224 if (bfn[0] == '.' && bfn[1] == '/') bfn += 2;
00225
00226
00227 if (afn[0] == '/') afn += 1;
00228 if (bfn[0] == '/') bfn += 1;
00229
00230 return strcmp(afn, bfn);
00231 }
00232
00239 static int mapFind( IOSMI_t iter, const char * iosmPath)
00240
00241 {
00242 int ix = -1;
00243
00244 if (iter) {
00245
00246 const rpmfi fi = iter->fi;
00247
00248 #if !defined(_RPMFI_NOMETHODS)
00249 size_t fc = rpmfiFC(fi);
00250 #else
00251 size_t fc = (fi ? fi->fc : 0);
00252 #endif
00253 if (fi && fc > 0 && fi->apath && iosmPath && *iosmPath) {
00254 const char ** p = NULL;
00255
00256 if (fi->apath != NULL)
00257 p = bsearch(&iosmPath, fi->apath, fc, sizeof(iosmPath),
00258 iosmStrCmp);
00259 if (p) {
00260 iter->i = p - fi->apath;
00261 ix = mapNextIterator(iter);
00262 }
00263 }
00264 }
00265 return ix;
00266 }
00267
00271 typedef struct dnli_s {
00272 rpmfi fi;
00273
00274 char * active;
00275 int reverse;
00276 int isave;
00277 int i;
00278 } * DNLI_t;
00279
00285 static void * dnlFreeIterator( const void * a)
00286
00287 {
00288 if (a) {
00289 DNLI_t dnli = (void *)a;
00290 if (dnli->active) free(dnli->active);
00291 }
00292 return _free(a);
00293 }
00294
00297 static inline int dnlCount( const DNLI_t dnli)
00298
00299 {
00300 return (int) (dnli ? dnli->fi->dc : 0);
00301 }
00302
00305 static inline int dnlIndex( const DNLI_t dnli)
00306
00307 {
00308 return (dnli ? dnli->isave : -1);
00309 }
00310
00317
00318 static
00319 void * dnlInitIterator( const IOSM_t iosm,
00320 int reverse)
00321
00322
00323 {
00324 rpmfi fi = iosmGetFi(iosm);
00325 const char * dnl;
00326 DNLI_t dnli;
00327 int i, j;
00328
00329 if (fi == NULL)
00330 return NULL;
00331 dnli = xcalloc(1, sizeof(*dnli));
00332 dnli->fi = fi;
00333 dnli->reverse = reverse;
00334 dnli->i = (int) (reverse ? fi->dc : 0);
00335
00336 if (fi->dc) {
00337 dnli->active = xcalloc(fi->dc, sizeof(*dnli->active));
00338
00339
00340 #if !defined(_RPMFI_NOMETHODS)
00341 if ((fi = rpmfiInit(fi, 0)) != NULL)
00342 while ((i = rpmfiNext(fi)) >= 0)
00343 #else
00344 for (i = 0; i < (int)fi->fc; i++)
00345 #endif
00346 {
00347 if (!iosmFileActionSkipped(fi->actions[i]))
00348 dnli->active[fi->dil[i]] = (char)1;
00349 }
00350
00351
00352 #if !defined(_RPMFI_NOMETHODS)
00353 if ((fi = rpmfiInit(fi, 0)) != NULL)
00354 while ((i = rpmfiNext(fi)) >= 0)
00355 #else
00356 for (i = 0; i < (int)fi->fc; i++)
00357 #endif
00358 {
00359 rpmuint32_t dil;
00360 size_t dnlen, bnlen;
00361
00362 if (!S_ISDIR(fi->fmodes[i]))
00363 continue;
00364
00365 dil = fi->dil[i];
00366 dnlen = strlen(fi->dnl[dil]);
00367 bnlen = strlen(fi->bnl[i]);
00368
00369 for (j = 0; j < (int)fi->dc; j++) {
00370 size_t jlen;
00371
00372 if (!dnli->active[j] || j == (int)dil)
00373 continue;
00374 (void) urlPath(fi->dnl[j], &dnl);
00375 jlen = strlen(dnl);
00376 if (jlen != (dnlen+bnlen+1))
00377 continue;
00378 if (strncmp(dnl, fi->dnl[dil], dnlen))
00379 continue;
00380 if (strncmp(dnl+dnlen, fi->bnl[i], bnlen))
00381 continue;
00382 if (dnl[dnlen+bnlen] != '/' || dnl[dnlen+bnlen+1] != '\0')
00383 continue;
00384
00385 dnli->active[j] = (char)0;
00386 break;
00387 }
00388 }
00389
00390
00391 if (!reverse) {
00392 j = 0;
00393 for (i = 0; i < (int)fi->dc; i++) {
00394 if (!dnli->active[i]) continue;
00395 if (j == 0) {
00396 j = 1;
00397 rpmlog(RPMLOG_DEBUG,
00398 D_("========== Directories not explicitly included in package:\n"));
00399 }
00400 (void) urlPath(fi->dnl[i], &dnl);
00401 rpmlog(RPMLOG_DEBUG, "%10d %s\n", i, dnl);
00402 }
00403 if (j)
00404 rpmlog(RPMLOG_DEBUG, "==========\n");
00405 }
00406 }
00407 return dnli;
00408 }
00409
00410
00416 static
00417 const char * dnlNextIterator( DNLI_t dnli)
00418
00419 {
00420 const char * dn = NULL;
00421
00422 if (dnli) {
00423 rpmfi fi = dnli->fi;
00424 int i = -1;
00425
00426 if (dnli->active)
00427 do {
00428 i = (!dnli->reverse ? dnli->i++ : --dnli->i);
00429 } while (i >= 0 && i < (int)fi->dc && !dnli->active[i]);
00430
00431 if (i >= 0 && i < (int)fi->dc)
00432 dn = fi->dnl[i];
00433 else
00434 i = -1;
00435 dnli->isave = i;
00436 }
00437 return dn;
00438 }
00439
00440 #if defined(WITH_PTHREADS)
00441 static void * iosmThread(void * arg)
00442
00443
00444 {
00445 IOSM_t iosm = arg;
00446
00447 return ((void *) ((long)iosmStage(iosm, iosm->nstage)));
00448
00449 }
00450 #endif
00451
00452 int iosmNext(IOSM_t iosm, iosmFileStage nstage)
00453
00454
00455 {
00456 iosm->nstage = nstage;
00457 #if defined(WITH_PTHREADS)
00458 if (iosm->multithreaded)
00459 return rpmsqJoin( rpmsqThread(iosmThread, iosm) );
00460 #endif
00461 return iosmStage(iosm, iosm->nstage);
00462 }
00463
00469 static int saveHardLink( IOSM_t iosm)
00470
00471
00472
00473
00474
00475 {
00476 struct stat * st = &iosm->sb;
00477 int rc = 0;
00478 int ix = -1;
00479 int j;
00480
00481
00482 for (iosm->li = iosm->links; iosm->li; iosm->li = iosm->li->next) {
00483 if (iosm->li->sb.st_ino == st->st_ino && iosm->li->sb.st_dev == st->st_dev)
00484 break;
00485 }
00486
00487
00488 if (iosm->li == NULL) {
00489 iosm->li = xcalloc(1, sizeof(*iosm->li));
00490 iosm->li->next = NULL;
00491 iosm->li->sb = *st;
00492 iosm->li->nlink = (int) st->st_nlink;
00493 iosm->li->linkIndex = iosm->ix;
00494 iosm->li->createdPath = -1;
00495
00496 iosm->li->filex = xcalloc(st->st_nlink, sizeof(iosm->li->filex[0]));
00497 memset(iosm->li->filex, -1, (st->st_nlink * sizeof(iosm->li->filex[0])));
00498 iosm->li->nsuffix = xcalloc(st->st_nlink, sizeof(*iosm->li->nsuffix));
00499
00500 if (iosm->goal == IOSM_PKGBUILD)
00501 iosm->li->linksLeft = (int) st->st_nlink;
00502 if (iosm->goal == IOSM_PKGINSTALL)
00503 iosm->li->linksLeft = 0;
00504
00505
00506 iosm->li->next = iosm->links;
00507
00508 iosm->links = iosm->li;
00509 }
00510
00511 if (iosm->goal == IOSM_PKGBUILD) --iosm->li->linksLeft;
00512 iosm->li->filex[iosm->li->linksLeft] = iosm->ix;
00513
00514 iosm->li->nsuffix[iosm->li->linksLeft] = iosm->nsuffix;
00515
00516 if (iosm->goal == IOSM_PKGINSTALL) iosm->li->linksLeft++;
00517
00518 if (iosm->goal == IOSM_PKGBUILD)
00519 return (iosm->li->linksLeft > 0);
00520
00521 if (iosm->goal != IOSM_PKGINSTALL)
00522 return 0;
00523
00524 if (!(st->st_size || iosm->li->linksLeft == (int) st->st_nlink))
00525 return 1;
00526
00527
00528 { rpmfi fi = iosmGetFi(iosm);
00529
00530 for (j = iosm->li->linksLeft - 1; j >= 0; j--) {
00531 ix = iosm->li->filex[j];
00532 if (ix < 0 || iosmFileActionSkipped(fi->actions[ix]))
00533 continue;
00534 break;
00535 }
00536 }
00537
00538
00539 if (ix < 0 || j < 0)
00540 return 1;
00541
00542
00543 iosm->li->linkIndex = j;
00544 iosm->path = _free(iosm->path);
00545 iosm->ix = ix;
00546 rc = iosmNext(iosm, IOSM_MAP);
00547 return rc;
00548 }
00549
00555 static void * freeHardLink( struct hardLink_s * li)
00556
00557 {
00558 if (li) {
00559 li->nsuffix = _free(li->nsuffix);
00560 li->filex = _free(li->filex);
00561 }
00562 return _free(li);
00563 }
00564
00565 IOSM_t newIOSM(void)
00566 {
00567 IOSM_t iosm = xcalloc(1, sizeof(*iosm));
00568 return iosm;
00569 }
00570
00571 IOSM_t freeIOSM(IOSM_t iosm)
00572 {
00573 if (iosm) {
00574 iosm->path = _free(iosm->path);
00575 while ((iosm->li = iosm->links) != NULL) {
00576 iosm->links = iosm->li->next;
00577 iosm->li->next = NULL;
00578 iosm->li = freeHardLink(iosm->li);
00579 }
00580 iosm->dnlx = _free(iosm->dnlx);
00581 iosm->ldn = _free(iosm->ldn);
00582 iosm->iter = mapFreeIterator(iosm->iter);
00583 }
00584 return _free(iosm);
00585 }
00586
00587 static int arSetup(IOSM_t iosm, rpmfi fi)
00588
00589 {
00590 const char * path;
00591 char * t;
00592 size_t lmtablen = 0;
00593 size_t nb;
00594
00595
00596 #if !defined(_RPMFI_NOMETHODS)
00597 if ((fi = rpmfiInit(fi, 0)) != NULL)
00598 while (rpmfiNext(fi) >= 0)
00599 #else
00600 int i;
00601 if (fi != NULL)
00602 for (i = 0; i < (int)fi->fc; i++)
00603 #endif
00604 {
00605 #ifdef NOTYET
00606 if (fi->apath) {
00607 const char * apath = NULL;
00608 (void) urlPath(fi->apath[ix], &apath);
00609 path = apath + fi->striplen;
00610 } else
00611 #endif
00612 #if !defined(_RPMFI_NOMETHODS)
00613 path = rpmfiBN(fi);
00614 #else
00615 path = fi->bnl[i];
00616 #endif
00617 if ((nb = strlen(path)) < 15)
00618 continue;
00619 lmtablen += nb + 1;
00620 }
00621
00622
00623 if (lmtablen == 0)
00624 return 0;
00625
00626
00627 iosm->lmtab = t = xmalloc(lmtablen + 1);
00628 iosm->lmtablen = lmtablen;
00629 iosm->lmtaboff = 0;
00630 #if !defined(_RPMFI_NOMETHODS)
00631 if ((fi = rpmfiInit(fi, 0)) != NULL)
00632 while (rpmfiNext(fi) >= 0)
00633 #else
00634 if (fi != NULL)
00635 for (i = 0; i < (int)fi->fc; i++)
00636 #endif
00637 {
00638 #ifdef NOTYET
00639 if (fi->apath) {
00640 const char * apath = NULL;
00641 (void) urlPath(fi->apath[ix], &apath);
00642 path = apath + fi->striplen;
00643 } else
00644 #endif
00645 #if !defined(_RPMFI_NOMETHODS)
00646 path = rpmfiBN(fi);
00647 #else
00648 path = fi->bnl[i];
00649 #endif
00650 if ((nb = strlen(path)) < 15)
00651 continue;
00652 t = stpcpy(t, path);
00653 *t++ = '\n';
00654 }
00655 *t = '\0';
00656
00657 return 0;
00658 }
00659
00660 int iosmSetup(IOSM_t iosm, iosmFileStage goal, const char * afmt,
00661 const void * _ts, const void * _fi, FD_t cfd,
00662 unsigned int * archiveSize, const char ** failedFile)
00663 {
00664 #if defined(_USE_RPMTS)
00665 const rpmts ts = (const rpmts) _ts;
00666 #endif
00667 const rpmfi fi = (const rpmfi) _fi;
00668 #if defined(_USE_RPMTE)
00669 int reverse = (rpmteType(fi->te) == TR_REMOVED && fi->action != FA_COPYOUT);
00670 int adding = (rpmteType(fi->te) == TR_ADDED);
00671 #else
00672 int reverse = 0;
00673 int adding = 1;
00674 #endif
00675 size_t pos = 0;
00676 int rc, ec = 0;
00677
00678 iosm->debug = _iosm_debug;
00679 iosm->multithreaded = _iosm_threads;
00680 iosm->adding = adding;
00681
00682
00683 if (iosm->debug < 0)
00684 fprintf(stderr, "--> iosmSetup(%p, 0x%x, \"%s\", %p, %p, %p, %p, %p)\n", iosm, goal, afmt, (void *)_ts, _fi, cfd, archiveSize, failedFile);
00685
00686
00687 _iosmNext = &iosmNext;
00688 if (iosm->headerRead == NULL) {
00689 if (afmt != NULL && (!strcmp(afmt, "tar") || !strcmp(afmt, "ustar"))) {
00690 if (iosm->debug < 0)
00691 fprintf(stderr, "\ttar vectors set\n");
00692 iosm->headerRead = &tarHeaderRead;
00693 iosm->headerWrite = &tarHeaderWrite;
00694 iosm->trailerWrite = &tarTrailerWrite;
00695 iosm->blksize = TAR_BLOCK_SIZE;
00696 } else
00697 if (afmt != NULL && !strcmp(afmt, "ar")) {
00698 if (iosm->debug < 0)
00699 fprintf(stderr, "\tar vectors set\n");
00700 iosm->headerRead = &arHeaderRead;
00701 iosm->headerWrite = &arHeaderWrite;
00702 iosm->trailerWrite = &arTrailerWrite;
00703 iosm->blksize = 2;
00704 if (goal == IOSM_PKGBUILD || goal == IOSM_PKGERASE)
00705 (void) arSetup(iosm, fi);
00706 } else
00707 {
00708 if (iosm->debug < 0)
00709 fprintf(stderr, "\tcpio vectors set\n");
00710 iosm->headerRead = &cpioHeaderRead;
00711 iosm->headerWrite = &cpioHeaderWrite;
00712 iosm->trailerWrite = &cpioTrailerWrite;
00713 iosm->blksize = 4;
00714 }
00715 }
00716
00717 iosm->goal = goal;
00718 if (cfd != NULL) {
00719
00720 iosm->cfd = fdLink(cfd, "persist (iosm)");
00721
00722 pos = fdGetCpioPos(iosm->cfd);
00723 fdSetCpioPos(iosm->cfd, 0);
00724 }
00725
00726 iosm->iter = mapInitIterator(fi, reverse);
00727
00728 #if defined(_USE_RPMTS)
00729 iosm->iter->ts = rpmtsLink(ts, "mapIterator");
00730 iosm->nofcontexts = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS);
00731 iosm->nofdigests =
00732 (ts != NULL && !(rpmtsFlags(ts) & RPMTRANS_FLAG_NOFDIGESTS))
00733 ? 0 : 1;
00734 #define _tsmask (RPMTRANS_FLAG_PKGCOMMIT | RPMTRANS_FLAG_COMMIT)
00735 iosm->commit = ((ts && (rpmtsFlags(ts) & _tsmask) &&
00736 iosm->goal != IOSM_PKGCOMMIT) ? 0 : 1);
00737 #undef _tsmask
00738 #else
00739
00740 iosm->iter->ts = (void *)_ts;
00741
00742 iosm->nofcontexts = 1;
00743 iosm->nofdigests = 1;
00744 iosm->commit = 1;
00745 #endif
00746
00747 if (iosm->goal == IOSM_PKGINSTALL || iosm->goal == IOSM_PKGBUILD) {
00748 fi->archivePos = 0;
00749 #if defined(_USE_RPMTS)
00750 (void) rpmtsNotify(ts, fi->te,
00751 RPMCALLBACK_INST_START, fi->archivePos, fi->archiveSize);
00752 #endif
00753 }
00754
00755
00756 iosm->archiveSize = archiveSize;
00757 if (iosm->archiveSize)
00758 *iosm->archiveSize = 0;
00759 iosm->failedFile = failedFile;
00760 if (iosm->failedFile)
00761 *iosm->failedFile = NULL;
00762
00763
00764 memset(iosm->sufbuf, 0, sizeof(iosm->sufbuf));
00765 if (iosm->goal == IOSM_PKGINSTALL) {
00766 rpmuint32_t tid;
00767 #if defined(_USE_RPMTS)
00768 tid = (ts != NULL ? rpmtsGetTid(ts) : 0);
00769 #else
00770 static time_t now = 0;
00771 if (now == 0) now = time(NULL);
00772 tid = (rpmuint32_t) now;
00773 #endif
00774 if (tid > 0 && tid < 0xffffffff)
00775 sprintf(iosm->sufbuf, ";%08x", (unsigned)tid);
00776 }
00777
00778 ec = iosm->rc = 0;
00779 rc = iosmUNSAFE(iosm, IOSM_CREATE);
00780 if (rc && !ec) ec = rc;
00781
00782 rc = iosmUNSAFE(iosm, iosm->goal);
00783 if (rc && !ec) ec = rc;
00784
00785 if (iosm->archiveSize && ec == 0)
00786 *iosm->archiveSize = (fdGetCpioPos(iosm->cfd) - pos);
00787
00788
00789 return ec;
00790
00791 }
00792
00793 int iosmTeardown(IOSM_t iosm)
00794 {
00795 int rc = iosm->rc;
00796
00797 if (iosm->debug < 0)
00798 fprintf(stderr, "--> iosmTeardown(%p)\n", iosm);
00799 if (!rc)
00800 rc = iosmUNSAFE(iosm, IOSM_DESTROY);
00801
00802 iosm->lmtab = _free(iosm->lmtab);
00803
00804 #if defined(_USE_RPMTS)
00805 (void) rpmswAdd(rpmtsOp(iosmGetTs(iosm), RPMTS_OP_DIGEST),
00806 &iosm->op_digest);
00807 (void)rpmtsFree(iter->ts);
00808 iter->ts = NULL;
00809 #else
00810 iosm->iter->ts = NULL;
00811 #endif
00812 iosm->iter = mapFreeIterator(iosm->iter);
00813 if (iosm->cfd != NULL) {
00814 iosm->cfd = fdFree(iosm->cfd, "persist (iosm)");
00815 iosm->cfd = NULL;
00816 }
00817 iosm->failedFile = NULL;
00818 return rc;
00819 }
00820
00821
00822
00823
00824
00825
00826 static int iosmMapFContext(IOSM_t iosm)
00827
00828 {
00829
00830
00831
00832 iosm->fcontext = NULL;
00833 if (!iosm->nofcontexts) {
00834 security_context_t scon = NULL;
00835 int xx = matchpathcon(iosm->path, iosm->sb.st_mode, &scon);
00836
00837
00838 if (!xx && scon != NULL)
00839 iosm->fcontext = scon;
00840 #ifdef DYING
00841 else {
00842 rpmfi fi = iosmGetFi(iosm);
00843 int i = iosm->ix;
00844
00845
00846 if (fi && i >= 0 && i < (int)fi->fc)
00847 iosm->fcontext = (fi->fcontexts ? fi->fcontexts[i] : NULL);
00848 }
00849 #endif
00850
00851 }
00852 return 0;
00853 }
00854
00855 int iosmMapPath(IOSM_t iosm)
00856 {
00857 rpmfi fi = iosmGetFi(iosm);
00858 int teAdding = iosm->adding;
00859 int rc = 0;
00860 int i = iosm->ix;
00861
00862 iosm->osuffix = NULL;
00863 iosm->nsuffix = NULL;
00864 iosm->astriplen = 0;
00865 iosm->action = FA_UNKNOWN;
00866 iosm->mapFlags = fi->mapflags;
00867
00868 if (fi && i >= 0 && i < (int)fi->fc) {
00869
00870 iosm->astriplen = fi->astriplen;
00871 iosm->action = (fi->actions ? fi->actions[i] : fi->action);
00872 iosm->fflags = (fi->fflags ? fi->fflags[i] : fi->flags);
00873 iosm->mapFlags = (fi->fmapflags ? fi->fmapflags[i] : fi->mapflags);
00874
00875
00876 iosm->dirName = fi->dnl[fi->dil[i]];
00877 iosm->baseName = fi->bnl[i];
00878
00879 switch (iosm->action) {
00880 case FA_SKIP:
00881 break;
00882 case FA_UNKNOWN:
00883 break;
00884
00885 case FA_COPYOUT:
00886 break;
00887 case FA_COPYIN:
00888 case FA_CREATE:
00889 assert(teAdding);
00890 break;
00891
00892 case FA_SKIPNSTATE:
00893 if (fi->fstates && teAdding)
00894 fi->fstates[i] = (rpmuint8_t)RPMFILE_STATE_NOTINSTALLED;
00895 break;
00896
00897 case FA_SKIPNETSHARED:
00898 if (fi->fstates && teAdding)
00899 fi->fstates[i] = (rpmuint8_t)RPMFILE_STATE_NETSHARED;
00900 break;
00901
00902 case FA_SKIPCOLOR:
00903 if (fi->fstates && teAdding)
00904 fi->fstates[i] = (rpmuint8_t)RPMFILE_STATE_WRONGCOLOR;
00905 break;
00906
00907 case FA_BACKUP:
00908 if (!(iosm->fflags & RPMFILE_GHOST))
00909 iosm->osuffix = (teAdding ? SUFFIX_RPMORIG : SUFFIX_RPMSAVE);
00910 break;
00911
00912 case FA_ALTNAME:
00913 assert(teAdding);
00914 if (!(iosm->fflags & RPMFILE_GHOST))
00915 iosm->nsuffix = SUFFIX_RPMNEW;
00916 break;
00917
00918 case FA_SAVE:
00919 assert(teAdding);
00920 if (!(iosm->fflags & RPMFILE_GHOST))
00921 iosm->osuffix = SUFFIX_RPMSAVE;
00922 break;
00923 case FA_ERASE:
00924 #if 0
00925 assert(rpmteType(fi->te) == TR_REMOVED);
00926 #endif
00927
00928
00929
00930
00931 break;
00932 default:
00933 break;
00934 }
00935
00936 if ((iosm->mapFlags & IOSM_MAP_PATH) || iosm->nsuffix) {
00937 const struct stat * st = &iosm->sb;
00938 iosm->path = _free(iosm->path);
00939 iosm->path = iosmFsPath(iosm, st, iosm->subdir,
00940 (iosm->suffix ? iosm->suffix : iosm->nsuffix));
00941 }
00942 }
00943 return rc;
00944 }
00945
00946 int iosmMapAttrs(IOSM_t iosm)
00947 {
00948 struct stat * st = &iosm->sb;
00949 rpmfi fi = iosmGetFi(iosm);
00950 int i = iosm->ix;
00951
00952 if (fi && i >= 0 && i < (int)fi->fc) {
00953 mode_t perms = (S_ISDIR(st->st_mode) ? fi->dperms : fi->fperms);
00954 mode_t finalMode = (fi->fmodes ? (mode_t)fi->fmodes[i] : perms);
00955 dev_t finalRdev = (fi->frdevs ? fi->frdevs[i] : 0);
00956 rpmuint32_t finalMtime = (fi->fmtimes ? fi->fmtimes[i] : 0);
00957 uid_t uid = fi->uid;
00958 gid_t gid = fi->gid;
00959
00960 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK)
00961
00962
00963
00964
00965
00966
00967 #endif
00968 if (fi->fuser && unameToUid(fi->fuser[i], &uid)) {
00969 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK)
00970 if (!fi->isSource) {
00971 #endif
00972 if (iosm->goal == IOSM_PKGINSTALL)
00973 rpmlog(RPMLOG_WARNING,
00974 _("user %s does not exist - using root\n"), fi->fuser[i]);
00975 uid = 0;
00976 finalMode &= ~S_ISUID;
00977 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK)
00978 }
00979 #endif
00980 }
00981
00982 if (fi->fgroup && gnameToGid(fi->fgroup[i], &gid)) {
00983 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK)
00984 if (!fi->isSource) {
00985 #endif
00986 if (iosm->goal == IOSM_PKGINSTALL)
00987 rpmlog(RPMLOG_WARNING,
00988 _("group %s does not exist - using root\n"), fi->fgroup[i]);
00989 gid = 0;
00990 finalMode &= ~S_ISGID;
00991 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK)
00992 }
00993 #endif
00994 }
00995
00996 if (iosm->mapFlags & IOSM_MAP_MODE)
00997 st->st_mode = (st->st_mode & S_IFMT) | (finalMode & ~S_IFMT);
00998 if (iosm->mapFlags & IOSM_MAP_TYPE) {
00999 st->st_mode = (st->st_mode & ~S_IFMT) | (finalMode & S_IFMT);
01000 if ((S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
01001 && st->st_nlink == 0)
01002 st->st_nlink = 1;
01003 st->st_rdev = finalRdev;
01004 st->st_mtime = finalMtime;
01005 }
01006 if (iosm->mapFlags & IOSM_MAP_UID)
01007 st->st_uid = uid;
01008 if (iosm->mapFlags & IOSM_MAP_GID)
01009 st->st_gid = gid;
01010
01011
01012
01013
01014 if (!iosm->nofdigests) {
01015 iosm->fdigestalgo = fi->digestalgo;
01016 iosm->fdigest = (fi->fdigests ? fi->fdigests[i] : NULL);
01017 iosm->digestlen = fi->digestlen;
01018 iosm->digest = (fi->digests ? (fi->digests + (iosm->digestlen * i)) : NULL);
01019 } else {
01020 iosm->fdigestalgo = 0;
01021 iosm->fdigest = NULL;
01022 iosm->digestlen = 0;
01023 iosm->digest = NULL;
01024 }
01025 }
01026 return 0;
01027 }
01028
01034
01035 static int extractRegular( IOSM_t iosm)
01036
01037
01038
01039 {
01040 const struct stat * st = &iosm->sb;
01041 size_t left = (size_t) st->st_size;
01042 int rc = 0;
01043 int xx;
01044
01045 rc = iosmNext(iosm, IOSM_WOPEN);
01046 if (rc)
01047 goto exit;
01048
01049 if (st->st_size > 0 && (iosm->fdigest != NULL || iosm->digest != NULL))
01050 fdInitDigest(iosm->wfd, iosm->fdigestalgo, 0);
01051
01052 while (left) {
01053
01054 iosm->wrlen = (left > iosm->wrsize ? iosm->wrsize : left);
01055 rc = iosmNext(iosm, IOSM_DREAD);
01056 if (rc)
01057 goto exit;
01058
01059 rc = iosmNext(iosm, IOSM_WRITE);
01060 if (rc)
01061 goto exit;
01062
01063 left -= iosm->wrnb;
01064
01065
01066 if (!rc && left)
01067 (void) iosmNext(iosm, IOSM_NOTIFY);
01068 }
01069
01070 xx = fsync(Fileno(iosm->wfd));
01071
01072 if (st->st_size > 0 && (iosm->fdigest || iosm->digest)) {
01073 void * digest = NULL;
01074 int asAscii = (iosm->digest == NULL ? 1 : 0);
01075
01076 (void) Fflush(iosm->wfd);
01077 fdFiniDigest(iosm->wfd, iosm->fdigestalgo, &digest, NULL, asAscii);
01078
01079 if (digest == NULL) {
01080 rc = IOSMERR_DIGEST_MISMATCH;
01081 goto exit;
01082 }
01083
01084 if (iosm->digest != NULL) {
01085 if (memcmp(digest, iosm->digest, iosm->digestlen))
01086 rc = IOSMERR_DIGEST_MISMATCH;
01087 } else {
01088 if (strcmp(digest, iosm->fdigest))
01089 rc = IOSMERR_DIGEST_MISMATCH;
01090 }
01091 digest = _free(digest);
01092 }
01093
01094 exit:
01095 (void) iosmNext(iosm, IOSM_WCLOSE);
01096 return rc;
01097 }
01098
01099
01106
01107 static int writeFile( IOSM_t iosm, int writeData)
01108
01109
01110
01111 {
01112 const char * path = iosm->path;
01113 const char * opath = iosm->opath;
01114 struct stat * st = &iosm->sb;
01115 struct stat * ost = &iosm->osb;
01116 size_t left;
01117 int xx;
01118 int rc;
01119
01120 st->st_size = (writeData ? ost->st_size : 0);
01121
01122 if (S_ISDIR(st->st_mode)) {
01123 st->st_size = 0;
01124 } else if (S_ISLNK(st->st_mode)) {
01125
01126
01127
01128
01129
01130 rc = iosmUNSAFE(iosm, IOSM_READLINK);
01131 if (rc) goto exit;
01132 st->st_size = iosm->rdnb;
01133 iosm->lpath = xstrdup(iosm->rdbuf);
01134 }
01135
01136 if (iosm->mapFlags & IOSM_MAP_ABSOLUTE) {
01137 size_t nb=strlen(iosm->dirName) + strlen(iosm->baseName) + sizeof(".");
01138 char * t = alloca(nb);
01139 *t = '\0';
01140 iosm->path = t;
01141 if (iosm->mapFlags & IOSM_MAP_ADDDOT)
01142 *t++ = '.';
01143 t = stpcpy( stpcpy(t, iosm->dirName), iosm->baseName);
01144 } else if (iosm->mapFlags & IOSM_MAP_PATH) {
01145 rpmfi fi = iosmGetFi(iosm);
01146 if (fi->apath) {
01147 const char * apath = NULL;
01148 (void) urlPath(fi->apath[iosm->ix], &apath);
01149 iosm->path = apath + fi->striplen;
01150 } else
01151 iosm->path = fi->bnl[iosm->ix];
01152 }
01153
01154 rc = iosmNext(iosm, IOSM_HWRITE);
01155 iosm->path = path;
01156 if (rc) goto exit;
01157
01158 if (writeData && S_ISREG(st->st_mode)) {
01159 #if defined(HAVE_MMAP)
01160 char * rdbuf = NULL;
01161 void * mapped = (void *)-1;
01162 size_t nmapped = 0;
01163
01164 int use_mmap = (st->st_size <= 0x07ffffff);
01165 #endif
01166
01167 rc = iosmNext(iosm, IOSM_ROPEN);
01168 if (rc) goto exit;
01169
01170
01171 #if defined(HAVE_MMAP)
01172 if (use_mmap) {
01173 mapped = mmap(NULL, st->st_size, PROT_READ, MAP_SHARED, Fileno(iosm->rfd), 0);
01174 if (mapped != (void *)-1) {
01175 rdbuf = iosm->rdbuf;
01176 iosm->rdbuf = (char *) mapped;
01177 iosm->rdlen = nmapped = st->st_size;
01178 #if defined(HAVE_MADVISE) && defined(MADV_DONTNEED)
01179 xx = madvise(mapped, nmapped, MADV_DONTNEED);
01180 #endif
01181 }
01182 }
01183 #endif
01184
01185 left = st->st_size;
01186
01187 while (left) {
01188 #if defined(HAVE_MMAP)
01189 if (mapped != (void *)-1) {
01190 iosm->rdnb = nmapped;
01191 } else
01192 #endif
01193 {
01194 iosm->rdlen = (left > iosm->rdsize ? iosm->rdsize : left),
01195 rc = iosmNext(iosm, IOSM_READ);
01196 if (rc) goto exit;
01197 }
01198
01199
01200 rc = iosmNext(iosm, IOSM_DWRITE);
01201 if (rc) goto exit;
01202
01203 left -= iosm->wrnb;
01204 }
01205
01206 #if defined(HAVE_MMAP)
01207 if (mapped != (void *)-1) {
01208
01209 xx = msync(mapped, nmapped, MS_ASYNC);
01210 #if defined(HAVE_MADVISE) && defined(MADV_DONTNEED)
01211 xx = madvise(mapped, nmapped, MADV_DONTNEED);
01212 #endif
01213 xx = munmap(mapped, nmapped);
01214 iosm->rdbuf = rdbuf;
01215 } else
01216 #endif
01217 xx = fsync(Fileno(iosm->rfd));
01218
01219 }
01220
01221 rc = iosmNext(iosm, IOSM_PAD);
01222 if (rc) goto exit;
01223
01224 rc = 0;
01225
01226 exit:
01227 if (iosm->rfd != NULL)
01228 (void) iosmNext(iosm, IOSM_RCLOSE);
01229
01230 iosm->opath = opath;
01231 iosm->path = path;
01232
01233 return rc;
01234 }
01235
01236
01242 static int writeLinkedFile( IOSM_t iosm)
01243
01244
01245
01246 {
01247 const char * path = iosm->path;
01248 const char * lpath = iosm->lpath;
01249 const char * nsuffix = iosm->nsuffix;
01250 int iterIndex = iosm->ix;
01251 int ec = 0;
01252 int rc;
01253 int i;
01254 const char * linkpath = NULL;
01255 int firstfile = 1;
01256
01257 iosm->path = NULL;
01258 iosm->lpath = NULL;
01259 iosm->nsuffix = NULL;
01260 iosm->ix = -1;
01261
01262 for (i = iosm->li->nlink - 1; i >= 0; i--) {
01263
01264 if (iosm->li->filex[i] < 0) continue;
01265
01266 iosm->ix = iosm->li->filex[i];
01267
01268 rc = iosmNext(iosm, IOSM_MAP);
01269
01270
01271
01272 if (iosm->headerWrite == tarHeaderWrite) {
01273 if (firstfile) {
01274 const char * apath = NULL;
01275 char *t;
01276 (void) urlPath(iosm->path, &apath);
01277
01278 t = xmalloc(sizeof(".") + strlen(apath + iosm->astriplen));
01279 (void) stpcpy( stpcpy(t, "."), apath + iosm->astriplen);
01280 linkpath = t;
01281 firstfile = 0;
01282 } else
01283 iosm->lpath = linkpath;
01284
01285
01286 rc = writeFile(iosm, (iosm->lpath == NULL));
01287 } else {
01288
01289 rc = writeFile(iosm, (i == 0));
01290 }
01291 if (iosm->failedFile && rc != 0 && *iosm->failedFile == NULL) {
01292 ec = rc;
01293 *iosm->failedFile = xstrdup(iosm->path);
01294 }
01295
01296 iosm->path = _free(iosm->path);
01297 iosm->li->filex[i] = -1;
01298 }
01299
01300
01301 linkpath = _free(linkpath);
01302
01303 iosm->ix = iterIndex;
01304 iosm->nsuffix = nsuffix;
01305 iosm->lpath = lpath;
01306 iosm->path = path;
01307 return ec;
01308 }
01309
01315
01316 static int iosmMakeLinks( IOSM_t iosm)
01317
01318
01319
01320 {
01321 const char * path = iosm->path;
01322 const char * opath = iosm->opath;
01323 const char * nsuffix = iosm->nsuffix;
01324 int iterIndex = iosm->ix;
01325 int ec = 0;
01326 int rc;
01327 int i;
01328
01329 iosm->path = NULL;
01330 iosm->opath = NULL;
01331 iosm->nsuffix = NULL;
01332 iosm->ix = -1;
01333
01334 iosm->ix = iosm->li->filex[iosm->li->createdPath];
01335 rc = iosmNext(iosm, IOSM_MAP);
01336 iosm->opath = iosm->path;
01337 iosm->path = NULL;
01338 for (i = 0; i < iosm->li->nlink; i++) {
01339 if (iosm->li->filex[i] < 0) continue;
01340 if (iosm->li->createdPath == i) continue;
01341
01342 iosm->ix = iosm->li->filex[i];
01343 iosm->path = _free(iosm->path);
01344 rc = iosmNext(iosm, IOSM_MAP);
01345 if (iosmFileActionSkipped(iosm->action)) continue;
01346
01347 rc = iosmUNSAFE(iosm, IOSM_VERIFY);
01348 if (!rc) continue;
01349 if (!(rc == IOSMERR_ENOENT)) break;
01350
01351
01352 rc = iosmNext(iosm, IOSM_LINK);
01353 if (iosm->failedFile && rc != 0 && *iosm->failedFile == NULL) {
01354 ec = rc;
01355 *iosm->failedFile = xstrdup(iosm->path);
01356 }
01357
01358 iosm->li->linksLeft--;
01359 }
01360 iosm->path = _free(iosm->path);
01361 iosm->opath = _free(iosm->opath);
01362
01363 iosm->ix = iterIndex;
01364 iosm->nsuffix = nsuffix;
01365 iosm->path = path;
01366 iosm->opath = opath;
01367 return ec;
01368 }
01369
01370
01376
01377 static int iosmCommitLinks( IOSM_t iosm)
01378
01379
01380
01381
01382 {
01383 const char * path = iosm->path;
01384 const char * nsuffix = iosm->nsuffix;
01385 int iterIndex = iosm->ix;
01386 struct stat * st = &iosm->sb;
01387 int rc = 0;
01388 int i;
01389
01390 iosm->path = NULL;
01391 iosm->nsuffix = NULL;
01392 iosm->ix = -1;
01393
01394 for (iosm->li = iosm->links; iosm->li; iosm->li = iosm->li->next) {
01395 if (iosm->li->sb.st_ino == st->st_ino && iosm->li->sb.st_dev == st->st_dev)
01396 break;
01397 }
01398
01399 for (i = 0; i < iosm->li->nlink; i++) {
01400 if (iosm->li->filex[i] < 0) continue;
01401 iosm->ix = iosm->li->filex[i];
01402 rc = iosmNext(iosm, IOSM_MAP);
01403 if (!iosmFileActionSkipped(iosm->action))
01404 rc = iosmNext(iosm, IOSM_COMMIT);
01405 iosm->path = _free(iosm->path);
01406 iosm->li->filex[i] = -1;
01407 }
01408
01409 iosm->ix = iterIndex;
01410 iosm->nsuffix = nsuffix;
01411 iosm->path = path;
01412 return rc;
01413 }
01414
01415
01421 static int iosmRmdirs( IOSM_t iosm)
01422
01423
01424
01425 {
01426 const char * path = iosm->path;
01427 void * dnli = dnlInitIterator(iosm, 1);
01428 char * dn = iosm->rdbuf;
01429 int dc = dnlCount(dnli);
01430 int rc = 0;
01431
01432 iosm->path = NULL;
01433 dn[0] = '\0';
01434
01435 if (iosm->ldn != NULL && iosm->dnlx != NULL)
01436 while ((iosm->path = dnlNextIterator(dnli)) != NULL) {
01437 size_t dnlen = strlen(iosm->path);
01438 char * te;
01439
01440 dc = dnlIndex(dnli);
01441 if (iosm->dnlx[dc] < 1 || (size_t)iosm->dnlx[dc] >= dnlen)
01442 continue;
01443
01444
01445 te = stpcpy(dn, iosm->path) - 1;
01446 iosm->path = dn;
01447
01448
01449
01450 do {
01451 if (*te == '/') {
01452 *te = '\0';
01453
01454 rc = iosmNext(iosm, IOSM_RMDIR);
01455
01456 *te = '/';
01457 }
01458 if (rc)
01459 break;
01460 te--;
01461 } while ((te - iosm->path) > iosm->dnlx[dc]);
01462
01463 }
01464 dnli = dnlFreeIterator(dnli);
01465
01466
01467 iosm->path = path;
01468 return rc;
01469 }
01470
01476 static int iosmMkdirs( IOSM_t iosm)
01477
01478
01479
01480
01481
01482 {
01483 struct stat * st = &iosm->sb;
01484 struct stat * ost = &iosm->osb;
01485 const char * path = iosm->path;
01486 mode_t st_mode = st->st_mode;
01487 void * dnli = dnlInitIterator(iosm, 0);
01488 char * dn = iosm->rdbuf;
01489 int dc = dnlCount(dnli);
01490 int rc = 0;
01491 size_t i;
01492
01493 iosm->path = NULL;
01494
01495 dn[0] = '\0';
01496 iosm->dnlx = (dc ? xcalloc(dc, sizeof(*iosm->dnlx)) : NULL);
01497
01498 if (iosm->dnlx != NULL)
01499 while ((iosm->path = dnlNextIterator(dnli)) != NULL) {
01500 size_t dnlen = strlen(iosm->path);
01501 char * te;
01502
01503 dc = dnlIndex(dnli);
01504 if (dc < 0) continue;
01505 iosm->dnlx[dc] = (unsigned short) dnlen;
01506 if (dnlen <= 1)
01507 continue;
01508
01509
01510 if (dnlen <= iosm->ldnlen && !strcmp(iosm->path, iosm->ldn))
01511 continue;
01512
01513
01514
01515 (void) stpcpy(dn, iosm->path);
01516 iosm->path = dn;
01517
01518
01519 (void) urlPath(dn, (const char **)&te);
01520 for (i = 1, te++; *te != '\0'; te++, i++) {
01521 if (*te != '/')
01522 continue;
01523
01524 *te = '\0';
01525
01526
01527
01528 if (i < iosm->ldnlen &&
01529 (iosm->ldn[i] == '/' || iosm->ldn[i] == '\0') &&
01530 !strncmp(iosm->path, iosm->ldn, i))
01531 {
01532 *te = '/';
01533
01534 iosm->dnlx[dc] = (te - dn);
01535 continue;
01536 }
01537
01538
01539
01540 rc = iosmUNSAFE(iosm, IOSM_LSTAT);
01541 *te = '/';
01542
01543
01544 if (rc == 0 && S_ISDIR(ost->st_mode)) {
01545
01546 iosm->dnlx[dc] = (te - dn);
01547 } else if (rc == IOSMERR_ENOENT) {
01548 rpmfi fi = iosmGetFi(iosm);
01549 *te = '\0';
01550 st->st_mode = S_IFDIR | (fi->dperms & 07777);
01551 rc = iosmNext(iosm, IOSM_MKDIR);
01552 if (!rc) {
01553 #if defined(_USE_RPMSX)
01554 security_context_t scon = NULL;
01555
01556
01557 if (!fsm->nofcontexts
01558 && !matchpathcon(iosm->path, st->st_mode, &scon)
01559 && scon != NULL)
01560 {
01561 iosm->fcontext = scon;
01562 rc = iosmNext(iosm, IOSM_LSETFCON);
01563 } else
01564 #endif
01565 iosm->fcontext = NULL;
01566 if (iosm->fcontext == NULL)
01567 rpmlog(RPMLOG_DEBUG,
01568 D_("%s directory created with perms %04o, no context.\n"),
01569 iosm->path, (unsigned)(st->st_mode & 07777));
01570 else {
01571 rpmlog(RPMLOG_DEBUG,
01572 D_("%s directory created with perms %04o, context %s.\n"),
01573 iosm->path, (unsigned)(st->st_mode & 07777),
01574 iosm->fcontext);
01575 #if defined(_USE_RPMSX)
01576 iosm->fcontext = NULL;
01577 scon = _free(scon);
01578 #endif
01579 }
01580 }
01581 *te = '/';
01582 }
01583 if (rc)
01584 break;
01585 }
01586 if (rc) break;
01587
01588
01589
01590 if (iosm->ldnalloc < (dnlen + 1)) {
01591 iosm->ldnalloc = dnlen + 100;
01592 iosm->ldn = xrealloc(iosm->ldn, iosm->ldnalloc);
01593 }
01594 if (iosm->ldn != NULL) {
01595 strcpy(iosm->ldn, iosm->path);
01596 iosm->ldnlen = dnlen;
01597 }
01598
01599 }
01600 dnli = dnlFreeIterator(dnli);
01601
01602
01603 iosm->path = path;
01604 st->st_mode = st_mode;
01605
01606 return rc;
01607
01608 }
01609
01610 #ifdef NOTYET
01611
01616 static int iosmStat( IOSM_t iosm)
01617
01618
01619 {
01620 int rc = 0;
01621
01622 if (iosm->path != NULL) {
01623 int saveernno = errno;
01624 rc = iosmUNSAFE(iosm, (!(iosm->mapFlags & IOSM_FOLLOW_SYMLINKS)
01625 ? IOSM_LSTAT : IOSM_STAT));
01626 if (rc == IOSMERR_ENOENT) {
01627 errno = saveerrno;
01628 rc = 0;
01629 iosm->exists = 0;
01630 } else if (rc == 0) {
01631 iosm->exists = 1;
01632 }
01633 } else {
01634
01635 iosm->exists = 0;
01636 }
01637 return rc;
01638 }
01639 #endif
01640
01641 #define IS_DEV_LOG(_x) \
01642 ((_x) != NULL && strlen(_x) >= (sizeof("/dev/log")-1) && \
01643 !strncmp((_x), "/dev/log", sizeof("/dev/log")-1) && \
01644 ((_x)[sizeof("/dev/log")-1] == '\0' || \
01645 (_x)[sizeof("/dev/log")-1] == ';'))
01646
01647
01648 int iosmStage(IOSM_t iosm, iosmFileStage stage)
01649 {
01650 #ifdef NOTUSED
01651 iosmFileStage prevStage = iosm->stage;
01652 const char * const prev = iosmFileStageString(prevStage);
01653 #endif
01654 const char * const cur = iosmFileStageString(stage);
01655 struct stat * st = &iosm->sb;
01656 struct stat * ost = &iosm->osb;
01657 int saveerrno = errno;
01658 int rc = iosm->rc;
01659 size_t left;
01660 int i;
01661
01662 #define _fafilter(_a) \
01663 (!((_a) == FA_CREATE || (_a) == FA_ERASE || (_a) == FA_COPYIN || (_a) == FA_COPYOUT) \
01664 ? iosmFileActionString(_a) : "")
01665
01666 if (stage & IOSM_DEAD) {
01667
01668 } else if (stage & IOSM_INTERNAL) {
01669 if (iosm->debug && !(stage & IOSM_SYSCALL))
01670 rpmlog(RPMLOG_DEBUG, " %8s %06o%3d (%4d,%4d)%12lu %s %s\n",
01671 cur,
01672 (unsigned)st->st_mode, (int)st->st_nlink,
01673 (int)st->st_uid, (int)st->st_gid, (unsigned long)st->st_size,
01674 (iosm->path ? iosm->path : ""),
01675 _fafilter(iosm->action));
01676 } else {
01677 const char * apath = NULL;
01678 if (iosm->path)
01679 (void) urlPath(iosm->path, &apath);
01680 iosm->stage = stage;
01681 if (iosm->debug || !(stage & IOSM_VERBOSE))
01682 rpmlog(RPMLOG_DEBUG, "%-8s %06o%3d (%4d,%4d)%12lu %s %s\n",
01683 cur,
01684 (unsigned)st->st_mode, (int)st->st_nlink,
01685 (int)st->st_uid, (int)st->st_gid, (unsigned long)st->st_size,
01686 (apath ? apath + iosm->astriplen : ""),
01687 _fafilter(iosm->action));
01688 }
01689 #undef _fafilter
01690
01691 switch (stage) {
01692 case IOSM_UNKNOWN:
01693 break;
01694 case IOSM_PKGINSTALL:
01695 while (1) {
01696
01697 rc = iosmUNSAFE(iosm, IOSM_INIT);
01698
01699
01700 if (rc == IOSMERR_HDR_TRAILER) {
01701 rc = 0;
01702 break;
01703 }
01704
01705
01706 if (rc) {
01707 iosm->postpone = 1;
01708 (void) iosmNext(iosm, IOSM_UNDO);
01709 break;
01710 }
01711
01712
01713 rc = iosmNext(iosm, IOSM_PROCESS);
01714 if (rc) {
01715 (void) iosmNext(iosm, IOSM_UNDO);
01716 break;
01717 }
01718
01719
01720 (void) iosmNext(iosm, IOSM_NOTIFY);
01721
01722 rc = iosmNext(iosm, IOSM_FINI);
01723 if (rc) {
01724 break;
01725 }
01726 }
01727 break;
01728 case IOSM_PKGERASE:
01729 case IOSM_PKGCOMMIT:
01730 while (1) {
01731
01732 rc = iosmUNSAFE(iosm, IOSM_INIT);
01733
01734
01735 if (rc == IOSMERR_HDR_TRAILER) {
01736 rc = 0;
01737 break;
01738 }
01739
01740
01741 if (iosmNext(iosm, IOSM_FINI))
01742 break;
01743 }
01744 break;
01745 case IOSM_PKGBUILD:
01746 while (1) {
01747
01748 rc = iosmUNSAFE(iosm, IOSM_INIT);
01749
01750
01751 if (rc == IOSMERR_HDR_TRAILER) {
01752 rc = 0;
01753 break;
01754 }
01755
01756
01757 if (rc) {
01758 iosm->postpone = 1;
01759 (void) iosmNext(iosm, IOSM_UNDO);
01760 break;
01761 }
01762
01763
01764 rc = iosmNext(iosm, IOSM_PROCESS);
01765 if (rc) {
01766 (void) iosmNext(iosm, IOSM_UNDO);
01767 break;
01768 }
01769
01770
01771 (void) iosmNext(iosm, IOSM_NOTIFY);
01772
01773 if (iosmNext(iosm, IOSM_FINI))
01774 break;
01775 }
01776
01777
01778 if (!(iosm->mapFlags & IOSM_ALL_HARDLINKS)) {
01779 int nlink, j;
01780 while ((iosm->li = iosm->links) != NULL) {
01781 iosm->links = iosm->li->next;
01782 iosm->li->next = NULL;
01783
01784
01785 for (j = -1, nlink = 0, i = 0; i < iosm->li->nlink; i++) {
01786 if (iosm->li->filex[i] < 0)
01787 continue;
01788 nlink++;
01789 if (j == -1) j = i;
01790 }
01791
01792 if (j != 0) {
01793 iosm->li->filex[0] = iosm->li->filex[j];
01794 iosm->li->filex[j] = -1;
01795 }
01796 iosm->li->sb.st_nlink = nlink;
01797
01798 iosm->sb = iosm->li->sb;
01799 iosm->osb = iosm->sb;
01800
01801 if (!rc) rc = writeLinkedFile(iosm);
01802
01803 iosm->li = freeHardLink(iosm->li);
01804 }
01805 }
01806
01807 if (!rc)
01808 rc = iosmNext(iosm, IOSM_TRAILER);
01809
01810 break;
01811 case IOSM_CREATE:
01812 iosm->path = _free(iosm->path);
01813 iosm->lpath = _free(iosm->lpath);
01814 iosm->opath = _free(iosm->opath);
01815 iosm->dnlx = _free(iosm->dnlx);
01816
01817 iosm->ldn = _free(iosm->ldn);
01818 iosm->ldnalloc = iosm->ldnlen = 0;
01819
01820 iosm->rdsize = iosm->wrsize = 0;
01821 iosm->rdbuf = iosm->rdb = _free(iosm->rdb);
01822 iosm->wrbuf = iosm->wrb = _free(iosm->wrb);
01823 if (iosm->goal == IOSM_PKGINSTALL || iosm->goal == IOSM_PKGBUILD) {
01824 iosm->rdsize = 16 * BUFSIZ;
01825 iosm->rdbuf = iosm->rdb = xmalloc(iosm->rdsize);
01826 iosm->wrsize = 16 * BUFSIZ;
01827 iosm->wrbuf = iosm->wrb = xmalloc(iosm->wrsize);
01828 }
01829
01830 iosm->mkdirsdone = 0;
01831 iosm->ix = -1;
01832 iosm->links = NULL;
01833 iosm->li = NULL;
01834 errno = 0;
01835
01836
01837 if (iosm->goal == IOSM_PKGINSTALL) {
01838
01839 rc = iosmNext(iosm, IOSM_MKDIRS);
01840
01841 if (!rc) iosm->mkdirsdone = 1;
01842 }
01843
01844 break;
01845 case IOSM_INIT:
01846 iosm->path = _free(iosm->path);
01847 iosm->lpath = _free(iosm->lpath);
01848 iosm->postpone = 0;
01849 iosm->diskchecked = iosm->exists = 0;
01850 iosm->subdir = NULL;
01851 iosm->suffix = (iosm->sufbuf[0] != '\0' ? iosm->sufbuf : NULL);
01852 iosm->action = FA_UNKNOWN;
01853 iosm->osuffix = NULL;
01854 iosm->nsuffix = NULL;
01855
01856 if (iosm->goal == IOSM_PKGINSTALL) {
01857
01858 rc = iosmUNSAFE(iosm, IOSM_NEXT);
01859 }
01860 if (rc) break;
01861
01862
01863 iosm->ix = ((iosm->goal == IOSM_PKGINSTALL)
01864 ? mapFind(iosm->iter, iosm->path) : mapNextIterator(iosm->iter));
01865
01866 { rpmfi fi = iosmGetFi(iosm);
01867 if (!(fi->mapflags & IOSM_PAYLOAD_LIST)) {
01868
01869 if (!(fi->mapflags & IOSM_PAYLOAD_EXTRACT)) {
01870 if (iosm->ix < 0) {
01871 if (iosm->goal == IOSM_PKGINSTALL) {
01872 #if 0
01873 rpmlog(RPMLOG_WARNING,
01874 _("archive file %s was not found in header file list\n"),
01875 iosm->path);
01876 #endif
01877 if (iosm->failedFile && *iosm->failedFile == NULL)
01878 *iosm->failedFile = xstrdup(iosm->path);
01879 rc = IOSMERR_UNMAPPED_FILE;
01880 } else {
01881 rc = IOSMERR_HDR_TRAILER;
01882 }
01883 break;
01884 }
01885 }
01886
01887
01888 if (iosm->goal != IOSM_PKGINSTALL) {
01889 st->st_mode = fi->fmodes[iosm->ix];
01890 }
01891 }
01892 }
01893
01894
01895 rc = iosmNext(iosm, IOSM_MAP);
01896 if (rc) break;
01897
01898
01899 #ifdef NOTYET
01900 rc = iosmStat(iosm);
01901 #else
01902 if (iosm->path != NULL &&
01903 !(iosm->goal == IOSM_PKGINSTALL && S_ISREG(st->st_mode)))
01904 {
01905 rc = iosmUNSAFE(iosm, (!(iosm->mapFlags & IOSM_FOLLOW_SYMLINKS)
01906 ? IOSM_LSTAT : IOSM_STAT));
01907 if (rc == IOSMERR_ENOENT) {
01908 errno = saveerrno;
01909 rc = 0;
01910 iosm->exists = 0;
01911 } else if (rc == 0) {
01912 iosm->exists = 1;
01913 }
01914 } else {
01915
01916 iosm->exists = 0;
01917 }
01918 #endif
01919 iosm->diskchecked = 1;
01920 if (rc) break;
01921
01922
01923 if (iosm->goal != IOSM_PKGINSTALL)
01924 *st = *ost;
01925
01926
01927 rc = iosmMapAttrs(iosm);
01928 if (rc) break;
01929
01930 iosm->postpone = iosmFileActionSkipped(iosm->action);
01931 if (iosm->goal == IOSM_PKGINSTALL || iosm->goal == IOSM_PKGBUILD) {
01932
01933 if (S_ISREG(st->st_mode) && st->st_nlink > 1)
01934 iosm->postpone = saveHardLink(iosm);
01935
01936 }
01937 { rpmfi fi = iosmGetFi(iosm);
01938 if (fi->mapflags & IOSM_PAYLOAD_LIST) iosm->postpone = 1;
01939 }
01940 break;
01941 case IOSM_PRE:
01942 break;
01943 case IOSM_MAP:
01944 rc = iosmMapPath(iosm);
01945 break;
01946 case IOSM_MKDIRS:
01947 rc = iosmMkdirs(iosm);
01948 break;
01949 case IOSM_RMDIRS:
01950 if (iosm->dnlx)
01951 rc = iosmRmdirs(iosm);
01952 break;
01953 case IOSM_PROCESS:
01954 if (iosm->postpone) {
01955 if (iosm->goal == IOSM_PKGINSTALL) {
01956
01957 if (S_ISREG(st->st_mode))
01958 rc = iosmNext(iosm, IOSM_EAT);
01959 }
01960 break;
01961 }
01962
01963 if (iosm->goal == IOSM_PKGBUILD) {
01964 if (iosm->fflags & RPMFILE_GHOST)
01965 break;
01966 if (S_ISREG(st->st_mode) && st->st_nlink > 1) {
01967 struct hardLink_s * li, * prev;
01968
01969 if (!(iosm->mapFlags & IOSM_ALL_HARDLINKS)) break;
01970 rc = writeLinkedFile(iosm);
01971 if (rc) break;
01972
01973 for (li = iosm->links, prev = NULL; li; prev = li, li = li->next)
01974 if (li == iosm->li)
01975 break;
01976
01977 if (prev == NULL)
01978 iosm->links = iosm->li->next;
01979 else
01980 prev->next = iosm->li->next;
01981 iosm->li->next = NULL;
01982 iosm->li = freeHardLink(iosm->li);
01983 } else {
01984 rc = writeFile(iosm, 1);
01985 }
01986 break;
01987 }
01988
01989 if (iosm->goal != IOSM_PKGINSTALL)
01990 break;
01991
01992 if (S_ISREG(st->st_mode) && iosm->lpath != NULL) {
01993 const char * opath = iosm->opath;
01994 char * t = xmalloc(strlen(iosm->lpath+1) + strlen(iosm->suffix) + 1);
01995 (void) stpcpy(t, iosm->lpath+1);
01996 iosm->opath = t;
01997
01998 rc = iosmNext(iosm, IOSM_LINK);
01999 if (iosm->failedFile && rc != 0 && *iosm->failedFile == NULL) {
02000 *iosm->failedFile = xstrdup(iosm->path);
02001 }
02002 iosm->opath = _free(iosm->opath);
02003 iosm->opath = opath;
02004 break;
02005 }
02006 if (S_ISREG(st->st_mode)) {
02007 const char * path = iosm->path;
02008 if (iosm->osuffix)
02009 iosm->path = iosmFsPath(iosm, st, NULL, NULL);
02010 rc = iosmUNSAFE(iosm, IOSM_VERIFY);
02011
02012 if (rc == 0 && iosm->osuffix) {
02013 const char * opath = iosm->opath;
02014 iosm->opath = iosm->path;
02015 iosm->path = iosmFsPath(iosm, st, NULL, iosm->osuffix);
02016 rc = iosmNext(iosm, IOSM_RENAME);
02017 if (!rc)
02018 rpmlog(RPMLOG_WARNING,
02019 _("%s saved as %s\n"),
02020 (iosm->opath ? iosm->opath : ""),
02021 (iosm->path ? iosm->path : ""));
02022 iosm->path = _free(iosm->path);
02023 iosm->opath = opath;
02024 }
02025
02026
02027 iosm->path = path;
02028
02029 if (!(rc == IOSMERR_ENOENT)) return rc;
02030 rc = extractRegular(iosm);
02031 } else if (S_ISDIR(st->st_mode)) {
02032 mode_t st_mode = st->st_mode;
02033 rc = iosmUNSAFE(iosm, IOSM_VERIFY);
02034 if (rc == IOSMERR_ENOENT) {
02035 st->st_mode &= ~07777;
02036 st->st_mode |= 00700;
02037 rc = iosmNext(iosm, IOSM_MKDIR);
02038 st->st_mode = st_mode;
02039 }
02040 } else if (S_ISLNK(st->st_mode)) {
02041 assert(iosm->lpath != NULL);
02042 rc = iosmUNSAFE(iosm, IOSM_VERIFY);
02043 if (rc == IOSMERR_ENOENT)
02044 rc = iosmNext(iosm, IOSM_SYMLINK);
02045 } else if (S_ISFIFO(st->st_mode)) {
02046 mode_t st_mode = st->st_mode;
02047
02048 rc = iosmUNSAFE(iosm, IOSM_VERIFY);
02049 if (rc == IOSMERR_ENOENT) {
02050 st->st_mode = 0000;
02051 rc = iosmNext(iosm, IOSM_MKFIFO);
02052 st->st_mode = st_mode;
02053 }
02054 } else if (S_ISCHR(st->st_mode) ||
02055 S_ISBLK(st->st_mode) ||
02056 S_ISSOCK(st->st_mode) )
02057 {
02058 rc = iosmUNSAFE(iosm, IOSM_VERIFY);
02059 if (rc == IOSMERR_ENOENT)
02060 rc = iosmNext(iosm, IOSM_MKNOD);
02061 } else {
02062
02063 if (iosm->repackaged)
02064 break;
02065
02066
02067 if (!IS_DEV_LOG(iosm->path))
02068 rc = IOSMERR_UNKNOWN_FILETYPE;
02069 }
02070 if (S_ISREG(st->st_mode) && st->st_nlink > 1) {
02071 iosm->li->createdPath = iosm->li->linkIndex;
02072 rc = iosmMakeLinks(iosm);
02073 }
02074 break;
02075 case IOSM_POST:
02076 break;
02077 case IOSM_MKLINKS:
02078 rc = iosmMakeLinks(iosm);
02079 break;
02080 case IOSM_NOTIFY:
02081 if (iosm->goal == IOSM_PKGINSTALL || iosm->goal == IOSM_PKGBUILD) {
02082 rpmfi fi = iosmGetFi(iosm);
02083 rpmuint64_t archivePos = fdGetCpioPos(iosm->cfd);
02084 if (archivePos > fi->archivePos) {
02085 fi->archivePos = (unsigned long long) archivePos;
02086 #if defined(_USE_RPMTS)
02087 (void) rpmtsNotify(iosmGetTs(iosm), fi->te,RPMCALLBACK_INST_PROGRESS,
02088 fi->archivePos, fi->archiveSize);
02089 #endif
02090 }
02091 }
02092 break;
02093 case IOSM_UNDO:
02094 if (iosm->postpone)
02095 break;
02096 if (iosm->goal == IOSM_PKGINSTALL) {
02097
02098 if (iosm->sufbuf[0] != '\0')
02099 (void) iosmNext(iosm,
02100 (S_ISDIR(st->st_mode) ? IOSM_RMDIR : IOSM_UNLINK));
02101
02102 #ifdef NOTYET
02103 if (iosm->dnlx)
02104 (void) iosmNext(iosm, IOSM_RMDIRS);
02105 #endif
02106 errno = saveerrno;
02107 }
02108 if (iosm->failedFile && *iosm->failedFile == NULL)
02109 *iosm->failedFile = xstrdup(iosm->path);
02110 break;
02111 case IOSM_FINI:
02112 if (!iosm->postpone && iosm->commit) {
02113 if (iosm->goal == IOSM_PKGINSTALL)
02114 rc = ((S_ISREG(st->st_mode) && st->st_nlink > 1)
02115 ? iosmCommitLinks(iosm) : iosmNext(iosm, IOSM_COMMIT));
02116 if (iosm->goal == IOSM_PKGCOMMIT)
02117 rc = iosmNext(iosm, IOSM_COMMIT);
02118 if (iosm->goal == IOSM_PKGERASE)
02119 rc = iosmNext(iosm, IOSM_COMMIT);
02120 }
02121 iosm->path = _free(iosm->path);
02122 iosm->lpath = _free(iosm->lpath);
02123 iosm->opath = _free(iosm->opath);
02124 memset(st, 0, sizeof(*st));
02125 memset(ost, 0, sizeof(*ost));
02126 break;
02127 case IOSM_COMMIT:
02128
02129 if (iosm->osuffix && iosm->diskchecked &&
02130 (iosm->exists || (iosm->goal == IOSM_PKGINSTALL && S_ISREG(st->st_mode))))
02131 {
02132 const char * opath = iosm->opath;
02133 const char * path = iosm->path;
02134 iosm->opath = iosmFsPath(iosm, st, NULL, NULL);
02135 iosm->path = iosmFsPath(iosm, st, NULL, iosm->osuffix);
02136 rc = iosmNext(iosm, IOSM_RENAME);
02137 if (!rc) {
02138 rpmlog(RPMLOG_WARNING, _("%s saved as %s\n"),
02139 (iosm->opath ? iosm->opath : ""),
02140 (iosm->path ? iosm->path : ""));
02141 }
02142 iosm->path = _free(iosm->path);
02143 iosm->path = path;
02144 iosm->opath = _free(iosm->opath);
02145 iosm->opath = opath;
02146 }
02147
02148
02149 if (iosm->goal == IOSM_PKGERASE) {
02150 if (iosm->action == FA_ERASE) {
02151 if (S_ISDIR(st->st_mode)) {
02152 rc = iosmNext(iosm, IOSM_RMDIR);
02153 if (!rc) break;
02154 switch (rc) {
02155 case IOSMERR_ENOENT:
02156 case IOSMERR_ENOTEMPTY:
02157
02158 if (iosm->fflags & RPMFILE_MISSINGOK)
02159 break;
02160
02161
02162 rpmlog(
02163 (iosm->strict_erasures ? RPMLOG_ERR : RPMLOG_DEBUG),
02164 _("rmdir of %s failed: Directory not empty\n"),
02165 iosm->path);
02166 break;
02167 default:
02168 rpmlog(
02169 (iosm->strict_erasures ? RPMLOG_ERR : RPMLOG_DEBUG),
02170 _("rmdir of %s failed: %s\n"),
02171 iosm->path, strerror(errno));
02172 break;
02173 }
02174 } else {
02175 rc = iosmNext(iosm, IOSM_UNLINK);
02176 if (!rc) break;
02177 switch (rc) {
02178 case IOSMERR_ENOENT:
02179 if (iosm->fflags & RPMFILE_MISSINGOK)
02180 break;
02181
02182 default:
02183 rpmlog(
02184 (iosm->strict_erasures ? RPMLOG_ERR : RPMLOG_DEBUG),
02185 _("unlink of %s failed: %s\n"),
02186 iosm->path, strerror(errno));
02187 break;
02188 }
02189 }
02190 }
02191
02192 if (!iosm->strict_erasures) rc = 0;
02193 break;
02194 }
02195
02196
02197 { rpmfi fi = iosmGetFi(iosm);
02198 if (!(fi->mapflags & IOSM_PAYLOAD_EXTRACT)) {
02199 if (!S_ISSOCK(st->st_mode) && !IS_DEV_LOG(iosm->path)) {
02200
02201 if (!S_ISDIR(st->st_mode) &&
02202 (iosm->subdir || iosm->suffix || iosm->nsuffix))
02203 {
02204 iosm->opath = iosm->path;
02205 iosm->path = iosmFsPath(iosm, st, NULL, iosm->nsuffix);
02206 rc = iosmNext(iosm, IOSM_RENAME);
02207 if (rc)
02208 (void) Unlink(iosm->opath);
02209 else if (iosm->nsuffix) {
02210 const char * opath = iosmFsPath(iosm, st, NULL, NULL);
02211 rpmlog(RPMLOG_WARNING, _("%s created as %s\n"),
02212 (opath ? opath : ""),
02213 (iosm->path ? iosm->path : ""));
02214 opath = _free(opath);
02215 }
02216 iosm->opath = _free(iosm->opath);
02217 }
02218
02219
02220
02221 if (!rc && !getuid()) {
02222 rc = iosmMapFContext(iosm);
02223 if (!rc)
02224 rc = iosmNext(iosm, IOSM_LSETFCON);
02225 iosm->fcontext = NULL;
02226 }
02227 if (S_ISLNK(st->st_mode)) {
02228 if (!rc && !getuid())
02229 rc = iosmNext(iosm, IOSM_LCHOWN);
02230 } else {
02231 if (!rc && !getuid())
02232 rc = iosmNext(iosm, IOSM_CHOWN);
02233 if (!rc)
02234 rc = iosmNext(iosm, IOSM_CHMOD);
02235 if (!rc) {
02236 time_t mtime = st->st_mtime;
02237 if (fi->fmtimes)
02238 st->st_mtime = fi->fmtimes[iosm->ix];
02239 rc = iosmNext(iosm, IOSM_UTIME);
02240 st->st_mtime = mtime;
02241 }
02242 }
02243 }
02244 }
02245 }
02246
02247
02248 if (!rc) rc = iosmNext(iosm, IOSM_NOTIFY);
02249 else if (iosm->failedFile && *iosm->failedFile == NULL) {
02250 *iosm->failedFile = iosm->path;
02251 iosm->path = NULL;
02252 }
02253 break;
02254 case IOSM_DESTROY:
02255 iosm->path = _free(iosm->path);
02256
02257
02258 while ((iosm->li = iosm->links) != NULL) {
02259 iosm->links = iosm->li->next;
02260 iosm->li->next = NULL;
02261 if (iosm->goal == IOSM_PKGINSTALL &&
02262 iosm->commit && iosm->li->linksLeft)
02263 {
02264 for (i = 0 ; i < iosm->li->linksLeft; i++) {
02265 if (iosm->li->filex[i] < 0)
02266 continue;
02267 rc = IOSMERR_MISSING_HARDLINK;
02268 if (iosm->failedFile && *iosm->failedFile == NULL) {
02269 iosm->ix = iosm->li->filex[i];
02270 if (!iosmNext(iosm, IOSM_MAP)) {
02271 *iosm->failedFile = iosm->path;
02272 iosm->path = NULL;
02273 }
02274 }
02275 break;
02276 }
02277 }
02278 if (iosm->goal == IOSM_PKGBUILD &&
02279 (iosm->mapFlags & IOSM_ALL_HARDLINKS))
02280 {
02281 rc = IOSMERR_MISSING_HARDLINK;
02282 }
02283 iosm->li = freeHardLink(iosm->li);
02284 }
02285 iosm->ldn = _free(iosm->ldn);
02286 iosm->ldnalloc = iosm->ldnlen = 0;
02287 iosm->rdbuf = iosm->rdb = _free(iosm->rdb);
02288 iosm->wrbuf = iosm->wrb = _free(iosm->wrb);
02289 break;
02290 case IOSM_VERIFY:
02291 if (iosm->diskchecked && !iosm->exists) {
02292 rc = IOSMERR_ENOENT;
02293 break;
02294 }
02295 if (S_ISREG(st->st_mode)) {
02296 char * path = alloca(strlen(iosm->path) + sizeof("-RPMDELETE"));
02297 (void) stpcpy( stpcpy(path, iosm->path), "-RPMDELETE");
02298
02299
02300
02301
02302 iosm->opath = iosm->path;
02303 iosm->path = path;
02304 rc = iosmNext(iosm, IOSM_RENAME);
02305 if (!rc)
02306 (void) iosmNext(iosm, IOSM_UNLINK);
02307 else
02308 rc = IOSMERR_UNLINK_FAILED;
02309 iosm->path = iosm->opath;
02310 iosm->opath = NULL;
02311 return (rc ? rc : IOSMERR_ENOENT);
02312 break;
02313 } else if (S_ISDIR(st->st_mode)) {
02314 if (S_ISDIR(ost->st_mode)) return 0;
02315 if (S_ISLNK(ost->st_mode)) {
02316 rc = iosmUNSAFE(iosm, IOSM_STAT);
02317 if (rc == IOSMERR_ENOENT) rc = 0;
02318 if (rc) break;
02319 errno = saveerrno;
02320 if (S_ISDIR(ost->st_mode)) return 0;
02321 }
02322 } else if (S_ISLNK(st->st_mode)) {
02323 if (S_ISLNK(ost->st_mode)) {
02324
02325 rc = iosmUNSAFE(iosm, IOSM_READLINK);
02326 errno = saveerrno;
02327 if (rc) break;
02328 if (!strcmp(iosm->lpath, iosm->rdbuf)) return 0;
02329 }
02330 } else if (S_ISFIFO(st->st_mode)) {
02331 if (S_ISFIFO(ost->st_mode)) return 0;
02332 } else if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) {
02333 if ((S_ISCHR(ost->st_mode) || S_ISBLK(ost->st_mode)) &&
02334 (ost->st_rdev == st->st_rdev)) return 0;
02335 } else if (S_ISSOCK(st->st_mode)) {
02336 if (S_ISSOCK(ost->st_mode)) return 0;
02337 }
02338
02339 rc = 0;
02340 if (iosm->stage == IOSM_PROCESS) rc = iosmNext(iosm, IOSM_UNLINK);
02341 if (rc == 0) rc = IOSMERR_ENOENT;
02342 return (rc ? rc : IOSMERR_ENOENT);
02343 break;
02344
02345 case IOSM_UNLINK:
02346
02347 if (iosm->mapFlags & IOSM_SBIT_CHECK) {
02348 struct stat stb;
02349 if (Lstat(iosm->path, &stb) == 0 && S_ISREG(stb.st_mode) && (stb.st_mode & 06000) != 0) {
02350
02351 (void)Chmod(iosm->path, stb.st_mode & 0777);
02352 }
02353 }
02354 rc = Unlink(iosm->path);
02355 if (iosm->debug && (stage & IOSM_SYSCALL))
02356 rpmlog(RPMLOG_DEBUG, " %8s (%s) %s\n", cur,
02357 iosm->path, (rc < 0 ? strerror(errno) : ""));
02358 if (rc < 0)
02359 rc = (errno == ENOENT ? IOSMERR_ENOENT : IOSMERR_UNLINK_FAILED);
02360 break;
02361 case IOSM_RENAME:
02362
02363 if (iosm->mapFlags & IOSM_SBIT_CHECK) {
02364 struct stat stb;
02365 if (Lstat(iosm->path, &stb) == 0 && S_ISREG(stb.st_mode) && (stb.st_mode & 06000) != 0) {
02366
02367 (void)Chmod(iosm->path, stb.st_mode & 0777);
02368 }
02369 }
02370 rc = Rename(iosm->opath, iosm->path);
02371
02372 if (iosm->repackaged)
02373 rc = 0;
02374 #if defined(ETXTBSY)
02375 if (rc && errno == ETXTBSY) {
02376 char * path = alloca(strlen(iosm->path) + sizeof("-RPMDELETE"));
02377 (void) stpcpy( stpcpy(path, iosm->path), "-RPMDELETE");
02378
02379
02380
02381
02382 rc = Rename(iosm->path, path);
02383 if (!rc) rc = Rename(iosm->opath, iosm->path);
02384 }
02385 #endif
02386 if (iosm->debug && (stage & IOSM_SYSCALL))
02387 rpmlog(RPMLOG_DEBUG, " %8s (%s, %s) %s\n", cur,
02388 iosm->opath, iosm->path, (rc < 0 ? strerror(errno) : ""));
02389 if (rc < 0) rc = IOSMERR_RENAME_FAILED;
02390 break;
02391 case IOSM_MKDIR:
02392 rc = Mkdir(iosm->path, (st->st_mode & 07777));
02393 if (iosm->debug && (stage & IOSM_SYSCALL))
02394 rpmlog(RPMLOG_DEBUG, " %8s (%s, 0%04o) %s\n", cur,
02395 iosm->path, (unsigned)(st->st_mode & 07777),
02396 (rc < 0 ? strerror(errno) : ""));
02397 if (rc < 0) rc = IOSMERR_MKDIR_FAILED;
02398 break;
02399 case IOSM_RMDIR:
02400 rc = Rmdir(iosm->path);
02401 if (iosm->debug && (stage & IOSM_SYSCALL))
02402 rpmlog(RPMLOG_DEBUG, " %8s (%s) %s\n", cur,
02403 iosm->path, (rc < 0 ? strerror(errno) : ""));
02404 if (rc < 0)
02405 switch (errno) {
02406 case ENOENT: rc = IOSMERR_ENOENT; break;
02407 case ENOTEMPTY: rc = IOSMERR_ENOTEMPTY; break;
02408 default: rc = IOSMERR_RMDIR_FAILED; break;
02409 }
02410 break;
02411 case IOSM_LSETFCON:
02412 { const char * iosmpath = NULL;
02413 if (iosm->fcontext == NULL || *iosm->fcontext == '\0'
02414 || !strcmp(iosm->fcontext, "<<none>>"))
02415 break;
02416 (void) urlPath(iosm->path, &iosmpath);
02417 rc = lsetfilecon(iosmpath, (security_context_t)iosm->fcontext);
02418 if (iosm->debug && (stage & IOSM_SYSCALL))
02419 rpmlog(RPMLOG_DEBUG, " %8s (%s, %s) %s\n", cur,
02420 iosm->path, iosm->fcontext,
02421 (rc < 0 ? strerror(errno) : ""));
02422 if (rc < 0) rc = (errno == EOPNOTSUPP ? 0 : IOSMERR_LSETFCON_FAILED);
02423 } break;
02424 case IOSM_CHOWN:
02425 rc = Chown(iosm->path, st->st_uid, st->st_gid);
02426 if (iosm->debug && (stage & IOSM_SYSCALL))
02427 rpmlog(RPMLOG_DEBUG, " %8s (%s, %d, %d) %s\n", cur,
02428 iosm->path, (int)st->st_uid, (int)st->st_gid,
02429 (rc < 0 ? strerror(errno) : ""));
02430 if (rc < 0) rc = IOSMERR_CHOWN_FAILED;
02431 break;
02432 case IOSM_LCHOWN:
02433 #if ! CHOWN_FOLLOWS_SYMLINK
02434 rc = Lchown(iosm->path, st->st_uid, st->st_gid);
02435 if (iosm->debug && (stage & IOSM_SYSCALL))
02436 rpmlog(RPMLOG_DEBUG, " %8s (%s, %d, %d) %s\n", cur,
02437 iosm->path, (int)st->st_uid, (int)st->st_gid,
02438 (rc < 0 ? strerror(errno) : ""));
02439 if (rc < 0) rc = IOSMERR_CHOWN_FAILED;
02440 #endif
02441 break;
02442 case IOSM_CHMOD:
02443 rc = Chmod(iosm->path, (st->st_mode & 07777));
02444 if (iosm->debug && (stage & IOSM_SYSCALL))
02445 rpmlog(RPMLOG_DEBUG, " %8s (%s, 0%04o) %s\n", cur,
02446 iosm->path, (unsigned)(st->st_mode & 07777),
02447 (rc < 0 ? strerror(errno) : ""));
02448 if (rc < 0) rc = IOSMERR_CHMOD_FAILED;
02449 break;
02450 case IOSM_UTIME:
02451 { struct utimbuf stamp;
02452 stamp.actime = st->st_mtime;
02453 stamp.modtime = st->st_mtime;
02454 rc = Utime(iosm->path, &stamp);
02455 if (iosm->debug && (stage & IOSM_SYSCALL))
02456 rpmlog(RPMLOG_DEBUG, " %8s (%s, 0x%x) %s\n", cur,
02457 iosm->path, (unsigned)st->st_mtime,
02458 (rc < 0 ? strerror(errno) : ""));
02459 if (rc < 0) rc = IOSMERR_UTIME_FAILED;
02460 }
02461 break;
02462 case IOSM_SYMLINK:
02463 rc = Symlink(iosm->lpath, iosm->path);
02464 if (iosm->debug && (stage & IOSM_SYSCALL))
02465 rpmlog(RPMLOG_DEBUG, " %8s (%s, %s) %s\n", cur,
02466 iosm->lpath, iosm->path, (rc < 0 ? strerror(errno) : ""));
02467 if (rc < 0) rc = IOSMERR_SYMLINK_FAILED;
02468 break;
02469 case IOSM_LINK:
02470 rc = Link(iosm->opath, iosm->path);
02471 if (iosm->debug && (stage & IOSM_SYSCALL))
02472 rpmlog(RPMLOG_DEBUG, " %8s (%s, %s) %s\n", cur,
02473 iosm->opath, iosm->path, (rc < 0 ? strerror(errno) : ""));
02474 if (rc < 0) rc = IOSMERR_LINK_FAILED;
02475 break;
02476 case IOSM_MKFIFO:
02477 rc = Mkfifo(iosm->path, (st->st_mode & 07777));
02478 if (iosm->debug && (stage & IOSM_SYSCALL))
02479 rpmlog(RPMLOG_DEBUG, " %8s (%s, 0%04o) %s\n", cur,
02480 iosm->path, (unsigned)(st->st_mode & 07777),
02481 (rc < 0 ? strerror(errno) : ""));
02482 if (rc < 0) rc = IOSMERR_MKFIFO_FAILED;
02483 break;
02484 case IOSM_MKNOD:
02485
02486 rc = Mknod(iosm->path, (st->st_mode & ~07777), st->st_rdev);
02487
02488 if (iosm->debug && (stage & IOSM_SYSCALL))
02489 rpmlog(RPMLOG_DEBUG, " %8s (%s, 0%o, 0x%x) %s\n", cur,
02490 iosm->path, (unsigned)(st->st_mode & ~07777),
02491 (unsigned)st->st_rdev,
02492 (rc < 0 ? strerror(errno) : ""));
02493 if (rc < 0) rc = IOSMERR_MKNOD_FAILED;
02494 break;
02495 case IOSM_LSTAT:
02496 rc = Lstat(iosm->path, ost);
02497 if (iosm->debug && (stage & IOSM_SYSCALL) && rc && errno != ENOENT)
02498 rpmlog(RPMLOG_DEBUG, " %8s (%s, ost) %s\n", cur,
02499 iosm->path, (rc < 0 ? strerror(errno) : ""));
02500 if (rc < 0) {
02501 rc = (errno == ENOENT ? IOSMERR_ENOENT : IOSMERR_LSTAT_FAILED);
02502 memset(ost, 0, sizeof(*ost));
02503 }
02504 break;
02505 case IOSM_STAT:
02506 rc = Stat(iosm->path, ost);
02507 if (iosm->debug && (stage & IOSM_SYSCALL) && rc && errno != ENOENT)
02508 rpmlog(RPMLOG_DEBUG, " %8s (%s, ost) %s\n", cur,
02509 iosm->path, (rc < 0 ? strerror(errno) : ""));
02510 if (rc < 0) {
02511 rc = (errno == ENOENT ? IOSMERR_ENOENT : IOSMERR_STAT_FAILED);
02512 memset(ost, 0, sizeof(*ost));
02513 }
02514 break;
02515 case IOSM_READLINK:
02516
02517 rc = Readlink(iosm->path, iosm->rdbuf, iosm->rdsize - 1);
02518 if (iosm->debug && (stage & IOSM_SYSCALL))
02519 rpmlog(RPMLOG_DEBUG, " %8s (%s, rdbuf, %d) %s\n", cur,
02520 iosm->path, (int)(iosm->rdsize -1), (rc < 0 ? strerror(errno) : ""));
02521 if (rc < 0) rc = IOSMERR_READLINK_FAILED;
02522 else {
02523 iosm->rdnb = rc;
02524 iosm->rdbuf[iosm->rdnb] = '\0';
02525 rc = 0;
02526 }
02527 break;
02528 case IOSM_CHROOT:
02529 break;
02530
02531 case IOSM_NEXT:
02532 rc = iosmUNSAFE(iosm, IOSM_HREAD);
02533 if (rc) break;
02534 if (!strcmp(iosm->path, CPIO_TRAILER)) {
02535 iosm->path = _free(iosm->path);
02536 rc = IOSMERR_HDR_TRAILER;
02537 }
02538 if (!rc)
02539 rc = iosmNext(iosm, IOSM_POS);
02540 break;
02541 case IOSM_EAT:
02542 for (left = st->st_size; left > 0; left -= iosm->rdnb) {
02543 iosm->wrlen = (left > iosm->wrsize ? iosm->wrsize : left);
02544 rc = iosmNext(iosm, IOSM_DREAD);
02545 if (rc)
02546 break;
02547 }
02548 break;
02549 case IOSM_POS:
02550 left = (iosm->blksize - (fdGetCpioPos(iosm->cfd) % iosm->blksize)) % iosm->blksize;
02551 if (left) {
02552 iosm->wrlen = left;
02553 (void) iosmNext(iosm, IOSM_DREAD);
02554 }
02555 break;
02556 case IOSM_PAD:
02557 left = (iosm->blksize - (fdGetCpioPos(iosm->cfd) % iosm->blksize)) % iosm->blksize;
02558 if (left) {
02559 if (iosm->blksize == 2)
02560 iosm->rdbuf[0] = '\n';
02561 else
02562 memset(iosm->rdbuf, 0, left);
02563
02564 iosm->rdnb = left;
02565 (void) iosmNext(iosm, IOSM_DWRITE);
02566 }
02567 break;
02568 case IOSM_TRAILER:
02569 rc = (*iosm->trailerWrite) (iosm);
02570 break;
02571 case IOSM_HREAD:
02572 rc = iosmNext(iosm, IOSM_POS);
02573 if (!rc)
02574 rc = (*iosm->headerRead) (iosm, st);
02575 break;
02576 case IOSM_HWRITE:
02577 rc = (*iosm->headerWrite) (iosm, st);
02578 break;
02579 case IOSM_DREAD:
02580 iosm->rdnb = Fread(iosm->wrbuf, sizeof(*iosm->wrbuf), iosm->wrlen, iosm->cfd);
02581 if (iosm->debug && (stage & IOSM_SYSCALL))
02582 rpmlog(RPMLOG_DEBUG, " %8s (%s, %d, cfd)\trdnb %d\n",
02583 cur, (iosm->wrbuf == iosm->wrb ? "wrbuf" : "mmap"),
02584 (int)iosm->wrlen, (int)iosm->rdnb);
02585 if (iosm->rdnb != iosm->wrlen || Ferror(iosm->cfd))
02586 rc = IOSMERR_READ_FAILED;
02587 if (iosm->rdnb > 0)
02588 fdSetCpioPos(iosm->cfd, fdGetCpioPos(iosm->cfd) + iosm->rdnb);
02589 break;
02590 case IOSM_DWRITE:
02591 iosm->wrnb = Fwrite(iosm->rdbuf, sizeof(*iosm->rdbuf), iosm->rdnb, iosm->cfd);
02592 if (iosm->debug && (stage & IOSM_SYSCALL))
02593 rpmlog(RPMLOG_DEBUG, " %8s (%s, %d, cfd)\twrnb %d\n",
02594 cur, (iosm->rdbuf == iosm->rdb ? "rdbuf" : "mmap"),
02595 (int)iosm->rdnb, (int)iosm->wrnb);
02596 if (iosm->rdnb != iosm->wrnb || Ferror(iosm->cfd))
02597 rc = IOSMERR_WRITE_FAILED;
02598 if (iosm->wrnb > 0)
02599 fdSetCpioPos(iosm->cfd, fdGetCpioPos(iosm->cfd) + iosm->wrnb);
02600 break;
02601
02602 case IOSM_ROPEN:
02603 iosm->rfd = Fopen(iosm->path, "r.fdio");
02604 if (iosm->rfd == NULL || Ferror(iosm->rfd)) {
02605 if (iosm->rfd != NULL) (void) iosmNext(iosm, IOSM_RCLOSE);
02606 iosm->rfd = NULL;
02607 rc = IOSMERR_OPEN_FAILED;
02608 break;
02609 }
02610 if (iosm->debug && (stage & IOSM_SYSCALL))
02611 rpmlog(RPMLOG_DEBUG, " %8s (%s, \"r\") rfd %p rdbuf %p\n", cur,
02612 iosm->path, iosm->rfd, iosm->rdbuf);
02613 break;
02614 case IOSM_READ:
02615 iosm->rdnb = Fread(iosm->rdbuf, sizeof(*iosm->rdbuf), iosm->rdlen, iosm->rfd);
02616 if (iosm->debug && (stage & IOSM_SYSCALL))
02617 rpmlog(RPMLOG_DEBUG, " %8s (rdbuf, %d, rfd)\trdnb %d\n",
02618 cur, (int)iosm->rdlen, (int)iosm->rdnb);
02619 if (iosm->rdnb != iosm->rdlen || Ferror(iosm->rfd))
02620 rc = IOSMERR_READ_FAILED;
02621 break;
02622 case IOSM_RCLOSE:
02623 if (iosm->rfd != NULL) {
02624 if (iosm->debug && (stage & IOSM_SYSCALL))
02625 rpmlog(RPMLOG_DEBUG, " %8s (%p)\n", cur, iosm->rfd);
02626 (void) rpmswAdd(&iosm->op_digest,
02627 fdstat_op(iosm->rfd, FDSTAT_DIGEST));
02628 (void) Fclose(iosm->rfd);
02629 errno = saveerrno;
02630 }
02631 iosm->rfd = NULL;
02632 break;
02633 case IOSM_WOPEN:
02634 iosm->wfd = Fopen(iosm->path, "w.fdio");
02635 if (iosm->wfd == NULL || Ferror(iosm->wfd)) {
02636 if (iosm->wfd != NULL) (void) iosmNext(iosm, IOSM_WCLOSE);
02637 iosm->wfd = NULL;
02638 rc = IOSMERR_OPEN_FAILED;
02639 }
02640 if (iosm->debug && (stage & IOSM_SYSCALL))
02641 rpmlog(RPMLOG_DEBUG, " %8s (%s, \"w\") wfd %p wrbuf %p\n", cur,
02642 iosm->path, iosm->wfd, iosm->wrbuf);
02643 break;
02644 case IOSM_WRITE:
02645 iosm->wrnb = Fwrite(iosm->wrbuf, sizeof(*iosm->wrbuf), iosm->rdnb, iosm->wfd);
02646 if (iosm->debug && (stage & IOSM_SYSCALL))
02647 rpmlog(RPMLOG_DEBUG, " %8s (wrbuf, %d, wfd)\twrnb %d\n",
02648 cur, (int)iosm->rdnb, (int)iosm->wrnb);
02649 if (iosm->rdnb != iosm->wrnb || Ferror(iosm->wfd))
02650 rc = IOSMERR_WRITE_FAILED;
02651 break;
02652 case IOSM_WCLOSE:
02653 if (iosm->wfd != NULL) {
02654 if (iosm->debug && (stage & IOSM_SYSCALL))
02655 rpmlog(RPMLOG_DEBUG, " %8s (%p)\n", cur, iosm->wfd);
02656 (void) rpmswAdd(&iosm->op_digest,
02657 fdstat_op(iosm->wfd, FDSTAT_DIGEST));
02658 (void) Fclose(iosm->wfd);
02659 errno = saveerrno;
02660 }
02661 iosm->wfd = NULL;
02662 break;
02663
02664 default:
02665 break;
02666 }
02667
02668 if (!(stage & IOSM_INTERNAL)) {
02669 iosm->rc = (rc == IOSMERR_HDR_TRAILER ? 0 : rc);
02670 }
02671 return rc;
02672 }
02673
02674
02675 #define IOSM_SKIPPING(_a) \
02676 ((_a) == FA_SKIP || (_a) == FA_SKIPNSTATE || (_a) == FA_SKIPNETSHARED || (_a) == FA_SKIPCOLOR)
02677
02678 int iosmFileActionSkipped(iosmFileAction action)
02679 {
02680 return IOSM_SKIPPING(action);
02681 }
02682
02683 const char * iosmFileActionString(iosmFileAction a)
02684 {
02685 switch (a) {
02686 case FA_UNKNOWN: return "unknown";
02687 case FA_CREATE: return "create";
02688 case FA_COPYOUT: return "copyout";
02689 case FA_COPYIN: return "copyin";
02690 case FA_BACKUP: return "backup";
02691 case FA_SAVE: return "save";
02692 case FA_SKIP: return "skip";
02693 case FA_ALTNAME: return "altname";
02694 case FA_ERASE: return "erase";
02695 case FA_SKIPNSTATE: return "skipnstate";
02696 case FA_SKIPNETSHARED: return "skipnetshared";
02697 case FA_SKIPCOLOR: return "skipcolor";
02698 default: return "???";
02699 }
02700
02701 }
02702
02703 const char * iosmFileStageString(iosmFileStage a) {
02704 switch(a) {
02705 case IOSM_UNKNOWN: return "unknown";
02706
02707 case IOSM_PKGINSTALL:return "INSTALL";
02708 case IOSM_PKGERASE: return "ERASE";
02709 case IOSM_PKGBUILD: return "BUILD";
02710 case IOSM_PKGCOMMIT: return "COMMIT";
02711 case IOSM_PKGUNDO: return "UNDO";
02712
02713 case IOSM_CREATE: return "create";
02714 case IOSM_INIT: return "init";
02715 case IOSM_MAP: return "map";
02716 case IOSM_MKDIRS: return "mkdirs";
02717 case IOSM_RMDIRS: return "rmdirs";
02718 case IOSM_PRE: return "pre";
02719 case IOSM_PROCESS: return "process";
02720 case IOSM_POST: return "post";
02721 case IOSM_MKLINKS: return "mklinks";
02722 case IOSM_NOTIFY: return "notify";
02723 case IOSM_UNDO: return "undo";
02724 case IOSM_FINI: return "fini";
02725 case IOSM_COMMIT: return "commit";
02726 case IOSM_DESTROY: return "destroy";
02727 case IOSM_VERIFY: return "verify";
02728
02729 case IOSM_UNLINK: return "Unlink";
02730 case IOSM_RENAME: return "Rename";
02731 case IOSM_MKDIR: return "Mkdir";
02732 case IOSM_RMDIR: return "Rmdir";
02733 case IOSM_LSETFCON: return "lsetfcon";
02734 case IOSM_CHOWN: return "Chown";
02735 case IOSM_LCHOWN: return "Lchown";
02736 case IOSM_CHMOD: return "Chmod";
02737 case IOSM_UTIME: return "Utime";
02738 case IOSM_SYMLINK: return "Symlink";
02739 case IOSM_LINK: return "Link";
02740 case IOSM_MKFIFO: return "Mkfifo";
02741 case IOSM_MKNOD: return "Mknod";
02742 case IOSM_LSTAT: return "Lstat";
02743 case IOSM_STAT: return "Stat";
02744 case IOSM_READLINK: return "Readlink";
02745 case IOSM_CHROOT: return "Chroot";
02746
02747 case IOSM_NEXT: return "next";
02748 case IOSM_EAT: return "eat";
02749 case IOSM_POS: return "pos";
02750 case IOSM_PAD: return "pad";
02751 case IOSM_TRAILER: return "trailer";
02752 case IOSM_HREAD: return "hread";
02753 case IOSM_HWRITE: return "hwrite";
02754 case IOSM_DREAD: return "Fread";
02755 case IOSM_DWRITE: return "Fwrite";
02756
02757 case IOSM_ROPEN: return "Fopen";
02758 case IOSM_READ: return "Fread";
02759 case IOSM_RCLOSE: return "Fclose";
02760 case IOSM_WOPEN: return "Fopen";
02761 case IOSM_WRITE: return "Fwrite";
02762 case IOSM_WCLOSE: return "Fclose";
02763
02764 default: return "???";
02765 }
02766
02767 }
02768
02769 char * iosmStrerror(int rc)
02770 {
02771 char msg[256];
02772 char *s;
02773 int l, myerrno = errno;
02774
02775 strcpy(msg, "cpio: ");
02776 switch (rc) {
02777 default:
02778 s = msg + strlen(msg);
02779 sprintf(s, _("(error 0x%x)"), (unsigned)rc);
02780 s = NULL;
02781 break;
02782 case IOSMERR_BAD_MAGIC: s = _("Bad magic"); break;
02783 case IOSMERR_BAD_HEADER: s = _("Bad/unreadable header"); break;
02784
02785 case IOSMERR_OPEN_FAILED: s = "open"; break;
02786 case IOSMERR_CHMOD_FAILED: s = "chmod"; break;
02787 case IOSMERR_CHOWN_FAILED: s = "chown"; break;
02788 case IOSMERR_WRITE_FAILED: s = "write"; break;
02789 case IOSMERR_UTIME_FAILED: s = "utime"; break;
02790 case IOSMERR_UNLINK_FAILED: s = "unlink"; break;
02791 case IOSMERR_RENAME_FAILED: s = "rename"; break;
02792 case IOSMERR_SYMLINK_FAILED: s = "symlink"; break;
02793 case IOSMERR_STAT_FAILED: s = "stat"; break;
02794 case IOSMERR_LSTAT_FAILED: s = "lstat"; break;
02795 case IOSMERR_MKDIR_FAILED: s = "mkdir"; break;
02796 case IOSMERR_RMDIR_FAILED: s = "rmdir"; break;
02797 case IOSMERR_MKNOD_FAILED: s = "mknod"; break;
02798 case IOSMERR_MKFIFO_FAILED: s = "mkfifo"; break;
02799 case IOSMERR_LINK_FAILED: s = "link"; break;
02800 case IOSMERR_READLINK_FAILED: s = "readlink"; break;
02801 case IOSMERR_READ_FAILED: s = "read"; break;
02802 case IOSMERR_COPY_FAILED: s = "copy"; break;
02803 case IOSMERR_LSETFCON_FAILED: s = "lsetfilecon"; break;
02804
02805 case IOSMERR_HDR_SIZE: s = _("Header size too big"); break;
02806 case IOSMERR_UNKNOWN_FILETYPE: s = _("Unknown file type"); break;
02807 case IOSMERR_MISSING_HARDLINK: s = _("Missing hard link(s)"); break;
02808 case IOSMERR_DIGEST_MISMATCH: s = _("File digest mismatch"); break;
02809 case IOSMERR_INTERNAL: s = _("Internal error"); break;
02810 case IOSMERR_UNMAPPED_FILE: s = _("Archive file not in header"); break;
02811 case IOSMERR_ENOENT: s = strerror(ENOENT); break;
02812 case IOSMERR_ENOTEMPTY: s = strerror(ENOTEMPTY); break;
02813 }
02814
02815 l = sizeof(msg) - strlen(msg) - 1;
02816 if (s != NULL) {
02817 if (l > 0) strncat(msg, s, l);
02818 l -= strlen(s);
02819 }
02820 if ((rc & IOSMERR_CHECK_ERRNO) && myerrno) {
02821 s = _(" failed - ");
02822 if (l > 0) strncat(msg, s, l);
02823 l -= strlen(s);
02824 if (l > 0) strncat(msg, strerror(myerrno), l);
02825 }
02826 return xstrdup(msg);
02827 }