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 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 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
00069 DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
00070 ;
00071
00079
00080 DIGEST_CTX rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
00081 ;
00082
00090 int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
00091 ;
00092
00104 int rpmDigestFinal( DIGEST_CTX ctx,
00105 void ** datap,
00106 size_t * lenp, int asAscii)
00107 ;
00108
00112 struct _FD_s {
00113 int nrefs;
00114 int flags;
00115 #define RPMIO_DEBUG_IO 0x40000000
00116 #define RPMIO_DEBUG_REFS 0x20000000
00117 int magic;
00118 #define FDMAGIC 0x04463138
00119 int nfps;
00120 FDSTACK_t fps[8];
00121 int urlType;
00122
00123 void * url;
00124 int rd_timeoutsecs;
00125 ssize_t bytesRemain;
00126 ssize_t contentLength;
00127 int persist;
00128 int wr_chunked;
00129
00130 int syserrno;
00131 const void *errcookie;
00132
00133 FDSTAT_t stats;
00134
00135 int ndigests;
00136 #define FDDIGEST_MAX 4
00137 struct _FDDIGEST_s digests[FDDIGEST_MAX];
00138
00139 int ftpFileDoneNeeded;
00140 unsigned int firstFree;
00141 long int fileSize;
00142 long int fd_cpioPos;
00143 };
00144
00145
00146 #define FDSANE(fd) assert(fd && fd->magic == FDMAGIC)
00147
00148
00149
00150 extern int _rpmio_debug;
00151
00152
00153
00154 extern int _ftp_debug;
00155
00156
00157 #define DBG(_f, _m, _x) \
00158 if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x
00159
00160 #if defined(__LCLINT__XXX)
00161 #define DBGIO(_f, _x)
00162 #define DBGREFS(_f, _x)
00163 #else
00164 #define DBGIO(_f, _x) DBG((_f), RPMIO_DEBUG_IO, _x)
00165 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
00166 #endif
00167
00168 #ifdef __cplusplus
00169 extern "C" {
00170 #endif
00171
00174 int fdFgets(FD_t fd, char * buf, size_t len)
00175
00176 ;
00177
00180 FD_t ftpOpen(const char *url, int flags,
00181 mode_t mode, urlinfo *uret)
00182
00183 ;
00184
00187 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
00188
00189 ;
00190
00193 int ftpCmd(const char * cmd, const char * url, const char * arg2)
00194
00195 ;
00196
00199 int ufdClose( void * cookie)
00200
00201 ;
00202
00205 static inline
00206 FDIO_t fdGetIo(FD_t fd)
00207
00208 {
00209 FDSANE(fd);
00210 return fd->fps[fd->nfps].io;
00211 }
00212
00215
00216 static inline
00217 void fdSetIo(FD_t fd, FDIO_t io)
00218
00219 {
00220 FDSANE(fd);
00221
00222 fd->fps[fd->nfps].io = io;
00223
00224 }
00225
00226
00229 static inline
00230 FILE * fdGetFILE(FD_t fd)
00231
00232 {
00233 FDSANE(fd);
00234
00235 return ((FILE *)fd->fps[fd->nfps].fp);
00236
00237 }
00238
00241 static inline
00242 void * fdGetFp(FD_t fd)
00243
00244 {
00245 FDSANE(fd);
00246 return fd->fps[fd->nfps].fp;
00247 }
00248
00251
00252 static inline
00253 void fdSetFp(FD_t fd, void * fp)
00254
00255 {
00256 FDSANE(fd);
00257
00258 fd->fps[fd->nfps].fp = fp;
00259
00260 }
00261
00262
00265 static inline
00266 int fdGetFdno(FD_t fd)
00267
00268 {
00269 FDSANE(fd);
00270 return fd->fps[fd->nfps].fdno;
00271 }
00272
00275 static inline
00276 void fdSetFdno(FD_t fd, int fdno)
00277
00278 {
00279 FDSANE(fd);
00280 fd->fps[fd->nfps].fdno = fdno;
00281 }
00282
00285 static inline
00286 void fdSetContentLength(FD_t fd, ssize_t contentLength)
00287
00288 {
00289 FDSANE(fd);
00290 fd->contentLength = fd->bytesRemain = contentLength;
00291 }
00292
00295 static inline
00296 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
00297
00298 {
00299 FDSANE(fd);
00300 if (fd->nfps >= (sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
00301 return;
00302 fd->nfps++;
00303 fdSetIo(fd, io);
00304 fdSetFp(fd, fp);
00305 fdSetFdno(fd, fdno);
00306 }
00307
00310 static inline void fdPop(FD_t fd)
00311
00312 {
00313 FDSANE(fd);
00314 if (fd->nfps < 0) return;
00315 fdSetIo(fd, NULL);
00316 fdSetFp(fd, NULL);
00317 fdSetFdno(fd, -1);
00318 fd->nfps--;
00319 }
00320
00323 static inline void fdstat_enter( FD_t fd, int opx)
00324
00325 {
00326 if (fd == NULL || fd->stats == NULL) return;
00327 fd->stats->ops[opx].count++;
00328 (void) gettimeofday(&fd->stats->begin, NULL);
00329 }
00330
00333 static inline
00334 time_t tvsub( const struct timeval * etv,
00335 const struct timeval * btv)
00336
00337 {
00338 time_t secs, usecs;
00339 if (etv == NULL || btv == NULL) return 0;
00340 secs = etv->tv_sec - btv->tv_sec;
00341 for (usecs = etv->tv_usec - btv->tv_usec; usecs < 0; usecs += 1000000)
00342 secs++;
00343 return ((secs * 1000) + (usecs/1000));
00344 }
00345
00348 static inline
00349 void fdstat_exit( FD_t fd, int opx, ssize_t rc)
00350
00351 {
00352 struct timeval end;
00353 if (fd == NULL) return;
00354 if (rc == -1) fd->syserrno = errno;
00355 if (fd->stats == NULL) return;
00356 (void) gettimeofday(&end, NULL);
00357 if (rc >= 0) {
00358 switch(opx) {
00359 case FDSTAT_SEEK:
00360 fd->stats->ops[opx].bytes = rc;
00361 break;
00362 default:
00363 fd->stats->ops[opx].bytes += rc;
00364 if (fd->bytesRemain > 0) fd->bytesRemain -= rc;
00365 break;
00366 }
00367 }
00368 fd->stats->ops[opx].msecs += tvsub(&end, &fd->stats->begin);
00369 fd->stats->begin = end;
00370 }
00371
00374 static inline
00375 void fdstat_print( FD_t fd, const char * msg, FILE * fp)
00376
00377
00378 {
00379 int opx;
00380 if (fd == NULL || fd->stats == NULL) return;
00381 for (opx = 0; opx < 4; opx++) {
00382 OPSTAT_t *ops = &fd->stats->ops[opx];
00383 if (ops->count <= 0) continue;
00384 switch (opx) {
00385 case FDSTAT_READ:
00386 if (msg) fprintf(fp, "%s:", msg);
00387 fprintf(fp, "%8d reads, %8ld total bytes in %d.%03d secs\n",
00388 ops->count, (long)ops->bytes,
00389 (int)(ops->msecs/1000), (int)(ops->msecs%1000));
00390 break;
00391 case FDSTAT_WRITE:
00392 if (msg) fprintf(fp, "%s:", msg);
00393 fprintf(fp, "%8d writes, %8ld total bytes in %d.%03d secs\n",
00394 ops->count, (long)ops->bytes,
00395 (int)(ops->msecs/1000), (int)(ops->msecs%1000));
00396 break;
00397 case FDSTAT_SEEK:
00398 break;
00399 case FDSTAT_CLOSE:
00400 break;
00401 }
00402 }
00403 }
00404
00407 static inline
00408 void fdSetSyserrno(FD_t fd, int syserrno, const void * errcookie)
00409
00410 {
00411 FDSANE(fd);
00412 fd->syserrno = syserrno;
00413
00414 fd->errcookie = errcookie;
00415
00416 }
00417
00420 static inline
00421 int fdGetRdTimeoutSecs(FD_t fd)
00422
00423 {
00424 FDSANE(fd);
00425 return fd->rd_timeoutsecs;
00426 }
00427
00430 static inline
00431 long int fdGetCpioPos(FD_t fd)
00432
00433 {
00434 FDSANE(fd);
00435 return fd->fd_cpioPos;
00436 }
00437
00440 static inline
00441 void fdSetCpioPos(FD_t fd, long int cpioPos)
00442
00443 {
00444 FDSANE(fd);
00445 fd->fd_cpioPos = cpioPos;
00446 }
00447
00450 static inline
00451 FD_t c2f( void * cookie)
00452
00453 {
00454
00455 FD_t fd = (FD_t) cookie;
00456
00457 FDSANE(fd);
00458 return fd;
00459 }
00460
00464 static inline
00465 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
00466
00467 {
00468 FDDIGEST_t fddig = fd->digests + fd->ndigests;
00469 if (fddig != (fd->digests + FDDIGEST_MAX)) {
00470 fd->ndigests++;
00471 fddig->hashalgo = hashalgo;
00472 fddig->hashctx = rpmDigestInit(hashalgo, flags);
00473 }
00474 }
00475
00479 static inline
00480 void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen)
00481
00482 {
00483 int i;
00484
00485 if (buf != NULL && buflen > 0)
00486 for (i = fd->ndigests - 1; i >= 0; i--) {
00487 FDDIGEST_t fddig = fd->digests + i;
00488 if (fddig->hashctx == NULL)
00489 continue;
00490 (void) rpmDigestUpdate(fddig->hashctx, buf, buflen);
00491 }
00492 }
00493
00496 static inline
00497 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo,
00498 void ** datap,
00499 size_t * lenp,
00500 int asAscii)
00501
00502 {
00503 int imax = -1;
00504 int i;
00505
00506 for (i = fd->ndigests - 1; i >= 0; i--) {
00507 FDDIGEST_t fddig = fd->digests + i;
00508 if (fddig->hashctx == NULL)
00509 continue;
00510 if (i > imax) imax = i;
00511 if (fddig->hashalgo != hashalgo)
00512 continue;
00513 (void) rpmDigestFinal(fddig->hashctx, datap, lenp, asAscii);
00514 fddig->hashctx = NULL;
00515 break;
00516 }
00517 if (i < 0) {
00518 if (datap) *datap = NULL;
00519 if (lenp) *lenp = 0;
00520 }
00521
00522 fd->ndigests = imax;
00523 if (i < imax)
00524 fd->ndigests++;
00525 }
00526
00527
00530 static inline
00531 int fdFileno( void * cookie)
00532
00533 {
00534 FD_t fd;
00535 if (cookie == NULL) return -2;
00536 fd = c2f(cookie);
00537 return fd->fps[0].fdno;
00538 }
00539
00540
00543 int rpmioSlurp(const char * fn,
00544 const unsigned char ** bp, ssize_t * blenp)
00545
00546 ;
00547
00548 #ifdef __cplusplus
00549 }
00550 #endif
00551
00552 #endif