1998-07-26 05:00:26 +08:00
|
|
|
#include "system.h"
|
1997-01-18 00:22:57 +08:00
|
|
|
|
|
|
|
#include <signal.h>
|
1998-07-31 06:09:42 +08:00
|
|
|
|
|
|
|
#include "rpmlib.h"
|
1996-01-09 03:31:44 +08:00
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
#include "cpio.h"
|
1996-01-09 03:31:44 +08:00
|
|
|
#include "install.h"
|
1996-01-30 03:37:59 +08:00
|
|
|
#include "md5.h"
|
1996-02-15 06:20:08 +08:00
|
|
|
#include "misc.h"
|
1996-09-17 06:28:56 +08:00
|
|
|
#include "rpmdb.h"
|
1999-01-03 11:13:50 +08:00
|
|
|
#include "rpmmacro.h"
|
1996-01-09 03:31:44 +08:00
|
|
|
|
1997-05-06 23:27:46 +08:00
|
|
|
struct callbackInfo {
|
|
|
|
unsigned long archiveSize;
|
1999-01-12 11:11:25 +08:00
|
|
|
rpmCallbackFunction notify;
|
1997-05-07 02:19:19 +08:00
|
|
|
char ** specFilePtr;
|
1998-12-17 05:58:53 +08:00
|
|
|
Header h;
|
|
|
|
void * notifyData;
|
1999-01-12 11:11:25 +08:00
|
|
|
const void * pkgKey;
|
1997-05-06 23:27:46 +08:00
|
|
|
};
|
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
struct fileMemory {
|
|
|
|
char ** md5s;
|
|
|
|
char ** links;
|
|
|
|
char ** names;
|
1998-01-30 03:39:12 +08:00
|
|
|
char ** cpioNames;
|
1997-05-06 04:46:58 +08:00
|
|
|
struct fileInfo * files;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct fileInfo {
|
|
|
|
char * cpioPath;
|
|
|
|
char * relativePath; /* relative to root */
|
|
|
|
char * md5;
|
|
|
|
char * link;
|
|
|
|
uid_t uid;
|
|
|
|
gid_t gid;
|
|
|
|
uint_32 flags;
|
|
|
|
uint_32 size;
|
|
|
|
mode_t mode;
|
|
|
|
char state;
|
1999-01-05 00:42:15 +08:00
|
|
|
enum fileActions action;
|
1997-05-06 04:46:58 +08:00
|
|
|
int install;
|
1996-01-23 05:13:12 +08:00
|
|
|
} ;
|
|
|
|
|
1998-11-19 05:41:05 +08:00
|
|
|
static int installArchive(FD_t fd, struct fileInfo * files,
|
1999-01-12 11:11:25 +08:00
|
|
|
int fileCount, rpmCallbackFunction notify,
|
|
|
|
void * notifydb, const void * pkgKey, Header h,
|
1997-05-06 04:46:58 +08:00
|
|
|
char ** specFile, int archiveSize);
|
1999-01-07 01:33:50 +08:00
|
|
|
static int installSources(Header h, const char * rootdir, FD_t fd,
|
1999-01-12 11:11:25 +08:00
|
|
|
const char ** specFilePtr, rpmCallbackFunction notify,
|
1999-01-07 12:07:31 +08:00
|
|
|
void * notifyData);
|
1998-01-29 00:49:43 +08:00
|
|
|
static int assembleFileList(Header h, struct fileMemory * mem,
|
|
|
|
int * fileCountPtr, struct fileInfo ** filesPtr,
|
1999-01-05 00:42:15 +08:00
|
|
|
int stripPrefixLength, enum fileActions * actions);
|
1997-10-29 04:59:16 +08:00
|
|
|
static void setFileOwners(Header h, struct fileInfo * files, int fileCount);
|
1997-05-06 04:46:58 +08:00
|
|
|
static void freeFileMemory(struct fileMemory fileMem);
|
1998-01-29 00:49:43 +08:00
|
|
|
static void trimChangelog(Header h);
|
1999-01-08 01:05:02 +08:00
|
|
|
static int markReplacedFiles(rpmdb db, struct sharedFileInfo * replList);
|
1996-02-15 04:09:14 +08:00
|
|
|
|
|
|
|
/* 0 success */
|
|
|
|
/* 1 bad magic */
|
|
|
|
/* 2 error */
|
1999-01-07 12:07:31 +08:00
|
|
|
int rpmInstallSourcePackage(const char * rootdir, FD_t fd,
|
1999-01-12 11:11:25 +08:00
|
|
|
const char ** specFile, rpmCallbackFunction notify,
|
1999-01-07 12:07:31 +08:00
|
|
|
void * notifyData, char ** cookie) {
|
1996-02-15 04:09:14 +08:00
|
|
|
int rc, isSource;
|
|
|
|
Header h;
|
1996-08-29 12:16:07 +08:00
|
|
|
int major, minor;
|
1996-02-15 04:09:14 +08:00
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
rc = rpmReadPackageHeader(fd, &h, &isSource, &major, &minor);
|
1996-02-15 04:09:14 +08:00
|
|
|
if (rc) return rc;
|
|
|
|
|
|
|
|
if (!isSource) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_NOTSRPM, _("source package expected, binary found"));
|
1996-02-15 04:09:14 +08:00
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
1996-08-29 12:16:07 +08:00
|
|
|
if (major == 1) {
|
|
|
|
notify = NULL;
|
|
|
|
h = NULL;
|
|
|
|
}
|
1996-03-30 03:40:08 +08:00
|
|
|
|
1997-10-29 23:53:35 +08:00
|
|
|
if (cookie) {
|
|
|
|
*cookie = NULL;
|
|
|
|
if (h && headerGetEntry(h, RPMTAG_COOKIE, NULL, (void *) cookie,
|
|
|
|
NULL)) {
|
|
|
|
*cookie = strdup(*cookie);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-01-07 12:07:31 +08:00
|
|
|
rc = installSources(h, rootdir, fd, specFile, notify, notifyData);
|
1998-11-17 05:40:28 +08:00
|
|
|
if (h != NULL) headerFree(h);
|
1996-08-29 12:16:07 +08:00
|
|
|
|
|
|
|
return rc;
|
1996-02-15 04:09:14 +08:00
|
|
|
}
|
1996-01-09 03:31:44 +08:00
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
static void freeFileMemory(struct fileMemory fileMem) {
|
|
|
|
free(fileMem.files);
|
|
|
|
free(fileMem.md5s);
|
|
|
|
free(fileMem.links);
|
|
|
|
free(fileMem.names);
|
1998-01-30 03:39:12 +08:00
|
|
|
free(fileMem.cpioNames);
|
1997-05-06 04:46:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* files should not be preallocated */
|
1998-01-29 00:49:43 +08:00
|
|
|
static int assembleFileList(Header h, struct fileMemory * mem,
|
1997-05-06 04:46:58 +08:00
|
|
|
int * fileCountPtr, struct fileInfo ** filesPtr,
|
1999-01-01 03:16:12 +08:00
|
|
|
int stripPrefixLength,
|
1999-01-05 00:42:15 +08:00
|
|
|
enum fileActions * actions) {
|
1997-05-06 04:46:58 +08:00
|
|
|
uint_32 * fileFlags;
|
|
|
|
uint_32 * fileSizes;
|
|
|
|
uint_16 * fileModes;
|
|
|
|
struct fileInfo * files;
|
|
|
|
struct fileInfo * file;
|
|
|
|
int fileCount;
|
1998-12-17 05:58:53 +08:00
|
|
|
int i;
|
1998-03-24 00:34:38 +08:00
|
|
|
char ** fileLangs;
|
1998-12-17 05:58:53 +08:00
|
|
|
char * chptr;
|
1998-03-24 00:34:38 +08:00
|
|
|
char ** languages, ** lang;
|
1998-01-29 00:49:43 +08:00
|
|
|
|
1999-01-19 11:02:45 +08:00
|
|
|
if (!headerGetEntry(h, RPMTAG_FILENAMES, NULL, (void **) &mem->names,
|
1998-12-17 05:58:53 +08:00
|
|
|
fileCountPtr))
|
1999-01-19 11:02:45 +08:00
|
|
|
return 0;
|
|
|
|
|
1998-12-31 07:03:18 +08:00
|
|
|
if (!headerGetEntry(h, RPMTAG_ORIGFILENAMES, NULL,
|
|
|
|
(void **) &mem->cpioNames, NULL))
|
|
|
|
headerGetEntry(h, RPMTAG_FILENAMES, NULL, (void **) &mem->cpioNames,
|
|
|
|
fileCountPtr);
|
1999-01-19 11:02:45 +08:00
|
|
|
headerRemoveEntry(h, RPMTAG_ORIGFILENAMES);
|
1997-05-06 04:46:58 +08:00
|
|
|
|
|
|
|
fileCount = *fileCountPtr;
|
1998-01-29 00:49:43 +08:00
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
files = *filesPtr = mem->files = malloc(sizeof(*mem->files) * fileCount);
|
|
|
|
|
|
|
|
headerGetEntry(h, RPMTAG_FILEMD5S, NULL, (void **) &mem->md5s, 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);
|
1998-05-06 07:12:17 +08:00
|
|
|
if (!headerGetEntry(h, RPMTAG_FILELANGS, NULL, (void **) &fileLangs, NULL))
|
|
|
|
fileLangs = NULL;
|
1998-03-24 00:34:38 +08:00
|
|
|
|
|
|
|
if ((chptr = getenv("LINGUAS"))) {
|
|
|
|
languages = splitString(chptr, strlen(chptr), ':');
|
|
|
|
} else
|
|
|
|
languages = NULL;
|
1997-05-06 04:46:58 +08:00
|
|
|
|
|
|
|
for (i = 0, file = files; i < fileCount; i++, file++) {
|
|
|
|
file->state = RPMFILE_STATE_NORMAL;
|
1999-01-01 03:16:12 +08:00
|
|
|
if (actions)
|
|
|
|
file->action = actions[i];
|
|
|
|
else
|
|
|
|
file->action = UNKNOWN;
|
1997-05-06 04:46:58 +08:00
|
|
|
file->install = 1;
|
|
|
|
|
|
|
|
file->relativePath = mem->names[i];
|
1998-01-30 03:39:12 +08:00
|
|
|
file->cpioPath = mem->cpioNames[i] + stripPrefixLength;
|
1997-05-06 04:46:58 +08:00
|
|
|
file->mode = fileModes[i];
|
|
|
|
file->md5 = mem->md5s[i];
|
|
|
|
file->link = mem->links[i];
|
|
|
|
file->size = fileSizes[i];
|
|
|
|
file->flags = fileFlags[i];
|
1998-03-24 00:34:38 +08:00
|
|
|
|
1999-01-01 03:16:12 +08:00
|
|
|
/* FIXME: move this logic someplace else */
|
1998-03-24 00:34:38 +08:00
|
|
|
if (fileLangs && languages && *fileLangs[i]) {
|
|
|
|
for (lang = languages; *lang; lang++)
|
|
|
|
if (!strcmp(*lang, fileLangs[i])) break;
|
|
|
|
if (!*lang) {
|
|
|
|
file->install = 0;
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("not installing %s -- linguas\n"),
|
1998-03-24 00:34:38 +08:00
|
|
|
file->relativePath);
|
|
|
|
}
|
|
|
|
}
|
1999-01-01 03:16:12 +08:00
|
|
|
|
|
|
|
rpmMessage(RPMMESS_DEBUG, _(" file: %s action: %s\n"),
|
1999-01-05 00:42:15 +08:00
|
|
|
file->relativePath, fileActionString(file->action));
|
1997-10-29 04:59:16 +08:00
|
|
|
}
|
1998-01-29 00:49:43 +08:00
|
|
|
|
1998-05-06 07:12:17 +08:00
|
|
|
if (fileLangs) free(fileLangs);
|
|
|
|
if (languages) freeSplitString(languages);
|
|
|
|
|
1998-01-29 00:49:43 +08:00
|
|
|
return 0;
|
1997-10-29 04:59:16 +08:00
|
|
|
}
|
1997-05-06 04:46:58 +08:00
|
|
|
|
1997-10-29 04:59:16 +08:00
|
|
|
static void setFileOwners(Header h, struct fileInfo * files, int fileCount) {
|
|
|
|
char ** fileOwners;
|
|
|
|
char ** fileGroups;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
headerGetEntry(h, RPMTAG_FILEUSERNAME, NULL, (void **) &fileOwners, NULL);
|
|
|
|
headerGetEntry(h, RPMTAG_FILEGROUPNAME, NULL, (void **) &fileGroups, NULL);
|
|
|
|
|
|
|
|
for (i = 0; i < fileCount; i++) {
|
1997-05-06 04:46:58 +08:00
|
|
|
if (unameToUid(fileOwners[i], &files[i].uid)) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_NOUSER, _("user %s does not exist - using root"),
|
1997-05-06 04:46:58 +08:00
|
|
|
fileOwners[i]);
|
|
|
|
files[i].uid = 0;
|
|
|
|
/* turn off the suid bit */
|
|
|
|
files[i].mode &= ~S_ISUID;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gnameToGid(fileGroups[i], &files[i].gid)) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_NOGROUP, _("group %s does not exist - using root"),
|
1997-05-06 04:46:58 +08:00
|
|
|
fileGroups[i]);
|
|
|
|
files[i].gid = 0;
|
|
|
|
/* turn off the sgid bit */
|
|
|
|
files[i].mode &= ~S_ISGID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
free(fileOwners);
|
|
|
|
free(fileGroups);
|
|
|
|
}
|
|
|
|
|
1998-01-29 00:49:43 +08:00
|
|
|
static void trimChangelog(Header h) {
|
|
|
|
int * times;
|
|
|
|
char ** names, ** texts;
|
|
|
|
long numToKeep;
|
|
|
|
char * buf, * end;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
buf = rpmGetVar(RPMVAR_INSTCHANGELOG);
|
|
|
|
if (!buf) return;
|
|
|
|
|
|
|
|
numToKeep = strtol(buf, &end, 10);
|
|
|
|
if (*end) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_RPMRC, _("instchangelog value in rpmrc should be a "
|
|
|
|
"number, but isn't"));
|
1998-01-29 00:49:43 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (numToKeep < 0) return;
|
|
|
|
|
|
|
|
if (!numToKeep) {
|
|
|
|
headerRemoveEntry(h, RPMTAG_CHANGELOGTIME);
|
|
|
|
headerRemoveEntry(h, RPMTAG_CHANGELOGNAME);
|
|
|
|
headerRemoveEntry(h, RPMTAG_CHANGELOGTEXT);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!headerGetEntry(h, RPMTAG_CHANGELOGTIME, NULL, (void **) ×,
|
|
|
|
&count) ||
|
|
|
|
count < numToKeep) return;
|
|
|
|
headerGetEntry(h, RPMTAG_CHANGELOGNAME, NULL, (void **) &names, &count);
|
|
|
|
headerGetEntry(h, RPMTAG_CHANGELOGTEXT, NULL, (void **) &texts, &count);
|
|
|
|
|
|
|
|
headerModifyEntry(h, RPMTAG_CHANGELOGTIME, RPM_INT32_TYPE, times,
|
|
|
|
numToKeep);
|
|
|
|
headerModifyEntry(h, RPMTAG_CHANGELOGNAME, RPM_STRING_ARRAY_TYPE, names,
|
|
|
|
numToKeep);
|
|
|
|
headerModifyEntry(h, RPMTAG_CHANGELOGTEXT, RPM_STRING_ARRAY_TYPE, texts,
|
|
|
|
numToKeep);
|
1998-05-06 07:12:17 +08:00
|
|
|
|
|
|
|
free(names);
|
|
|
|
free(texts);
|
1998-01-29 00:49:43 +08:00
|
|
|
}
|
|
|
|
|
1996-01-09 03:31:44 +08:00
|
|
|
/* 0 success */
|
|
|
|
/* 1 bad magic */
|
|
|
|
/* 2 error */
|
1999-01-07 01:33:50 +08:00
|
|
|
int installBinaryPackage(const char * rootdir, rpmdb db, FD_t fd, Header h,
|
1999-01-12 11:11:25 +08:00
|
|
|
int flags, rpmCallbackFunction notify,
|
|
|
|
void * notifyData, const void * pkgKey,
|
|
|
|
enum fileActions * actions,
|
1999-01-08 01:05:02 +08:00
|
|
|
struct sharedFileInfo * sharedList) {
|
1998-12-17 05:58:53 +08:00
|
|
|
int rc;
|
1996-01-15 03:32:17 +08:00
|
|
|
char * name, * version, * release;
|
1996-08-29 12:16:07 +08:00
|
|
|
int fileCount, type, count;
|
1997-05-06 04:46:58 +08:00
|
|
|
struct fileInfo * files;
|
1996-01-30 03:37:59 +08:00
|
|
|
int_32 installTime;
|
1997-05-06 04:46:58 +08:00
|
|
|
char * fileStates;
|
1999-01-03 11:13:50 +08:00
|
|
|
int i;
|
1996-01-30 03:37:59 +08:00
|
|
|
int installFile = 0;
|
1996-02-15 05:26:21 +08:00
|
|
|
int otherOffset = 0;
|
1996-01-30 03:37:59 +08:00
|
|
|
char * ext = NULL, * newpath;
|
1996-10-21 10:17:39 +08:00
|
|
|
char * defaultPrefix;
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiIndexSet matches;
|
1996-06-28 22:38:12 +08:00
|
|
|
int scriptArg;
|
1998-01-29 00:49:43 +08:00
|
|
|
int stripSize = 1; /* strip at least first / for cpio */
|
1996-08-29 12:16:07 +08:00
|
|
|
uint_32 * archiveSizePtr;
|
1997-05-06 04:46:58 +08:00
|
|
|
struct fileMemory fileMem;
|
|
|
|
int freeFileMem = 0;
|
1997-07-18 03:18:15 +08:00
|
|
|
char * currDir = NULL, * tmpptr;
|
1996-01-09 03:31:44 +08:00
|
|
|
|
1997-07-24 23:15:48 +08:00
|
|
|
if (flags & RPMINSTALL_JUSTDB)
|
|
|
|
flags |= RPMINSTALL_NOSCRIPTS;
|
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &fileCount);
|
|
|
|
headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &fileCount);
|
|
|
|
headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &fileCount);
|
1996-07-11 23:48:21 +08:00
|
|
|
|
1996-10-21 10:17:39 +08:00
|
|
|
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("package: %s-%s-%s files test = %d\n"),
|
1996-11-19 02:02:36 +08:00
|
|
|
name, version, release, flags & RPMINSTALL_TEST);
|
1996-01-15 03:32:17 +08:00
|
|
|
|
1997-09-17 07:16:21 +08:00
|
|
|
rc = rpmdbFindPackage(db, name, &matches);
|
|
|
|
if (rc == -1) return 2;
|
|
|
|
if (rc) {
|
|
|
|
scriptArg = 1;
|
|
|
|
} else {
|
1998-11-20 02:10:28 +08:00
|
|
|
scriptArg = dbiIndexSetCount(matches) + 1;
|
1997-09-17 07:16:21 +08:00
|
|
|
}
|
|
|
|
|
1997-07-16 09:44:27 +08:00
|
|
|
if (rootdir) {
|
1997-08-24 21:00:51 +08:00
|
|
|
/* this loads all of the name services libraries, in case we
|
|
|
|
don't have access to them in the chroot() */
|
1998-11-17 05:40:28 +08:00
|
|
|
(void)getpwnam("root");
|
1997-08-24 21:00:51 +08:00
|
|
|
endpwent();
|
|
|
|
|
1999-01-08 11:11:54 +08:00
|
|
|
tmpptr = currentDirectory();
|
|
|
|
currDir = alloca(strlen(tmpptr) + 1);
|
|
|
|
strcpy(currDir, tmpptr);
|
|
|
|
free(tmpptr);
|
|
|
|
|
1997-07-16 09:44:27 +08:00
|
|
|
chdir("/");
|
|
|
|
chroot(rootdir);
|
|
|
|
}
|
|
|
|
|
1997-07-24 23:15:48 +08:00
|
|
|
if (!(flags & RPMINSTALL_JUSTDB) && headerIsEntry(h, RPMTAG_FILENAMES)) {
|
1998-12-31 07:03:18 +08:00
|
|
|
/* old format relocateable packages need the entire default
|
|
|
|
prefix stripped to form the cpio list, while all other packages
|
|
|
|
need the leading / stripped */
|
1998-01-29 00:49:43 +08:00
|
|
|
if (headerGetEntry(h, RPMTAG_DEFAULTPREFIX, NULL, (void *)
|
|
|
|
&defaultPrefix, NULL)) {
|
1998-01-30 03:39:12 +08:00
|
|
|
stripSize = strlen(defaultPrefix) + 1;
|
1998-01-29 00:49:43 +08:00
|
|
|
} else {
|
|
|
|
stripSize = 1;
|
|
|
|
}
|
|
|
|
|
1999-01-01 03:16:12 +08:00
|
|
|
if (assembleFileList(h, &fileMem, &fileCount, &files, stripSize,
|
|
|
|
actions)) {
|
1998-01-29 00:49:43 +08:00
|
|
|
if (rootdir) {
|
|
|
|
chroot(".");
|
|
|
|
chdir(currDir);
|
|
|
|
}
|
1998-02-03 23:21:47 +08:00
|
|
|
return 2;
|
1998-01-29 00:49:43 +08:00
|
|
|
}
|
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
freeFileMem = 1;
|
|
|
|
} else {
|
|
|
|
files = NULL;
|
1996-01-23 05:13:12 +08:00
|
|
|
}
|
1996-01-15 03:32:17 +08:00
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
if (flags & RPMINSTALL_TEST) {
|
1997-07-16 09:44:27 +08:00
|
|
|
if (rootdir) {
|
|
|
|
chroot(".");
|
1997-07-18 03:18:15 +08:00
|
|
|
chdir(currDir);
|
1997-07-16 09:44:27 +08:00
|
|
|
}
|
|
|
|
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("stopping install as we're running --test\n"));
|
1997-05-06 04:46:58 +08:00
|
|
|
if (freeFileMem) freeFileMemory(fileMem);
|
1996-01-15 03:32:17 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("running preinstall script (if any)\n"));
|
1998-03-28 00:46:39 +08:00
|
|
|
if (runInstScript("/", h, RPMTAG_PREIN, RPMTAG_PREINPROG, scriptArg,
|
|
|
|
flags & RPMINSTALL_NOSCRIPTS, 0)) {
|
1997-05-06 04:46:58 +08:00
|
|
|
if (freeFileMem) freeFileMemory(fileMem);
|
1997-07-16 09:44:27 +08:00
|
|
|
|
|
|
|
if (rootdir) {
|
|
|
|
chroot(".");
|
1997-07-18 03:18:15 +08:00
|
|
|
chdir(currDir);
|
1997-07-16 09:44:27 +08:00
|
|
|
}
|
|
|
|
|
1996-01-09 03:31:44 +08:00
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
if (files) {
|
1997-10-29 04:59:16 +08:00
|
|
|
setFileOwners(h, files, fileCount);
|
|
|
|
|
1996-01-23 05:13:12 +08:00
|
|
|
for (i = 0; i < fileCount; i++) {
|
1997-05-06 04:46:58 +08:00
|
|
|
switch (files[i].action) {
|
1996-01-30 03:37:59 +08:00
|
|
|
case BACKUP:
|
|
|
|
ext = ".rpmorig";
|
|
|
|
installFile = 1;
|
|
|
|
break;
|
|
|
|
|
1997-06-19 04:45:17 +08:00
|
|
|
case ALTNAME:
|
|
|
|
ext = NULL;
|
|
|
|
installFile = 1;
|
|
|
|
|
1997-07-16 09:44:27 +08:00
|
|
|
newpath = alloca(strlen(files[i].relativePath) + 20);
|
|
|
|
strcpy(newpath, files[i].relativePath);
|
1997-06-19 04:45:17 +08:00
|
|
|
strcat(newpath, ".rpmnew");
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMMESS_ALTNAME, _("warning: %s created as %s"),
|
1997-07-16 09:44:27 +08:00
|
|
|
files[i].relativePath, newpath);
|
|
|
|
files[i].relativePath = newpath;
|
1997-06-19 04:45:17 +08:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
1996-01-30 03:37:59 +08:00
|
|
|
case SAVE:
|
|
|
|
ext = ".rpmsave";
|
|
|
|
installFile = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CREATE:
|
|
|
|
installFile = 1;
|
|
|
|
ext = NULL;
|
|
|
|
break;
|
|
|
|
|
1996-03-30 04:52:03 +08:00
|
|
|
case SKIP:
|
|
|
|
installFile = 0;
|
1996-01-30 03:37:59 +08:00
|
|
|
ext = NULL;
|
|
|
|
break;
|
1997-05-06 04:46:58 +08:00
|
|
|
|
1999-01-20 00:24:43 +08:00
|
|
|
case SKIPNSTATE:
|
|
|
|
installFile = 0;
|
|
|
|
ext = NULL;
|
|
|
|
files[i].state = RPMFILE_STATE_NOTINSTALLED;
|
|
|
|
break;
|
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
case UNKNOWN:
|
1999-01-05 00:42:15 +08:00
|
|
|
case REMOVE:
|
1997-05-06 04:46:58 +08:00
|
|
|
break;
|
1996-01-30 03:37:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ext) {
|
1997-07-16 09:44:27 +08:00
|
|
|
newpath = alloca(strlen(files[i].relativePath) + 20);
|
|
|
|
strcpy(newpath, files[i].relativePath);
|
1996-01-30 03:37:59 +08:00
|
|
|
strcat(newpath, ext);
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMMESS_BACKUP, _("warning: %s saved as %s"),
|
1997-07-16 09:44:27 +08:00
|
|
|
files[i].relativePath, newpath);
|
1996-01-30 03:37:59 +08:00
|
|
|
|
1997-07-16 09:44:27 +08:00
|
|
|
if (rename(files[i].relativePath, newpath)) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s"),
|
1997-07-16 09:44:27 +08:00
|
|
|
files[i].relativePath, newpath, strerror(errno));
|
1997-05-06 04:46:58 +08:00
|
|
|
if (freeFileMem) freeFileMemory(fileMem);
|
1997-07-16 09:44:27 +08:00
|
|
|
|
|
|
|
if (rootdir) {
|
|
|
|
chroot(".");
|
1997-07-18 03:18:15 +08:00
|
|
|
chdir(currDir);
|
1997-07-16 09:44:27 +08:00
|
|
|
}
|
|
|
|
|
1996-04-16 05:09:40 +08:00
|
|
|
return 2;
|
1996-01-30 03:37:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
if (!installFile) {
|
|
|
|
files[i].install = 0;
|
1996-01-30 03:37:59 +08:00
|
|
|
}
|
1996-01-23 05:13:12 +08:00
|
|
|
}
|
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, &type,
|
|
|
|
(void *) &archiveSizePtr, &count))
|
1996-08-29 12:16:07 +08:00
|
|
|
archiveSizePtr = NULL;
|
|
|
|
|
1998-12-17 05:58:53 +08:00
|
|
|
if (notify) {
|
1999-01-12 11:11:25 +08:00
|
|
|
notify(h, RPMCALLBACK_INST_START, 0, 0, pkgKey, notifyData);
|
1997-02-12 13:05:13 +08:00
|
|
|
}
|
|
|
|
|
1996-01-15 03:32:17 +08:00
|
|
|
/* the file pointer for fd is pointing at the cpio archive */
|
1999-01-12 11:11:25 +08:00
|
|
|
if (installArchive(fd, files, fileCount, notify, notifyData, pkgKey, h,
|
1997-05-06 04:46:58 +08:00
|
|
|
NULL, archiveSizePtr ? *archiveSizePtr : 0)) {
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(h);
|
1997-05-06 04:46:58 +08:00
|
|
|
if (freeFileMem) freeFileMemory(fileMem);
|
1997-07-16 09:44:27 +08:00
|
|
|
|
|
|
|
if (rootdir) {
|
|
|
|
chroot(".");
|
1997-07-18 03:18:15 +08:00
|
|
|
chdir(currDir);
|
1997-07-16 09:44:27 +08:00
|
|
|
}
|
|
|
|
|
1996-01-15 03:32:17 +08:00
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
1998-05-26 21:45:16 +08:00
|
|
|
fileStates = malloc(sizeof(*fileStates) * fileCount);
|
|
|
|
for (i = 0; i < fileCount; i++)
|
|
|
|
fileStates[i] = files[i].state;
|
|
|
|
|
|
|
|
headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStates,
|
|
|
|
fileCount);
|
1996-02-16 05:08:48 +08:00
|
|
|
|
1998-05-26 21:45:16 +08:00
|
|
|
free(fileStates);
|
|
|
|
if (freeFileMem) freeFileMemory(fileMem);
|
|
|
|
} else if (flags & RPMINSTALL_JUSTDB) {
|
|
|
|
char ** fileNames;
|
|
|
|
|
|
|
|
if (headerGetEntry(h, RPMTAG_FILENAMES, NULL, (void **) &fileNames,
|
|
|
|
&fileCount)) {
|
|
|
|
fileStates = malloc(sizeof(*fileStates) * fileCount);
|
1998-06-12 04:02:29 +08:00
|
|
|
memset(fileStates, RPMFILE_STATE_NORMAL, fileCount);
|
1997-05-06 04:46:58 +08:00
|
|
|
headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStates,
|
|
|
|
fileCount);
|
|
|
|
free(fileStates);
|
|
|
|
}
|
1996-01-09 03:31:44 +08:00
|
|
|
}
|
|
|
|
|
1998-05-26 21:45:16 +08:00
|
|
|
installTime = time(NULL);
|
|
|
|
headerAddEntry(h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE, &installTime, 1);
|
|
|
|
|
1997-07-16 09:44:27 +08:00
|
|
|
if (rootdir) {
|
|
|
|
chroot(".");
|
1997-07-18 03:18:15 +08:00
|
|
|
chdir(currDir);
|
1997-07-16 09:44:27 +08:00
|
|
|
}
|
|
|
|
|
1998-01-29 00:49:43 +08:00
|
|
|
trimChangelog(h);
|
|
|
|
|
1996-02-15 05:26:21 +08:00
|
|
|
/* if this package has already been installed, remove it from the database
|
|
|
|
before adding the new one */
|
|
|
|
if (otherOffset) {
|
|
|
|
rpmdbRemove(db, otherOffset, 1);
|
|
|
|
}
|
|
|
|
|
1996-01-09 03:31:44 +08:00
|
|
|
if (rpmdbAdd(db, h)) {
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(h);
|
1996-01-09 03:31:44 +08:00
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("running postinstall script (if any)\n"));
|
1996-01-30 03:37:59 +08:00
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
if (runInstScript(rootdir, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg,
|
|
|
|
flags & RPMINSTALL_NOSCRIPTS, 0)) {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
1998-07-01 02:51:44 +08:00
|
|
|
if (!(flags & RPMINSTALL_NOTRIGGERS)) {
|
|
|
|
/* Run triggers this package sets off */
|
|
|
|
if (runTriggers(rootdir, db, RPMSENSE_TRIGGERIN, h, 0)) {
|
|
|
|
return 2;
|
|
|
|
}
|
1998-03-28 00:46:39 +08:00
|
|
|
|
1998-07-01 02:51:44 +08:00
|
|
|
/* Run triggers in this package which are set off by other things in
|
|
|
|
the database. */
|
|
|
|
if (runImmedTriggers(rootdir, db, RPMSENSE_TRIGGERIN, h, 0)) {
|
|
|
|
return 2;
|
|
|
|
}
|
1996-01-30 03:37:59 +08:00
|
|
|
}
|
|
|
|
|
1999-01-08 01:05:02 +08:00
|
|
|
if (sharedList)
|
|
|
|
markReplacedFiles(db, sharedList);
|
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(h);
|
1996-08-31 03:17:33 +08:00
|
|
|
|
1996-01-09 03:31:44 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1997-05-06 23:27:46 +08:00
|
|
|
static void callback(struct cpioCallbackInfo * cpioInfo, void * data) {
|
|
|
|
struct callbackInfo * ourInfo = data;
|
1997-05-07 02:19:19 +08:00
|
|
|
char * chptr;
|
1997-05-06 23:27:46 +08:00
|
|
|
|
1997-05-07 02:19:19 +08:00
|
|
|
if (ourInfo->notify)
|
1999-01-12 11:11:25 +08:00
|
|
|
ourInfo->notify(ourInfo->h, RPMCALLBACK_INST_PROGRESS,
|
1998-12-17 05:58:53 +08:00
|
|
|
cpioInfo->bytesProcessed,
|
1999-01-12 11:11:25 +08:00
|
|
|
ourInfo->archiveSize, ourInfo->pkgKey,
|
|
|
|
ourInfo->notifyData);
|
1997-05-07 02:19:19 +08:00
|
|
|
|
|
|
|
if (ourInfo->specFilePtr) {
|
|
|
|
chptr = cpioInfo->file + strlen(cpioInfo->file) - 5;
|
|
|
|
if (!strcmp(chptr, ".spec"))
|
|
|
|
*ourInfo->specFilePtr = strdup(cpioInfo->file);
|
|
|
|
}
|
1997-05-06 23:27:46 +08:00
|
|
|
}
|
1996-01-09 03:31:44 +08:00
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
/* NULL files means install all files */
|
1998-11-19 05:41:05 +08:00
|
|
|
static int installArchive(FD_t fd, struct fileInfo * files,
|
1999-01-12 11:11:25 +08:00
|
|
|
int fileCount, rpmCallbackFunction notify,
|
|
|
|
void * notifyData, const void * pkgKey, Header h,
|
1997-05-06 04:46:58 +08:00
|
|
|
char ** specFile, int archiveSize) {
|
|
|
|
int rc, i;
|
1997-05-07 02:19:19 +08:00
|
|
|
struct cpioFileMapping * map = NULL;
|
1997-07-14 22:48:38 +08:00
|
|
|
int mappedFiles = 0;
|
1997-05-06 04:46:58 +08:00
|
|
|
char * failedFile;
|
1997-05-06 23:27:46 +08:00
|
|
|
struct callbackInfo info;
|
1997-05-06 04:46:58 +08:00
|
|
|
|
|
|
|
if (!files) {
|
|
|
|
/* install all files */
|
|
|
|
fileCount = 0;
|
|
|
|
} else if (!fileCount) {
|
|
|
|
/* no files to install */
|
|
|
|
return 0;
|
1996-01-09 03:31:44 +08:00
|
|
|
}
|
|
|
|
|
1997-05-06 23:27:46 +08:00
|
|
|
info.archiveSize = archiveSize;
|
|
|
|
info.notify = notify;
|
1998-12-17 05:58:53 +08:00
|
|
|
info.notifyData = notifyData;
|
1997-05-07 02:19:19 +08:00
|
|
|
info.specFilePtr = specFile;
|
1998-12-17 05:58:53 +08:00
|
|
|
info.h = h;
|
1999-01-12 11:11:25 +08:00
|
|
|
info.pkgKey = pkgKey;
|
1997-05-06 23:27:46 +08:00
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
if (specFile) *specFile = NULL;
|
1996-01-09 03:31:44 +08:00
|
|
|
|
1997-05-07 02:19:19 +08:00
|
|
|
if (files) {
|
|
|
|
map = alloca(sizeof(*map) * fileCount);
|
1997-05-23 23:18:15 +08:00
|
|
|
for (i = 0, mappedFiles = 0; i < fileCount; i++) {
|
|
|
|
if (!files[i].install) continue;
|
|
|
|
|
|
|
|
map[mappedFiles].archivePath = files[i].cpioPath;
|
1997-07-24 02:08:51 +08:00
|
|
|
map[mappedFiles].fsPath = files[i].relativePath;
|
1997-05-23 23:18:15 +08:00
|
|
|
map[mappedFiles].finalMode = files[i].mode;
|
|
|
|
map[mappedFiles].finalUid = files[i].uid;
|
|
|
|
map[mappedFiles].finalGid = files[i].gid;
|
|
|
|
map[mappedFiles].mapFlags = CPIO_MAP_PATH | CPIO_MAP_MODE |
|
|
|
|
CPIO_MAP_UID | CPIO_MAP_GID;
|
|
|
|
mappedFiles++;
|
1997-05-07 02:19:19 +08:00
|
|
|
}
|
|
|
|
|
1997-05-23 23:18:15 +08:00
|
|
|
qsort(map, mappedFiles, sizeof(*map), cpioFileMapCmp);
|
1996-01-23 05:13:12 +08:00
|
|
|
}
|
1996-01-09 03:31:44 +08:00
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
if (notify)
|
1999-01-12 11:11:25 +08:00
|
|
|
notify(h, RPMCALLBACK_INST_PROGRESS, 0, archiveSize, pkgKey,
|
|
|
|
notifyData);
|
1996-11-23 06:24:59 +08:00
|
|
|
|
1998-07-25 23:33:15 +08:00
|
|
|
{ CFD_t cfdbuf, *cfd = &cfdbuf;
|
|
|
|
cfd->cpioIoType = cpioIoTypeGzFd;
|
1998-11-25 08:42:36 +08:00
|
|
|
cfd->cpioGzFd = gzdFdopen(fdDup(fdFileno(fd)), "r");
|
1998-07-25 23:33:15 +08:00
|
|
|
rc = cpioInstallArchive(cfd, map, mappedFiles,
|
1997-05-07 02:19:19 +08:00
|
|
|
((notify && archiveSize) || specFile) ?
|
|
|
|
callback : NULL,
|
1997-05-06 23:27:46 +08:00
|
|
|
&info, &failedFile);
|
1998-11-23 03:48:48 +08:00
|
|
|
gzdClose(cfd->cpioGzFd);
|
1998-07-25 23:33:15 +08:00
|
|
|
}
|
1996-05-07 11:21:44 +08:00
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
if (rc) {
|
1996-01-09 03:31:44 +08:00
|
|
|
/* this would probably be a good place to check if disk space
|
|
|
|
was used up - if so, we should return a different error */
|
1999-01-22 01:18:38 +08:00
|
|
|
rpmError(RPMERR_CPIO, _("unpacking of archive failed%s%s: %s"),
|
|
|
|
(failedFile != NULL ? _(" on file") : ""),
|
|
|
|
(failedFile != NULL ? failedFile : ""),
|
|
|
|
cpioStrerror(rc));
|
1996-01-09 03:31:44 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
1997-05-06 23:27:46 +08:00
|
|
|
if (notify && archiveSize)
|
1999-01-12 11:11:25 +08:00
|
|
|
notify(h, RPMCALLBACK_INST_PROGRESS, archiveSize, archiveSize,
|
|
|
|
pkgKey, notifyData);
|
1997-05-06 23:27:46 +08:00
|
|
|
else if (notify) {
|
1999-01-12 11:11:25 +08:00
|
|
|
notify(h, RPMCALLBACK_INST_PROGRESS, 100, 100, pkgKey, notifyData);
|
1997-05-06 23:27:46 +08:00
|
|
|
}
|
1996-01-23 05:13:12 +08:00
|
|
|
|
1996-01-09 03:31:44 +08:00
|
|
|
return 0;
|
|
|
|
}
|
1996-01-15 03:32:17 +08:00
|
|
|
|
1996-11-01 05:06:55 +08:00
|
|
|
/* 0 success */
|
|
|
|
/* 1 bad magic */
|
|
|
|
/* 2 error */
|
1999-01-07 01:33:50 +08:00
|
|
|
static int installSources(Header h, const char * rootdir, FD_t fd,
|
1999-01-12 11:11:25 +08:00
|
|
|
const char ** specFilePtr, rpmCallbackFunction notify,
|
1999-01-07 12:07:31 +08:00
|
|
|
void * notifyData) {
|
1996-02-15 01:54:37 +08:00
|
|
|
char * specFile;
|
1997-05-07 02:19:19 +08:00
|
|
|
int specFileIndex = -1;
|
1999-01-06 07:13:56 +08:00
|
|
|
const char * realSourceDir = NULL;
|
|
|
|
const char * realSpecDir = NULL;
|
1996-02-15 01:54:37 +08:00
|
|
|
char * instSpecFile, * correctSpecFile;
|
1997-05-07 02:19:19 +08:00
|
|
|
int fileCount = 0;
|
1996-08-29 12:16:07 +08:00
|
|
|
uint_32 * archiveSizePtr = NULL;
|
1997-05-07 02:19:19 +08:00
|
|
|
struct fileMemory fileMem;
|
|
|
|
struct fileInfo * files;
|
|
|
|
int i;
|
|
|
|
char * chptr;
|
1997-05-16 23:25:31 +08:00
|
|
|
char * currDir;
|
|
|
|
int currDirLen;
|
1997-10-30 04:08:20 +08:00
|
|
|
uid_t currUid = getuid();
|
|
|
|
gid_t currGid = getgid();
|
1999-01-06 07:13:56 +08:00
|
|
|
int rc = 0;
|
1996-02-15 01:54:37 +08:00
|
|
|
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("installing a source package\n"));
|
1996-02-15 04:09:14 +08:00
|
|
|
|
1999-01-06 07:13:56 +08:00
|
|
|
realSourceDir = rpmGetPath(rootdir, "/%{_sourcedir}", NULL);
|
1999-01-07 08:45:52 +08:00
|
|
|
realSpecDir = rpmGetPath(rootdir, "/%{_specdir}", NULL);
|
1996-02-15 01:54:37 +08:00
|
|
|
|
1997-02-12 13:05:13 +08:00
|
|
|
if (access(realSourceDir, W_OK)) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_CREATE, _("cannot write to %s"), realSourceDir);
|
1999-01-06 07:13:56 +08:00
|
|
|
rc = 2;
|
|
|
|
goto exit;
|
1997-02-12 13:05:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (access(realSpecDir, W_OK)) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_CREATE, _("cannot write to %s"), realSpecDir);
|
1999-01-06 07:13:56 +08:00
|
|
|
rc = 2;
|
|
|
|
goto exit;
|
1997-02-12 13:05:13 +08:00
|
|
|
}
|
|
|
|
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("sources in: %s\n"), realSourceDir);
|
|
|
|
rpmMessage(RPMMESS_DEBUG, _("spec file in: %s\n"), realSpecDir);
|
1996-02-15 01:54:37 +08:00
|
|
|
|
1997-05-07 02:19:19 +08:00
|
|
|
if (h && headerIsEntry(h, RPMTAG_FILENAMES)) {
|
|
|
|
/* we can't remap v1 packages */
|
1999-01-01 03:16:12 +08:00
|
|
|
assembleFileList(h, &fileMem, &fileCount, &files, 0, NULL);
|
1997-05-07 02:19:19 +08:00
|
|
|
|
1997-10-30 04:08:20 +08:00
|
|
|
for (i = 0; i < fileCount; i++) {
|
1997-07-16 09:44:27 +08:00
|
|
|
files[i].relativePath = files[i].relativePath;
|
1997-10-30 04:08:20 +08:00
|
|
|
files[i].uid = currUid;
|
|
|
|
files[i].gid = currGid;
|
|
|
|
}
|
1997-05-07 02:19:19 +08:00
|
|
|
|
1997-10-29 23:53:35 +08:00
|
|
|
if (headerIsEntry(h, RPMTAG_COOKIE))
|
|
|
|
for (i = 0; i < fileCount; i++)
|
|
|
|
if (files[i].flags & RPMFILE_SPECFILE) break;
|
|
|
|
|
1997-05-07 02:19:19 +08:00
|
|
|
if (i == fileCount) {
|
|
|
|
/* find the spec file by name */
|
|
|
|
for (i = 0; i < fileCount; i++) {
|
|
|
|
chptr = files[i].cpioPath + strlen(files[i].cpioPath) - 5;
|
|
|
|
if (!strcmp(chptr, ".spec")) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i < fileCount) {
|
|
|
|
specFileIndex = i;
|
|
|
|
|
1997-07-16 09:44:27 +08:00
|
|
|
files[i].relativePath = alloca(strlen(realSpecDir) +
|
1997-05-07 02:19:19 +08:00
|
|
|
strlen(files[i].cpioPath) + 5);
|
1997-07-16 09:44:27 +08:00
|
|
|
strcpy(files[i].relativePath, realSpecDir);
|
|
|
|
strcat(files[i].relativePath, "/");
|
|
|
|
strcat(files[i].relativePath, files[i].cpioPath);
|
1997-05-07 02:19:19 +08:00
|
|
|
} else {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_NOSPEC, _("source package contains no .spec file"));
|
1997-05-07 02:19:19 +08:00
|
|
|
if (fileCount > 0) freeFileMemory(fileMem);
|
1999-01-06 07:13:56 +08:00
|
|
|
rc = 2;
|
|
|
|
goto exit;
|
1997-05-07 02:19:19 +08:00
|
|
|
}
|
|
|
|
}
|
1996-07-26 00:39:01 +08:00
|
|
|
|
1999-01-07 12:07:31 +08:00
|
|
|
if (notify) {
|
1999-01-12 11:11:25 +08:00
|
|
|
notify(h, RPMCALLBACK_INST_START, 0, 0, NULL, notifyData);
|
1996-08-29 12:16:07 +08:00
|
|
|
}
|
|
|
|
|
1997-05-16 23:25:31 +08:00
|
|
|
currDirLen = 50;
|
|
|
|
currDir = malloc(currDirLen);
|
|
|
|
while (!getcwd(currDir, currDirLen)) {
|
|
|
|
currDirLen += 50;
|
|
|
|
currDir = realloc(currDir, currDirLen);
|
|
|
|
}
|
|
|
|
|
1997-05-07 02:19:19 +08:00
|
|
|
chdir(realSourceDir);
|
|
|
|
if (installArchive(fd, fileCount > 0 ? files : NULL,
|
1999-01-12 11:11:25 +08:00
|
|
|
fileCount, notify, notifyData, NULL, h,
|
1997-05-07 02:19:19 +08:00
|
|
|
specFileIndex >=0 ? NULL : &specFile,
|
|
|
|
archiveSizePtr ? *archiveSizePtr : 0)) {
|
|
|
|
if (fileCount > 0) freeFileMemory(fileMem);
|
1999-01-06 07:13:56 +08:00
|
|
|
rc = 2;
|
|
|
|
goto exit;
|
1996-02-15 01:54:37 +08:00
|
|
|
}
|
|
|
|
|
1997-05-16 23:25:31 +08:00
|
|
|
chdir(currDir);
|
1996-02-15 01:54:37 +08:00
|
|
|
|
1997-05-07 02:19:19 +08:00
|
|
|
if (specFileIndex == -1) {
|
|
|
|
if (!specFile) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_NOSPEC, _("source package contains no .spec file"));
|
1999-01-06 07:13:56 +08:00
|
|
|
rc = 1;
|
|
|
|
goto exit;
|
1997-05-07 02:19:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* This logic doesn't work is realSpecDir and realSourceDir are on
|
|
|
|
different filesystems, but we only do this on v1 source packages
|
|
|
|
so I don't really care much. */
|
|
|
|
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);
|
|
|
|
|
|
|
|
free(specFile);
|
|
|
|
|
|
|
|
rpmMessage(RPMMESS_DEBUG,
|
1998-09-28 06:03:52 +08:00
|
|
|
_("renaming %s to %s\n"), instSpecFile, correctSpecFile);
|
1997-05-07 02:19:19 +08:00
|
|
|
if (rename(instSpecFile, correctSpecFile)) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s"),
|
1997-05-07 02:19:19 +08:00
|
|
|
instSpecFile, correctSpecFile, strerror(errno));
|
1999-01-06 07:13:56 +08:00
|
|
|
rc = 2;
|
|
|
|
goto exit;
|
1997-05-07 02:19:19 +08:00
|
|
|
}
|
1996-02-15 01:54:37 +08:00
|
|
|
|
1997-05-07 02:19:19 +08:00
|
|
|
if (specFilePtr)
|
|
|
|
*specFilePtr = strdup(correctSpecFile);
|
|
|
|
} else {
|
|
|
|
if (specFilePtr)
|
1997-07-16 09:44:27 +08:00
|
|
|
*specFilePtr = strdup(files[specFileIndex].relativePath);
|
1997-05-07 02:19:19 +08:00
|
|
|
|
|
|
|
if (fileCount > 0) freeFileMemory(fileMem);
|
|
|
|
}
|
1999-01-06 07:13:56 +08:00
|
|
|
rc = 0;
|
1996-02-15 04:09:14 +08:00
|
|
|
|
1999-01-06 07:13:56 +08:00
|
|
|
exit:
|
|
|
|
if (realSpecDir) xfree(realSpecDir);
|
|
|
|
if (realSourceDir) xfree(realSourceDir);
|
|
|
|
return rc;
|
1996-02-15 01:54:37 +08:00
|
|
|
}
|
1996-02-16 05:08:48 +08:00
|
|
|
|
1999-01-08 01:05:02 +08:00
|
|
|
static int markReplacedFiles(rpmdb db, struct sharedFileInfo * replList) {
|
|
|
|
struct sharedFileInfo * fileInfo;
|
1996-02-16 05:08:48 +08:00
|
|
|
Header secHeader = NULL, sh;
|
|
|
|
char * secStates;
|
|
|
|
int type, count;
|
|
|
|
|
|
|
|
int secOffset = 0;
|
|
|
|
|
1999-01-08 01:05:02 +08:00
|
|
|
for (fileInfo = replList; fileInfo->otherPkg; fileInfo++) {
|
|
|
|
if (secOffset != fileInfo->otherPkg) {
|
1998-11-17 05:40:28 +08:00
|
|
|
if (secHeader != NULL) {
|
1996-02-16 05:08:48 +08:00
|
|
|
/* ignore errors here - just do the best we can */
|
|
|
|
|
|
|
|
rpmdbUpdateRecord(db, secOffset, secHeader);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(secHeader);
|
1996-02-16 05:08:48 +08:00
|
|
|
}
|
|
|
|
|
1999-01-08 01:05:02 +08:00
|
|
|
secOffset = fileInfo->otherPkg;
|
1996-02-16 05:08:48 +08:00
|
|
|
sh = rpmdbGetRecord(db, secOffset);
|
1998-11-17 05:40:28 +08:00
|
|
|
if (sh == NULL) {
|
1996-02-16 05:08:48 +08:00
|
|
|
secOffset = 0;
|
|
|
|
} else {
|
1996-11-19 02:02:36 +08:00
|
|
|
secHeader = headerCopy(sh); /* so we can modify it */
|
|
|
|
headerFree(sh);
|
1996-02-16 05:08:48 +08:00
|
|
|
}
|
|
|
|
|
1997-05-06 04:46:58 +08:00
|
|
|
headerGetEntry(secHeader, RPMTAG_FILESTATES, &type,
|
|
|
|
(void **) &secStates, &count);
|
1996-02-16 05:08:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* by now, secHeader is the right header to modify, secStates is
|
|
|
|
the right states list to modify */
|
|
|
|
|
1999-01-08 01:05:02 +08:00
|
|
|
secStates[fileInfo->otherFileNum] = RPMFILE_STATE_REPLACED;
|
1996-02-16 05:08:48 +08:00
|
|
|
}
|
|
|
|
|
1998-11-17 05:40:28 +08:00
|
|
|
if (secHeader != NULL) {
|
1996-02-16 05:08:48 +08:00
|
|
|
/* ignore errors here - just do the best we can */
|
|
|
|
|
|
|
|
rpmdbUpdateRecord(db, secOffset, secHeader);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(secHeader);
|
1996-02-16 05:08:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
1996-02-26 06:11:00 +08:00
|
|
|
|
1997-01-16 00:24:14 +08:00
|
|
|
int rpmVersionCompare(Header first, Header second) {
|
|
|
|
char * one, * two;
|
1998-08-19 10:30:02 +08:00
|
|
|
int_32 * epochOne, * epochTwo;
|
1997-01-16 00:24:14 +08:00
|
|
|
int rc;
|
1996-02-26 06:11:00 +08:00
|
|
|
|
1998-08-21 03:12:30 +08:00
|
|
|
if (!headerGetEntry(first, RPMTAG_EPOCH, NULL, (void **) &epochOne, NULL))
|
1998-08-19 10:30:02 +08:00
|
|
|
epochOne = NULL;
|
|
|
|
if (!headerGetEntry(second, RPMTAG_EPOCH, NULL, (void **) &epochTwo,
|
1997-10-15 23:44:57 +08:00
|
|
|
NULL))
|
1998-08-19 10:30:02 +08:00
|
|
|
epochTwo = NULL;
|
1997-01-16 00:24:14 +08:00
|
|
|
|
1998-08-19 10:30:02 +08:00
|
|
|
if (epochOne && !epochTwo)
|
1997-01-16 00:24:14 +08:00
|
|
|
return 1;
|
1998-08-19 10:30:02 +08:00
|
|
|
else if (!epochOne && epochTwo)
|
1997-07-24 22:41:55 +08:00
|
|
|
return -1;
|
1998-08-19 10:30:02 +08:00
|
|
|
else if (epochOne && epochTwo) {
|
|
|
|
if (*epochOne < *epochTwo)
|
1997-10-15 23:44:57 +08:00
|
|
|
return -1;
|
1998-08-19 10:30:02 +08:00
|
|
|
else if (*epochOne > *epochTwo)
|
1997-10-15 23:44:57 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
1997-01-16 00:24:14 +08:00
|
|
|
headerGetEntry(first, RPMTAG_VERSION, NULL, (void **) &one, NULL);
|
1997-01-17 00:18:48 +08:00
|
|
|
headerGetEntry(second, RPMTAG_VERSION, NULL, (void **) &two, NULL);
|
1996-02-26 06:11:00 +08:00
|
|
|
|
1997-01-16 00:24:14 +08:00
|
|
|
rc = rpmvercmp(one, two);
|
|
|
|
if (rc)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
headerGetEntry(first, RPMTAG_RELEASE, NULL, (void **) &one, NULL);
|
1997-01-17 00:18:48 +08:00
|
|
|
headerGetEntry(second, RPMTAG_RELEASE, NULL, (void **) &two, NULL);
|
1997-01-16 00:24:14 +08:00
|
|
|
|
|
|
|
return rpmvercmp(one, two);
|
|
|
|
}
|
|
|
|
|
1999-01-06 07:13:56 +08:00
|
|
|
#ifdef UNUSED
|
|
|
|
static int ensureOlder(rpmdb db, Header new, int dbOffset);
|
1997-01-16 00:24:14 +08:00
|
|
|
static int ensureOlder(rpmdb db, Header new, int dbOffset) {
|
|
|
|
Header old;
|
|
|
|
char * name, * version, * release;
|
|
|
|
int result, rc = 0;
|
|
|
|
|
|
|
|
old = rpmdbGetRecord(db, dbOffset);
|
1998-11-17 05:40:28 +08:00
|
|
|
if (old == NULL) return 1;
|
1997-01-16 00:24:14 +08:00
|
|
|
|
|
|
|
result = rpmVersionCompare(old, new);
|
1996-02-26 06:11:00 +08:00
|
|
|
if (result < 0)
|
|
|
|
rc = 0;
|
1997-01-16 00:24:14 +08:00
|
|
|
else if (result > 0) {
|
1996-02-26 06:11:00 +08:00
|
|
|
rc = 1;
|
1997-01-16 00:24:14 +08:00
|
|
|
headerGetEntry(old, RPMTAG_NAME, NULL, (void **) &name, NULL);
|
|
|
|
headerGetEntry(old, RPMTAG_VERSION, NULL, (void **) &version, NULL);
|
|
|
|
headerGetEntry(old, RPMTAG_RELEASE, NULL, (void **) &release, NULL);
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_OLDPACKAGE, _("package %s-%s-%s (which is newer) is "
|
|
|
|
"already installed"), name, version, release);
|
1996-02-26 06:11:00 +08:00
|
|
|
}
|
|
|
|
|
1997-01-16 00:24:14 +08:00
|
|
|
headerFree(old);
|
1996-02-26 06:11:00 +08:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
1999-01-06 07:13:56 +08:00
|
|
|
#endif
|
1996-02-29 11:38:33 +08:00
|
|
|
|
1999-01-05 00:42:15 +08:00
|
|
|
const char * fileActionString(enum fileActions a) {
|
1999-01-01 03:16:12 +08:00
|
|
|
switch (a) {
|
|
|
|
case UNKNOWN: return "unknown";
|
|
|
|
case CREATE: return "create";
|
|
|
|
case BACKUP: return "backup";
|
|
|
|
case SAVE: return "save";
|
|
|
|
case SKIP: return "skip";
|
1999-01-20 00:24:43 +08:00
|
|
|
case SKIPNSTATE: return "skipnstate";
|
1999-01-01 03:16:12 +08:00
|
|
|
case ALTNAME: return "altname";
|
1999-01-05 00:42:15 +08:00
|
|
|
case REMOVE: return "remove";
|
1999-01-01 03:16:12 +08:00
|
|
|
}
|
1996-07-10 10:33:38 +08:00
|
|
|
|
1999-01-01 03:16:12 +08:00
|
|
|
return "???";
|
|
|
|
}
|