rpm 5.3.12
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     DIGEST_CTX          hashctx;
00054 } * FDDIGEST_t;
00055 
00059 struct _FD_s {
00060     struct rpmioItem_s _item;   
00061     int         flags;
00062 #define RPMIO_DEBUG_IO          0x40000000
00063 #define RPMIO_DEBUG_REFS        0x20000000
00064     int         magic;
00065 #define FDMAGIC                 0x04463138
00066     int         nfps;
00067     FDSTACK_t   fps[8];
00068 
00069 /*@dependent@*/ /*@relnull@*/
00070     void *      u;              /* ufdio: URL info */
00071 /*@relnull@*/
00072     void *      req;            /* ufdio: HTTP request */
00073 
00074     int         rd_timeoutsecs; /* ufdRead: per FD_t timer */
00075     ssize_t     bytesRemain;    /* ufdio: */
00076     ssize_t     contentLength;  /* ufdio: */
00077     int         persist;        /* ufdio: */
00078     int         wr_chunked;     /* ufdio: */
00079 
00080     int         syserrno;       /* last system errno encountered */
00081 /*@observer@*/
00082     const void *errcookie;      /* gzdio/bzdio/ufdio: */
00083 
00084 /*null@*/
00085     const char *opath;          /* open(2) args. */
00086     int         oflags;
00087     mode_t      omode;
00088 
00089 /*@refcounted@*/ /*@relnull@*/
00090     rpmxar      xar;            /* xar archive wrapper */
00091 /*@refcounted@*/ /*@relnull@*/
00092     pgpDig      dig;            /* signature parameters */
00093 
00094     FDSTAT_t    stats;          /* I/O statistics */
00095 
00096     size_t      ndigests;
00097     DIGEST_CTX *digests;
00098 
00099 /*null@*/
00100     const char *contentType;    /* ufdio: (HTTP) */
00101 /*null@*/
00102     const char *contentDisposition;     /* ufdio: (HTTP) */
00103     time_t      lastModified;   /* ufdio: (HTTP) */
00104     int         ftpFileDoneNeeded; /* ufdio: (FTP) */
00105     unsigned long long  fd_cpioPos;     /* cpio: */
00106 #if defined(__LCLINT__)
00107 /*@refs@*/
00108     int nrefs;                  
00109 #endif
00110 };
00111 /*@access FD_t@*/
00112 
00113 #define FDSANE(fd)      assert(fd != NULL && fd->magic == FDMAGIC)
00114 
00115 #define DBG(_f, _m, _x) \
00116     /*@-modfilesys@*/ \
00117     if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x \
00118     /*@=modfilesys@*/
00119 
00120 #if defined(__LCLINT__XXX)
00121 #define DBGIO(_f, _x)
00122 #define DBGREFS(_f, _x)
00123 #else
00124 #define DBGIO(_f, _x)   DBG((_f), RPMIO_DEBUG_IO, _x)
00125 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
00126 #endif
00127 
00128 #ifdef __cplusplus
00129 extern "C" {
00130 #endif
00131 
00134 /*@observer@*/ const char * fdbg(/*@null@*/ FD_t fd)
00135         /*@*/;
00136 
00139 int fdFgets(FD_t fd, char * buf, size_t len)
00140         /*@globals errno, fileSystem @*/
00141         /*@modifies *buf, fd, errno, fileSystem @*/;
00142 
00145 /*@null@*/ FD_t ftpOpen(const char *url, /*@unused@*/ int flags,
00146                 /*@unused@*/ mode_t mode, /*@out@*/ urlinfo *uret)
00147         /*@globals h_errno, fileSystem, internalState @*/
00148         /*@modifies *uret, fileSystem, internalState @*/;
00149 
00152 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
00153         /*@globals fileSystem, internalState @*/
00154         /*@modifies data, fileSystem, internalState @*/;
00155 
00158 int ftpCmd(const char * cmd, const char * url, const char * arg2)
00159         /*@globals h_errno, fileSystem, internalState @*/
00160         /*@modifies fileSystem, internalState @*/;
00161 
00164 int ufdClose( /*@only@*/ void * cookie)
00165         /*@globals fileSystem, internalState @*/
00166         /*@modifies cookie, fileSystem, internalState @*/;
00167 
00170 /*@unused@*/ static inline
00171 void fdSetOpen(FD_t fd, const char * path, int flags, mode_t mode)
00172         /*@modifies fd @*/
00173 {
00174     FDSANE(fd);
00175     if (fd->opath != NULL) {
00176         free((void *)fd->opath);
00177         fd->opath = NULL;
00178     }
00179     fd->opath = xstrdup(path);
00180     fd->oflags = flags;
00181     fd->omode = mode;
00182 }
00183 
00186 /*@unused@*/ static inline
00187 /*@null@*/ /*@observer@*/ const char * fdGetOPath(FD_t fd)
00188         /*@*/
00189 {
00190     FDSANE(fd);
00191     return fd->opath;
00192 }
00193 
00196 /*@unused@*/ static inline
00197 int fdGetOFlags(FD_t fd)
00198         /*@*/
00199 {
00200     FDSANE(fd);
00201     return fd->oflags;
00202 }
00203 
00206 /*@unused@*/ static inline
00207 mode_t fdGetOMode(FD_t fd)
00208         /*@*/
00209 {
00210     FDSANE(fd);
00211     return fd->omode;
00212 }
00213 
00216 /*@unused@*/ static inline
00217 void fdSetDig(FD_t fd, pgpDig dig)
00218         /*@globals fileSystem @*/
00219         /*@modifies fd, dig, fileSystem @*/
00220 {
00221     FDSANE(fd);
00222 /*@-assignexpose -castexpose @*/
00223     fd->dig = pgpDigFree(fd->dig);
00224     fd->dig = pgpDigLink(dig);
00225 /*@=assignexpose =castexpose @*/
00226 }
00227 
00230 /*@unused@*/ static inline
00231 /*@null@*/ pgpDig fdGetDig(FD_t fd)
00232         /*@*/
00233 {
00234     FDSANE(fd);
00235     /*@-compdef -retexpose -refcounttrans -usereleased @*/
00236     return fd->dig;
00237     /*@=compdef =retexpose =refcounttrans =usereleased @*/
00238 }
00239 
00242 /*@unused@*/ static inline
00243 void fdSetXAR(FD_t fd, rpmxar xar)
00244         /*@globals fileSystem @*/
00245         /*@modifies fd, xar, fileSystem @*/
00246 {
00247     FDSANE(fd);
00248 /*@-assignexpose -castexpose @*/
00249     fd->xar = rpmxarLink(xar, "fdSetXAR");
00250 /*@=assignexpose =castexpose @*/
00251 }
00252 
00255 /*@unused@*/ static inline
00256 /*@null@*/ rpmxar fdGetXAR(FD_t fd)
00257         /*@*/
00258 {
00259     FDSANE(fd);
00260     /*@-compdef -refcounttrans -retexpose -usereleased @*/
00261     return fd->xar;
00262     /*@=compdef =refcounttrans =retexpose =usereleased @*/
00263 }
00264 
00267 /*@unused@*/ static inline
00268 /*@null@*/ FDIO_t fdGetIo(FD_t fd)
00269         /*@*/
00270 {
00271     FDSANE(fd);
00272     return fd->fps[fd->nfps].io;
00273 }
00274 
00277 /*@-nullstate@*/ /* FIX: io may be NULL */
00278 /*@unused@*/ static inline
00279 void fdSetIo(FD_t fd, /*@kept@*/ /*@null@*/ FDIO_t io)
00280         /*@modifies fd @*/
00281 {
00282     FDSANE(fd);
00283     /*@-assignexpose@*/
00284     fd->fps[fd->nfps].io = io;
00285     /*@=assignexpose@*/
00286 }
00287 /*@=nullstate@*/
00288 
00291 /*@unused@*/ static inline
00292 /*@exposed@*/ /*@dependent@*/ /*@null@*/ FILE * fdGetFILE(FD_t fd)
00293         /*@*/
00294 {
00295     FDSANE(fd);
00296     /*@+voidabstract@*/
00297     return ((FILE *)fd->fps[fd->nfps].fp);
00298     /*@=voidabstract@*/
00299 }
00300 
00303 /*@unused@*/ static inline
00304 /*@exposed@*/ /*@dependent@*/ /*@null@*/ void * fdGetFp(FD_t fd)
00305         /*@*/
00306 {
00307     FDSANE(fd);
00308     return fd->fps[fd->nfps].fp;
00309 }
00310 
00313 /*@-nullstate@*/ /* FIX: fp may be NULL */
00314 /*@unused@*/ static inline
00315 void fdSetFp(FD_t fd, /*@kept@*/ /*@null@*/ void * fp)
00316         /*@modifies fd @*/
00317 {
00318     FDSANE(fd);
00319     /*@-assignexpose@*/
00320     fd->fps[fd->nfps].fp = fp;
00321     /*@=assignexpose@*/
00322 }
00323 /*@=nullstate@*/
00324 
00327 /*@unused@*/ static inline
00328 int fdGetFdno(FD_t fd)
00329         /*@*/
00330 {
00331     FDSANE(fd);
00332     return fd->fps[fd->nfps].fdno;
00333 }
00334 
00337 /*@unused@*/ static inline
00338 void fdSetFdno(FD_t fd, int fdno)
00339         /*@modifies fd @*/
00340 {
00341     FDSANE(fd);
00342     fd->fps[fd->nfps].fdno = fdno;
00343 }
00344 
00347 /*@unused@*/ static inline
00348 void fdSetContentLength(FD_t fd, ssize_t contentLength)
00349         /*@modifies fd @*/
00350 {
00351     FDSANE(fd);
00352     fd->contentLength = fd->bytesRemain = contentLength;
00353 }
00354 
00357 /*@unused@*/ static inline
00358 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
00359         /*@modifies fd @*/
00360 {
00361     FDSANE(fd);
00362     if (fd->nfps >= (int)(sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
00363         return;
00364     fd->nfps++;
00365     fdSetIo(fd, io);
00366     fdSetFp(fd, fp);
00367     fdSetFdno(fd, fdno);
00368 }
00369 
00372 /*@unused@*/ static inline
00373 void fdPop(FD_t fd)
00374         /*@modifies fd @*/
00375 {
00376     FDSANE(fd);
00377     if (fd->nfps < 0) return;
00378     fdSetIo(fd, NULL);
00379     fdSetFp(fd, NULL);
00380     fdSetFdno(fd, -1);
00381     fd->nfps--;
00382 }
00383 
00386 /*@unused@*/ static inline /*@null@*/
00387 rpmop fdstat_op(/*@null@*/ FD_t fd, fdOpX opx)
00388         /*@*/
00389 {
00390     rpmop op = NULL;
00391 
00392     if (fd != NULL && fd->stats != NULL && (int)opx >= 0 && opx < FDSTAT_MAX)
00393         op = fd->stats->ops + opx;
00394     return op;
00395 }
00396 
00399 /*@unused@*/ static inline
00400 void fdstat_enter(/*@null@*/ FD_t fd, int opx)
00401         /*@globals internalState @*/
00402         /*@modifies internalState @*/
00403 {
00404     if (fd == NULL) return;
00405     if (fd->stats != NULL)
00406         (void) rpmswEnter(fdstat_op(fd, opx), 0);
00407 }
00408 
00411 /*@unused@*/ static inline
00412 void fdstat_exit(/*@null@*/ FD_t fd, int opx, ssize_t rc)
00413         /*@globals internalState @*/
00414         /*@modifies fd, internalState @*/
00415 {
00416     if (fd == NULL) return;
00417     if (rc == -1)
00418         fd->syserrno = errno;
00419     else if (rc > 0 && fd->bytesRemain > 0)
00420         switch (opx) {
00421         case FDSTAT_READ:
00422         case FDSTAT_WRITE:
00423         fd->bytesRemain -= rc;
00424             break;
00425         default:
00426             break;
00427         }
00428     if (fd->stats != NULL)
00429         (void) rpmswExit(fdstat_op(fd, opx), rc);
00430 }
00431 
00434 /*@unused@*/ static inline
00435 void fdstat_print(/*@null@*/ FD_t fd, const char * msg, FILE * fp)
00436         /*@globals fileSystem @*/
00437         /*@modifies *fp, fileSystem @*/
00438 {
00439     static int usec_scale = (1000*1000);
00440     int opx;
00441 
00442     if (fd == NULL || fd->stats == NULL) return;
00443     for (opx = 0; opx < 4; opx++) {
00444         rpmop op = &fd->stats->ops[opx];
00445         if (op->count <= 0) continue;
00446         switch (opx) {
00447         case FDSTAT_READ:
00448             if (msg != NULL) fprintf(fp, "%s:", msg);
00449             fprintf(fp, "%8d reads, %8lu total bytes in %d.%06d secs\n",
00450                 op->count, (unsigned long)op->bytes,
00451                 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
00452             /*@switchbreak@*/ break;
00453         case FDSTAT_WRITE:
00454             if (msg != NULL) fprintf(fp, "%s:", msg);
00455             fprintf(fp, "%8d writes, %8lu total bytes in %d.%06d secs\n",
00456                 op->count, (unsigned long)op->bytes,
00457                 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
00458             /*@switchbreak@*/ break;
00459         case FDSTAT_SEEK:
00460             /*@switchbreak@*/ break;
00461         case FDSTAT_CLOSE:
00462             /*@switchbreak@*/ break;
00463         }
00464     }
00465 }
00466 
00469 /*@unused@*/ static inline
00470 void fdSetSyserrno(FD_t fd, int syserrno, /*@kept@*/ const void * errcookie)
00471         /*@modifies fd @*/
00472 {
00473     FDSANE(fd);
00474     fd->syserrno = syserrno;
00475     /*@-assignexpose@*/
00476     fd->errcookie = errcookie;
00477     /*@=assignexpose@*/
00478 }
00479 
00482 /*@unused@*/ static inline
00483 int fdGetRdTimeoutSecs(FD_t fd)
00484         /*@*/
00485 {
00486     FDSANE(fd);
00487     return fd->rd_timeoutsecs;
00488 }
00489 
00492 /*@unused@*/ static inline
00493 unsigned long long fdGetCpioPos(FD_t fd)
00494         /*@*/
00495 {
00496     FDSANE(fd);
00497     return fd->fd_cpioPos;
00498 }
00499 
00502 /*@unused@*/ static inline
00503 void fdSetCpioPos(FD_t fd, long int cpioPos)
00504         /*@modifies fd @*/
00505 {
00506     FDSANE(fd);
00507     fd->fd_cpioPos = cpioPos;
00508 }
00509 
00512 /*@mayexit@*/ /*@unused@*/ static inline
00513 FD_t c2f(/*@null@*/ void * cookie)
00514         /*@*/
00515 {
00516     /*@-castexpose@*/
00517     FD_t fd = (FD_t) cookie;
00518     /*@=castexpose@*/
00519     FDSANE(fd);
00520     /*@-refcounttrans -retalias@*/ return fd; /*@=refcounttrans =retalias@*/
00521 }
00522 
00526 /*@unused@*/ static inline
00527 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
00528         /*@globals internalState @*/
00529         /*@modifies fd, internalState @*/
00530 {
00531 /*@+voidabstract@*/
00532     fd->digests = xrealloc(fd->digests,
00533                         (fd->ndigests + 1) * sizeof(*fd->digests));
00534 /*@=voidabstract@*/
00535     fdstat_enter(fd, FDSTAT_DIGEST);
00536     fd->digests[fd->ndigests++] = rpmDigestInit(hashalgo, flags);
00537     fdstat_exit(fd, FDSTAT_DIGEST, 0);
00538 }
00539 
00543 /*@unused@*/ static inline
00544 void fdInitHmac(FD_t fd, const void * key, size_t keylen)
00545         /*@globals internalState @*/
00546         /*@modifies internalState @*/
00547 {
00548     if (fd->digests != NULL && fd->ndigests > 0 && key != NULL)
00549         (void) rpmHmacInit(fd->digests[fd->ndigests-1], key, keylen);
00550 }
00551 
00555 /*@unused@*/ static inline
00556 void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen)
00557         /*@globals internalState @*/
00558         /*@modifies fd, internalState @*/
00559 {
00560     int i;
00561 
00562   if (fd->ndigests > 0 && buf != NULL && buflen > 0) {
00563     fdstat_enter(fd, FDSTAT_DIGEST);
00564 #if defined(_OPENMP)
00565 #pragma omp parallel for if (fd->ndigests > 1)
00566 #endif
00567     for (i = fd->ndigests - 1; i >= 0; i--) {
00568         DIGEST_CTX ctx = fd->digests[i];
00569         if (ctx == NULL)
00570             continue;
00571         (void) rpmDigestUpdate(ctx, buf, buflen);
00572     }
00573     fdstat_exit(fd, FDSTAT_DIGEST, buflen);
00574   }
00575 }
00576 
00579 /*@unused@*/ static inline
00580 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo,
00581                 /*@null@*/ /*@out@*/ void * datap,
00582                 /*@null@*/ /*@out@*/ size_t * lenp,
00583                 int asAscii)
00584         /*@globals internalState @*/
00585         /*@modifies fd, *datap, *lenp, internalState @*/
00586 {
00587     int i = -1;
00588 
00589   if (fd->ndigests > 0) {
00590     fdstat_enter(fd, FDSTAT_DIGEST);
00591     for (i = fd->ndigests - 1; i >= 0; i--) {
00592         DIGEST_CTX ctx = fd->digests[i];
00593         if (ctx == NULL)
00594             continue;
00595         if (rpmDigestAlgo(ctx) != hashalgo)
00596             continue;
00597         fd->digests[i] = NULL;
00598         (void) rpmDigestFinal(ctx, datap, lenp, asAscii);
00599         break;
00600     }
00601     fdstat_exit(fd, FDSTAT_DIGEST, 0);
00602   }
00603     if (i < 0) {
00604         if (datap != NULL) *(void **)datap = NULL;
00605         if (lenp != NULL) *lenp = 0;
00606     }
00607 }
00608 
00611 /*@-mustmod@*/
00612 /*@unused@*/ static inline
00613 void fdStealDigest(FD_t fd, pgpDig dig)
00614         /*@modifies fd, dig @*/
00615 {
00616     int i;
00617 /*@-type@*/     /* FIX: getters for pgpDig internals */
00618     if (fd->ndigests > 0)
00619     for (i = fd->ndigests - 1; i >= 0; i--) {
00620         DIGEST_CTX ctx = fd->digests[i];
00621         if (ctx != NULL)
00622         switch (rpmDigestAlgo(ctx)) {
00623         case PGPHASHALGO_MD5:
00624 assert(dig->md5ctx == NULL);
00625 /*@-assignexpose -onlytrans@*/
00626             dig->md5ctx = ctx;
00627 /*@=assignexpose =onlytrans@*/
00628             fd->digests[i] = NULL;
00629             /*@switchbreak@*/ break;
00630         case PGPHASHALGO_SHA1:
00631         case PGPHASHALGO_RIPEMD160:
00632         case PGPHASHALGO_SHA256:
00633         case PGPHASHALGO_SHA384:
00634         case PGPHASHALGO_SHA512:
00635 assert(dig->sha1ctx == NULL);
00636 /*@-assignexpose -onlytrans@*/
00637             dig->sha1ctx = ctx;
00638 /*@=assignexpose =onlytrans@*/
00639             fd->digests[i] = NULL;
00640             /*@switchbreak@*/ break;
00641         default:
00642             /*@switchbreak@*/ break;
00643         }
00644     }
00645 /*@=type@*/
00646 }
00647 /*@=mustmod@*/
00648 
00649 /*@-shadow@*/
00652 /*@unused@*/ static inline
00653 int fdFileno(/*@null@*/ void * cookie)
00654         /*@*/
00655 {
00656     FD_t fd;
00657     if (cookie == NULL) return -2;
00658     fd = c2f(cookie);
00659     return fd->fps[0].fdno;
00660 }
00661 /*@=shadow@*/
00662 
00663 #ifdef __cplusplus
00664 }
00665 #endif
00666 
00667 #endif  /* H_RPMIO_INTERNAL */