RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Arkadiusz Miskiewicz Root: /v/rpm/cvs Email: [EMAIL PROTECTED] Module: rpm Date: 29-Jul-2008 17:36:09 Branch: HEAD Handle: 2008072915360900 Added files: rpm/tools rpmspecdump.c Modified files: rpm/tools Makefile.am Log: Tool for dumping spec tags. Summary: Revision Changes Path 2.113 +4 -1 rpm/tools/Makefile.am 2.1 +359 -0 rpm/tools/rpmspecdump.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/tools/Makefile.am ============================================================================ $ cvs diff -u -r2.112 -r2.113 Makefile.am --- rpm/tools/Makefile.am 16 Jun 2008 18:47:20 -0000 2.112 +++ rpm/tools/Makefile.am 29 Jul 2008 15:36:09 -0000 2.113 @@ -40,7 +40,7 @@ $(top_builddir)/build/librpmbuild.la \ $(RPM_LDADD_COMMON) -bin_PROGRAMS = rpm2cpio rpmcache rpmdigest rpmmtree rpmrepo +bin_PROGRAMS = rpm2cpio rpmcache rpmdigest rpmmtree rpmrepo rpmspecdump pkglibdir = @USRLIBRPM@ pkglib_PROGRAMS = rpmcmp rpmdeps @WITH_LIBELF_DEBUGEDIT@ @@ -66,6 +66,9 @@ rpmrepo_SOURCES = rpmrepo.c rpmrepo_LDADD = $(RPM_LDADD_COMMON) +rpmspecdump_SOURCES = rpmspecdump.c +rpmspecdump_LDADD = $(RPM_LDADD_COMMON) + ## ## Traditional rpm2cpio ## @@ . patch -p0 <<'@@ .' Index: rpm/tools/rpmspecdump.c ============================================================================ $ cvs diff -u -r0 -r2.1 rpmspecdump.c --- /dev/null 2008-07-29 17:36:08 +0200 +++ rpmspecdump.c 2008-07-29 17:36:09 +0200 @@ -0,0 +1,359 @@ +/* + * $Id: rpmspecdump.c,v 2.1 2008/07/29 15:36:09 arekm Exp $ + * + * Prints out following information in same format as %dump for builder: + * $ rpmbuild --nodigest --nosignature --nobuild -bp --define 'prep %{echo:dummy: PACKAGE_NAME %{name} }%dump' qemu.spec 2>&1 | awk '$2 ~ /^SOURCEURL/ {print} $2 ~ /^PATCHURL/ {print} $2 ~ /^nosource/ {print} $2 ~ /^PACKAGE_/ {print}' + * dummy: PACKAGE_NAME qemu ======================== + * -2: PACKAGE_RELEASE [EMAIL PROTECTED] + * -1: PACKAGE_VERSION 1.3.0pre11 + * -3: PATCHURL0 qemu-nostatic.patch + * -3: PATCHURL1 qemu-cc.patch + * -3: PATCHURL11 qemu-0.7.2-gcc4-opts.patch + * -3: PATCHURL13 qemu-dosguest.patch + * -3: PATCHURL3 qemu-dot.patch + * -3: PATCHURL4 qemu-gcc4_x86.patch + * -3: PATCHURL5 qemu-gcc4_ppc.patch + * -3: PATCHURL6 qemu-nosdlgui.patch + * -3: PATCHURL8 qemu-kde_virtual_workspaces_hack.patch + * -3: PATCHURL9 qemu-0.8.0-gcc4-hacks.patch + * -3: SOURCEURL0 http://fabrice.bellard.free.fr/qemu/qemu-0.9.0.tar.gz + * -3: SOURCEURL1 http://fabrice.bellard.free.fr/qemu/kqemu-1.3.0pre11.tar.gz + * + * $ rpm-specdump qemu.spec + * h PACKAGE_NAME qemu + * h PACKAGE_VERSION 0.9.0 + * h PACKAGE_RELEASE 60k + * s PATCHURL13 qemu-dosguest.patch + * s PATCHURL11 qemu-0.7.2-gcc4-opts.patch + * s PATCHURL9 qemu-0.8.0-gcc4-hacks.patch + * s PATCHURL8 qemu-kde_virtual_workspaces_hack.patch + * s PATCHURL6 qemu-nosdlgui.patch + * s PATCHURL5 qemu-gcc4_ppc.patch + * s PATCHURL4 qemu-gcc4_x86.patch + * s PATCHURL3 qemu-dot.patch + * s PATCHURL1 qemu-cc.patch + * s PATCHURL0 qemu-nostatic.patch + * s SOURCEURL1 http://fabrice.bellard.free.fr/qemu/kqemu-1.3.0pre11.tar.gz + * s SOURCEURL0 http://fabrice.bellard.free.fr/qemu/qemu-0.9.0.tar.gz + * + * And with NoSource: 1, NoSource: 2 + * + * $ rpmbuild --nodigest --nosignature --nobuild -bp --define 'prep %{echo:dummy: PACKAGE_NAME %{name} }%dump' ZendDebugger.spec 2>&1 | awk '$2 ~ /^SOURCEURL/ {print} $2 ~ /^PATCHURL/ {print} $2 ~ /^nosource/ {print} $2 ~ /^PACKAGE_/ {print}' + * dummy: PACKAGE_NAME ZendDebugger ======================== + * -2: PACKAGE_RELEASE 0.4 + * -1: PACKAGE_VERSION 5.2.10 + * -3: SOURCEURL0 http://downloads.zend.com/pdt/server-debugger/ZendDebugger-5.2.10-linux-glibc21-i386.tar.gz + * -3: SOURCEURL1 http://downloads.zend.com/pdt/server-debugger/ZendDebugger-5.2.10-linux-glibc23-x86_64.tar.gz + * -3: nosource 1 + * + * $ rpm-specdump ZendDebugger.spec + * h PACKAGE_NAME ZendDebugger + * h PACKAGE_VERSION 5.2.10 + * h PACKAGE_RELEASE 0.4 + * s SOURCEURL1 http://downloads.zend.com/pdt/server-debugger/ZendDebugger-5.2.10-linux-glibc23-x86_64.tar.gz + * s nosource 1 + * s SOURCEURL0 http://downloads.zend.com/pdt/server-debugger/ZendDebugger-5.2.10-linux-glibc21-i386.tar.gz + * s nosource 0 + * + * Compile with: + * gcc -lrpm -I/usr/include/rpm -lrpmbuild rpm-specdump.c -o rpm-specdump + * + * Version 0.1, 2008-01-23 + * - initial version, based on getdeps.c + */ + +#define _GNU_SOURCE + +// macros from kernel +#define RPM_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#define RPM_VERSION_CODE RPM_VERSION(RPM_FORMAT_VERSION, RPM_MAJOR_VERSION, RPM_MINOR_VERSION) + +#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> +#if RPM_VERSION_CODE < RPM_VERSION(5,0,0) +#include <header.h> +#endif +#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 + +// RPM 4.4.2 +#if RPM_VERSION_CODE < RPM_VERSION(4,4,9) +# define RPMFILE_SOURCE RPMBUILD_ISSOURCE +#endif + +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 RPM_VERSION_CODE >= RPM_VERSION(4,4,9) + if (parseSpec(ts, args.specfile, NULL, 0, NULL, NULL, 1, 1, 0) != 0) { +#else + if (parseSpec(ts, args.specfile, NULL, NULL, 1, NULL, NULL, 1, 1) != 0) { +#endif + return EXIT_FAILURE; + } + + s = rpmtsSpec(ts); + + // here starts the code for builder + const char *name = NULL, *version = NULL, *release = NULL; + +#if RPM_VERSION_CODE >= RPM_VERSION(4,4,9) + initSourceHeader(s, NULL); +#else + initSourceHeader(s); +#endif + Header h = s->sourceHeader; + +#if RPM_VERSION_CODE < RPM_VERSION(5,0,0) + 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 + ) { + fprintf(stderr, "NVR query failed\n"); + return EXIT_FAILURE; + } + +#else + { + HE_t he; + int rc; + + he = (HE_s*)memset(alloca(sizeof(*he)), 0, sizeof(*he)); + he->tag = (rpmTag) RPMTAG_NAME; + rc = headerGet(h, he, 0); + if (!rc) { + fprintf(stderr, "Name (NVR) query failed\n"); + return EXIT_FAILURE; + } + name = (char *)he->p.ptr; + + he = (HE_s*)memset(alloca(sizeof(*he)), 0, sizeof(*he)); + he->tag = (rpmTag) RPMTAG_VERSION; + rc = headerGet(h, he, 0); + if (!rc) { + fprintf(stderr, "Version (NVR) query failed\n"); + return EXIT_FAILURE; + } + version = (char *)he->p.ptr; + + he = (HE_s*)memset(alloca(sizeof(*he)), 0, sizeof(*he)); + he->tag = (rpmTag) RPMTAG_RELEASE; + rc = headerGet(h, he, 0); + if (!rc) { + fprintf(stderr, "Release (NVR) query failed\n"); + return EXIT_FAILURE; + } + release = (char *)he->p.ptr; + } +#endif + + printf("h PACKAGE_NAME %s\n", name); + printf("h PACKAGE_VERSION %s\n", version); + printf("h PACKAGE_RELEASE %s\n", release); + + struct Source *ps = s->sources; + while (ps) { + const char *type = (ps->flags & RPMFILE_SOURCE) ? "SOURCE" : "PATCH"; + 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; + } + + const char *arch = rpmExpand("%{_target_cpu}", NULL); + printf("m _target_cpu %s\n", arch); + + return(0); +} @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org