--- /dev/null
+Makefile
+Makefile.in
+aclocal.m4
+config.*
+config/
+autom4te.cache/
+configure
+libtool
+plover-*.tar.gz
+stamp-h1
+.deps/
+.libs/
+*.o
+*.lo
+*.la
+plover/plover.pc
+setup/resources.rc
+setup/setup
--- /dev/null
+SUBDIRS=plover setup
--- /dev/null
+#!/bin/sh
+set -e
+mkdir -p config
+autoheader
+aclocal
+libtoolize
+automake --foreign --add-missing
+autoconf
--- /dev/null
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_INIT([plover],[0.1],[ali@juiblex.co.uk])
+AC_PREREQ(2.59)
+AC_CONFIG_AUX_DIR([config])
+AC_CONFIG_SRCDIR([plover/plover.h])
+AC_CONFIG_HEADER([config.h])
+AC_CONFIG_FILES([Makefile
+plover/Makefile
+plover/plover.pc
+setup/Makefile
+setup/resources.rc
+])
+AM_INIT_AUTOMAKE(no-define)
+case $VERSION in
+ *.*.*)
+ AC_SUBST(PLOVER_MAJOR_VERSION,[[`echo $VERSION | sed 's/\..*//'`]])
+ AC_SUBST(PLOVER_MINOR_VERSION,
+ [[`echo $VERSION | sed 's/[^.]*\.\([^.]*\)\..*/\1/'`]])
+ AC_SUBST(PLOVER_MICRO_VERSION,[[`echo $VERSION | sed 's/.*\.\([^.]*\)/\1/'`]]) ;;
+ *.*)
+ AC_SUBST(PLOVER_MAJOR_VERSION,[[`echo $VERSION | sed 's/\..*//'`]])
+ AC_SUBST(PLOVER_MINOR_VERSION,
+ [[`echo $VERSION | sed 's/[^.]*\.\([^.]*\)/\1/'`]])
+ AC_SUBST(PLOVER_MICRO_VERSION,0)
+ ;;
+ *)
+ AC_SUBST(PLOVER_MAJOR_VERSION,0)
+ AC_SUBST(PLOVER_MINOR_VERSION,0)
+ AC_SUBST(PLOVER_MICRO_VERSION,0)
+ ;;
+esac
+
+##################################################
+# Checks for programs.
+##################################################
+AC_PROG_CC
+AC_LIBTOOL_WIN32_DLL
+AC_PROG_LIBTOOL
+PKG_PROG_PKG_CONFIG
+AC_CHECK_TOOL(WINDRES,windres,no)
+AM_CONDITIONAL([HAVE_WINDRES],[test x$WINDRES != xno])
+
+##################################################
+# Checks for header files.
+##################################################
+AC_HEADER_STDC
+
+##################################################
+# Checks for typedefs, structures, and compiler characteristics.
+##################################################
+
+##################################################
+# Checks for libraries.
+##################################################
+PKG_CHECK_MODULES(RAZOR,[razor],[:],[RAZOR_LIBS=-lrazor])
+PKG_CHECK_MODULES(EXPAT,[expat],[:],[EXPAT_LIBS=-lexpat])
+PKG_CHECK_MODULES(ZLIB,[zlib],[:],[ZLIB_LIBS=-lz])
+LIBPLOVER_CFLAGS="$RAZOR_CFLAGS $EXPAT_CFLAGS $ZLIB_CFLAGS"
+LIBPLOVER_LIBS="$RAZOR_LIBS $EXPAT_LIBS $ZLIB_LIBS"
+AC_SUBST(LIBPLOVER_CFLAGS)
+AC_SUBST(LIBPLOVER_LIBS)
+save_PKG_CONFIG="$PKG_CONFIG"
+PKG_CONFIG="$PKG_CONFIG --static"
+PKG_CHECK_MODULES(SETUP,[whelk])
+PKG_CONFIG="$save_PKG_CONFIG"
+save_LIBS="$LIBS"
+AC_SEARCH_LIBS([crypt],[crypt])
+SETUP_LIBS="$SETUP_LIBS $RAZOR_LIBS -llua-posix $LIBS"
+SETUP_CFLAGS="$SETUP_CFLAGS $RAZOR_CFLAGS"
+AC_SUBST(SETUP_LIBS)
+AC_SUBST(SETUP_CFLAGS)
+LIBS="$save_LIBS"
+
+##################################################
+# Checks for library functions.
+##################################################
+
+##################################################
+# Checks for processor independent files.
+##################################################
+
+##################################################
+# Generate the various configured files
+##################################################
+AC_OUTPUT
--- /dev/null
+AM_CFLAGS=-g $(LIBPLOVER_CFLAGS)
+LIBS=$(LIBPLOVER_LIBS)
+INCLUDES=-I$(top_srcdir)
+LDFLAGS=-no-undefined
+
+lib_LTLIBRARIES=libplover.la
+libplover_la_SOURCES=plover.h util.c import-yum.c razor.c comps.c
+
+pkginclude_HEADERS=plover.h
+
+pkgconfigdir=$(libdir)/pkgconfig
+pkgconfig_DATA=plover.pc
--- /dev/null
+/*
+ * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
+ * Copyright (C) 2008 Red Hat, Inc
+ * Copyright (C) 2009 J. Ali Harlow <ali@juiblex.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <expat.h>
+#include <assert.h>
+#include "plover/plover.h"
+
+/* Parse a comps.xml package group file. */
+
+static struct comps_requirement *comps_package_requirement_new(void)
+{
+ struct comps_requirement *req;
+ req=calloc(sizeof(*req),1);
+ assert(req != NULL);
+ req->type=COMPS_REQUIREMENT_OPTIONAL;
+ return req;
+}
+
+static void comps_package_requirement_free_1(struct comps_requirement *req)
+{
+ if (req)
+ {
+ free(req->requires);
+ free(req->name);
+ free(req);
+ }
+}
+
+static void comps_package_requirement_free(struct comps_requirement *req)
+{
+ struct comps_requirement *next;
+ while(req)
+ {
+ next=req->next;
+ comps_package_requirement_free_1(req);
+ req=next;
+ }
+}
+
+struct comps_group *comps_group_new(void)
+{
+ struct comps_group *group;
+ group=calloc(sizeof(*group),1);
+ assert(group != NULL);
+ group->bydefault=1;
+ group->uservisible=1;
+ return group;
+}
+
+static void comps_group_free_1(struct comps_group *group)
+{
+ if (group)
+ {
+ free(group->id);
+ free(group->name);
+ free(group->description);
+ comps_package_requirement_free(group->packages);
+ free(group);
+ }
+}
+static void comps_group_free(struct comps_group *group)
+{
+ struct comps_group *next;
+ while(group)
+ {
+ next=group->next;
+ comps_group_free_1(group);
+ group=next;
+ }
+}
+
+struct comps *plover_comps_new(void)
+{
+ struct comps *comps;
+ comps=calloc(sizeof(*comps),1);
+ assert(comps != NULL);
+ return comps;
+}
+
+void plover_comps_free(struct comps *comps)
+{
+ if (comps)
+ {
+ free(comps->vendor);
+ comps_group_free(comps->groups);
+ free(comps);
+ }
+}
+
+enum comps_state {
+ COMPS_STATE_BEGIN,
+ COMPS_STATE_ROOT,
+ COMPS_STATE_GROUP,
+ COMPS_STATE_GROUP_ID,
+ COMPS_STATE_GROUP_NAME,
+ COMPS_STATE_GROUP_DESCRIPTION,
+ COMPS_STATE_GROUP_DEFAULT,
+ COMPS_STATE_GROUP_USERVISIBLE,
+ COMPS_STATE_GROUP_PACKAGELIST,
+ COMPS_STATE_GROUP_PACKAGELIST_REQ,
+};
+
+struct comps_context {
+ XML_Parser parser;
+ enum comps_state state;
+ int unknown_elements;
+ char *vendor;
+ struct comps_group *group;
+ void *p;
+};
+
+static enum comps_requirement_type comps_to_requirement_type(const char *flags)
+{
+ if (strcmp(flags, "conditional") == 0)
+ return COMPS_REQUIREMENT_CONDITIONAL;
+ else if (strcmp(flags, "mandatory") == 0)
+ return COMPS_REQUIREMENT_MANDATORY;
+ else if (strcmp(flags, "default") == 0)
+ return COMPS_REQUIREMENT_DEFAULT;
+ else
+ return COMPS_REQUIREMENT_OPTIONAL;
+}
+
+static void comps_start_element(void *data,const char *name,const char **atts)
+{
+ struct comps_context *ctx = data;
+ struct comps_group *group;
+ struct comps_requirement *packages;
+ int i;
+#if 0
+ fprintf(stderr,"Starting element '");
+ switch(ctx->state)
+ {
+ case COMPS_STATE_BEGIN:
+ fprintf(stderr,"/");
+ break;
+ case COMPS_STATE_ROOT:
+ fprintf(stderr,"/comps/");
+ break;
+ case COMPS_STATE_GROUP:
+ fprintf(stderr,"/comps/group/");
+ break;
+ case COMPS_STATE_GROUP_ID:
+ fprintf(stderr,"/comps/group/id/");
+ break;
+ case COMPS_STATE_GROUP_NAME:
+ fprintf(stderr,"/comps/group/name/");
+ break;
+ case COMPS_STATE_GROUP_DESCRIPTION:
+ fprintf(stderr,"/comps/group/description/");
+ break;
+ case COMPS_STATE_GROUP_DEFAULT:
+ fprintf(stderr,"/comps/group/default/");
+ break;
+ case COMPS_STATE_GROUP_USERVISIBLE:
+ fprintf(stderr,"/comps/group/uservisible/");
+ break;
+ case COMPS_STATE_GROUP_PACKAGELIST:
+ fprintf(stderr,"/comps/group/packagelist/");
+ break;
+ case COMPS_STATE_GROUP_PACKAGELIST_REQ:
+ fprintf(stderr,"/comps/group/packagelist/packagereq/");
+ break;
+
+ }
+ for(i=0;i<ctx->unknown_elements;i++)
+ fprintf(stderr,"*/");
+ fprintf(stderr,"%s'\n",name);
+#endif
+ if (ctx->unknown_elements)
+ ctx->unknown_elements++;
+ else if (ctx->state==COMPS_STATE_BEGIN && !strcmp(name,"comps"))
+ {
+ ctx->state=COMPS_STATE_ROOT;
+ for (i=0;atts[i];i+=2)
+ {
+ if (!strcmp(atts[i],
+ "http://project.juiblex.co.uk/plover/ns/2009\xFFvendor"))
+ ctx->vendor=strdup(atts[i+1]);
+ }
+ }
+ else if (ctx->state==COMPS_STATE_ROOT && !strcmp(name,"group"))
+ {
+ ctx->state=COMPS_STATE_GROUP;
+ group=comps_group_new();
+ group->next=ctx->group;
+ ctx->group=group;
+ }
+ else if (ctx->state==COMPS_STATE_GROUP && !strcmp(name,"id"))
+ {
+ ctx->state=COMPS_STATE_GROUP_ID;
+ ctx->p=&ctx->group->id;
+ }
+ else if (ctx->state==COMPS_STATE_GROUP && !strcmp(name,"name"))
+ {
+ ctx->state=COMPS_STATE_GROUP_NAME;
+ ctx->p=&ctx->group->name;
+ }
+ else if (ctx->state==COMPS_STATE_GROUP && !strcmp(name,"description"))
+ {
+ ctx->state=COMPS_STATE_GROUP_DESCRIPTION;
+ ctx->p=&ctx->group->description;
+ }
+ else if (ctx->state==COMPS_STATE_GROUP && !strcmp(name,"default"))
+ {
+ ctx->state=COMPS_STATE_GROUP_DEFAULT;
+ ctx->p=&ctx->group->bydefault;
+ }
+ else if (ctx->state==COMPS_STATE_GROUP && !strcmp(name,"uservisible"))
+ {
+ ctx->state=COMPS_STATE_GROUP_USERVISIBLE;
+ ctx->p=&ctx->group->uservisible;
+ }
+ else if (ctx->state==COMPS_STATE_GROUP && !strcmp(name,"packagelist"))
+ ctx->state=COMPS_STATE_GROUP_PACKAGELIST;
+ else if (ctx->state==COMPS_STATE_GROUP_PACKAGELIST &&
+ !strcmp(name,"packagereq"))
+ {
+ packages=comps_package_requirement_new();
+ packages->next=ctx->group->packages;
+ ctx->group->packages=packages;
+ for (i=0;atts[i];i+=2)
+ {
+ if (!strcmp(atts[i],"type"))
+ packages->type=comps_to_requirement_type(atts[i+1]);
+ else if (!strcmp(atts[i],"requires"))
+ {
+ packages->requires=strdup(atts[i+1]);
+ packages->type=COMPS_REQUIREMENT_CONDITIONAL;
+ }
+ }
+ ctx->state=COMPS_STATE_GROUP_PACKAGELIST_REQ;
+ ctx->p=&packages->name;
+ }
+ else
+ ctx->unknown_elements++;
+}
+
+struct comps_list
+{
+ struct comps_list *next;
+ /* body */
+};
+
+void *comps_list_reverse(void *list)
+{
+ struct comps_list *link=list,*prev=NULL,*next;
+ while(link)
+ {
+ next=link->next;
+ link->next=prev;
+ prev=link;
+ link=next;
+ }
+ return prev;
+}
+
+static void comps_end_element(void *data,const char *name)
+{
+ struct comps_context *ctx=data;
+ if (ctx->unknown_elements)
+ ctx->unknown_elements--;
+ else
+ switch (ctx->state)
+ {
+ case COMPS_STATE_ROOT:
+ ctx->group=comps_list_reverse(ctx->group);
+ ctx->state=COMPS_STATE_BEGIN;
+ break;
+ case COMPS_STATE_GROUP:
+ ctx->group->packages=comps_list_reverse(ctx->group->packages);
+ ctx->state=COMPS_STATE_ROOT;
+ break;
+ case COMPS_STATE_GROUP_ID:
+ case COMPS_STATE_GROUP_NAME:
+ case COMPS_STATE_GROUP_DESCRIPTION:
+ case COMPS_STATE_GROUP_DEFAULT:
+ case COMPS_STATE_GROUP_USERVISIBLE:
+ case COMPS_STATE_GROUP_PACKAGELIST:
+ ctx->state=COMPS_STATE_GROUP;
+ break;
+ case COMPS_STATE_GROUP_PACKAGELIST_REQ:
+ ctx->state=COMPS_STATE_GROUP_PACKAGELIST;
+ break;
+ }
+#if 0
+ fprintf(stderr,"Ending element '");
+ switch(ctx->state)
+ {
+ case COMPS_STATE_BEGIN:
+ fprintf(stderr,"/");
+ break;
+ case COMPS_STATE_ROOT:
+ fprintf(stderr,"/comps/");
+ break;
+ case COMPS_STATE_GROUP:
+ fprintf(stderr,"/comps/group/");
+ break;
+ case COMPS_STATE_GROUP_ID:
+ fprintf(stderr,"/comps/group/id/");
+ break;
+ case COMPS_STATE_GROUP_NAME:
+ fprintf(stderr,"/comps/group/name/");
+ break;
+ case COMPS_STATE_GROUP_DESCRIPTION:
+ fprintf(stderr,"/comps/group/description/");
+ break;
+ case COMPS_STATE_GROUP_DEFAULT:
+ fprintf(stderr,"/comps/group/default/");
+ break;
+ case COMPS_STATE_GROUP_USERVISIBLE:
+ fprintf(stderr,"/comps/group/uservisible/");
+ break;
+ case COMPS_STATE_GROUP_PACKAGELIST:
+ fprintf(stderr,"/comps/group/packagelist/");
+ break;
+ case COMPS_STATE_GROUP_PACKAGELIST_REQ:
+ fprintf(stderr,"/comps/group/packagelist/packagereq/");
+ break;
+
+ }
+ {
+ int i;
+ for(i=0;i<ctx->unknown_elements;i++)
+ fprintf(stderr,"*/");
+ }
+ fprintf(stderr,"%s'\n",name);
+#endif
+}
+
+static void comps_character_data(void *data,const XML_Char *s,int len)
+{
+ struct comps_context *ctx=data;
+ char *str;
+ switch (ctx->state)
+ {
+ case COMPS_STATE_GROUP_ID:
+ case COMPS_STATE_GROUP_NAME:
+ case COMPS_STATE_GROUP_DESCRIPTION:
+ case COMPS_STATE_GROUP_PACKAGELIST_REQ:
+ *(char **)ctx->p=str=malloc(len+1);
+ memcpy(str,s,len);
+ str[len]='\0';
+ break;
+ case COMPS_STATE_GROUP_DEFAULT:
+ case COMPS_STATE_GROUP_USERVISIBLE:
+ *(int *)ctx->p=*s=='T'||*s=='t';
+ break;
+ }
+}
+
+#define XML_BUFFER_SIZE 4096
+
+struct comps *plover_comps_new_from_file(const char *filename)
+{
+ struct comps_context ctx={0};
+ void *buf;
+ int len;
+ FILE *fp;
+ XML_ParsingStatus status;
+ struct comps *comps;
+ fp=fopen(filename,"r");
+ if (!fp)
+ return NULL;
+ ctx.state=COMPS_STATE_BEGIN;
+ ctx.parser=XML_ParserCreateNS(NULL,'\xFF');
+ XML_SetUserData(ctx.parser,&ctx);
+ XML_SetElementHandler(ctx.parser,comps_start_element,comps_end_element);
+ XML_SetCharacterDataHandler(ctx.parser,comps_character_data);
+ do
+ {
+ XML_GetParsingStatus(ctx.parser,&status);
+ switch (status.parsing)
+ {
+ case XML_SUSPENDED:
+ XML_ResumeParser(ctx.parser);
+ break;
+ case XML_PARSING:
+ case XML_INITIALIZED:
+ buf=XML_GetBuffer(ctx.parser,XML_BUFFER_SIZE);
+ len=fread(buf,1,XML_BUFFER_SIZE,fp);
+ if (len<0)
+ {
+ comps_group_free(ctx.group);
+ XML_ParserFree(ctx.parser);
+ fclose(fp);
+ return NULL;
+ }
+ if (!XML_ParseBuffer(ctx.parser,len,!len))
+ {
+ comps_group_free(ctx.group);
+ XML_ParserFree(ctx.parser);
+ fclose(fp);
+ return NULL;
+ }
+ break;
+ case XML_FINISHED:
+ break;
+ }
+ } while (status.parsing!=XML_FINISHED);
+ XML_ParserFree(ctx.parser);
+ fclose(fp);
+ comps=plover_comps_new();
+ comps->vendor=ctx.vendor;
+ comps->groups=ctx.group;
+ return comps;
+}
+
+struct comps_group *plover_comps_lookup_group(struct comps *comps,
+ const char *id)
+{
+ struct comps_group *group;
+ for(group=comps->groups;group;group=group->next)
+ if (!strcmp(group->id,id))
+ return group;
+ return NULL;
+}
--- /dev/null
+/*
+ * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
+ * Copyright (C) 2008 Red Hat, Inc
+ * Copyright (C) 2009 J. Ali Harlow <ali@juiblex.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define _GNU_SOURCE
+
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <expat.h>
+#include <zlib.h>
+#include <razor.h>
+#include "plover.h"
+
+/* Import a yum filelist as a razor package set. */
+
+enum {
+ YUM_STATE_BEGIN,
+ YUM_STATE_PACKAGE_NAME,
+ YUM_STATE_PACKAGE_ARCH,
+ YUM_STATE_SUMMARY,
+ YUM_STATE_DESCRIPTION,
+ YUM_STATE_URL,
+ YUM_STATE_LICENSE,
+ YUM_STATE_CHECKSUM,
+ YUM_STATE_REQUIRES,
+ YUM_STATE_PROVIDES,
+ YUM_STATE_OBSOLETES,
+ YUM_STATE_CONFLICTS,
+ YUM_STATE_FILE
+};
+
+struct yum_context {
+ XML_Parser primary_parser;
+ XML_Parser filelists_parser;
+ XML_Parser current_parser;
+
+ struct razor_importer *importer;
+ struct import_property_context *current_property_context;
+ char name[256], arch[64], summary[512], description[4096];
+ char url[256], license[64], buffer[512], *p;
+ char pkgid[128];
+ uint32_t property_type;
+ int state;
+
+ int total, current;
+};
+
+static uint32_t
+yum_to_razor_relation (const char *flags)
+{
+ if (flags[0] == 'L') {
+ if (flags[1] == 'T')
+ return RAZOR_PROPERTY_LESS;
+ else
+ return RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL;
+ } else if (flags[0] == 'G') {
+ if (flags[1] == 'T')
+ return RAZOR_PROPERTY_GREATER;
+ else
+ return RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL;
+ } else
+ return RAZOR_PROPERTY_EQUAL;
+}
+
+static void
+yum_primary_start_element(void *data, const char *name, const char **atts)
+{
+ struct yum_context *ctx = data;
+ const char *n, *epoch, *version, *release;
+ char buffer[128];
+ uint32_t pre, relation, flags;
+ int i;
+
+ if (strcmp(name, "metadata") == 0) {
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "packages") == 0)
+ ctx->total = atoi(atts[i + 1]);
+ }
+ } else if (strcmp(name, "name") == 0) {
+ ctx->state = YUM_STATE_PACKAGE_NAME;
+ ctx->p = ctx->name;
+ } else if (strcmp(name, "arch") == 0) {
+ ctx->state = YUM_STATE_PACKAGE_ARCH;
+ ctx->p = ctx->arch;
+ } else if (strcmp(name, "version") == 0) {
+ epoch = NULL;
+ version = NULL;
+ release = NULL;
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "epoch") == 0)
+ epoch = atts[i + 1];
+ else if (strcmp(atts[i], "ver") == 0)
+ version = atts[i + 1];
+ else if (strcmp(atts[i], "rel") == 0)
+ release = atts[i + 1];
+ }
+ if (version == NULL || release == NULL) {
+ fprintf(stderr, "invalid version tag, "
+ "missing version or release attribute\n");
+ return;
+ }
+
+ razor_build_evr(buffer, sizeof buffer, epoch, version, release);
+ razor_importer_begin_package(ctx->importer,
+ ctx->name, buffer, ctx->arch);
+ } else if (strcmp(name, "summary") == 0) {
+ ctx->p = ctx->summary;
+ ctx->state = YUM_STATE_SUMMARY;
+ } else if (strcmp(name, "description") == 0) {
+ ctx->p = ctx->description;
+ ctx->state = YUM_STATE_DESCRIPTION;
+ } else if (strcmp(name, "url") == 0) {
+ ctx->p = ctx->url;
+ ctx->state = YUM_STATE_URL;
+ } else if (strcmp(name, "checksum") == 0) {
+ ctx->p = ctx->pkgid;
+ ctx->state = YUM_STATE_CHECKSUM;
+ } else if (strcmp(name, "rpm:license") == 0) {
+ ctx->p = ctx->license;
+ ctx->state = YUM_STATE_LICENSE;
+ } else if (strcmp(name, "rpm:requires") == 0) {
+ ctx->state = YUM_STATE_REQUIRES;
+ ctx->property_type = RAZOR_PROPERTY_REQUIRES;
+ } else if (strcmp(name, "rpm:provides") == 0) {
+ ctx->state = YUM_STATE_PROVIDES;
+ ctx->property_type = RAZOR_PROPERTY_PROVIDES;
+ } else if (strcmp(name, "rpm:obsoletes") == 0) {
+ ctx->state = YUM_STATE_OBSOLETES;
+ ctx->property_type = RAZOR_PROPERTY_OBSOLETES;
+ } else if (strcmp(name, "rpm:conflicts") == 0) {
+ ctx->state = YUM_STATE_CONFLICTS;
+ ctx->property_type = RAZOR_PROPERTY_CONFLICTS;
+ } else if (strcmp(name, "rpm:entry") == 0 &&
+ ctx->state != YUM_STATE_BEGIN) {
+ n = NULL;
+ epoch = NULL;
+ version = NULL;
+ release = NULL;
+ relation = RAZOR_PROPERTY_EQUAL;
+ pre = 0;
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "name") == 0)
+ n = atts[i + 1];
+ else if (strcmp(atts[i], "epoch") == 0)
+ epoch = atts[i + 1];
+ else if (strcmp(atts[i], "ver") == 0)
+ version = atts[i + 1];
+ else if (strcmp(atts[i], "rel") == 0)
+ release = atts[i + 1];
+ else if (strcmp(atts[i], "flags") == 0)
+ relation = yum_to_razor_relation(atts[i + 1]);
+ else if (strcmp(atts[i], "pre") == 0)
+ pre =
+ RAZOR_PROPERTY_PRE |
+ RAZOR_PROPERTY_POST |
+ RAZOR_PROPERTY_PREUN |
+ RAZOR_PROPERTY_POSTUN;
+ }
+
+ if (n == NULL) {
+ fprintf(stderr, "invalid rpm:entry, "
+ "missing name or version attributes\n");
+ return;
+ }
+
+ razor_build_evr(buffer, sizeof buffer, epoch, version, release);
+ flags = ctx->property_type | relation | pre;
+ razor_importer_add_property(ctx->importer, n, flags, buffer);
+ }
+}
+
+static void
+yum_primary_end_element (void *data, const char *name)
+{
+ struct yum_context *ctx = data;
+
+ switch (ctx->state) {
+ case YUM_STATE_PACKAGE_NAME:
+ case YUM_STATE_PACKAGE_ARCH:
+ case YUM_STATE_SUMMARY:
+ case YUM_STATE_DESCRIPTION:
+ case YUM_STATE_URL:
+ case YUM_STATE_LICENSE:
+ case YUM_STATE_CHECKSUM:
+ case YUM_STATE_FILE:
+ ctx->state = YUM_STATE_BEGIN;
+ break;
+ }
+
+ if (strcmp(name, "package") == 0) {
+ razor_importer_add_details(ctx->importer, ctx->summary,
+ ctx->description, ctx->url,
+ ctx->license);
+
+ XML_StopParser(ctx->current_parser, XML_TRUE);
+ ctx->current_parser = ctx->filelists_parser;
+
+ printf("\rimporting %d/%d", ++ctx->current, ctx->total);
+ fflush(stdout);
+ }
+}
+
+static void
+yum_character_data (void *data, const XML_Char *s, int len)
+{
+ struct yum_context *ctx = data;
+
+ switch (ctx->state) {
+ case YUM_STATE_PACKAGE_NAME:
+ case YUM_STATE_PACKAGE_ARCH:
+ case YUM_STATE_SUMMARY:
+ case YUM_STATE_DESCRIPTION:
+ case YUM_STATE_URL:
+ case YUM_STATE_LICENSE:
+ case YUM_STATE_CHECKSUM:
+ case YUM_STATE_FILE:
+ memcpy(ctx->p, s, len);
+ ctx->p += len;
+ *ctx->p = '\0';
+ break;
+ }
+}
+
+static void
+yum_filelists_start_element(void *data, const char *name, const char **atts)
+{
+ struct yum_context *ctx = data;
+ const char *pkg, *pkgid;
+ int i;
+
+ if (strcmp(name, "package") == 0) {
+ pkg = NULL;
+ pkgid = NULL;
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "name") == 0)
+ pkg = atts[i + 1];
+ else if (strcmp(atts[i], "pkgid") == 0)
+ pkgid = atts[i + 1];
+ }
+ if (strcmp(pkgid, ctx->pkgid) != 0)
+ fprintf(stderr, "primary.xml and filelists.xml "
+ "mismatch for %s: %s vs %s",
+ pkg, pkgid, ctx->pkgid);
+ } else if (strcmp(name, "file") == 0) {
+ ctx->state = YUM_STATE_FILE;
+ ctx->p = ctx->buffer;
+ }
+}
+
+static void
+yum_filelists_end_element (void *data, const char *name)
+{
+ struct yum_context *ctx = data;
+
+ ctx->state = YUM_STATE_BEGIN;
+ if (strcmp(name, "package") == 0) {
+ XML_StopParser(ctx->current_parser, XML_TRUE);
+ ctx->current_parser = ctx->primary_parser;
+ razor_importer_finish_package(ctx->importer);
+ } else if (strcmp(name, "file") == 0)
+ razor_importer_add_file(ctx->importer, ctx->buffer);
+
+}
+
+#define XML_BUFFER_SIZE 4096
+
+struct razor_set *
+plover_razor_set_create_from_yum(const char *base)
+{
+ struct yum_context ctx;
+ void *buf;
+ int len, ret;
+ gzFile primary, filelists;
+ XML_ParsingStatus status;
+
+ ctx.importer = razor_importer_create();
+ ctx.state = YUM_STATE_BEGIN;
+
+ ctx.primary_parser = XML_ParserCreate(NULL);
+ XML_SetUserData(ctx.primary_parser, &ctx);
+ XML_SetElementHandler(ctx.primary_parser,
+ yum_primary_start_element,
+ yum_primary_end_element);
+ XML_SetCharacterDataHandler(ctx.primary_parser,
+ yum_character_data);
+
+ ctx.filelists_parser = XML_ParserCreate(NULL);
+ XML_SetUserData(ctx.filelists_parser, &ctx);
+ XML_SetElementHandler(ctx.filelists_parser,
+ yum_filelists_start_element,
+ yum_filelists_end_element);
+ XML_SetCharacterDataHandler(ctx.filelists_parser,
+ yum_character_data);
+
+ primary = gzopen("primary.xml.gz", "rb");
+ if (primary == NULL)
+ return NULL;
+ filelists = gzopen("filelists.xml.gz", "rb");
+ if (filelists == NULL)
+ return NULL;
+
+ ctx.current_parser = ctx.primary_parser;
+
+ ctx.current = 0;
+
+ do {
+ XML_GetParsingStatus(ctx.current_parser, &status);
+ switch (status.parsing) {
+ case XML_SUSPENDED:
+ ret = XML_ResumeParser(ctx.current_parser);
+ break;
+ case XML_PARSING:
+ case XML_INITIALIZED:
+ buf = XML_GetBuffer(ctx.current_parser,
+ XML_BUFFER_SIZE);
+ if (ctx.current_parser == ctx.primary_parser)
+ len = gzread(primary, buf, XML_BUFFER_SIZE);
+ else
+ len = gzread(filelists, buf, XML_BUFFER_SIZE);
+ if (len < 0) {
+ fprintf(stderr,
+ "couldn't read input: %s\n",
+ strerror(errno));
+ return NULL;
+ }
+
+ XML_ParseBuffer(ctx.current_parser, len, len == 0);
+ break;
+ case XML_FINISHED:
+ break;
+ }
+ } while (status.parsing != XML_FINISHED);
+
+
+ XML_ParserFree(ctx.primary_parser);
+ XML_ParserFree(ctx.filelists_parser);
+
+ gzclose(primary);
+ gzclose(filelists);
+
+ printf ("\nsaving\n");
+ return razor_importer_finish(ctx.importer);
+}
--- /dev/null
+#ifndef __PLOVER_H__
+#define __PLOVER_H__
+
+#include <razor.h>
+
+enum comps_requirement_type
+{
+ COMPS_REQUIREMENT_OPTIONAL,
+ COMPS_REQUIREMENT_DEFAULT,
+ COMPS_REQUIREMENT_MANDATORY,
+ COMPS_REQUIREMENT_CONDITIONAL
+};
+
+struct comps_requirement
+{
+ struct comps_requirement *next;
+ enum comps_requirement_type type;
+ char *requires; /* For type == COMPS_REQUIREMENT_CONDITIONAL */
+ char *name;
+};
+
+struct comps_group
+{
+ struct comps_group *next;
+ char *id,*name,*description;
+ int bydefault,uservisible;
+ struct comps_requirement *packages;
+};
+
+struct comps
+{
+ char *vendor;
+ struct comps_group *groups;
+};
+
+char *plover_strconcat(const char *string,...);
+
+struct razor_set *plover_razor_set_create_from_yum(const char *base);
+
+struct razor_set *plover_relocate_packages(struct razor_set *set,
+ const char *base,struct razor_relocations *relocations);
+int plover_run_transaction(struct razor_transaction *trans,const char *base,
+ const char *install_root,struct razor_set *system,struct razor_set *next,
+ struct razor_relocations *relocations);
+int plover_install(const char *base,const char *prefix,char **pkgs);
+int plover_remove(char **pkgs);
+
+struct comps *plover_comps_new(void);
+struct comps *plover_comps_new_from_file(const char *filename);
+void plover_comps_free(struct comps *comps);
+struct comps_group *plover_comps_lookup_group(struct comps *comps,
+ const char *id);
+
+#endif /* __PLOVER_H__ */
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: plover
+Description: Plover packaging system
+Version: @VERSION@
+Requires: razor expat zlib
+Libs: -L${libdir} -lplover
+Cflags: -I${includedir}
--- /dev/null
+/*
+ * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
+ * Copyright (C) 2008 Red Hat, Inc
+ * Copyright (C) 2009 J. Ali Harlow <ali@juiblex.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <razor.h>
+#include "config.h"
+#include "plover/plover.h"
+
+static char *rpm_filename(const char *name,const char *version,const char *arch)
+{
+ const char *v;
+ v=strchr(version,':'); /* Skip epoch */
+ if (v)
+ v++;
+ else
+ v=version;
+ return plover_strconcat(name,"-",v,".",arch,".rpm",NULL);
+}
+
+struct razor_set *plover_relocate_packages(struct razor_set *set,
+ const char *base,struct razor_relocations *relocations)
+{
+ struct razor_importer *importer;
+ struct razor_property_iterator *prop_iter;
+ struct razor_package_iterator *pkg_iter;
+ struct razor_file_iterator *file_iter;
+ struct razor_package *package;
+ struct razor_property *property;
+ struct razor_rpm *rpm;
+ const char *name,*version,*arch,*summary,*desc,*url,*license;
+ char *s,*file;
+ uint32_t flags;
+ importer=razor_importer_create();
+ pkg_iter=razor_package_iterator_create(set);
+ while (razor_package_iterator_next(pkg_iter,&package,RAZOR_DETAIL_NAME,
+ &name,RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
+ RAZOR_DETAIL_SUMMARY,&summary,RAZOR_DETAIL_DESCRIPTION,&desc,
+ RAZOR_DETAIL_URL,&url,RAZOR_DETAIL_LICENSE,&license,RAZOR_DETAIL_LAST))
+ {
+ s=rpm_filename(name,version,arch);
+ file=plover_strconcat(base,"/rpms/",s,NULL);
+ free(s);
+ rpm=razor_rpm_open(file);
+ if (!rpm)
+ {
+ fprintf(stderr,"failed to open rpm %s\n",file);
+ razor_package_iterator_destroy(pkg_iter);
+ razor_importer_destroy(importer);
+ free(file);
+ return NULL;
+ }
+ free(file);
+ razor_relocations_set_rpm(relocations,rpm);
+ razor_rpm_close(rpm);
+ razor_importer_begin_package(importer,name,version,arch);
+ razor_importer_add_details(importer,summary,desc,url,license);
+ prop_iter=razor_property_iterator_create(set,package);
+ while (razor_property_iterator_next(prop_iter,&property,&name,&flags,
+ &version))
+ razor_importer_add_property(importer,name,flags,version);
+ razor_property_iterator_destroy(prop_iter);
+ file_iter=razor_file_iterator_create(set,package,0);
+ while (razor_file_iterator_next(file_iter,&name))
+ {
+ name=razor_relocations_apply(relocations,name);
+ razor_importer_add_file(importer,name);
+ }
+ razor_file_iterator_destroy(file_iter);
+ razor_importer_finish_package(importer);
+ }
+ razor_package_iterator_destroy(pkg_iter);
+ return razor_importer_finish(importer);
+}
+
+int plover_run_transaction(struct razor_transaction *trans,const char *base,
+ const char *install_root,struct razor_set *system,struct razor_set *next,
+ struct razor_relocations *relocations)
+{
+ struct razor_install_iterator *ii;
+ struct razor_package *package;
+ struct razor_set *set;
+ enum razor_install_action action;
+ struct razor_rpm *rpm;
+ const char *name,*version,*arch;
+ char *s,*file;
+ int count;
+ ii=razor_set_create_install_iterator(system,next);
+ printf("Running Transaction\n");
+ while (razor_install_iterator_next(ii,&set,&package,&action,&count))
+ {
+ if (action==RAZOR_INSTALL_ACTION_REMOVE)
+ {
+ razor_package_get_details(set,package,RAZOR_DETAIL_NAME,&name,
+ RAZOR_DETAIL_LAST);
+ printf(" Removing : %s ",name);
+ if (razor_package_remove(set,package,install_root,0)<0)
+ printf(
+ "\nWarning: one or more errors occurred while removing %s",
+ name);
+ printf("\n");
+ }
+ else
+ {
+ razor_package_get_details(set,package,RAZOR_DETAIL_NAME,&name,
+ RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
+ RAZOR_DETAIL_LAST);
+ printf(" Installing : %s ",name);
+ s=rpm_filename(name,version,arch);
+ file=plover_strconcat(base,"/rpms/",s,NULL);
+ free(s);
+ rpm=razor_rpm_open(file);
+ if (!rpm)
+ {
+ fprintf(stderr,"failed to open rpm %s\n",file);
+ free(file);
+ razor_install_iterator_destroy(ii);
+ return -1;
+ }
+ if (relocations)
+ razor_rpm_set_relocations(rpm,relocations);
+ razor_transaction_fixup_package(trans,package,rpm);
+ if (razor_rpm_install(rpm,install_root,1)<0)
+ {
+ fprintf(stderr,"failed to install rpm %s\n",file);
+ razor_rpm_close(rpm);
+ free(file);
+ razor_install_iterator_destroy(ii);
+ return -1;
+ }
+ razor_rpm_close(rpm);
+ free(file);
+ printf("\n");
+ }
+ }
+ razor_install_iterator_destroy(ii);
+ return 0;
+}
+
+static int plover_mark_package_for_update(struct razor_transaction *trans,
+ struct razor_set *set,const char *pkg)
+{
+ struct razor_package_iterator *pi;
+ struct razor_package *package;
+ const char *name;
+ int retval=-1;
+ pi=razor_package_iterator_create(set);
+ while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
+ RAZOR_DETAIL_LAST))
+ {
+ if (!strcmp(name,pkg))
+ {
+ razor_transaction_update_package(trans,package);
+ retval=0;
+ break;
+ }
+ }
+ razor_package_iterator_destroy(pi);
+ return retval;
+}
+
+int plover_install(const char *base,const char *prefix,char **pkgs)
+{
+ int i;
+ char *s;
+ char *install_root;
+ struct razor_root *root;
+ struct razor_set *system,*set,*upstream,*next;
+ struct razor_transaction *trans;
+ struct razor_relocations *relocations;
+ install_root=getenv("RAZOR_ROOT");
+ if (!install_root)
+ install_root="";
+ if (prefix)
+ {
+ relocations=razor_relocations_create();
+ razor_relocations_add(relocations,"/usr",prefix);
+ }
+ /*
+ * Calling razor_root_open() on a system that hasn't yet had
+ * razor_root_create() run generates a confusing error message
+ * on stderr. Avoid this by trying to open it R/O first which
+ * fails without generating any error.
+ */
+ set=razor_root_open_read_only(install_root);
+ if (set)
+ razor_set_destroy(set);
+ else
+ razor_root_create(install_root);
+ root=razor_root_open(install_root);
+ if (!root)
+ return -1;
+ system=razor_root_get_system_set(root);
+ if (!system)
+ {
+ razor_root_close(root);
+ return -1;
+ }
+ s=plover_strconcat(base,"/repodata",NULL);
+ if (!s)
+ {
+ razor_root_close(root);
+ return -1;
+ }
+ if (chdir(s)<0)
+ {
+ perror(s);
+ free(s);
+ razor_root_close(root);
+ return -1;
+ }
+ free(s);
+ set=plover_razor_set_create_from_yum(base);
+ if (!set)
+ {
+ razor_root_close(root);
+ return -1;
+ }
+ upstream=plover_relocate_packages(set,base,relocations);
+ razor_set_destroy(set);
+ trans=razor_transaction_create(system,upstream);
+ for(i=0;pkgs[i];i++)
+ if (plover_mark_package_for_update(trans,upstream,pkgs[i]))
+ {
+ fprintf(stderr,"%s: Package not found\n",pkgs[i]);
+ razor_root_close(root);
+ return -1;
+ }
+ razor_transaction_resolve(trans);
+ if (razor_transaction_describe(trans)>0)
+ {
+ razor_root_close(root);
+ return -1;
+ }
+ next=razor_transaction_commit(trans);
+ plover_run_transaction(trans,base,install_root,system,next,relocations);
+ razor_root_update(root,next);
+ razor_transaction_destroy(trans);
+ razor_set_destroy(next);
+ razor_set_destroy(upstream);
+ if (prefix)
+ razor_relocations_destroy(relocations);
+ return razor_root_commit(root);
+}
+
+static int plover_mark_packages_for_removal(struct razor_transaction *trans,
+ struct razor_set *set,const char *pkg)
+{
+ struct razor_package_iterator *pi;
+ struct razor_package *package;
+ const char *name;
+ int retval=pkg?-1:0;
+ pi=razor_package_iterator_create(set);
+ while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
+ RAZOR_DETAIL_LAST))
+ {
+ if (!pkg || !strcmp(name,pkg))
+ {
+ razor_transaction_remove_package(trans,package);
+ retval=0;
+ }
+ }
+ razor_package_iterator_destroy(pi);
+ return retval;
+}
+
+int plover_remove(char **pkgs)
+{
+ int i;
+ char *install_root;
+ struct razor_root *root;
+ struct razor_set *system,*set,*upstream,*next;
+ struct razor_transaction *trans;
+ install_root=getenv("RAZOR_ROOT");
+ if (!install_root)
+ install_root="";
+ set=razor_root_open_read_only(install_root);
+ if (!set)
+ return 0;
+ razor_set_destroy(set);
+ root=razor_root_open(install_root);
+ if (!root)
+ return -1;
+ system=razor_root_get_system_set(root);
+ if (!system)
+ {
+ razor_root_close(root);
+ return -1;
+ }
+ upstream=razor_set_create_without_root();
+ trans=razor_transaction_create(system,upstream);
+ if (pkgs)
+ for(i=0;pkgs[i];i++)
+ {
+ if (plover_mark_packages_for_removal(trans,system,pkgs[i]))
+ {
+ fprintf(stderr,"%s: Package not found\n",pkgs[i]);
+ razor_transaction_destroy(trans);
+ razor_set_destroy(upstream);
+ razor_set_destroy(system);
+ razor_root_close(root);
+ return -1;
+ }
+ }
+ else
+ plover_mark_packages_for_removal(trans,system,NULL);
+ razor_transaction_resolve(trans);
+ if (razor_transaction_describe(trans)>0)
+ {
+ razor_transaction_destroy(trans);
+ razor_set_destroy(upstream);
+ razor_set_destroy(system);
+ razor_root_close(root);
+ return -1;
+ }
+ next=razor_transaction_commit(trans);
+ plover_run_transaction(trans,NULL,install_root,system,next,NULL);
+ razor_root_update(root,next);
+ razor_transaction_destroy(trans);
+ razor_set_destroy(next);
+ razor_set_destroy(upstream);
+ return razor_root_commit(root);
+}
--- /dev/null
+/*
+ * Copyright (C) 2009 J. Ali Harlow <ali@juiblex.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include "config.h"
+#include "plover.h"
+
+char *plover_strconcat(const char *string,...)
+{
+ va_list ap,aq;
+ size_t n;
+ char *result=NULL,*t;
+ const char *s;
+ if (string)
+ {
+ va_start(ap,string);
+ va_copy(aq,ap);
+ n=strlen(string);
+ while((s=va_arg(aq,const char *)))
+ n+=strlen(s);
+ va_end(aq);
+ result=malloc(n+1);
+ if (result)
+ {
+ strcpy(result,string);
+ t=result+strlen(result);
+ while((s=va_arg(ap,const char *)))
+ {
+ strcpy(t,s);
+ t+=strlen(t);
+ }
+ }
+ va_end(ap);
+ }
+ return result;
+}
--- /dev/null
+AM_CFLAGS=-g $(SETUP_CFLAGS)
+LDADD=../plover/libplover.la $(SETUP_LIBS)
+INCLUDES=-I$(top_srcdir)
+
+bin_PROGRAMS=setup
+
+setup_SOURCES=setup.c
+setup_LDFLAGS=-all-static
+if HAVE_WINDRES
+setup_SOURCES+=resources.rc
+endif
+
+.png.pnm:
+ pngtopnm $< | pnmquant 256 > $@
+
+resources.$(OBJEXT): resources.rc setup.ico
+ $(WINDRES) resources.rc $@
+
+setup.ico: icon16.pnm icon22.pnm icon32.pnm
+ ppmtowinicon -output=$@ $^
+
+EXTRA_DIST=icon16.png icon22.png icon32.png
--- /dev/null
+#include <winver.h>
+
+MAINICON ICON "setup.ico"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,@PLOVER_MICRO_VERS
+ION@,0
+ PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,@PLOVER_MICRO_V
+ERSION@,0
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_APP
+ {
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "080904B0"
+ {
+ VALUE "CompanyName","The plover development team"
+ VALUE "FileDescription","Plover setup program"
+ VALUE "FileVersion","@PACKAGE_VERSION@"
+ VALUE "InternalName","setup"
+ VALUE "LegalCopyright",
+ "Copyright (c) 2009 J. Ali Harlow et al"
+ VALUE "OriginalFilename","setup.exe"
+ VALUE "ProductName","plover"
+ VALUE "ProductVersion","@PACKAGE_VERSION@"
+ }
+ }
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation",0x809,0x4B0
+ }
+ }
--- /dev/null
+/*
+ * Copyright (C) 2009 J. Ali Harlow <ali@juiblex.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#ifdef WIN32
+#include <windows.h>
+#include <shlobj.h>
+#endif
+#include <lua.h>
+#include "config.h"
+#include "plover/plover.h"
+#include "whelk/whelk.h"
+
+LUALIB_API int luaopen_posix(lua_State *L);
+
+struct vector {
+ int len,alloc;
+ char **strings;
+};
+
+struct vector *vector_new(void)
+{
+ struct vector *vector;
+ vector=malloc(sizeof(*vector));
+ vector->len=0;
+ vector->alloc=16;
+ vector->strings=calloc(vector->alloc,sizeof(char *));
+ return vector;
+}
+
+void vector_append(struct vector *vector,const char *str)
+{
+ if (++(vector->len)>=vector->alloc)
+ {
+ vector->alloc*=2;
+ vector->strings=realloc(vector->strings,vector->alloc*sizeof(char *));
+ }
+ vector->strings[vector->len-1]=strdup(str);
+ vector->strings[vector->len]=NULL;
+}
+
+int vector_contains(struct vector *vector,const char *str)
+{
+ int i;
+ for(i=0;i<vector->len;i++)
+ if (!strcmp(vector->strings[i],str))
+ return 1;
+ return 0;
+}
+
+void vector_free(struct vector *vector)
+{
+ int i;
+ for(i=0;i<vector->len;i++)
+ free(vector->strings[i]);
+ free(vector->strings);
+ free(vector);
+}
+
+static void *alloc_lua(void *user_data,void *ptr,size_t osize,size_t nsize)
+{
+ if (!nsize)
+ {
+ free(ptr);
+ return NULL;
+ }
+ else
+ return realloc(ptr,nsize);
+}
+
+void setup()
+{
+ char path[PATH_MAX],*s,*t,*prefix;
+ int changed;
+ struct comps *comps;
+ struct comps_group *group;
+ struct comps_requirement *pkg;
+ struct vector *packages=NULL;
+#ifdef WIN32
+ SHGetFolderPath(NULL,CSIDL_PROGRAM_FILES|CSIDL_FLAG_DONT_VERIFY,NULL,0,
+ path);
+ prefix=strdup(path);
+ GetModuleFileName(NULL,path,sizeof(path));
+ s=strrchr(path,'/');
+ if (s)
+ {
+ t=strrchr(s,'\\');
+ if (t)
+ s=t;
+ }
+ else
+ s=strrchr(path,'\\');
+ if (s)
+ *s='\0';
+#else
+ strcpy(path,"/tmp");
+ prefix=NULL;
+#endif
+ s=plover_strconcat(path,"/repodata/comps.xml",NULL);
+ comps=plover_comps_new_from_file(s);
+ if (!comps)
+ {
+ perror(s);
+ exit(1);
+ }
+ free(s);
+#ifdef WIN32
+ s=plover_strconcat(prefix,"\\",comps->vendor?comps->vendor:"Plover",NULL);
+ free(prefix);
+ prefix=s;
+#endif
+ group=plover_comps_lookup_group(comps,"base");
+ if (!group)
+ {
+ fprintf(stderr,"No base group found in comps.xml\n");
+ exit(1);
+ }
+ packages=vector_new();
+ do
+ {
+ changed=0;
+ for(pkg=group->packages;pkg;pkg=pkg->next)
+ {
+ if (vector_contains(packages,pkg->name))
+ continue;
+ if (pkg->type==COMPS_REQUIREMENT_DEFAULT ||
+ pkg->type==COMPS_REQUIREMENT_MANDATORY ||
+ pkg->type==COMPS_REQUIREMENT_CONDITIONAL &&
+ vector_contains(packages,pkg->requires))
+ {
+ changed++;
+ vector_append(packages,pkg->name);
+ }
+ }
+ } while(changed);
+ if (!packages->len)
+ {
+ fprintf(stderr,"No packages to install\n");
+ exit(1);
+ }
+ plover_install(path,prefix,packages->strings);
+ vector_free(packages);
+ plover_comps_free(comps);
+#ifdef WIN32
+ free(prefix);
+#endif
+}
+
+int main(int argc,char **argv)
+{
+ razor_set_lua_loader("posix",luaopen_posix);
+ razor_set_lua_loader("whelk",luaopen_whelk);
+ if (argc>1 && !strcmp(argv[1],"-u"))
+ plover_remove(NULL);
+ else
+ setup();
+}