00001 #ifndef H_RPMIO_INTERNAL
00002 #define H_RPMIO_INTERNAL
00003
00008 #include <rpmio.h>
00009 #include <rpmurl.h>
00010
00011 #define _RPMPGP_INTERNAL
00012 #include <rpmpgp.h>
00013
00014 #include <rpmxar.h>
00015
00018 typedef struct _FDSTACK_s {
00019
00020 FDIO_t io;
00021
00022 void * fp;
00023 int fdno;
00024 } FDSTACK_t;
00025
00029 typedef enum fdOpX_e {
00030 FDSTAT_READ = 0,
00031 FDSTAT_WRITE = 1,
00032 FDSTAT_SEEK = 2,
00033 FDSTAT_CLOSE = 3,
00034 FDSTAT_DIGEST = 4,
00035 FDSTAT_MAX = 5
00036 } fdOpX;
00037
00041 typedef struct {
00042 struct rpmop_s ops[FDSTAT_MAX];
00043 } * FDSTAT_t;
00044
00047 typedef struct _FDDIGEST_s {
00048 pgpHashAlgo hashalgo;
00049 DIGEST_CTX hashctx;
00050 } * FDDIGEST_t;
00051
00055 struct _FD_s {
00056
00057 int nrefs;
00058 int flags;
00059 #define RPMIO_DEBUG_IO 0x40000000
00060 #define RPMIO_DEBUG_REFS 0x20000000
00061 int magic;
00062 #define FDMAGIC 0x04463138
00063 int nfps;
00064 FDSTACK_t fps[8];
00065 int urlType;
00066
00067
00068 void * url;
00069
00070 void * req;
00071
00072 int rd_timeoutsecs;
00073 ssize_t bytesRemain;
00074 ssize_t contentLength;
00075 int persist;
00076 int wr_chunked;
00077
00078 int syserrno;
00079
00080 const void *errcookie;
00081
00082
00083 const char *opath;
00084 int oflags;
00085 mode_t omode;
00086
00087
00088 rpmxar xar;
00089
00090 pgpDig dig;
00091
00092 FDSTAT_t stats;
00093
00094 int ndigests;
00095 #define FDDIGEST_MAX 4
00096 struct _FDDIGEST_s digests[FDDIGEST_MAX];
00097
00098 int ftpFileDoneNeeded;
00099 unsigned long long fd_cpioPos;
00100 };
00101
00102
00103 #define FDSANE(fd) assert(fd && fd->magic == FDMAGIC)
00104
00105
00106
00107 extern int _rpmio_debug;
00108
00109
00110
00111
00112 extern int _av_debug;
00113
00114
00115
00116
00117 extern int _ftp_debug;
00118
00119
00120
00121
00122 extern int _dav_debug;
00123
00124
00125 #define DBG(_f, _m, _x) \
00126 \
00127 if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x \
00128
00129
00130 #if defined(__LCLINT__XXX)
00131 #define DBGIO(_f, _x)
00132 #define DBGREFS(_f, _x)
00133 #else
00134 #define DBGIO(_f, _x) DBG((_f), RPMIO_DEBUG_IO, _x)
00135 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
00136 #endif
00137
00138 #ifdef __cplusplus
00139 extern "C" {
00140 #endif
00141
00144 int fdFgets(FD_t fd, char * buf, size_t len)
00145
00146 ;
00147
00150 FD_t ftpOpen(const char *url, int flags,
00151 mode_t mode, urlinfo *uret)
00152
00153 ;
00154
00157 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
00158
00159 ;
00160
00163 int ftpCmd(const char * cmd, const char * url, const char * arg2)
00164
00165 ;
00166
00169 int ufdClose( void * cookie)
00170
00171 ;
00172
00175 static inline
00176 void fdSetOpen(FD_t fd, const char * path, int flags, mode_t mode)
00177
00178 {
00179 FDSANE(fd);
00180 if (fd->opath != NULL) {
00181 free((void *)fd->opath);
00182 fd->opath = NULL;
00183 }
00184 fd->opath = xstrdup(path);
00185 fd->oflags = flags;
00186 fd->omode = mode;
00187 }
00188
00191 static inline
00192 const char * fdGetOPath(FD_t fd)
00193
00194 {
00195 FDSANE(fd);
00196 return fd->opath;
00197 }
00198
00201 static inline
00202 int fdGetOFlags(FD_t fd)
00203
00204 {
00205 FDSANE(fd);
00206 return fd->oflags;
00207 }
00208
00211 static inline
00212 mode_t fdGetOMode(FD_t fd)
00213
00214 {
00215 FDSANE(fd);
00216 return fd->omode;
00217 }
00218
00221 static inline
00222 void fdSetDig(FD_t fd, pgpDig dig)
00223
00224 {
00225 FDSANE(fd);
00226 fd->dig = pgpDigFree(fd->dig);
00227 fd->dig = pgpDigLink(dig, "fdSetDig");
00228 }
00229
00232 static inline
00233 pgpDig fdGetDig(FD_t fd)
00234
00235 {
00236 FDSANE(fd);
00237
00238 return fd->dig;
00239
00240 }
00241
00244 static inline
00245 void fdSetXAR(FD_t fd, rpmxar xar)
00246
00247 {
00248 FDSANE(fd);
00249 fd->xar = rpmxarLink(xar, "fdSetXAR");
00250 }
00251
00254 static inline
00255 rpmxar fdGetXAR(FD_t fd)
00256
00257 {
00258 FDSANE(fd);
00259
00260 return fd->xar;
00261
00262 }
00263
00266 static inline
00267 FDIO_t fdGetIo(FD_t fd)
00268
00269 {
00270 FDSANE(fd);
00271 return fd->fps[fd->nfps].io;
00272 }
00273
00276
00277 static inline
00278 void fdSetIo(FD_t fd, FDIO_t io)
00279
00280 {
00281 FDSANE(fd);
00282
00283 fd->fps[fd->nfps].io = io;
00284
00285 }
00286
00287
00290 static inline
00291 FILE * fdGetFILE(FD_t fd)
00292
00293 {
00294 FDSANE(fd);
00295
00296 return ((FILE *)fd->fps[fd->nfps].fp);
00297
00298 }
00299
00302 static inline
00303 void * fdGetFp(FD_t fd)
00304
00305 {
00306 FDSANE(fd);
00307 return fd->fps[fd->nfps].fp;
00308 }
00309
00312
00313 static inline
00314 void fdSetFp(FD_t fd, void * fp)
00315
00316 {
00317 FDSANE(fd);
00318
00319 fd->fps[fd->nfps].fp = fp;
00320
00321 }
00322
00323
00326 static inline
00327 int fdGetFdno(FD_t fd)
00328
00329 {
00330 FDSANE(fd);
00331 return fd->fps[fd->nfps].fdno;
00332 }
00333
00336 static inline
00337 void fdSetFdno(FD_t fd, int fdno)
00338
00339 {
00340 FDSANE(fd);
00341 fd->fps[fd->nfps].fdno = fdno;
00342 }
00343
00346 static inline
00347 void fdSetContentLength(FD_t fd, ssize_t contentLength)
00348
00349 {
00350 FDSANE(fd);
00351 fd->contentLength = fd->bytesRemain = contentLength;
00352 }
00353
00356 static inline
00357 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
00358
00359 {
00360 FDSANE(fd);
00361 if (fd->nfps >= (sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
00362 return;
00363 fd->nfps++;
00364 fdSetIo(fd, io);
00365 fdSetFp(fd, fp);
00366 fdSetFdno(fd, fdno);
00367 }
00368
00371 static inline
00372 void fdPop(FD_t fd)
00373
00374 {
00375 FDSANE(fd);
00376 if (fd->nfps < 0) return;
00377 fdSetIo(fd, NULL);
00378 fdSetFp(fd, NULL);
00379 fdSetFdno(fd, -1);
00380 fd->nfps--;
00381 }
00382
00385 static inline
00386 rpmop fdstat_op( FD_t fd, fdOpX opx)
00387
00388 {
00389 rpmop op = NULL;
00390
00391 if (fd != NULL && fd->stats != NULL && opx >= 0 && opx < FDSTAT_MAX)
00392 op = fd->stats->ops + opx;
00393 return op;
00394 }
00395
00398 static inline
00399 void fdstat_enter( FD_t fd, int opx)
00400
00401
00402 {
00403 if (fd == NULL) return;
00404 if (fd->stats != NULL)
00405 (void) rpmswEnter(fdstat_op(fd, opx), 0);
00406 }
00407
00410 static inline
00411 void fdstat_exit( FD_t fd, int opx, ssize_t rc)
00412
00413
00414 {
00415 if (fd == NULL) return;
00416 if (rc == -1)
00417 fd->syserrno = errno;
00418 else if (rc > 0 && fd->bytesRemain > 0)
00419 switch (opx) {
00420 case FDSTAT_READ:
00421 case FDSTAT_WRITE:
00422 fd->bytesRemain -= rc;
00423 break;
00424 default:
00425 break;
00426 }
00427 if (fd->stats != NULL)
00428 (void) rpmswExit(fdstat_op(fd, opx), rc);
00429 }
00430
00433 static inline
00434 void fdstat_print( FD_t fd, const char * msg, FILE * fp)
00435
00436
00437 {
00438 static int usec_scale = (1000*1000);
00439 int opx;
00440
00441 if (fd == NULL || fd->stats == NULL) return;
00442 for (opx = 0; opx < 4; opx++) {
00443 rpmop op = &fd->stats->ops[opx];
00444 if (op->count <= 0) continue;
00445 switch (opx) {
00446 case FDSTAT_READ:
00447 if (msg) fprintf(fp, "%s:", msg);
00448 fprintf(fp, "%8d reads, %8lu total bytes in %d.%06d secs\n",
00449 op->count, (unsigned long)op->bytes,
00450 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
00451 break;
00452 case FDSTAT_WRITE:
00453 if (msg) fprintf(fp, "%s:", msg);
00454 fprintf(fp, "%8d writes, %8lu total bytes in %d.%06d secs\n",
00455 op->count, (unsigned long)op->bytes,
00456 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
00457 break;
00458 case FDSTAT_SEEK:
00459 break;
00460 case FDSTAT_CLOSE:
00461 break;
00462 }
00463 }
00464 }
00465
00468 static inline
00469 void fdSetSyserrno(FD_t fd, int syserrno, const void * errcookie)
00470
00471 {
00472 FDSANE(fd);
00473 fd->syserrno = syserrno;
00474
00475 fd->errcookie = errcookie;
00476
00477 }
00478
00481 static inline
00482 int fdGetRdTimeoutSecs(FD_t fd)
00483
00484 {
00485 FDSANE(fd);
00486 return fd->rd_timeoutsecs;
00487 }
00488
00491 static inline
00492 unsigned long long fdGetCpioPos(FD_t fd)
00493
00494 {
00495 FDSANE(fd);
00496 return fd->fd_cpioPos;
00497 }
00498
00501 static inline
00502 void fdSetCpioPos(FD_t fd, long int cpioPos)
00503
00504 {
00505 FDSANE(fd);
00506 fd->fd_cpioPos = cpioPos;
00507 }
00508
00511 static inline
00512 FD_t c2f( void * cookie)
00513
00514 {
00515
00516 FD_t fd = (FD_t) cookie;
00517
00518 FDSANE(fd);
00519 return fd;
00520 }
00521
00525 static inline
00526 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
00527
00528
00529 {
00530 FDDIGEST_t fddig = fd->digests + fd->ndigests;
00531 if (fddig != (fd->digests + FDDIGEST_MAX)) {
00532 fd->ndigests++;
00533 fddig->hashalgo = hashalgo;
00534 fdstat_enter(fd, FDSTAT_DIGEST);
00535 fddig->hashctx = rpmDigestInit(hashalgo, flags);
00536 fdstat_exit(fd, FDSTAT_DIGEST, 0);
00537 }
00538 }
00539
00543 static inline
00544 void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen)
00545
00546
00547 {
00548 int i;
00549
00550 if (buf != NULL && buflen > 0)
00551 for (i = fd->ndigests - 1; i >= 0; i--) {
00552 FDDIGEST_t fddig = fd->digests + i;
00553 if (fddig->hashctx == NULL)
00554 continue;
00555 fdstat_enter(fd, FDSTAT_DIGEST);
00556 (void) rpmDigestUpdate(fddig->hashctx, buf, buflen);
00557 fdstat_exit(fd, FDSTAT_DIGEST, buflen);
00558 }
00559 }
00560
00563 static inline
00564 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo,
00565 void * datap,
00566 size_t * lenp,
00567 int asAscii)
00568
00569
00570 {
00571 int imax = -1;
00572 int i;
00573
00574 for (i = fd->ndigests - 1; i >= 0; i--) {
00575 FDDIGEST_t fddig = fd->digests + i;
00576 if (fddig->hashctx == NULL)
00577 continue;
00578 if (i > imax) imax = i;
00579 if (fddig->hashalgo != hashalgo)
00580 continue;
00581 fdstat_enter(fd, FDSTAT_DIGEST);
00582 (void) rpmDigestFinal(fddig->hashctx, datap, lenp, asAscii);
00583 fdstat_exit(fd, FDSTAT_DIGEST, 0);
00584 fddig->hashctx = NULL;
00585 break;
00586 }
00587 if (i < 0) {
00588 if (datap) *(void **)datap = NULL;
00589 if (lenp) *lenp = 0;
00590 }
00591
00592 fd->ndigests = imax;
00593 if (i < imax)
00594 fd->ndigests++;
00595 }
00596
00599
00600 static inline
00601 void fdStealDigest(FD_t fd, pgpDig dig)
00602
00603 {
00604 int i;
00605
00606 for (i = fd->ndigests - 1; i >= 0; i--) {
00607 FDDIGEST_t fddig = fd->digests + i;
00608 if (fddig->hashctx != NULL)
00609 switch (fddig->hashalgo) {
00610 case PGPHASHALGO_MD5:
00611 assert(dig->md5ctx == NULL);
00612
00613 dig->md5ctx = fddig->hashctx;
00614
00615 fddig->hashctx = NULL;
00616 break;
00617 case PGPHASHALGO_SHA1:
00618 case PGPHASHALGO_RIPEMD160:
00619 #if defined(HAVE_BEECRYPT_API_H)
00620 case PGPHASHALGO_SHA256:
00621 case PGPHASHALGO_SHA384:
00622 case PGPHASHALGO_SHA512:
00623 #endif
00624 assert(dig->sha1ctx == NULL);
00625
00626 dig->sha1ctx = fddig->hashctx;
00627
00628 fddig->hashctx = NULL;
00629 break;
00630 default:
00631 break;
00632 }
00633 }
00634
00635 }
00636
00637
00638
00641 static inline
00642 int fdFileno( void * cookie)
00643
00644 {
00645 FD_t fd;
00646 if (cookie == NULL) return -2;
00647 fd = c2f(cookie);
00648 return fd->fps[0].fdno;
00649 }
00650
00651
00659 int rpmioSlurp(const char * fn,
00660 uint8_t ** bp, ssize_t * blenp)
00661
00662 ;
00663
00664 #ifdef __cplusplus
00665 }
00666 #endif
00667
00668 #endif