RIP rpmsx and all its uses
This commit is contained in:
parent
c0bd72b026
commit
0df97d170a
|
@ -20,7 +20,7 @@ check_PROGRAMS =
|
|||
pkgincdir = $(pkgincludedir)
|
||||
pkginc_HEADERS = \
|
||||
idtx.h misc.h rpmcli.h rpmlib.h \
|
||||
rpmal.h rpmds.h rpmfi.h rpmgi.h rpmps.h rpmsx.h rpmte.h rpmts.h \
|
||||
rpmal.h rpmds.h rpmfi.h rpmgi.h rpmps.h rpmte.h rpmts.h \
|
||||
stringbuf.h
|
||||
|
||||
usrlibdir = $(libdir)
|
||||
|
@ -30,7 +30,7 @@ librpm_la_SOURCES = \
|
|||
idtx.c manifest.c manifest.h misc.c package.c \
|
||||
poptALL.c poptI.c poptQV.c psm.c psm.h query.c \
|
||||
rpmal.c rpmchecksig.c rpmds.c rpmfi.c rpmgi.c rpminstall.c \
|
||||
rpmlead.c rpmlead.h rpmlibprov.c rpmps.c rpmrc.c rpmsx.c rpmte.c rpmts.c \
|
||||
rpmlead.c rpmlead.h rpmlibprov.c rpmps.c rpmrc.c rpmte.c rpmts.c \
|
||||
rpmvercmp.c signature.c signature.h stringbuf.c transaction.c \
|
||||
verify.c rpmlock.c rpmlock.h
|
||||
librpm_la_LDFLAGS = -release 4.4 \
|
||||
|
@ -100,11 +100,6 @@ tsystem_SOURCES = tsystem.c
|
|||
tsystem_LDFLAGS =
|
||||
tsystem_LDADD = ../rpmio/librpmio.la @WITH_POPT_LIB@
|
||||
|
||||
check_PROGRAMS += tre
|
||||
tre_SOURCES = tre.c
|
||||
tre_LDFLAGS =
|
||||
tre_LDADD = librpm.la @WITH_SELINUX_LIB@
|
||||
|
||||
check_PROGRAMS += tcpu
|
||||
tcpu_SOURCES = tcpu.c
|
||||
# tcpu_LDFLAGS = @LDFLAGS_STATIC@
|
||||
|
|
|
@ -72,9 +72,6 @@ extern int _rpmps_debug;
|
|||
/*@unchecked@*/
|
||||
extern int _rpmsq_debug;
|
||||
|
||||
/*@unchecked@*/
|
||||
extern int _rpmsx_debug;
|
||||
|
||||
/*@unchecked@*/
|
||||
extern int _rpmte_debug;
|
||||
|
||||
|
@ -357,8 +354,6 @@ struct poptOption rpmcliAllPoptTable[] = {
|
|||
NULL, NULL},
|
||||
{ "rpmsqdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmsq_debug, -1,
|
||||
NULL, NULL},
|
||||
{ "rpmsxdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmsx_debug, -1,
|
||||
NULL, NULL},
|
||||
{ "rpmtedebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmte_debug, -1,
|
||||
NULL, NULL},
|
||||
{ "rpmtsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_debug, -1,
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
#define _RPMFI_INTERNAL
|
||||
#include "rpmfi.h"
|
||||
|
||||
#include "rpmsx.h"
|
||||
|
||||
#define _RPMTE_INTERNAL /* relocations */
|
||||
#include "rpmte.h"
|
||||
#include "rpmts.h"
|
||||
|
|
709
lib/rpmsx.c
709
lib/rpmsx.c
|
@ -1,709 +0,0 @@
|
|||
/** \ingroup rpmdep
|
||||
* \file lib/rpmsx.c
|
||||
*/
|
||||
#include "system.h"
|
||||
|
||||
#include <rpmlib.h>
|
||||
#include <rpmmacro.h> /* for rpmGetPath() */
|
||||
|
||||
#define _RPMSX_INTERNAL
|
||||
#include "rpmsx.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
/*@access regex_t @*/
|
||||
|
||||
/*@unchecked@*/
|
||||
int _rpmsx_debug = 0;
|
||||
|
||||
/**
|
||||
* Stable sort for policy specifications, patterns before paths.
|
||||
* @param sx security context patterns
|
||||
*/
|
||||
static void rpmsxSort(rpmsx sx)
|
||||
/*@modifies sx @*/
|
||||
{
|
||||
rpmsxp sxp;
|
||||
int i, j;
|
||||
|
||||
/* Stable sort for policy regex's and paths. */
|
||||
sxp = xmalloc(sizeof(*sxp) * sx->Count);
|
||||
|
||||
/* Regex patterns first ... */
|
||||
j = 0;
|
||||
for (i = 0; i < sx->Count; i++) {
|
||||
if (!sx->sxp[i].hasMetaChars)
|
||||
continue;
|
||||
memcpy(sxp + j, sx->sxp + i, sizeof(*sxp));
|
||||
j++;
|
||||
}
|
||||
|
||||
/* ... then file paths. */
|
||||
for (i = 0; i < sx->Count; i++) {
|
||||
if (sx->sxp[i].hasMetaChars)
|
||||
continue;
|
||||
memcpy(sxp + j, sx->sxp + i, sizeof(*sxp));
|
||||
j++;
|
||||
}
|
||||
|
||||
sx->sxp = _free(sx->sxp);
|
||||
sx->sxp = sxp;
|
||||
/*@-compdef@*/ /* XXX *(sx->sxp) annotation */
|
||||
return;
|
||||
/*@=compdef@*/
|
||||
}
|
||||
|
||||
/* Determine if the regular expression specification has any meta characters. */
|
||||
static void rpmsxpHasMetaChars(rpmsxp sxp)
|
||||
/*@modifies sxp @*/
|
||||
{
|
||||
const char * s = sxp->pattern;
|
||||
size_t ns = strlen(s);
|
||||
const char * se = s + ns;
|
||||
|
||||
sxp->hasMetaChars = 0;
|
||||
|
||||
/* Look at each character in the RE specification string for a
|
||||
* meta character. Return when any meta character reached. */
|
||||
while (s != se) {
|
||||
switch(*s) {
|
||||
case '.':
|
||||
case '^':
|
||||
case '$':
|
||||
case '?':
|
||||
case '*':
|
||||
case '+':
|
||||
case '|':
|
||||
case '[':
|
||||
case '(':
|
||||
case '{':
|
||||
sxp->hasMetaChars = 1;
|
||||
return;
|
||||
/*@notreached@*/ /*@switchbreak@*/ break;
|
||||
case '\\': /* skip the next character */
|
||||
s++;
|
||||
/*@switchbreak@*/ break;
|
||||
default:
|
||||
/*@switchbreak@*/ break;
|
||||
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length of the text that can be considered the stem.
|
||||
* @return stem length, 0 if no identifiable stem
|
||||
*/
|
||||
static size_t rpmsxsPStem(const char * const buf)
|
||||
/*@*/
|
||||
{
|
||||
/*@observer@*/
|
||||
static const char * const regex_chars = ".^$?*+|[({";
|
||||
const char * tmp = strchr(buf, '/');
|
||||
const char * ind;
|
||||
|
||||
if (!tmp)
|
||||
return 0;
|
||||
|
||||
for (ind = buf; ind < tmp; ind++) {
|
||||
if (strchr(regex_chars, (int)*ind))
|
||||
return 0;
|
||||
}
|
||||
return tmp - buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length of the text that is the stem of a file name.
|
||||
* @return stem length, 0 if no identifiable stem
|
||||
*/
|
||||
static size_t rpmsxsFStem(const char * const buf)
|
||||
/*@*/
|
||||
{
|
||||
const char * tmp = strchr(buf + 1, '/');
|
||||
|
||||
if (!tmp)
|
||||
return 0;
|
||||
return tmp - buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find (or create) the stem of a file spec.
|
||||
* Error iff a file in the root directory or a regex that is too complex.
|
||||
*
|
||||
* @retval *bpp ptr to text after stem.
|
||||
* @return stem index, -1 on error
|
||||
*/
|
||||
static int rpmsxAdd(rpmsx sx, const char ** bpp)
|
||||
/*@modifies sx, *bpp @*/
|
||||
{
|
||||
size_t stem_len = rpmsxsPStem(*bpp);
|
||||
rpmsxs sxs;
|
||||
int i;
|
||||
|
||||
if (!stem_len)
|
||||
return -1;
|
||||
for (i = 0; i < sx->nsxs; i++) {
|
||||
sxs = sx->sxs + i;
|
||||
if (stem_len != sxs->len)
|
||||
continue;
|
||||
if (strncmp(*bpp, sxs->stem, stem_len))
|
||||
continue;
|
||||
*bpp += stem_len;
|
||||
return i;
|
||||
}
|
||||
|
||||
if (sx->nsxs == sx->maxsxs) {
|
||||
sx->maxsxs = sx->maxsxs * 2 + 16;
|
||||
sx->sxs = xrealloc(sx->sxs, sizeof(*sx->sxs) * sx->maxsxs);
|
||||
}
|
||||
sxs = sx->sxs + sx->nsxs;
|
||||
sxs->len = stem_len;
|
||||
#ifdef HAVE_STRNDUP
|
||||
/*@i@*/ sxs->stem = strndup(*bpp, stem_len);
|
||||
#else
|
||||
sxs->stem = xmalloc(stem_len+1);
|
||||
strncpy(sxs->stem, *bpp, stem_len);
|
||||
#endif
|
||||
sx->nsxs++;
|
||||
*bpp += stem_len;
|
||||
return sx->nsxs - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the stem of a file name.
|
||||
* Error iff a file in the root directory or a regex that is too complex.
|
||||
*
|
||||
* @param sx security context patterns
|
||||
* @retval *bpp ptr to text after stem.
|
||||
* @return stem index, -1 on error
|
||||
*/
|
||||
static int rpmsxFind(/*@null@*/ const rpmsx sx, const char ** bpp)
|
||||
/*@modifies *bpp @*/
|
||||
{
|
||||
size_t stem_len = rpmsxsFStem(*bpp);
|
||||
rpmsxs sxs;
|
||||
int i;
|
||||
|
||||
if (sx != NULL && stem_len > 0)
|
||||
for (i = 0; i < sx->nsxs; i++) {
|
||||
sxs = sx->sxs + i;
|
||||
if (stem_len != sxs->len)
|
||||
continue;
|
||||
/*@i@*/ if (strncmp(*bpp, sxs->stem, stem_len))
|
||||
continue;
|
||||
*bpp += stem_len;
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
rpmsx XrpmsxUnlink(rpmsx sx, const char * msg, const char * fn, unsigned ln)
|
||||
{
|
||||
if (sx == NULL) return NULL;
|
||||
/*@-modfilesys@*/
|
||||
if (_rpmsx_debug && msg != NULL)
|
||||
fprintf(stderr, "--> sx %p -- %d %s at %s:%u\n", sx, sx->nrefs, msg, fn, ln);
|
||||
/*@=modfilesys@*/
|
||||
sx->nrefs--;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rpmsx XrpmsxLink(rpmsx sx, const char * msg, const char * fn, unsigned ln)
|
||||
{
|
||||
if (sx == NULL) return NULL;
|
||||
sx->nrefs++;
|
||||
|
||||
/*@-modfilesys@*/
|
||||
if (_rpmsx_debug && msg != NULL)
|
||||
fprintf(stderr, "--> sx %p ++ %d %s at %s:%u\n", sx, sx->nrefs, msg, fn, ln);
|
||||
/*@=modfilesys@*/
|
||||
|
||||
/*@-refcounttrans@*/ return sx; /*@=refcounttrans@*/
|
||||
}
|
||||
|
||||
rpmsx rpmsxFree(rpmsx sx)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (sx == NULL)
|
||||
return NULL;
|
||||
|
||||
if (sx->nrefs > 1)
|
||||
return rpmsxUnlink(sx, __func__);
|
||||
|
||||
/*@-modfilesys@*/
|
||||
if (_rpmsx_debug < 0)
|
||||
fprintf(stderr, "*** sx %p\t%s[%d]\n", sx, __func__, sx->Count);
|
||||
/*@=modfilesys@*/
|
||||
|
||||
/*@-branchstate@*/
|
||||
if (sx->Count > 0)
|
||||
for (i = 0; i < sx->Count; i++) {
|
||||
rpmsxp sxp = sx->sxp + i;
|
||||
sxp->pattern = _free(sxp->pattern);
|
||||
sxp->type = _free(sxp->type);
|
||||
sxp->context = _free(sxp->context);
|
||||
/*@i@*/ regfree(sxp->preg);
|
||||
/*@i@*/ sxp->preg = _free(sxp->preg);
|
||||
}
|
||||
sx->sxp = _free(sx->sxp);
|
||||
|
||||
if (sx->nsxs > 0)
|
||||
for (i = 0; i < sx->nsxs; i++) {
|
||||
rpmsxs sxs = sx->sxs + i;
|
||||
sxs->stem = _free(sxs->stem);
|
||||
}
|
||||
sx->sxs = _free(sx->sxs);
|
||||
/*@=branchstate@*/
|
||||
|
||||
(void) rpmsxUnlink(sx, __func__);
|
||||
/*@-refcounttrans -usereleased@*/
|
||||
/*@-boundswrite@*/
|
||||
memset(sx, 0, sizeof(*sx)); /* XXX trash and burn */
|
||||
/*@=boundswrite@*/
|
||||
sx = _free(sx);
|
||||
/*@=refcounttrans =usereleased@*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for duplicate specifications. If a duplicate specification is found
|
||||
* and the context is the same, give a warning to the user. If a duplicate
|
||||
* specification is found and the context is different, give a warning
|
||||
* to the user (This could be changed to error). Return of non-zero is an error.
|
||||
*
|
||||
* @param sx security context patterns
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int rpmsxpCheckNoDupes(const rpmsx sx)
|
||||
/*@*/
|
||||
{
|
||||
int i, j;
|
||||
int rc = 0;
|
||||
|
||||
for (i = 0; i < sx->Count; i++) {
|
||||
rpmsxp sxpi = sx->sxp + i;
|
||||
for (j = i + 1; j < sx->Count; j++) {
|
||||
rpmsxp sxpj = sx->sxp + j;
|
||||
|
||||
/* Check if same RE string */
|
||||
if (strcmp(sxpj->pattern, sxpi->pattern))
|
||||
/*@innercontinue@*/ continue;
|
||||
if (sxpj->fmode && sxpi->fmode && sxpj->fmode != sxpi->fmode)
|
||||
/*@innercontinue@*/ continue;
|
||||
|
||||
/* Same RE string found */
|
||||
if (strcmp(sxpj->context, sxpi->context)) {
|
||||
/* If different contexts, give warning */
|
||||
/*@-modfilesys@*/
|
||||
fprintf(stderr,
|
||||
"ERROR: Multiple different specifications for %s (%s and %s).\n",
|
||||
sxpi->pattern, sxpj->context, sxpi->context);
|
||||
/*@=modfilesys@*/
|
||||
rc = -1;
|
||||
} else {
|
||||
/* If same contexts give warning */
|
||||
/*@-modfilesys@*/
|
||||
fprintf(stderr,
|
||||
"WARNING: Multiple same specifications for %s.\n",
|
||||
sxpi->pattern);
|
||||
/*@=modfilesys@*/
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int rpmsxParse(rpmsx sx, const char * fn)
|
||||
{
|
||||
FILE * fp;
|
||||
char buf[BUFSIZ + 1];
|
||||
char * bp;
|
||||
char * regex;
|
||||
char * type;
|
||||
char * context;
|
||||
char * anchored_regex;
|
||||
int items;
|
||||
int len;
|
||||
int lineno;
|
||||
int pass;
|
||||
int regerr;
|
||||
int nerr = 0;
|
||||
|
||||
#define inc_err() nerr++
|
||||
|
||||
/*@-branchstate@*/
|
||||
if (fn == NULL)
|
||||
fn = "%{?__file_context_path}";
|
||||
/*@=branchstate@*/
|
||||
|
||||
{ const char * myfn = rpmGetPath(fn, NULL);
|
||||
|
||||
if (myfn == NULL || *myfn == '\0'
|
||||
|| (fp = fopen(myfn, "r")) == NULL)
|
||||
{
|
||||
myfn = _free(myfn);
|
||||
return -1;
|
||||
}
|
||||
myfn = _free(myfn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform two passes over the specification file.
|
||||
* The first pass counts the number of specifications and
|
||||
* performs simple validation of the input. At the end
|
||||
* of the first pass, the spec array is allocated.
|
||||
* The second pass performs detailed validation of the input
|
||||
* and fills in the spec array.
|
||||
*/
|
||||
/*@-branchstate@*/
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
rpmsxp sxp;
|
||||
|
||||
lineno = 0;
|
||||
sx->Count = 0;
|
||||
sxp = sx->sxp;
|
||||
while (fgets(buf, sizeof(buf)-1, fp)) {
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
lineno++;
|
||||
len = strlen(buf);
|
||||
if (buf[len - 1] != '\n') {
|
||||
fprintf(stderr,
|
||||
_("%s: no newline on line number %d (only read %s)\n"),
|
||||
fn, lineno, buf);
|
||||
inc_err();
|
||||
/*@innercontinue@*/ continue;
|
||||
}
|
||||
buf[len - 1] = 0;
|
||||
bp = buf;
|
||||
while (isspace(*bp))
|
||||
bp++;
|
||||
/* Skip comment lines and empty lines. */
|
||||
if (*bp == '#' || *bp == 0)
|
||||
/*@innercontinue@*/ continue;
|
||||
/*@-formatcode@*/
|
||||
items = sscanf(buf, "%as %as %as", ®ex, &type, &context);
|
||||
/*@=formatcode@*/
|
||||
if (items < 2) {
|
||||
fprintf(stderr,
|
||||
_("%s: line number %d is missing fields (only read %s)\n"),
|
||||
fn, lineno, buf);
|
||||
inc_err();
|
||||
if (items == 1)
|
||||
free(regex);
|
||||
/*@innercontinue@*/ continue;
|
||||
} else if (items == 2) {
|
||||
/* The type field is optional. */
|
||||
free(context);
|
||||
context = type;
|
||||
type = 0;
|
||||
}
|
||||
|
||||
/* On pass 2, compile and store the specification. */
|
||||
if (pass == 1) {
|
||||
const char * reg_buf = regex;
|
||||
sxp->fstem = rpmsxAdd(sx, ®_buf);
|
||||
sxp->pattern = regex;
|
||||
|
||||
/* Anchor the regular expression. */
|
||||
len = strlen(reg_buf);
|
||||
anchored_regex = xmalloc(len + 3);
|
||||
sprintf(anchored_regex, "^%s$", reg_buf);
|
||||
|
||||
/* Compile the regular expression. */
|
||||
/*@i@*/ sxp->preg = xcalloc(1, sizeof(*sxp->preg));
|
||||
regerr = regcomp(sxp->preg, anchored_regex,
|
||||
REG_EXTENDED | REG_NOSUB);
|
||||
if (regerr < 0) {
|
||||
char errbuf[BUFSIZ + 1];
|
||||
(void) regerror(regerr, sxp->preg, errbuf, sizeof(errbuf)-1);
|
||||
errbuf[sizeof(errbuf)-1] = '\0';
|
||||
fprintf(stderr,
|
||||
_("%s: unable to compile regular expression %s on line number %d: %s\n"),
|
||||
fn, regex, lineno,
|
||||
errbuf);
|
||||
inc_err();
|
||||
}
|
||||
free(anchored_regex);
|
||||
|
||||
/* Convert the type string to a mode format */
|
||||
sxp->type = type;
|
||||
sxp->fmode = 0;
|
||||
if (!type)
|
||||
goto skip_type;
|
||||
len = strlen(type);
|
||||
if (type[0] != '-' || len != 2) {
|
||||
fprintf(stderr,
|
||||
_("%s: invalid type specifier %s on line number %d\n"),
|
||||
fn, type, lineno);
|
||||
inc_err();
|
||||
goto skip_type;
|
||||
}
|
||||
switch (type[1]) {
|
||||
case 'b': sxp->fmode = S_IFBLK; /*@switchbreak@*/ break;
|
||||
case 'c': sxp->fmode = S_IFCHR; /*@switchbreak@*/ break;
|
||||
case 'd': sxp->fmode = S_IFDIR; /*@switchbreak@*/ break;
|
||||
case 'p': sxp->fmode = S_IFIFO; /*@switchbreak@*/ break;
|
||||
case 'l': sxp->fmode = S_IFLNK; /*@switchbreak@*/ break;
|
||||
/*@i@*/ case 's': sxp->fmode = S_IFSOCK; /*@switchbreak@*/ break;
|
||||
case '-': sxp->fmode = S_IFREG; /*@switchbreak@*/ break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
_("%s: invalid type specifier %s on line number %d\n"),
|
||||
fn, type, lineno);
|
||||
inc_err();
|
||||
/*@switchbreak@*/ break;
|
||||
}
|
||||
|
||||
skip_type:
|
||||
|
||||
sxp->context = context;
|
||||
|
||||
if (strcmp(context, "<<none>>")) {
|
||||
if (security_check_context(context) < 0 && errno != ENOENT) {
|
||||
fprintf(stderr,
|
||||
_("%s: invalid context %s on line number %d\n"),
|
||||
fn, context, lineno);
|
||||
inc_err();
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if specification has
|
||||
* any meta characters in the RE */
|
||||
rpmsxpHasMetaChars(sxp);
|
||||
sxp++;
|
||||
}
|
||||
|
||||
sx->Count++;
|
||||
if (pass == 0) {
|
||||
/*@-kepttrans@*/
|
||||
free(regex);
|
||||
if (type)
|
||||
free(type);
|
||||
free(context);
|
||||
/*@=kepttrans@*/
|
||||
}
|
||||
}
|
||||
|
||||
if (nerr) {
|
||||
(void) fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pass == 0) {
|
||||
if (sx->Count == 0) {
|
||||
(void) fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
sx->sxp = xcalloc(sx->Count, sizeof(*sx->sxp));
|
||||
rewind(fp);
|
||||
}
|
||||
}
|
||||
/*@=branchstate@*/
|
||||
(void) fclose(fp);
|
||||
|
||||
/* Stable sort for policy specifications, patterns before paths. */
|
||||
rpmsxSort(sx);
|
||||
|
||||
/* Verify no exact duplicates */
|
||||
if (rpmsxpCheckNoDupes(sx) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
rpmsx rpmsxNew(const char * fn)
|
||||
{
|
||||
rpmsx sx;
|
||||
|
||||
sx = xcalloc(1, sizeof(*sx));
|
||||
sx->sxp = NULL;
|
||||
sx->Count = 0;
|
||||
sx->i = -1;
|
||||
sx->sxs = NULL;
|
||||
sx->nsxs = 0;
|
||||
sx->maxsxs = 0;
|
||||
sx->reverse = 0;
|
||||
|
||||
(void) rpmsxLink(sx, __func__);
|
||||
|
||||
if (rpmsxParse(sx, fn) != 0)
|
||||
return rpmsxFree(sx);
|
||||
|
||||
return sx;
|
||||
}
|
||||
|
||||
int rpmsxCount(const rpmsx sx)
|
||||
{
|
||||
return (sx != NULL ? sx->Count : 0);
|
||||
}
|
||||
|
||||
int rpmsxIx(const rpmsx sx)
|
||||
{
|
||||
return (sx != NULL ? sx->i : -1);
|
||||
}
|
||||
|
||||
int rpmsxSetIx(rpmsx sx, int ix)
|
||||
{
|
||||
int i = -1;
|
||||
|
||||
if (sx != NULL) {
|
||||
i = sx->i;
|
||||
sx->i = ix;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
const char * rpmsxPattern(const rpmsx sx)
|
||||
{
|
||||
const char * pattern = NULL;
|
||||
|
||||
if (sx != NULL && sx->i >= 0 && sx->i < sx->Count)
|
||||
pattern = (sx->sxp + sx->i)->pattern;
|
||||
return pattern;
|
||||
}
|
||||
|
||||
const char * rpmsxType(const rpmsx sx)
|
||||
{
|
||||
const char * type = NULL;
|
||||
|
||||
if (sx != NULL && sx->i >= 0 && sx->i < sx->Count)
|
||||
type = (sx->sxp + sx->i)->type;
|
||||
return type;
|
||||
}
|
||||
|
||||
const char * rpmsxContext(const rpmsx sx)
|
||||
{
|
||||
const char * context = NULL;
|
||||
|
||||
if (sx != NULL && sx->i >= 0 && sx->i < sx->Count)
|
||||
context = (sx->sxp + sx->i)->context;
|
||||
return context;
|
||||
}
|
||||
|
||||
regex_t * rpmsxRE(const rpmsx sx)
|
||||
{
|
||||
regex_t * preg = NULL;
|
||||
|
||||
if (sx != NULL && sx->i >= 0 && sx->i < sx->Count)
|
||||
preg = (sx->sxp + sx->i)->preg;
|
||||
return preg;
|
||||
}
|
||||
|
||||
mode_t rpmsxFMode(const rpmsx sx)
|
||||
{
|
||||
mode_t fmode = 0;
|
||||
|
||||
if (sx != NULL && sx->i >= 0 && sx->i < sx->Count)
|
||||
fmode = (sx->sxp + sx->i)->fmode;
|
||||
return fmode;
|
||||
}
|
||||
|
||||
int rpmsxFStem(const rpmsx sx)
|
||||
{
|
||||
int fstem = -1;
|
||||
|
||||
if (sx != NULL && sx->i >= 0 && sx->i < sx->Count)
|
||||
fstem = (sx->sxp + sx->i)->fstem;
|
||||
return fstem;
|
||||
}
|
||||
|
||||
int rpmsxNext(/*@null@*/ rpmsx sx)
|
||||
/*@modifies sx @*/
|
||||
{
|
||||
int i = -1;
|
||||
|
||||
if (sx != NULL) {
|
||||
if (sx->reverse != 0) {
|
||||
i = --sx->i;
|
||||
if (sx->i < 0) {
|
||||
sx->i = sx->Count;
|
||||
i = -1;
|
||||
}
|
||||
} else {
|
||||
i = ++sx->i;
|
||||
if (sx->i >= sx->Count) {
|
||||
sx->i = -1;
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*@-modfilesys @*/
|
||||
if (_rpmsx_debug < 0 && i != -1) {
|
||||
rpmsxp sxp = sx->sxp + i;
|
||||
fprintf(stderr, "*** sx %p\t%s[%d]\t%s\t%s\n", sx, __func__, i, sxp->pattern, sxp->context);
|
||||
/*@=modfilesys @*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
rpmsx rpmsxInit(/*@null@*/ rpmsx sx, int reverse)
|
||||
/*@modifies sx @*/
|
||||
{
|
||||
if (sx != NULL) {
|
||||
sx->reverse = reverse;
|
||||
sx->i = (sx->reverse ? sx->Count : -1);
|
||||
}
|
||||
/*@-refcounttrans@*/
|
||||
return sx;
|
||||
/*@=refcounttrans@*/
|
||||
}
|
||||
|
||||
const char * rpmsxFContext(rpmsx sx, const char * fn, mode_t fmode)
|
||||
{
|
||||
const char * fcontext = NULL;
|
||||
const char * myfn = fn;
|
||||
/*@-mods@*/
|
||||
int fstem = rpmsxFind(sx, &myfn);
|
||||
/*@=mods@*/
|
||||
int i;
|
||||
|
||||
sx = rpmsxInit(sx, 1);
|
||||
if (sx != NULL)
|
||||
while ((i = rpmsxNext(sx)) >= 0) {
|
||||
regex_t * preg;
|
||||
mode_t sxfmode;
|
||||
int sxfstem;
|
||||
int ret;
|
||||
|
||||
sxfstem = rpmsxFStem(sx);
|
||||
if (sxfstem != -1 && sxfstem != fstem)
|
||||
continue;
|
||||
|
||||
sxfmode = rpmsxFMode(sx);
|
||||
if (sxfmode && (fmode & S_IFMT) != sxfmode)
|
||||
continue;
|
||||
|
||||
preg = rpmsxRE(sx);
|
||||
if (preg == NULL)
|
||||
continue;
|
||||
|
||||
ret = regexec(preg, (sxfstem == -1 ? fn : myfn), 0, NULL, 0);
|
||||
switch (ret) {
|
||||
case REG_NOMATCH:
|
||||
continue;
|
||||
/*@notreached@*/ /*@switchbreak@*/ break;
|
||||
case 0:
|
||||
fcontext = rpmsxContext(sx);
|
||||
/*@switchbreak@*/ break;
|
||||
default:
|
||||
{ static char errbuf[BUFSIZ + 1];
|
||||
(void) regerror(ret, preg, errbuf, sizeof(errbuf)-1);
|
||||
/*@-modfilesys -nullpass @*/
|
||||
errbuf[sizeof(errbuf)-1] = '\0';
|
||||
fprintf(stderr, "unable to match %s against %s: %s\n",
|
||||
fn, rpmsxPattern(sx), errbuf);
|
||||
/*@=modfilesys =nullpass @*/
|
||||
} /*@switchbreak@*/ break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return fcontext;
|
||||
}
|
277
lib/rpmsx.h
277
lib/rpmsx.h
|
@ -1,277 +0,0 @@
|
|||
#ifndef H_RPMSX
|
||||
#define H_RPMSX
|
||||
|
||||
/** \ingroup rpmdep rpmtrans
|
||||
* \file lib/rpmsx.h
|
||||
* Structure(s) used for file security context pattern handling
|
||||
*/
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
/**
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
/*@unchecked@*/
|
||||
extern int _rpmsx_debug;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
/*@unchecked@*/
|
||||
extern int _rpmsx_nopromote;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
typedef /*@abstract@*/ /*@refcounted@*/ struct rpmsx_s * rpmsx;
|
||||
typedef struct rpmsxp_s * rpmsxp;
|
||||
typedef struct rpmsxs_s * rpmsxs;
|
||||
|
||||
#if defined(_RPMSX_INTERNAL)
|
||||
/**
|
||||
* File security context regex pattern.
|
||||
*/
|
||||
struct rpmsxp_s {
|
||||
/*@only@*/ /*@relnull@*/
|
||||
const char * pattern; /*!< File path regex pattern. */
|
||||
/*@only@*/ /*@relnull@*/
|
||||
const char * type; /*!< File type string. */
|
||||
/*@only@*/ /*@relnull@*/
|
||||
const char * context; /*!< Security context. */
|
||||
/*@only@*/ /*@relnull@*/
|
||||
regex_t * preg; /*!< Compiled regex. */
|
||||
mode_t fmode; /*!< File type. */
|
||||
int matches;
|
||||
int hasMetaChars;
|
||||
int fstem; /*!< Stem id. */
|
||||
};
|
||||
|
||||
/**
|
||||
* File/pattern stem.
|
||||
*/
|
||||
struct rpmsxs_s {
|
||||
/*@only@*/ /*@relnull@*/
|
||||
const char * stem;
|
||||
int len;
|
||||
};
|
||||
|
||||
/**
|
||||
* File security context patterns container.
|
||||
*/
|
||||
struct rpmsx_s {
|
||||
/*@only@*/ /*@relnull@*/
|
||||
rpmsxp sxp; /*!< File context patterns. */
|
||||
int Count; /*!< No. of file context patterns. */
|
||||
int i; /*!< Current pattern index. */
|
||||
/*@only@*/ /*@relnull@*/
|
||||
rpmsxs sxs; /*!< File stems. */
|
||||
int nsxs; /*!< No. of file stems. */
|
||||
int maxsxs; /*!< No. of allocated file stems. */
|
||||
int reverse; /*!< Reverse traversal? */
|
||||
/*@refs@*/
|
||||
int nrefs; /*!< Reference count. */
|
||||
};
|
||||
#endif /* defined(_RPMSX_INTERNAL) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Unreference a security context patterns instance.
|
||||
* @param sx security context patterns
|
||||
* @param msg
|
||||
* @return NULL always
|
||||
*/
|
||||
/*@unused@*/ /*@null@*/
|
||||
rpmsx rpmsxUnlink (/*@killref@*/ /*@only@*/ /*@null@*/ rpmsx sx,
|
||||
/*@null@*/ const char * msg)
|
||||
/*@modifies sx @*/;
|
||||
|
||||
/** @todo Remove debugging entry from the ABI. */
|
||||
/*@-exportlocal@*/
|
||||
/*@null@*/
|
||||
rpmsx XrpmsxUnlink (/*@killref@*/ /*@only@*/ /*@null@*/ rpmsx sx,
|
||||
/*@null@*/ const char * msg, const char * fn, unsigned ln)
|
||||
/*@modifies sx @*/;
|
||||
/*@=exportlocal@*/
|
||||
#define rpmsxUnlink(_sx, _msg) XrpmsxUnlink(_sx, _msg, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Reference a security context patterns instance.
|
||||
* @param sx security context patterns
|
||||
* @param msg
|
||||
* @return new security context patterns reference
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
/*@unused@*/ /*@newref@*/ /*@null@*/
|
||||
rpmsx rpmsxLink (/*@null@*/ rpmsx sx, /*@null@*/ const char * msg)
|
||||
/*@modifies sx @*/;
|
||||
|
||||
/** @todo Remove debugging entry from the ABI. */
|
||||
/*@newref@*/ /*@null@*/
|
||||
rpmsx XrpmsxLink (/*@null@*/ rpmsx sx, /*@null@*/ const char * msg,
|
||||
const char * fn, unsigned ln)
|
||||
/*@modifies sx @*/;
|
||||
/*@=exportlocal@*/
|
||||
#define rpmsxLink(_sx, _msg) XrpmsxLink(_sx, _msg, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Destroy a security context patterns.
|
||||
* @param sx security context patterns
|
||||
* @return NULL always
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
/*@null@*/
|
||||
rpmsx rpmsxFree(/*@killref@*/ /*@only@*/ /*@null@*/ rpmsx sx)
|
||||
/*@modifies sx@*/;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
* Parse selinux file security context patterns.
|
||||
* @param sx security context patterns
|
||||
* @param fn file name to parse
|
||||
* @return 0 on success
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
int rpmsxParse(rpmsx sx, /*@null@*/ const char *fn)
|
||||
/*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
|
||||
/*@modifies sx, rpmGlobalMacroContext, h_errno, fileSystem @*/;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
* Create and load security context patterns.
|
||||
* @param fn security context patterns file name
|
||||
* @return new security context patterns
|
||||
*/
|
||||
/*@null@*/
|
||||
rpmsx rpmsxNew(const char * fn)
|
||||
/*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
|
||||
/*@modifies rpmGlobalMacroContext, h_errno, fileSystem @*/;
|
||||
|
||||
/**
|
||||
* Return security context patterns count.
|
||||
* @param sx security context patterns
|
||||
* @return current count
|
||||
*/
|
||||
int rpmsxCount(/*@null@*/ const rpmsx sx)
|
||||
/*@*/;
|
||||
|
||||
/**
|
||||
* Return security context patterns index.
|
||||
* @param sx security context patterns
|
||||
* @return current index
|
||||
*/
|
||||
int rpmsxIx(/*@null@*/ const rpmsx sx)
|
||||
/*@*/;
|
||||
|
||||
/**
|
||||
* Set security context patterns index.
|
||||
* @param sx security context patterns
|
||||
* @param ix new index
|
||||
* @return current index
|
||||
*/
|
||||
int rpmsxSetIx(/*@null@*/ rpmsx sx, int ix)
|
||||
/*@modifies sx @*/;
|
||||
|
||||
/**
|
||||
* Return current pattern.
|
||||
* @param sx security context patterns
|
||||
* @return current pattern, NULL on invalid
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
/*@observer@*/ /*@null@*/
|
||||
extern const char * rpmsxPattern(/*@null@*/ const rpmsx sx)
|
||||
/*@*/;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
* Return current type.
|
||||
* @param sx security context patterns
|
||||
* @return current type, NULL on invalid/missing
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
/*@observer@*/ /*@null@*/
|
||||
extern const char * rpmsxType(/*@null@*/ const rpmsx sx)
|
||||
/*@*/;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
* Return current context.
|
||||
* @param sx security context patterns
|
||||
* @return current context, NULL on invalid
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
/*@observer@*/ /*@null@*/
|
||||
extern const char * rpmsxContext(/*@null@*/ const rpmsx sx)
|
||||
/*@*/;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
* Return current regex.
|
||||
* @param sx security context patterns
|
||||
* @return current context, NULL on invalid
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
/*@observer@*/ /*@null@*/
|
||||
extern regex_t * rpmsxRE(/*@null@*/ const rpmsx sx)
|
||||
/*@*/;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
* Return current file mode.
|
||||
* @param sx security context patterns
|
||||
* @return current file mode, 0 on invalid
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
extern mode_t rpmsxFMode(/*@null@*/ const rpmsx sx)
|
||||
/*@*/;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
* Return current file stem.
|
||||
* @param sx security context patterns
|
||||
* @return current file stem, -1 on invalid
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
extern int rpmsxFStem(/*@null@*/ const rpmsx sx)
|
||||
/*@*/;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
* Return next security context patterns iterator index.
|
||||
* @param sx security context patterns
|
||||
* @return security context patterns iterator index, -1 on termination
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
int rpmsxNext(/*@null@*/ rpmsx sx)
|
||||
/*@modifies sx @*/;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
* Initialize security context patterns iterator.
|
||||
* @param sx security context patterns
|
||||
* @param reverse iterate in reverse order?
|
||||
* @return security context patterns
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
/*@null@*/
|
||||
rpmsx rpmsxInit(/*@null@*/ rpmsx sx, int reverse)
|
||||
/*@modifies sx @*/;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
* Find file security context from path and type.
|
||||
* @param sx security context patterns
|
||||
* @param fn file path
|
||||
* @param fmode file mode
|
||||
* @return file security context
|
||||
*/
|
||||
/*@owned@*/ /*@null@*/
|
||||
const char * rpmsxFContext(/*@null@*/ rpmsx sx, const char * fn, mode_t fmode)
|
||||
/*@modifies sx @*/;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_RPMSX */
|
20
lib/rpmts.c
20
lib/rpmts.c
|
@ -55,7 +55,6 @@ extern int statvfs (const char * file, /*@out@*/ struct statvfs * buf)
|
|||
|
||||
/*@access rpmps @*/
|
||||
/*@access rpmDiskSpaceInfo @*/
|
||||
/*@access rpmsx @*/
|
||||
/*@access rpmte @*/
|
||||
/*@access rpmtsi @*/
|
||||
/*@access fnpyKey @*/
|
||||
|
@ -863,8 +862,6 @@ rpmts rpmtsFree(rpmts ts)
|
|||
|
||||
(void) rpmtsCloseSDB(ts);
|
||||
|
||||
ts->sx = rpmsxFree(ts->sx);
|
||||
|
||||
ts->removedPackages = _free(ts->removedPackages);
|
||||
|
||||
ts->availablePackages = rpmalFree(ts->availablePackages);
|
||||
|
@ -1084,23 +1081,6 @@ int rpmtsSetChrootDone(rpmts ts, int chrootDone)
|
|||
return ochrootDone;
|
||||
}
|
||||
|
||||
rpmsx rpmtsREContext(rpmts ts)
|
||||
{
|
||||
return ( (ts && ts->sx ? rpmsxLink(ts->sx, __func__) : NULL) );
|
||||
}
|
||||
|
||||
int rpmtsSetREContext(rpmts ts, rpmsx sx)
|
||||
{
|
||||
int rc = -1;
|
||||
if (ts != NULL) {
|
||||
ts->sx = rpmsxFree(ts->sx);
|
||||
ts->sx = rpmsxLink(sx, __func__);
|
||||
if (ts->sx != NULL)
|
||||
rc = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int_32 rpmtsGetTid(rpmts ts)
|
||||
{
|
||||
int_32 tid = 0;
|
||||
|
|
22
lib/rpmts.h
22
lib/rpmts.h
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "rpmps.h"
|
||||
#include "rpmsw.h"
|
||||
#include "rpmsx.h"
|
||||
|
||||
/*@-exportlocal@*/
|
||||
/*@unchecked@*/
|
||||
|
@ -283,9 +282,6 @@ struct rpmts_s {
|
|||
int numAvailablePackages; /*!< No. available package instances. */
|
||||
#endif
|
||||
|
||||
/*@refcounted@*/ /*@null@*/
|
||||
rpmsx sx; /*!< Security context patterns. */
|
||||
|
||||
/*@null@*/
|
||||
rpmte relocateElement; /*!< Element to use when relocating packages. */
|
||||
|
||||
|
@ -731,24 +727,6 @@ int rpmtsChrootDone(rpmts ts)
|
|||
int rpmtsSetChrootDone(rpmts ts, int chrootDone)
|
||||
/*@modifies ts @*/;
|
||||
|
||||
/** \ingroup rpmts
|
||||
* Get file security context patterns.
|
||||
* @param ts transaction set
|
||||
* @return file security context patterns
|
||||
*/
|
||||
/*@null@*/
|
||||
rpmsx rpmtsREContext(const rpmts ts)
|
||||
/*@modifies ts @*/;
|
||||
|
||||
/** \ingroup rpmts
|
||||
* Get file security context patterns.
|
||||
* @param ts transaction set
|
||||
* @param sx security context patterns
|
||||
* @return 0 on success
|
||||
*/
|
||||
int rpmtsSetREContext(rpmts ts, rpmsx sx)
|
||||
/*@modifies ts, sx @*/;
|
||||
|
||||
/** \ingroup rpmts
|
||||
* Get transaction id, i.e. transaction time stamp.
|
||||
* @param ts transaction set
|
||||
|
|
142
lib/tre.c
142
lib/tre.c
|
@ -1,142 +0,0 @@
|
|||
#include "system.h"
|
||||
|
||||
#define _RPMSX_INTERNAL
|
||||
#include <rpmsx.h>
|
||||
#include <popt.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
static int add_assoc = 1;
|
||||
|
||||
/*
|
||||
* Command-line options.
|
||||
*/
|
||||
static int change = 1;
|
||||
static int quiet = 0;
|
||||
#define QPRINTF(args...) do { if (!quiet) printf(args); } while (0)
|
||||
static int use_stdin = 0;
|
||||
static int verbose = 0;
|
||||
static int warn_no_match = 0;
|
||||
static char *rootpath = NULL;
|
||||
static int rootpathlen = 0;
|
||||
|
||||
static struct poptOption optionsTable[] = {
|
||||
{ "debug", 'd', POPT_ARG_VAL, &_rpmsx_debug, -1,
|
||||
N_("show what specification matched each file"), NULL },
|
||||
{ "nochange", 'n', POPT_ARG_VAL, &change, 0,
|
||||
N_("do not change any file labels"), NULL },
|
||||
{ "quiet", 'q', POPT_ARG_VAL, &quiet, 1,
|
||||
N_("be quiet (suppress non-error output)"), NULL },
|
||||
{ "root", 'r', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &rootpath, 0,
|
||||
N_("use an alternate root path"), N_("ROOT") },
|
||||
{ "stdin", 's', POPT_ARG_VAL, &use_stdin, 1,
|
||||
N_("use stdin for a list of files instead of searching a partition"), NULL },
|
||||
{ "verbose", 'v', POPT_ARG_VAL, &warn_no_match, 1,
|
||||
N_("show changes in file labels"), NULL },
|
||||
{ "warn", 'W', POPT_ARG_VAL, &warn_no_match, 1,
|
||||
N_("warn about entries that have no matching file"), NULL },
|
||||
|
||||
POPT_AUTOHELP
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
poptContext optCon;
|
||||
const char ** av;
|
||||
const char * arg;
|
||||
rpmsx sx;
|
||||
int ec = EXIT_FAILURE; /* assume failure. */
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
#if HAVE_MCHECK_H && HAVE_MTRACE
|
||||
/*@-noeffect@*/
|
||||
mtrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
|
||||
/*@=noeffect@*/
|
||||
#endif
|
||||
|
||||
setprogname(argv[0]); /* Retrofit glibc __progname */
|
||||
/* XXX glibc churn sanity */
|
||||
if (__progname == NULL) {
|
||||
if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
|
||||
else __progname = argv[0];
|
||||
}
|
||||
|
||||
(void) setlocale(LC_ALL, "" );
|
||||
(void) bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
(void) textdomain(PACKAGE);
|
||||
|
||||
optCon = poptGetContext(__progname, argc, (const char **)argv, optionsTable, 0);
|
||||
|
||||
/* Process all options, whine if unknown. */
|
||||
while ((rc = poptGetNextOpt(optCon)) > 0) {
|
||||
switch (rc) {
|
||||
default:
|
||||
/*@-nullpass@*/
|
||||
fprintf(stderr, _("%s: option table misconfigured (%d)\n"),
|
||||
__progname, rc);
|
||||
/*@=nullpass@*/
|
||||
goto exit;
|
||||
/*@notreached@*/ /*@switchbreak@*/ break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc < -1) {
|
||||
/*@-nullpass@*/
|
||||
fprintf(stderr, "%s: %s: %s\n", __progname,
|
||||
poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
|
||||
poptStrerror(rc));
|
||||
/*@=nullpass@*/
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* trim trailing /, if present */
|
||||
if (rootpath != NULL) {
|
||||
rootpathlen = strlen(rootpath);
|
||||
while (rootpath[rootpathlen - 1] == '/')
|
||||
rootpath[--rootpathlen] = 0;
|
||||
}
|
||||
|
||||
av = poptGetArgs(optCon);
|
||||
|
||||
/* Parse the specification file. */
|
||||
sx = rpmsxNew(NULL);
|
||||
|
||||
if (_rpmsx_debug) {
|
||||
sx = rpmsxInit(sx, 1);
|
||||
if (sx != NULL)
|
||||
while ((i = rpmsxNext(sx)) >= 0) {
|
||||
const char * pattern = rpmsxPattern(sx);
|
||||
const char * type = rpmsxType(sx);
|
||||
const char * context = rpmsxContext(sx);
|
||||
|
||||
fprintf(stderr, "%5d: %s\t%s\t%s\n", i,
|
||||
pattern, (type ? type : ""), context);
|
||||
}
|
||||
}
|
||||
|
||||
if (av != NULL)
|
||||
while ((arg = *av++) != NULL) {
|
||||
const char * context = rpmsxFContext(sx, arg, S_IFREG);
|
||||
fprintf(stderr, "%s: %s\n", arg, context);
|
||||
}
|
||||
|
||||
sx = rpmsxFree(sx);
|
||||
|
||||
/*
|
||||
* Apply the specifications to the file systems.
|
||||
*/
|
||||
ec = 0;
|
||||
|
||||
exit:
|
||||
optCon = poptFreeContext(optCon);
|
||||
|
||||
#if HAVE_MCHECK_H && HAVE_MTRACE
|
||||
/*@-noeffect@*/
|
||||
muntrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
|
||||
/*@=noeffect@*/
|
||||
#endif
|
||||
|
||||
return ec;
|
||||
}
|
Loading…
Reference in New Issue