rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

rpmio/rpmio_internal.h
Go to the documentation of this file.

    00001 #ifndef H_RPMIO_INTERNAL
    00002 #define H_RPMIO_INTERNAL
    00003
    00008 #include <rpmiotypes.h>
    00009 #include <rpmlog.h>
    00010 #include <rpmio.h>
    00011 #include <rpmurl.h>
    00012
    00013 #define _RPMPGP_INTERNAL
    00014 #include <rpmpgp.h>
    00015
    00016 #include <rpmxar.h>
    00017
    00018 /*@access pgpDig @*/    /* XXX FIXME: (by refactoring to foo.c) */
    00019 /*@access rpmxar @*/    /* XXX FIXME: (by refactoring to foo.c) */
    00020
    00023 typedef struct _FDSTACK_s {
    00024 /*@exposed@*/
    00025     FDIO_t              io;
    00026 /*@dependent@*/
    00027     void *              fp;
    00028     int                 fdno;
    00029 } FDSTACK_t;
    00030
    00034 typedef enum fdOpX_e {
    00035     FDSTAT_READ         = 0,
    00036     FDSTAT_WRITE        = 1,
    00037     FDSTAT_SEEK         = 2,
    00038     FDSTAT_CLOSE        = 3,
    00039     FDSTAT_DIGEST       = 4,
    00040     FDSTAT_MAX          = 5
    00041 } fdOpX;
    00042
    00046 typedef /*@abstract@*/ struct {
    00047     struct rpmop_s      ops[FDSTAT_MAX];
    00048 } * FDSTAT_t;
    00049
    00052 typedef struct _FDDIGEST_s {
    00053     pgpHashAlgo         hashalgo;
    00054     DIGEST_CTX          hashctx;
    00055 } * FDDIGEST_t;
    00056
    00060 struct _FD_s {
    00061     struct rpmioItem_s _item;
    00062     int         flags;
    00063 #define RPMIO_DEBUG_IO          0x40000000
    00064 #define RPMIO_DEBUG_REFS        0x20000000
    00065     int         magic;
    00066 #define FDMAGIC                 0x04463138
    00067     int         nfps;
    00068     FDSTACK_t   fps[8];
    00069     int         urlType;        /* ufdio: */
    00070
    00071 /*@dependent@*/ /*@relnull@*/
    00072     void *      url;            /* ufdio: URL info */
    00073 /*@relnull@*/
    00074     void *      req;            /* ufdio: HTTP request */
    00075
    00076     int         rd_timeoutsecs; /* ufdRead: per FD_t timer */
    00077     ssize_t     bytesRemain;    /* ufdio: */
    00078     ssize_t     contentLength;  /* ufdio: */
    00079     int         persist;        /* ufdio: */
    00080     int         wr_chunked;     /* ufdio: */
    00081
    00082     int         syserrno;       /* last system errno encountered */
    00083 /*@observer@*/
    00084     const void *errcookie;      /* gzdio/bzdio/ufdio: */
    00085
    00086 /*null@*/
    00087     const char *opath;          /* open(2) args. */
    00088     int         oflags;
    00089     mode_t      omode;
    00090
    00091 /*@refcounted@*/ /*@relnull@*/
    00092     rpmxar      xar;            /* xar archive wrapper */
    00093 /*@refcounted@*/ /*@relnull@*/
    00094     pgpDig      dig;            /* signature parameters */
    00095
    00096     FDSTAT_t    stats;          /* I/O statistics */
    00097
    00098     int         ndigests;
    00099 #define FDDIGEST_MAX    32
    00100     struct _FDDIGEST_s  digests[FDDIGEST_MAX];
    00101
    00102 /*null@*/
    00103     const char *contentType;    /* ufdio: (HTTP) */
    00104 /*null@*/
    00105     const char *contentDisposition;     /* ufdio: (HTTP) */
    00106     time_t      lastModified;   /* ufdio: (HTTP) */
    00107     int         ftpFileDoneNeeded; /* ufdio: (FTP) */
    00108     unsigned long long  fd_cpioPos;     /* cpio: */
    00109 #if defined(__LCLINT__)
    00110 /*@refs@*/
    00111     int nrefs;
    00112 #endif
    00113 };
    00114 /*@access FD_t@*/
    00115
    00116 #define FDSANE(fd)      assert(fd != NULL && fd->magic == FDMAGIC)
    00117
    00118 /*@-redecl@*/
    00119 /*@unchecked@*/
    00120 extern int _rpmio_debug;
    00121 /*@=redecl@*/
    00122
    00123 /*@-redecl@*/
    00124 /*@unchecked@*/
    00125 extern int _av_debug;
    00126 /*@=redecl@*/
    00127
    00128 /*@-redecl@*/
    00129 /*@unchecked@*/
    00130 extern int _ftp_debug;
    00131 /*@=redecl@*/
    00132
    00133 /*@-redecl@*/
    00134 /*@unchecked@*/
    00135 extern int _dav_debug;
    00136 /*@=redecl@*/
    00137
    00138 #define DBG(_f, _m, _x) \
    00139     /*@-modfilesys@*/ \
    00140     if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x \
    00141     /*@=modfilesys@*/
    00142
    00143 #if defined(__LCLINT__XXX)
    00144 #define DBGIO(_f, _x)
    00145 #define DBGREFS(_f, _x)
    00146 #else
    00147 #define DBGIO(_f, _x)   DBG((_f), RPMIO_DEBUG_IO, _x)
    00148 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
    00149 #endif
    00150
    00151 #ifdef __cplusplus
    00152 extern "C" {
    00153 #endif
    00154
    00157 /*@observer@*/ const char * fdbg(/*@null@*/ FD_t fd)
    00158         /*@*/;
    00159
    00162 int fdFgets(FD_t fd, char * buf, size_t len)
    00163         /*@globals errno, fileSystem @*/
    00164         /*@modifies *buf, fd, errno, fileSystem @*/;
    00165
    00168 /*@null@*/ FD_t ftpOpen(const char *url, /*@unused@*/ int flags,
    00169                 /*@unused@*/ mode_t mode, /*@out@*/ urlinfo *uret)
    00170         /*@globals h_errno, fileSystem, internalState @*/
    00171         /*@modifies *uret, fileSystem, internalState @*/;
    00172
    00175 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
    00176         /*@globals fileSystem, internalState @*/
    00177         /*@modifies data, fileSystem, internalState @*/;
    00178
    00181 int ftpCmd(const char * cmd, const char * url, const char * arg2)
    00182         /*@globals h_errno, fileSystem, internalState @*/
    00183         /*@modifies fileSystem, internalState @*/;
    00184
    00187 int ufdClose( /*@only@*/ void * cookie)
    00188         /*@globals fileSystem, internalState @*/
    00189         /*@modifies cookie, fileSystem, internalState @*/;
    00190
    00193 /*@unused@*/ static inline
    00194 void fdSetOpen(FD_t fd, const char * path, int flags, mode_t mode)
    00195         /*@modifies fd @*/
    00196 {
    00197     FDSANE(fd);
    00198     if (fd->opath != NULL) {
    00199         free((void *)fd->opath);
    00200         fd->opath = NULL;
    00201     }
    00202     fd->opath = xstrdup(path);
    00203     fd->oflags = flags;
    00204     fd->omode = mode;
    00205 }
    00206
    00209 /*@unused@*/ static inline
    00210 /*@null@*/ /*@observer@*/ const char * fdGetOPath(FD_t fd)
    00211         /*@*/
    00212 {
    00213     FDSANE(fd);
    00214     return fd->opath;
    00215 }
    00216
    00219 /*@unused@*/ static inline
    00220 int fdGetOFlags(FD_t fd)
    00221         /*@*/
    00222 {
    00223     FDSANE(fd);
    00224     return fd->oflags;
    00225 }
    00226
    00229 /*@unused@*/ static inline
    00230 mode_t fdGetOMode(FD_t fd)
    00231         /*@*/
    00232 {
    00233     FDSANE(fd);
    00234     return fd->omode;
    00235 }
    00236
    00239 /*@unused@*/ static inline
    00240 void fdSetDig(FD_t fd, pgpDig dig)
    00241         /*@globals fileSystem @*/
    00242         /*@modifies fd, dig, fileSystem @*/
    00243 {
    00244     FDSANE(fd);
    00245 /*@-assignexpose -castexpose @*/
    00246     fd->dig = pgpDigFree(fd->dig, "fdSetDig");
    00247     fd->dig = pgpDigLink(dig, "fdSetDig");
    00248 /*@=assignexpose =castexpose @*/
    00249 }
    00250
    00253 /*@unused@*/ static inline
    00254 /*@null@*/ pgpDig fdGetDig(FD_t fd)
    00255         /*@*/
    00256 {
    00257     FDSANE(fd);
    00258     /*@-compdef -retexpose -refcounttrans -usereleased @*/
    00259     return fd->dig;
    00260     /*@=compdef =retexpose =refcounttrans =usereleased @*/
    00261 }
    00262
    00265 /*@unused@*/ static inline
    00266 void fdSetXAR(FD_t fd, rpmxar xar)
    00267         /*@globals fileSystem @*/
    00268         /*@modifies fd, xar, fileSystem @*/
    00269 {
    00270     FDSANE(fd);
    00271 /*@-assignexpose -castexpose @*/
    00272     fd->xar = rpmxarLink(xar, "fdSetXAR");
    00273 /*@=assignexpose =castexpose @*/
    00274 }
    00275
    00278 /*@unused@*/ static inline
    00279 /*@null@*/ rpmxar fdGetXAR(FD_t fd)
    00280         /*@*/
    00281 {
    00282     FDSANE(fd);
    00283     /*@-compdef -refcounttrans -retexpose -usereleased @*/
    00284     return fd->xar;
    00285     /*@=compdef =refcounttrans =retexpose =usereleased @*/
    00286 }
    00287
    00290 /*@unused@*/ static inline
    00291 /*@null@*/ FDIO_t fdGetIo(FD_t fd)
    00292         /*@*/
    00293 {
    00294     FDSANE(fd);
    00295     return fd->fps[fd->nfps].io;
    00296 }
    00297
    00300 /*@-nullstate@*/ /* FIX: io may be NULL */
    00301 /*@unused@*/ static inline
    00302 void fdSetIo(FD_t fd, /*@kept@*/ /*@null@*/ FDIO_t io)
    00303         /*@modifies fd @*/
    00304 {
    00305     FDSANE(fd);
    00306     /*@-assignexpose@*/
    00307     fd->fps[fd->nfps].io = io;
    00308     /*@=assignexpose@*/
    00309 }
    00310 /*@=nullstate@*/
    00311
    00314 /*@unused@*/ static inline
    00315 /*@exposed@*/ /*@dependent@*/ /*@null@*/ FILE * fdGetFILE(FD_t fd)
    00316         /*@*/
    00317 {
    00318     FDSANE(fd);
    00319     /*@+voidabstract@*/
    00320     return ((FILE *)fd->fps[fd->nfps].fp);
    00321     /*@=voidabstract@*/
    00322 }
    00323
    00326 /*@unused@*/ static inline
    00327 /*@exposed@*/ /*@dependent@*/ /*@null@*/ void * fdGetFp(FD_t fd)
    00328         /*@*/
    00329 {
    00330     FDSANE(fd);
    00331     return fd->fps[fd->nfps].fp;
    00332 }
    00333
    00336 /*@-nullstate@*/ /* FIX: fp may be NULL */
    00337 /*@unused@*/ static inline
    00338 void fdSetFp(FD_t fd, /*@kept@*/ /*@null@*/ void * fp)
    00339         /*@modifies fd @*/
    00340 {
    00341     FDSANE(fd);
    00342     /*@-assignexpose@*/
    00343     fd->fps[fd->nfps].fp = fp;
    00344     /*@=assignexpose@*/
    00345 }
    00346 /*@=nullstate@*/
    00347
    00350 /*@unused@*/ static inline
    00351 int fdGetFdno(FD_t fd)
    00352         /*@*/
    00353 {
    00354     FDSANE(fd);
    00355     return fd->fps[fd->nfps].fdno;
    00356 }
    00357
    00360 /*@unused@*/ static inline
    00361 void fdSetFdno(FD_t fd, int fdno)
    00362         /*@modifies fd @*/
    00363 {
    00364     FDSANE(fd);
    00365     fd->fps[fd->nfps].fdno = fdno;
    00366 }
    00367
    00370 /*@unused@*/ static inline
    00371 void fdSetContentLength(FD_t fd, ssize_t contentLength)
    00372         /*@modifies fd @*/
    00373 {
    00374     FDSANE(fd);
    00375     fd->contentLength = fd->bytesRemain = contentLength;
    00376 }
    00377
    00380 /*@unused@*/ static inline
    00381 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
    00382         /*@modifies fd @*/
    00383 {
    00384     FDSANE(fd);
    00385     if (fd->nfps >= (int)(sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
    00386         return;
    00387     fd->nfps++;
    00388     fdSetIo(fd, io);
    00389     fdSetFp(fd, fp);
    00390     fdSetFdno(fd, fdno);
    00391 }
    00392
    00395 /*@unused@*/ static inline
    00396 void fdPop(FD_t fd)
    00397         /*@modifies fd @*/
    00398 {
    00399     FDSANE(fd);
    00400     if (fd->nfps < 0) return;
    00401     fdSetIo(fd, NULL);
    00402     fdSetFp(fd, NULL);
    00403     fdSetFdno(fd, -1);
    00404     fd->nfps--;
    00405 }
    00406
    00409 /*@unused@*/ static inline /*@null@*/
    00410 rpmop fdstat_op(/*@null@*/ FD_t fd, fdOpX opx)
    00411         /*@*/
    00412 {
    00413     rpmop op = NULL;
    00414
    00415     if (fd != NULL && fd->stats != NULL && (int)opx >= 0 && opx < FDSTAT_MAX)
    00416         op = fd->stats->ops + opx;
    00417     return op;
    00418 }
    00419
    00422 /*@unused@*/ static inline
    00423 void fdstat_enter(/*@null@*/ FD_t fd, int opx)
    00424         /*@globals internalState @*/
    00425         /*@modifies internalState @*/
    00426 {
    00427     if (fd == NULL) return;
    00428     if (fd->stats != NULL)
    00429         (void) rpmswEnter(fdstat_op(fd, opx), 0);
    00430 }
    00431
    00434 /*@unused@*/ static inline
    00435 void fdstat_exit(/*@null@*/ FD_t fd, int opx, ssize_t rc)
    00436         /*@globals internalState @*/
    00437         /*@modifies fd, internalState @*/
    00438 {
    00439     if (fd == NULL) return;
    00440     if (rc == -1)
    00441         fd->syserrno = errno;
    00442     else if (rc > 0 && fd->bytesRemain > 0)
    00443         switch (opx) {
    00444         case FDSTAT_READ:
    00445         case FDSTAT_WRITE:
    00446         fd->bytesRemain -= rc;
    00447             break;
    00448         default:
    00449             break;
    00450         }
    00451     if (fd->stats != NULL)
    00452         (void) rpmswExit(fdstat_op(fd, opx), rc);
    00453 }
    00454
    00457 /*@unused@*/ static inline
    00458 void fdstat_print(/*@null@*/ FD_t fd, const char * msg, FILE * fp)
    00459         /*@globals fileSystem @*/
    00460         /*@modifies *fp, fileSystem @*/
    00461 {
    00462     static int usec_scale = (1000*1000);
    00463     int opx;
    00464
    00465     if (fd == NULL || fd->stats == NULL) return;
    00466     for (opx = 0; opx < 4; opx++) {
    00467         rpmop op = &fd->stats->ops[opx];
    00468         if (op->count <= 0) continue;
    00469         switch (opx) {
    00470         case FDSTAT_READ:
    00471             if (msg != NULL) fprintf(fp, "%s:", msg);
    00472             fprintf(fp, "%8d reads, %8lu total bytes in %d.%06d secs\n",
    00473                 op->count, (unsigned long)op->bytes,
    00474                 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
    00475             /*@switchbreak@*/ break;
    00476         case FDSTAT_WRITE:
    00477             if (msg != NULL) fprintf(fp, "%s:", msg);
    00478             fprintf(fp, "%8d writes, %8lu total bytes in %d.%06d secs\n",
    00479                 op->count, (unsigned long)op->bytes,
    00480                 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
    00481             /*@switchbreak@*/ break;
    00482         case FDSTAT_SEEK:
    00483             /*@switchbreak@*/ break;
    00484         case FDSTAT_CLOSE:
    00485             /*@switchbreak@*/ break;
    00486         }
    00487     }
    00488 }
    00489
    00492 /*@unused@*/ static inline
    00493 void fdSetSyserrno(FD_t fd, int syserrno, /*@kept@*/ const void * errcookie)
    00494         /*@modifies fd @*/
    00495 {
    00496     FDSANE(fd);
    00497     fd->syserrno = syserrno;
    00498     /*@-assignexpose@*/
    00499     fd->errcookie = errcookie;
    00500     /*@=assignexpose@*/
    00501 }
    00502
    00505 /*@unused@*/ static inline
    00506 int fdGetRdTimeoutSecs(FD_t fd)
    00507         /*@*/
    00508 {
    00509     FDSANE(fd);
    00510     return fd->rd_timeoutsecs;
    00511 }
    00512
    00515 /*@unused@*/ static inline
    00516 unsigned long long fdGetCpioPos(FD_t fd)
    00517         /*@*/
    00518 {
    00519     FDSANE(fd);
    00520     return fd->fd_cpioPos;
    00521 }
    00522
    00525 /*@unused@*/ static inline
    00526 void fdSetCpioPos(FD_t fd, long int cpioPos)
    00527         /*@modifies fd @*/
    00528 {
    00529     FDSANE(fd);
    00530     fd->fd_cpioPos = cpioPos;
    00531 }
    00532
    00535 /*@mayexit@*/ /*@unused@*/ static inline
    00536 FD_t c2f(/*@null@*/ void * cookie)
    00537         /*@*/
    00538 {
    00539     /*@-castexpose@*/
    00540     FD_t fd = (FD_t) cookie;
    00541     /*@=castexpose@*/
    00542     FDSANE(fd);
    00543     /*@-refcounttrans -retalias@*/ return fd; /*@=refcounttrans =retalias@*/
    00544 }
    00545
    00549 /*@unused@*/ static inline
    00550 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
    00551         /*@globals internalState @*/
    00552         /*@modifies fd, internalState @*/
    00553 {
    00554     FDDIGEST_t fddig = fd->digests + fd->ndigests;
    00555     if (fddig != (fd->digests + FDDIGEST_MAX)) {
    00556         fd->ndigests++;
    00557         fddig->hashalgo = hashalgo;
    00558         fdstat_enter(fd, FDSTAT_DIGEST);
    00559         fddig->hashctx = rpmDigestInit(hashalgo, flags);
    00560         fdstat_exit(fd, FDSTAT_DIGEST, 0);
    00561     }
    00562 }
    00563
    00567 /*@unused@*/ static inline
    00568 void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen)
    00569         /*@globals internalState @*/
    00570         /*@modifies fd, internalState @*/
    00571 {
    00572     int i;
    00573
    00574     if (buf != NULL && buflen > 0)
    00575     for (i = fd->ndigests - 1; i >= 0; i--) {
    00576         FDDIGEST_t fddig = fd->digests + i;
    00577         if (fddig->hashctx == NULL)
    00578             continue;
    00579         fdstat_enter(fd, FDSTAT_DIGEST);
    00580         (void) rpmDigestUpdate(fddig->hashctx, buf, buflen);
    00581         fdstat_exit(fd, FDSTAT_DIGEST, buflen);
    00582     }
    00583 }
    00584
    00587 /*@unused@*/ static inline
    00588 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo,
    00589                 /*@null@*/ /*@out@*/ void * datap,
    00590                 /*@null@*/ /*@out@*/ size_t * lenp,
    00591                 int asAscii)
    00592         /*@globals internalState @*/
    00593         /*@modifies fd, *datap, *lenp, internalState @*/
    00594 {
    00595     int imax = -1;
    00596     int i;
    00597
    00598     for (i = fd->ndigests - 1; i >= 0; i--) {
    00599         FDDIGEST_t fddig = fd->digests + i;
    00600         if (fddig->hashctx == NULL)
    00601             continue;
    00602         if (i > imax) imax = i;
    00603         if (fddig->hashalgo != hashalgo)
    00604             continue;
    00605         fdstat_enter(fd, FDSTAT_DIGEST);
    00606         (void) rpmDigestFinal(fddig->hashctx, datap, lenp, asAscii);
    00607         fdstat_exit(fd, FDSTAT_DIGEST, 0);
    00608         fddig->hashctx = NULL;
    00609         break;
    00610     }
    00611     if (i < 0) {
    00612         if (datap != NULL) *(void **)datap = NULL;
    00613         if (lenp != NULL) *lenp = 0;
    00614     }
    00615
    00616     fd->ndigests = imax;
    00617     if (i < imax)
    00618         fd->ndigests++;         /* convert index to count */
    00619 }
    00620
    00623 /*@-mustmod@*/
    00624 /*@unused@*/ static inline
    00625 void fdStealDigest(FD_t fd, pgpDig dig)
    00626         /*@modifies fd, dig @*/
    00627 {
    00628     int i;
    00629 /*@-type@*/     /* FIX: getters for pgpDig internals */
    00630     for (i = fd->ndigests - 1; i >= 0; i--) {
    00631         FDDIGEST_t fddig = fd->digests + i;
    00632         if (fddig->hashctx != NULL)
    00633         switch (fddig->hashalgo) {
    00634         case PGPHASHALGO_MD5:
    00635 assert(dig->md5ctx == NULL);
    00636 /*@-onlytrans@*/
    00637             dig->md5ctx = fddig->hashctx;
    00638 /*@=onlytrans@*/
    00639             fddig->hashctx = NULL;
    00640             /*@switchbreak@*/ break;
    00641         case PGPHASHALGO_SHA1:
    00642         case PGPHASHALGO_RIPEMD160:
    00643 #if defined(HAVE_BEECRYPT_API_H)
    00644         case PGPHASHALGO_SHA256:
    00645         case PGPHASHALGO_SHA384:
    00646         case PGPHASHALGO_SHA512:
    00647 #endif
    00648 assert(dig->sha1ctx == NULL);
    00649 /*@-onlytrans@*/
    00650             dig->sha1ctx = fddig->hashctx;
    00651 /*@=onlytrans@*/
    00652             fddig->hashctx = NULL;
    00653             /*@switchbreak@*/ break;
    00654         default:
    00655             /*@switchbreak@*/ break;
    00656         }
    00657     }
    00658 /*@=type@*/
    00659 }
    00660 /*@=mustmod@*/
    00661
    00662 /*@-shadow@*/
    00665 /*@unused@*/ static inline
    00666 int fdFileno(/*@null@*/ void * cookie)
    00667         /*@*/
    00668 {
    00669     FD_t fd;
    00670     if (cookie == NULL) return -2;
    00671     fd = c2f(cookie);
    00672     return fd->fps[0].fdno;
    00673 }
    00674 /*@=shadow@*/
    00675
    00676 #ifdef __cplusplus
    00677 }
    00678 #endif
    00679
    00680 #endif  /* H_RPMIO_INTERNAL */