diff options
author | ewt <devnull@localhost> | 1997-05-06 15:27:46 +0000 |
---|---|---|
committer | ewt <devnull@localhost> | 1997-05-06 15:27:46 +0000 |
commit | 0a02b64c726bce0763e71ba393ad2740c2ecdd9f (patch) | |
tree | b8c61743bb8f4ea5ca43cc10b7c215fa326fa9ec | |
parent | 260850e9b840b6b745121a8c7c9fe8d70b116d7e (diff) | |
download | librpm-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.c | 51 | ||||
-rw-r--r-- | lib/cpio.h | 12 | ||||
-rw-r--r-- | lib/install.c | 28 |
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; } |