diff options
author | jbj <devnull@localhost> | 2003-04-08 21:42:55 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2003-04-08 21:42:55 +0000 |
commit | 783219a8325bca538d21c367f9c523a79dbcb011 (patch) | |
tree | 4ae43dc0fa37c05931ff370a09f05fcfb14a1e21 | |
parent | f60ec855de0d6bfd29325fcb73b2901780e72e3d (diff) | |
download | librpm-tizen-783219a8325bca538d21c367f9c523a79dbcb011.tar.gz librpm-tizen-783219a8325bca538d21c367f9c523a79dbcb011.tar.bz2 librpm-tizen-783219a8325bca538d21c367f9c523a79dbcb011.zip |
fix: prevent segfault if malicious server sends 1 GB of data through ftpNLST.
fix: rpmal could segfault under obscure conditions.
Use array, not individual structures, for rpmsw{Enter,Exit} timestamps.
CVS patchset: 6735
CVS date: 2003/04/08 21:42:55
-rw-r--r-- | lib/depends.c | 12 | ||||
-rw-r--r-- | lib/fsm.c | 17 | ||||
-rw-r--r-- | lib/package.c | 9 | ||||
-rw-r--r-- | lib/psm.c | 30 | ||||
-rw-r--r-- | lib/rpmal.c | 2 | ||||
-rw-r--r-- | lib/rpmte.c | 2 | ||||
-rw-r--r-- | lib/rpmts.c | 85 | ||||
-rw-r--r-- | lib/rpmts.h | 80 | ||||
-rw-r--r-- | lib/signature.c | 32 | ||||
-rw-r--r-- | lib/transaction.c | 20 | ||||
-rw-r--r-- | rpmdb/rpmdb.c | 6 | ||||
-rw-r--r-- | rpmdb/rpmdb.h | 20 | ||||
-rw-r--r-- | rpmio/rpmio_internal.h | 41 | ||||
-rw-r--r-- | rpmio/rpmrpc.c | 1 | ||||
-rw-r--r-- | rpmio/rpmsw.c | 18 | ||||
-rw-r--r-- | rpmio/rpmsw.h | 6 |
16 files changed, 216 insertions, 165 deletions
diff --git a/lib/depends.c b/lib/depends.c index 9fdbfa79f..ea0be77b7 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -1002,8 +1002,8 @@ static inline int addRelation(rpmts ts, /*@dependent@*/ rpmte p, unsigned char * selected, rpmds requires) - /*@globals fileSystem @*/ - /*@modifies ts, p, *selected, fileSystem @*/ + /*@globals fileSystem, internalState @*/ + /*@modifies ts, p, *selected, fileSystem, internalState @*/ { rpmtsi qi; rpmte q; tsortInfo tsi; @@ -1179,7 +1179,7 @@ int rpmtsOrder(rpmts ts) rpmalMakeIndex(ts->addedPackages); #endif - (void) rpmswEnter(&ts->op_order, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_ORDER), 0); /* T1. Initialize. */ if (oType == 0) @@ -1582,7 +1582,7 @@ assert(newOrderCount == ts->orderCount); #endif freeBadDeps(); - (void) rpmswExit(&ts->op_order, 0); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_ORDER), 0); return 0; } @@ -1597,7 +1597,7 @@ int rpmtsCheck(rpmts ts) int xx; int rc; - (void) rpmswEnter(&ts->op_check, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_CHECK), 0); /* Do lazy, readonly, open of rpm database. */ if (rpmtsGetRdb(ts) == NULL && ts->dbmode != -1) { @@ -1724,7 +1724,7 @@ exit: mi = rpmdbFreeIterator(mi); pi = rpmtsiFree(pi); - rpmswExit(&ts->op_check, 0); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_CHECK), 0); /*@-branchstate@*/ if (closeatexit) @@ -18,7 +18,6 @@ #define _RPMFI_INTERNAL #include "rpmfi.h" #include "rpmte.h" -#define _RPMTS_INTERNAL #include "rpmts.h" #include "rpmsq.h" @@ -115,7 +114,9 @@ static /*@null@*/ void * mapFreeIterator(/*@only@*//*@null@*/ void * p) { FSMI_t iter = p; if (iter) { +/*@-internalglobs@*/ /* XXX rpmswExit() */ iter->ts = rpmtsFree(iter->ts); +/*@=internalglobs@*/ iter->fi = rpmfiUnlink(iter->fi, "mapIterator"); } return _free(p); @@ -2303,11 +2304,8 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break; if (fsm->rfd != NULL) { if (_fsm_debug && (stage & FSM_SYSCALL)) rpmMessage(RPMMESS_DEBUG, " %8s (%p)\n", cur, fsm->rfd); - if (fsm->rfd->stats != NULL) { - FDSTAT_t stats = fsm->rfd->stats; - rpmts ts = fsmGetTs(fsm); - (void) rpmswAdd(&ts->op_digest, &stats->ops[FDSTAT_DIGEST]); - } + (void) rpmswAdd(rpmtsOp(fsmGetTs(fsm), RPMTS_OP_DIGEST), + fdstat_op(fsm->rfd, FDSTAT_DIGEST)); (void) Fclose(fsm->rfd); errno = saveerrno; } @@ -2336,11 +2334,8 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break; if (fsm->wfd != NULL) { if (_fsm_debug && (stage & FSM_SYSCALL)) rpmMessage(RPMMESS_DEBUG, " %8s (%p)\n", cur, fsm->wfd); - if (fsm->wfd->stats != NULL) { - FDSTAT_t stats = fsm->wfd->stats; - rpmts ts = fsmGetTs(fsm); - (void) rpmswAdd(&ts->op_digest, &stats->ops[FDSTAT_DIGEST]); - } + (void) rpmswAdd(rpmtsOp(fsmGetTs(fsm), RPMTS_OP_DIGEST), + fdstat_op(fsm->wfd, FDSTAT_DIGEST)); (void) Fclose(fsm->wfd); errno = saveerrno; } diff --git a/lib/package.c b/lib/package.c index 5871629ae..e2da6adb2 100644 --- a/lib/package.c +++ b/lib/package.c @@ -9,7 +9,6 @@ #include <rpmio_internal.h> #include <rpmlib.h> -#define _RPMTS_INTERNAL #include "rpmts.h" #include "misc.h" /* XXX stripTrailingChar() */ @@ -543,7 +542,7 @@ verifyinfo_exit: ildl[1] = (regionEnd - dataStart); ildl[1] = htonl(ildl[1]); - (void) rpmswEnter(&ts->op_digest, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0); dig->hdrmd5ctx = rpmDigestInit(PGPHASHALGO_MD5, RPMDIGEST_NONE); b = (unsigned char *) header_magic; @@ -565,7 +564,7 @@ verifyinfo_exit: nb = htonl(ildl[1]); (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb); dig->nbytes += nb; - (void) rpmswExit(&ts->op_digest, dig->nbytes); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes); break; #endif @@ -588,7 +587,7 @@ verifyinfo_exit: ildl[1] = htonl(ildl[1]); /*@=boundswrite@*/ - (void) rpmswEnter(&ts->op_digest, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0); dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE); b = (unsigned char *) header_magic; @@ -610,7 +609,7 @@ verifyinfo_exit: nb = htonl(ildl[1]); (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb); dig->nbytes += nb; - (void) rpmswExit(&ts->op_digest, dig->nbytes); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes); break; default: @@ -474,7 +474,7 @@ static pid_t psmWait(rpmpsm psm) (void) rpmsqWait(&psm->sq); msecs = psm->sq.op.usecs/1000; - (void) rpmswAdd(&ts->op_scriptlets, &psm->sq.op); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_SCRIPTLETS), &psm->sq.op); rpmMessage(RPMMESS_DEBUG, _("%s: waitpid(%d) rc %d status %x secs %u.%03u\n"), @@ -1112,7 +1112,9 @@ rpmpsm rpmpsmFree(rpmpsm psm) #else psm->te = NULL; #endif +/*@-internalglobs@*/ psm->ts = rpmtsFree(psm->ts); +/*@=internalglobs@*/ (void) rpmpsmUnlink(psm, msg); @@ -1517,11 +1519,10 @@ psm->te->h = headerLink(fi->h); rc = fsmSetup(fi->fsm, FSM_PKGINSTALL, ts, fi, psm->cfd, NULL, &psm->failedFile); - if (psm->cfd->stats != NULL) { - FDSTAT_t stats = psm->cfd->stats; - (void) rpmswAdd(&ts->op_uncompress, &stats->ops[FDSTAT_READ]); - (void) rpmswAdd(&ts->op_digest, &stats->ops[FDSTAT_DIGEST]); - } + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_UNCOMPRESS), + fdstat_op(psm->cfd, FDSTAT_READ)); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST), + fdstat_op(psm->cfd, FDSTAT_DIGEST)); xx = fsmTeardown(fi->fsm); saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */ @@ -1601,11 +1602,10 @@ psm->te->h = headerLink(fi->h); rc = fsmSetup(fi->fsm, FSM_PKGBUILD, ts, fi, psm->cfd, NULL, &psm->failedFile); - if (psm->cfd->stats != NULL) { - FDSTAT_t stats = psm->cfd->stats; - (void) rpmswAdd(&ts->op_uncompress, &stats->ops[FDSTAT_WRITE]); - (void) rpmswAdd(&ts->op_digest, &stats->ops[FDSTAT_DIGEST]); - } + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_COMPRESS), + fdstat_op(psm->cfd, FDSTAT_WRITE)); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST), + fdstat_op(psm->cfd, FDSTAT_DIGEST)); xx = fsmTeardown(fi->fsm); saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */ @@ -1885,21 +1885,21 @@ assert(psm->mi == NULL); case PSM_RPMDB_ADD: if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break; if (fi->h == NULL) break; /* XXX can't happen */ - (void) rpmswEnter(&ts->op_dbadd, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBADD), 0); if (!(rpmtsVSFlags(ts) & RPMVSF_NOHDRCHK)) rc = rpmdbAdd(rpmtsGetRdb(ts), rpmtsGetTid(ts), fi->h, ts, headerCheck); else rc = rpmdbAdd(rpmtsGetRdb(ts), rpmtsGetTid(ts), fi->h, NULL, NULL); - (void) rpmswExit(&ts->op_dbadd, 0); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBADD), 0); break; case PSM_RPMDB_REMOVE: if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break; - (void) rpmswEnter(&ts->op_dbremove, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0); rc = rpmdbRemove(rpmtsGetRdb(ts), rpmtsGetTid(ts), fi->record, NULL, NULL); - (void) rpmswExit(&ts->op_dbremove, 0); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0); break; default: diff --git a/lib/rpmal.c b/lib/rpmal.c index bf0c168e9..b6cdea3f6 100644 --- a/lib/rpmal.c +++ b/lib/rpmal.c @@ -752,7 +752,7 @@ rpmalAllSatisfiesDepend(const rpmal al, const rpmds ds, alKey * keyp) if (al->list != NULL) /* XXX always true */ for (ret = NULL, found = 0; - match <= ai->index + ai->size && indexcmp(match, needle) == 0; + match < ai->index + ai->size && indexcmp(match, needle) == 0; match++) { alp = al->list + alKey2Num(al, match->pkgKey); diff --git a/lib/rpmte.c b/lib/rpmte.c index e1e882f6d..de3ce5cdc 100644 --- a/lib/rpmte.c +++ b/lib/rpmte.c @@ -543,8 +543,10 @@ rpmtsi XrpmtsiFree(/*@only@*//*@null@*/ rpmtsi tsi, const char * fn, unsigned int ln) { /* XXX watchout: a funky recursion segfaults here iff nrefs is wrong. */ +/*@-internalglobs@*/ if (tsi) tsi->ts = rpmtsFree(tsi->ts); +/*@=internalglobs@*/ /*@-modfilesys@*/ if (_rpmte_debug) diff --git a/lib/rpmts.c b/lib/rpmts.c index c56609ffa..0b9eec822 100644 --- a/lib/rpmts.c +++ b/lib/rpmts.c @@ -133,9 +133,9 @@ int rpmtsCloseDB(rpmts ts) int rc = 0; if (ts->rdb != NULL) { - (void) rpmswAdd(&ts->op_dbget, &ts->rdb->db_getops); - (void) rpmswAdd(&ts->op_dbput, &ts->rdb->db_putops); - (void) rpmswAdd(&ts->op_dbdel, &ts->rdb->db_delops); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBGET), &ts->rdb->db_getops); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBPUT), &ts->rdb->db_putops); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBDEL), &ts->rdb->db_delops); rc = rpmdbClose(ts->rdb); ts->rdb = NULL; } @@ -316,9 +316,9 @@ int rpmtsCloseSDB(rpmts ts) int rc = 0; if (ts->sdb != NULL) { - (void) rpmswAdd(&ts->op_dbget, &ts->sdb->db_getops); - (void) rpmswAdd(&ts->op_dbput, &ts->sdb->db_putops); - (void) rpmswAdd(&ts->op_dbdel, &ts->sdb->db_delops); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBGET), &ts->sdb->db_getops); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBPUT), &ts->sdb->db_putops); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBDEL), &ts->sdb->db_delops); rc = rpmdbClose(ts->sdb); ts->sdb = NULL; } @@ -636,42 +636,41 @@ void rpmtsEmpty(rpmts ts) /*@=nullstate@*/ } -static void rpmtsPrintStat(const char * name, struct rpmop_s * op) +static void rpmtsPrintStat(const char * name, /*@null@*/ struct rpmop_s * op) /*@globals fileSystem @*/ /*@modifies fileSystem @*/ { - static unsigned uscale = (1000 * 1000); - static unsigned mscale = (1024 * 1024); - if (op->count > 0) + static unsigned int scale = (1000 * 1000); + if (op != NULL && op->count > 0) fprintf(stderr, " %s %6d %6lu.%06lu MB %6lu.%06lu secs\n", name, op->count, - (unsigned long)op->bytes/mscale, (unsigned long)op->bytes%mscale, - op->usecs/uscale, op->usecs%uscale); + (unsigned long)op->bytes/scale, (unsigned long)op->bytes%scale, + op->usecs/scale, op->usecs%scale); } static void rpmtsPrintStats(rpmts ts) - /*@globals fileSystem @*/ - /*@modifies fileSystem @*/ -{ - (void) rpmswExit(&ts->op_total, 0); - - rpmtsPrintStat("total: ", &ts->op_total); - rpmtsPrintStat("check: ", &ts->op_check); - rpmtsPrintStat("order: ", &ts->op_order); - rpmtsPrintStat("fingerprint: ", &ts->op_fingerprint); - rpmtsPrintStat("repackage: ", &ts->op_repackage); - rpmtsPrintStat("install: ", &ts->op_install); - rpmtsPrintStat("erase: ", &ts->op_erase); - rpmtsPrintStat("scriptlets: ", &ts->op_scriptlets); - rpmtsPrintStat("compress: ", &ts->op_compress); - rpmtsPrintStat("uncompress: ", &ts->op_uncompress); - rpmtsPrintStat("digest: ", &ts->op_digest); - rpmtsPrintStat("signature: ", &ts->op_signature); - rpmtsPrintStat("dbadd: ", &ts->op_dbadd); - rpmtsPrintStat("dbremove: ", &ts->op_dbremove); - rpmtsPrintStat("dbget: ", &ts->op_dbget); - rpmtsPrintStat("dbput: ", &ts->op_dbput); - rpmtsPrintStat("dbdel: ", &ts->op_dbdel); + /*@globals fileSystem, internalState @*/ + /*@modifies fileSystem, internalState @*/ +{ + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_TOTAL), 0); + + rpmtsPrintStat("total: ", rpmtsOp(ts, RPMTS_OP_TOTAL)); + rpmtsPrintStat("check: ", rpmtsOp(ts, RPMTS_OP_CHECK)); + rpmtsPrintStat("order: ", rpmtsOp(ts, RPMTS_OP_ORDER)); + rpmtsPrintStat("fingerprint: ", rpmtsOp(ts, RPMTS_OP_FINGERPRINT)); + rpmtsPrintStat("repackage: ", rpmtsOp(ts, RPMTS_OP_REPACKAGE)); + rpmtsPrintStat("install: ", rpmtsOp(ts, RPMTS_OP_INSTALL)); + rpmtsPrintStat("erase: ", rpmtsOp(ts, RPMTS_OP_ERASE)); + rpmtsPrintStat("scriptlets: ", rpmtsOp(ts, RPMTS_OP_SCRIPTLETS)); + rpmtsPrintStat("compress: ", rpmtsOp(ts, RPMTS_OP_COMPRESS)); + rpmtsPrintStat("uncompress: ", rpmtsOp(ts, RPMTS_OP_UNCOMPRESS)); + rpmtsPrintStat("digest: ", rpmtsOp(ts, RPMTS_OP_DIGEST)); + rpmtsPrintStat("signature: ", rpmtsOp(ts, RPMTS_OP_SIGNATURE)); + rpmtsPrintStat("dbadd: ", rpmtsOp(ts, RPMTS_OP_DBADD)); + rpmtsPrintStat("dbremove: ", rpmtsOp(ts, RPMTS_OP_DBREMOVE)); + rpmtsPrintStat("dbget: ", rpmtsOp(ts, RPMTS_OP_DBGET)); + rpmtsPrintStat("dbput: ", rpmtsOp(ts, RPMTS_OP_DBPUT)); + rpmtsPrintStat("dbdel: ", rpmtsOp(ts, RPMTS_OP_DBDEL)); } rpmts rpmtsFree(rpmts ts) @@ -714,11 +713,11 @@ rpmts rpmtsFree(rpmts ts) ts->pkpktlen = 0; memset(ts->pksignid, 0, sizeof(ts->pksignid)); - (void) rpmtsUnlink(ts, "tsCreate"); - if (_rpmts_stats) rpmtsPrintStats(ts); + (void) rpmtsUnlink(ts, "tsCreate"); + /*@-refcounttrans -usereleased @*/ ts = _free(ts); /*@=refcounttrans =usereleased @*/ @@ -1227,6 +1226,17 @@ uint_32 rpmtsSetColor(rpmts ts, uint_32 color) return ocolor; } +rpmop rpmtsOp(rpmts ts, rpmtsOpX opx) +{ + rpmop op = NULL; + + if (ts != NULL && opx >= 0 && opx < RPMTS_OP_MAX) + op = ts->ops + opx; +/*@-usereleased -compdef @*/ + return op; +/*@=usereleased =compdef @*/ +} + int rpmtsSetNotifyCallback(rpmts ts, rpmCallbackFunction notify, rpmCallbackData notifyData) { @@ -1272,7 +1282,8 @@ rpmts rpmtsCreate(void) rpmts ts; ts = xcalloc(1, sizeof(*ts)); - (void) rpmswEnter(&ts->op_total, -1); + memset(&ts->ops, 0, sizeof(ts->ops)); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_TOTAL), -1); ts->goal = TSM_UNKNOWN; ts->filesystemCount = 0; ts->filesystems = NULL; diff --git a/lib/rpmts.h b/lib/rpmts.h index 95ba0b8e2..c00609d57 100644 --- a/lib/rpmts.h +++ b/lib/rpmts.h @@ -62,6 +62,30 @@ typedef enum rpmVSFlags_e { RPMVSF_NODSA | \ RPMVSF_NORSA ) +/** + * Indices for timestamps. + */ +typedef enum rpmtsOpX_e { + RPMTS_OP_TOTAL = 0, + RPMTS_OP_CHECK = 1, + RPMTS_OP_ORDER = 2, + RPMTS_OP_FINGERPRINT = 3, + RPMTS_OP_REPACKAGE = 4, + RPMTS_OP_INSTALL = 5, + RPMTS_OP_ERASE = 6, + RPMTS_OP_SCRIPTLETS = 7, + RPMTS_OP_COMPRESS = 8, + RPMTS_OP_UNCOMPRESS = 9, + RPMTS_OP_DIGEST = 10, + RPMTS_OP_SIGNATURE = 11, + RPMTS_OP_DBADD = 12, + RPMTS_OP_DBREMOVE = 13, + RPMTS_OP_DBGET = 14, + RPMTS_OP_DBPUT = 15, + RPMTS_OP_DBDEL = 16, + RPMTS_OP_MAX = 17 +} rpmtsOpX; + #if defined(_RPMTS_INTERNAL) #include "rpmhash.h" /* XXX hashTable */ @@ -196,23 +220,7 @@ struct rpmts_s { size_t pkpktlen; /*!< Current pubkey packet length. */ unsigned char pksignid[8]; /*!< Current pubkey fingerprint. */ - struct rpmop_s op_total; - struct rpmop_s op_check; - struct rpmop_s op_order; - struct rpmop_s op_fingerprint; - struct rpmop_s op_repackage; - struct rpmop_s op_install; - struct rpmop_s op_erase; - struct rpmop_s op_scriptlets; - struct rpmop_s op_compress; - struct rpmop_s op_uncompress; - struct rpmop_s op_digest; - struct rpmop_s op_signature; - struct rpmop_s op_dbadd; - struct rpmop_s op_dbremove; - struct rpmop_s op_dbget; - struct rpmop_s op_dbput; - struct rpmop_s op_dbdel; + struct rpmop_s ops[RPMTS_OP_MAX]; /*@null@*/ pgpDig dig; /*!< Current signature/pubkey parameters. */ @@ -461,16 +469,16 @@ void rpmtsCleanDig(rpmts ts) * @param ts transaction set */ void rpmtsClean(rpmts ts) - /*@globals fileSystem @*/ - /*@modifies ts, fileSystem @*/; + /*@globals fileSystem, internalState @*/ + /*@modifies ts, fileSystem , internalState@*/; /** \ingroup rpmts * Re-create an empty transaction set. * @param ts transaction set */ void rpmtsEmpty(rpmts ts) - /*@globals fileSystem @*/ - /*@modifies ts, fileSystem @*/; + /*@globals fileSystem, internalState @*/ + /*@modifies ts, fileSystem, internalState @*/; /** \ingroup rpmts * Destroy transaction set, closing the database as well. @@ -479,8 +487,8 @@ void rpmtsEmpty(rpmts ts) */ /*@null@*/ rpmts rpmtsFree(/*@killref@*/ /*@only@*//*@null@*/ rpmts ts) - /*@globals fileSystem @*/ - /*@modifies ts, fileSystem @*/; + /*@globals fileSystem, internalState @*/ + /*@modifies ts, fileSystem, internalState @*/; /** \ingroup rpmts * Get verify signatures flag(s). @@ -792,6 +800,16 @@ Spec rpmtsSetSpec(rpmts ts, /*@null@*/ Spec spec) rpmte rpmtsRelocateElement(rpmts ts) /*@*/; +/** \ingroup rpmts + * Set current relocate transaction element. + * @param ts transaction set + * @param relocateElement new relocate transaction element + * @return previous relocate transaction element + */ +/*@null@*/ +rpmte rpmtsSetRelocateElement(rpmts ts, /*@null@*/ rpmte relocateElement) + /*@modifies ts @*/; + /** * Retrieve color bits of transaction set. * @param ts transaction set @@ -809,15 +827,15 @@ uint_32 rpmtsColor(rpmts ts) uint_32 rpmtsSetColor(rpmts ts, uint_32 color) /*@modifies ts @*/; -/** \ingroup rpmts - * Set current relocate transaction element. +/** + * Retrieve operation timestamp from a transaction set. * @param ts transaction set - * @param relocateElement new relocate transaction element - * @return previous relocate transaction element + * @param opx operation timestamp index + * @return pointer to operation timestamp. */ /*@null@*/ -rpmte rpmtsSetRelocateElement(rpmts ts, /*@null@*/ rpmte relocateElement) - /*@modifies ts @*/; +rpmop rpmtsOp(rpmts ts, rpmtsOpX opx) + /*@*/; /** \ingroup rpmts * Set transaction notify callback function and argument. @@ -888,8 +906,8 @@ int rpmtsAddEraseElement(rpmts ts, Header h, int dboffset) int rpmtsGetKeys(rpmts ts, /*@null@*/ /*@out@*/ fnpyKey ** ep, /*@null@*/ /*@out@*/ int * nep) - /*@globals fileSystem @*/ - /*@modifies ts, ep, nep, fileSystem @*/; + /*@globals fileSystem, internalState @*/ + /*@modifies ts, ep, nep, fileSystem, internalState @*/; /** * Return (malloc'd) header name-version-release string. diff --git a/lib/signature.c b/lib/signature.c index 5fa669089..eff62ddac 100644 --- a/lib/signature.c +++ b/lib/signature.c @@ -9,7 +9,6 @@ #include <rpmmacro.h> /* XXX for rpmGetPath() */ #include "rpmdb.h" -#define _RPMTS_INTERNAL #include "rpmts.h" #include "misc.h" /* XXX for dosetenv() and makeTempFile() */ @@ -1003,7 +1002,8 @@ exit: static rpmRC verifyMD5Signature(const rpmts ts, /*@out@*/ char * t, /*@null@*/ DIGEST_CTX md5ctx) - /*@modifies *t @*/ + /*@globals internalState @*/ + /*@modifies *t, internalState @*/ { const void * sig = rpmtsSig(ts); int_32 siglen = rpmtsSiglen(ts); @@ -1021,10 +1021,10 @@ verifyMD5Signature(const rpmts ts, /*@out@*/ char * t, goto exit; } - (void) rpmswEnter(&ts->op_digest, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0); (void) rpmDigestFinal(rpmDigestDup(md5ctx), (void **)&md5sum, &md5len, 0); - (void) rpmswExit(&ts->op_digest, 0); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), 0); if (md5len != siglen || memcmp(md5sum, sig, md5len)) { res = RPMRC_FAIL; @@ -1060,7 +1060,8 @@ exit: static rpmRC verifySHA1Signature(const rpmts ts, /*@out@*/ char * t, /*@null@*/ DIGEST_CTX sha1ctx) - /*@modifies *t @*/ + /*@globals internalState @*/ + /*@modifies *t, internalState @*/ { const void * sig = rpmtsSig(ts); #ifdef NOTYET @@ -1079,10 +1080,10 @@ verifySHA1Signature(const rpmts ts, /*@out@*/ char * t, goto exit; } - (void) rpmswEnter(&ts->op_digest, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0); (void) rpmDigestFinal(rpmDigestDup(sha1ctx), (void **)&SHA1, NULL, 1); - (void) rpmswExit(&ts->op_digest, 0); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), 0); if (SHA1 == NULL || strlen(SHA1) != strlen(sig) || strcmp(SHA1, sig)) { res = RPMRC_FAIL; @@ -1164,7 +1165,7 @@ verifyPGPSignature(rpmts ts, /*@out@*/ char * t, goto exit; } - (void) rpmswEnter(&ts->op_digest, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0); { DIGEST_CTX ctx = rpmDigestDup(md5ctx); byte signhash16[2]; const char * s; @@ -1185,7 +1186,7 @@ verifyPGPSignature(rpmts ts, /*@out@*/ char * t, #endif xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 1); - (void) rpmswExit(&ts->op_digest, sigp->hashlen); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), sigp->hashlen); /* Compare leading 16 bits of digest for quick check. */ s = dig->md5; @@ -1224,12 +1225,12 @@ verifyPGPSignature(rpmts ts, /*@out@*/ char * t, if (res != RPMRC_OK) goto exit; - (void) rpmswEnter(&ts->op_signature, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_SIGNATURE), 0); if (rsavrfy(&dig->rsa_pk, &dig->rsahm, &dig->c)) res = RPMRC_OK; else res = RPMRC_FAIL; - (void) rpmswExit(&ts->op_signature, 0); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_SIGNATURE), 0); exit: t = stpcpy(t, rpmSigString(res)); @@ -1286,11 +1287,10 @@ verifyGPGSignature(rpmts ts, /*@out@*/ char * t, goto exit; } - (void) rpmswEnter(&ts->op_digest, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0); { DIGEST_CTX ctx = rpmDigestDup(sha1ctx); byte signhash16[2]; - (void) rpmswEnter(&ts->op_digest, 0); if (sigp->hash != NULL) xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen); @@ -1306,7 +1306,7 @@ verifyGPGSignature(rpmts ts, /*@out@*/ char * t, } #endif xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 1); - (void) rpmswExit(&ts->op_digest, sigp->hashlen); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), sigp->hashlen); mp32nzero(&dig->hm); mp32nsethex(&dig->hm, dig->sha1); @@ -1324,13 +1324,13 @@ verifyGPGSignature(rpmts ts, /*@out@*/ char * t, if (res != RPMRC_OK) goto exit; - (void) rpmswEnter(&ts->op_signature, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_SIGNATURE), 0); if (dsavrfy(&dig->p, &dig->q, &dig->g, &dig->hm, &dig->y, &dig->r, &dig->s)) res = RPMRC_OK; else res = RPMRC_FAIL; - (void) rpmswExit(&ts->op_signature, 0); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_SIGNATURE), 0); exit: t = stpcpy(t, rpmSigString(res)); diff --git a/lib/transaction.c b/lib/transaction.c index a93757ef8..d019de475 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -1209,7 +1209,7 @@ rpmMessage(RPMMESS_DEBUG, _("computing %d file fingerprints\n"), totalFileCount) continue; /* XXX can't happen */ fc = rpmfiFC(fi); - (void) rpmswEnter(&ts->op_fingerprint, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); fpLookupList(fpc, fi->dnl, fi->bnl, fi->dil, fc, fi->fps); /*@-branchstate@*/ fi = rpmfiInit(fi, 0); @@ -1222,7 +1222,7 @@ rpmMessage(RPMMESS_DEBUG, _("computing %d file fingerprints\n"), totalFileCount) /*@=dependenttrans@*/ } /*@=branchstate@*/ - (void) rpmswExit(&ts->op_fingerprint, fc); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc); } pi = rpmtsiFree(pi); @@ -1252,7 +1252,7 @@ rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n")); if (fc == 0) continue; - (void) rpmswEnter(&ts->op_fingerprint, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); /* Extract file info for all files in this package from the database. */ matches = xcalloc(fc, sizeof(*matches)); if (rpmdbFindFpList(rpmtsGetRdb(ts), fi->fps, matches, fc)) { @@ -1352,7 +1352,7 @@ rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n")); case TR_REMOVED: /*@switchbreak@*/ break; } - (void) rpmswExit(&ts->op_fingerprint, fc); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc); } pi = rpmtsiFree(pi); ps = rpmpsFree(ps); @@ -1425,7 +1425,7 @@ rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n")); numRemoved, NULL, ts->notifyData)); progress++; - (void) rpmswEnter(&ts->op_repackage, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_REPACKAGE), 0); /* XXX TR_REMOVED needs CPIO_MAP_{ABSOLUTE,ADDDOT} CPIO_ALL_HARDLINKS */ fi->mapflags |= CPIO_MAP_ABSOLUTE; @@ -1438,7 +1438,7 @@ rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n")); fi->mapflags &= ~CPIO_MAP_ADDDOT; fi->mapflags &= ~CPIO_ALL_HARDLINKS; - (void) rpmswExit(&ts->op_repackage, 0); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_REPACKAGE), 0); /*@switchbreak@*/ break; } @@ -1473,7 +1473,7 @@ assert(psm != NULL); switch (rpmteType(p)) { case TR_ADDED: - (void) rpmswEnter(&ts->op_install, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_INSTALL), 0); pkgKey = rpmteAddedKey(p); @@ -1570,12 +1570,12 @@ assert(psm != NULL); p->h = headerFree(p->h); - (void) rpmswExit(&ts->op_install, 0); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_INSTALL), 0); /*@switchbreak@*/ break; case TR_REMOVED: - (void) rpmswEnter(&ts->op_erase, 0); + (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_ERASE), 0); rpmMessage(RPMMESS_DEBUG, "========== --- %s\n", rpmteNEVR(p)); /* @@ -1587,7 +1587,7 @@ assert(psm != NULL); ourrc++; } - (void) rpmswExit(&ts->op_erase, 0); + (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_ERASE), 0); /*@switchbreak@*/ break; } diff --git a/rpmdb/rpmdb.c b/rpmdb/rpmdb.c index ebe3a313d..946d7d262 100644 --- a/rpmdb/rpmdb.c +++ b/rpmdb/rpmdb.c @@ -1536,7 +1536,7 @@ static rpmRC dbiFindByLabel(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, */ static int miFreeHeader(rpmdbMatchIterator mi, dbiIndex dbi) /*@globals fileSystem, internalState @*/ - /*@modifies mi, fileSystem, internalState @*/ + /*@modifies mi, dbi, fileSystem, internalState @*/ { int rc = 0; @@ -2279,8 +2279,8 @@ static void rpmdbSortIterator(/*@null@*/ rpmdbMatchIterator mi) /*@-bounds@*/ /* LCL: segfault */ static int rpmdbGrowIterator(/*@null@*/ rpmdbMatchIterator mi, int fpNum) - /*@globals rpmGlobalMacroContext, fileSystem @*/ - /*@modifies mi, rpmGlobalMacroContext, fileSystem @*/ + /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/ + /*@modifies mi, rpmGlobalMacroContext, fileSystem, internalState @*/ { DBC * dbcursor; DBT * key; diff --git a/rpmdb/rpmdb.h b/rpmdb/rpmdb.h index 2affb46fc..afb460931 100644 --- a/rpmdb/rpmdb.h +++ b/rpmdb/rpmdb.h @@ -559,8 +559,8 @@ int dbiCdup(dbiIndex dbi, DBC * dbcursor, /*@out@*/ DBC ** dbcp, /*@unused@*/ static inline int dbiDel(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data, unsigned int flags) - /*@globals fileSystem @*/ - /*@modifies *dbcursor, fileSystem @*/ + /*@globals fileSystem, internalState @*/ + /*@modifies dbi, *dbcursor, fileSystem, internalState @*/ { int rc; assert(key->data != NULL && key->size > 0); @@ -582,8 +582,8 @@ int dbiDel(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data, /*@unused@*/ static inline int dbiGet(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data, unsigned int flags) - /*@globals fileSystem @*/ - /*@modifies *dbcursor, *key, *data, fileSystem @*/ + /*@globals fileSystem, internalState @*/ + /*@modifies dbi, *dbcursor, *key, *data, fileSystem, internalState @*/ { int rc; assert((flags == DB_NEXT) || (key->data != NULL && key->size > 0)); @@ -606,8 +606,8 @@ int dbiGet(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data, /*@unused@*/ static inline int dbiPget(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * pkey, DBT * data, unsigned int flags) - /*@globals fileSystem @*/ - /*@modifies *dbcursor, *key, *pkey, *data, fileSystem @*/ + /*@globals fileSystem, internalState @*/ + /*@modifies dbi, *dbcursor, *key, *pkey, *data, fileSystem, internalState @*/ { int rc; assert((flags == DB_NEXT) || (key->data != NULL && key->size > 0)); @@ -629,8 +629,8 @@ int dbiPget(dbiIndex dbi, /*@null@*/ DBC * dbcursor, /*@unused@*/ static inline int dbiPut(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data, unsigned int flags) - /*@globals fileSystem @*/ - /*@modifies *dbcursor, *key, fileSystem @*/ + /*@globals fileSystem, internalState @*/ + /*@modifies dbi, *dbcursor, *key, fileSystem, internalState @*/ { int rc; assert(key->data != NULL && key->size > 0 && data->data != NULL && data->size > 0); @@ -928,8 +928,8 @@ int rpmdbOpenAll (/*@null@*/ rpmdb db) * @return number of instances */ int rpmdbCountPackages(/*@null@*/ rpmdb db, const char * name) - /*@globals rpmGlobalMacroContext, fileSystem @*/ - /*@modifies db, rpmGlobalMacroContext, fileSystem @*/; + /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/ + /*@modifies db, rpmGlobalMacroContext, fileSystem, internalState @*/; /** \ingroup rpmdb * Return header join key for current position of rpm database iterator. diff --git a/rpmio/rpmio_internal.h b/rpmio/rpmio_internal.h index 2be3ceb8b..505c6da69 100644 --- a/rpmio/rpmio_internal.h +++ b/rpmio/rpmio_internal.h @@ -104,14 +104,14 @@ typedef struct _FDSTACK_s { /** \ingroup rpmio * Identify per-desciptor I/O operation statistics. */ -enum FDSTAT_e { +typedef enum fdOpX_e { FDSTAT_READ = 0, /*!< Read statistics index. */ FDSTAT_WRITE = 1, /*!< Write statistics index. */ FDSTAT_SEEK = 2, /*!< Seek statistics index. */ FDSTAT_CLOSE = 3, /*!< Close statistics index */ FDSTAT_DIGEST = 4, /*!< Digest statistics index. */ FDSTAT_MAX = 5 -}; +} fdOpX; /** \ingroup rpmio * Cumulative statistics for a descriptor. @@ -346,7 +346,8 @@ void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno) /** \ingroup rpmio */ -/*@unused@*/ static inline void fdPop(FD_t fd) +/*@unused@*/ static inline +void fdPop(FD_t fd) /*@modifies fd @*/ { FDSANE(fd); @@ -359,16 +360,29 @@ void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno) /** \ingroup rpmio */ +/*@unused@*/ static inline /*@null@*/ +rpmop fdstat_op(/*@null@*/ FD_t fd, fdOpX opx) + /*@*/ +{ + rpmop op = NULL; + +/*@-boundsread@*/ + if (fd != NULL && fd->stats != NULL && opx >= 0 && opx < FDSTAT_MAX) + op = fd->stats->ops + opx; +/*@=boundsread@*/ + return op; +} + +/** \ingroup rpmio + */ /*@unused@*/ static inline void fdstat_enter(/*@null@*/ FD_t fd, int opx) /*@globals internalState @*/ - /*@modifies fd, internalState @*/ + /*@modifies internalState @*/ { if (fd == NULL) return; -/*@-boundswrite@*/ if (fd->stats != NULL) - (void) rpmswEnter(&fd->stats->ops[opx], 0); -/*@=boundswrite@*/ + (void) rpmswEnter(fdstat_op(fd, opx), 0); } /** \ingroup rpmio @@ -383,10 +397,8 @@ void fdstat_exit(/*@null@*/ FD_t fd, int opx, ssize_t rc) fd->syserrno = errno; else if (rc > 0 && fd->bytesRemain > 0) fd->bytesRemain -= rc; -/*@-boundswrite@*/ if (fd->stats != NULL) - (void) rpmswExit(&fd->stats->ops[opx], rc); -/*@=boundswrite@*/ + (void) rpmswExit(fdstat_op(fd, opx), rc); } /** \ingroup rpmio @@ -487,7 +499,8 @@ FD_t c2f(/*@null@*/ void * cookie) */ /*@unused@*/ static inline void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags) - /*@modifies fd @*/ + /*@globals internalState @*/ + /*@modifies fd, internalState @*/ { FDDIGEST_t fddig = fd->digests + fd->ndigests; if (fddig != (fd->digests + FDDIGEST_MAX)) { @@ -504,7 +517,8 @@ void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags) */ /*@unused@*/ static inline void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen) - /*@modifies fd @*/ + /*@globals internalState @*/ + /*@modifies fd, internalState @*/ { int i; @@ -526,7 +540,8 @@ void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo, /*@null@*/ /*@out@*/ void ** datap, /*@null@*/ /*@out@*/ size_t * lenp, int asAscii) - /*@modifies fd, *datap, *lenp @*/ + /*@globals internalState @*/ + /*@modifies fd, *datap, *lenp, internalState @*/ { int imax = -1; int i; diff --git a/rpmio/rpmrpc.c b/rpmio/rpmrpc.c index de21d8876..9f3be35d7 100644 --- a/rpmio/rpmrpc.c +++ b/rpmio/rpmrpc.c @@ -903,6 +903,7 @@ static int ftpNLST(const char * url, ftpSysCall_t ftpSysCall, /* XXX FIXME: realloc ftpBuf if < ~128 chars remain */ if ((ftpBufAlloced - bufLength) < (1024+80)) { ftpBufAlloced <<= 2; + assert(ftpBufAlloced < (8*1024*1024)); ftpBuf = xrealloc(ftpBuf, ftpBufAlloced); } s = se = ftpBuf + bufLength; diff --git a/rpmio/rpmsw.c b/rpmio/rpmsw.c index b51a3dc1a..f8b2fc9dc 100644 --- a/rpmio/rpmsw.c +++ b/rpmio/rpmsw.c @@ -179,7 +179,6 @@ static rpmtime_t rpmswCalibrate(void) /*@=type@*/ #endif -/*@-incondefs@*/ rpmtime_t rpmswInit(void) /*@globals rpmsw_cycles, rpmsw_initialized, rpmsw_overhead, rpmsw_type @*/ @@ -228,6 +227,8 @@ rpmtime_t rpmswInit(void) /* Compute cycles/usec */ rpmsw_cycles = sum_cycles/sum_usecs; +#else + rpmsw_type = 0; #endif /* Calculate timing overhead in usecs. */ @@ -242,11 +243,13 @@ rpmtime_t rpmswInit(void) return rpmsw_overhead; } -/*@=incondefs@*/ /*@-mods@*/ int rpmswEnter(rpmop op, ssize_t rc) { + if (op == NULL) + return 0; + op->count++; if (rc < 0) { op->bytes = 0; @@ -262,6 +265,9 @@ rpmtime_t rpmswExit(rpmop op, ssize_t rc) { struct rpmsw_s end; + if (op == NULL) + return 0; + /*@-uniondef@*/ op->usecs += rpmswDiff(rpmswNow(&end), &op->begin); /*@=uniondef@*/ @@ -273,22 +279,26 @@ rpmtime_t rpmswExit(rpmop op, ssize_t rc) rpmtime_t rpmswAdd(rpmop to, rpmop from) { + rpmtime_t usecs = 0; if (to != NULL && from != NULL) { to->count += from->count; to->bytes += from->bytes; to->usecs += from->usecs; + usecs = to->usecs; } - return to->usecs; + return usecs; } rpmtime_t rpmswSub(rpmop to, rpmop from) { + rpmtime_t usecs = 0; if (to != NULL && from != NULL) { to->count -= from->count; to->bytes -= from->bytes; to->usecs -= from->usecs; + usecs = to->usecs; } - return to->usecs; + return usecs; } /*@=mods@*/ diff --git a/rpmio/rpmsw.h b/rpmio/rpmsw.h index 8bcedf274..3cae71198 100644 --- a/rpmio/rpmsw.h +++ b/rpmio/rpmsw.h @@ -77,7 +77,7 @@ rpmtime_t rpmswInit(void) * @param rc -1 clears usec counter * @return 0 always */ -int rpmswEnter(rpmop op, ssize_t rc) +int rpmswEnter(/*@null@*/ rpmop op, ssize_t rc) /*@globals internalState @*/ /*@modifies *op, internalState @*/; @@ -87,7 +87,7 @@ int rpmswEnter(rpmop op, ssize_t rc) * @param rc per-operation data (e.g. bytes transferred) * @return cumulative usecs for operation */ -rpmtime_t rpmswExit(rpmop op, ssize_t rc) +rpmtime_t rpmswExit(/*@null@*/ rpmop op, ssize_t rc) /*@globals internalState @*/ /*@modifies op, internalState @*/; @@ -97,7 +97,7 @@ rpmtime_t rpmswExit(rpmop op, ssize_t rc) * @param from operation statistics * @return cumulative usecs for operation */ -rpmtime_t rpmswAdd(rpmop to, rpmop from) +rpmtime_t rpmswAdd(/*@null@*/ rpmop to, /*@null@*/ rpmop from) /*@modifies to @*/; /** \ingroup rpmio |