SOURCES: rpm-specdump.c (NEW) - provide same output as builder cac...
glen
glen at pld-linux.org
Wed Jan 23 02:05:27 CET 2008
Author: glen Date: Wed Jan 23 01:05:26 2008 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- provide same output as builder cache_rpm_dump, except source header is queried
---- Files affected:
SOURCES:
rpm-specdump.c (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/rpm-specdump.c
diff -u /dev/null SOURCES/rpm-specdump.c:1.1
--- /dev/null Wed Jan 23 02:05:26 2008
+++ SOURCES/rpm-specdump.c Wed Jan 23 02:05:21 2008
@@ -0,0 +1,280 @@
+/*
+ * $Id$
+ *
+ * Prints out following information in same format as %dump for builder:
+ *
+ * $2 ~ /^PACKAGE_/ {print}
+ * $2 ~ /^SOURCEURL/ {print}
+ * $2 ~ /^PATCHURL/ {print}
+ * $2 ~ /^nosource/ {print}
+ * $2 ~ /^PACKAGE_/ {print}
+ *
+ * $ rpm-specdump qemu.spec
+ * h PACKAGE_NAME qemu
+ * h PACKAGE_VERSION 0.9.0
+ * h PACKAGE_RELEASE 60k
+ * source: /home/glen/rpm/pld/SOURCES
+ * patch: /home/glen/rpm/pld/SOURCES
+ * s PATCH13 /home/glen/rpm/pld/SOURCES/qemu-dosguest.patch
+ * s PATCH11 /home/glen/rpm/pld/SOURCES/qemu-0.7.2-gcc4-opts.patch
+ * s PATCH9 /home/glen/rpm/pld/SOURCES/qemu-0.8.0-gcc4-hacks.patch
+ * s PATCH8 /home/glen/rpm/pld/SOURCES/qemu-kde_virtual_workspaces_hack.patch
+ * s PATCH6 /home/glen/rpm/pld/SOURCES/qemu-nosdlgui.patch
+ * s PATCH5 /home/glen/rpm/pld/SOURCES/qemu-gcc4_ppc.patch
+ * s PATCH4 /home/glen/rpm/pld/SOURCES/qemu-gcc4_x86.patch
+ * s PATCH3 /home/glen/rpm/pld/SOURCES/qemu-dot.patch
+ * s PATCH1 /home/glen/rpm/pld/SOURCES/qemu-cc.patch
+ * s PATCH0 /home/glen/rpm/pld/SOURCES/qemu-nostatic.patch
+ * s SOURCE1 /home/glen/rpm/pld/SOURCES/kqemu-1.3.0pre11.tar.gz
+ * s SOURCEURL1 http://fabrice.bellard.free.fr/qemu/kqemu-1.3.0pre11.tar.gz
+ * s SOURCE0 /home/glen/rpm/pld/SOURCES/qemu-0.9.0.tar.gz
+ * s SOURCEURL0 http://fabrice.bellard.free.fr/qemu/qemu-0.9.0.tar.gz
+ *
+ * Version 0.1, 2008-01-23
+ * - initial version, based on getdeps.c
+ */
+
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <getopt.h>
+#include <stdbool.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+#include <grp.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <rpmbuild.h>
+#include <rpmlib.h>
+#include <header.h>
+#include <rpmts.h>
+
+#define ARG_WITH 1024
+#define ARG_WITHOUT 1025
+#define ARG_DEFINE 1026
+#define ARG_TARGET 1027
+#define ARG_RCFILE 1028
+#define ARG_CHROOT 1029
+#define ARG_UID 1030
+#define ARG_GID 1031
+
+static struct option const
+CMDLINE_OPTIONS[] = {
+ { "help", no_argument, 0, 'h' },
+ { "version", no_argument, 0, 'v' },
+ { "with", required_argument, 0, ARG_WITH },
+ { "without", required_argument, 0, ARG_WITHOUT },
+ { "define", required_argument, 0, ARG_DEFINE },
+ { "target", required_argument, 0, ARG_TARGET },
+ { "rcfile", required_argument, 0, ARG_RCFILE },
+ { "chroot", required_argument, 0, ARG_CHROOT },
+ { "uid", required_argument, 0, ARG_UID },
+ { "gid", required_argument, 0, ARG_GID },
+ { 0,0,0,0 }
+};
+
+struct Arguments
+{
+ char const * target;
+ char const * rcfile;
+ char const * chroot;
+ uid_t uid;
+ gid_t gid;
+
+ struct {
+ char const ** values;
+ size_t cnt;
+ size_t reserved;
+ } macros;
+
+ char const * specfile;
+};
+
+struct DepSet {
+ int32_t const * flags;
+ char const ** name;
+ char const ** version;
+ ssize_t cnt;
+};
+
+inline static void
+writeStr(int fd, char const *cmd)
+{
+ (void)write(fd, cmd, strlen(cmd));
+}
+
+#define WRITE_MSG(FD,X) (void)(write(FD,X,sizeof(X)-1))
+#define WRITE_STR(FD,X) writeStr(FD,X)
+
+static void
+showHelp(int fd, char const *cmd, int res)
+{
+ char tmp[strlen(cmd)+1];
+ strcpy(tmp, cmd);
+
+ WRITE_MSG(fd, "Usage: ");
+ WRITE_STR(fd, basename(tmp));
+ WRITE_MSG(fd,
+ " [--define '<macro> <value>']* [--with[out] <key>]* [--chroot <dir>]\n"
+ " [--target <target>] [--rcfile <rcfile>] [--] <specfile>\n");
+ exit(res);
+}
+
+static void
+addDefine(struct Arguments *args, char const *val)
+{
+ register size_t c = args->macros.cnt;
+ if (args->macros.reserved <= c) {
+ args->macros.reserved *= 2;
+ args->macros.reserved += 1;
+
+ args->macros.values = realloc(args->macros.values,
+ args->macros.reserved * sizeof(char const *));
+ if (args->macros.values==0) {
+ perror("realloc()");
+ exit(1);
+ }
+ }
+
+ args->macros.values[c] = strdup(val);
+ ++args->macros.cnt;
+}
+
+static void
+setWithMacro(struct Arguments *args,
+ char const *name, char const *prefix, size_t prefix_len)
+{
+ size_t len = strlen(name);
+ char tmp[2*len + 2*prefix_len + sizeof("__ ---")];
+ char * ptr = tmp;
+
+ // set '_<prefix>_<name>'
+ *ptr++ = '_';
+ memcpy(ptr, prefix, prefix_len); ptr += prefix_len;
+ *ptr++ = '_';
+ memcpy(ptr, name, len); ptr += len;
+ *ptr++ = ' ';
+
+ // append ' --<prefix>-<name>'
+ *ptr++ = '-';
+ *ptr++ = '-';
+ memcpy(ptr, prefix, prefix_len); ptr += prefix_len;
+ *ptr++ = '-';
+ memcpy(ptr, name, len); ptr += len;
+ *ptr = '\0';
+
+ addDefine(args, tmp);
+}
+
+
+static void
+parseArgs(struct Arguments *args, int argc, char *argv[])
+{
+ while (1) {
+ int c = getopt_long(argc, argv, "", CMDLINE_OPTIONS, 0);
+ if (c==-1) break;
+ switch (c) {
+ case 'h' : showHelp(1, argv[0], 0);
+ case ARG_TARGET : args->target = optarg; break;
+ case ARG_RCFILE : args->rcfile = optarg; break;
+ case ARG_CHROOT : args->chroot = optarg; break;
+ case ARG_UID : args->uid = atoi(optarg); break;
+ case ARG_GID : args->gid = atoi(optarg); break;
+ case ARG_DEFINE : addDefine(args, optarg); break;
+ case ARG_WITH : setWithMacro(args, optarg, "with", 4); break;
+ case ARG_WITHOUT : setWithMacro(args, optarg, "without", 7); break;
+ default:
+ WRITE_MSG(2, "Try '");
+ WRITE_STR(2, argv[0]);
+ WRITE_MSG(2, " --help\" for more information.\n");
+ exit(1);
+ }
+ }
+
+ if (optind+1!=argc) {
+ write(2, "No/too much specfile(s) given; aborting\n", 40);
+ exit(1);
+ }
+
+ if (args->gid==(gid_t)(-1))
+ args->gid = args->uid;
+
+ args->specfile = argv[optind];
+}
+
+static void
+setMacros(char const * const *macros, size_t cnt)
+{
+ size_t i;
+ for (i=0; i<cnt; ++i)
+ rpmDefineMacro(rpmGlobalMacroContext, macros[i], 0);
+}
+
+int main(int argc, char *argv[])
+{
+struct Arguments args = { 0,0,0,-1,-1, {0,0,0}, 0 };
+Spec s;
+
+ parseArgs(&args, argc, argv);
+
+ if ((args.chroot && chroot(args.chroot)==-1) ||
+ (args.uid!=(uid_t)(-1) && (setgroups(0,0) ==-1 || getgroups(0,0)!=0)) ||
+ (args.gid!=(gid_t)(-1) && (setgid(args.gid)==-1 || getgid()!=args.gid)) ||
+ (args.uid!=(uid_t)(-1) && (setuid(args.uid)==-1 || getuid()!=args.uid))) {
+
+ perror("chroot/setuid/setgid()");
+ return EXIT_FAILURE;
+ }
+
+ rpmReadConfigFiles(args.rcfile, args.target);
+ setMacros(args.macros.values, args.macros.cnt);
+
+ rpmts ts = rpmtsCreate();
+ if (parseSpec(ts, args.specfile, NULL, 0, NULL, NULL, 0, 1, 1) != 0) {
+ return EXIT_FAILURE;
+ }
+
+ s = rpmtsSpec(ts);
+ Header h = s->sourceHeader;
+ const char *name, *version, *release;
+
+ initSourceHeader(s, NULL);
+
+ if (
+ headerGetEntryMinMemory(h, RPMTAG_NAME, NULL, (void *)&name, NULL) == 0 ||
+ headerGetEntryMinMemory(h, RPMTAG_VERSION, NULL, (void *)&version, NULL) == 0 ||
+ headerGetEntryMinMemory(h, RPMTAG_RELEASE, NULL, (void *)&release, NULL) == 0
+ ) {
+ printf(stderr, "NVR query failed\n");
+ return EXIT_FAILURE;
+ }
+
+ printf("h PACKAGE_NAME %s\n", name);
+ printf("h PACKAGE_VERSION %s\n", version);
+ printf("h PACKAGE_RELEASE %s\n", release);
+ // XXX kill the ! hack
+ const char *sourcedir = rpmExpand("%{_sourcedir}!"); *(strchr(sourcedir, '!')) = '\0';
+ const char *patchdir = rpmExpand("%{_patchdir}!"); *(strchr(patchdir, '!')) = '\0';
+
+ struct Source *ps = s->sources;
+ while (ps) {
+ const char *type = (ps->flags & RPMFILE_SOURCE) ? "SOURCE" : "PATCH";
+ const char *sdir = (ps->flags & RPMFILE_SOURCE) ? sourcedir : patchdir;
+ printf("s %s%d %s/%s\n", type, ps->num, sdir, ps->source);
+ if (ps->source != ps->fullSource) {
+ printf("s %sURL%d %s\n", type, ps->num, ps->fullSource);
+ }
+ if (ps->flags & RPMFILE_GHOST) {
+ printf("s nosource %d\n", ps->num);
+ }
+ ps = ps->next;
+ }
+
+ return(0);
+}
================================================================
More information about the pld-cvs-commit
mailing list