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 static inline
00172 void fdSetIo(FD_t fd, FDIO_t io)
00173
00174 {
00175 FDSANE(fd);
00176
00177 fd->fps[fd->nfps].io = io;
00178
00179 }
00180
00183 static inline
00184 FILE * fdGetFILE(FD_t fd)
00185
00186 {
00187 FDSANE(fd);
00188
00189 return ((FILE *)fd->fps[fd->nfps].fp);
00190
00191 }
00192
00195 static inline
00196 void * fdGetFp(FD_t fd)
00197
00198 {
00199 FDSANE(fd);
00200
00201 return fd->fps[fd->nfps].fp;
00202
00203 }
00204
00207 static inline
00208 void fdSetFp(FD_t fd, void * fp)
00209
00210 {
00211 FDSANE(fd);
00212
00213 fd->fps[fd->nfps].fp = fp;
00214
00215 }
00216
00219 static inline
00220 int fdGetFdno(FD_t fd)
00221
00222 {
00223 FDSANE(fd);
00224 return fd->fps[fd->nfps].fdno;
00225 }
00226
00229 static inline
00230 void fdSetFdno(FD_t fd, int fdno)
00231
00232 {
00233 FDSANE(fd);
00234 fd->fps[fd->nfps].fdno = fdno;
00235 }
00236
00239 static inline
00240 void fdSetContentLength(FD_t fd, ssize_t contentLength)
00241
00242 {
00243 FDSANE(fd);
00244 fd->contentLength = fd->bytesRemain = contentLength;
00245 }
00246
00249 static inline
00250 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
00251
00252 {
00253 FDSANE(fd);
00254 if (fd->nfps >= (sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
00255 return;
00256 fd->nfps++;
00257 fdSetIo(fd, io);
00258 fdSetFp(fd, fp);
00259 fdSetFdno(fd, fdno);
00260 }
00261
00264 static inline void fdPop(FD_t fd)
00265
00266 {
00267 FDSANE(fd);
00268 if (fd->nfps < 0) return;
00269 fdSetIo(fd, NULL);
00270 fdSetFp(fd, NULL);
00271 fdSetFdno(fd, -1);
00272 fd->nfps--;
00273 }
00274
00277 static inline void fdstat_enter( FD_t fd, int opx)
00278
00279 {
00280 if (fd == NULL || fd->stats == NULL) return;
00281 fd->stats->ops[opx].count++;
00282 (void) gettimeofday(&fd->stats->begin, NULL);
00283 }
00284
00287 static inline
00288 time_t tvsub( const struct timeval * etv,
00289 const struct timeval * btv)
00290
00291 {
00292 time_t secs, usecs;
00293 if (etv == NULL || btv == NULL) return 0;
00294 secs = etv->tv_sec - btv->tv_sec;
00295 for (usecs = etv->tv_usec - btv->tv_usec; usecs < 0; usecs += 1000000)
00296 secs++;
00297 return ((secs * 1000) + (usecs/1000));
00298 }
00299
00302 static inline
00303 void fdstat_exit( FD_t fd, int opx, ssize_t rc)
00304
00305 {
00306 struct timeval end;
00307 if (fd == NULL) return;
00308 if (rc == -1) fd->syserrno = errno;
00309 if (fd->stats == NULL) return;
00310 (void) gettimeofday(&end, NULL);
00311 if (rc >= 0) {
00312 switch(opx) {
00313 case FDSTAT_SEEK:
00314 fd->stats->ops[opx].bytes = rc;
00315 break;
00316 default:
00317 fd->stats->ops[opx].bytes += rc;
00318 if (fd->bytesRemain > 0) fd->bytesRemain -= rc;
00319 break;
00320 }
00321 }
00322 fd->stats->ops[opx].msecs += tvsub(&end, &fd->stats->begin);
00323 fd->stats->begin = end;
00324 }
00325
00328 static inline
00329 void fdstat_print( FD_t fd, const char * msg, FILE * fp)
00330
00331 {
00332 int opx;
00333 if (fd == NULL || fd->stats == NULL) return;
00334 for (opx = 0; opx < 4; opx++) {
00335 OPSTAT_t *ops = &fd->stats->ops[opx];
00336 if (ops->count <= 0) continue;
00337 switch (opx) {
00338 case FDSTAT_READ:
00339 if (msg) fprintf(fp, "%s:", msg);
00340 fprintf(fp, "%8d reads, %8ld total bytes in %d.%03d secs\n",
00341 ops->count, (long)ops->bytes,
00342 (int)(ops->msecs/1000), (int)(ops->msecs%1000));
00343 break;
00344 case FDSTAT_WRITE:
00345 if (msg) fprintf(fp, "%s:", msg);
00346 fprintf(fp, "%8d writes, %8ld total bytes in %d.%03d secs\n",
00347 ops->count, (long)ops->bytes,
00348 (int)(ops->msecs/1000), (int)(ops->msecs%1000));
00349 break;
00350 case FDSTAT_SEEK:
00351 break;
00352 case FDSTAT_CLOSE:
00353 break;
00354 }
00355 }
00356 }
00357
00360 static inline
00361 void fdSetSyserrno(FD_t fd, int syserrno, const void * errcookie)
00362
00363 {
00364 FDSANE(fd);
00365 fd->syserrno = syserrno;
00366
00367 fd->errcookie = errcookie;
00368
00369 }
00370
00373 static inline
00374 int fdGetRdTimeoutSecs(FD_t fd)
00375
00376 {
00377 FDSANE(fd);
00378 return fd->rd_timeoutsecs;
00379 }
00380
00383 static inline
00384 long int fdGetCpioPos(FD_t fd)
00385
00386 {
00387 FDSANE(fd);
00388 return fd->fd_cpioPos;
00389 }
00390
00393 static inline
00394 void fdSetCpioPos(FD_t fd, long int cpioPos)
00395
00396 {
00397 FDSANE(fd);
00398 fd->fd_cpioPos = cpioPos;
00399 }
00400
00403 static inline
00404 FD_t c2f( void * cookie)
00405
00406 {
00407
00408 FD_t fd = (FD_t) cookie;
00409
00410 FDSANE(fd);
00411 return fd;
00412 }
00413
00416 static inline
00417 void fdInitMD5(FD_t fd, int flags)
00418
00419 {
00420 if (flags) flags = RPMDIGEST_REVERSE;
00421 flags |= RPMDIGEST_MD5;
00422 fd->digest = rpmDigestInit(flags);
00423 }
00424
00427 static inline
00428 void fdInitSHA1(FD_t fd, int flags)
00429
00430 {
00431 if (flags) flags = RPMDIGEST_REVERSE;
00432 flags |= RPMDIGEST_SHA1;
00433 fd->digest = rpmDigestInit(flags);
00434 }
00435
00438 static inline
00439 void fdFiniMD5(FD_t fd,
00440 void ** datap,
00441 size_t * lenp,
00442 int asAscii)
00443
00444 {
00445 if (fd->digest == NULL) {
00446 if (datap) *datap = NULL;
00447 if (lenp) *lenp = 0;
00448 return;
00449 }
00450
00451 rpmDigestFinal(fd->digest, datap, lenp, asAscii);
00452
00453 fd->digest = NULL;
00454 }
00455
00458 static inline
00459 void fdFiniSHA1(FD_t fd,
00460 void ** datap,
00461 size_t * lenp,
00462 int asAscii)
00463
00464 {
00465 if (fd->digest == NULL) {
00466 if (datap) *datap = NULL;
00467 if (lenp) *lenp = 0;
00468 return;
00469 }
00470
00471 rpmDigestFinal(fd->digest, datap, lenp, asAscii);
00472
00473 fd->digest = NULL;
00474 }
00475
00476
00479 static inline
00480 int fdFileno( void * cookie)
00481
00482 {
00483 FD_t fd;
00484 if (cookie == NULL) return -2;
00485 fd = c2f(cookie);
00486 return fd->fps[0].fdno;
00487 }
00488
00489
00490 #ifdef __cplusplus
00491 }
00492 #endif
00493
00494 #endif