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
00019
00020
00023 typedef struct _FDSTACK_s {
00024
00025 FDIO_t io;
00026
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 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;
00070
00071
00072 void * url;
00073
00074 void * req;
00075
00076 int rd_timeoutsecs;
00077 ssize_t bytesRemain;
00078 ssize_t contentLength;
00079 int persist;
00080 int wr_chunked;
00081
00082 int syserrno;
00083
00084 const void *errcookie;
00085
00086
00087 const char *opath;
00088 int oflags;
00089 mode_t omode;
00090
00091
00092 rpmxar xar;
00093
00094 pgpDig dig;
00095
00096 FDSTAT_t stats;
00097
00098 int ndigests;
00099 #define FDDIGEST_MAX 32
00100 struct _FDDIGEST_s digests[FDDIGEST_MAX];
00101
00102
00103 const char *contentType;
00104
00105 const char *contentDisposition;
00106 time_t lastModified;
00107 int ftpFileDoneNeeded;
00108 unsigned long long fd_cpioPos;
00109 #if defined(__LCLINT__)
00110
00111 int nrefs;
00112 #endif
00113 };
00114
00115
00116 #define FDSANE(fd) assert(fd != NULL && fd->magic == FDMAGIC)
00117
00118
00119
00120 extern int _rpmio_debug;
00121
00122
00123
00124
00125 extern int _av_debug;
00126
00127
00128
00129
00130 extern int _ftp_debug;
00131
00132
00133
00134
00135 extern int _dav_debug;
00136
00137
00138 #define DBG(_f, _m, _x) \
00139 \
00140 if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x \
00141
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 const char * fdbg( FD_t fd)
00158 ;
00159
00162 int fdFgets(FD_t fd, char * buf, size_t len)
00163
00164 ;
00165
00168 FD_t ftpOpen(const char *url, int flags,
00169 mode_t mode, urlinfo *uret)
00170
00171 ;
00172
00175 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
00176
00177 ;
00178
00181 int ftpCmd(const char * cmd, const char * url, const char * arg2)
00182
00183 ;
00184
00187 int ufdClose( void * cookie)
00188
00189 ;
00190
00193 static inline
00194 void fdSetOpen(FD_t fd, const char * path, int flags, mode_t mode)
00195
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 static inline
00210 const char * fdGetOPath(FD_t fd)
00211
00212 {
00213 FDSANE(fd);
00214 return fd->opath;
00215 }
00216
00219 static inline
00220 int fdGetOFlags(FD_t fd)
00221
00222 {
00223 FDSANE(fd);
00224 return fd->oflags;
00225 }
00226
00229 static inline
00230 mode_t fdGetOMode(FD_t fd)
00231
00232 {
00233 FDSANE(fd);
00234 return fd->omode;
00235 }
00236
00239 static inline
00240 void fdSetDig(FD_t fd, pgpDig dig)
00241
00242
00243 {
00244 FDSANE(fd);
00245
00246 fd->dig = pgpDigFree(fd->dig, "fdSetDig");
00247 fd->dig = pgpDigLink(dig, "fdSetDig");
00248
00249 }
00250
00253 static inline
00254 pgpDig fdGetDig(FD_t fd)
00255
00256 {
00257 FDSANE(fd);
00258
00259 return fd->dig;
00260
00261 }
00262
00265 static inline
00266 void fdSetXAR(FD_t fd, rpmxar xar)
00267
00268
00269 {
00270 FDSANE(fd);
00271
00272 fd->xar = rpmxarLink(xar, "fdSetXAR");
00273
00274 }
00275
00278 static inline
00279 rpmxar fdGetXAR(FD_t fd)
00280
00281 {
00282 FDSANE(fd);
00283
00284 return fd->xar;
00285
00286 }
00287
00290 static inline
00291 FDIO_t fdGetIo(FD_t fd)
00292
00293 {
00294 FDSANE(fd);
00295 return fd->fps[fd->nfps].io;
00296 }
00297
00300
00301 static inline
00302 void fdSetIo(FD_t fd, FDIO_t io)
00303
00304 {
00305 FDSANE(fd);
00306
00307 fd->fps[fd->nfps].io = io;
00308
00309 }
00310
00311
00314 static inline
00315 FILE * fdGetFILE(FD_t fd)
00316
00317 {
00318 FDSANE(fd);
00319
00320 return ((FILE *)fd->fps[fd->nfps].fp);
00321
00322 }
00323
00326 static inline
00327 void * fdGetFp(FD_t fd)
00328
00329 {
00330 FDSANE(fd);
00331 return fd->fps[fd->nfps].fp;
00332 }
00333
00336
00337 static inline
00338 void fdSetFp(FD_t fd, void * fp)
00339
00340 {
00341 FDSANE(fd);
00342
00343 fd->fps[fd->nfps].fp = fp;
00344
00345 }
00346
00347
00350 static inline
00351 int fdGetFdno(FD_t fd)
00352
00353 {
00354 FDSANE(fd);
00355 return fd->fps[fd->nfps].fdno;
00356 }
00357
00360 static inline
00361 void fdSetFdno(FD_t fd, int fdno)
00362
00363 {
00364 FDSANE(fd);
00365 fd->fps[fd->nfps].fdno = fdno;
00366 }
00367
00370 static inline
00371 void fdSetContentLength(FD_t fd, ssize_t contentLength)
00372
00373 {
00374 FDSANE(fd);
00375 fd->contentLength = fd->bytesRemain = contentLength;
00376 }
00377
00380 static inline
00381 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
00382
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 static inline
00396 void fdPop(FD_t fd)
00397
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 static inline
00410 rpmop fdstat_op( 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 static inline
00423 void fdstat_enter( FD_t fd, int opx)
00424
00425
00426 {
00427 if (fd == NULL) return;
00428 if (fd->stats != NULL)
00429 (void) rpmswEnter(fdstat_op(fd, opx), 0);
00430 }
00431
00434 static inline
00435 void fdstat_exit( FD_t fd, int opx, ssize_t rc)
00436
00437
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 static inline
00458 void fdstat_print( FD_t fd, const char * msg, FILE * fp)
00459
00460
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 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 break;
00482 case FDSTAT_SEEK:
00483 break;
00484 case FDSTAT_CLOSE:
00485 break;
00486 }
00487 }
00488 }
00489
00492 static inline
00493 void fdSetSyserrno(FD_t fd, int syserrno, const void * errcookie)
00494
00495 {
00496 FDSANE(fd);
00497 fd->syserrno = syserrno;
00498
00499 fd->errcookie = errcookie;
00500
00501 }
00502
00505 static inline
00506 int fdGetRdTimeoutSecs(FD_t fd)
00507
00508 {
00509 FDSANE(fd);
00510 return fd->rd_timeoutsecs;
00511 }
00512
00515 static inline
00516 unsigned long long fdGetCpioPos(FD_t fd)
00517
00518 {
00519 FDSANE(fd);
00520 return fd->fd_cpioPos;
00521 }
00522
00525 static inline
00526 void fdSetCpioPos(FD_t fd, long int cpioPos)
00527
00528 {
00529 FDSANE(fd);
00530 fd->fd_cpioPos = cpioPos;
00531 }
00532
00535 static inline
00536 FD_t c2f( void * cookie)
00537
00538 {
00539
00540 FD_t fd = (FD_t) cookie;
00541
00542 FDSANE(fd);
00543 return fd;
00544 }
00545
00549 static inline
00550 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
00551
00552
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 static inline
00568 void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen)
00569
00570
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 static inline
00588 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo,
00589 void * datap,
00590 size_t * lenp,
00591 int asAscii)
00592
00593
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++;
00619 }
00620
00623
00624 static inline
00625 void fdStealDigest(FD_t fd, pgpDig dig)
00626
00627 {
00628 int i;
00629
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
00637 dig->md5ctx = fddig->hashctx;
00638
00639 fddig->hashctx = NULL;
00640 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
00650 dig->sha1ctx = fddig->hashctx;
00651
00652 fddig->hashctx = NULL;
00653 break;
00654 default:
00655 break;
00656 }
00657 }
00658
00659 }
00660
00661
00662
00665 static inline
00666 int fdFileno( 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
00675
00676 #ifdef __cplusplus
00677 }
00678 #endif
00679
00680 #endif