added support for user specified query formats
CVS patchset: 516 CVS date: 1996/04/02 03:36:00
This commit is contained in:
parent
0fff3d855d
commit
7ac93a6cfb
252
query.c
252
query.c
|
@ -1,3 +1,4 @@
|
|||
#include <alloca.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -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 (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_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 (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);
|
||||
}
|
||||
}
|
||||
|
|
2
query.h
2
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 */
|
||||
|
|
15
rpm.c
15
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue