summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am6
-rw-r--r--lib/depends.c4
-rw-r--r--lib/header.c241
-rw-r--r--lib/header.h28
-rw-r--r--lib/header_internal.c128
-rw-r--r--lib/header_internal.h127
-rw-r--r--lib/misc.c112
-rw-r--r--lib/misc.h7
-rw-r--r--lib/rpmcli.h6
-rw-r--r--lib/rpminstall.c2
-rw-r--r--lib/rpmlib.h36
-rw-r--r--lib/rpmvercmp.c103
-rw-r--r--lib/signature.c4
-rw-r--r--lib/transaction.c2
-rw-r--r--lib/verify.c2
15 files changed, 408 insertions, 400 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f442f9879..245883c49 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -16,7 +16,7 @@ pkgincdir = $(pkgincludedir)
pkginc_HEADERS = \
header.h misc.h rpmcli.h rpmlib.h stringbuf.h
noinst_HEADERS = \
- cpio.h depends.h fsm.h \
+ cpio.h depends.h fsm.h header_internal.h \
manifest.h md5.h psm.h \
rpmlead.h signature.h
@@ -32,9 +32,9 @@ LIBS =
lib_LTLIBRARIES = librpm.la
librpm_la_SOURCES = \
cpio.c depends.c formats.c fs.c fsm.c getdate.c \
- header.c manifest.c md5.c md5sum.c misc.c package.c \
+ header.c header_internal.c manifest.c md5.c md5sum.c misc.c package.c \
problems.c poptBT.c poptI.c poptK.c poptQV.c psm.c query.c \
- rpmchecksig.c rpminstall.c rpmlead.c rpmlibprov.c rpmrc.c \
+ rpmchecksig.c rpminstall.c rpmlead.c rpmlibprov.c rpmrc.c rpmvercmp.c \
signature.c stringbuf.c tagName.c tagtable.c transaction.c \
verify.c
diff --git a/lib/depends.c b/lib/depends.c
index dd4917be7..44e33b7cb 100644
--- a/lib/depends.c
+++ b/lib/depends.c
@@ -11,8 +11,8 @@
#include <rpmlib.h>
#include "depends.h"
-#include "rpmdb.h"
-#include "misc.h"
+#include "rpmdb.h" /* XXX response cache needs dbiOpen et al. */
+
#include "debug.h"
/*@access dbiIndex@*/ /* XXX compared with NULL */
diff --git a/lib/header.c b/lib/header.c
index 5a1c5ee95..3237a9d4e 100644
--- a/lib/header.c
+++ b/lib/header.c
@@ -14,11 +14,7 @@
#include "system.h"
-#if !defined(__LCLINT__)
-#include <netinet/in.h>
-#endif /* __LCLINT__ */
-
-#include <header.h>
+#include <header_internal.h>
#include "debug.h"
@@ -59,98 +55,6 @@ static int typeSizes[] = {
};
/**
- * Description of tag data.
- */
-struct entryInfo {
- int_32 tag; /*!< Tag identifier. */
- int_32 type; /*!< Tag data type. */
- int_32 offset; /*!< Offset into data segment (ondisk only). */
- int_32 count; /*!< Number of tag elements. */
-};
-
-#define REGION_TAG_TYPE RPM_BIN_TYPE
-#define REGION_TAG_COUNT sizeof(struct entryInfo)
-
-#define ENTRY_IS_REGION(_e) ((_e)->info.tag < HEADER_I18NTABLE)
-#define ENTRY_IN_REGION(_e) ((_e)->info.offset < 0)
-
-/**
- * A single tag from a Header.
- */
-struct indexEntry {
- struct entryInfo info; /*!< Description of tag data. */
-/*@owned@*/ void * data; /*!< Location of tag data. */
- int length; /*!< No. bytes of data. */
- int rdlen; /*!< No. bytes of data in region. */
-};
-
-/**
- * The Header data structure.
- */
-struct headerToken {
-/*@owned@*/ struct indexEntry * index; /*!< Array of tags. */
- int indexUsed; /*!< Current size of tag array. */
- int indexAlloced; /*!< Allocated size of tag array. */
- int region_allocated; /*!< Is 1st header region allocated? */
- int sorted; /*!< Are header entries sorted? */
- int legacy; /*!< Header came from legacy source? */
-/*@refs@*/ int nrefs; /*!< Reference count. */
-};
-
-/**
- */
-struct sprintfTag {
-/*@null@*/ headerTagTagFunction ext; /*!< if NULL tag element is invalid */
- int extNum;
- int_32 tag;
- int justOne;
- int arrayCount;
-/*@kept@*/ char * format;
-/*@kept@*/ /*@null@*/ char * type;
- int pad;
-};
-
-/**
- */
-struct extensionCache {
- int_32 type;
- int_32 count;
- int avail;
- int freeit;
-/*@owned@*/ const void * data;
-};
-
-/**
- */
-struct sprintfToken {
- enum {
- PTOK_NONE = 0,
- PTOK_TAG,
- PTOK_ARRAY,
- PTOK_STRING,
- PTOK_COND
- } type;
- union {
- struct {
- /*@only@*/ struct sprintfToken * format;
- int numTokens;
- } array;
- struct sprintfTag tag;
- struct {
- /*@dependent@*/ char * string;
- int len;
- } string;
- struct {
- /*@only@*/ /*@null@*/ struct sprintfToken * ifFormat;
- int numIfTokens;
- /*@only@*/ /*@null@*/ struct sprintfToken * elseFormat;
- int numElseTokens;
- struct sprintfTag tag;
- } cond;
- } u;
-};
-
-/**
* Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
* @param p memory to free
* @return NULL always
@@ -1062,124 +966,6 @@ exit:
return h;
}
-void headerDump(Header h, FILE *f, int flags,
- const struct headerTagTableEntry * tags)
-{
- int i;
- struct indexEntry *p;
- const struct headerTagTableEntry * tage;
- const char *tag;
- char *type;
-
- /* First write out the length of the index (count of index entries) */
- fprintf(f, "Entry count: %d\n", h->indexUsed);
-
- /* Now write the index */
- p = h->index;
- fprintf(f, "\n CT TAG TYPE "
- " OFSET COUNT\n");
- for (i = 0; i < h->indexUsed; i++) {
- switch (p->info.type) {
- case RPM_NULL_TYPE: type = "NULL"; break;
- case RPM_CHAR_TYPE: type = "CHAR"; break;
- case RPM_BIN_TYPE: type = "BIN"; break;
- case RPM_INT8_TYPE: type = "INT8"; break;
- case RPM_INT16_TYPE: type = "INT16"; break;
- case RPM_INT32_TYPE: type = "INT32"; break;
- /*case RPM_INT64_TYPE: type = "INT64"; break;*/
- case RPM_STRING_TYPE: type = "STRING"; break;
- case RPM_STRING_ARRAY_TYPE: type = "STRING_ARRAY"; break;
- case RPM_I18NSTRING_TYPE: type = "I18N_STRING"; break;
- default: type = "(unknown)"; break;
- }
-
- tage = tags;
- while (tage->name && tage->val != p->info.tag) tage++;
-
- if (!tage->name)
- tag = "(unknown)";
- else
- tag = tage->name;
-
- fprintf(f, "Entry : %3.3d (%d)%-14s %-18s 0x%.8x %.8d\n", i,
- p->info.tag, tag, type, (unsigned) p->info.offset,
- (int) p->info.count);
-
- if (flags & HEADER_DUMP_INLINE) {
- char *dp = p->data;
- int c = p->info.count;
- int ct = 0;
-
- /* Print the data inline */
- switch (p->info.type) {
- case RPM_INT32_TYPE:
- while (c--) {
- fprintf(f, " Data: %.3d 0x%08x (%d)\n", ct++,
- (unsigned) *((int_32 *) dp),
- (int) *((int_32 *) dp));
- dp += sizeof(int_32);
- }
- break;
-
- case RPM_INT16_TYPE:
- while (c--) {
- fprintf(f, " Data: %.3d 0x%04x (%d)\n", ct++,
- (unsigned) (*((int_16 *) dp) & 0xffff),
- (int) *((int_16 *) dp));
- dp += sizeof(int_16);
- }
- break;
- case RPM_INT8_TYPE:
- while (c--) {
- fprintf(f, " Data: %.3d 0x%02x (%d)\n", ct++,
- (unsigned) (*((int_8 *) dp) & 0xff),
- (int) *((int_8 *) dp));
- dp += sizeof(int_8);
- }
- break;
- case RPM_BIN_TYPE:
- while (c > 0) {
- fprintf(f, " Data: %.3d ", ct);
- while (c--) {
- fprintf(f, "%02x ", (unsigned) (*(int_8 *)dp & 0xff));
- ct++;
- dp += sizeof(int_8);
- if (! (ct % 8)) {
- /*@loopbreak@*/ break;
- }
- }
- fprintf(f, "\n");
- }
- break;
- case RPM_CHAR_TYPE:
- while (c--) {
- char ch = (char) *((char *) dp);
- fprintf(f, " Data: %.3d 0x%2x %c (%d)\n", ct++,
- (unsigned)(ch & 0xff),
- (isprint(ch) ? ch : ' '),
- (int) *((char *) dp));
- dp += sizeof(char);
- }
- break;
- case RPM_STRING_TYPE:
- case RPM_STRING_ARRAY_TYPE:
- case RPM_I18NSTRING_TYPE:
- while (c--) {
- fprintf(f, " Data: %.3d %s\n", ct++, (char *) dp);
- dp = strchr(dp, 0);
- dp++;
- }
- break;
- default:
- fprintf(stderr, _("Data type %d not supported\n"),
- (int) p->info.type);
- break;
- }
- }
- p++;
- }
-}
-
/**
* Find matching (tag,type) entry in header.
* @param h header
@@ -1497,11 +1283,6 @@ Header headerLink(Header h)
/*@-refcounttrans@*/ return h; /*@=refcounttrans@*/
}
-int headerUsageCount(Header h)
-{
- return h->nrefs;
-}
-
unsigned int headerSizeof(Header h, enum hMagic magicp)
{
struct indexEntry * entry;
@@ -1641,26 +1422,6 @@ int headerAddEntry(Header h, int_32 tag, int_32 type, const void *p, int_32 c)
return 1;
}
-char **
-headerGetLangs(Header h)
-{
- char **s, *e, **table;
- int i, type, count;
-
- if (!headerGetRawEntry(h, HEADER_I18NTABLE, &type, (const void **)&s, &count))
- return NULL;
-
- /* XXX xcalloc never returns NULL. */
- if ((table = (char **)xcalloc((count+1), sizeof(char *))) == NULL)
- return NULL;
-
- for (i = 0, e = *s; i < count > 0; i++, e += strlen(e)+1)
- table[i] = e;
- table[count] = NULL;
-
- /*@-nullret@*/ return table; /*@=nullret@*/ /* LCL: double indirection? */
-}
-
int headerAddI18NString(Header h, int_32 tag, const char * string, const char * lang)
{
struct indexEntry * table, * entry;
diff --git a/lib/header.h b/lib/header.h
index 0412507f2..1bb5b3c1d 100644
--- a/lib/header.h
+++ b/lib/header.h
@@ -266,25 +266,6 @@ Header headerLink(Header h)
/*@null@*/ Header headerFree( /*@null@*/ /*@killref@*/ Header h)
/*@modifies h @*/;
-/** \ingroup header
- * Return header reference count.
- * @param h header
- * @return no. of references
- */
-/*@unused@*/
-int headerUsageCount(Header h) /*@*/;
-
-/** \ingroup header
- * Dump a header in human readable format (for debugging).
- * @param h header
- * @param flags 0 or HEADER_DUMP_LINLINE
- * @param tags array of tag name/value pairs
- */
-/*@unused@*/
-void headerDump(Header h, FILE *f, int flags,
- const struct headerTagTableEntry * tags);
-#define HEADER_DUMP_INLINE 1
-
/*@-redef@*/ /* LCL: no clue */
typedef const char * errmsg_t;
/*@=redef@*/
@@ -339,15 +320,6 @@ int headerModifyEntry(Header h, int_32 tag, int_32 type,
/*@modifies h @*/;
/** \ingroup header
- * Return array of locales found in header.
- * The array is terminated with a NULL sentinel.
- * @param h header
- * @return array of locales (or NULL on error)
- */
-/*@unused@*/
-/*@only@*/ /*@null@*/ char ** headerGetLangs(Header h) /*@*/;
-
-/** \ingroup header
* Add locale specific tag to header.
* A NULL lang is interpreted as the C locale. Here are the rules:
* \verbatim
diff --git a/lib/header_internal.c b/lib/header_internal.c
new file mode 100644
index 000000000..3e77222c5
--- /dev/null
+++ b/lib/header_internal.c
@@ -0,0 +1,128 @@
+/** \ingroup header
+ * \file lib/header_internal.c
+ */
+
+#include "system.h"
+
+#include <header_internal.h>
+
+#include "debug.h"
+
+void headerDump(Header h, FILE *f, int flags,
+ const struct headerTagTableEntry * tags)
+{
+ int i;
+ struct indexEntry *p;
+ const struct headerTagTableEntry * tage;
+ const char *tag;
+ char *type;
+
+ /* First write out the length of the index (count of index entries) */
+ fprintf(f, "Entry count: %d\n", h->indexUsed);
+
+ /* Now write the index */
+ p = h->index;
+ fprintf(f, "\n CT TAG TYPE "
+ " OFSET COUNT\n");
+ for (i = 0; i < h->indexUsed; i++) {
+ switch (p->info.type) {
+ case RPM_NULL_TYPE: type = "NULL"; break;
+ case RPM_CHAR_TYPE: type = "CHAR"; break;
+ case RPM_BIN_TYPE: type = "BIN"; break;
+ case RPM_INT8_TYPE: type = "INT8"; break;
+ case RPM_INT16_TYPE: type = "INT16"; break;
+ case RPM_INT32_TYPE: type = "INT32"; break;
+ /*case RPM_INT64_TYPE: type = "INT64"; break;*/
+ case RPM_STRING_TYPE: type = "STRING"; break;
+ case RPM_STRING_ARRAY_TYPE: type = "STRING_ARRAY"; break;
+ case RPM_I18NSTRING_TYPE: type = "I18N_STRING"; break;
+ default: type = "(unknown)"; break;
+ }
+
+ tage = tags;
+ while (tage->name && tage->val != p->info.tag) tage++;
+
+ if (!tage->name)
+ tag = "(unknown)";
+ else
+ tag = tage->name;
+
+ fprintf(f, "Entry : %3.3d (%d)%-14s %-18s 0x%.8x %.8d\n", i,
+ p->info.tag, tag, type, (unsigned) p->info.offset,
+ (int) p->info.count);
+
+ if (flags & HEADER_DUMP_INLINE) {
+ char *dp = p->data;
+ int c = p->info.count;
+ int ct = 0;
+
+ /* Print the data inline */
+ switch (p->info.type) {
+ case RPM_INT32_TYPE:
+ while (c--) {
+ fprintf(f, " Data: %.3d 0x%08x (%d)\n", ct++,
+ (unsigned) *((int_32 *) dp),
+ (int) *((int_32 *) dp));
+ dp += sizeof(int_32);
+ }
+ break;
+
+ case RPM_INT16_TYPE:
+ while (c--) {
+ fprintf(f, " Data: %.3d 0x%04x (%d)\n", ct++,
+ (unsigned) (*((int_16 *) dp) & 0xffff),
+ (int) *((int_16 *) dp));
+ dp += sizeof(int_16);
+ }
+ break;
+ case RPM_INT8_TYPE:
+ while (c--) {
+ fprintf(f, " Data: %.3d 0x%02x (%d)\n", ct++,
+ (unsigned) (*((int_8 *) dp) & 0xff),
+ (int) *((int_8 *) dp));
+ dp += sizeof(int_8);
+ }
+ break;
+ case RPM_BIN_TYPE:
+ while (c > 0) {
+ fprintf(f, " Data: %.3d ", ct);
+ while (c--) {
+ fprintf(f, "%02x ", (unsigned) (*(int_8 *)dp & 0xff));
+ ct++;
+ dp += sizeof(int_8);
+ if (! (ct % 8)) {
+ /*@loopbreak@*/ break;
+ }
+ }
+ fprintf(f, "\n");
+ }
+ break;
+ case RPM_CHAR_TYPE:
+ while (c--) {
+ char ch = (char) *((char *) dp);
+ fprintf(f, " Data: %.3d 0x%2x %c (%d)\n", ct++,
+ (unsigned)(ch & 0xff),
+ (isprint(ch) ? ch : ' '),
+ (int) *((char *) dp));
+ dp += sizeof(char);
+ }
+ break;
+ case RPM_STRING_TYPE:
+ case RPM_STRING_ARRAY_TYPE:
+ case RPM_I18NSTRING_TYPE:
+ while (c--) {
+ fprintf(f, " Data: %.3d %s\n", ct++, (char *) dp);
+ dp = strchr(dp, 0);
+ dp++;
+ }
+ break;
+ default:
+ fprintf(stderr, _("Data type %d not supported\n"),
+ (int) p->info.type);
+ break;
+ }
+ }
+ p++;
+ }
+}
+
diff --git a/lib/header_internal.h b/lib/header_internal.h
new file mode 100644
index 000000000..db87fdbab
--- /dev/null
+++ b/lib/header_internal.h
@@ -0,0 +1,127 @@
+#ifndef H_HEADER_INTERNAL
+#define H_HEADER_INTERNAL
+
+/** \ingroup header
+ * \file lib/header_internal.h
+ */
+
+#include <header.h>
+
+#if !defined(__LCLINT__)
+#include <netinet/in.h>
+#endif /* __LCLINT__ */
+
+
+/**
+ * Description of tag data.
+ */
+struct entryInfo {
+ int_32 tag; /*!< Tag identifier. */
+ int_32 type; /*!< Tag data type. */
+ int_32 offset; /*!< Offset into data segment (ondisk only). */
+ int_32 count; /*!< Number of tag elements. */
+};
+
+#define REGION_TAG_TYPE RPM_BIN_TYPE
+#define REGION_TAG_COUNT sizeof(struct entryInfo)
+
+#define ENTRY_IS_REGION(_e) ((_e)->info.tag < HEADER_I18NTABLE)
+#define ENTRY_IN_REGION(_e) ((_e)->info.offset < 0)
+
+/**
+ * A single tag from a Header.
+ */
+struct indexEntry {
+ struct entryInfo info; /*!< Description of tag data. */
+/*@owned@*/ void * data; /*!< Location of tag data. */
+ int length; /*!< No. bytes of data. */
+ int rdlen; /*!< No. bytes of data in region. */
+};
+
+/**
+ * The Header data structure.
+ */
+struct headerToken {
+/*@owned@*/ struct indexEntry * index; /*!< Array of tags. */
+ int indexUsed; /*!< Current size of tag array. */
+ int indexAlloced; /*!< Allocated size of tag array. */
+ int region_allocated; /*!< Is 1st header region allocated? */
+ int sorted; /*!< Are header entries sorted? */
+ int legacy; /*!< Header came from legacy source? */
+/*@refs@*/ int nrefs; /*!< Reference count. */
+};
+
+/**
+ */
+struct sprintfTag {
+/*@null@*/ headerTagTagFunction ext; /*!< if NULL tag element is invalid */
+ int extNum;
+ int_32 tag;
+ int justOne;
+ int arrayCount;
+/*@kept@*/ char * format;
+/*@kept@*/ /*@null@*/ char * type;
+ int pad;
+};
+
+/**
+ */
+struct extensionCache {
+ int_32 type;
+ int_32 count;
+ int avail;
+ int freeit;
+/*@owned@*/ const void * data;
+};
+
+/**
+ */
+struct sprintfToken {
+ enum {
+ PTOK_NONE = 0,
+ PTOK_TAG,
+ PTOK_ARRAY,
+ PTOK_STRING,
+ PTOK_COND
+ } type;
+ union {
+ struct {
+ /*@only@*/ struct sprintfToken * format;
+ int numTokens;
+ } array;
+ struct sprintfTag tag;
+ struct {
+ /*@dependent@*/ char * string;
+ int len;
+ } string;
+ struct {
+ /*@only@*/ /*@null@*/ struct sprintfToken * ifFormat;
+ int numIfTokens;
+ /*@only@*/ /*@null@*/ struct sprintfToken * elseFormat;
+ int numElseTokens;
+ struct sprintfTag tag;
+ } cond;
+ } u;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** \ingroup header
+ * Dump a header in human readable format (for debugging).
+ * @param h header
+ * @param flags 0 or HEADER_DUMP_LINLINE
+ * @param tags array of tag name/value pairs
+ */
+/*@unused@*/
+void headerDump(Header h, FILE *f, int flags,
+ const struct headerTagTableEntry * tags);
+#define HEADER_DUMP_INLINE 1
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_HEADER_INTERNAL */
diff --git a/lib/misc.c b/lib/misc.c
index 08d14ae6a..a8ca602e6 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -94,129 +94,25 @@ int rpmfileexists(const char * urlfn)
return 1;
}
-/* compare alpha and numeric segments of two versions */
-/* return 1: a is newer than b */
-/* 0: a and b are the same version */
-/* -1: b is newer than a */
-int rpmvercmp(const char * a, const char * b)
-{
- char oldch1, oldch2;
- char * str1, * str2;
- char * one, * two;
- int rc;
- int isnum;
-
- /* easy comparison to see if versions are identical */
- if (!strcmp(a, b)) return 0;
-
- str1 = alloca(strlen(a) + 1);
- str2 = alloca(strlen(b) + 1);
-
- strcpy(str1, a);
- strcpy(str2, b);
-
- one = str1;
- two = str2;
-
- /* loop through each version segment of str1 and str2 and compare them */
- while (*one && *two) {
- while (*one && !xisalnum(*one)) one++;
- while (*two && !xisalnum(*two)) two++;
-
- str1 = one;
- str2 = two;
-
- /* grab first completely alpha or completely numeric segment */
- /* leave one and two pointing to the start of the alpha or numeric */
- /* segment and walk str1 and str2 to end of segment */
- if (xisdigit(*str1)) {
- while (*str1 && xisdigit(*str1)) str1++;
- while (*str2 && xisdigit(*str2)) str2++;
- isnum = 1;
- } else {
- while (*str1 && xisalpha(*str1)) str1++;
- while (*str2 && xisalpha(*str2)) str2++;
- isnum = 0;
- }
-
- /* save character at the end of the alpha or numeric segment */
- /* so that they can be restored after the comparison */
- oldch1 = *str1;
- *str1 = '\0';
- oldch2 = *str2;
- *str2 = '\0';
-
- /* take care of the case where the two version segments are */
- /* different types: one numeric, the other alpha (i.e. empty) */
- if (one == str1) return -1; /* arbitrary */
- if (two == str2) return 1;
-
- if (isnum) {
- /* this used to be done by converting the digit segments */
- /* to ints using atoi() - it's changed because long */
- /* digit segments can overflow an int - this should fix that. */
-
- /* throw away any leading zeros - it's a number, right? */
- while (*one == '0') one++;
- while (*two == '0') two++;
-
- /* whichever number has more digits wins */
- if (strlen(one) > strlen(two)) return 1;
- if (strlen(two) > strlen(one)) return -1;
- }
-
- /* strcmp will return which one is greater - even if the two */
- /* segments are alpha or if they are numeric. don't return */
- /* if they are equal because there might be more segments to */
- /* compare */
- rc = strcmp(one, two);
- if (rc) return rc;
-
- /* restore character that was replaced by null above */
- *str1 = oldch1;
- one = str1;
- *str2 = oldch2;
- two = str2;
- }
-
- /* this catches the case where all numeric and alpha segments have */
- /* compared identically but the segment sepparating characters were */
- /* different */
- if ((!*one) && (!*two)) return 0;
-
- /* whichever version still has characters left over wins */
- if (!*one) return -1; else return 1;
-}
-
int doputenv(const char *str)
{
char * a;
/* FIXME: this leaks memory! */
-
a = xmalloc(strlen(str) + 1);
strcpy(a, str);
-
return putenv(a);
}
-int dosetenv(const char *name, const char *value, int overwrite)
+int dosetenv(const char * name, const char * value, int overwrite)
{
- int i;
char * a;
- /* FIXME: this leaks memory! */
-
if (!overwrite && getenv(name)) return 0;
- i = strlen(name) + strlen(value) + 2;
- a = xmalloc(i);
- if (!a) return 1;
-
- strcpy(a, name);
- strcat(a, "=");
- strcat(a, value);
-
+ /* FIXME: this leaks memory! */
+ a = xmalloc(strlen(name) + strlen(value) + sizeof("="));
+ (void) stpcpy( stpcpy( stpcpy( a, name), "="), value);
return putenv(a);
}
diff --git a/lib/misc.h b/lib/misc.h
index 965bb0b3b..1b36478b8 100644
--- a/lib/misc.h
+++ b/lib/misc.h
@@ -47,10 +47,12 @@ void freeSplitString( /*@only@*/ char ** list)
int rpmfileexists(const char * urlfn)
/*@modifies fileSystem @*/;
+#ifdef DYING
/**
*/
int rpmvercmp(const char * a, const char * b)
/*@*/;
+#endif
/*
* These are like the libc functions, but they malloc() the space which
@@ -72,7 +74,7 @@ int doputenv(const char * str)
* A unique temporaray file path will be generated using
* rpmGenPath(prefix, "%{_tmppath}/", "rpm-tmp.XXXXX")
* where "XXXXXX" is filled in using rand(3). The file is opened, and
- * the link count and (dev,ino) location are * verified after opening.
+ * the link count and (dev,ino) location are verified after opening.
* The file name and the open file handle are returned.
*
* @param prefix leading part of temp file path
@@ -86,7 +88,8 @@ int makeTempFile(/*@null@*/ const char * prefix,
/*@modifies *fnptr, *fdptr, fileSystem @*/;
/**
- * @return cureent working directory (malloc'ed)
+ * Return (malloc'd) current working directory.
+ * @return current working directory (malloc'ed)
*/
/*@only@*/ char * currentDirectory(void)
/*@modifies fileSystem @*/;
diff --git a/lib/rpmcli.h b/lib/rpmcli.h
index 358a43854..f90a21bee 100644
--- a/lib/rpmcli.h
+++ b/lib/rpmcli.h
@@ -5,9 +5,9 @@
* \file lib/rpmcli.h
*/
-#include <rpmlib.h>
-#include <rpmurl.h>
-#include <rpmmacro.h>
+#include "rpmlib.h"
+#include "rpmurl.h"
+#include "rpmmacro.h"
/** \ingroup rpmcli
* Should version 3 packages be produced?
diff --git a/lib/rpminstall.c b/lib/rpminstall.c
index 01ca59a59..01619a176 100644
--- a/lib/rpminstall.c
+++ b/lib/rpminstall.c
@@ -7,7 +7,7 @@
#include <rpmcli.h>
#include "manifest.h"
-#include "misc.h"
+#include "misc.h" /* XXX for rpmGlob() */
#include "debug.h"
/*@access rpmTransactionSet@*/ /* XXX compared with NULL */
diff --git a/lib/rpmlib.h b/lib/rpmlib.h
index 2bb66da18..1c82d7850 100644
--- a/lib/rpmlib.h
+++ b/lib/rpmlib.h
@@ -841,6 +841,12 @@ int rpmdbSetIteratorModified(/*@null@*/ rpmdbMatchIterator mi, int modified)
/*@null@*/ Header rpmdbNextIterator(/*@null@*/ rpmdbMatchIterator mi)
/*@modifies mi @*/;
+/** @todo Remove debugging entry from the ABI. */
+/*@unused@*/
+/*@null@*/ Header XrpmdbNextIterator(rpmdbMatchIterator mi,
+ const char * f, unsigned int l)
+ /*@modifies mi @*/;
+
/** \ingroup rpmdb
* Return database iterator.
* @param db rpm database
@@ -931,19 +937,21 @@ void printDepFlags(FILE *fp, const char *version, int flags)
/*@modifies *fp, fileSystem @*/;
/**
- */
-typedef /*@abstract@*/ struct rpmDependencyConflict_s {
- const char * byName;
- const char * byVersion;
- const char * byRelease;
- Header byHeader;
+ * Dependency problems found by rpmdepCheck().
+ * @todo Rename, but rpmfind prevents "struct rpmDependencyConflict_s".
+ */
+typedef /*@abstract@*/ struct rpmDependencyConflict {
+ const char * byName; /*!< package name */
+ const char * byVersion; /*!< package version */
+ const char * byRelease; /*!< package release */
+ Header byHeader; /*!< header with dependency problems */
/*
* These needs fields are misnamed -- they are used for the package
* which isn't needed as well.
*/
- const char * needsName;
- const char * needsVersion;
- int needsFlags;
+ const char * needsName; /*!< dependency name */
+ const char * needsVersion; /*!< dependency epoch:version-release */
+ int needsFlags; /*!< dependency flags */
/*@owned@*/ /*@null@*/ const void ** suggestedPackages; /* terminated by NULL */
enum {
RPMDEP_SENSE_REQUIRES, /*!< requirement not satisfied. */
@@ -1374,6 +1382,16 @@ int rpmGetRpmlibProvides(/*@null@*/ /*@out@*/ const char *** provNames,
/*@ modifies *provNames, *provFlags, *provVersions @*/;
/** \ingroup rpmtrans
+ * Segmented string compare for version and/or release.
+ *
+ * @param a 1st string
+ * @param b 2nd string
+ * @return +1 if a is "newer", 0 if equal, -1 if b is "newer"
+ */
+int rpmvercmp(const char * a, const char * b)
+ /*@*/;
+
+/** \ingroup rpmtrans
* Compare two versioned dependency ranges, looking for overlap.
* @param AName 1st dependncy name string
* @param AEVR 1st dependency [epoch:]version[-release] string
diff --git a/lib/rpmvercmp.c b/lib/rpmvercmp.c
new file mode 100644
index 000000000..ec09447dd
--- /dev/null
+++ b/lib/rpmvercmp.c
@@ -0,0 +1,103 @@
+/** \ingroup rpmtrans
+ * \file lib/rpmvercmp.c
+ */
+
+#include "system.h"
+
+#include <rpmio.h>
+
+#include "debug.h"
+
+/* compare alpha and numeric segments of two versions */
+/* return 1: a is newer than b */
+/* 0: a and b are the same version */
+/* -1: b is newer than a */
+int rpmvercmp(const char * a, const char * b)
+{
+ char oldch1, oldch2;
+ char * str1, * str2;
+ char * one, * two;
+ int rc;
+ int isnum;
+
+ /* easy comparison to see if versions are identical */
+ if (!strcmp(a, b)) return 0;
+
+ str1 = alloca(strlen(a) + 1);
+ str2 = alloca(strlen(b) + 1);
+
+ strcpy(str1, a);
+ strcpy(str2, b);
+
+ one = str1;
+ two = str2;
+
+ /* loop through each version segment of str1 and str2 and compare them */
+ while (*one && *two) {
+ while (*one && !xisalnum(*one)) one++;
+ while (*two && !xisalnum(*two)) two++;
+
+ str1 = one;
+ str2 = two;
+
+ /* grab first completely alpha or completely numeric segment */
+ /* leave one and two pointing to the start of the alpha or numeric */
+ /* segment and walk str1 and str2 to end of segment */
+ if (xisdigit(*str1)) {
+ while (*str1 && xisdigit(*str1)) str1++;
+ while (*str2 && xisdigit(*str2)) str2++;
+ isnum = 1;
+ } else {
+ while (*str1 && xisalpha(*str1)) str1++;
+ while (*str2 && xisalpha(*str2)) str2++;
+ isnum = 0;
+ }
+
+ /* save character at the end of the alpha or numeric segment */
+ /* so that they can be restored after the comparison */
+ oldch1 = *str1;
+ *str1 = '\0';
+ oldch2 = *str2;
+ *str2 = '\0';
+
+ /* take care of the case where the two version segments are */
+ /* different types: one numeric, the other alpha (i.e. empty) */
+ if (one == str1) return -1; /* arbitrary */
+ if (two == str2) return 1;
+
+ if (isnum) {
+ /* this used to be done by converting the digit segments */
+ /* to ints using atoi() - it's changed because long */
+ /* digit segments can overflow an int - this should fix that. */
+
+ /* throw away any leading zeros - it's a number, right? */
+ while (*one == '0') one++;
+ while (*two == '0') two++;
+
+ /* whichever number has more digits wins */
+ if (strlen(one) > strlen(two)) return 1;
+ if (strlen(two) > strlen(one)) return -1;
+ }
+
+ /* strcmp will return which one is greater - even if the two */
+ /* segments are alpha or if they are numeric. don't return */
+ /* if they are equal because there might be more segments to */
+ /* compare */
+ rc = strcmp(one, two);
+ if (rc) return rc;
+
+ /* restore character that was replaced by null above */
+ *str1 = oldch1;
+ one = str1;
+ *str2 = oldch2;
+ two = str2;
+ }
+
+ /* this catches the case where all numeric and alpha segments have */
+ /* compared identically but the segment sepparating characters were */
+ /* different */
+ if ((!*one) && (!*two)) return 0;
+
+ /* whichever version still has characters left over wins */
+ if (!*one) return -1; else return 1;
+}
diff --git a/lib/signature.c b/lib/signature.c
index c3c987dde..e1b3e0fec 100644
--- a/lib/signature.c
+++ b/lib/signature.c
@@ -18,10 +18,10 @@
#endif
#include <rpmlib.h>
-#include <rpmmacro.h> /* XXX for rpmGetPath */
+#include <rpmmacro.h> /* XXX for rpmGetPath() */
#include "md5.h"
-#include "misc.h"
+#include "misc.h" /* XXX for dosetenv() and makeTempFile() */
#include "rpmlead.h"
#include "signature.h"
#include "debug.h"
diff --git a/lib/transaction.c b/lib/transaction.c
index 4b5d307a3..fe5f8e286 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -11,7 +11,7 @@
#include "fprint.h"
#include "rpmhash.h"
#include "md5.h"
-#include "misc.h"
+#include "misc.h" /* XXX stripTrailingChar, splitString, currentDirectory */
#include "rpmdb.h"
/* XXX FIXME: merge with existing (broken?) tests in system.h */
diff --git a/lib/verify.c b/lib/verify.c
index f897f56a8..11a5ed83d 100644
--- a/lib/verify.c
+++ b/lib/verify.c
@@ -9,7 +9,7 @@
#include "psm.h"
#include "md5.h"
-#include "misc.h"
+#include "misc.h" /* XXX for uidToUname() and gnameToGid() */
#include "debug.h"
/*@access TFI_t*/