rpm  5.2.1
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 */