Understands source packages

CVS patchset: 264
CVS date: 1996/02/14 17:54:37
This commit is contained in:
root 1996-02-14 17:54:37 +00:00
parent 1ac992f934
commit 2a9f4dea65
2 changed files with 127 additions and 21 deletions

View File

@ -29,7 +29,8 @@ struct fileToInstall {
} ;
static int installArchive(char * prefix, int fd, struct fileToInstall * files,
int fileCount, notifyFunction notify);
int fileCount, notifyFunction notify,
char ** installArchive);
static int packageAlreadyInstalled(rpmdb db, char * name, char * version,
char * release, int flags);
static int setFileOwnerships(char * prefix, char ** fileList,
@ -44,6 +45,7 @@ static int instHandleSharedFiles(rpmdb db, int ignoreOffset, char ** fileList,
enum instActions * instActions,
char ** prefixedFileList, int flags);
static int fileCompare(const void * one, const void * two);
static int installSources(char * prefix, int fd);
/* 0 success */
/* 1 bad magic */
@ -72,6 +74,23 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
rc = pkgReadHeader(fd, &h, &isSource);
if (rc) return rc;
if (isSource) {
/* We deal with source packages pretty badly. They should end
up in the database, and we should be smarter about installing
them. Old source packages are broken though, and this hack
is the easiest way. It's to bad the notify stuff doesn't work
though */
message(MESS_DEBUG, "installing a source package\n");
if (flags & INSTALL_TEST) {
message(MESS_DEBUG, "stopping install as we're running --test\n");
return 0;
}
return installSources(prefix, fd);
}
/* we make a copy of the header here so we have one which we can add
entries to */
h2 = copyHeader(h);
@ -209,7 +228,7 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
}
/* the file pointer for fd is pointing at the cpio archive */
if (installArchive(prefix, fd, files, archiveFileCount, notify)) {
if (installArchive(prefix, fd, files, archiveFileCount, notify, NULL)) {
freeHeader(h);
free(fileList);
return 2;
@ -259,7 +278,8 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
#define BLOCKSIZE 1024
static int installArchive(char * prefix, int fd, struct fileToInstall * files,
int fileCount, notifyFunction notify) {
int fileCount, notifyFunction notify,
char ** specFile) {
gzFile stream;
char buf[BLOCKSIZE];
pid_t child;
@ -281,10 +301,13 @@ static int installArchive(char * prefix, int fd, struct fileToInstall * files,
struct fileToInstall * file;
char * chptr;
char ** args;
int len;
/* fd should be a gzipped cpio archive */
needSecondPipe = (notify != NULL);
needSecondPipe = (notify != NULL) || specFile;
if (specFile) *specFile = NULL;
if (access("/bin/cpio", X_OK)) {
if (access("/usr/bin/cpio", X_OK)) {
@ -307,6 +330,8 @@ static int installArchive(char * prefix, int fd, struct fileToInstall * files,
if (needSecondPipe)
args[i++] = "--verbose";
/* note - if fileCount == 0, all files get installed */
for (j = 0; j < fileCount; j++)
args[i++] = files[j].fileName;
@ -368,11 +393,27 @@ static int installArchive(char * prefix, int fd, struct fileToInstall * files,
message(MESS_DEBUG, "file \"%s\" complete\n", line);
file = bsearch(&fileInstalled, files, fileCount,
sizeof(struct fileToInstall), fileCompare);
if (file) {
sizeInstalled += file->size;
notify(sizeInstalled, totalSize);
if (notify) {
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;
@ -773,3 +814,57 @@ static int fileCompare(const void * one, const void * two) {
return strcmp(((struct fileToInstall *) one)->fileName,
((struct fileToInstall *) two)->fileName);
}
static int installSources(char * prefix, int fd) {
char * specFile;
char * sourceDir, * specDir;
char * realSourceDir, * realSpecDir;
char * instSpecFile, * correctSpecFile;
sourceDir = getVar(RPMVAR_SOURCEDIR);
specDir = getVar(RPMVAR_SPECDIR);
realSourceDir = alloca(strlen(prefix) + strlen(sourceDir) + 2);
strcpy(realSourceDir, prefix);
strcat(realSourceDir, "/");
strcat(realSourceDir, sourceDir);
realSpecDir = alloca(strlen(prefix) + strlen(specDir) + 2);
strcpy(realSpecDir, prefix);
strcat(realSpecDir, "/");
strcat(realSpecDir, specDir);
message(MESS_DEBUG, "sources in: %s\n", realSourceDir);
message(MESS_DEBUG, "spec file in: %s\n", realSpecDir);
if (installArchive(realSourceDir, fd, NULL, 0, NULL, &specFile)) {
return 1;
}
if (!specFile) {
error(RPMERR_NOSPEC, "source package contains no .spec file\n");
return 1;
}
/* This logic doesn't work is realSpecDir and realSourceDir are on
different filesystems XXX */
instSpecFile = alloca(strlen(realSourceDir) + strlen(specFile) + 2);
strcpy(instSpecFile, realSourceDir);
strcat(instSpecFile, "/");
strcat(instSpecFile, specFile);
correctSpecFile = alloca(strlen(realSpecDir) + strlen(specFile) + 2);
strcpy(correctSpecFile, realSpecDir);
strcat(correctSpecFile, "/");
strcat(correctSpecFile, specFile);
message(MESS_DEBUG, "renaming %s to %s\n", instSpecFile, correctSpecFile);
if (rename(instSpecFile, correctSpecFile)) {
error(RPMERR_RENAME, "rename of %s to %s failed: %s\n",
instSpecFile, correctSpecFile, strerror(errno));
return 1;
}
return 0;
}

View File

@ -1,4 +1,5 @@
#include <fcntl.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
@ -19,10 +20,9 @@ static int readOldHeader(int fd, Header * hdr, int * isSource);
/* 2 = error */
int pkgReadHeader(int fd, Header * hdr, int * isSource) {
struct rpmlead lead;
struct oldrpmlead * oldLead = (struct oldrpmlead *) &lead;
if (read(fd, &lead, sizeof(lead)) != sizeof(lead)) {
error(RPMERR_READERROR, "read failed: %s (%d)", strerror(errno),
errno);
if (readLead(fd, &lead)) {
return 2;
}
@ -34,16 +34,27 @@ int pkgReadHeader(int fd, Header * hdr, int * isSource) {
*isSource = lead.type == RPMLEAD_SOURCE;
if (lead.major == 1) {
readOldHeader(fd, hdr, isSource);
} else if (lead.major == 2) {
*hdr = readHeader(fd);
if (! *hdr) return 2;
if (*isSource) {
if (lead.major == 1) {
oldLead->archiveOffset = ntohl(oldLead->archiveOffset);
lseek(fd, oldLead->archiveOffset, SEEK_SET);
} else {
*hdr = readHeader(fd);
if (! *hdr) return 2;
freeHeader(*hdr);
}
} else {
error(RPMERR_NEWPACKAGE, "only packages with major numbers <= 2 are"
" supported by this version of RPM");
return 2;
}
if (lead.major == 1) {
readOldHeader(fd, hdr, isSource);
} else if (lead.major == 2) {
*hdr = readHeader(fd);
if (! *hdr) return 2;
} else {
error(RPMERR_NEWPACKAGE, "only packages with major numbers <= 2 are"
" supported by this version of RPM");
return 2;
}
}
return 0;
}