00001 #ifndef H_RPMIO_INTERNAL
00002 #define H_RPMIO_INTERNAL
00003
00009 #include <rpmio.h>
00010 #undef fdFileno
00011
00012 #include <rpmurl.h>
00013
00016 typedef struct _FDSTACK_s {
00017 FDIO_t io;
00018 void * fp;
00019 int fdno;
00020 } FDSTACK_t;
00021
00025 typedef struct {
00026 int count;
00027 off_t bytes;
00028 time_t msecs;
00029 } OPSTAT_t;
00030
00034 enum FDSTAT_e {
00035 FDSTAT_READ = 0,
00036 FDSTAT_WRITE = 1,
00037 FDSTAT_SEEK = 2,
00038 FDSTAT_CLOSE = 3
00039 };
00040
00044 typedef struct {
00045 struct timeval create;
00046 struct timeval begin;
00047 OPSTAT_t ops[4];
00048 } * FDSTAT_t;
00049
00053 typedef enum rpmDigestFlags_e {
00054 RPMDIGEST_MD5 = (1 << 0),
00055 RPMDIGEST_SHA1 = (1 << 1),
00056 RPMDIGEST_REVERSE = (1 << 16),
00057 RPMDIGEST_BCSWAP = (1 << 17),
00058 } rpmDigestFlags;
00059
00060 typedef struct DIGEST_CTX_s * DIGEST_CTX;
00061
00068 DIGEST_CTX rpmDigestInit(rpmDigestFlags flags)
00069 ;
00070
00077 void rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
00078 ;
00079
00090 void rpmDigestFinal( DIGEST_CTX ctx,
00091 void ** datap,
00092 size_t * lenp, int asAscii)
00093 ;
00094
00098 struct _FD_s {
00099 int nrefs;
00100 int flags;
00101 #define RPMIO_DEBUG_IO 0x40000000
00102 #define RPMIO_DEBUG_REFS 0x20000000
00103 int magic;
00104 #define FDMAGIC 0x04463138
00105 int nfps;
00106 FDSTACK_t fps[8];
00107 int urlType;
00108
00109 void * url;
00110 int rd_timeoutsecs;
00111 ssize_t bytesRemain;
00112 ssize_t contentLength;
00113 int persist;
00114 int wr_chunked;
00115
00116 int syserrno;
00117 const void *errcookie;
00118
00119 FDSTAT_t stats;
00120 DIGEST_CTX digest;
00121
00122 int ftpFileDoneNeeded;
00123 unsigned int firstFree;
00124 long int fileSize;
00125 long int fd_cpioPos;
00126 };
00127
00128
00129 #define FDSANE(fd) assert(fd && fd->magic == FDMAGIC)
00130
00131
00132 extern int _rpmio_debug;
00133
00134
00135 #define DBG(_f, _m, _x) \
00136 if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x
00137
00138 #define DBGIO(_f, _x) DBG((_f), RPMIO_DEBUG_IO, _x)
00139 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
00140
00141 #ifdef __cplusplus
00142 extern "C" {
00143 #endif
00144
00145 int fdFgets(FD_t fd, char * buf, size_t len)
00146 ;
00147
00148 FD_t ftpOpen(const char *url, int flags,
00149 mode_t mode, urlinfo *uret)
00150 ;
00151 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
00152 ;
00153 int ftpCmd(const char * cmd, const char * url, const char * arg2)
00154 ;
00155
00156 int ufdClose( void * cookie)
00157 ;
00158
00161 static inline
00162 const FDIO_t fdGetIo(FD_t fd)
00163
00164 {
00165 FDSANE(fd);
00166 return fd->fps[fd->nfps].io;
00167 }
00168
00171
00172 static inline
00173 void fdSetIo(FD_t fd, FDIO_t io)
00174
00175 {
00176 FDSANE(fd);
00177
00178 fd->fps[fd->nfps].io = io;
00179
00180 }
00181
00182
00185 static inline
00186 FILE * fdGetFILE(FD_t fd)
00187
00188 {
00189 FDSANE(fd);
00190
00191 return ((FILE *)fd->fps[fd->nfps].fp);
00192
00193 }
00194
00197 static inline
00198 void * fdGetFp(FD_t fd)
00199
00200 {
00201 FDSANE(fd);
00202
00203 return fd->fps[fd->nfps].fp;
00204
00205 }
00206
00209
00210 static inline
00211 void fdSetFp(FD_t fd, void * fp)
00212
00213 {
00214 FDSANE(fd);
00215
00216 fd->fps[fd->nfps].fp = fp;
00217
00218 }
00219
00220
00223 static inline
00224 int fdGetFdno(FD_t fd)
00225
00226 {
00227 FDSANE(fd);
00228 return fd->fps[fd->nfps].fdno;
00229 }
00230
00233 static inline
00234 void fdSetFdno(FD_t fd, int fdno)
00235
00236 {
00237 FDSANE(fd);
00238 fd->fps[fd->nfps].fdno = fdno;
00239 }
00240
00243 static inline
00244 void fdSetContentLength(FD_t fd, ssize_t contentLength)
00245
00246 {
00247 FDSANE(fd);
00248 fd->contentLength = fd->bytesRemain = contentLength;
00249 }
00250
00253 static inline
00254 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
00255
00256 {
00257 FDSANE(fd);
00258 if (fd->nfps >= (sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
00259 return;
00260 fd->nfps++;
00261 fdSetIo(fd, io);
00262 fdSetFp(fd, fp);
00263 fdSetFdno(fd, fdno);
00264 }
00265
00268 static inline void fdPop(FD_t fd)
00269
00270 {
00271 FDSANE(fd);
00272 if (fd->nfps < 0) return;
00273 fdSetIo(fd, NULL);
00274 fdSetFp(fd, NULL);
00275 fdSetFdno(fd, -1);
00276 fd->nfps--;
00277 }
00278
00281 static inline void fdstat_enter( FD_t fd, int opx)
00282
00283 {
00284 if (fd == NULL || fd->stats == NULL) return;
00285 fd->stats->ops[opx].count++;
00286 (void) gettimeofday(&fd->stats->begin, NULL);
00287 }
00288
00291 static inline
00292 time_t tvsub( const struct timeval * etv,
00293 const struct timeval * btv)
00294
00295 {
00296 time_t secs, usecs;
00297 if (etv == NULL || btv == NULL) return 0;
00298 secs = etv->tv_sec - btv->tv_sec;
00299 for (usecs = etv->tv_usec - btv->tv_usec; usecs < 0; usecs += 1000000)
00300 secs++;
00301 return ((secs * 1000) + (usecs/1000));
00302 }
00303
00306 static inline
00307 void fdstat_exit( FD_t fd, int opx, ssize_t rc)
00308
00309 {
00310 struct timeval end;
00311 if (fd == NULL) return;
00312 if (rc == -1) fd->syserrno = errno;
00313 if (fd->stats == NULL) return;
00314 (void) gettimeofday(&end, NULL);
00315 if (rc >= 0) {
00316 switch(opx) {
00317 case FDSTAT_SEEK:
00318 fd->stats->ops[opx].bytes = rc;
00319 break;
00320 default:
00321 fd->stats->ops[opx].bytes += rc;
00322 if (fd->bytesRemain > 0) fd->bytesRemain -= rc;
00323 break;
00324 }
00325 }
00326 fd->stats->ops[opx].msecs += tvsub(&end, &fd->stats->begin);
00327 fd->stats->begin = end;
00328 }
00329
00332 static inline
00333 void fdstat_print( FD_t fd, const char * msg, FILE * fp)
00334
00335 {
00336 int opx;
00337 if (fd == NULL || fd->stats == NULL) return;
00338 for (opx = 0; opx < 4; opx++) {
00339 OPSTAT_t *ops = &fd->stats->ops[opx];
00340 if (ops->count <= 0) continue;
00341 switch (opx) {
00342 case FDSTAT_READ:
00343 if (msg) fprintf(fp, "%s:", msg);
00344 fprintf(fp, "%8d reads, %8ld total bytes in %d.%03d secs\n",
00345 ops->count, (long)ops->bytes,
00346 (int)(ops->msecs/1000), (int)(ops->msecs%1000));
00347 break;
00348 case FDSTAT_WRITE:
00349 if (msg) fprintf(fp, "%s:", msg);
00350 fprintf(fp, "%8d writes, %8ld total bytes in %d.%03d secs\n",
00351 ops->count, (long)ops->bytes,
00352 (int)(ops->msecs/1000), (int)(ops->msecs%1000));
00353 break;
00354 case FDSTAT_SEEK:
00355 break;
00356 case FDSTAT_CLOSE:
00357 break;
00358 }
00359 }
00360 }
00361
00364 static inline
00365 void fdSetSyserrno(FD_t fd, int syserrno, const void * errcookie)
00366
00367 {
00368 FDSANE(fd);
00369 fd->syserrno = syserrno;
00370
00371 fd->errcookie = errcookie;
00372
00373 }
00374
00377 static inline
00378 int fdGetRdTimeoutSecs(FD_t fd)
00379
00380 {
00381 FDSANE(fd);
00382 return fd->rd_timeoutsecs;
00383 }
00384
00387 static inline
00388 long int fdGetCpioPos(FD_t fd)
00389
00390 {
00391 FDSANE(fd);
00392 return fd->fd_cpioPos;
00393 }
00394
00397 static inline
00398 void fdSetCpioPos(FD_t fd, long int cpioPos)
00399
00400 {
00401 FDSANE(fd);
00402 fd->fd_cpioPos = cpioPos;
00403 }
00404
00407 static inline
00408 FD_t c2f( void * cookie)
00409
00410 {
00411
00412 FD_t fd = (FD_t) cookie;
00413
00414 FDSANE(fd);
00415 return fd;
00416 }
00417
00420 static inline
00421 void fdInitMD5(FD_t fd, int flags)
00422
00423 {
00424 if (flags) flags = RPMDIGEST_REVERSE;
00425 flags |= RPMDIGEST_MD5;
00426 fd->digest = rpmDigestInit(flags);
00427 }
00428
00431 static inline
00432 void fdInitSHA1(FD_t fd, int flags)
00433
00434 {
00435 if (flags) flags = RPMDIGEST_REVERSE;
00436 flags |= RPMDIGEST_SHA1;
00437 fd->digest = rpmDigestInit(flags);
00438 }
00439
00442 static inline
00443 void fdFiniMD5(FD_t fd,
00444 void ** datap,
00445 size_t * lenp,
00446 int asAscii)
00447
00448 {
00449 if (fd->digest == NULL) {
00450 if (datap) *datap = NULL;
00451 if (lenp) *lenp = 0;
00452 return;
00453 }
00454
00455 rpmDigestFinal(fd->digest, datap, lenp, asAscii);
00456
00457 fd->digest = NULL;
00458 }
00459
00462 static inline
00463 void fdFiniSHA1(FD_t fd,
00464 void ** datap,
00465 size_t * lenp,
00466 int asAscii)
00467
00468 {
00469 if (fd->digest == NULL) {
00470 if (datap) *datap = NULL;
00471 if (lenp) *lenp = 0;
00472 return;
00473 }
00474
00475 rpmDigestFinal(fd->digest, datap, lenp, asAscii);
00476
00477 fd->digest = NULL;
00478 }
00479
00480
00483 static inline
00484 int fdFileno( void * cookie)
00485
00486 {
00487 FD_t fd;
00488 if (cookie == NULL) return -2;
00489 fd = c2f(cookie);
00490 return fd->fps[0].fdno;
00491 }
00492
00493
00494 #ifdef __cplusplus
00495 }
00496 #endif
00497
00498 #endif