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