summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorewt <devnull@localhost>1997-05-06 15:27:46 +0000
committerewt <devnull@localhost>1997-05-06 15:27:46 +0000
commit0a02b64c726bce0763e71ba393ad2740c2ecdd9f (patch)
treeb8c61743bb8f4ea5ca43cc10b7c215fa326fa9ec
parent260850e9b840b6b745121a8c7c9fe8d70b116d7e (diff)
downloadlibrpm-tizen-0a02b64c726bce0763e71ba393ad2740c2ecdd9f.tar.gz
librpm-tizen-0a02b64c726bce0763e71ba393ad2740c2ecdd9f.tar.bz2
librpm-tizen-0a02b64c726bce0763e71ba393ad2740c2ecdd9f.zip
Added callbacks to cpio to allow -h to work.
CVS patchset: 1596 CVS date: 1997/05/06 15:27:46
-rw-r--r--lib/cpio.c51
-rw-r--r--lib/cpio.h12
-rw-r--r--lib/install.c28
3 files changed, 69 insertions, 22 deletions
diff --git a/lib/cpio.c b/lib/cpio.c
index ddff7a4f7..7bc554111 100644
--- a/lib/cpio.c
+++ b/lib/cpio.c
@@ -148,10 +148,7 @@ 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)) {
if (S_ISDIR(sb.st_mode)) {
return 0;
} else if (S_ISLNK(sb.st_mode)) {
@@ -240,14 +237,17 @@ static int checkDirectory(char * filename) {
return rc;
}
-static int expandRegular(struct ourfd * fd, struct cpioHeader * hdr) {
+static int expandRegular(struct ourfd * fd, struct cpioHeader * hdr,
+ cpioCallback cb, void * cbData) {
int out;
- char buf[16384];
+ char buf[8192];
int bytesRead;
int left = hdr->size;
int rc = 0;
+ struct cpioCallbackInfo cbInfo;
+ struct stat sb;
- if (!access(hdr->path, X_OK))
+ if (!lstat(hdr->path, &sb))
if (unlink(hdr->path))
return CPIO_UNLINK_FAILED;
@@ -255,6 +255,9 @@ static int expandRegular(struct ourfd * fd, struct cpioHeader * hdr) {
if (out < 0)
return CPIO_OPEN_FAILED;
+ cbInfo.file = hdr->path;
+ cbInfo.fileSize = hdr->size;
+
while (left) {
bytesRead = ourread(fd, buf, left < sizeof(buf) ? left : sizeof(buf));
if (bytesRead <= 0) {
@@ -268,6 +271,13 @@ static int expandRegular(struct ourfd * fd, struct cpioHeader * hdr) {
}
left -= bytesRead;
+
+ /* don't call this with fileSize == fileComplete */
+ if (!rc && cb && left) {
+ cbInfo.fileComplete = hdr->size - left;
+ cbInfo.bytesProcessed = fd->pos;
+ cb(&cbInfo, cbData);
+ }
}
close(out);
@@ -277,8 +287,9 @@ static int expandRegular(struct ourfd * fd, struct cpioHeader * hdr) {
static int expandSymlink(struct ourfd * fd, struct cpioHeader * hdr) {
char buf[2048];
+ struct stat sb;
- if (!access(hdr->path, X_OK))
+ if (!lstat(hdr->path, &sb))
if (unlink(hdr->path))
return CPIO_UNLINK_FAILED;
@@ -299,10 +310,7 @@ static int expandSymlink(struct ourfd * fd, struct cpioHeader * hdr) {
static int expandFifo(struct ourfd * fd, struct cpioHeader * hdr) {
struct stat sb;
- if (!access(hdr->path, X_OK)) {
- if (lstat(hdr->path, &sb))
- return CPIO_STAT_FAILED;
-
+ if (!lstat(hdr->path, &sb)) {
if (S_ISFIFO(sb.st_mode)) return 0;
if (unlink(hdr->path))
@@ -316,7 +324,9 @@ static int expandFifo(struct ourfd * fd, struct cpioHeader * hdr) {
}
static int expandDevice(struct ourfd * fd, struct cpioHeader * hdr) {
- if (!access(hdr->path, X_OK))
+ struct stat sb;
+
+ if (!lstat(hdr->path, &sb))
if (unlink(hdr->path))
return CPIO_UNLINK_FAILED;
@@ -327,7 +337,8 @@ static int expandDevice(struct ourfd * fd, struct cpioHeader * hdr) {
}
int cpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings,
- int numMappings, cpioCallback cb, char ** failedFile) {
+ int numMappings, cpioCallback cb, void * cbData,
+ char ** failedFile) {
struct cpioHeader ch;
struct ourfd fd;
int rc = 0;
@@ -335,6 +346,7 @@ int cpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings,
struct cpioFileMapping needle;
mode_t cpioMode;
int olderr;
+ struct cpioCallbackInfo cbInfo;
fd.fd = stream;
fd.pos = 0;
@@ -377,7 +389,7 @@ int cpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings,
if (!rc) {
if (S_ISREG(ch.mode))
- rc = expandRegular(&fd, &ch);
+ rc = expandRegular(&fd, &ch, cb, cbData);
else if (S_ISDIR(ch.mode))
rc = createDirectory(ch.path);
else if (S_ISLNK(ch.mode))
@@ -407,6 +419,15 @@ int cpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings,
}
padfd(&fd, 4);
+
+ if (!rc && cb) {
+ cbInfo.file = ch.path;
+ cbInfo.fileSize = ch.size;
+ cbInfo.fileComplete = ch.size;
+ cbInfo.bytesProcessed = fd.pos;
+ cb(&cbInfo, cbData);
+ }
+
free(ch.path);
} while (1 && !rc);
diff --git a/lib/cpio.h b/lib/cpio.h
index 2105d9ade..1f3b1e773 100644
--- a/lib/cpio.h
+++ b/lib/cpio.h
@@ -39,7 +39,14 @@ struct cpioFileMapping {
int mapFlags;
};
-typedef void (*cpioCallback)(char * filespec);
+struct cpioCallbackInfo {
+ char * file;
+ long fileSize; /* total file size */
+ long fileComplete; /* amount of file unpacked */
+ long bytesProcessed; /* bytes in archive read */
+};
+
+typedef void (*cpioCallback)(struct cpioCallbackInfo * filespec, void * data);
/* If no mappings are passed, this installs everything! If one is passed
it should be sorted according to cpioFileMapCmp() and only files included
@@ -49,7 +56,8 @@ typedef void (*cpioCallback)(char * filespec);
for the file type. The owner/group mappings are ignored for the nonroot
user. If *failedFile is non-NULL on return, it should be free()d. */
int cpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings,
- int numMappings, cpioCallback cb, char ** failedFile);
+ int numMappings, cpioCallback cb, void * cbData,
+ char ** failedFile);
/* This is designed to be qsort/bsearch compatible */
int cpioFileMapCmp(const void * a, const void * b);
diff --git a/lib/install.c b/lib/install.c
index a87cd8193..f4616d15d 100644
--- a/lib/install.c
+++ b/lib/install.c
@@ -30,6 +30,11 @@
enum instActions { UNKNOWN, CREATE, BACKUP, KEEP, SAVE, SKIP };
enum fileTypes { XDIR, BDEV, CDEV, SOCK, PIPE, REG, LINK } ;
+struct callbackInfo {
+ unsigned long archiveSize;
+ rpmNotifyFunction notify;
+};
+
struct fileMemory {
char ** md5s;
char ** links;
@@ -573,7 +578,11 @@ int rpmInstallPackage(char * rootdir, rpmdb db, int fd, char * location,
return 0;
}
-#define BLOCKSIZE 1024
+static void callback(struct cpioCallbackInfo * cpioInfo, void * data) {
+ struct callbackInfo * ourInfo = data;
+
+ ourInfo->notify(cpioInfo->bytesProcessed, ourInfo->archiveSize);
+}
/* NULL files means install all files */
static int installArchive(char * prefix, int fd, struct fileInfo * files,
@@ -583,6 +592,7 @@ static int installArchive(char * prefix, int fd, struct fileInfo * files,
int rc, i;
struct cpioFileMapping * map;
char * failedFile;
+ struct callbackInfo info;
if (!files) {
/* install all files */
@@ -592,6 +602,9 @@ static int installArchive(char * prefix, int fd, struct fileInfo * files,
return 0;
}
+ info.archiveSize = archiveSize;
+ info.notify = notify;
+
if (specFile) *specFile = NULL;
map = alloca(sizeof(*map) * fileCount);
@@ -611,18 +624,23 @@ static int installArchive(char * prefix, int fd, struct fileInfo * files,
qsort(map, fileCount, sizeof(*map), cpioFileMapCmp);
stream = gzdopen(fd, "r");
- rc = cpioInstallArchive(stream, map, fileCount, NULL, &failedFile);
+ rc = cpioInstallArchive(stream, map, fileCount,
+ (notify && archiveSize) ? callback : NULL,
+ &info, &failedFile);
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 on file %s: %d",
- failedFile, rc);
+ rpmError(RPMERR_CPIO, "unpacking of archive failed on file %s: %d: %s",
+ failedFile, rc, strerror(errno));
return 1;
}
- if (notify)
+ if (notify && archiveSize)
notify(archiveSize, archiveSize);
+ else if (notify) {
+ notify(100, 100);
+ }
return 0;
}