# rpmio/rpmio_internal.h

Go to the documentation of this file.

    00001 #ifndef H_RPMIO_INTERNAL
    00002 #define H_RPMIO_INTERNAL
    00003
    00009 #include <rpmio.h>
    00010 #include <rpmurl.h>
    00011 #include <rpmpgp.h>
    00012
    00015 typedef struct _FDSTACK_s {
    00016     FDIO_t              io;
    00017 /*@dependent@*/ void *  fp;
    00018     int                 fdno;
    00019 } FDSTACK_t;
    00020
    00024 typedef struct {
    00025     int                 count;
    00026     off_t               bytes;
    00027     time_t              msecs;
    00028 } OPSTAT_t;
    00029
    00033 enum FDSTAT_e {
    00034     FDSTAT_READ         = 0,
    00035     FDSTAT_WRITE        = 1,
    00036     FDSTAT_SEEK         = 2,
    00037     FDSTAT_CLOSE        = 3
    00038 };
    00039
    00043 typedef /*@abstract@*/ struct {
    00044     struct timeval      create;
    00045     struct timeval      begin;
    00046     OPSTAT_t            ops[4];
    00047 } * FDSTAT_t;
    00048
    00052 typedef enum rpmDigestFlags_e {
    00053     RPMDIGEST_NONE      = 0
    00054 } rpmDigestFlags;
    00055
    00058 typedef struct _FDDIGEST_s {
    00059     pgpHashAlgo         hashalgo;
    00060     DIGEST_CTX          hashctx;
    00061 } * FDDIGEST_t;
    00062
    00068 /*@only@*/ /*@unused@*/
    00069 DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
    00070         /*@*/;
    00071
    00078 /*@only@*/
    00079 DIGEST_CTX rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
    00080         /*@*/;
    00081
    00089 int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
    00090         /*@modifies ctx @*/;
    00091
    00103 int rpmDigestFinal(/*@only@*/ DIGEST_CTX ctx,
    00104         /*@null@*/ /*@out@*/ void ** datap,
    00105         /*@null@*/ /*@out@*/ size_t * lenp, int asAscii)
    00106                 /*@modifies *datap, *lenp @*/;
    00107
    00111 struct _FD_s {
    00112 /*@refs@*/ int  nrefs;
    00113     int         flags;
    00114 #define RPMIO_DEBUG_IO          0x40000000
    00115 #define RPMIO_DEBUG_REFS        0x20000000
    00116     int         magic;
    00117 #define FDMAGIC                 0x04463138
    00118     int         nfps;
    00119     FDSTACK_t   fps[8];
    00120     int         urlType;        /* ufdio: */
    00121
    00122 /*@dependent@*/ void *  url;    /* ufdio: URL info */
    00123     int         rd_timeoutsecs; /* ufdRead: per FD_t timer */
    00124     ssize_t     bytesRemain;    /* ufdio: */
    00125     ssize_t     contentLength;  /* ufdio: */
    00126     int         persist;        /* ufdio: */
    00127     int         wr_chunked;     /* ufdio: */
    00128
    00129     int         syserrno;       /* last system errno encountered */
    00130 /*@observer@*/ const void *errcookie;   /* gzdio/bzdio/ufdio: */
    00131
    00132     FDSTAT_t    stats;          /* I/O statistics */
    00133
    00134     int         ndigests;
    00135 #define FDDIGEST_MAX    4
    00136     struct _FDDIGEST_s  digests[FDDIGEST_MAX];
    00137
    00138     int         ftpFileDoneNeeded; /* ufdio: (FTP) */
    00139     unsigned int firstFree;     /* fadio: */
    00140     long int    fileSize;       /* fadio: */
    00141     long int    fd_cpioPos;     /* cpio: */
    00142 };
    00143 /*@access FD_t@*/
    00144
    00145 #define FDSANE(fd)      assert(fd && fd->magic == FDMAGIC)
    00146
    00147 /*@-redecl@*/
    00148 /*@unchecked@*/
    00149 extern int _rpmio_debug;
    00150 /*@=redecl@*/
    00151
    00152 #define DBG(_f, _m, _x) \
    00153     if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x
    00154
    00155 #define DBGIO(_f, _x)   DBG((_f), RPMIO_DEBUG_IO, _x)
    00156 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
    00157
    00158 #ifdef __cplusplus
    00159 extern "C" {
    00160 #endif
    00161
    00164 int fdFgets(FD_t fd, char * buf, size_t len)
    00165         /*@globals errno, fileSystem @*/
    00166         /*@modifies *buf, fd, errno, fileSystem @*/;
    00167
    00170 /*@null@*/ FD_t ftpOpen(const char *url, /*@unused@*/ int flags,
    00171                 /*@unused@*/ mode_t mode, /*@out@*/ urlinfo *uret)
    00172         /*@globals fileSystem @*/
    00173         /*@modifies *uret, fileSystem @*/;
    00174
    00177 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
    00178         /*@globals fileSystem @*/
    00179         /*@modifies data, fileSystem @*/;
    00180
    00183 int ftpCmd(const char * cmd, const char * url, const char * arg2)
    00184         /*@globals fileSystem @*/
    00185         /*@modifies fileSystem @*/;
    00186
    00189 int ufdClose( /*@only@*/ void * cookie)
    00190         /*@globals fileSystem @*/
    00191         /*@modifies cookie, fileSystem @*/;
    00192
    00195 /*@unused@*/ static inline
    00196 /*@null@*/ const FDIO_t fdGetIo(FD_t fd)
    00197         /*@*/
    00198 {
    00199     FDSANE(fd);
    00200     return fd->fps[fd->nfps].io;
    00201 }
    00202
    00205 /*@-nullstate@*/ /* FIX: io may be NULL */
    00206 /*@unused@*/ static inline
    00207 void fdSetIo(FD_t fd, /*@kept@*/ /*@null@*/ FDIO_t io)
    00208         /*@modifies fd @*/
    00209 {
    00210     FDSANE(fd);
    00211     /*@-assignexpose@*/
    00212     fd->fps[fd->nfps].io = io;
    00213     /*@=assignexpose@*/
    00214 }
    00215 /*@=nullstate@*/
    00216
    00219 /*@unused@*/ static inline
    00220 /*@exposed@*/ /*@dependent@*/ /*@null@*/ FILE * fdGetFILE(FD_t fd)
    00221         /*@*/
    00222 {
    00223     FDSANE(fd);
    00224     /*@+voidabstract@*/
    00225     return ((FILE *)fd->fps[fd->nfps].fp);
    00226     /*@=voidabstract@*/
    00227 }
    00228
    00231 /*@unused@*/ static inline
    00232 /*@exposed@*/ /*@dependent@*/ /*@null@*/ void * fdGetFp(FD_t fd)
    00233         /*@*/
    00234 {
    00235     FDSANE(fd);
    00236     return fd->fps[fd->nfps].fp;
    00237 }
    00238
    00241 /*@-nullstate@*/ /* FIX: fp may be NULL */
    00242 /*@unused@*/ static inline
    00243 void fdSetFp(FD_t fd, /*@kept@*/ /*@null@*/ void * fp)
    00244         /*@modifies fd @*/
    00245 {
    00246     FDSANE(fd);
    00247     /*@-assignexpose@*/
    00248     fd->fps[fd->nfps].fp = fp;
    00249     /*@=assignexpose@*/
    00250 }
    00251 /*@=nullstate@*/
    00252
    00255 /*@unused@*/ static inline
    00256 int fdGetFdno(FD_t fd)
    00257         /*@*/
    00258 {
    00259     FDSANE(fd);
    00260     return fd->fps[fd->nfps].fdno;
    00261 }
    00262
    00265 /*@unused@*/ static inline
    00266 void fdSetFdno(FD_t fd, int fdno)
    00267         /*@modifies fd @*/
    00268 {
    00269     FDSANE(fd);
    00270     fd->fps[fd->nfps].fdno = fdno;
    00271 }
    00272
    00275 /*@unused@*/ static inline
    00276 void fdSetContentLength(FD_t fd, ssize_t contentLength)
    00277         /*@modifies fd @*/
    00278 {
    00279     FDSANE(fd);
    00280     fd->contentLength = fd->bytesRemain = contentLength;
    00281 }
    00282
    00285 /*@unused@*/ static inline
    00286 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
    00287         /*@modifies fd @*/
    00288 {
    00289     FDSANE(fd);
    00290     if (fd->nfps >= (sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
    00291         return;
    00292     fd->nfps++;
    00293     fdSetIo(fd, io);
    00294     fdSetFp(fd, fp);
    00295     fdSetFdno(fd, fdno);
    00296 }
    00297
    00300 /*@unused@*/ static inline void fdPop(FD_t fd)
    00301         /*@modifies fd @*/
    00302 {
    00303     FDSANE(fd);
    00304     if (fd->nfps < 0) return;
    00305     fdSetIo(fd, NULL);
    00306     fdSetFp(fd, NULL);
    00307     fdSetFdno(fd, -1);
    00308     fd->nfps--;
    00309 }
    00310
    00313 /*@unused@*/ static inline void fdstat_enter(/*@null@*/ FD_t fd, int opx)
    00314         /*@modifies fd @*/
    00315 {
    00316     if (fd == NULL || fd->stats == NULL) return;
    00317     fd->stats->ops[opx].count++;
    00318     (void) gettimeofday(&fd->stats->begin, NULL);
    00319 }
    00320
    00323 /*@unused@*/ static inline
    00324 time_t tvsub(/*@null@*/ const struct timeval * etv,
    00325                 /*@null@*/ const struct timeval * btv)
    00326         /*@*/
    00327 {
    00328     time_t secs, usecs;
    00329     if (etv == NULL  || btv == NULL) return 0;
    00330     secs = etv->tv_sec - btv->tv_sec;
    00331     for (usecs = etv->tv_usec - btv->tv_usec; usecs < 0; usecs += 1000000)
    00332         secs++;
    00333     return ((secs * 1000) + (usecs/1000));
    00334 }
    00335
    00338 /*@unused@*/ static inline
    00339 void fdstat_exit(/*@null@*/ FD_t fd, int opx, ssize_t rc)
    00340         /*@modifies fd @*/
    00341 {
    00342     struct timeval end;
    00343     if (fd == NULL) return;
    00344     if (rc == -1) fd->syserrno = errno;
    00345     if (fd->stats == NULL) return;
    00346     (void) gettimeofday(&end, NULL);
    00347     if (rc >= 0) {
    00348         switch(opx) {
    00349         case FDSTAT_SEEK:
    00350             fd->stats->ops[opx].bytes = rc;
    00351             break;
    00352         default:
    00353             fd->stats->ops[opx].bytes += rc;
    00354             if (fd->bytesRemain > 0) fd->bytesRemain -= rc;
    00355             break;
    00356         }
    00357     }
    00358     fd->stats->ops[opx].msecs += tvsub(&end, &fd->stats->begin);
    00359     fd->stats->begin = end;     /* structure assignment */
    00360 }
    00361
    00364 /*@unused@*/ static inline
    00365 void fdstat_print(/*@null@*/ FD_t fd, const char * msg, FILE * fp)
    00366         /*@globals fileSystem @*/
    00367         /*@modifies *fp, fileSystem @*/
    00368 {
    00369     int opx;
    00370     if (fd == NULL || fd->stats == NULL) return;
    00371     for (opx = 0; opx < 4; opx++) {
    00372         OPSTAT_t *ops = &fd->stats->ops[opx];
    00373         if (ops->count <= 0) continue;
    00374         switch (opx) {
    00375         case FDSTAT_READ:
    00376             if (msg) fprintf(fp, "%s:", msg);
    00377             fprintf(fp, "%8d reads, %8ld total bytes in %d.%03d secs\n",
    00378                 ops->count, (long)ops->bytes,
    00379                 (int)(ops->msecs/1000), (int)(ops->msecs%1000));
    00380             /*@switchbreak@*/ break;
    00381         case FDSTAT_WRITE:
    00382             if (msg) fprintf(fp, "%s:", msg);
    00383             fprintf(fp, "%8d writes, %8ld total bytes in %d.%03d secs\n",
    00384                 ops->count, (long)ops->bytes,
    00385                 (int)(ops->msecs/1000), (int)(ops->msecs%1000));
    00386             /*@switchbreak@*/ break;
    00387         case FDSTAT_SEEK:
    00388             /*@switchbreak@*/ break;
    00389         case FDSTAT_CLOSE:
    00390             /*@switchbreak@*/ break;
    00391         }
    00392     }
    00393 }
    00394
    00397 /*@unused@*/ static inline
    00398 void fdSetSyserrno(FD_t fd, int syserrno, /*@kept@*/ const void * errcookie)
    00399         /*@modifies fd @*/
    00400 {
    00401     FDSANE(fd);
    00402     fd->syserrno = syserrno;
    00403     /*@-assignexpose@*/
    00404     fd->errcookie = errcookie;
    00405     /*@=assignexpose@*/
    00406 }
    00407
    00410 /*@unused@*/ static inline
    00411 int fdGetRdTimeoutSecs(FD_t fd)
    00412         /*@*/
    00413 {
    00414     FDSANE(fd);
    00415     return fd->rd_timeoutsecs;
    00416 }
    00417
    00420 /*@unused@*/ static inline
    00421 long int fdGetCpioPos(FD_t fd)
    00422         /*@*/
    00423 {
    00424     FDSANE(fd);
    00425     return fd->fd_cpioPos;
    00426 }
    00427
    00430 /*@unused@*/ static inline
    00431 void fdSetCpioPos(FD_t fd, long int cpioPos)
    00432         /*@modifies fd @*/
    00433 {
    00434     FDSANE(fd);
    00435     fd->fd_cpioPos = cpioPos;
    00436 }
    00437
    00440 /*@mayexit@*/ /*@unused@*/ static inline
    00441 FD_t c2f(/*@null@*/ void * cookie)
    00442         /*@*/
    00443 {
    00444     /*@-castexpose@*/
    00445     FD_t fd = (FD_t) cookie;
    00446     /*@=castexpose@*/
    00447     FDSANE(fd);
    00448     /*@-refcounttrans -retalias@*/ return fd; /*@=refcounttrans =retalias@*/
    00449 }
    00450
    00454 /*@unused@*/ static inline
    00455 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
    00456         /*@modifies fd @*/
    00457 {
    00458     FDDIGEST_t fddig = fd->digests + fd->ndigests;
    00459     if (fddig != (fd->digests + FDDIGEST_MAX)) {
    00460         fd->ndigests++;
    00461         fddig->hashalgo = hashalgo;
    00462         fddig->hashctx = rpmDigestInit(hashalgo, flags);
    00463     }
    00464 }
    00465
    00469 /*@unused@*/ static inline
    00470 void fdUpdateDigests(FD_t fd, const byte * buf, ssize_t buflen)
    00471         /*@modifies fd @*/
    00472 {
    00473     int i;
    00474
    00475     if (buf != NULL && buflen > 0)
    00476     for (i = fd->ndigests - 1; i >= 0; i--) {
    00477         FDDIGEST_t fddig = fd->digests + i;
    00478         if (fddig->hashctx == NULL)
    00479             continue;
    00480         (void) rpmDigestUpdate(fddig->hashctx, buf, buflen);
    00481     }
    00482 }
    00483
    00486 /*@unused@*/ static inline
    00487 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo,
    00488                 /*@null@*/ /*@out@*/ void ** datap,
    00489                 /*@null@*/ /*@out@*/ size_t * lenp,
    00490                 int asAscii)
    00491         /*@modifies fd, *datap, *lenp @*/
    00492 {
    00493     int imax = -1;
    00494     int i;
    00495
    00496     for (i = fd->ndigests - 1; i >= 0; i--) {
    00497         FDDIGEST_t fddig = fd->digests + i;
    00498         if (fddig->hashctx == NULL)
    00499             continue;
    00500         if (i > imax) imax = i;
    00501         if (fddig->hashalgo != hashalgo)
    00502             continue;
    00503         (void) rpmDigestFinal(fddig->hashctx, datap, lenp, asAscii);
    00504         fddig->hashctx = NULL;
    00505         break;
    00506     }
    00507     if (i < 0) {
    00508         if (datap) *datap = NULL;
    00509         if (lenp) *lenp = 0;
    00510         return;
    00511     } else if (i == imax)
    00512         fd->ndigests = imax - 1;
    00513     else
    00514         fd->ndigests = imax;
    00515 }
    00516
    00517 /*@-shadow@*/
    00520 /*@unused@*/ static inline
    00521 int fdFileno(/*@null@*/ void * cookie)
    00522         /*@*/
    00523 {
    00524     FD_t fd;
    00525     if (cookie == NULL) return -2;
    00526     fd = c2f(cookie);
    00527     return fd->fps[0].fdno;
    00528 }
    00529 /*@=shadow@*/
    00530
    00533 int rpmioSlurp(const char * fn,
    00534                 /*@out@*/ const byte ** bp, /*@out@*/ ssize_t * blenp)
    00535         /*@globals fileSystem @*/
    00536         /*@modifies *bp, *blenp, fileSystem @*/;
    00537
    00538 #ifdef __cplusplus
    00539 }
    00540 #endif
    00541
    00542 #endif  /* H_RPMIO_INTERNAL */