-#include "system.h"
-
-#include <rpmio.h>
+#include <alloca.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <utime.h>
+
+#include "config.h"
#include "cpio.h"
+#include "miscfn.h"
+
+#if MAJOR_IN_SYSMACROS
+#include <sys/sysmacros.h>
+#elif MAJOR_IN_MKDEV
+#include <sys/mkdev.h>
+#endif
-#define CPIO_NEWC_MAGIC "070701"
#define CPIO_CRC_MAGIC "070702"
#define TRAILER "TRAILER!!!"
should both be the same, but really odd things are going to happen if
that's not true! */
-struct hardLink {
- struct hardLink * next;
- const char ** files; /* nlink of these, used by install */
- int * fileMaps; /* used by build */
- dev_t dev;
- ino_t inode;
- int nlink;
- int linksLeft;
- int createdPath;
- struct stat sb;
+/* We need to maintain our oun file pointer to allow padding */
+struct ourfd {
+ gzFile fd;
+ int pos;
};
struct cpioCrcPhysicalHeader {
char checksum[8]; /* ignored !! */
};
-#define PHYS_HDR_SIZE 110 /* don't depend on sizeof(struct) */
-
struct cpioHeader {
ino_t inode;
mode_t mode;
time_t mtime;
long size;
dev_t dev, rdev;
- /*@owned@*/char * path;
+ char * path;
};
-static inline off_t saferead(FD_t cfd, /*@out@*/void * vbuf, size_t amount)
-{
- off_t rc = 0;
- char * buf = vbuf;
-
- while (amount > 0) {
- size_t nb;
-
- nb = Fread(buf, sizeof(buf[0]), amount, cfd);
- if (nb <= 0)
- return nb;
- rc += nb;
- if (rc >= amount)
- break;
- buf += nb;
- amount -= nb;
- }
- return rc;
-}
+static inline loff_t ourread(struct ourfd * thefd, void * buf, size_t size) {
+ loff_t i;
-static inline off_t ourread(FD_t cfd, /*@out@*/void * buf, size_t size)
-{
- off_t i = saferead(cfd, buf, size);
- if (i > 0)
- fdSetCpioPos(cfd, fdGetCpioPos(cfd) + i);
+ i = gzread(thefd->fd, buf, size);
+ thefd->pos += i;
+
return i;
}
-static inline void padinfd(FD_t cfd, int modulo)
-{
+static inline void padfd(struct ourfd * fd, int modulo) {
int buf[10];
int amount;
- amount = (modulo - fdGetCpioPos(cfd) % modulo) % modulo;
- (void)ourread(cfd, buf, amount);
+ amount = (modulo - fd->pos % modulo) % modulo;
+ ourread(fd, buf, amount);
}
-static inline off_t safewrite(FD_t cfd, const void * vbuf, size_t amount)
-{
- off_t rc = 0;
- const char * buf = vbuf;
-
- while (amount > 0) {
- size_t nb;
-
- nb = Fwrite(buf, sizeof(buf[0]), amount, cfd);
- if (nb <= 0)
- return nb;
- rc += nb;
- if (rc >= amount)
- break;
- buf += nb;
- amount -= nb;
- }
-
- return rc;
-}
-
-static inline int padoutfd(FD_t cfd, size_t * where, int modulo)
-{
- static int buf[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int amount;
-
- amount = (modulo - *where % modulo) % modulo;
- *where += amount;
-
- if (safewrite(cfd, buf, amount) != amount)
- return CPIOERR_WRITE_FAILED;
- return 0;
-}
-
-static int strntoul(const char *str, /*@out@*/char **endptr, int base, int num)
-{
- char * buf, * end;
- unsigned long ret;
+static int strntoul(const char * str, char ** endptr, int base, int num) {
+ char * buf;
buf = alloca(num + 1);
strncpy(buf, str, num);
buf[num] = '\0';
- ret = strtoul(buf, &end, base);
- if (*end)
- *endptr = ((char *)str) + (end - buf); /* XXX discards const */
- else
- *endptr = ((char *)str) + strlen(str);
-
return strtoul(buf, endptr, base);
}
#define GET_NUM_FIELD(phys, log) \
log = strntoul(phys, &end, 16, sizeof(phys)); \
- if (*end) return CPIOERR_BAD_HEADER;
-#define SET_NUM_FIELD(phys, val, space) \
- sprintf(space, "%8.8lx", (unsigned long) (val)); \
- memcpy(phys, space, 8);
+ if (*end) return CPIO_BAD_HEADER;
-static int getNextHeader(FD_t cfd, /*@out@*/ struct cpioHeader * chPtr)
-{
+static int getNextHeader(struct ourfd * fd, struct cpioHeader * chPtr) {
struct cpioCrcPhysicalHeader physHeader;
int nameSize;
char * end;
int major, minor;
- if (ourread(cfd, &physHeader, PHYS_HDR_SIZE) != PHYS_HDR_SIZE)
- return CPIOERR_READ_FAILED;
+ if (ourread(fd, &physHeader, sizeof(physHeader)) != sizeof(physHeader))
+ return CPIO_READ_FAILED;
- if (strncmp(CPIO_CRC_MAGIC, physHeader.magic, sizeof(CPIO_CRC_MAGIC)-1) &&
- strncmp(CPIO_NEWC_MAGIC, physHeader.magic, sizeof(CPIO_NEWC_MAGIC)-1))
- return CPIOERR_BAD_MAGIC;
+ if (strncmp(CPIO_CRC_MAGIC, physHeader.magic, strlen(CPIO_CRC_MAGIC)))
+ return CPIO_BAD_MAGIC;
+
GET_NUM_FIELD(physHeader.inode, chPtr->inode);
GET_NUM_FIELD(physHeader.mode, chPtr->mode);
GET_NUM_FIELD(physHeader.uid, chPtr->uid);
GET_NUM_FIELD(physHeader.devMajor, major);
GET_NUM_FIELD(physHeader.devMinor, minor);
- chPtr->dev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ;
+ chPtr->dev = makedev(major, minor);
GET_NUM_FIELD(physHeader.rdevMajor, major);
GET_NUM_FIELD(physHeader.rdevMinor, minor);
- chPtr->rdev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ;
+ chPtr->rdev = makedev(major, minor);
GET_NUM_FIELD(physHeader.namesize, nameSize);
- chPtr->path = xmalloc(nameSize + 1);
- if (ourread(cfd, chPtr->path, nameSize) != nameSize) {
+ chPtr->path = malloc(nameSize + 1);
+ if (ourread(fd, chPtr->path, nameSize) != nameSize) {
free(chPtr->path);
- chPtr->path = NULL;
- return CPIOERR_BAD_HEADER;
+ return CPIO_BAD_HEADER;
}
- /* this is unecessary chPtr->path[nameSize] = '\0'; */
+ chPtr->path[nameSize] = '\0';
- padinfd(cfd, 4);
+ padfd(fd, 4);
return 0;
}
-int cpioFileMapCmp(const void * a, const void * b)
-{
+int cpioFileMapCmp(const void * a, const void * b) {
const struct cpioFileMapping * first = a;
const struct cpioFileMapping * second = b;
}
/* This could trash files in the path! I'm not sure that's a good thing */
-static int createDirectory(char * path, mode_t perms)
-{
+static int createDirectory(char * path) {
struct stat sb;
+ int dounlink;
+
+ if (!access(path, X_OK)) {
+ if (lstat(path, &sb))
+ return CPIO_STAT_FAILED;
- if (!lstat(path, &sb)) {
- int dounlink = 0; /* XXX eliminate, dounlink==1 on all paths */
if (S_ISDIR(sb.st_mode)) {
return 0;
} else if (S_ISLNK(sb.st_mode)) {
if (stat(path, &sb)) {
if (errno != ENOENT)
- return CPIOERR_STAT_FAILED;
+ return CPIO_STAT_FAILED;
dounlink = 1;
} else {
if (S_ISDIR(sb.st_mode))
}
if (dounlink && unlink(path)) {
- return CPIOERR_UNLINK_FAILED;
+ return CPIO_UNLINK_FAILED;
}
}
if (mkdir(path, 000))
- return CPIOERR_MKDIR_FAILED;
-
- if (chmod(path, perms))
- return CPIOERR_CHMOD_FAILED;
+ return CPIO_MKDIR_FAILED;
return 0;
}
-static int setInfo(struct cpioHeader * hdr)
-{
+static int setInfo(struct cpioHeader * hdr) {
int rc = 0;
- struct utimbuf stamp;
+ struct utimbuf stamp = { hdr->mtime, hdr->mtime };
- stamp.actime = hdr->mtime;
- stamp.modtime = hdr->mtime;
+ if (!getuid() && !rc && chown(hdr->path, hdr->uid, hdr->gid))
+ rc = CPIO_CHOWN_FAILED;
if (!S_ISLNK(hdr->mode)) {
- if (!getuid() && chown(hdr->path, hdr->uid, hdr->gid))
- rc = CPIOERR_CHOWN_FAILED;
if (!rc && chmod(hdr->path, hdr->mode & 07777))
- rc = CPIOERR_CHMOD_FAILED;
+ rc = CPIO_CHMOD_FAILED;
if (!rc && utime(hdr->path, &stamp))
- rc = CPIOERR_UTIME_FAILED;
- } else {
-# if ! CHOWN_FOLLOWS_SYMLINK
- if (!getuid() && !rc && lchown(hdr->path, hdr->uid, hdr->gid))
- rc = CPIOERR_CHOWN_FAILED;
-# endif
+ rc = CPIO_UTIME_FAILED;
}
return rc;
}
-static int checkDirectory(const char * filename)
-{
- /*@only@*/ static char * lastDir = NULL; /* XXX memory leak */
+static int checkDirectory(char * filename) {
+ static char * lastDir = NULL;
static int lastDirLength = 0;
static int lastDirAlloced = 0;
int length = strlen(filename);
if (lastDirAlloced < (length + 1)) {
lastDirAlloced = length + 100;
- lastDir = xrealloc(lastDir, lastDirAlloced); /* XXX memory leak */
+ lastDir = realloc(lastDir, lastDirAlloced);
}
strcpy(lastDir, buf);
for (chptr = buf + 1; *chptr; chptr++) {
if (*chptr == '/') {
*chptr = '\0';
- rc = createDirectory(buf, 0755);
+ rc = createDirectory(buf);
*chptr = '/';
if (rc) return rc;
}
}
- rc = createDirectory(buf, 0755);
+ rc = createDirectory(buf);
return rc;
}
-static int expandRegular(FD_t cfd, struct cpioHeader * hdr,
- cpioCallback cb, void * cbData)
-{
- FD_t ofd;
- char buf[BUFSIZ];
+static int expandRegular(struct ourfd * fd, struct cpioHeader * hdr) {
+ int out;
+ char buf[16384];
int bytesRead;
int left = hdr->size;
int rc = 0;
- struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
- struct stat sb;
-
- /* Rename the old file before attempting unlink to avoid EBUSY errors */
- if (!lstat(hdr->path, &sb)) {
- strcpy(buf, hdr->path);
- strcat(buf, "-RPMDELETE");
- if (rename(hdr->path, buf)) {
- fprintf(stderr, _("can't rename %s to %s: %s\n"),
- hdr->path, buf, strerror(errno));
- return CPIOERR_UNLINK_FAILED;
- }
-
- if (unlink(buf)) {
- fprintf(stderr, _("can't unlink %s: %s\n"),
- buf, strerror(errno));
-#if 0
- return CPIOERR_UNLINK_FAILED;
-#endif
- }
- }
- ofd = Fopen(hdr->path, "w.ufdio");
- if (ofd == NULL || Ferror(ofd))
- return CPIOERR_OPEN_FAILED;
+ if (!access(hdr->path, X_OK))
+ if (unlink(hdr->path))
+ return CPIO_UNLINK_FAILED;
- cbInfo.file = hdr->path;
- cbInfo.fileSize = hdr->size;
+ out = open(hdr->path, O_CREAT | O_WRONLY, 0);
+ if (out < 0)
+ return CPIO_OPEN_FAILED;
while (left) {
- bytesRead = ourread(cfd, buf, left < sizeof(buf) ? left : sizeof(buf));
+ bytesRead = ourread(fd, buf, left < sizeof(buf) ? left : sizeof(buf));
if (bytesRead <= 0) {
- rc = CPIOERR_READ_FAILED;
+ rc = CPIO_READ_FAILED;
break;
}
- if (Fwrite(buf, sizeof(buf[0]), bytesRead, ofd) != bytesRead) {
- rc = CPIOERR_COPY_FAILED;
+ if (write(out, buf, bytesRead) != bytesRead) {
+ rc = CPIO_READ_FAILED;
break;
}
left -= bytesRead;
-
- /* don't call this with fileSize == fileComplete */
- if (!rc && cb && left) {
- cbInfo.fileComplete = hdr->size - left;
- cbInfo.bytesProcessed = fdGetCpioPos(cfd);
- cb(&cbInfo, cbData);
- }
}
- Fclose(ofd);
+ close(out);
return rc;
}
-static int expandSymlink(FD_t cfd, struct cpioHeader * hdr)
-{
- char buf[2048], buf2[2048];
- struct stat sb;
- int len;
+static int expandSymlink(struct ourfd * fd, struct cpioHeader * hdr) {
+ char buf[2048];
+
+ if (!access(hdr->path, X_OK))
+ if (unlink(hdr->path))
+ return CPIO_UNLINK_FAILED;
if ((hdr->size + 1)> sizeof(buf))
- return CPIOERR_HDR_SIZE;
+ return CPIO_INTERNAL;
- if (ourread(cfd, buf, hdr->size) != hdr->size)
- return CPIOERR_READ_FAILED;
+ if (ourread(fd, buf, hdr->size) != hdr->size)
+ return CPIO_READ_FAILED;
buf[hdr->size] = '\0';
- if (!lstat(hdr->path, &sb)) {
- if (S_ISLNK(sb.st_mode)) {
- len = readlink(hdr->path, buf2, sizeof(buf2) - 1);
- if (len > 0) {
- buf2[len] = '\0';
- if (!strcmp(buf, buf2)) return 0;
- }
- }
-
- if (unlink(hdr->path))
- return CPIOERR_UNLINK_FAILED;
- }
-
- if (symlink(buf, hdr->path) < 0)
- return CPIOERR_SYMLINK_FAILED;
+ if (symlink(buf, hdr->path))
+ return CPIO_SYMLINK_FAILED;
return 0;
}
-static int expandFifo( /*@unused@*/ FD_t cfd, struct cpioHeader * hdr)
-{
+static int expandFifo(struct ourfd * fd, struct cpioHeader * hdr) {
struct stat sb;
- if (!lstat(hdr->path, &sb)) {
+ if (!access(hdr->path, X_OK)) {
+ if (lstat(hdr->path, &sb))
+ return CPIO_STAT_FAILED;
+
if (S_ISFIFO(sb.st_mode)) return 0;
if (unlink(hdr->path))
- return CPIOERR_UNLINK_FAILED;
+ return CPIO_UNLINK_FAILED;
}
if (mkfifo(hdr->path, 0))
- return CPIOERR_MKFIFO_FAILED;
+ return CPIO_MKFIFO_FAILED;
return 0;
}
-static int expandDevice( /*@unused@*/ FD_t cfd, struct cpioHeader * hdr)
-{
- struct stat sb;
-
- if (!lstat(hdr->path, &sb)) {
- if ((S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) &&
- (sb.st_rdev == hdr->rdev))
- return 0;
+static int expandDevice(struct ourfd * fd, struct cpioHeader * hdr) {
+ if (!access(hdr->path, X_OK))
if (unlink(hdr->path))
- return CPIOERR_UNLINK_FAILED;
- }
+ return CPIO_UNLINK_FAILED;
- if ( /*@-unrecog@*/ mknod(hdr->path, hdr->mode & (~0777), hdr->rdev) /*@=unrecog@*/ )
- return CPIOERR_MKNOD_FAILED;
+ if (mknod(hdr->path, hdr->mode & (~0777), hdr->rdev))
+ return CPIO_MKNOD_FAILED;
return 0;
}
-static void freeLink( /*@only@*/ struct hardLink * li)
-{
- int i;
-
- for (i = 0; i < li->nlink; i++) {
- if (li->files[i] == NULL) continue;
- /*@-unqualifiedtrans@*/ free((void *)li->files[i]) /*@=unqualifiedtrans@*/ ;
- li->files[i] = NULL;
- }
- free(li->files);
-}
-
-static int createLinks(struct hardLink * li, /*@out@*/const char ** failedFile)
-{
- int i;
- struct stat sb;
-
- for (i = 0; i < li->nlink; i++) {
- if (i == li->createdPath) continue;
- if (!li->files[i]) continue;
-
- if (!lstat(li->files[i], &sb)) {
- if (unlink(li->files[i])) {
- if (failedFile)
- *failedFile = xstrdup(li->files[i]);
- return CPIOERR_UNLINK_FAILED;
- }
- }
-
- if (link(li->files[li->createdPath], li->files[i])) {
- if (failedFile)
- *failedFile = xstrdup(li->files[i]);
- return CPIOERR_LINK_FAILED;
- }
-
- /*@-unqualifiedtrans@*/ free((void *)li->files[i]) /*@=unqualifiedtrans@*/ ;
- li->files[i] = NULL;
- li->linksLeft--;
- }
-
- return 0;
-}
-
-static int eatBytes(FD_t cfd, int amount)
-{
- char buf[4096];
- int bite;
-
- while (amount) {
- bite = (amount > sizeof(buf)) ? sizeof(buf) : amount;
- if (ourread(cfd, buf, bite) != bite)
- return CPIOERR_READ_FAILED;
- amount -= bite;
- }
-
- return 0;
-}
-
-int cpioInstallArchive(FD_t cfd, struct cpioFileMapping * mappings,
- int numMappings, cpioCallback cb, void * cbData,
- const char ** failedFile)
-{
+int cpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings,
+ int numMappings, cpioCallback cb, char ** failedFile) {
struct cpioHeader ch;
+ struct ourfd fd;
int rc = 0;
- int linkNum = 0;
struct cpioFileMapping * map = NULL;
struct cpioFileMapping needle;
mode_t cpioMode;
int olderr;
- struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
- struct hardLink * links = NULL;
- struct hardLink * li = NULL;
- fdSetCpioPos(cfd, 0);
- if (failedFile)
- *failedFile = NULL;
+ fd.fd = stream;
+ fd.pos = 0;
- ch.path = NULL;
do {
- if ((rc = getNextHeader(cfd, &ch))) {
-#if 0 /* XXX this is the failure point for an unreadable rpm */
- fprintf(stderr, _("getNextHeader: %s\n"), cpioStrerror(rc));
-#endif
- return rc;
+ if ((rc = getNextHeader(&fd, &ch))) {
+ printf("error %d reading header: %s\n", rc, strerror(errno));
+ exit(1);
}
if (!strcmp(ch.path, TRAILER)) {
- if (ch.path) free(ch.path);
+ free(ch.path);
break;
}
cpioFileMapCmp);
}
- if (mappings && !map) {
- eatBytes(cfd, ch.size);
- } else {
+ if (!mappings || map) {
cpioMode = ch.mode;
if (map) {
if (map->mapFlags & CPIO_MAP_PATH) {
- if (ch.path) free(ch.path);
- ch.path = xstrdup(map->fsPath);
+ free(ch.path);
+ ch.path = strdup(map->finalPath);
}
if (map->mapFlags & CPIO_MAP_MODE)
ch.gid = map->finalGid;
}
- /* This won't get hard linked symlinks right, but I can't seem
- to create those anyway */
-
- if (S_ISREG(ch.mode) && ch.nlink > 1) {
- for (li = links; li; li = li->next) {
- if (li->inode == ch.inode && li->dev == ch.dev) break;
+ rc = checkDirectory(ch.path);
+
+ if (!rc) {
+ if (S_ISREG(ch.mode))
+ rc = expandRegular(&fd, &ch);
+ else if (S_ISDIR(ch.mode))
+ rc = createDirectory(ch.path);
+ else if (S_ISLNK(ch.mode))
+ rc = expandSymlink(&fd, &ch);
+ else if (S_ISFIFO(ch.mode))
+ rc = expandFifo(&fd, &ch);
+ else if (S_ISCHR(ch.mode) || S_ISBLK(ch.mode))
+ rc = expandDevice(&fd, &ch);
+ else if (S_ISSOCK(ch.mode)) {
+ /* should we do something here??? */
+ rc = 0;
+ } else {
+ rc = CPIO_INTERNAL;
}
-
- if (li == NULL) {
- li = xmalloc(sizeof(*li));
- li->inode = ch.inode;
- li->dev = ch.dev;
- li->nlink = ch.nlink;
- li->linksLeft = ch.nlink;
- li->createdPath = -1;
- li->files = xcalloc(li->nlink,(sizeof(*li->files)));
- li->next = links;
- links = li;
- }
-
- for (linkNum = 0; linkNum < li->nlink; linkNum++)
- if (!li->files[linkNum]) break;
- li->files[linkNum] = xstrdup(ch.path);
}
-
- if ((ch.nlink > 1) && S_ISREG(ch.mode) && !ch.size &&
- li->createdPath == -1) {
- /* defer file creation */
- } else if ((ch.nlink > 1) && S_ISREG(ch.mode) &&
- (li->createdPath != -1)) {
- createLinks(li, failedFile);
-
- /* this only happens for cpio archives which contain
- hardlinks w/ the contents of each hardlink being
- listed (intead of the data being given just once. This
- shouldn't happen, but I've made it happen w/ buggy
- code, so what the heck? GNU cpio handles this well fwiw */
- if (ch.size) eatBytes(cfd, ch.size);
- } else {
- rc = checkDirectory(ch.path);
-
- if (!rc) {
- if (S_ISREG(ch.mode))
- rc = expandRegular(cfd, &ch, cb, cbData);
- else if (S_ISDIR(ch.mode))
- rc = createDirectory(ch.path, 000);
- else if (S_ISLNK(ch.mode))
- rc = expandSymlink(cfd, &ch);
- else if (S_ISFIFO(ch.mode))
- rc = expandFifo(cfd, &ch);
- else if (S_ISCHR(ch.mode) || S_ISBLK(ch.mode))
- rc = expandDevice(cfd, &ch);
- else if (S_ISSOCK(ch.mode)) {
- /* this mimicks cpio but probably isnt' right */
- rc = expandFifo(cfd, &ch);
- } else {
- rc = CPIOERR_UNKNOWN_FILETYPE;
- }
- }
-
- if (!rc)
- rc = setInfo(&ch);
- if (S_ISREG(ch.mode) && ch.nlink > 1) {
- li->createdPath = linkNum;
- li->linksLeft--;
- rc = createLinks(li, failedFile);
- }
- }
+ if (!rc)
+ rc = setInfo(&ch);
- if (rc && failedFile && *failedFile == NULL) {
- *failedFile = xstrdup(ch.path);
+ if (rc) {
+ *failedFile = strdup(ch.path);
olderr = errno;
unlink(ch.path);
}
}
- padinfd(cfd, 4);
-
- if (!rc && cb) {
- cbInfo.file = ch.path;
- cbInfo.fileSize = ch.size;
- cbInfo.fileComplete = ch.size;
- cbInfo.bytesProcessed = fdGetCpioPos(cfd);
- cb(&cbInfo, cbData);
- }
-
- if (ch.path) free(ch.path);
- ch.path = NULL;
+ padfd(&fd, 4);
+ free(ch.path);
} while (1 && !rc);
- li = links;
- while (li && !rc) {
- if (li->linksLeft) {
- if (li->createdPath == -1)
- rc = CPIOERR_MISSING_HARDLINK;
- else
- rc = createLinks(li, failedFile);
- }
-
- freeLink(li);
-
- links = li;
- li = li->next;
- free(links);
- links = li;
- }
-
- li = links;
- /* if an error got us here links will still be eating some memory */
- while (li) {
- freeLink(li);
- links = li;
- li = li->next;
- free(links);
- }
-
return rc;
}
-
-static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map,
- /*@out@*/size_t * sizep, int writeData)
-{
- struct cpioCrcPhysicalHeader hdr;
- char buf[8192], symbuf[2048];
- dev_t num;
- FD_t datafd;
- size_t size, amount = 0;
- int rc, olderrno;
-
- if (!(map->mapFlags & CPIO_MAP_PATH))
- map->archivePath = map->fsPath;
- if (map->mapFlags & CPIO_MAP_MODE)
- sb.st_mode = (sb.st_mode & S_IFMT) | map->finalMode;
- if (map->mapFlags & CPIO_MAP_UID)
- sb.st_uid = map->finalUid;
- if (map->mapFlags & CPIO_MAP_GID)
- sb.st_gid = map->finalGid;
-
- if (!writeData || S_ISDIR(sb.st_mode)) {
- sb.st_size = 0;
- } else if (S_ISLNK(sb.st_mode)) {
- /* While linux puts the size of a symlink in the st_size field,
- I don't think that's a specified standard */
-
- amount = Readlink(map->fsPath, symbuf, sizeof(symbuf));
- if (amount <= 0) {
- return CPIOERR_READLINK_FAILED;
- }
-
- sb.st_size = amount;
- }
-
- memcpy(hdr.magic, CPIO_NEWC_MAGIC, sizeof(hdr.magic));
- SET_NUM_FIELD(hdr.inode, sb.st_ino, buf);
- SET_NUM_FIELD(hdr.mode, sb.st_mode, buf);
- SET_NUM_FIELD(hdr.uid, sb.st_uid, buf);
- SET_NUM_FIELD(hdr.gid, sb.st_gid, buf);
- SET_NUM_FIELD(hdr.nlink, sb.st_nlink, buf);
- SET_NUM_FIELD(hdr.mtime, sb.st_mtime, buf);
- SET_NUM_FIELD(hdr.filesize, sb.st_size, buf);
-
- num = major((unsigned)sb.st_dev); SET_NUM_FIELD(hdr.devMajor, num, buf);
- num = minor((unsigned)sb.st_dev); SET_NUM_FIELD(hdr.devMinor, num, buf);
- num = major((unsigned)sb.st_rdev); SET_NUM_FIELD(hdr.rdevMajor, num, buf);
- num = minor((unsigned)sb.st_rdev); SET_NUM_FIELD(hdr.rdevMinor, num, buf);
-
- num = strlen(map->archivePath) + 1; SET_NUM_FIELD(hdr.namesize, num, buf);
- memcpy(hdr.checksum, "00000000", 8);
-
- if ((rc = safewrite(cfd, &hdr, PHYS_HDR_SIZE)) != PHYS_HDR_SIZE)
- return rc;
- if ((rc = safewrite(cfd, map->archivePath, num)) != num)
- return rc;
- size = PHYS_HDR_SIZE + num;
- if ((rc = padoutfd(cfd, &size, 4)))
- return rc;
-
- if (writeData && S_ISREG(sb.st_mode)) {
- char *b;
-#if HAVE_MMAP
- void *mapped;
- size_t nmapped;
-#endif
-
- /* XXX unbuffered mmap generates *lots* of fdio debugging */
- datafd = Fopen(map->fsPath, "r.ufdio");
- if (datafd == NULL || Ferror(datafd))
- return CPIOERR_OPEN_FAILED;
-
-#if HAVE_MMAP
- nmapped = 0;
- mapped = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, Fileno(datafd), 0);
- if (mapped != (void *)-1) {
- b = (char *)mapped;
- nmapped = sb.st_size;
- } else
-#endif
- {
- b = buf;
- }
-
- size += sb.st_size;
-
- while (sb.st_size) {
-#if HAVE_MMAP
- if (mapped != (void *)-1) {
- amount = nmapped;
- } else
-#endif
- {
- amount = Fread(b, sizeof(buf[0]),
- (sb.st_size > sizeof(buf) ? sizeof(buf) : sb.st_size),
- datafd);
- if (amount <= 0) {
- olderrno = errno;
- Fclose(datafd);
- errno = olderrno;
- return CPIOERR_READ_FAILED;
- }
- }
-
- if ((rc = safewrite(cfd, b, amount)) != amount) {
- olderrno = errno;
- Fclose(datafd);
- errno = olderrno;
- return rc;
- }
-
- sb.st_size -= amount;
- }
-
-#if HAVE_MMAP
- if (mapped != (void *)-1) {
- munmap(mapped, nmapped);
- }
-#endif
-
- Fclose(datafd);
- } else if (writeData && S_ISLNK(sb.st_mode)) {
- if ((rc = safewrite(cfd, symbuf, amount)) != amount)
- return rc;
- size += amount;
- }
-
- /* this is a noop for most file types */
- if ((rc = padoutfd(cfd, &size, 4)))
- return rc;
-
- if (sizep)
- *sizep = size;
-
- return 0;
-}
-
-static int writeLinkedFile(FD_t cfd, struct hardLink * hlink,
- struct cpioFileMapping * mappings,
- cpioCallback cb, void * cbData,
- /*@out@*/size_t * sizep,
- /*@out@*/const char ** failedFile)
-{
- int i, rc;
- size_t size, total;
- struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
-
- total = 0;
-
- for (i = hlink->nlink - 1; i > hlink->linksLeft; i--) {
- if ((rc = writeFile(cfd, hlink->sb, mappings + hlink->fileMaps[i],
- &size, 0))) {
- if (failedFile)
- *failedFile = xstrdup(mappings[hlink->fileMaps[i]].fsPath);
- return rc;
- }
-
- total += size;
-
- if (cb) {
- cbInfo.file = mappings[i].archivePath;
- cb(&cbInfo, cbData);
- }
- }
-
- if ((rc = writeFile(cfd, hlink->sb,
- mappings + hlink->fileMaps[hlink->linksLeft],
- &size, 1))) {
- if (sizep)
- *sizep = total;
- if (failedFile)
- *failedFile = xstrdup(mappings[hlink->fileMaps[hlink->linksLeft]].fsPath);
- return rc;
- }
- total += size;
-
- if (sizep)
- *sizep = total;
-
- if (cb) {
- cbInfo.file = mappings[i].archivePath;
- cb(&cbInfo, cbData);
- }
-
- return 0;
-}
-
-int cpioBuildArchive(FD_t cfd, struct cpioFileMapping * mappings,
- int numMappings, cpioCallback cb, void * cbData,
- unsigned int * archiveSize, const char ** failedFile)
-{
- size_t size, totalsize = 0;
- int rc;
- int i;
- struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
- struct cpioCrcPhysicalHeader hdr;
- struct stat sb;
-/*@-fullinitblock@*/
- struct hardLink hlinkList = { NULL };
-/*@=fullinitblock@*/
- struct hardLink * hlink, * parent;
-
- hlinkList.next = NULL;
-
- for (i = 0; i < numMappings; i++) {
- if (mappings[i].mapFlags & CPIO_FOLLOW_SYMLINKS)
- rc = Stat(mappings[i].fsPath, &sb);
- else
- rc = Lstat(mappings[i].fsPath, &sb);
-
- if (rc) {
- if (failedFile)
- *failedFile = xstrdup(mappings[i].fsPath);
- return CPIOERR_STAT_FAILED;
- }
-
- if (!S_ISDIR(sb.st_mode) && sb.st_nlink > 1) {
- hlink = hlinkList.next;
- while (hlink &&
- (hlink->dev != sb.st_dev || hlink->inode != sb.st_ino))
- hlink = hlink->next;
- if (!hlink) {
- hlink = xmalloc(sizeof(*hlink));
- hlink->next = hlinkList.next;
- hlinkList.next = hlink;
- hlink->sb = sb; /* structure assignment */
- hlink->dev = sb.st_dev;
- hlink->inode = sb.st_ino;
- hlink->nlink = sb.st_nlink;
- hlink->linksLeft = sb.st_nlink;
- hlink->fileMaps = xmalloc(sizeof(*hlink->fileMaps) *
- sb.st_nlink);
- }
-
- hlink->fileMaps[--hlink->linksLeft] = i;
-
- if (!hlink->linksLeft) {
- if ((rc = writeLinkedFile(cfd, hlink, mappings, cb, cbData,
- &size, failedFile)))
- return rc;
-
- totalsize += size;
-
- free(hlink->fileMaps);
-
- parent = &hlinkList;
- while (parent->next != hlink) parent = parent->next;
- parent->next = parent->next->next;
- free(hlink);
- }
- } else {
- if ((rc = writeFile(cfd, sb, mappings + i, &size, 1))) {
- if (failedFile)
- *failedFile = xstrdup(mappings[i].fsPath);
- return rc;
- }
-
- if (cb) {
- cbInfo.file = mappings[i].archivePath;
- cb(&cbInfo, cbData);
- }
-
- totalsize += size;
- }
- }
-
- hlink = hlinkList.next;
- while (hlink) {
- if ((rc = writeLinkedFile(cfd, hlink, mappings, cb, cbData,
- &size, failedFile)))
- return rc;
- free(hlink->fileMaps);
- parent = hlink;
- hlink = hlink->next;
- free(parent);
-
- totalsize += size;
- }
-
- memset(&hdr, '0', PHYS_HDR_SIZE);
- memcpy(hdr.magic, CPIO_NEWC_MAGIC, sizeof(hdr.magic));
- memcpy(hdr.nlink, "00000001", 8);
- memcpy(hdr.namesize, "0000000b", 8);
- if ((rc = safewrite(cfd, &hdr, PHYS_HDR_SIZE)) != PHYS_HDR_SIZE)
- return rc;
- if ((rc = safewrite(cfd, "TRAILER!!!", 11)) != 11)
- return rc;
- totalsize += PHYS_HDR_SIZE + 11;
-
- /* GNU cpio pads to 512 bytes here, but we don't. I'm not sure if
- it matters or not */
-
- if ((rc = padoutfd(cfd, &totalsize, 4)))
- return rc;
-
- if (archiveSize) *archiveSize = totalsize;
-
- return 0;
-}
-
-const char * cpioStrerror(int rc)
-{
- static char msg[256];
- char *s;
- int l, myerrno = errno;
-
- strcpy(msg, "cpio: ");
- switch (rc) {
- default:
- s = msg + strlen(msg);
- sprintf(s, _("(error 0x%x)"), (unsigned)rc);
- s = NULL;
- break;
- case CPIOERR_BAD_MAGIC: s = _("Bad magic"); break;
- case CPIOERR_BAD_HEADER: s = _("Bad/unreadable header");break;
-
- case CPIOERR_OPEN_FAILED: s = "open"; break;
- case CPIOERR_CHMOD_FAILED: s = "chmod"; break;
- case CPIOERR_CHOWN_FAILED: s = "chown"; break;
- case CPIOERR_WRITE_FAILED: s = "write"; break;
- case CPIOERR_UTIME_FAILED: s = "utime"; break;
- case CPIOERR_UNLINK_FAILED: s = "unlink"; break;
- case CPIOERR_SYMLINK_FAILED: s = "symlink"; break;
- case CPIOERR_STAT_FAILED: s = "stat"; break;
- case CPIOERR_MKDIR_FAILED: s = "mkdir"; break;
- case CPIOERR_MKNOD_FAILED: s = "mknod"; break;
- case CPIOERR_MKFIFO_FAILED: s = "mkfifo"; break;
- case CPIOERR_LINK_FAILED: s = "link"; break;
- case CPIOERR_READLINK_FAILED: s = "readlink"; break;
- case CPIOERR_READ_FAILED: s = "read"; break;
- case CPIOERR_COPY_FAILED: s = "copy"; break;
-
- case CPIOERR_HDR_SIZE: s = _("Header size too big"); break;
- case CPIOERR_UNKNOWN_FILETYPE: s = _("Unknown file type"); break;
- case CPIOERR_MISSING_HARDLINK: s = _("Missing hard link"); break;
- case CPIOERR_INTERNAL: s = _("Internal error"); break;
- }
-
- l = sizeof(msg) - strlen(msg) - 1;
- if (s != NULL) {
- if (l > 0) strncat(msg, s, l);
- l -= strlen(s);
- }
- if ((rc & CPIOERR_CHECK_ERRNO) && myerrno) {
- s = _(" failed - ");
- if (l > 0) strncat(msg, s, l);
- l -= strlen(s);
- if (l > 0) strncat(msg, strerror(myerrno), l);
- }
- return msg;
-}
#include <utime.h>
#include <zlib.h>
+#include "cpio.h"
#include "header.h"
#include "install.h"
#include "md5.h"
+#include "messages.h"
#include "misc.h"
#include "miscfn.h"
#include "rpmdb.h"
#include "rpmlib.h"
-#include "messages.h"
-enum instActions { CREATE, BACKUP, KEEP, SAVE, SKIP };
+enum instActions { UNKNOWN, CREATE, BACKUP, KEEP, SAVE, SKIP };
enum fileTypes { XDIR, BDEV, CDEV, SOCK, PIPE, REG, LINK } ;
-struct fileToInstall {
- char * fileName;
- int size;
+struct fileMemory {
+ char ** md5s;
+ char ** links;
+ char ** names;
+ struct fileInfo * files;
+};
+
+struct fileInfo {
+ char * cpioPath;
+ char * relativePath; /* relative to root */
+ char * rootedPath; /* absolute relative to / */
+ char * md5;
+ char * link;
+ uid_t uid;
+ gid_t gid;
+ uint_32 flags;
+ uint_32 size;
+ mode_t mode;
+ char state;
+ enum instActions action;
+ int install;
} ;
struct replacedFile {
static enum instActions decideFileFate(char * filespec, short dbMode,
char * dbMd5, char * dbLink, short newMode,
char * newMd5, char * newLink, int brokenMd5);
-static int installArchive(char * prefix, int fd, struct fileToInstall * files,
- int fileCount, rpmNotifyFunction notify,
- char ** installArchive, char * tmpPath,
- int archiveSize);
+static int installArchive(char * prefix, int fd, struct fileInfo * files,
+ int fileCount, rpmNotifyFunction notify,
+ char ** specFile, int archiveSize);
static int packageAlreadyInstalled(rpmdb db, char * name, char * version,
char * release, int * recOffset, int flags);
-static int setFileOwnerships(char * rootdir, char ** fileList,
- char ** fileOwners, char ** fileGroups,
- int_16 * fileModes,
- enum instActions * instActions, int fileCount);
-static int setFileOwner(char * file, char * owner, char * group, int_16 mode);
-static int createDirectories(char ** fileList, uint_32 * modesList,
- uint_32 * mtimesList, int fileCount);
-static int mkdirIfNone(char * directory, mode_t perms, uint_32 stamp);
-static int instHandleSharedFiles(rpmdb db, int ignoreOffset, char ** fileList,
- char ** fileMd5List, int_16 * fileModeList,
- char ** fileLinkList, uint_32 * fileFlagsList,
- int fileCount, enum instActions * instActions,
- char ** prootdirootdir, int * notErrors,
+static int instHandleSharedFiles(rpmdb db, int ignoreOffset,
+ struct fileInfo * files,
+ int fileCount, int * notErrors,
struct replacedFile ** repListPtr, int flags);
-static int fileCompare(const void * one, const void * two);
static int installSources(Header h, char * rootdir, int fd,
char ** specFilePtr, rpmNotifyFunction notify,
char * labelFormat);
static int osOkay(Header h);
static int moveFile(char * sourceName, char * destName);
static int copyFile(char * sourceName, char * destName);
-static void unglobFilename(char * dptr, char * sptr);
static int ensureOlder(rpmdb db, Header new, int dbOffset);
+static void assembleFileList(Header h, struct fileMemory * mem,
+ int * fileCountPtr, struct fileInfo ** files,
+ int stripPrefixLength);
+static void freeFileMemory(struct fileMemory fileMem);
/* 0 success */
/* 1 bad magic */
return rc;
}
+static void freeFileMemory(struct fileMemory fileMem) {
+ free(fileMem.files);
+ free(fileMem.md5s);
+ free(fileMem.links);
+ free(fileMem.names);
+}
+
+/* files should not be preallocated */
+static void assembleFileList(Header h, struct fileMemory * mem,
+ int * fileCountPtr, struct fileInfo ** filesPtr,
+ int stripPrefixLength) {
+ char ** fileOwners;
+ char ** fileGroups;
+ uint_32 * fileFlags;
+ uint_32 * fileSizes;
+ uint_16 * fileModes;
+ struct fileInfo * files;
+ struct fileInfo * file;
+ int fileCount;
+ int i;
+
+ headerGetEntry(h, RPMTAG_FILENAMES, NULL, (void **) &mem->names,
+ fileCountPtr);
+ fileCount = *fileCountPtr;
+ files = *filesPtr = mem->files = malloc(sizeof(*mem->files) * fileCount);
+
+ headerGetEntry(h, RPMTAG_FILEMD5S, NULL, (void **) &mem->md5s, NULL);
+ headerGetEntry(h, RPMTAG_FILEUSERNAME, NULL, (void **) &fileOwners, NULL);
+ headerGetEntry(h, RPMTAG_FILEGROUPNAME, NULL, (void **) &fileGroups, NULL);
+ headerGetEntry(h, RPMTAG_FILEFLAGS, NULL, (void **) &fileFlags, NULL);
+ headerGetEntry(h, RPMTAG_FILEMODES, NULL, (void **) &fileModes, NULL);
+ headerGetEntry(h, RPMTAG_FILESIZES, NULL, (void **) &fileSizes, NULL);
+ headerGetEntry(h, RPMTAG_FILELINKTOS, NULL, (void **) &mem->links, NULL);
+
+ for (i = 0, file = files; i < fileCount; i++, file++) {
+ /* It would be nice to take care of assembling the rooted
+ path here, but making the caller do it lets us use alloca()
+ and makes the memory management easier. */
+ file->rootedPath = NULL;
+ file->state = RPMFILE_STATE_NORMAL;
+ file->action = UNKNOWN;
+ file->install = 1;
+
+ file->relativePath = mem->names[i];
+ file->cpioPath = mem->names[i] + stripPrefixLength;
+ file->mode = fileModes[i];
+ file->md5 = mem->md5s[i];
+ file->link = mem->links[i];
+ file->size = fileSizes[i];
+ file->flags = fileFlags[i];
+
+ if (unameToUid(fileOwners[i], &files[i].uid)) {
+ rpmError(RPMERR_NOUSER, "user %s does not exist - using root",
+ fileOwners[i]);
+ files[i].uid = 0;
+ /* turn off the suid bit */
+ files[i].mode &= ~S_ISUID;
+ }
+
+ if (gnameToGid(fileGroups[i], &files[i].gid)) {
+ rpmError(RPMERR_NOGROUP, "user %s does not exist - using root",
+ fileGroups[i]);
+ files[i].gid = 0;
+ /* turn off the sgid bit */
+ files[i].mode &= ~S_ISGID;
+ }
+ }
+
+ free(fileOwners);
+ free(fileGroups);
+}
+
/* 0 success */
/* 1 bad magic */
/* 2 error */
char * name, * version, * release;
Header h;
int fileCount, type, count;
- char ** fileList;
- char ** fileOwners, ** fileGroups, ** fileMd5s, ** fileLinkList;
- uint_32 * fileFlagsList;
- uint_32 * fileSizesList, * fileMtimesList;
- int_16 * fileModesList;
+ struct fileInfo * files;
int_32 installTime;
- char * fileStatesList = NULL;
- struct fileToInstall * files;
- enum instActions * instActions = NULL;
+ char * fileStates;
int i;
- int archiveFileCount = 0;
int installFile = 0;
int otherOffset = 0;
char * ext = NULL, * newpath;
int rootLength = strlen(rootdir);
- char ** rootedFileList = NULL;
- char ** finalFileList = NULL;
- char ** mkdirFileList = NULL;
- int mkdirFileCount = 0;
- uint_32 * mkdirModesList, * mkdirMtimesList;
struct replacedFile * replacedList = NULL;
char * defaultPrefix;
dbiIndexSet matches;
int hasOthers = 0;
int relocationSize = 1; /* strip at least first / for cpio */
uint_32 * archiveSizePtr;
+ struct fileMemory fileMem;
+ int freeFileMem = 0;
oldVersions = alloca(sizeof(int));
*oldVersions = 0;
if (isSource) {
if (flags & RPMINSTALL_TEST) {
- rpmMessage(RPMMESS_DEBUG, "stopping install as we're running --test\n");
+ rpmMessage(RPMMESS_DEBUG,
+ "stopping install as we're running --test\n");
return 0;
}
return rc;
}
- /* Do this now so we can give error messages, even though we'll just
- do it again after relocating everything */
headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &fileCount);
headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &fileCount);
headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &fileCount);
if (hasOthers)
dbiFreeIndexRecord(matches);
- fileList = NULL;
- if (headerGetEntry(h, RPMTAG_FILENAMES, &type, (void **) &fileList,
- &fileCount)) {
+ if (headerIsEntry(h, RPMTAG_FILENAMES)) {
char ** netsharedPaths;
char ** nsp;
+ freeFileMem = 1;
+ assembleFileList(h, &fileMem, &fileCount, &files, relocationSize);
+
if (netsharedPath)
netsharedPaths = splitString(netsharedPath,
strlen(netsharedPath), ':');
else
netsharedPaths = NULL;
- instActions = alloca(sizeof(enum instActions) * fileCount);
- rootedFileList = alloca(sizeof(char *) * fileCount);
- fileStatesList = alloca(sizeof(*fileStatesList) * fileCount);
-
- headerGetEntry(h, RPMTAG_FILEMD5S, &type, (void **) &fileMd5s, &fileCount);
- headerGetEntry(h, RPMTAG_FILEFLAGS, &type, (void **) &fileFlagsList,
- &fileCount);
- headerGetEntry(h, RPMTAG_FILEMODES, &type, (void **) &fileModesList,
- &fileCount);
- headerGetEntry(h, RPMTAG_FILELINKTOS, &type, (void **) &fileLinkList,
- &fileCount);
-
/* check for any config files that already exist. If they do, plan
on making a backup copy. If that's not the right thing to do
instHandleSharedFiles() below will take care of the problem */
for (i = 0; i < fileCount; i++) {
if (rootLength > 1) {
- rootedFileList[i] = alloca(strlen(fileList[i]) +
+ files[i].rootedPath = alloca(strlen(files[i].relativePath) +
rootLength + 3);
- strcpy(rootedFileList[i], rootdir);
- strcat(rootedFileList[i], fileList[i]);
+ strcpy(files[i].rootedPath, rootdir);
+ strcat(files[i].rootedPath, files[i].relativePath);
} else
- rootedFileList[i] = fileList[i];
+ files[i].rootedPath = files[i].relativePath;
/* netsharedPaths are not relative to the current root (though
they do need to take the package prefix into account */
for (nsp = netsharedPaths; nsp && *nsp; nsp++)
- if (!strncmp(fileList[i], *nsp, strlen(*nsp))) break;
+ if (!strncmp(files[i].relativePath, *nsp, strlen(*nsp)))
+ break;
if (nsp && *nsp) {
rpmMessage(RPMMESS_DEBUG, "file %s in netshared path\n",
- rootedFileList[i]);
- instActions[i] = SKIP;
- fileStatesList[i] = RPMFILE_STATE_NETSHARED;
- } else if ((fileFlagsList[i] & RPMFILE_DOC) &&
+ files[i].rootedPath);
+ files[i].action = SKIP;
+ files[i].state = RPMFILE_STATE_NETSHARED;
+ } else if ((files[i].flags & RPMFILE_DOC) &&
(flags & RPMINSTALL_NODOCS)) {
- instActions[i] = SKIP;
- fileStatesList[i] = RPMFILE_STATE_NOTINSTALLED;
+ files[i].action = SKIP;
+ files[i].state = RPMFILE_STATE_NOTINSTALLED;
} else {
- fileStatesList[i] = RPMFILE_STATE_NORMAL;
+ files[i].state = RPMFILE_STATE_NORMAL;
- instActions[i] = CREATE;
- if ((fileFlagsList[i] & RPMFILE_CONFIG) &&
- !S_ISDIR(fileModesList[i])) {
- if (exists(rootedFileList[i])) {
+ files[i].action = CREATE;
+ if ((files[i].flags & RPMFILE_CONFIG) &&
+ !S_ISDIR(files[i].mode)) {
+ if (exists(files[i].rootedPath)) {
rpmMessage(RPMMESS_DEBUG, "%s exists - backing up\n",
- rootedFileList[i]);
- instActions[i] = BACKUP;
+ files[i].rootedPath);
+ files[i].action = BACKUP;
}
}
}
}
- rc = instHandleSharedFiles(db, 0, fileList, fileMd5s, fileModesList,
- fileLinkList, fileFlagsList, fileCount,
- instActions, rootedFileList, oldVersions,
- &replacedList, flags);
+ rc = instHandleSharedFiles(db, otherOffset, files, fileCount,
+ oldVersions, &replacedList, flags);
- free(fileMd5s);
- free(fileLinkList);
if (rc) {
if (replacedList) free(replacedList);
- free(fileList);
+ if (freeFileMem) freeFileMemory(fileMem);
return 2;
}
+ } else {
+ files = NULL;
}
if (flags & RPMINSTALL_TEST) {
rpmMessage(RPMMESS_DEBUG, "stopping install as we're running --test\n");
- free(fileList);
if (replacedList) free(replacedList);
+ if (freeFileMem) freeFileMemory(fileMem);
return 0;
}
rpmMessage(RPMMESS_DEBUG, "running preinstall script (if any)\n");
if (runScript(rootdir, h, RPMTAG_PREIN, scriptArg,
flags & RPMINSTALL_NOSCRIPTS)) {
- free(fileList);
if (replacedList) free(replacedList);
+ if (freeFileMem) freeFileMemory(fileMem);
return 2;
}
- if (fileList) {
- headerGetEntry(h, RPMTAG_FILESIZES, &type, (void **) &fileSizesList,
- &fileCount);
- headerGetEntry(h, RPMTAG_FILEMTIMES, &type, (void **) &fileMtimesList,
- &fileCount);
-
- files = alloca(sizeof(struct fileToInstall) * fileCount);
- finalFileList = alloca(sizeof(char *) * fileCount);
- mkdirFileList = alloca(sizeof(char *) * fileCount);
- mkdirModesList = alloca(sizeof(*mkdirModesList) * fileCount);
- mkdirMtimesList = alloca(sizeof(*mkdirMtimesList) * fileCount);
+ if (files) {
for (i = 0; i < fileCount; i++) {
- switch (instActions[i]) {
+ switch (files[i].action) {
case BACKUP:
ext = ".rpmorig";
installFile = 1;
installFile = 0;
ext = NULL;
break;
+
+ case UNKNOWN:
+ break;
}
if (ext) {
- newpath = alloca(strlen(rootedFileList[i]) + 20);
- strcpy(newpath, rootedFileList[i]);
+ newpath = alloca(strlen(files[i].rootedPath) + 20);
+ strcpy(newpath, files[i].rootedPath);
strcat(newpath, ext);
rpmError(RPMMESS_BACKUP, "warning: %s saved as %s",
- rootedFileList[i], newpath);
+ files[i].rootedPath, newpath);
- if (rename(rootedFileList[i], newpath)) {
+ if (rename(files[i].rootedPath, newpath)) {
rpmError(RPMERR_RENAME, "rename of %s to %s failed: %s",
- rootedFileList[i], newpath, strerror(errno));
+ files[i].rootedPath, newpath, strerror(errno));
if (replacedList) free(replacedList);
+ if (freeFileMem) freeFileMemory(fileMem);
return 2;
}
}
- if (installFile) {
- /* if we are using a relocateable package, we need to strip
- off whatever part of the (already relocated!) filelist
-
- we also need to strip globbing characters, as cpio
- globs the patterns we pass to it against the filenames
- in the archive */
-
- files[archiveFileCount].fileName =
- alloca((strlen(fileList[i]) * 2) + 1);
-
- unglobFilename(files[archiveFileCount].fileName,
- fileList[i] + relocationSize);
- files[archiveFileCount].size = fileSizesList[i];
-
-
- /* both of these list what files need to be installed and
- where they end up *after* any relocations have been done
- the mkdir list includes direcories though, while the final
- list does *not -- we don't let cpio expand directories as
- it has a bad habit of replacing symlinks with directories
- when we'd rather it didn't */
- mkdirFileList[mkdirFileCount] = rootedFileList[i];
- mkdirModesList[mkdirFileCount] = fileModesList[i];
- mkdirMtimesList[mkdirFileCount] = fileMtimesList[i];
- mkdirFileCount++;
-
- if (!S_ISDIR(fileModesList[i])) {
- finalFileList[archiveFileCount] = rootedFileList[i];
- archiveFileCount++;
- }
+ if (!installFile) {
+ files[i].install = 0;
}
}
} else
tmpPath = rpmGetVar(RPMVAR_TMPPATH);
- if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, &type, (void *) &archiveSizePtr,
- &count))
+ if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, &type,
+ (void *) &archiveSizePtr, &count))
archiveSizePtr = NULL;
- if (createDirectories(mkdirFileList, mkdirModesList, mkdirMtimesList,
- mkdirFileCount)) {
- headerFree(h);
- free(fileList);
- if (replacedList) free(replacedList);
- return 2;
- }
-
if (labelFormat) {
printf(labelFormat, name, version, release);
fflush(stdout);
}
/* the file pointer for fd is pointing at the cpio archive */
- if (installArchive(archivePrefix, fd, files, archiveFileCount, notify,
- NULL, tmpPath,
- archiveSizePtr ? *archiveSizePtr : 0)) {
+ if (installArchive(archivePrefix, fd, files, fileCount, notify,
+ NULL, archiveSizePtr ? *archiveSizePtr : 0)) {
headerFree(h);
- free(fileList);
if (replacedList) free(replacedList);
+ if (freeFileMem) freeFileMemory(fileMem);
return 2;
}
- if (headerGetEntry(h, RPMTAG_FILEUSERNAME, &type, (void **) &fileOwners,
- &fileCount)) {
- if (headerGetEntry(h, RPMTAG_FILEGROUPNAME, &type, (void **) &fileGroups,
- &fileCount)) {
- if (setFileOwnerships(rootdir, fileList, fileOwners, fileGroups,
- fileModesList, instActions, fileCount)) {
- free(fileOwners);
- free(fileGroups);
- free(fileList);
- if (replacedList) free(replacedList);
+ if (files) {
+ fileStates = malloc(sizeof(*fileStates) * fileCount);
+ for (i = 0; i < fileCount; i++)
+ fileStates[i] = files[i].state;
- return 2;
- }
- free(fileGroups);
- }
- free(fileOwners);
- }
- free(fileList);
+ headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStates,
+ fileCount);
- headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStatesList, fileCount);
+ free(fileStates);
+ if (freeFileMem) freeFileMemory(fileMem);
+ }
installTime = time(NULL);
headerAddEntry(h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE, &installTime, 1);
#define BLOCKSIZE 1024
-/* -1 fileCount means install all files */
-static int installArchive(char * prefix, int fd, struct fileToInstall * files,
+/* NULL files means install all files */
+static int installArchive(char * prefix, int fd, struct fileInfo * files,
int fileCount, rpmNotifyFunction notify,
- char ** specFile, char * tmpPath, int archiveSize) {
+ char ** specFile, int archiveSize) {
gzFile stream;
- char buf[BLOCKSIZE];
- pid_t child;
- int p[2];
- int statusPipe[2];
- int bytesRead;
- int bytes;
- int status;
- int cpioFailed = 0;
- void * oldhandler;
- int needSecondPipe;
- char line[1024];
- int j;
- int i = 0;
- int childGotStatus = 0;
- unsigned long totalSize = 0;
- unsigned long sizeInstalled = 0;
- struct fileToInstall fileInstalled;
- struct fileToInstall * file;
- char * chptr, * filelist;
- char ** args;
- FILE * f;
- int len;
- int childDead = 0;
-
- /* no files to install */
- if (!fileCount) return 0;
-
- /* install all files, so don't pass a filelist to cpio */
- if (fileCount == -1) fileCount = 0;
-
- /* fd should be a gzipped cpio archive */
-
- rpmMessage(RPMMESS_DEBUG, "installing archive into %s\n", prefix);
-
- needSecondPipe = (notify != NULL && !archiveSize) || specFile;
-
- if (specFile) *specFile = NULL;
-
- args = alloca(sizeof(char *) * (fileCount + 10));
-
- args[i++] = rpmGetVar(RPMVAR_CPIOBIN);
- args[i++] = "--extract";
- args[i++] = "--unconditional";
- args[i++] = "--preserve-modification-time";
- args[i++] = "--make-directories";
- args[i++] = "--quiet";
-
- if (!args[0]) args[0] = "cpio";
-
- if (needSecondPipe)
- args[i++] = "--verbose";
-
- /* note - if fileCount == 0, all files get installed */
- /* if fileCount > 500, we use a temporary file to pass the file
- list to cpio rather then args because we're in danger of passing
- too much argv/env stuff */
-
- if (fileCount > 500) {
- filelist = alloca(strlen(tmpPath) + 40);
-
- rpmMessage(RPMMESS_DEBUG, "using a %s filelist\n", tmpPath);
- sprintf(filelist, "%s/rpm-cpiofilelist.%d.tmp", tmpPath,
- (int) getpid());
- f = fopen(filelist, "w");
- if (!f) {
- rpmError(RPMERR_CREATE, "failed to create %s: %s", filelist,
- strerror(errno));
- return 1;
- }
-
- for (j = 0; j < fileCount; j++) {
- if ((fputs(files[j].fileName, f) == EOF) ||
- (fputs("\n", f) == EOF)) {
- if (errno == ENOSPC) {
- rpmError(RPMERR_NOSPACE, "out of space on device");
- } else {
- rpmError(RPMERR_CREATE, "failed to create %s: %s", filelist,
- strerror(errno));
- }
-
- fclose(f);
- unlink(filelist);
- return 1;
- }
- }
-
- fclose(f);
-
- args[i++] = "--pattern-file";
- args[i++] = filelist;
- } else {
- filelist = NULL;
- for (j = 0; j < fileCount; j++)
- args[i++] = files[j].fileName;
- }
-
- args[i++] = NULL;
-
- stream = gzdopen(fd, "r");
- pipe(p);
-
- if (needSecondPipe) {
- pipe(statusPipe);
- for (i = 0; i < fileCount; i++)
- totalSize += files[i].size;
- qsort(files, fileCount, sizeof(struct fileToInstall), fileCompare);
+ int rc, i;
+ struct cpioFileMapping * map;
+ char * failedFile;
+
+ if (!files) {
+ /* install all files */
+ fileCount = 0;
+ } else if (!fileCount) {
+ /* no files to install */
+ return 0;
}
- oldhandler = signal(SIGPIPE, SIG_IGN);
-
- child = fork();
- if (!child) {
- chdir(prefix);
-
- close(p[1]); /* we don't need to write to it */
- close(0); /* stdin will come from the pipe instead */
- dup2(p[0], 0);
- close(p[0]);
-
- if (needSecondPipe) {
- close(statusPipe[0]); /* we don't need to read from it*/
- close(2); /* stderr will go to a pipe instead */
- dup2(statusPipe[1], 2);
- close(statusPipe[1]);
- }
-
- execvp(args[0], args);
-
- _exit(-1);
- }
+ if (specFile) *specFile = NULL;
- close(p[0]);
- if (needSecondPipe) {
- close(statusPipe[1]);
- fcntl(statusPipe[0], F_SETFL, O_NONBLOCK);
+ map = alloca(sizeof(*map) * fileCount);
+ for (i = 0; i < fileCount; i++) {
+ map[i].archivePath = files[i].cpioPath;
+ map[i].finalPath = files[i].rootedPath;
+ map[i].finalMode = files[i].mode;
+ map[i].finalUid = files[i].uid;
+ map[i].finalGid = files[i].gid;
+ map[i].mapFlags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID |
+ CPIO_MAP_GID;
}
- do {
- if (waitpid(child, &status, WNOHANG)) childDead = 1;
-
- bytesRead = gzread(stream, buf, sizeof(buf));
- if (bytesRead < 0) {
- cpioFailed = 1;
- childDead = 1;
- kill(child, SIGTERM);
- } else if (bytesRead == 0) {
- /* if it's not dead yet, it will be when we close the pipe */
- waitpid(child, &status, 0);
- childDead = 1;
- childGotStatus = 1;
- } else if (bytesRead && write(p[1], buf, bytesRead) != bytesRead) {
- cpioFailed = 1;
- childDead = 1;
- kill(child, SIGTERM);
- }
-
- if (needSecondPipe) {
- bytes = read(statusPipe[0], line, sizeof(line));
-
- while (bytes > 0) {
- /* the sooner we erase this, the better. less chance
- of leaving it sitting around after a SIGINT
- (or SIGSEGV!) */
- if (filelist) {
- unlink(filelist);
- filelist = NULL;
- }
-
- fileInstalled.fileName = line;
-
- while ((chptr = (strchr(fileInstalled.fileName, '\n')))) {
- *chptr = '\0';
-
- rpmMessage(RPMMESS_DEBUG, "file \"%s\" complete\n",
- fileInstalled.fileName);
-
- if (notify && !archiveSize) {
- file = bsearch(&fileInstalled, files, fileCount,
- sizeof(struct fileToInstall),
- fileCompare);
- if (file) {
- sizeInstalled += file->size;
- notify(sizeInstalled, totalSize);
- }
- }
-
- if (specFile) {
- len = strlen(fileInstalled.fileName);
- if (fileInstalled.fileName[len - 1] == 'c' &&
- fileInstalled.fileName[len - 2] == 'e' &&
- fileInstalled.fileName[len - 3] == 'p' &&
- fileInstalled.fileName[len - 4] == 's' &&
- fileInstalled.fileName[len - 5] == '.') {
-
- if (*specFile) free(*specFile);
- *specFile = strdup(fileInstalled.fileName);
- }
- }
-
- fileInstalled.fileName = chptr + 1;
- }
-
- bytes = read(statusPipe[0], line, sizeof(line));
- }
- }
-
- if (notify && archiveSize) {
- sizeInstalled += bytesRead;
- notify(sizeInstalled, archiveSize);
- }
- } while (!childDead);
-
- gzclose(stream);
- close(p[1]);
- if (needSecondPipe) close(statusPipe[0]);
- signal(SIGPIPE, oldhandler);
+ if (notify)
+ notify(0, archiveSize);
- if (!childGotStatus)
- waitpid(child, &status, 0);
+ qsort(map, fileCount, sizeof(*map), cpioFileMapCmp);
- if (filelist) {
- unlink(filelist);
- }
+ stream = gzdopen(fd, "r");
+ rc = cpioInstallArchive(stream, map, fileCount, NULL, &failedFile);
- if (cpioFailed || !WIFEXITED(status) || WEXITSTATUS(status)) {
+ if (rc) {
/* this would probably be a good place to check if disk space
was used up - if so, we should return a different error */
- rpmError(RPMERR_CPIO, "unpacking of archive failed");
+ rpmError(RPMERR_CPIO, "unpacking of archive failed on file %s: %d",
+ failedFile, rc);
return 1;
}
if (notify)
- notify(totalSize, totalSize);
+ notify(archiveSize, archiveSize);
return 0;
}
return 0;
}
-static int setFileOwnerships(char * rootdir, char ** fileList,
- char ** fileOwners, char ** fileGroups,
- int_16 * fileModesList,
- enum instActions * instActions, int fileCount) {
- int i;
- char * chptr;
- int doFork = 0;
- pid_t child;
- int status;
-
- rpmMessage(RPMMESS_DEBUG, "setting file owners and groups by name (not id)\n");
-
- chptr = rootdir;
- while (*chptr && *chptr == '/')
- chptr++;
-
- if (*chptr) {
- rpmMessage(RPMMESS_DEBUG, "forking child to setid's in chroot() "
- "environment\n");
- doFork = 1;
-
- if ((child = fork())) {
- waitpid(child, &status, 0);
- return 0;
- } else {
- chroot(rootdir);
- }
- }
-
- for (i = 0; i < fileCount; i++) {
- if (instActions[i] != SKIP) {
- /* ignore errors here - setFileOwner handles them reasonable
- and we want to keep running */
- setFileOwner(fileList[i], fileOwners[i], fileGroups[i],
- fileModesList[i]);
- }
- }
-
- if (doFork)
- _exit(0);
-
- return 0;
-}
-
-/* setFileOwner() is really poorly implemented. It really ought to use
- hash tables. I just made the guess that most files would be owned by
- root or the same person/group who owned the last file. Those two values
- are cached, everything else is looked up via getpw() and getgr() functions.
- If this performs too poorly I'll have to implement it properly :-( */
-
-static int setFileOwner(char * file, char * owner, char * group,
- int_16 mode ) {
- uid_t uid;
- gid_t gid;
-
- if ((uid = unameToUid(owner)) == -1) {
- rpmError(RPMERR_NOUSER, "user %s does not exist - using root", owner);
- uid = 0;
- /* turn off the suid bit */
- mode &= ~S_ISUID;
- }
-
- if ((gid = gnameToGid(group)) == -1) {
- rpmError(RPMERR_NOUSER, "group %s does not exist - using root", group);
- gid = 0;
- /* turn off the sgid bit */
- mode &= ~S_ISGID;
- }
-
- rpmMessage(RPMMESS_DEBUG, "%s owned by %s (%d), group %s (%d) mode %o\n",
- file, owner, uid, group, gid, mode & 07777);
- if (chown(file, uid, gid)) {
- rpmError(RPMERR_CHOWN, "cannot set owner and group for %s - %s",
- file, strerror(errno));
- /* screw with the permissions so it's not SUID and 0.0 */
- chmod(file, mode & ~S_ISUID & ~S_ISGID);
- return 1;
- }
- /* Also set the mode according to what is stored in the header */
- if (! S_ISLNK(mode)) {
- if (chmod(file, mode & 07777)) {
- rpmError(RPMERR_CHOWN, "cannot change mode for %s - %s",
- file, strerror(errno));
- /* try to screw with the permissions so it's not SUID and 0.0 */
- chmod(file, mode & ~S_ISUID & ~S_ISGID);
- return 1;
- }
- }
-
- return 0;
-}
-
-/* This could be more efficient. A brute force tokenization and mkdir's
- seems like horrible overkill. I did make it know better then trying to
- create the same directory string twice in a row though. That should make it
- perform adequatally thanks to the sorted filelist.
-
- This could create directories that should be symlinks :-( RPM building
- should probably resolve symlinks in paths.
-
- This creates directories which are always 0755, despite the current umask */
-
-static int createDirectories(char ** fileList, uint_32 * modesList,
- uint_32 * fileMtimesList, int fileCount) {
- int i;
- char * lastDirectory;
- char * buffer;
- int bufferLength;
- int neededLength;
- char * chptr;
-
- lastDirectory = malloc(1);
- lastDirectory[0] = '\0';
-
- bufferLength = 1000; /* should be more then adequate */
- buffer = malloc(bufferLength);
-
- for (i = 0; i < fileCount; i++) {
- neededLength = strlen(fileList[i]) + 1;
- if (neededLength > bufferLength) {
- free(buffer);
- bufferLength = neededLength * 2;
- buffer = malloc(bufferLength);
- }
- strcpy(buffer, fileList[i]);
-
- for (chptr = buffer + strlen(buffer) - 1; *chptr; chptr--) {
- if (*chptr == '/') break;
- }
-
- if (! *chptr) continue; /* no path, just filename */
- if (chptr == buffer) continue; /* /filename - no directories */
-
- *chptr = '\0'; /* buffer is now just directories */
-
- if (strcmp(buffer, lastDirectory)) {
- for (chptr = buffer + 1; *chptr; chptr++) {
- if (*chptr == '/') {
- if (*(chptr -1) != '/') {
- *chptr = '\0';
- if (mkdirIfNone(buffer, 0755, 0)) {
- free(lastDirectory);
- free(buffer);
- return 1;
- }
- *chptr = '/';
- }
- }
- }
-
- if (mkdirIfNone(buffer, 0755, 0)) {
- free(lastDirectory);
- free(buffer);
- return 1;
- }
-
- free(lastDirectory);
- lastDirectory = strdup(buffer);
- }
-
- if (S_ISDIR(modesList[i])) {
- if (mkdirIfNone(fileList[i], 0755, fileMtimesList[i])) {
- free(lastDirectory);
- free(buffer);
- return 1;
- }
- }
- }
-
- free(lastDirectory);
- free(buffer);
-
- return 0;
-}
-
-static int mkdirIfNone(char * directory, mode_t perms, uint_32 mtime) {
- int rc;
- char * chptr;
- struct utimbuf stamp;
-
- for (chptr = directory; *chptr; chptr++)
- if (*chptr != '/') break;
- if (!*chptr) return 0;
-
- if (exists(directory)) {
- return 0;
- }
-
- rpmMessage(RPMMESS_DEBUG, "trying to make %s\n", directory);
-
- rc = mkdir(directory, perms);
- if (!rc) {
- if (mtime) {
- stamp.actime = mtime;
- stamp.modtime = mtime;
- utime(directory, &stamp);
- }
- return 0;
- }
-
- rpmError(RPMERR_MKDIR, "failed to create %s - %s", directory,
- strerror(errno));
-
- return errno;
-}
-
static int filecmp(short mode1, char * md51, char * link1,
short mode2, char * md52, char * link2) {
enum fileTypes what1, what2;
/* return 0: okay, continue install */
/* return 1: problem, halt install */
-static int instHandleSharedFiles(rpmdb db, int ignoreOffset, char ** fileList,
- char ** fileMd5List, int_16 * fileModesList,
- char ** fileLinkList, uint_32 * fileFlagsList,
- int fileCount, enum instActions * instActions,
- char ** prefixedFileList, int * notErrors,
+static int instHandleSharedFiles(rpmdb db, int ignoreOffset,
+ struct fileInfo * files,
+ int fileCount, int * notErrors,
struct replacedFile ** repListPtr, int flags) {
struct sharedFile * sharedList;
int secNum, mainNum;
struct replacedFile * replacedList;
int numReplacedFiles, numReplacedAlloced;
char state;
+ char ** fileList;
+
+ fileList = malloc(sizeof(*fileList) * fileCount);
+ for (i = 0; i < fileCount; i++)
+ fileList[i] = files[i].rootedPath;
if (findSharedFiles(db, 0, fileList, fileCount, &sharedList,
&sharedCount)) {
+ free(fileList);
return 1;
}
+ free(fileList);
numReplacedAlloced = 10;
numReplacedFiles = 0;
replacedList = malloc(sizeof(*replacedList) * numReplacedAlloced);
for (i = 0; i < sharedCount; i++) {
- if (sharedList[i].secRecOffset == ignoreOffset) continue;
-
if (secOffset != sharedList[i].secRecOffset) {
if (secOffset) {
headerFree(sech);
continue;
}
- if (filecmp(fileModesList[mainNum], fileMd5List[mainNum],
- fileLinkList[mainNum], secFileModesList[secNum],
+ if (filecmp(files[mainNum].mode, files[mainNum].md5,
+ files[mainNum].link, secFileModesList[secNum],
secFileMd5List[secNum], secFileLinksList[secNum])) {
if (!(flags & RPMINSTALL_REPLACEFILES) && !(*intptr)) {
rpmError(RPMERR_PKGINSTALLED, "%s conflicts with file from "
- "%s-%s-%s", fileList[sharedList[i].mainFileNumber],
- name, version, release);
+ "%s-%s-%s",
+ files[sharedList[i].mainFileNumber].relativePath,
+ name, version, release);
rc = 1;
} else {
if (numReplacedFiles == numReplacedAlloced) {
numReplacedFiles++;
rpmMessage(RPMMESS_DEBUG, "%s from %s-%s-%s will be replaced\n",
- fileList[sharedList[i].mainFileNumber],
+ files[sharedList[i].mainFileNumber].relativePath,
name, version, release);
}
}
/* if this is a config file, we need to be carefull here */
- if (fileFlagsList[sharedList[i].mainFileNumber] & RPMFILE_CONFIG ||
+ if (files[sharedList[i].mainFileNumber].flags & RPMFILE_CONFIG ||
secFileFlagsList[sharedList[i].secFileNumber] & RPMFILE_CONFIG) {
- instActions[sharedList[i].mainFileNumber] =
- decideFileFate(prefixedFileList[mainNum],
+ files[sharedList[i].mainFileNumber].action =
+ decideFileFate(files[mainNum].rootedPath,
secFileModesList[secNum],
secFileMd5List[secNum], secFileLinksList[secNum],
- fileModesList[mainNum], fileMd5List[mainNum],
- fileLinkList[mainNum],
+ files[mainNum].mode, files[mainNum].md5,
+ files[mainNum].link,
!headerIsEntry(sech, RPMTAG_RPMVERSION));
}
}
return rc;
}
-static int fileCompare(const void * one, const void * two) {
- return strcmp(((struct fileToInstall *) one)->fileName,
- ((struct fileToInstall *) two)->fileName);
-}
-
/* 0 success */
/* 1 bad magic */
/* 2 error */
headerGetEntry(h, RPMTAG_NAME, &type, (void *) &name, &count);
headerGetEntry(h, RPMTAG_VERSION, &type, (void *) &version, &count);
headerGetEntry(h, RPMTAG_RELEASE, &type, (void *) &release, &count);
- if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, &type, (void *) &archiveSizePtr,
- &count))
+ if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, &type,
+ (void *) &archiveSizePtr, &count))
archiveSizePtr = NULL;
printf(labelFormat, name, version, release);
fflush(stdout);
}
+/*
+ FIXME
+
if (installArchive(realSourceDir, fd, NULL, -1, notify, &specFile,
tmpPath, archiveSizePtr ? *archiveSizePtr : 0)) {
return 2;
}
+*/
if (!specFile) {
rpmError(RPMERR_NOSPEC, "source package contains no .spec file");
strcat(correctSpecFile, "/");
strcat(correctSpecFile, specFile);
- rpmMessage(RPMMESS_DEBUG, "renaming %s to %s\n", instSpecFile, correctSpecFile);
+ rpmMessage(RPMMESS_DEBUG,
+ "renaming %s to %s\n", instSpecFile, correctSpecFile);
if (rename(instSpecFile, correctSpecFile)) {
/* try copying the file */
if (moveFile(instSpecFile, correctSpecFile))
headerFree(sh);
}
- headerGetEntry(secHeader, RPMTAG_FILESTATES, &type, (void **) &secStates,
- &count);
+ headerGetEntry(secHeader, RPMTAG_FILESTATES, &type,
+ (void **) &secStates, &count);
}
/* by now, secHeader is the right header to modify, secStates is
return 0;
}
-
-static void unglobFilename(char * dptr, char * sptr) {
- while (*sptr) {
- switch (*sptr) {
- case '*': case '[': case ']': case '?': case '\\':
- *dptr++ = '\\';
- /*fallthrough*/
- default:
- *dptr++ = *sptr++;
- }
- }
- *dptr++ = *sptr;
-}