SOURCES: getdeps.c (NEW) - add to pld cvs

glen glen at pld-linux.org
Mon Jan 14 22:26:04 CET 2008


Author: glen                         Date: Mon Jan 14 21:26:04 2008 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- add to pld cvs

---- Files affected:
SOURCES:
   getdeps.c (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/getdeps.c
diff -u /dev/null SOURCES/getdeps.c:1.1
--- /dev/null	Mon Jan 14 22:26:04 2008
+++ SOURCES/getdeps.c	Mon Jan 14 22:25:59 2008
@@ -0,0 +1,295 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2003 Enrico Scholz <enrico.scholz at informatik.tu-chemnitz.de>
+//  
+// 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; version 2 of the License.
+//  
+// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// version 0.0.7, 2003-11-21
+//    * made it compilable with non-C99 compilers
+//
+// version 0.0.6, 2003-11-21
+//    * added rpm-4.0.4 compatibility (define RPM404 macro)
+//
+// version 0.0.5, 2003-11-21
+//    * added '--uid' and '--gid' options
+//    * use macros for option-ids
+//
+// version 0.0.4, 2003-11-19
+//    * set 'force' flag on parseSpec() to ignore missing sources & patches
+//
+// version 0.0.3, 2003-11-19
+//    * fixed buffer-overflow in '--with[out]' statements
+//
+// version 0.0.2, 2003-11-19
+//    * big rewrite; implemented nearly the full functionality
+//
+// version 0.0.1, 2003-11-19
+//    * initial version
+
+
+#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 <sys/time.h>
+#include <sys/types.h>
+
+#include <rpmbuild.h>
+#include <rpmlib.h>
+#include <header.h>
+
+#ifndef RPM404
+#  include <rpmts.h>
+#endif
+
+#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);
+}
+
+static void
+printDepSet(struct DepSet const *set, char const *prefix)
+{
+  ssize_t	i;
+  for (i=0; i<set->cnt; ++i)
+    printf("%s%08x %s %s\n", prefix, set->flags[i], set->name[i], set->version[i]);
+}
+
+static void
+evaluateHeader(Header h)
+{
+  int32_t		cnt[3];
+  struct DepSet		buildreqs = { 0,0,0,0 };
+  struct DepSet		conflicts = { 0,0,0,0 };
+
+  if (headerGetEntry(h, RPMTAG_REQUIREFLAGS,    0, (void**)&buildreqs.flags,   cnt+0) &&
+      headerGetEntry(h, RPMTAG_REQUIRENAME,     0, (void**)&buildreqs.name,    cnt+1) &&
+      headerGetEntry(h, RPMTAG_REQUIREVERSION,  0, (void**)&buildreqs.version, cnt+2)) {
+    assert(cnt[0]==cnt[1] && cnt[1]==cnt[2]);
+    buildreqs.cnt = cnt[0];
+  }
+
+  if (headerGetEntry(h, RPMTAG_CONFLICTFLAGS,   0, (void**)&conflicts.flags,   cnt+0) &&
+      headerGetEntry(h, RPMTAG_CONFLICTNAME,    0, (void**)&conflicts.name,    cnt+1) &&
+      headerGetEntry(h, RPMTAG_CONFLICTVERSION, 0, (void**)&conflicts.version, cnt+2)) {
+    assert(cnt[0]==cnt[1] && cnt[1]==cnt[2]);
+    conflicts.cnt = cnt[0];
+  }
+
+  printDepSet(&buildreqs, "+ ");
+  printDepSet(&conflicts, "- ");
+}
+
+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);
+
+
+#ifndef RPM404
+  rpmts			ts = rpmtsCreate();
+  if (parseSpec(ts, args.specfile, 0,0, 1, 0,0, 1,1)!=0) {
+    return EXIT_FAILURE;
+  }
+  
+  s = rpmtsSpec(ts);
+#else
+  if (parseSpec(&s, args.specfile, 0,0, 1, 0,0, 1,1)!=0) {
+    return EXIT_FAILURE;
+  }
+#endif
+
+  evaluateHeader(s->buildRestrictions);
+}
+
+/// Local Variables:
+/// compile-command: "make getdeps LDFLAGS='-lrpm       -lrpmbuild'       CFLAGS='-I/usr/include/rpm       -Wall -W -pedantic --std=c99 -g3 -O0'"
+/// compile-commandX: "make getdeps LDFLAGS='-lrpm-4.0.4 -lrpmbuild-4.0.4 -lrpmio-4.0.4 -lrpmdb-4.0.4 -lpopt' CFLAGS='-I/usr/include/rpm-4.0.4 -Wall -W -pedantic --std=c99 -g3 -O0 -DRPM404'"
+/// End:
================================================================


More information about the pld-cvs-commit mailing list