00001 #ifndef H_RPMIO_INTERNAL
00002 #define H_RPMIO_INTERNAL
00003
00008 static inline int fdFileno(void * cookie);
00009
00010 #include <rpmio.h>
00011 #include <rpmurl.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_MD5 = (1 << 0),
00054 RPMDIGEST_SHA1 = (1 << 1),
00055 RPMDIGEST_NATIVE = (1 << 16),
00056 } rpmDigestFlags;
00057
00058 typedef struct DIGEST_CTX_s * DIGEST_CTX;
00059
00066 DIGEST_CTX rpmDigestInit(rpmDigestFlags flags);
00067
00074 void rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len);
00075
00086 void rpmDigestFinal( DIGEST_CTX ctx, void ** datap,
00087 size_t *lenp, int asAscii);
00088
00092 struct _FD_s {
00093 int nrefs;
00094 int flags;
00095 #define RPMIO_DEBUG_IO 0x40000000
00096 #define RPMIO_DEBUG_REFS 0x20000000
00097 int magic;
00098 #define FDMAGIC 0x04463138
00099 int nfps;
00100 FDSTACK_t fps[8];
00101 int urlType;
00102
00103 void * url;
00104 int rd_timeoutsecs;
00105 ssize_t bytesRemain;
00106 ssize_t contentLength;
00107 int persist;
00108 int wr_chunked;
00109
00110 int syserrno;
00111 const void *errcookie;
00112
00113 FDSTAT_t stats;
00114 DIGEST_CTX digest;
00115
00116 int ftpFileDoneNeeded;
00117 unsigned int firstFree;
00118 long int fileSize;
00119 long int fd_cpioPos;
00120 };
00121
00122
00123 #define FDSANE(fd) assert(fd && fd->magic == FDMAGIC)
00124
00125 extern int _rpmio_debug;
00126
00127 #define DBG(_f, _m, _x) \
00128 if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x
00129
00130 #define DBGIO(_f, _x) DBG((_f), RPMIO_DEBUG_IO, _x)
00131 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
00132
00133 #ifdef __cplusplus
00134 extern "C" {
00135 #endif
00136
00137 int fdFgets(FD_t fd, char * buf, size_t len);
00138
00139 FD_t ftpOpen(const char *url, int flags,
00140 mode_t mode, urlinfo *uret);
00141 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg);
00142 int ftpCmd(const char * cmd, const char * url, const char * arg2);
00143
00144 int ufdClose( void * cookie);
00145
00148 static inline const FDIO_t fdGetIo(FD_t fd) {
00149 FDSANE(fd);
00150 return fd->fps[fd->nfps].io;
00151 }
00152
00155 static inline void fdSetIo(FD_t fd, FDIO_t io) {
00156 FDSANE(fd);
00157 fd->fps[fd->nfps].io = io;
00158 }
00159
00162 static inline FILE * fdGetFILE(FD_t fd) {
00163 FDSANE(fd);
00164
00165 return ((FILE *)fd->fps[fd->nfps].fp);
00166
00167 }
00168
00171 static inline void * fdGetFp(FD_t fd) {
00172 FDSANE(fd);
00173 return fd->fps[fd->nfps].fp;
00174 }
00175
00178 static inline void fdSetFp(FD_t fd, void * fp) {
00179 FDSANE(fd);
00180 fd->fps[fd->nfps].fp = fp;
00181 }
00182
00185 static inline int fdGetFdno(FD_t fd) {
00186 FDSANE(fd);
00187 return fd->fps[fd->nfps].fdno;
00188 }
00189
00192 static inline void fdSetFdno(FD_t fd, int fdno) {
00193 FDSANE(fd);
00194 fd->fps[fd->nfps].fdno = fdno;
00195 }
00196
00199 static inline void fdSetContentLength(FD_t fd, ssize_t contentLength)
00200 {
00201 FDSANE(fd);
00202 fd->contentLength = fd->bytesRemain = contentLength;
00203 }
00204
00207 static inline void fdPush(FD_t fd, FDIO_t io,
00208 void * fp, int fdno)
00209 {
00210 FDSANE(fd);
00211 if (fd->nfps >= (sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
00212 return;
00213 fd->nfps++;
00214 fdSetIo(fd, io);
00215 fdSetFp(fd, fp);
00216 fdSetFdno(fd, fdno);
00217 }
00218
00221 static inline void fdPop(FD_t fd) {
00222 FDSANE(fd);
00223 if (fd->nfps < 0) return;
00224 fdSetIo(fd, NULL);
00225 fdSetFp(fd, NULL);
00226 fdSetFdno(fd, -1);
00227 fd->nfps--;
00228 }
00229
00232 static inline void fdstat_enter(FD_t fd, int opx)
00233 {
00234 if (fd->stats == NULL) return;
00235 fd->stats->ops[opx].count++;
00236 gettimeofday(&fd->stats->begin, NULL);
00237 }
00238
00241 static inline time_t tvsub(struct timeval *etv, struct timeval *btv) {
00242 time_t secs, usecs;
00243 if (!(etv && btv)) return 0;
00244 secs = etv->tv_sec - btv->tv_sec;
00245 usecs = etv->tv_usec - btv->tv_usec;
00246 while (usecs < 0) {
00247 secs++;
00248 usecs += 1000000;
00249 }
00250 return ((secs * 1000) + (usecs/1000));
00251 }
00252
00255 static inline void fdstat_exit(FD_t fd, int opx, ssize_t rc)
00256 {
00257 struct timeval end;
00258 if (rc == -1) fd->syserrno = errno;
00259 if (fd->stats == NULL) return;
00260 gettimeofday(&end, NULL);
00261 if (rc >= 0) {
00262 switch(opx) {
00263 case FDSTAT_SEEK:
00264 fd->stats->ops[opx].bytes = rc;
00265 break;
00266 default:
00267 fd->stats->ops[opx].bytes += rc;
00268 if (fd->bytesRemain > 0) fd->bytesRemain -= rc;
00269 break;
00270 }
00271 }
00272 fd->stats->ops[opx].msecs += tvsub(&end, &fd->stats->begin);
00273 fd->stats->begin = end;
00274 }
00275
00278 static inline void fdstat_print(FD_t fd, const char * msg, FILE * fp) {
00279 int opx;
00280 if (fd->stats == NULL) return;
00281 for (opx = 0; opx < 4; opx++) {
00282 OPSTAT_t *ops = &fd->stats->ops[opx];
00283 if (ops->count <= 0) continue;
00284 switch (opx) {
00285 case FDSTAT_READ:
00286 if (msg) fprintf(fp, "%s:", msg);
00287 fprintf(fp, "%8d reads, %8ld total bytes in %d.%03d secs\n",
00288 ops->count, (long)ops->bytes,
00289 (int)(ops->msecs/1000), (int)(ops->msecs%1000));
00290 break;
00291 case FDSTAT_WRITE:
00292 if (msg) fprintf(fp, "%s:", msg);
00293 fprintf(fp, "%8d writes, %8ld total bytes in %d.%03d secs\n",
00294 ops->count, (long)ops->bytes,
00295 (int)(ops->msecs/1000), (int)(ops->msecs%1000));
00296 break;
00297 case FDSTAT_SEEK:
00298 break;
00299 case FDSTAT_CLOSE:
00300 break;
00301 }
00302 }
00303 }
00304
00307 static inline void fdSetSyserrno(FD_t fd, int syserrno, const void * errcookie) {
00308 FDSANE(fd);
00309 fd->syserrno = syserrno;
00310 fd->errcookie = errcookie;
00311 }
00312
00315 static inline int fdGetRdTimeoutSecs(FD_t fd) {
00316 FDSANE(fd);
00317 return fd->rd_timeoutsecs;
00318 }
00319
00322 static inline long int fdGetCpioPos(FD_t fd) {
00323 FDSANE(fd);
00324 return fd->fd_cpioPos;
00325 }
00326
00329 static inline void fdSetCpioPos(FD_t fd, long int cpioPos) {
00330 FDSANE(fd);
00331 fd->fd_cpioPos = cpioPos;
00332 }
00333
00336 static inline FD_t c2f(void * cookie) {
00337 FD_t fd = (FD_t) cookie;
00338 FDSANE(fd);
00339 return fd;
00340 }
00341
00344 static inline void fdInitMD5(FD_t fd, int flags) {
00345 if (flags) flags = RPMDIGEST_NATIVE;
00346 flags |= RPMDIGEST_MD5;
00347 fd->digest = rpmDigestInit(flags);
00348 }
00349
00352 static inline void fdInitSHA1(FD_t fd) {
00353 fd->digest = rpmDigestInit(RPMDIGEST_SHA1);
00354 }
00355
00358 static inline void fdFiniMD5(FD_t fd, void **datap, size_t *lenp, int asAscii) {
00359 if (fd->digest == NULL) {
00360 if (datap) *datap = NULL;
00361 if (lenp) *lenp = 0;
00362 return;
00363 }
00364 rpmDigestFinal(fd->digest, datap, lenp, asAscii);
00365 fd->digest = NULL;
00366 }
00367
00370 static inline void fdFiniSHA1(FD_t fd, void **datap, size_t *lenp, int asAscii) {
00371 if (fd->digest == NULL) {
00372 if (datap) *datap = NULL;
00373 if (lenp) *lenp = 0;
00374 return;
00375 }
00376 rpmDigestFinal(fd->digest, datap, lenp, asAscii);
00377 fd->digest = NULL;
00378 }
00379
00380
00383 static inline int fdFileno(void * cookie) {
00384 FD_t fd;
00385 if (cookie == NULL) return -2;
00386 fd = c2f(cookie);
00387 return fd->fps[0].fdno;
00388 }
00389
00390
00391 #ifdef __cplusplus
00392 }
00393 #endif
00394
00395 #endif