1998-07-26 05:00:26 +08:00
|
|
|
#include "system.h"
|
1997-01-18 00:20:18 +08:00
|
|
|
|
1998-07-25 04:30:55 +08:00
|
|
|
#ifndef PATH_MAX
|
|
|
|
# define PATH_MAX 255
|
|
|
|
#endif
|
|
|
|
|
1998-07-31 06:09:42 +08:00
|
|
|
#include "build/rpmbuild.h"
|
1998-10-27 13:41:02 +08:00
|
|
|
#include "popt/popt.h"
|
1996-10-15 11:14:50 +08:00
|
|
|
#include "url.h"
|
1995-12-28 04:08:35 +08:00
|
|
|
|
1996-06-28 04:47:54 +08:00
|
|
|
static char * permsString(int mode);
|
1996-04-02 11:36:00 +08:00
|
|
|
static void printHeader(Header h, int queryFlags, char * queryFormat);
|
1996-11-19 02:02:36 +08:00
|
|
|
static void showMatches(rpmdb db, dbiIndexSet matches, int queryFlags,
|
1996-04-02 11:36:00 +08:00
|
|
|
char * queryFormat);
|
1996-02-19 12:50:33 +08:00
|
|
|
static void printFileInfo(char * name, unsigned int size, unsigned short mode,
|
|
|
|
unsigned int mtime, unsigned short rdev,
|
1996-02-19 23:17:56 +08:00
|
|
|
char * owner, char * group, int uid, int gid,
|
|
|
|
char * linkto);
|
1996-01-06 02:12:17 +08:00
|
|
|
|
1998-10-27 13:41:02 +08:00
|
|
|
#define POPT_QUERYFORMAT 1000
|
|
|
|
#define POPT_WHATREQUIRES 1001
|
|
|
|
#define POPT_WHATPROVIDES 1002
|
|
|
|
#define POPT_QUERYBYNUMBER 1003
|
|
|
|
#define POPT_TRIGGEREDBY 1004
|
|
|
|
#define POPT_DUMP 1005
|
1998-11-20 08:29:46 +08:00
|
|
|
#define POPT_SPECFILE 1006
|
1998-10-27 13:41:02 +08:00
|
|
|
|
|
|
|
static void queryArgCallback(poptContext con, enum poptCallbackReason reason,
|
|
|
|
const struct poptOption * opt, const char * arg,
|
|
|
|
struct rpmQueryArguments * data);
|
|
|
|
|
|
|
|
struct poptOption rpmQuerySourcePoptTable[] = {
|
|
|
|
{ NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA,
|
|
|
|
queryArgCallback, 0, NULL, NULL },
|
1998-12-02 01:18:38 +08:00
|
|
|
{ "file", 'f', 0, 0, 'f',
|
|
|
|
N_("query package owning file"), "FILE" },
|
|
|
|
{ "group", 'g', 0, 0, 'g',
|
|
|
|
N_("query packages in group"), "GROUP" },
|
|
|
|
{ "package", 'p', 0, 0, 'p',
|
|
|
|
N_("query a package file"), NULL },
|
|
|
|
{ "specfile", '\0', 0, 0, POPT_SPECFILE,
|
|
|
|
N_("query a spec file"), NULL },
|
1998-10-27 13:41:02 +08:00
|
|
|
{ "triggeredby", '\0', 0, 0, POPT_TRIGGEREDBY,
|
1998-12-02 01:18:38 +08:00
|
|
|
N_("query the pacakges triggered by the package"), "PACKAGE" },
|
1998-10-27 13:41:02 +08:00
|
|
|
{ "whatrequires", '\0', 0, 0, POPT_WHATREQUIRES,
|
1998-12-02 01:18:38 +08:00
|
|
|
N_("query the packages which require a capability"), "CAPABILITY" },
|
1998-10-27 13:41:02 +08:00
|
|
|
{ "whatprovides", '\0', 0, 0, POPT_WHATPROVIDES,
|
1998-12-02 01:18:38 +08:00
|
|
|
N_("query the packages which provide a capability"), "CAPABILITY" },
|
1998-11-20 03:10:23 +08:00
|
|
|
{ 0, 0, 0, 0, 0, NULL, NULL }
|
1998-10-27 13:41:02 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct poptOption rpmQueryPoptTable[] = {
|
|
|
|
{ NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA,
|
|
|
|
queryArgCallback, 0, NULL, NULL },
|
1998-12-02 01:18:38 +08:00
|
|
|
{ "configfiles", 'c', 0, 0, 'c',
|
|
|
|
N_("list all configuration files"), NULL },
|
|
|
|
{ "docfiles", 'd', 0, 0, 'd',
|
|
|
|
N_("list all documetnation files"), NULL },
|
|
|
|
{ "dump", '\0', 0, 0, POPT_DUMP,
|
|
|
|
N_("dump basic file information"), NULL },
|
|
|
|
{ "list", 'l', 0, 0, 'l',
|
|
|
|
N_("list files in package"), NULL },
|
1998-10-27 13:41:02 +08:00
|
|
|
{ "qf", '\0', POPT_ARG_STRING | POPT_ARGFLAG_DOC_HIDDEN, 0,
|
1998-11-20 03:10:23 +08:00
|
|
|
POPT_QUERYFORMAT, NULL, NULL },
|
1998-10-27 13:41:02 +08:00
|
|
|
{ "querybynumber", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0,
|
1998-11-20 03:10:23 +08:00
|
|
|
POPT_QUERYBYNUMBER, NULL, NULL },
|
1998-10-27 13:41:02 +08:00
|
|
|
{ "queryformat", '\0', POPT_ARG_STRING, 0, POPT_QUERYFORMAT,
|
1998-12-02 01:18:38 +08:00
|
|
|
N_("use the following query format"), "QUERYFORMAT" },
|
|
|
|
{ "state", 's', 0, 0, 's',
|
|
|
|
N_("display the states of the listed files"), NULL },
|
|
|
|
{ "verbose", 'v', 0, 0, 'v',
|
|
|
|
N_("display a verbose file listing"), NULL },
|
1998-11-20 03:10:23 +08:00
|
|
|
{ 0, 0, 0, 0, 0, NULL, NULL }
|
1998-10-27 13:41:02 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static void queryArgCallback(poptContext con, enum poptCallbackReason reason,
|
|
|
|
const struct poptOption * opt, const char * arg,
|
|
|
|
struct rpmQueryArguments * data) {
|
|
|
|
int len;
|
|
|
|
|
|
|
|
switch (opt->val) {
|
|
|
|
case 'c': data->flags |= QUERY_FOR_CONFIG | QUERY_FOR_LIST; break;
|
|
|
|
case 'd': data->flags |= QUERY_FOR_DOCS | QUERY_FOR_LIST; break;
|
|
|
|
case 'l': data->flags |= QUERY_FOR_LIST; break;
|
|
|
|
case 's': data->flags |= QUERY_FOR_STATE | QUERY_FOR_LIST; break;
|
|
|
|
case POPT_DUMP: data->flags |= QUERY_FOR_DUMPFILES | QUERY_FOR_LIST; break;
|
|
|
|
|
|
|
|
case 'a': data->source |= QUERY_ALL; data->sourceCount++; break;
|
|
|
|
case 'f': data->source |= QUERY_PATH; data->sourceCount++; break;
|
|
|
|
case 'g': data->source |= QUERY_GROUP; data->sourceCount++; break;
|
|
|
|
case 'p': data->source |= QUERY_RPM; data->sourceCount++; break;
|
1998-12-01 01:48:03 +08:00
|
|
|
case 'v': rpmIncreaseVerbosity(); break;
|
1998-11-20 08:29:46 +08:00
|
|
|
case POPT_SPECFILE: data->source |= QUERY_SPECFILE; data->sourceCount++; break;
|
1998-10-27 13:41:02 +08:00
|
|
|
case POPT_WHATPROVIDES: data->source |= QUERY_WHATPROVIDES;
|
|
|
|
data->sourceCount++; break;
|
|
|
|
case POPT_WHATREQUIRES: data->source |= QUERY_WHATREQUIRES;
|
|
|
|
data->sourceCount++; break;
|
|
|
|
case POPT_QUERYBYNUMBER: data->source |= QUERY_DBOFFSET;
|
|
|
|
data->sourceCount++; break;
|
|
|
|
case POPT_TRIGGEREDBY: data->source |= QUERY_TRIGGEREDBY;
|
|
|
|
data->sourceCount++; break;
|
|
|
|
|
|
|
|
case POPT_QUERYFORMAT:
|
|
|
|
if (data->queryFormat) {
|
|
|
|
len = strlen(data->queryFormat) + strlen(arg) + 1;
|
|
|
|
data->queryFormat = realloc(data->queryFormat, len);
|
|
|
|
strcat(data->queryFormat, arg);
|
|
|
|
} else {
|
|
|
|
data->queryFormat = malloc(strlen(arg) + 1);
|
|
|
|
strcpy(data->queryFormat, arg);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1996-06-28 04:47:54 +08:00
|
|
|
static int queryHeader(Header h, char * chptr) {
|
1997-05-30 04:09:45 +08:00
|
|
|
char * str;
|
|
|
|
char * error;
|
1996-06-28 04:47:54 +08:00
|
|
|
|
1997-05-30 04:09:45 +08:00
|
|
|
str = headerSprintf(h, chptr, rpmTagTable, rpmHeaderFormats, &error);
|
|
|
|
if (!str) {
|
1998-01-10 02:45:41 +08:00
|
|
|
fprintf(stderr, _("error in format: %s\n"), error);
|
1997-05-30 04:09:45 +08:00
|
|
|
return 1;
|
1996-04-02 11:36:00 +08:00
|
|
|
}
|
1996-06-09 01:27:10 +08:00
|
|
|
|
1997-05-30 04:09:45 +08:00
|
|
|
fputs(str, stdout);
|
1996-06-28 04:47:54 +08:00
|
|
|
|
|
|
|
return 0;
|
1996-04-02 11:36:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void printHeader(Header h, int queryFlags, char * queryFormat) {
|
1995-12-28 04:08:35 +08:00
|
|
|
char * name, * version, * release;
|
|
|
|
int_32 count, type;
|
|
|
|
char * prefix = NULL;
|
1996-06-21 06:28:02 +08:00
|
|
|
char ** fileList, ** fileMD5List;
|
1995-12-28 04:08:35 +08:00
|
|
|
char * fileStatesList;
|
1997-02-26 06:58:54 +08:00
|
|
|
char ** fileOwnerList = NULL;
|
|
|
|
char ** fileGroupList = NULL;
|
1996-02-19 23:17:56 +08:00
|
|
|
char ** fileLinktoList;
|
1996-02-19 12:50:33 +08:00
|
|
|
int_32 * fileFlagsList, * fileMTimeList, * fileSizeList;
|
|
|
|
int_32 * fileUIDList, * fileGIDList;
|
1996-06-21 06:28:02 +08:00
|
|
|
uint_16 * fileModeList;
|
|
|
|
uint_16 * fileRdevList;
|
1995-12-28 04:08:35 +08:00
|
|
|
int i;
|
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count);
|
|
|
|
headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &count);
|
|
|
|
headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &count);
|
1995-12-28 04:08:35 +08:00
|
|
|
|
1997-02-18 04:18:54 +08:00
|
|
|
if (!queryFormat && !queryFlags) {
|
1998-09-28 06:03:52 +08:00
|
|
|
fprintf(stdout, "%s-%s-%s\n", name, version, release);
|
1995-12-28 04:08:35 +08:00
|
|
|
} else {
|
1997-02-18 04:18:54 +08:00
|
|
|
if (queryFormat)
|
1996-06-28 04:47:54 +08:00
|
|
|
queryHeader(h, queryFormat);
|
1995-12-28 04:08:35 +08:00
|
|
|
|
|
|
|
if (queryFlags & QUERY_FOR_LIST) {
|
1996-11-19 02:02:36 +08:00
|
|
|
if (!headerGetEntry(h, RPMTAG_FILENAMES, &type, (void **) &fileList,
|
1996-01-06 02:12:17 +08:00
|
|
|
&count)) {
|
1998-09-28 06:03:52 +08:00
|
|
|
fputs(_("(contains no files)"), stdout);
|
1998-09-29 06:03:28 +08:00
|
|
|
fputs("\n", stdout);
|
1996-01-06 02:12:17 +08:00
|
|
|
} else {
|
1996-11-19 02:02:36 +08:00
|
|
|
if (!headerGetEntry(h, RPMTAG_FILESTATES, &type,
|
1996-03-30 03:24:52 +08:00
|
|
|
(void **) &fileStatesList, &count)) {
|
|
|
|
fileStatesList = NULL;
|
|
|
|
}
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILEFLAGS, &type,
|
1996-01-06 02:12:17 +08:00
|
|
|
(void **) &fileFlagsList, &count);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILESIZES, &type,
|
1996-02-19 12:50:33 +08:00
|
|
|
(void **) &fileSizeList, &count);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILEMODES, &type,
|
1996-02-19 12:50:33 +08:00
|
|
|
(void **) &fileModeList, &count);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILEMTIMES, &type,
|
1996-02-19 12:50:33 +08:00
|
|
|
(void **) &fileMTimeList, &count);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILERDEVS, &type,
|
1996-02-19 12:50:33 +08:00
|
|
|
(void **) &fileRdevList, &count);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILELINKTOS, &type,
|
1996-02-19 23:17:56 +08:00
|
|
|
(void **) &fileLinktoList, &count);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILEMD5S, &type,
|
1996-06-21 06:28:02 +08:00
|
|
|
(void **) &fileMD5List, &count);
|
1996-01-06 02:12:17 +08:00
|
|
|
|
1997-02-18 04:18:54 +08:00
|
|
|
if (!headerGetEntry(h, RPMTAG_FILEUIDS, &type,
|
|
|
|
(void **) &fileUIDList, &count)) {
|
|
|
|
fileUIDList = NULL;
|
1997-02-18 07:45:40 +08:00
|
|
|
} else {
|
1997-02-18 04:18:54 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILEGIDS, &type,
|
|
|
|
(void **) &fileGIDList, &count);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!headerGetEntry(h, RPMTAG_FILEUSERNAME, &type,
|
|
|
|
(void **) &fileOwnerList, &count)) {
|
|
|
|
fileOwnerList = NULL;
|
1997-02-18 07:45:40 +08:00
|
|
|
} else {
|
1997-02-18 04:18:54 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILEGROUPNAME, &type,
|
|
|
|
(void **) &fileGroupList, &count);
|
|
|
|
}
|
|
|
|
|
1996-01-06 02:12:17 +08:00
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
if (!((queryFlags & QUERY_FOR_DOCS) ||
|
|
|
|
(queryFlags & QUERY_FOR_CONFIG))
|
|
|
|
|| ((queryFlags & QUERY_FOR_DOCS) &&
|
|
|
|
(fileFlagsList[i] & RPMFILE_DOC))
|
|
|
|
|| ((queryFlags & QUERY_FOR_CONFIG) &&
|
|
|
|
(fileFlagsList[i] & RPMFILE_CONFIG))) {
|
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
if (!rpmIsVerbose())
|
1996-02-19 12:50:33 +08:00
|
|
|
prefix ? fputs(prefix, stdout) : 0;
|
1996-06-21 06:28:02 +08:00
|
|
|
|
|
|
|
if (queryFlags & QUERY_FOR_STATE) {
|
|
|
|
if (fileStatesList) {
|
|
|
|
switch (fileStatesList[i]) {
|
|
|
|
case RPMFILE_STATE_NORMAL:
|
1998-09-28 06:03:52 +08:00
|
|
|
fputs(_("normal "), stdout); break;
|
1996-06-21 06:28:02 +08:00
|
|
|
case RPMFILE_STATE_REPLACED:
|
1998-09-28 06:03:52 +08:00
|
|
|
fputs(_("replaced "), stdout); break;
|
1996-10-21 10:14:17 +08:00
|
|
|
case RPMFILE_STATE_NETSHARED:
|
1998-09-28 06:03:52 +08:00
|
|
|
fputs(_("net shared "), stdout); break;
|
1996-06-21 06:28:02 +08:00
|
|
|
case RPMFILE_STATE_NOTINSTALLED:
|
1998-09-28 06:03:52 +08:00
|
|
|
fputs(_("not installed "), stdout); break;
|
1996-06-21 06:28:02 +08:00
|
|
|
default:
|
1998-09-28 06:03:52 +08:00
|
|
|
fprintf(stdout, _("(unknown %3d) "),
|
1996-10-21 10:14:17 +08:00
|
|
|
fileStatesList[i]);
|
1996-02-19 12:50:33 +08:00
|
|
|
}
|
1996-06-21 06:28:02 +08:00
|
|
|
} else {
|
1998-09-28 06:03:52 +08:00
|
|
|
fputs( _("(no state) "), stdout);
|
1996-01-06 02:12:17 +08:00
|
|
|
}
|
1996-06-21 06:28:02 +08:00
|
|
|
}
|
1996-02-19 12:50:33 +08:00
|
|
|
|
1996-06-21 06:28:02 +08:00
|
|
|
if (queryFlags & QUERY_FOR_DUMPFILES) {
|
1998-09-28 06:03:52 +08:00
|
|
|
fprintf(stdout, "%s %d %d %s 0%o ", fileList[i],
|
1996-06-21 06:28:02 +08:00
|
|
|
fileSizeList[i], fileMTimeList[i],
|
|
|
|
fileMD5List[i], fileModeList[i]);
|
|
|
|
|
|
|
|
if (fileOwnerList)
|
1998-09-28 06:03:52 +08:00
|
|
|
fprintf(stdout, "%s %s", fileOwnerList[i],
|
1996-06-21 06:28:02 +08:00
|
|
|
fileGroupList[i]);
|
1997-02-18 04:18:54 +08:00
|
|
|
else if (fileUIDList)
|
1998-09-28 06:03:52 +08:00
|
|
|
fprintf(stdout, "%d %d", fileUIDList[i],
|
1996-06-21 06:28:02 +08:00
|
|
|
fileGIDList[i]);
|
1997-02-18 04:18:54 +08:00
|
|
|
else {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_INTERNAL, _("package has "
|
|
|
|
"neither file owner or id lists"));
|
1997-02-18 04:18:54 +08:00
|
|
|
}
|
1996-06-21 06:28:02 +08:00
|
|
|
|
1998-11-17 05:40:28 +08:00
|
|
|
fprintf(stdout, " %s %s %u ",
|
1996-06-21 06:28:02 +08:00
|
|
|
fileFlagsList[i] & RPMFILE_CONFIG ? "1" : "0",
|
|
|
|
fileFlagsList[i] & RPMFILE_DOC ? "1" : "0",
|
1998-11-17 05:40:28 +08:00
|
|
|
(unsigned)fileRdevList[i]);
|
1996-06-21 06:28:02 +08:00
|
|
|
|
|
|
|
if (strlen(fileLinktoList[i]))
|
1998-09-28 06:03:52 +08:00
|
|
|
fprintf(stdout, "%s\n", fileLinktoList[i]);
|
1996-06-21 06:28:02 +08:00
|
|
|
else
|
1998-09-28 06:03:52 +08:00
|
|
|
fprintf(stdout, "X\n");
|
1996-06-21 06:28:02 +08:00
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
} else if (!rpmIsVerbose()) {
|
1998-09-28 06:03:52 +08:00
|
|
|
fputs(fileList[i], stdout);
|
1998-09-29 06:03:28 +08:00
|
|
|
fputs("\n", stdout);
|
1996-02-19 12:50:33 +08:00
|
|
|
} else if (fileOwnerList)
|
|
|
|
printFileInfo(fileList[i], fileSizeList[i],
|
|
|
|
fileModeList[i], fileMTimeList[i],
|
|
|
|
fileRdevList[i], fileOwnerList[i],
|
1997-02-18 04:18:54 +08:00
|
|
|
fileGroupList[i], -1,
|
|
|
|
-1, fileLinktoList[i]);
|
|
|
|
else if (fileUIDList) {
|
1996-02-19 12:50:33 +08:00
|
|
|
printFileInfo(fileList[i], fileSizeList[i],
|
|
|
|
fileModeList[i], fileMTimeList[i],
|
|
|
|
fileRdevList[i], NULL,
|
|
|
|
NULL, fileUIDList[i],
|
1996-02-19 23:17:56 +08:00
|
|
|
fileGIDList[i], fileLinktoList[i]);
|
1997-02-18 04:18:54 +08:00
|
|
|
} else {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_INTERNAL, _("package has "
|
|
|
|
"neither file owner or id lists"));
|
1997-02-18 04:18:54 +08:00
|
|
|
}
|
1995-12-28 04:08:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1996-01-06 02:12:17 +08:00
|
|
|
free(fileList);
|
1996-02-19 23:17:56 +08:00
|
|
|
free(fileLinktoList);
|
1996-06-21 06:28:02 +08:00
|
|
|
free(fileMD5List);
|
1996-02-19 12:50:33 +08:00
|
|
|
if (fileOwnerList) free(fileOwnerList);
|
|
|
|
if (fileGroupList) free(fileGroupList);
|
1996-01-06 02:12:17 +08:00
|
|
|
}
|
1995-12-28 04:08:35 +08:00
|
|
|
}
|
1996-04-16 06:21:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1996-06-28 04:47:54 +08:00
|
|
|
static char * permsString(int mode) {
|
|
|
|
static char perms[11];
|
1996-02-20 00:29:15 +08:00
|
|
|
|
1998-09-29 06:03:28 +08:00
|
|
|
strcpy(perms, "----------");
|
1996-02-19 12:50:33 +08:00
|
|
|
|
1996-03-05 06:47:35 +08:00
|
|
|
if (mode & S_IRUSR) perms[1] = 'r';
|
|
|
|
if (mode & S_IWUSR) perms[2] = 'w';
|
|
|
|
if (mode & S_IXUSR) perms[3] = 'x';
|
|
|
|
|
|
|
|
if (mode & S_IRGRP) perms[4] = 'r';
|
|
|
|
if (mode & S_IWGRP) perms[5] = 'w';
|
|
|
|
if (mode & S_IXGRP) perms[6] = 'x';
|
|
|
|
|
|
|
|
if (mode & S_IROTH) perms[7] = 'r';
|
|
|
|
if (mode & S_IWOTH) perms[8] = 'w';
|
|
|
|
if (mode & S_IXOTH) perms[9] = 'x';
|
|
|
|
|
1998-09-29 06:03:28 +08:00
|
|
|
|
|
|
|
if (mode & S_ISVTX)
|
|
|
|
perms[9] = ((mode & S_IXOTH) ? 't' : 'T');
|
|
|
|
|
1996-03-05 06:47:35 +08:00
|
|
|
if (mode & S_ISUID) {
|
|
|
|
if (mode & S_IXUSR)
|
|
|
|
perms[3] = 's';
|
|
|
|
else
|
|
|
|
perms[3] = 'S';
|
|
|
|
}
|
1996-02-19 12:50:33 +08:00
|
|
|
|
1996-03-05 06:47:35 +08:00
|
|
|
if (mode & S_ISGID) {
|
|
|
|
if (mode & S_IXGRP)
|
|
|
|
perms[6] = 's';
|
|
|
|
else
|
|
|
|
perms[6] = 'S';
|
|
|
|
}
|
1996-02-19 12:50:33 +08:00
|
|
|
|
1996-06-28 04:47:54 +08:00
|
|
|
if (S_ISDIR(mode))
|
|
|
|
perms[0] = 'd';
|
|
|
|
else if (S_ISLNK(mode)) {
|
|
|
|
perms[0] = 'l';
|
|
|
|
}
|
|
|
|
else if (S_ISFIFO(mode))
|
|
|
|
perms[0] = 'p';
|
|
|
|
else if (S_ISSOCK(mode))
|
1998-09-28 00:05:54 +08:00
|
|
|
perms[0] = 's';
|
1996-06-28 04:47:54 +08:00
|
|
|
else if (S_ISCHR(mode)) {
|
|
|
|
perms[0] = 'c';
|
|
|
|
} else if (S_ISBLK(mode)) {
|
|
|
|
perms[0] = 'b';
|
|
|
|
}
|
|
|
|
|
|
|
|
return perms;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void printFileInfo(char * name, unsigned int size, unsigned short mode,
|
|
|
|
unsigned int mtime, unsigned short rdev,
|
|
|
|
char * owner, char * group, int uid, int gid,
|
|
|
|
char * linkto) {
|
|
|
|
char sizefield[15];
|
|
|
|
char ownerfield[9], groupfield[9];
|
|
|
|
char timefield[100] = "";
|
|
|
|
time_t themtime;
|
|
|
|
time_t currenttime;
|
|
|
|
static int thisYear = 0;
|
|
|
|
static int thisMonth = 0;
|
|
|
|
struct tm * tstruct;
|
|
|
|
char * namefield = name;
|
|
|
|
char * perms;
|
|
|
|
|
|
|
|
perms = permsString(mode);
|
|
|
|
|
|
|
|
if (!thisYear) {
|
|
|
|
currenttime = time(NULL);
|
|
|
|
tstruct = localtime(¤ttime);
|
|
|
|
thisYear = tstruct->tm_year;
|
|
|
|
thisMonth = tstruct->tm_mon;
|
|
|
|
}
|
|
|
|
|
1997-05-01 03:26:32 +08:00
|
|
|
ownerfield[8] = groupfield[8] = '\0';
|
|
|
|
|
1996-02-19 12:50:33 +08:00
|
|
|
if (owner)
|
|
|
|
strncpy(ownerfield, owner, 8);
|
|
|
|
else
|
|
|
|
sprintf(ownerfield, "%-8d", uid);
|
|
|
|
|
|
|
|
if (group)
|
|
|
|
strncpy(groupfield, group, 8);
|
1997-02-18 04:18:54 +08:00
|
|
|
else
|
1996-02-19 12:50:33 +08:00
|
|
|
sprintf(groupfield, "%-8d", gid);
|
|
|
|
|
|
|
|
/* this is normally right */
|
1998-11-17 05:40:28 +08:00
|
|
|
sprintf(sizefield, "%10u", size);
|
1996-02-19 12:50:33 +08:00
|
|
|
|
|
|
|
/* this knows too much about dev_t */
|
|
|
|
|
1996-06-28 04:47:54 +08:00
|
|
|
if (S_ISLNK(mode)) {
|
1996-02-19 23:17:56 +08:00
|
|
|
namefield = alloca(strlen(name) + strlen(linkto) + 10);
|
|
|
|
sprintf(namefield, "%s -> %s", name, linkto);
|
1996-06-28 04:47:54 +08:00
|
|
|
} else if (S_ISCHR(mode)) {
|
1996-02-19 12:50:33 +08:00
|
|
|
perms[0] = 'c';
|
1998-11-17 05:40:28 +08:00
|
|
|
sprintf(sizefield, "%3u, %3u", (rdev >> 8) & 0xff, rdev & 0xFF);
|
1996-02-19 12:50:33 +08:00
|
|
|
} else if (S_ISBLK(mode)) {
|
|
|
|
perms[0] = 'b';
|
1998-11-17 05:40:28 +08:00
|
|
|
sprintf(sizefield, "%3u, %3u", (rdev >> 8) & 0xff, rdev & 0xFF);
|
1996-02-19 12:50:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* this is important if sizeof(int_32) ! sizeof(time_t) */
|
|
|
|
themtime = mtime;
|
|
|
|
tstruct = localtime(&themtime);
|
|
|
|
|
|
|
|
if (tstruct->tm_year == thisYear ||
|
1998-11-17 05:40:28 +08:00
|
|
|
((tstruct->tm_year + 1) == thisYear && tstruct->tm_mon > thisMonth))
|
|
|
|
(void)strftime(timefield, sizeof(timefield) - 1, "%b %d %H:%M",tstruct);
|
1996-02-19 12:50:33 +08:00
|
|
|
else
|
1998-11-17 05:40:28 +08:00
|
|
|
(void)strftime(timefield, sizeof(timefield) - 1, "%b %d %Y", tstruct);
|
1996-02-19 12:50:33 +08:00
|
|
|
|
1998-09-28 06:03:52 +08:00
|
|
|
fprintf(stdout, "%s %8s %8s %10s %s %s\n", perms, ownerfield, groupfield,
|
1996-02-19 23:17:56 +08:00
|
|
|
sizefield, timefield, namefield);
|
1996-02-19 12:50:33 +08:00
|
|
|
}
|
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
static void showMatches(rpmdb db, dbiIndexSet matches, int queryFlags,
|
1996-04-02 11:36:00 +08:00
|
|
|
char * queryFormat) {
|
1996-01-06 02:12:17 +08:00
|
|
|
int i;
|
|
|
|
Header h;
|
|
|
|
|
1998-11-20 02:10:28 +08:00
|
|
|
for (i = 0; i < dbiIndexSetCount(matches); i++) {
|
|
|
|
unsigned int recOffset = dbiIndexRecordOffset(matches, i);
|
|
|
|
if (recOffset) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("querying record number %d\n"),
|
1998-11-20 02:10:28 +08:00
|
|
|
recOffset);
|
1996-02-15 04:56:22 +08:00
|
|
|
|
1998-11-20 02:10:28 +08:00
|
|
|
h = rpmdbGetRecord(db, recOffset);
|
1998-11-17 05:40:28 +08:00
|
|
|
if (h == NULL) {
|
1997-04-29 10:45:19 +08:00
|
|
|
fprintf(stderr, _("error: could not read database record\n"));
|
1996-02-15 04:56:22 +08:00
|
|
|
} else {
|
1996-04-02 11:36:00 +08:00
|
|
|
printHeader(h, queryFlags, queryFormat);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(h);
|
1996-02-15 04:56:22 +08:00
|
|
|
}
|
1996-01-06 02:12:17 +08:00
|
|
|
}
|
1995-12-28 04:08:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-10-27 13:41:02 +08:00
|
|
|
int rpmQuery(char * prefix, enum rpmQuerySources source, int queryFlags,
|
1996-04-02 11:36:00 +08:00
|
|
|
char * arg, char * queryFormat) {
|
1995-12-28 04:08:35 +08:00
|
|
|
Header h;
|
|
|
|
int offset;
|
1996-01-06 02:12:17 +08:00
|
|
|
int rc;
|
|
|
|
int isSource;
|
1995-12-28 04:08:35 +08:00
|
|
|
rpmdb db;
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiIndexSet matches;
|
1996-03-01 11:29:18 +08:00
|
|
|
int recNumber;
|
1996-04-03 11:45:27 +08:00
|
|
|
int retcode = 0;
|
1996-06-21 06:28:02 +08:00
|
|
|
char *end = NULL;
|
1998-07-25 04:30:55 +08:00
|
|
|
char path[PATH_MAX];
|
1995-12-28 04:08:35 +08:00
|
|
|
|
1998-11-20 08:29:46 +08:00
|
|
|
switch (source) {
|
|
|
|
default:
|
1996-02-19 12:50:33 +08:00
|
|
|
if (rpmdbOpen(prefix, &db, O_RDONLY, 0644)) {
|
1998-11-20 08:29:46 +08:00
|
|
|
fprintf(stderr, _("rpmQuery: rpmdbOpen() failed\n"));
|
1996-01-09 03:44:29 +08:00
|
|
|
exit(1);
|
|
|
|
}
|
1998-11-20 08:29:46 +08:00
|
|
|
break;
|
|
|
|
case QUERY_RPM:
|
|
|
|
case QUERY_SPECFILE:
|
|
|
|
break;
|
1995-12-28 04:08:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (source) {
|
|
|
|
case QUERY_RPM:
|
1998-12-01 08:10:18 +08:00
|
|
|
{ FD_t fd;
|
|
|
|
|
|
|
|
fd = ufdOpen(arg, O_RDONLY, 0);
|
|
|
|
if (fd == NULL) {
|
|
|
|
fprintf(stderr, _("open of %s failed\n"), arg);
|
|
|
|
ufdClose(fd);
|
|
|
|
retcode = 1;
|
|
|
|
break;
|
1996-10-15 11:14:50 +08:00
|
|
|
}
|
|
|
|
|
1998-12-01 08:10:18 +08:00
|
|
|
if (fdFileno(fd) >= 0) {
|
1996-11-19 02:02:36 +08:00
|
|
|
rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
|
1998-12-01 08:10:18 +08:00
|
|
|
} else
|
|
|
|
rc = 2;
|
1996-10-15 11:14:50 +08:00
|
|
|
|
1998-12-01 08:10:18 +08:00
|
|
|
ufdClose(fd);
|
1996-10-15 11:14:50 +08:00
|
|
|
|
1998-12-01 08:10:18 +08:00
|
|
|
switch (rc) {
|
|
|
|
case 0:
|
|
|
|
if (h == NULL) {
|
|
|
|
fprintf(stderr, _("old format source packages cannot "
|
|
|
|
"be queried\n"));
|
|
|
|
} else {
|
|
|
|
printHeader(h, queryFlags, queryFormat);
|
|
|
|
headerFree(h);
|
1996-01-06 02:12:17 +08:00
|
|
|
}
|
1998-12-01 08:10:18 +08:00
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
fprintf(stderr, _("%s does not appear to be a RPM package\n"), arg);
|
|
|
|
/* fallthrough */
|
|
|
|
case 2:
|
|
|
|
fprintf(stderr, _("query of %s failed\n"), arg);
|
|
|
|
retcode = 1;
|
|
|
|
break;
|
1996-01-06 02:12:17 +08:00
|
|
|
}
|
1998-11-19 05:41:05 +08:00
|
|
|
} break;
|
1995-12-28 04:08:35 +08:00
|
|
|
|
1998-11-20 08:29:46 +08:00
|
|
|
case QUERY_SPECFILE:
|
|
|
|
{ Spec spec = NULL;
|
|
|
|
Package pkg;
|
|
|
|
char * buildRoot = NULL;
|
|
|
|
int inBuildArch = 0;
|
|
|
|
char * passPhrase = "";
|
|
|
|
char *cookie = NULL;
|
|
|
|
int anyarch = 1;
|
|
|
|
int force = 1;
|
|
|
|
rc = parseSpec(&spec, arg, buildRoot, inBuildArch, passPhrase, cookie,
|
|
|
|
anyarch, force);
|
|
|
|
if (rc || spec == NULL) {
|
|
|
|
|
|
|
|
fprintf(stderr, _("query of specfile %s failed, can't parse\n"), arg);
|
|
|
|
if (spec != NULL) freeSpec(spec);
|
|
|
|
retcode = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
|
|
|
|
#if 0
|
|
|
|
char *binRpm, *errorString;
|
|
|
|
binRpm = headerSprintf(pkg->header, rpmGetVar(RPMVAR_RPMFILENAME),
|
|
|
|
rpmTagTable, rpmHeaderFormats, &errorString);
|
|
|
|
if (!(pkg == spec->packages && pkg->next == NULL))
|
|
|
|
fprintf(stdout, "====== %s\n", binRpm);
|
|
|
|
free(binRpm);
|
|
|
|
#endif
|
|
|
|
printHeader(pkg->header, queryFlags, queryFormat);
|
|
|
|
}
|
|
|
|
freeSpec(spec);
|
|
|
|
} break;
|
|
|
|
|
1995-12-28 04:08:35 +08:00
|
|
|
case QUERY_ALL:
|
|
|
|
offset = rpmdbFirstRecNum(db);
|
|
|
|
while (offset) {
|
|
|
|
h = rpmdbGetRecord(db, offset);
|
1998-11-17 05:40:28 +08:00
|
|
|
if (h == NULL) {
|
1997-04-29 10:45:19 +08:00
|
|
|
fprintf(stderr, _("could not read database record!\n"));
|
1996-04-03 11:45:27 +08:00
|
|
|
return 1;
|
1995-12-28 04:08:35 +08:00
|
|
|
}
|
1996-04-02 11:36:00 +08:00
|
|
|
printHeader(h, queryFlags, queryFormat);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(h);
|
1995-12-28 04:08:35 +08:00
|
|
|
offset = rpmdbNextRecNum(db, offset);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1996-01-06 02:12:17 +08:00
|
|
|
case QUERY_GROUP:
|
|
|
|
if (rpmdbFindByGroup(db, arg, &matches)) {
|
1997-04-29 10:45:19 +08:00
|
|
|
fprintf(stderr, _("group %s does not contain any packages\n"), arg);
|
1996-04-03 11:45:27 +08:00
|
|
|
retcode = 1;
|
1996-01-06 02:12:17 +08:00
|
|
|
} else {
|
1996-04-02 11:36:00 +08:00
|
|
|
showMatches(db, matches, queryFlags, queryFormat);
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiFreeIndexRecord(matches);
|
1996-01-06 02:12:17 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1996-06-21 06:28:02 +08:00
|
|
|
case QUERY_WHATPROVIDES:
|
1996-06-10 05:47:42 +08:00
|
|
|
if (rpmdbFindByProvides(db, arg, &matches)) {
|
1997-04-29 10:45:19 +08:00
|
|
|
fprintf(stderr, _("no package provides %s\n"), arg);
|
1996-06-10 05:47:42 +08:00
|
|
|
retcode = 1;
|
|
|
|
} else {
|
|
|
|
showMatches(db, matches, queryFlags, queryFormat);
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiFreeIndexRecord(matches);
|
1996-06-10 05:47:42 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
case QUERY_TRIGGEREDBY:
|
|
|
|
if (rpmdbFindByTriggeredBy(db, arg, &matches)) {
|
|
|
|
fprintf(stderr, _("no package triggers %s\n"), arg);
|
|
|
|
retcode = 1;
|
|
|
|
} else {
|
|
|
|
showMatches(db, matches, queryFlags, queryFormat);
|
|
|
|
dbiFreeIndexRecord(matches);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1996-06-21 06:28:02 +08:00
|
|
|
case QUERY_WHATREQUIRES:
|
1996-06-10 05:47:42 +08:00
|
|
|
if (rpmdbFindByRequiredBy(db, arg, &matches)) {
|
1997-04-29 10:45:19 +08:00
|
|
|
fprintf(stderr, _("no package requires %s\n"), arg);
|
1996-06-10 05:47:42 +08:00
|
|
|
retcode = 1;
|
|
|
|
} else {
|
|
|
|
showMatches(db, matches, queryFlags, queryFormat);
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiFreeIndexRecord(matches);
|
1996-06-10 05:47:42 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1995-12-28 04:08:35 +08:00
|
|
|
case QUERY_PATH:
|
1996-04-16 05:06:26 +08:00
|
|
|
if (*arg != '/') {
|
1998-07-25 04:30:55 +08:00
|
|
|
/* Using realpath on the arg isn't correct if the arg is a symlink,
|
|
|
|
* especially if the symlink is a dangling link. What we should
|
|
|
|
* instead do is use realpath() on `.' and then append arg to
|
|
|
|
* it.
|
|
|
|
*/
|
|
|
|
if (realpath(".", path) != NULL) {
|
|
|
|
if (path[strlen(path)] != '/') {
|
|
|
|
if (strncat(path, "/", PATH_MAX - strlen(path) - 1) == NULL) {
|
|
|
|
fprintf(stderr, _("maximum path length exceeded\n"));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* now append the original file name to the real path */
|
|
|
|
if (strncat(path, arg, PATH_MAX - strlen(path) - 1) == NULL) {
|
|
|
|
fprintf(stderr, _("maximum path length exceeded\n"));
|
|
|
|
return 1;
|
|
|
|
}
|
1996-04-16 05:06:26 +08:00
|
|
|
arg = path;
|
1998-07-25 04:30:55 +08:00
|
|
|
}
|
1996-04-16 05:06:26 +08:00
|
|
|
}
|
1995-12-28 04:08:35 +08:00
|
|
|
if (rpmdbFindByFile(db, arg, &matches)) {
|
1998-07-25 04:30:55 +08:00
|
|
|
int myerrno = 0;
|
|
|
|
if (access(arg, F_OK) != 0)
|
|
|
|
myerrno = errno;
|
|
|
|
switch (myerrno) {
|
|
|
|
default:
|
|
|
|
fprintf(stderr, _("file %s: %s\n"), arg, strerror(myerrno));
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
fprintf(stderr, _("file %s is not owned by any package\n"), arg);
|
|
|
|
break;
|
|
|
|
}
|
1996-04-03 11:45:27 +08:00
|
|
|
retcode = 1;
|
1995-12-28 04:08:35 +08:00
|
|
|
} else {
|
1996-04-02 11:36:00 +08:00
|
|
|
showMatches(db, matches, queryFlags, queryFormat);
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiFreeIndexRecord(matches);
|
1995-12-28 04:08:35 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1996-06-21 06:28:02 +08:00
|
|
|
case QUERY_DBOFFSET:
|
|
|
|
recNumber = strtoul(arg, &end, 10);
|
|
|
|
if ((*end) || (end == arg) || (recNumber == ULONG_MAX)) {
|
1997-04-29 10:45:19 +08:00
|
|
|
fprintf(stderr, _("invalid package number: %s\n"), arg);
|
1996-06-21 06:28:02 +08:00
|
|
|
return 1;
|
|
|
|
}
|
1997-04-29 10:45:19 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("showing package: %d\n"), recNumber);
|
1996-06-21 06:28:02 +08:00
|
|
|
h = rpmdbGetRecord(db, recNumber);
|
1998-11-17 05:40:28 +08:00
|
|
|
if (h == NULL) {
|
1997-04-29 10:45:19 +08:00
|
|
|
fprintf(stderr, _("record %d could not be read\n"), recNumber);
|
1996-06-21 06:28:02 +08:00
|
|
|
retcode = 1;
|
1996-01-06 02:12:17 +08:00
|
|
|
} else {
|
1996-06-21 06:28:02 +08:00
|
|
|
printHeader(h, queryFlags, queryFormat);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(h);
|
1996-06-21 06:28:02 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QUERY_PACKAGE:
|
1997-05-31 05:14:34 +08:00
|
|
|
rc = rpmdbFindByLabel(db, arg, &matches);
|
1996-06-21 06:28:02 +08:00
|
|
|
if (rc == 1) {
|
|
|
|
retcode = 1;
|
1997-04-29 10:45:19 +08:00
|
|
|
fprintf(stderr, _("package %s is not installed\n"), arg);
|
1996-06-21 06:28:02 +08:00
|
|
|
} else if (rc == 2) {
|
|
|
|
retcode = 1;
|
1997-04-29 10:45:19 +08:00
|
|
|
fprintf(stderr, _("error looking for package %s\n"), arg);
|
1996-06-21 06:28:02 +08:00
|
|
|
} else {
|
|
|
|
showMatches(db, matches, queryFlags, queryFormat);
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiFreeIndexRecord(matches);
|
1996-01-06 02:12:17 +08:00
|
|
|
}
|
1995-12-28 04:08:35 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1998-11-20 08:29:46 +08:00
|
|
|
switch (source) {
|
|
|
|
default:
|
1996-01-09 03:44:29 +08:00
|
|
|
rpmdbClose(db);
|
1998-11-20 08:29:46 +08:00
|
|
|
break;
|
|
|
|
case QUERY_RPM:
|
|
|
|
case QUERY_SPECFILE:
|
|
|
|
break;
|
1996-01-09 03:44:29 +08:00
|
|
|
}
|
1996-04-03 11:45:27 +08:00
|
|
|
|
|
|
|
return retcode;
|
1995-12-28 04:08:35 +08:00
|
|
|
}
|
1996-02-15 04:56:22 +08:00
|
|
|
|
1998-10-27 13:41:02 +08:00
|
|
|
void rpmDisplayQueryTags(FILE * f) {
|
1997-01-23 04:25:23 +08:00
|
|
|
const struct headerTagTableEntry * t;
|
1996-04-03 11:45:27 +08:00
|
|
|
int i;
|
1998-09-29 22:19:39 +08:00
|
|
|
const struct headerSprintfExtension * ext = rpmHeaderFormats;
|
1996-04-03 11:45:27 +08:00
|
|
|
|
|
|
|
for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++) {
|
1998-10-27 13:41:02 +08:00
|
|
|
fprintf(f, "%s\n", t->name + 7);
|
1996-04-03 11:45:27 +08:00
|
|
|
}
|
1998-08-16 22:06:19 +08:00
|
|
|
|
|
|
|
while (ext->name) {
|
|
|
|
if (ext->type == HEADER_EXT_TAG)
|
1998-10-27 13:41:02 +08:00
|
|
|
fprintf(f, "%s\n", ext->name + 7), ext++;
|
1998-08-16 22:06:19 +08:00
|
|
|
else if (ext->type == HEADER_EXT_MORE)
|
|
|
|
ext = ext->u.more;
|
|
|
|
else
|
|
|
|
ext++;
|
|
|
|
}
|
1996-04-03 11:45:27 +08:00
|
|
|
}
|