From 7ac93a6cfb262a02c55e1cb8f7fc241eb311e0e9 Mon Sep 17 00:00:00 2001 From: ewt Date: Tue, 2 Apr 1996 03:36:00 +0000 Subject: [PATCH] added support for user specified query formats CVS patchset: 516 CVS date: 1996/04/02 03:36:00 --- query.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------- query.h | 2 +- rpm.c | 15 +++- 3 files changed, 214 insertions(+), 59 deletions(-) diff --git a/query.c b/query.c index 65e6035..6b602bf 100644 --- a/query.c +++ b/query.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -13,9 +14,13 @@ #include "rpmlib.h" #include "query.h" -static void printHeader(Header h, int queryFlags); +static void printHeader(Header h, int queryFlags, char * queryFormat); +static void queryHeader(Header h, const char * incomingFormat); +static void escapedChar(char ch); +static const char * handleFormat(Header h, const char * chptr); static char * getString(Header h, int tag, char * def); -static void showMatches(rpmdb db, dbIndexSet matches, int queryFlags); +static void showMatches(rpmdb db, dbIndexSet matches, int queryFlags, + char * queryFormat); static int findMatches(rpmdb db, char * name, char * version, char * release, dbIndexSet * matches); static void printFileInfo(char * name, unsigned int size, unsigned short mode, @@ -34,7 +39,140 @@ static char * getString(Header h, int tag, char * def) { return str; } -static void printHeader(Header h, int queryFlags) { +static void queryHeader(Header h, const char * chptr) { + while (chptr && *chptr) { + switch (*chptr) { + case '\\': + chptr++; + if (!*chptr) return; + escapedChar(*chptr++); + break; + + case '%': + chptr++; + if (!*chptr) return; + if (*chptr == '%') { + putchar('%'); + chptr++; + } + chptr = handleFormat(h, chptr); + break; + + default: + putchar(*chptr++); + } + } +} + +static const char * handleFormat(Header h, const char * chptr) { + const char * f = chptr; + const char * tagptr; + char format[20]; + int i, tagLength; + char tag[100]; + const struct rpmTagTableEntry * t; + void * p; + int type, count; + int isDate = 0; + time_t dateint; + struct tm * tstruct; + char datestr[100]; + + strcpy(format, "%"); + while (*chptr && *chptr != '{') chptr++; + if (!*chptr || (chptr - f > (sizeof(format) - 3))) { + fprintf(stderr, "bad query format - %s\n", f); + return NULL; + } + + strncat(format, f, chptr - f); + + tagptr = ++chptr; + while (*chptr && *chptr != '}') chptr++; + if (tagptr == chptr || !*chptr) { + fprintf(stderr, "bad query format - %s\n", f); + return NULL; + } + + switch (*tagptr) { + case '-': isDate = 1, tagptr++; break; + } + + tagLength = chptr - tagptr; + chptr++; + + if (tagLength > (sizeof(tag) - 20)) { + fprintf(stderr, "query tag too long\n"); + return NULL; + } + memset(tag, 0, sizeof(tag)); + if (strncmp(tagptr, "RPMTAG_", 7)) { + strcpy(tag, "RPMTAG_"); + } + strncat(tag, tagptr, tagLength); + + for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++) { + if (!strcmp(tag, t->name)) break; + } + + if (i == rpmTagTableSize) { + fprintf(stderr, "unknown tag %s\n", tag); + return NULL; + } + + if (!getEntry(h, t->val, &type, &p, &count) || !p) { + p = "(unknown)"; + count = 1; + type = STRING_TYPE; + } else if (count > 1 || type == STRING_ARRAY_TYPE) { + p = "(array)"; + count = 1; + type = STRING_TYPE; + } + + switch (type) { + case STRING_TYPE: + strcat(format, "s"); + printf(format, p); + break; + + case INT32_TYPE: + if (isDate) { + strcat(format, "s"); + /* this is important if sizeof(int_32) ! sizeof(time_t) */ + dateint = *((int_32 *) p); + tstruct = localtime(&dateint); + strftime(datestr, sizeof(datestr) - 1, "%c", tstruct); + printf(format, datestr); + } else { + strcat(format, "d"); + printf(format, *((int_32 *) p)); + } + break; + + default: + printf("(can't handle type %d)", type); + break; + } + + return chptr; +} + +static void escapedChar(const char ch) { + switch (ch) { + case 'a': putchar('\a'); break; + case 'b': putchar('\b'); break; + case 'f': putchar('\f'); break; + case 'n': putchar('\n'); break; + case 'r': putchar('\r'); break; + case 't': putchar('\t'); break; + case 'v': putchar('\v'); break; + + default: putchar(ch); break; + } +} + +static void printHeader(Header h, int queryFlags, char * queryFormat) { char * name, * version, * release; char * distribution, * vendor, * group, *description, * buildHost; uint_32 * size; @@ -64,49 +202,56 @@ static void printHeader(Header h, int queryFlags) { printf("%s-%s-%s\n", name, version, release); } else { if (queryFlags & QUERY_FOR_INFO) { - distribution = getString(h, RPMTAG_DISTRIBUTION, ""); - description = getString(h, RPMTAG_DESCRIPTION, ""); - buildHost = getString(h, RPMTAG_BUILDHOST, ""); - vendor = getString(h, RPMTAG_VENDOR, ""); - group = getString(h, RPMTAG_GROUP, "Unknown"); - sourcePackage = getString(h, RPMTAG_SOURCERPM, "Unknown"); - if (!getEntry(h, RPMTAG_SIZE, &type, (void **) &size, &count)) - size = NULL; - - if (getEntry(h, RPMTAG_BUILDTIME, &type, (void **) &pBuildDate, - &count)) { - /* this is important if sizeof(int_32) ! sizeof(time_t) */ - buildDate = *pBuildDate; - tstruct = localtime(&buildDate); - strftime(buildDateStr, sizeof(buildDateStr) - 1, "%c", tstruct); - } else - strcpy(buildDateStr, "(unknown)"); - - if (getEntry(h, RPMTAG_INSTALLTIME, &type, (void **) &pInstallDate, - &count)) { - /* this is important if sizeof(int_32) ! sizeof(time_t) */ - installDate = *pInstallDate; - tstruct = localtime(&installDate); - strftime(installDateStr, sizeof(installDateStr) - 1, "%c", - tstruct); - } else - strcpy(installDateStr, "(unknown)"); - - printf("Name : %-27s Distribution: %s\n", - name, distribution); - printf("Version : %-27s Vendor: %s\n", version, vendor); - printf("Release : %-27s Build Date: %s\n", release, - buildDateStr); - printf("Install date: %-27s Build Host: %s\n", installDateStr, - buildHost); - printf("Group : %-27s Source RPM: %s\n", group, - sourcePackage); - if (size) - printf("Size : %d\n", *size); - else - printf("Size : (unknown)\n"); - printf("Description : %s\n", description); - prefix = " "; + if (queryFormat) { + queryHeader(h, queryFormat); + } else { + distribution = getString(h, RPMTAG_DISTRIBUTION, ""); + description = getString(h, RPMTAG_DESCRIPTION, ""); + buildHost = getString(h, RPMTAG_BUILDHOST, ""); + vendor = getString(h, RPMTAG_VENDOR, ""); + group = getString(h, RPMTAG_GROUP, "Unknown"); + sourcePackage = getString(h, RPMTAG_SOURCERPM, "Unknown"); + if (!getEntry(h, RPMTAG_SIZE, &type, (void **) &size, &count)) + size = NULL; + + if (getEntry(h, RPMTAG_BUILDTIME, &type, (void **) &pBuildDate, + &count)) { + /* this is important if sizeof(int_32) ! sizeof(time_t) */ + buildDate = *pBuildDate; + tstruct = localtime(&buildDate); + strftime(buildDateStr, sizeof(buildDateStr) - 1, "%c", + tstruct); + } else + strcpy(buildDateStr, "(unknown)"); + + if (getEntry(h, RPMTAG_INSTALLTIME, &type, + (void **) &pInstallDate, + &count)) { + /* this is important if sizeof(int_32) ! sizeof(time_t) */ + installDate = *pInstallDate; + tstruct = localtime(&installDate); + strftime(installDateStr, sizeof(installDateStr) - 1, "%c", + tstruct); + } else + strcpy(installDateStr, "(unknown)"); + + printf("Name : %-27s Distribution: %s\n", + name, distribution); + printf("Version : %-27s Vendor: %s\n", version, + vendor); + printf("Release : %-27s Build Date: %s\n", release, + buildDateStr); + printf("Install date: %-27s Build Host: %s\n", + installDateStr, buildHost); + printf("Group : %-27s Source RPM: %s\n", group, + sourcePackage); + if (size) + printf("Size : %d\n", *size); + else + printf("Size : (unknown)\n"); + printf("Description : %s\n", description); + prefix = " "; + } } if (queryFlags & QUERY_FOR_LIST) { @@ -291,7 +436,8 @@ static void printFileInfo(char * name, unsigned int size, unsigned short mode, sizefield, timefield, namefield); } -static void showMatches(rpmdb db, dbIndexSet matches, int queryFlags) { +static void showMatches(rpmdb db, dbIndexSet matches, int queryFlags, + char * queryFormat) { int i; Header h; @@ -304,7 +450,7 @@ static void showMatches(rpmdb db, dbIndexSet matches, int queryFlags) { if (!h) { fprintf(stderr, "error: could not read database record\n"); } else { - printHeader(h, queryFlags); + printHeader(h, queryFlags, queryFormat); freeHeader(h); } } @@ -312,7 +458,7 @@ static void showMatches(rpmdb db, dbIndexSet matches, int queryFlags) { } void doQuery(char * prefix, enum querysources source, int queryFlags, - char * arg) { + char * arg, char * queryFormat) { Header h; int offset; int fd; @@ -343,7 +489,7 @@ void doQuery(char * prefix, enum querysources source, int queryFlags, fprintf(stderr, "old format source packages cannot be " "queried\n"); } else { - printHeader(h, queryFlags); + printHeader(h, queryFlags, queryFormat); freeHeader(h); } break; @@ -363,7 +509,7 @@ void doQuery(char * prefix, enum querysources source, int queryFlags, fprintf(stderr, "could not read database record!\n"); exit(1); } - printHeader(h, queryFlags); + printHeader(h, queryFlags, queryFormat); freeHeader(h); offset = rpmdbNextRecNum(db, offset); } @@ -374,7 +520,7 @@ void doQuery(char * prefix, enum querysources source, int queryFlags, if (rpmdbFindByGroup(db, arg, &matches)) { fprintf(stderr, "group %s does not contain any pacakges\n", arg); } else { - showMatches(db, matches, queryFlags); + showMatches(db, matches, queryFlags, queryFormat); freeDBIndexRecord(matches); } break; @@ -384,7 +530,7 @@ void doQuery(char * prefix, enum querysources source, int queryFlags, if (rpmdbFindByFile(db, arg, &matches)) { fprintf(stderr, "file %s is not owned by any package\n", arg); } else { - showMatches(db, matches, queryFlags); + showMatches(db, matches, queryFlags, queryFormat); freeDBIndexRecord(matches); } break; @@ -399,7 +545,7 @@ void doQuery(char * prefix, enum querysources source, int queryFlags, if (!h) fprintf(stderr, "record %d could not be read\n", recNumber); else { - printHeader(h, queryFlags); + printHeader(h, queryFlags, queryFormat); freeHeader(h); } } else { @@ -409,7 +555,7 @@ void doQuery(char * prefix, enum querysources source, int queryFlags, else if (rc == 2) { fprintf(stderr, "error looking for package %s\n", arg); } else { - showMatches(db, matches, queryFlags); + showMatches(db, matches, queryFlags, queryFormat); freeDBIndexRecord(matches); } } diff --git a/query.h b/query.h index 6a6a1ce..cc4d76c 100644 --- a/query.h +++ b/query.h @@ -14,7 +14,7 @@ enum querysources { QUERY_PATH, QUERY_PACKAGE, QUERY_ALL, QUERY_SPATH, #define QUERY_FOR_CONFIG 16 void doQuery(char * prefix, enum querysources source, int queryFlags, - char * arg); + char * arg, char * queryFormat); /* 0 found matches */ /* 1 no matches */ diff --git a/rpm.c b/rpm.c index c173c37..30c169e 100755 --- a/rpm.c +++ b/rpm.c @@ -223,6 +223,7 @@ int main(int argc, char ** argv) { int badOption = 0; int excldocs = 0; int incldocs = 0; + char * queryFormat = NULL; char buildChar = ' '; char * prefix = "/"; char * specFile; @@ -250,6 +251,7 @@ int main(int argc, char ** argv) { { "package", 0, 0, 'p' }, { "percent", 0, &showPercents, 0 }, { "query", 0, 0, 'q' }, + { "queryformat", 1, 0, 0}, { "quiet", 0, &quiet, 0 }, { "recompile", 0, 0, 0 }, { "rebuild", 0, 0, 0 }, @@ -491,6 +493,12 @@ int main(int argc, char ** argv) { argerror(_("only one major mode may be specified")); bigMode = MODE_RESIGN; signIt = 1; + } else if (!strcmp(options[long_index].name, "queryformat")) { + if (bigMode != MODE_UNKNOWN && bigMode != MODE_QUERY) + argerror(_("only one major mode may be specified")); + bigMode = MODE_QUERY; + queryFormat = optarg; + queryFor |= QUERY_FOR_INFO; } } } @@ -699,7 +707,7 @@ int main(int argc, char ** argv) { case MODE_QUERY: if (querySource == QUERY_ALL) { - doQuery(prefix, QUERY_ALL, queryFor, NULL); + doQuery(prefix, QUERY_ALL, queryFor, NULL, queryFormat); } else if (querySource == QUERY_SPATH || querySource == QUERY_SPACKAGE || querySource == QUERY_SRPM) { @@ -710,13 +718,14 @@ int main(int argc, char ** argv) { i = strlen(buffer) - 1; if (buffer[i] == '\n') buffer[i] = 0; if (strlen(buffer)) - doQuery(prefix, querySource, queryFor, buffer); + doQuery(prefix, querySource, queryFor, buffer, queryFormat); } } else { if (optind == argc) argerror(_("no arguments given for query")); while (optind < argc) - doQuery(prefix, querySource, queryFor, argv[optind++]); + doQuery(prefix, querySource, queryFor, argv[optind++], + queryFormat); } break; -- 2.7.4