diff options
-rw-r--r-- | install.c | 35 | ||||
-rw-r--r-- | install.h | 8 | ||||
-rw-r--r-- | lib/package.c | 42 | ||||
-rw-r--r-- | lib/uninstall.c | 82 |
4 files changed, 167 insertions, 0 deletions
diff --git a/install.c b/install.c new file mode 100644 index 000000000..942f4c64d --- /dev/null +++ b/install.c @@ -0,0 +1,35 @@ +#include <fcntl.h> + +#include "install.h" +#include "lib/rpmlib.h" + +void doInstall(char * prefix, int test, int installFlags) { + printf("I can't install packages yet"); +} + +void doUninstall(char * prefix, char * arg, int test, int uninstallFlags) { + rpmdb db; + dbIndexSet matches; + int i; + + if (!rpmdbOpen(prefix, &db, O_RDWR | O_EXCL, 0644)) { + fprintf(stderr, "cannot open %s/var/lib/rpm/packages.rpm\n", prefix); + exit(1); + } + + if (rpmdbFindPackage(db, arg, &matches)) { + fprintf(stderr, "package %s is not installed\n", arg); + } else { + if (matches.count > 1) { + fprintf(stderr, "\"%s\" specifies multiple packages\n", arg); + rpmdbClose(db); + } + for (i = 0; i < matches.count; i++) { + rpmRemovePackage(prefix, db, matches.recs[i].recOffset, test); + } + + freeDBIndexRecord(matches); + } + + rpmdbClose(db); +} diff --git a/install.h b/install.h new file mode 100644 index 000000000..587475129 --- /dev/null +++ b/install.h @@ -0,0 +1,8 @@ +#ifndef _H_INSTALL +#define _H_INSTALL + +void doInstall(char * prefix, int test, int installFlags); +void doUninstall(char * prefix, char * arg, int test, int uninstallFlags); + +#endif + diff --git a/lib/package.c b/lib/package.c new file mode 100644 index 000000000..7493248a7 --- /dev/null +++ b/lib/package.c @@ -0,0 +1,42 @@ +#include <fcntl.h> +#include <unistd.h> + +#include "errno.h" +#include "header.h" +#include "package.h" +#include "rpmerr.h" +#include "rpmlead.h" + +/* 0 = success */ +/* 1 = bad magic */ +/* 2 = error */ +int pkgReadHeader(int fd, Header * hdr, int * isSource) { + struct rpmlead lead; + + if (read(fd, &lead, sizeof(lead)) != sizeof(lead)) { + error(RPMERR_READERROR, "read failed: %s (%d)", strerror(errno), + errno); + return 2; + } + + if (lead.magic[0] != RPMLEAD_MAGIC0 || lead.magic[1] != RPMLEAD_MAGIC1 || + lead.magic[2] != RPMLEAD_MAGIC2 || lead.magic[3] != RPMLEAD_MAGIC3) { + return 1; + } + + *isSource = lead.type == RPMLEAD_SOURCE; + + if (lead.major == 1) { + printf("old style packages are not yet supported\n"); + exit(1); + } else if (lead.major == 2) { + *hdr = readHeader(fd); + if (! *hdr) return 2; + } else { + error(RPMERR_NEWPACKAGE, "old packages with major numbers <= 2 are" + " supported by this version of RPM"); + return 2; + } + + return 0; +} diff --git a/lib/uninstall.c b/lib/uninstall.c new file mode 100644 index 000000000..33fb8bb85 --- /dev/null +++ b/lib/uninstall.c @@ -0,0 +1,82 @@ +#include <alloca.h> +#include <stdlib.h> +#include <string.h> + +#include "rpmerr.h" +#include "rpmlib.h" + +int rpmRemovePackage(char * prefix, rpmdb db, unsigned int offset, int test) { + Header h; + int i; + int count; + char * rmmess; + char * fnbuffer = NULL; + int fnbuffersize = 0; + int prefixLength = strlen(prefix); + char ** fileList; + int type; + char * fileStatesList; + + h = rpmdbGetRecord(db, offset); + if (!h) { + error(RPMERR_DBCORRUPT, "cannot read header at %d for uninstall", + offset); + return 0; + } + + /* dependency checking should go in here */ + + if (test) { + rmmess = "would remove"; + } else { + rmmess = "removing"; + } + + message(MESS_DEBUG, "%s files test = %d\n", rmmess, test); + if (!getEntry(h, RPMTAG_FILENAMES, &type, (void **) &fileList, + &count)) { + puts("(contains no files)"); + } else { + if (prefix[0]) { + fnbuffersize = 1024; + fnbuffer = alloca(fnbuffersize); + } + + getEntry(h, RPMTAG_FILESTATES, &type, + (void **) &fileStatesList, &count); + + for (i = 0; i < count; i++) { + if (prefix[0]) { + if ((strlen(fileList[i]) + prefixLength + 1) > fnbuffersize) { + fnbuffersize = (strlen(fileList[i]) + prefixLength) * 2; + fnbuffer = alloca(fnbuffersize); + } + strcpy(fnbuffer, ""); + strcat(fnbuffer, "/"); + strcpy(fnbuffer, fileList[i]); + } else { + fnbuffer = fileList[i]; + } + + switch (fileStatesList[i]) { + case RPMFILE_STATE_REPLACED: + message(MESS_DEBUG, "%s has already been replaced\n", + fileList[i]); + break; + + case RPMFILE_STATE_NORMAL: + message(MESS_DEBUG, "%s - %s\n", fileList[i], rmmess); + break; + } + } + + free(fileList); + } + + message(MESS_DEBUG, "%s database entry\n", rmmess); + if (!test) + rpmdbRemove(db, offset, 0); + + return 1; +} + |