rpm 5.3.7
|
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 /* FIXME: 00565 #if defined(_OPENMP) 00566 #pragma omp parallel for 00567 #endif 00568 */ 00569 for (i = fd->ndigests - 1; i >= 0; i--) { 00570 DIGEST_CTX ctx = fd->digests[i]; 00571 if (ctx == NULL) 00572 continue; 00573 (void) rpmDigestUpdate(ctx, buf, buflen); 00574 } 00575 fdstat_exit(fd, FDSTAT_DIGEST, buflen); 00576 } 00577 } 00578 00581 /*@unused@*/ static inline 00582 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo, 00583 /*@null@*/ /*@out@*/ void * datap, 00584 /*@null@*/ /*@out@*/ size_t * lenp, 00585 int asAscii) 00586 /*@globals internalState @*/ 00587 /*@modifies fd, *datap, *lenp, internalState @*/ 00588 { 00589 int i = -1; 00590 00591 if (fd->ndigests > 0) { 00592 fdstat_enter(fd, FDSTAT_DIGEST); 00593 for (i = fd->ndigests - 1; i >= 0; i--) { 00594 DIGEST_CTX ctx = fd->digests[i]; 00595 if (ctx == NULL) 00596 continue; 00597 if (rpmDigestAlgo(ctx) != hashalgo) 00598 continue; 00599 fd->digests[i] = NULL; 00600 (void) rpmDigestFinal(ctx, datap, lenp, asAscii); 00601 break; 00602 } 00603 fdstat_exit(fd, FDSTAT_DIGEST, 0); 00604 } 00605 if (i < 0) { 00606 if (datap != NULL) *(void **)datap = NULL; 00607 if (lenp != NULL) *lenp = 0; 00608 } 00609 } 00610 00613 /*@-mustmod@*/ 00614 /*@unused@*/ static inline 00615 void fdStealDigest(FD_t fd, pgpDig dig) 00616 /*@modifies fd, dig @*/ 00617 { 00618 int i; 00619 /*@-type@*/ /* FIX: getters for pgpDig internals */ 00620 if (fd->ndigests > 0) 00621 for (i = fd->ndigests - 1; i >= 0; i--) { 00622 DIGEST_CTX ctx = fd->digests[i]; 00623 if (ctx != NULL) 00624 switch (rpmDigestAlgo(ctx)) { 00625 case PGPHASHALGO_MD5: 00626 assert(dig->md5ctx == NULL); 00627 /*@-assignexpose -onlytrans@*/ 00628 dig->md5ctx = ctx; 00629 /*@=assignexpose =onlytrans@*/ 00630 fd->digests[i] = NULL; 00631 /*@switchbreak@*/ break; 00632 case PGPHASHALGO_SHA1: 00633 case PGPHASHALGO_RIPEMD160: 00634 case PGPHASHALGO_SHA256: 00635 case PGPHASHALGO_SHA384: 00636 case PGPHASHALGO_SHA512: 00637 assert(dig->sha1ctx == NULL); 00638 /*@-assignexpose -onlytrans@*/ 00639 dig->sha1ctx = ctx; 00640 /*@=assignexpose =onlytrans@*/ 00641 fd->digests[i] = NULL; 00642 /*@switchbreak@*/ break; 00643 default: 00644 /*@switchbreak@*/ break; 00645 } 00646 } 00647 /*@=type@*/ 00648 } 00649 /*@=mustmod@*/ 00650 00651 /*@-shadow@*/ 00654 /*@unused@*/ static inline 00655 int fdFileno(/*@null@*/ void * cookie) 00656 /*@*/ 00657 { 00658 FD_t fd; 00659 if (cookie == NULL) return -2; 00660 fd = c2f(cookie); 00661 return fd->fps[0].fdno; 00662 } 00663 /*@=shadow@*/ 00664 00665 #ifdef __cplusplus 00666 } 00667 #endif 00668 00669 #endif /* H_RPMIO_INTERNAL */