summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--install.c35
-rw-r--r--install.h8
-rw-r--r--lib/package.c42
-rw-r--r--lib/uninstall.c82
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;
+}
+