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