+2.4.1 -> 2.4.2:
+ - completely rewrote queryformat code
+ - added fsnames virtual query tag
+
2.4 -> 2.4.1:
- take advantage of lchown() if it's available
- fixed configure script to assume chown() doesn't follow symlinks
/* Define as 1 if you have lchown() */
#define HAVE_LCHOWN 0
+/* Define as one if you have <mntent.h> */
+#define HAVE_MNTENT_H 0
+
+/* Define as one if you have <sys/mnttab.h> */
+#define HAVE_SYS_MNTTAB_H 0
+
#endif
AC_CHECK_HEADERS(netinet/in_systm.h limits.h)
AC_CHECK_HEADERS(alloca.h dirent.h sys/socket.h sys/select.h)
AC_CHECK_HEADERS(machine/types.h string.h)
+AC_CHECK_HEADERS(mntent.h sys/mnttab.h)
AC_CHECK_HEADERS(glob.h,,MISCOBJS="$MISCOBJS glob.o")
AC_CHECK_HEADERS(fnmatch.h,,MISCOBJS="$MISCOBJS fnmatch.o")
stringbuf.o rpmlead.o package.o \
uninstall.o oldheader.o install.o \
signature.o verify.o rebuilddb.o \
- tread.o cpio.o formats.o
+ tread.o cpio.o formats.o \
+ fs.o
SOURCES = $(addprefix $(srcdir)/,$(subst .o,.c,$(LIBOBJECTS)))
TAGTABLE = tagtable.o
char * formatPrefix, int padding, int element);
static char * fflagsFormat(int_32 type, const void * data,
char * formatPrefix, int padding, int element);
+static int fsnamesTag(Header h, int_32 * type, void ** data, int_32 * count,
+ int * freeData);
static char * permsString(int mode);
const struct headerSprintfExtension rpmHeaderFormats[] = {
+ { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
{ HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
{ HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
{ HEADER_EXT_FORMAT, "perms", { permsFormat } },
return val;
}
+
+static int fsnamesTag(Header h, int_32 * type, void ** data, int_32 * count,
+ int * freeData) {
+ char ** list;
+ int i;
+
+ if (rpmGetFilesystemList(&list)) {
+ return 1;
+ }
+
+ *type = RPM_STRING_ARRAY_TYPE;
+ *((char ***) data) = list;
+
+ for (i = 0; list[i]; i++) ;
+ *count = i;
+
+ *freeData = 0;
+
+ return 0;
+}
};
struct sprintfTag {
+ /* if NULL tag element is invalid */
+ headerTagTagFunction ext;
int_32 tag;
int justOne;
char * format;
int numTokens;
int currToken;
const struct headerTagTableEntry * entry;
+ const struct headerSprintfExtension * ext;
int i;
int done = 0;
if (!strcasecmp(entry->name, tagname)) break;
if (!entry->name) {
- *error = "unknown tag";
- freeFormat(format, numTokens);
- return 1;
+ ext = extensions;
+ while (ext->type != HEADER_EXT_LAST) {
+ if (ext->type == HEADER_EXT_TAG &&
+ !strcmp(ext->name, tagname)) {
+ break;
+ }
+
+ if (ext->type == HEADER_EXT_MORE)
+ ext = ext->u.more;
+ else
+ ext++;
+ }
+
+ if (ext->type == HEADER_EXT_TAG) {
+ *error = "unknown tag";
+ freeFormat(format, numTokens);
+ return 1;
+ }
+
+ format[currToken].u.tag.ext = ext->u.tagFunction;
+ } else {
+ format[currToken].u.tag.ext = NULL;
+ format[currToken].u.tag.tag = entry->val;
}
- format[currToken].u.tag.tag = entry->val;
format[currToken].type = PTOK_TAG;
start = next;
char ** strarray;
headerTagFormatFunction tagtype = NULL;
const struct headerSprintfExtension * ext;
+ int freeit = 0;
- if (!headerGetEntry(h, tag->tag, &type, &data, &count)){
- count = 1;
- type = RPM_STRING_TYPE;
- data = "(none)";
+ if (tag->ext) {
+ if (tag->ext(h, &type, &data, &count, &freeit)) {
+ count = 1;
+ type = RPM_STRING_TYPE;
+ data = "(none)";
+ }
+ } else {
+ if (!headerGetEntry(h, tag->tag, &type, &data, &count)){
+ count = 1;
+ type = RPM_STRING_TYPE;
+ data = "(none)";
+ }
+ freeit = type == (RPM_STRING_ARRAY_TYPE);
}
strcpy(buf, "%");
sprintf(val, strarray[element], data);
}
- free(strarray);
break;
case RPM_STRING_TYPE:
strcpy(val, "(unknown type)");
}
+ if (freeit) free(data);
+
return val;
}
int len, alloced;
int i, j;
int numElements;
+ int type;
+ int freeit;
+ void * data;
/* we assume the token and header have been validated already! */
if (token->u.array.format[i].type != PTOK_TAG ||
token->u.array.format[i].u.tag.justOne) continue;
- headerGetEntry(h, token->u.array.format[i].u.tag.tag, NULL,
- (void **) &val, &numElements);
+ if (token->u.array.format[i].u.tag.ext) {
+ if (token->u.array.format[i].u.tag.ext(h, &type, &data,
+ &numElements, &freeit))
+ continue;
+ if (freeit) free(data);
+ } else {
+ if (!headerGetEntry(h, token->u.array.format[i].u.tag.tag,
+ &type, (void **) &val, &numElements))
+ continue;
+ if (type == RPM_STRING_ARRAY_TYPE) free(val);
+ }
break;
}
int val;
};
-enum headerSprintfExtenstionType { HEADER_EXT_TAG, HEADER_EXT_FORMAT,
- HEADER_EXT_MORE, HEADER_EXT_LAST = 0};
+enum headerSprintfExtenstionType { HEADER_EXT_LAST = 0, HEADER_EXT_FORMAT,
+ HEADER_EXT_MORE, HEADER_EXT_TAG };
/* This will only ever be passed RPM_TYPE_INT32 or RPM_TYPE_STRING to
help keep things simple */
typedef char * (*headerTagFormatFunction)(int_32 type, const void * data,
char * formatPrefix,
int padding, int element);
+typedef int (*headerTagTagFunction)(Header h, int_32 * type, void ** data,
+ int_32 * count, int * freeData);
struct headerSprintfExtension {
enum headerSprintfExtenstionType type;
union {
void * generic;
headerTagFormatFunction formatFunction;
+ headerTagTagFunction tagFunction;
struct headerSprintfExtension * more;
} u;
};
#define RPMERR_NORELOCATE -32 /* tried to relocate improper package */
#define RPMERR_BADOS -33 /* bad architecture or arch mismatch */
#define RPMMESS_BACKUP -34 /* backup made during [un]install */
+#define RPMERR_MTAB -35 /* failed to read mount table */
+#define RPMERR_STAT -36 /* failed to stat something */
/* spec.c build.c pack.c */
#define RPMERR_UNMATCHEDIF -107 /* unclosed %ifarch or %ifos */
int rpmVerifySignature(char *file, int_32 sigTag, void *sig, int count,
char *result);
+int rpmGetFilesystemList(char *** listptr);
+
#endif
#define lchown chown
#endif
+#if HAVE_MNTENT_H
+#include <mntent.h>
+#define GETMNTENT_ONE
+#define our_mntent struct mntent
+#elif HAVE_SYS_MNTTAB_H
+#include <sys/mnttab.h>
+#define GETMNTENT_TWO
+#define our_mntent struct mnttab
+#else
+#error Neither mntent.h nor mnttab.h exists. I cannot build on this system.
+#endif
+
+#ifndef MOUNTED
+#define MOUNTED "/etc/mnttab"
+#endif
+
#endif