From 400d7845e4c959660edf4cbeb1a390c6590cc4fc Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Sat, 5 Feb 2011 17:42:47 +0100 Subject: Add AUR package blacklist updater (aurblup). Signed-off-by: Lukas Fleischer --- scripts/aurblup/.gitignore | 3 + scripts/aurblup/Makefile | 30 ++++++ scripts/aurblup/README | 27 +++++ scripts/aurblup/aurblup.c | 224 +++++++++++++++++++++++++++++++++++++++++ scripts/aurblup/config.h.proto | 13 +++ scripts/aurblup/config.mk | 6 ++ 6 files changed, 303 insertions(+) create mode 100644 scripts/aurblup/.gitignore create mode 100644 scripts/aurblup/Makefile create mode 100644 scripts/aurblup/README create mode 100644 scripts/aurblup/aurblup.c create mode 100644 scripts/aurblup/config.h.proto create mode 100644 scripts/aurblup/config.mk (limited to 'scripts') 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 +#include +#include +#include + +#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 -- cgit v1.2.3-70-g09d2