16 #include "../rpmdb/rpmtag.h"
21 #define _IOSM_INTERNAL
23 #define iosmUNSAFE iosmStage
30 #define _RPMFI_INTERNAL
31 #define _RPMFI_NOMETHODS
32 #include "../lib/rpmfi.h"
37 #if defined(_USE_RPMTE)
43 #if defined(_USE_RPMSX)
44 #include "../lib/rpmsx.h"
52 #if defined(_USE_RPMTS)
65 GENfree(
unsigned short *)
71 #define alloca_strdup(_s) strcpy((char *)alloca(strlen(_s)+1), (_s))
87 #if defined(_USE_RPMTS)
92 return (iter ? iter->
ts : NULL);
101 return (iter ? iter->
fi : NULL);
105 #define SUFFIX_RPMORIG ".rpmorig"
106 #define SUFFIX_RPMSAVE ".rpmsave"
107 #define SUFFIX_RPMNEW ".rpmnew"
119 const struct stat *
st,
125 const char * s = NULL;
131 (st && !S_ISDIR(st->st_mode) ? (subdir ? strlen(subdir) : 0) : 0) +
132 (st && !S_ISDIR(st->st_mode) ? (suffix ? strlen(suffix) : 0) : 0) +
136 if (st && !S_ISDIR(st->st_mode))
137 if (subdir) t =
stpcpy(t, subdir);
139 if (st && !S_ISDIR(st->st_mode))
140 if (suffix) t =
stpcpy(t, suffix);
155 #if !defined(_RPMFI_NOMETHODS)
177 #if !defined(_RPMFI_NOMETHODS)
183 iter->
i = (iter->
reverse ? (fi->fc - 1) : 0);
202 if (iter->
i >= 0) i = iter->
i--;
204 if (iter->
i < (
int) ((
rpmfi)iter->
fi)->fc) i = iter->
i++;
216 const char * aurl = *(
const char **)a;
217 const char * burl = *(
const char **)b;
218 const char * afn = NULL;
219 const char * bfn = NULL;
224 #ifdef VERY_OLD_BUGGY_RPM_PACKAGES
226 if (strchr(afn,
'/') == NULL)
227 bfn = strrchr(bfn,
'/') + 1;
231 if (afn[0] ==
'.' && afn[1] ==
'/') afn += 2;
232 if (bfn[0] ==
'.' && bfn[1] ==
'/') bfn += 2;
235 if (afn[0] ==
'/') afn += 1;
236 if (bfn[0] ==
'/') bfn += 1;
238 return strcmp(afn, bfn);
259 size_t fc = (fi ? fi->fc : 0);
261 if (fi && fc > 0 && fi->apath && iosmPath && *iosmPath) {
262 const char ** p = NULL;
264 if (fi->apath != NULL)
266 bsearch(&iosmPath, fi->apath, fc,
sizeof(iosmPath),
269 iter->
i = p - fi->apath;
301 return _free((
void *)_dnli);
309 return (
int) (dnli ? dnli->
fi->dc : 0);
317 return (dnli ? dnli->
isave : -1);
343 dnli->
i = (int) (reverse ? fi->dc : 0);
349 #if !defined(_RPMFI_NOMETHODS)
353 for (i = 0; i < (int)fi->fc; i++)
357 dnli->
active[fi->dil[
i]] = (char)1;
361 #if !defined(_RPMFI_NOMETHODS)
365 for (i = 0; i < (int)fi->fc; i++)
371 if (!S_ISDIR(fi->fmodes[i]))
375 dnlen = strlen(fi->dnl[dil]);
376 bnlen = strlen(fi->bnl[i]);
378 for (j = 0; j < (int)fi->dc; j++) {
381 if (!dnli->
active[j] || j == (
int)dil)
383 (void)
urlPath(fi->dnl[j], &dnl);
385 if (jlen != (dnlen+bnlen+1))
387 if (strncmp(dnl, fi->dnl[dil], dnlen))
389 if (strncmp(dnl+dnlen, fi->bnl[i], bnlen))
391 if (dnl[dnlen+bnlen] !=
'/' || dnl[dnlen+bnlen+1] !=
'\0')
402 for (i = 0; i < (int)fi->dc; i++) {
403 if (!dnli->
active[i])
continue;
407 D_(
"========== Directories not explicitly included in package:\n"));
409 (void)
urlPath(fi->dnl[i], &dnl);
429 const char * dn = NULL;
437 i = (!dnli->
reverse ? dnli->
i++ : --dnli->
i);
438 }
while (i >= 0 && i < (
int)fi->dc && !dnli->
active[
i]);
440 if (i >= 0 && i < (
int)fi->dc)
449 #if defined(WITH_PTHREADS)
450 static void * iosmThread(
void * _iosm)
466 #if defined(WITH_PTHREADS)
485 struct stat * st = &iosm->
sb;
492 if (iosm->
li->
sb.st_ino == st->st_ino && iosm->
li->
sb.st_dev == st->st_dev)
497 if (iosm->
li == NULL) {
501 iosm->
li->
nlink = (int) st->st_nlink;
506 memset(iosm->
li->
filex, -1, (st->st_nlink *
sizeof(iosm->
li->
filex[0])));
533 if (!(st->st_size || iosm->
li->
linksLeft == (
int) st->st_nlink))
584 while ((iosm->
li = iosm->
links) != NULL) {
605 #if !defined(_RPMFI_NOMETHODS)
611 for (i = 0; i < (int)fi->fc; i++)
616 const char * apath = NULL;
617 (void)
urlPath(fi->apath[ix], &apath);
618 path = apath + fi->striplen;
621 #if !defined(_RPMFI_NOMETHODS)
626 if ((nb = strlen(path)) < 15)
639 #if !defined(_RPMFI_NOMETHODS)
644 for (i = 0; i < (int)fi->fc; i++)
649 const char * apath = NULL;
650 (void)
urlPath(fi->apath[ix], &apath);
651 path = apath + fi->striplen;
654 #if !defined(_RPMFI_NOMETHODS)
659 if ((nb = strlen(path)) < 15)
670 const void * _ts,
const void *
_fi,
FD_t cfd,
671 unsigned int * archiveSize,
const char ** failedFile)
673 #if defined(_USE_RPMTS)
677 #if defined(_USE_RPMTE)
693 fprintf(stderr,
"--> iosmSetup(%p, 0x%x, \"%s\", %p, %p, %p, %p, %p)\n", iosm, goal, afmt, (
void *)_ts, _fi, cfd, archiveSize, failedFile);
698 if (afmt != NULL && (!strcmp(afmt,
"tar") || !strcmp(afmt,
"ustar"))) {
700 fprintf(stderr,
"\ttar vectors set\n");
706 if (afmt != NULL && !strcmp(afmt,
"ar")) {
708 fprintf(stderr,
"\tar vectors set\n");
718 fprintf(stderr,
"\tcpio vectors set\n");
729 iosm->
cfd =
fdLink(cfd,
"persist (iosm)");
737 #if defined(_USE_RPMTS)
743 #define _tsmask (RPMTRANS_FLAG_PKGCOMMIT | RPMTRANS_FLAG_COMMIT)
749 iosm->
iter->
ts = (
void *)_ts;
756 #if defined(_USE_RPMTS)
776 #if defined(_USE_RPMTS)
779 static time_t now = 0;
780 if (now == 0) now =
time(NULL);
783 if (tid > 0 && tid < 0xffffffff)
784 sprintf(iosm->
sufbuf,
";%08x", (
unsigned)tid);
789 if (rc && !ec) ec = rc;
792 if (rc && !ec) ec = rc;
807 fprintf(stderr,
"--> iosmTeardown(%p)\n", iosm);
813 if (iosm->
iter != NULL) {
814 #if defined(_USE_RPMTS)
822 if (iosm->
cfd != NULL) {
849 if (fi && i >= 0 && i < (
int)fi->fc)
850 iosm->
fcontext = (fi->fcontexts ? fi->fcontexts[i] : NULL);
861 int teAdding = iosm->
adding;
871 if (fi && i >= 0 && i < (
int)fi->fc) {
875 iosm->
fflags = (fi->fflags ? fi->fflags[
i] : fi->flags);
879 iosm->
dirName = fi->dnl[fi->dil[
i]];
896 if (fi->fstates && teAdding)
901 if (fi->fstates && teAdding)
906 if (fi->fstates && teAdding)
940 const struct stat * st = &iosm->
sb;
951 struct stat * st = &iosm->
sb;
955 if (fi && i >= 0 && i < (
int)fi->fc) {
956 mode_t perms = (S_ISDIR(st->st_mode) ? fi->dperms : fi->fperms);
957 mode_t finalMode = (fi->fmodes ? (mode_t)fi->fmodes[i] : perms);
958 ino_t finalInode = (fi->finodes ? (ino_t)fi->finodes[i] : 0);
959 dev_t finalRdev = (fi->frdevs ? fi->frdevs[
i] : 0);
960 rpmuint32_t finalMtime = (fi->fmtimes ? fi->fmtimes[
i] : 0);
970 if (fi->fuser &&
unameToUid(fi->fuser[i], &uid)) {
974 _(
"user %s does not exist - using root\n"), fi->fuser[i]);
976 finalMode &= ~S_ISUID;
980 if (fi->fgroup &&
gnameToGid(fi->fgroup[i], &gid)) {
984 _(
"group %s does not exist - using root\n"), fi->fgroup[i]);
986 finalMode &= ~S_ISGID;
991 st->st_mode = (st->st_mode & S_IFMT) | (finalMode & ~S_IFMT);
993 st->st_mode = (st->st_mode & ~S_IFMT) | (finalMode & S_IFMT);
994 if ((S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
995 && st->st_nlink == 0)
997 st->st_rdev = finalRdev;
998 st->st_ino = finalInode;
999 st->st_mtime = finalMtime;
1011 iosm->
fdigest = (fi->fdigests ? fi->fdigests[
i] : NULL);
1013 iosm->
digest = (fi->digests ? (fi->digests + (iosm->
digestlen *
i)) : NULL);
1035 const struct stat * st = &iosm->
sb;
1036 size_t left = (size_t) st->st_size;
1044 if (st->st_size > 0 && (iosm->
fdigest != NULL || iosm->
digest != NULL))
1068 void * digest = NULL;
1069 int asAscii = (iosm->
digest == NULL ? 1 : 0);
1074 if (digest == NULL) {
1079 if (iosm->
digest != NULL) {
1083 if (strcmp((
char *)digest, iosm->
fdigest))
1086 digest =
_free(digest);
1107 const char * path = iosm->
path;
1108 const char * opath = iosm->
opath;
1109 struct stat * st = &iosm->
sb;
1110 struct stat * ost = &iosm->
osb;
1115 st->st_size = (writeData ? ost->st_size : 0);
1117 if (S_ISDIR(st->st_mode)) {
1119 }
else if (
S_ISLNK(st->st_mode)) {
1127 st->st_size = iosm->
rdnb;
1132 size_t nb=strlen(iosm->
dirName) + strlen(iosm->
baseName) +
sizeof(
".");
1133 char * t = (
char *)
alloca(nb);
1142 const char * apath = NULL;
1143 (void)
urlPath(fi->apath[iosm->
ix], &apath);
1144 iosm->
path = apath + fi->striplen;
1146 iosm->
path = fi->bnl[iosm->
ix];
1153 if (writeData && S_ISREG(st->st_mode)) {
1154 #if defined(HAVE_MMAP)
1155 char * rdbuf = NULL;
1156 void * mapped = (
void *)-1;
1159 int use_mmap = (st->st_size <= 0x07ffffff);
1166 #if defined(HAVE_MMAP)
1168 mapped = mmap(NULL, st->st_size, PROT_READ, MAP_SHARED,
Fileno(iosm->
rfd), 0);
1169 if (mapped != (
void *)-1) {
1170 rdbuf = iosm->
rdbuf;
1171 iosm->
rdbuf = (
char *) mapped;
1172 iosm->
rdlen = nmapped = st->st_size;
1173 #if defined(HAVE_MADVISE) && defined(MADV_DONTNEED)
1174 xx = madvise(mapped, nmapped, MADV_DONTNEED);
1183 #if defined(HAVE_MMAP)
1184 if (mapped != (
void *)-1) {
1185 iosm->
rdnb = nmapped;
1201 #if defined(HAVE_MMAP)
1202 if (mapped != (
void *)-1) {
1204 xx = msync(mapped, nmapped, MS_ASYNC);
1205 #if defined(HAVE_MADVISE) && defined(MADV_DONTNEED)
1206 xx = madvise(mapped, nmapped, MADV_DONTNEED);
1208 xx = munmap(mapped, nmapped);
1209 iosm->
rdbuf = rdbuf;
1225 if (iosm->
rfd != NULL)
1228 iosm->
opath = opath;
1245 const char * path = iosm->
path;
1246 const char * lpath = iosm->
lpath;
1247 const char * nsuffix = iosm->
nsuffix;
1248 int iterIndex = iosm->
ix;
1252 const char * linkpath = NULL;
1260 for (i = iosm->
li->
nlink - 1; i >= 0; i--) {
1262 if (iosm->
li->
filex[i] < 0)
continue;
1272 const char * apath = NULL;
1281 iosm->
lpath = linkpath;
1299 linkpath =
_free(linkpath);
1301 iosm->
ix = iterIndex;
1303 iosm->
lpath = lpath;
1319 const char * path = iosm->
path;
1320 const char * opath = iosm->
opath;
1321 const char * nsuffix = iosm->
nsuffix;
1322 int iterIndex = iosm->
ix;
1336 for (i = 0; i < iosm->
li->
nlink; i++) {
1337 if (iosm->
li->
filex[i] < 0)
continue;
1361 iosm->
ix = iterIndex;
1364 iosm->
opath = opath;
1381 const char * path = iosm->
path;
1382 const char * nsuffix = iosm->
nsuffix;
1383 int iterIndex = iosm->
ix;
1384 struct stat * st = &iosm->
sb;
1393 if (iosm->
li->
sb.st_ino == st->st_ino && iosm->
li->
sb.st_dev == st->st_dev)
1398 for (i = 0; i < iosm->
li->
nlink; i++) {
1399 if (iosm->
li->
filex[i] < 0)
continue;
1408 iosm->
ix = iterIndex;
1425 const char * path = iosm->
path;
1427 char * dn = iosm->
rdbuf;
1434 if (iosm->
ldn != NULL && iosm->
dnlx != NULL)
1436 size_t dnlen = strlen(iosm->
path);
1440 if (iosm->
dnlx[dc] < 1 || (
size_t)iosm->
dnlx[dc] >= dnlen)
1460 }
while ((te - iosm->
path) > iosm->
dnlx[dc]);
1482 struct stat * st = &iosm->
sb;
1483 struct stat * ost = &iosm->
osb;
1484 const char * path = iosm->
path;
1485 mode_t st_mode = st->st_mode;
1487 char * dn = iosm->
rdbuf;
1495 iosm->
dnlx = (
unsigned short *) (dc ?
xcalloc(dc,
sizeof(*iosm->
dnlx)) : NULL);
1497 if (iosm->
dnlx != NULL)
1499 size_t dnlen = strlen(iosm->
path);
1503 if (dc < 0)
continue;
1504 iosm->
dnlx[
dc] = (
unsigned short) dnlen;
1509 if (dnlen <= iosm->ldnlen && !strcmp(iosm->
path, iosm->
ldn))
1518 (void)
urlPath(dn, (
const char **)&te);
1519 for (i = 1, te++; *te !=
'\0'; te++, i++) {
1527 if (i < iosm->ldnlen &&
1528 (iosm->
ldn[i] ==
'/' || iosm->
ldn[i] ==
'\0') &&
1529 !strncmp(iosm->
path, iosm->
ldn, i))
1533 iosm->
dnlx[
dc] = (te - dn);
1543 if (rc == 0 && S_ISDIR(ost->st_mode)) {
1545 iosm->
dnlx[
dc] = (te - dn);
1549 st->st_mode = S_IFDIR | (fi->dperms & 07777);
1552 #if defined(_USE_RPMSX)
1555 if (!fsm->nofcontexts) {
1564 D_(
"%s directory created with perms %04o, context %s.\n"),
1565 iosm->
path, (
unsigned)(st->st_mode & 07777),
1567 #if defined(_USE_RPMSX)
1580 if (iosm->
ldnalloc < (dnlen + 1)) {
1584 if (iosm->
ldn != NULL) {
1585 strcpy(iosm->
ldn, iosm->
path);
1594 st->st_mode = st_mode;
1606 static int iosmStat(
IOSM_t iosm)
1612 if (iosm->
path != NULL) {
1613 int saveernno =
errno;
1620 }
else if (rc == 0) {
1631 #define IS_DEV_LOG(_x) \
1632 ((_x) != NULL && strlen(_x) >= (sizeof("/dev/log")-1) && \
1633 !strncmp((_x), "/dev/log", sizeof("/dev/log")-1) && \
1634 ((_x)[sizeof("/dev/log")-1] == '\0' || \
1635 (_x)[sizeof("/dev/log")-1] == ';'))
1645 struct stat * st = &iosm->
sb;
1646 struct stat * ost = &iosm->
osb;
1647 int saveerrno =
errno;
1652 #define _fafilter(_a) \
1653 (!((_a) == FA_CREATE || (_a) == FA_ERASE || (_a) == FA_COPYIN || (_a) == FA_COPYOUT) \
1654 ? iosmFileActionString(_a) : "")
1662 (
unsigned)st->st_mode, (
int)st->st_nlink,
1663 (
int)st->st_uid, (
int)st->st_gid, (
unsigned long)st->st_size,
1667 const char * apath = NULL;
1670 iosm->
stage = stage;
1674 (
unsigned)st->st_mode, (int)st->st_nlink,
1675 (
int)st->st_uid, (int)st->st_gid, (
unsigned long)st->st_size,
1770 while ((iosm->
li = iosm->
links) != NULL) {
1775 for (j = -1, nlink = 0, i = 0; i < iosm->
li->
nlink; i++) {
1786 iosm->
li->
sb.st_nlink = nlink;
1789 iosm->
osb = iosm->
sb;
1814 iosm->
rdsize = 16 * BUFSIZ;
1816 iosm->
wrsize = 16 * BUFSIZ;
1864 _(
"archive file %s was not found in header\n"),
1878 st->st_mode = fi->fmodes[iosm->
ix];
1888 rc = iosmStat(iosm);
1890 if (iosm->
path != NULL &&
1899 }
else if (rc == 0) {
1921 if (S_ISREG(st->st_mode) && st->st_nlink > 1)
1946 if (S_ISREG(st->st_mode))
1955 if (S_ISREG(st->st_mode) && st->st_nlink > 1) {
1962 for (li = iosm->
links, prev = NULL; li; prev = li, li = li->
next)
1981 if (S_ISREG(st->st_mode) && iosm->
lpath != NULL) {
1982 const char * opath = iosm->
opath;
1992 iosm->
opath = opath;
1995 if (S_ISREG(st->st_mode)) {
1996 const char * path = iosm->
path;
2001 if (rc == 0 && iosm->
osuffix) {
2002 const char * opath = iosm->
opath;
2008 _(
"%s saved as %s\n"),
2012 iosm->
opath = opath;
2020 }
else if (S_ISDIR(st->st_mode)) {
2021 mode_t st_mode = st->st_mode;
2024 st->st_mode &= ~07777;
2025 st->st_mode |= 00700;
2027 st->st_mode = st_mode;
2029 }
else if (
S_ISLNK(st->st_mode)) {
2030 assert(iosm->
lpath != NULL);
2034 }
else if (S_ISFIFO(st->st_mode)) {
2035 mode_t st_mode = st->st_mode;
2041 st->st_mode = st_mode;
2043 }
else if (S_ISCHR(st->st_mode) ||
2044 S_ISBLK(st->st_mode) ||
2059 if (S_ISREG(st->st_mode) && st->st_nlink > 1) {
2070 #if defined(_USE_RPMTS)
2074 if (archivePos > fi->archivePos) {
2075 fi->archivePos = (
unsigned long long) archivePos;
2077 fi->archivePos, fi->archiveSize);
2087 if (iosm->
sufbuf[0] !=
'\0')
2103 rc = ((S_ISREG(st->st_mode) && st->st_nlink > 1)
2113 memset(st, 0,
sizeof(*st));
2114 memset(ost, 0,
sizeof(*ost));
2121 const char * opath = iosm->
opath;
2122 const char * path = iosm->
path;
2134 iosm->
opath = opath;
2140 if (S_ISDIR(st->st_mode)) {
2153 _(
"rmdir of %s failed: Directory not empty\n"),
2159 _(
"rmdir of %s failed: %s\n"),
2174 _(
"unlink of %s failed: %s\n"),
2190 if (!S_ISDIR(st->st_mode) &&
2199 const char * opath =
iosmFsPath(iosm, st, NULL, NULL);
2201 (opath ? opath :
""),
2203 opath =
_free(opath);
2210 if (!rc && !getuid()) {
2217 if (!rc && !getuid())
2220 if (!rc && !getuid())
2225 time_t mtime = st->st_mtime;
2227 st->st_mtime = fi->fmtimes[iosm->
ix];
2229 st->st_mtime = mtime;
2247 while ((iosm->
li = iosm->
links) != NULL) {
2284 if (S_ISREG(st->st_mode)) {
2285 char * path = (
char *)
alloca(strlen(iosm->
path) +
sizeof(
"-RPMDELETE"));
2302 }
else if (S_ISDIR(st->st_mode)) {
2303 if (S_ISDIR(ost->st_mode))
return 0;
2309 if (S_ISDIR(ost->st_mode))
return 0;
2311 }
else if (
S_ISLNK(st->st_mode)) {
2317 if (!strcmp(iosm->
lpath, iosm->
rdbuf))
return 0;
2319 }
else if (S_ISFIFO(st->st_mode)) {
2320 if (S_ISFIFO(ost->st_mode))
return 0;
2321 }
else if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) {
2322 if ((S_ISCHR(ost->st_mode) || S_ISBLK(ost->st_mode)) &&
2323 (ost->st_rdev == st->st_rdev))
return 0;
2324 }
else if (
S_ISSOCK(st->st_mode)) {
2325 if (
S_ISSOCK(ost->st_mode))
return 0;
2339 && S_ISREG(stb.st_mode) && (stb.st_mode & 06000) != 0)
2342 (void)
Chmod(iosm->
path, stb.st_mode & 0777);
2348 iosm->
path, (rc < 0 ? strerror(
errno) :
""));
2357 && S_ISREG(stb.st_mode) && (stb.st_mode & 06000) != 0)
2360 (void)
Chmod(iosm->
path, stb.st_mode & 0777);
2367 #if defined(ETXTBSY)
2368 if (rc &&
errno == ETXTBSY) {
2369 char * path = (
char *)
alloca(strlen(iosm->
path) +
sizeof(
"-RPMDELETE"));
2379 if (iosm->
debug && (stage & IOSM_SYSCALL))
2385 rc =
Mkdir(iosm->
path, (st->st_mode & 07777));
2386 if (iosm->
debug && (stage & IOSM_SYSCALL))
2388 iosm->
path, (
unsigned)(st->st_mode & 07777),
2389 (rc < 0 ? strerror(
errno) :
""));
2394 if (iosm->
debug && (stage & IOSM_SYSCALL))
2396 iosm->
path, (rc < 0 ? strerror(
errno) :
""));
2405 {
const char * iosmpath = NULL;
2407 || !strcmp(iosm->
fcontext,
"<<none>>"))
2411 if (iosm->
debug && (stage & IOSM_SYSCALL))
2414 (rc < 0 ? strerror(
errno) :
""));
2418 rc =
Chown(iosm->
path, st->st_uid, st->st_gid);
2419 if (iosm->
debug && (stage & IOSM_SYSCALL))
2421 iosm->
path, (
int)st->st_uid, (
int)st->st_gid,
2422 (rc < 0 ? strerror(
errno) :
""));
2426 #if ! CHOWN_FOLLOWS_SYMLINK
2427 rc =
Lchown(iosm->
path, st->st_uid, st->st_gid);
2428 if (iosm->
debug && (stage & IOSM_SYSCALL))
2430 iosm->
path, (
int)st->st_uid, (
int)st->st_gid,
2431 (rc < 0 ? strerror(
errno) :
""));
2436 rc =
Chmod(iosm->
path, (st->st_mode & 07777));
2437 if (iosm->
debug && (stage & IOSM_SYSCALL))
2439 iosm->
path, (
unsigned)(st->st_mode & 07777),
2440 (rc < 0 ? strerror(
errno) :
""));
2444 {
struct utimbuf stamp;
2445 stamp.actime = st->st_mtime;
2446 stamp.modtime = st->st_mtime;
2448 if (iosm->
debug && (stage & IOSM_SYSCALL))
2450 iosm->
path, (
unsigned)st->st_mtime,
2451 (rc < 0 ? strerror(
errno) :
""));
2457 if (iosm->
debug && (stage & IOSM_SYSCALL))
2464 if (iosm->
debug && (stage & IOSM_SYSCALL))
2470 rc =
Mkfifo(iosm->
path, (st->st_mode & 07777));
2471 if (iosm->
debug && (stage & IOSM_SYSCALL))
2473 iosm->
path, (
unsigned)(st->st_mode & 07777),
2474 (rc < 0 ? strerror(
errno) :
""));
2479 rc =
Mknod(iosm->
path, (st->st_mode & ~07777), st->st_rdev);
2481 if (iosm->
debug && (stage & IOSM_SYSCALL))
2483 iosm->
path, (
unsigned)(st->st_mode & ~07777),
2484 (
unsigned)st->st_rdev,
2485 (rc < 0 ? strerror(
errno) :
""));
2490 if (iosm->
debug && (stage & IOSM_SYSCALL) && rc &&
errno != ENOENT)
2492 iosm->
path, (rc < 0 ? strerror(
errno) :
""));
2495 memset(ost, 0,
sizeof(*ost));
2500 if (iosm->
debug && (stage & IOSM_SYSCALL) && rc &&
errno != ENOENT)
2502 iosm->
path, (rc < 0 ? strerror(
errno) :
""));
2505 memset(ost, 0,
sizeof(*ost));
2511 if (iosm->
debug && (stage & IOSM_SYSCALL))
2535 for (left = st->st_size; left > 0; left -= iosm->
rdnb) {
2553 iosm->
rdbuf[0] =
'\n';
2555 memset(iosm->
rdbuf, 0, left);
2574 if (iosm->
debug && (stage & IOSM_SYSCALL))
2576 cur, (iosm->
wrbuf == iosm->
wrb ?
"wrbuf" :
"mmap"),
2585 if (iosm->
debug && (stage & IOSM_SYSCALL))
2587 cur, (iosm->
rdbuf == iosm->
rdb ?
"rdbuf" :
"mmap"),
2603 #if defined(POSIX_FADV_WILLNEED)
2604 (void)
Fadvise(iosm->
rfd, 0, 0, POSIX_FADV_WILLNEED);
2606 if (iosm->
debug && (stage & IOSM_SYSCALL))
2612 if (iosm->
debug && (stage & IOSM_SYSCALL))
2614 cur, (
int)iosm->
rdlen, (
int)iosm->
rdnb);
2619 if (iosm->
rfd != NULL) {
2620 if (iosm->
debug && (stage & IOSM_SYSCALL))
2636 #if defined(POSIX_FADV_DONTNEED)
2638 (
void)
Fadvise(iosm->
wfd, 0, 0, POSIX_FADV_DONTNEED);
2640 if (iosm->
debug && (stage & IOSM_SYSCALL))
2646 if (iosm->
debug && (stage & IOSM_SYSCALL))
2648 cur, (
int)iosm->
rdnb, (
int)iosm->
wrnb);
2653 if (iosm->
wfd != NULL) {
2654 if (iosm->
debug && (stage & IOSM_SYSCALL))
2668 if (!(stage & IOSM_INTERNAL)) {
2675 #define IOSM_SKIPPING(_a) \
2676 ((_a) == FA_SKIP || (_a) == FA_SKIPNSTATE || (_a) == FA_SKIPNETSHARED || (_a) == FA_SKIPCOLOR)
2698 default:
return "???";
2764 default:
return "???";
2773 int l, myerrno =
errno;
2775 strcpy(msg,
"cpio: ");
2778 s = msg + strlen(msg);
2779 sprintf((
char *)s,
_(
"(error 0x%x)"), (
unsigned)rc);
2815 l =
sizeof(msg) - strlen(msg) - 1;
2817 if (l > 0) strncat(msg, s, l);
2821 s =
_(
" failed - ");
2822 if (l > 0) strncat(msg, s, l);
2824 if (l > 0) strncat(msg, strerror(myerrno), l);
int arHeaderRead(void *_iosm, struct stat *st)
Read ar(1) header.
static const char * suffix[]
iosmMapFlags cpioMapFlags
static int dnlCount(const DNLI_t dnli)
int tarTrailerWrite(void *_iosm)
Write cpio trailer to payload.
void * rpmtsNotify(rpmts ts, rpmte te, rpmCallbackType what, rpmuint64_t amount, rpmuint64_t total)
Perform transaction progress notify callback.
const char bson_timestamp_t * ts
int rpmsxLsetfilecon(rpmsx sx, const char *fn, mode_t mode, const char *scon)
static const char * dnlNextIterator(DNLI_t dnli)
Return next directory name (from file info).
enum iosmFileAction_e iosmFileAction
File disposition(s) during package install/erase processing.
static int saveHardLink(IOSM_t iosm)
Save hard link in chain.
int Symlink(const char *oldpath, const char *newpath)
symlink(3) clone.
Structures used for an "rpmte" transaction element.
size_t Fwrite(const void *buf, size_t size, size_t nmemb, FD_t fd)
fwrite(3) clone.
char * xstrdup(const char *str)
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
static int iosmMkdirs(IOSM_t iosm)
Create (if necessary) directories not explicitly included in package.
static int iosmMapFContext(IOSM_t iosm)
static void * dnlInitIterator(const IOSM_t iosm, int reverse)
Create directory name iterator.
enum pgpHashAlgo_e pgpHashAlgo
9.4.
rpmfi rpmfiUnlink(rpmfi fi, const char *msg)
Unreference a file info set instance.
rpmtime_t rpmswAdd(rpmop to, rpmop from)
Sum statistic counters.
void * rpmsqThread(void *(*start)(void *arg), void *arg)
Call a function in a thread.
int Stat(const char *path, struct stat *st)
stat(2) clone.
FD_t fdLink(void *cookie, const char *msg)
#define reverse(bot, top)
static int mapFind(IOSMI_t iter, const char *iosmPath)
Locate archive path in file info.
int Fflush(FD_t fd)
fflush(3) clone.
unsigned int * archiveSize
int Link(const char *oldpath, const char *newpath)
link(2) clone.
Structures used for ar(1) archives.
rpmop rpmtsOp(rpmts ts, rpmtsOpX opx)
Retrieve operation timestamp from a transaction set.
int Fadvise(FD_t fd, off_t offset, off_t length, int advice)
posix_fadvise(2) clone.
static void rpmlog(int code, const char *fmt,...)
static int mapNextIterator(void *_iter)
Return next index into file info.
rpmElementType rpmteType(rpmte te)
Retrieve type of transaction element.
int iosmMapPath(IOSM_t iosm)
Map next file path and action.
rpmts rpmtsLink(rpmts ts, const char *msg)
Reference a transaction set instance.
enum iosmFileStage_e iosmFileStage
const char * rpmfiBN(rpmfi fi)
Return current base name from file info set.
const unsigned char * digest
IOSM_t freeIOSM(IOSM_t iosm)
Destroy I/O state machine instance.
static void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int _flags)
Attach digest to fd.
Keeps track of the set of all hard links to a file in an archive.
int Utime(const char *path, const struct utimbuf *buf)
int cpioHeaderWrite(void *_iosm, struct stat *st)
Write cpio header.
static void * freeHardLink(struct hardLink_s *li)
Destroy set of hard links.
Structures used for cpio(1) archives.
int rpmfiFC(rpmfi fi)
Return file count from file info set.
static rpmop fdstat_op(FD_t fd, fdOpX opx)
int(* headerWrite)(void *_iosm, struct stat *st)
int Chown(const char *path, uid_t owner, gid_t group)
chown(2) clone.
void * xcalloc(size_t nmemb, size_t size)
struct dnli_s * DNLI_t
Directory name iterator.
static const char * iosmFsPath(const IOSM_t iosm, const struct stat *st, const char *subdir, const char *suffix)
Build path to file from file info, ornamented with subdir and suffix.
int Rmdir(const char *path)
rmdir(2) clone.
int iosmSetup(IOSM_t iosm, iosmFileStage goal, const char *afmt, const void *_ts, const void *_fi, FD_t cfd, unsigned int *archiveSize, const char **failedFile)
Load external data into I/O state machine.
int gnameToGid(const char *thisGname, gid_t *gid)
FD_t fdFree(FD_t fd, const char *msg)
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
int Rename(const char *oldpath, const char *newpath)
rename(2) clone.
struct rpmfi_s * rpmfi
File info tag sets from a header, so that a header can be discarded early.
int(* _iosmNext)(IOSM_t iosm, iosmFileStage nstage)
Vector to iosmNext.
struct iosm_s * IOSM_t
File state machine data.
int Mkdir(const char *path, mode_t mode)
mkdir(2) clone.
int Lstat(const char *path, struct stat *st)
lstat(2) clone.
int rpmsqJoin(void *thread)
Wait for thread to terminate.
unsigned long long rpmuint64_t
int iosmFileActionSkipped(iosmFileAction action)
Is the file going to be skipped?
Structures used for tar(1) archives.
struct rpmPRCO_s * rpmPRCO
static int writeFile(IOSM_t iosm, int writeData)
Write next item to payload stream.
int(* trailerWrite)(void *_iosm)
static void * dnlFreeIterator(const void *_dnli)
Destroy directory name iterator.
static void * mapFreeIterator(void *_iter)
Destroy file info iterator.
The FD_t File Handle data structure.
static void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo, void *datap, size_t *lenp, int asAscii)
The structure used to store values parsed from a spec file.
static unsigned long long fdGetCpioPos(FD_t fd)
int Mknod(const char *path, mode_t mode, dev_t dev)
mknod(3) clone.
void * alKey
An added/available package retrieval key.
struct rpmRelocation_s * rpmRelocation
static void * mapInitIterator(rpmfi fi, int reverse)
Create file info iterator.
size_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd)
fread(3) clone.
IOSM_t newIOSM(void)
Create I/O state machine instance.
int iosmStage(IOSM_t iosm, iosmFileStage stage)
File state machine driver.
void * iosmGetFi(const IOSM_t iosm)
Retrieve transaction element file info from I/O state machine iterator.
static int iosmStrCmp(const void *a, const void *b)
int iosmTeardown(IOSM_t iosm)
Clean I/O state machine.
Iterator across package file info, forward on install, backward on erase.
int Fclose(FD_t fd)
fclose(3) clone.
char * iosmStrerror(int rc)
Return formatted error message on payload handling failure.
int rpmfiNext(rpmfi fi)
Return next file iterator index.
#define IOSM_SKIPPING(_a)
int Readlink(const char *path, char *buf, size_t bufsiz)
readlink(2) clone.
int cpioHeaderRead(void *_iosm, struct stat *st)
Read cpio header.
static void fdSetCpioPos(FD_t fd, long int cpioPos)
int iosmMapAttrs(IOSM_t iosm)
Map file stat(2) info.
int Ferror(FD_t fd)
ferror(3) clone.
int cpioTrailerWrite(void *_iosm)
Write cpio trailer.
rpmfi rpmfiInit(rpmfi fi, int fx)
Initialize file iterator index.
enum iosmMapFlags_e iosmMapFlags
void * iosmGetTs(const IOSM_t iosm)
Retrieve transaction set from I/O state machine iterator.
urltype urlPath(const char *url, const char **pathp)
Return path component of URL.
static int iosmCommitLinks(IOSM_t iosm)
Commit hard linked file set atomically.
rpmfi rpmfiLink(rpmfi fi, const char *msg)
Reference a file info set instance.
rpmts rpmtsFree(rpmts ts)
Destroy transaction set, closing the database as well.
int arHeaderWrite(void *_iosm, struct stat *st)
Write ar(1) header.
char * stpcpy(char *dest, const char *src)
struct rpmts_s * rpmts
The RPM Transaction Set.
const char * iosmFileStageString(iosmFileStage a)
Return formatted string representation of file stages.
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
struct hardLink_s * links
Structures and prototypes used for an "rpmts" transaction set.
int arTrailerWrite(void *_iosm)
Write ar(1) trailer.
int Lchown(const char *path, uid_t owner, gid_t group)
lchown(2) clone.
static int arSetup(IOSM_t iosm, rpmfi fi)
static int writeLinkedFile(IOSM_t iosm)
Write set of linked files to payload stream.
static int iosmMakeLinks(IOSM_t iosm)
Create pending hard links to existing file.
static int dnlIndex(const DNLI_t dnli)
static int extractRegular(IOSM_t iosm)
Create file from payload stream.
int Fileno(FD_t fd)
fileno(3) clone.
int Chmod(const char *path, mode_t mode)
chmod(2) clone.
File state machine to handle archive I/O and system call's.
const char * iosmFileActionString(iosmFileAction a)
Return formatted string representation of file disposition.
rpmuint32_t rpmtsGetTid(rpmts ts)
Get transaction id, i.e.
static int iosmRmdirs(IOSM_t iosm)
Remove (if created) directories not explicitly included in package.
int unameToUid(const char *thisUname, uid_t *uid)
int(* headerRead)(void *_iosm, struct stat *st)
const char * rpmsxMatch(rpmsx sx, const char *fn, mode_t mode)
Return security context for a file.
rpmtransFlags rpmtsFlags(rpmts ts)
Get transaction flags, i.e.
int tarHeaderRead(void *_iosm, struct stat *st)
Read tar header from payload.
int tarHeaderWrite(void *_iosm, struct stat *st)
Write tar header to payload.
File name and stat information.
int Mkfifo(const char *path, mode_t mode)
mkfifo(3) clone.
int iosmNext(IOSM_t iosm, iosmFileStage nstage)
File state machine driver.
#define IOSMERR_CHECK_ERRNO
struct iosmIterator_s * IOSMI_t
Iterator across package file info, forward on install, backward on erase.
int Unlink(const char *path)
unlink(2) clone.