summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Fleischer <archlinux@cryptocrack.de>2011-02-05 17:42:47 +0100
committerLukas Fleischer <archlinux@cryptocrack.de>2011-02-11 14:43:22 +0100
commit400d7845e4c959660edf4cbeb1a390c6590cc4fc (patch)
treeb404bf77af58e698d1ac55b82555c2fda35b9a7f
parentb69f548065e78d14afcdc91548d73539762f8d93 (diff)
Add AUR package blacklist updater (aurblup).
Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de>
-rw-r--r--scripts/aurblup/.gitignore3
-rw-r--r--scripts/aurblup/Makefile30
-rw-r--r--scripts/aurblup/README27
-rw-r--r--scripts/aurblup/aurblup.c224
-rw-r--r--scripts/aurblup/config.h.proto13
-rw-r--r--scripts/aurblup/config.mk6
6 files changed, 303 insertions, 0 deletions
diff --git a/scripts/aurblup/.gitignore b/scripts/aurblup/.gitignore
new file mode 100644
index 0000000..ae50736
--- /dev/null
+++ b/scripts/aurblup/.gitignore
@@ -0,0 +1,3 @@
+config.h
+*.o
+aurblup
diff --git a/scripts/aurblup/Makefile b/scripts/aurblup/Makefile
new file mode 100644
index 0000000..67fcac1
--- /dev/null
+++ b/scripts/aurblup/Makefile
@@ -0,0 +1,30 @@
+include config.mk
+
+SRC = aurblup.c
+OBJ = ${SRC:.c=.o}
+
+all: aurblup
+
+.c.o:
+ ${CC} -c ${CFLAGS} $<
+
+config.h:
+ cp config.h.proto config.h
+
+${OBJ}: config.h
+
+aurblup: ${OBJ}
+ ${CC} -o $@ ${OBJ} ${LDFLAGS}
+
+install: aurblup
+ install -Dm0755 aurblup "${DESTDIR}${PREFIX}/bin/aurblup"
+ install -dm0755 "${DESTDIR}/var/lib/aurblup/"
+
+uninstall:
+ rm -f "${DESTDIR}${PREFIX}/bin/aurblup"
+ rm -f "${DESTDIR}/var/lib/aurblup/"
+
+clean:
+ rm -f aurblup ${OBJ}
+
+.PHONY: all install uninstall clean
diff --git a/scripts/aurblup/README b/scripts/aurblup/README
new file mode 100644
index 0000000..8e5047d
--- /dev/null
+++ b/scripts/aurblup/README
@@ -0,0 +1,27 @@
+aurblup
+=======
+
+aurblup is a small and leightweight tool that updates the package blacklist of
+an AUR MySQL database using one (or more) package databases. It does the
+following things:
+
+- Sync a bunch of local package databases with a remote server.
+
+- Get a list of packages in those databases.
+
+- Update the MySQL blacklist table to match those packages.
+
+Requirements
+------------
+
+You need the libalpm and libmysqlclient header files to build aurblup.
+
+Installation
+------------
+
+Edit the "config.h" (copy from "config.h.proto" if doesn't exist) and
+"config.mk" configuration files to match your setup and enter the following
+command to build and install dwm:
+
+ make install
+
diff --git a/scripts/aurblup/aurblup.c b/scripts/aurblup/aurblup.c
new file mode 100644
index 0000000..2ecfb7b
--- /dev/null
+++ b/scripts/aurblup/aurblup.c
@@ -0,0 +1,224 @@
+/* aurblup - AUR blacklist updater
+ *
+ * Small utility to update the AUR package blacklist. Can be used in a cronjob.
+ * Check the "README" file for details.
+ */
+
+#include <alpm.h>
+#include <mysql.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+
+#define alpm_die(...) die(__VA_ARGS__, alpm_strerrorlast());
+#define mysql_die(...) die(__VA_ARGS__, mysql_error(c));
+
+void die(const char *, ...);
+void blacklist_sync(alpm_list_t *);
+alpm_list_t *get_package_list(alpm_list_t *);
+alpm_list_t *create_db_list(void);
+void read_config(const char *);
+void init(void);
+void cleanup(void);
+
+static char *mysql_host = NULL;
+static char *mysql_socket = NULL;
+static char *mysql_user = NULL;
+static char *mysql_passwd = NULL;
+static char *mysql_db = NULL;
+
+MYSQL *c;
+
+void
+die(const char *format, ...)
+{
+ va_list arg;
+
+ va_start(arg, format);
+ fprintf(stderr, "blackup: ");
+ vfprintf(stderr, format, arg);
+ va_end(arg);
+
+ cleanup();
+ exit(1);
+}
+
+void
+blacklist_sync(alpm_list_t *pkgs)
+{
+ alpm_list_t *r;
+ char *se;
+ char query[1024];
+
+ if (mysql_query(c, "LOCK TABLES PackageBlacklist WRITE;"))
+ mysql_die("failed to lock MySQL table: %s\n");
+
+ if (mysql_query(c, "DELETE FROM PackageBlacklist;"))
+ mysql_die("failed to clear MySQL table: %s\n");
+
+ for (r = pkgs; r; r = alpm_list_next(r)) {
+ const char *s = alpm_pkg_get_name(alpm_list_getdata(r));
+
+ se = malloc(strlen(s) * 2 + 1);
+ mysql_real_escape_string(c, se, s, strlen(s));
+ snprintf(query, 1024, "INSERT INTO PackageBlacklist (Name) "
+ "VALUES ('%s');", se);
+ free(se);
+
+ if (mysql_query(c, query))
+ mysql_die("failed to query MySQL database (\"%s\"): %s\n", query);
+ }
+
+ if (mysql_query(c, "UNLOCK TABLES;"))
+ mysql_die("failed to unlock MySQL tables: %s\n");
+}
+
+alpm_list_t *
+get_package_list(alpm_list_t *dblist)
+{
+ alpm_list_t *r, *pkgs = NULL;
+
+ for (r = dblist; r; r = alpm_list_next(r)) {
+ pmdb_t *db = alpm_list_getdata(r);
+
+ if (alpm_trans_init(0, NULL, NULL, NULL))
+ alpm_die("failed to initialize ALPM transaction: %s\n");
+ if (alpm_db_update(0, db) < 0)
+ alpm_die("failed to update ALPM database: %s\n");
+ if (alpm_trans_release())
+ alpm_die("failed to release ALPM transaction: %s\n");
+
+ pkgs = alpm_list_join(pkgs, alpm_list_copy(alpm_db_get_pkgcache(db)));
+ }
+
+ return pkgs;
+}
+
+alpm_list_t *
+create_db_list(void)
+{
+ alpm_list_t *r, *dblist = NULL;
+ int i;
+
+ for (i = 0; i < sizeof(alpm_repos) / sizeof(char *); i++) {
+ if (!alpm_db_register_sync(alpm_repos[i]))
+ alpm_die("failed to register sync db \"%s\": %s\n", alpm_repos[i]);
+ }
+
+ if (!(dblist = alpm_option_get_syncdbs()))
+ alpm_die("failed to get sync DBs: %s\n");
+
+ for (r = dblist; r; r = alpm_list_next(r)) {
+ pmdb_t *db = alpm_list_getdata(r);
+
+ char server[1024];
+ snprintf(server, 1024, ALPM_MIRROR, alpm_db_get_name(db));
+
+ if (alpm_db_setserver(db, server))
+ alpm_die("failed to set server \"%s\": %s\n", server);
+ }
+
+ return dblist;
+}
+
+void
+read_config(const char *fn)
+{
+ FILE *fp;
+ char line[128];
+ char **t, **u, *p, *q;
+
+ if (!(fp = fopen(fn, "r")))
+ die("failed to open AUR config file (\"%s\")\n", fn);
+
+ while (fgets(line, sizeof(line), fp)) {
+ u = NULL;
+ if (strstr(line, CONFIG_KEY_HOST)) {
+ t = &mysql_host;
+ u = &mysql_socket;
+ }
+ else if (strstr(line, CONFIG_KEY_USER)) t = &mysql_user;
+ else if (strstr(line, CONFIG_KEY_PASSWD)) t = &mysql_passwd;
+ else if (strstr(line, CONFIG_KEY_DB)) t = &mysql_db;
+ else t = NULL;
+
+ if (t) {
+ strtok(line, "\"");
+ strtok(NULL, "\"");
+ strtok(NULL, "\"");
+ p = strtok(NULL, "\"");
+
+ if (u) {
+ p = strtok(p, ":");
+ q = strtok(NULL, ":");
+ }
+ else q = NULL;
+
+ if (p && !*t) {
+ *t = malloc(strlen(p) + 1);
+ strncpy(*t, p, strlen(p) + 1);
+ }
+
+ if (q && !*u) {
+ *u = malloc(strlen(q) + 1);
+ strncpy(*u, q, strlen(q) + 1);
+ }
+ }
+ }
+
+ fclose(fp);
+
+ if (!mysql_host)
+ die("MySQL host setting not found in AUR config file\n");
+ if (!mysql_user)
+ die("MySQL user setting not found in AUR config file\n");
+ if (!mysql_passwd)
+ die("MySQL password setting not found in AUR config file\n");
+ if (!mysql_db)
+ die("MySQL database setting not found in AUR config file\n");
+}
+
+void
+init(void)
+{
+ if (!(c = mysql_init(NULL)))
+ mysql_die("failed to setup MySQL client: %s\n");
+ if (!mysql_real_connect(c, mysql_host, mysql_user, mysql_passwd,
+ mysql_db, 0, mysql_socket, 0))
+ mysql_die("failed to initiate MySQL connection to %s: %s\n", mysql_host);
+
+ if (alpm_initialize())
+ alpm_die("failed to initialize ALPM: %s\n");
+ if (alpm_option_set_root("/"))
+ alpm_die("failed to set ALPM root: %s\n");
+ if (alpm_option_set_dbpath(ALPM_DBPATH))
+ alpm_die("failed to set ALPM database path: %s\n");
+}
+
+void
+cleanup(void)
+{
+ if (mysql_host) free(mysql_host);
+ if (mysql_socket) free(mysql_socket);
+ if (mysql_user) free(mysql_user);
+ if (mysql_passwd) free(mysql_passwd);
+ if (mysql_db) free(mysql_db);
+
+ alpm_release();
+ mysql_close(c);
+}
+
+int main(int argc, char *argv[])
+{
+ alpm_list_t *pkgs;
+
+ read_config(AUR_CONFIG);
+ init();
+ pkgs = get_package_list(create_db_list());
+ blacklist_sync(pkgs);
+ alpm_list_free(pkgs);
+ cleanup();
+
+ return 0;
+}
diff --git a/scripts/aurblup/config.h.proto b/scripts/aurblup/config.h.proto
new file mode 100644
index 0000000..daf1744
--- /dev/null
+++ b/scripts/aurblup/config.h.proto
@@ -0,0 +1,13 @@
+/* AUR configuration file */
+#define AUR_CONFIG "/srv/aur/web/lib/config.inc"
+
+#define CONFIG_KEY_HOST "AUR_db_host"
+#define CONFIG_KEY_USER "AUR_db_user"
+#define CONFIG_KEY_PASSWD "AUR_db_pass"
+#define CONFIG_KEY_DB "AUR_db_name"
+
+/* libalpm options */
+#define ALPM_DBPATH "/var/lib/aurblup/"
+#define ALPM_MIRROR "ftp://mirrors.kernel.org/archlinux/%s/os/i686"
+
+static const char *alpm_repos[] = { "core", "community", "extra" };
diff --git a/scripts/aurblup/config.mk b/scripts/aurblup/config.mk
new file mode 100644
index 0000000..9545f2c
--- /dev/null
+++ b/scripts/aurblup/config.mk
@@ -0,0 +1,6 @@
+PREFIX = /usr/local
+
+CFLAGS = -g -std=c99 -pedantic -Wall -I/usr/include/mysql
+LDFLAGS = -g -lalpm -lmysqlclient
+
+CC = cc