1 #ifndef H_RPMIO_INTERNAL
2 #define H_RPMIO_INTERNAL
5 * \file rpmio/rpmio_internal.h
12 #if HAVE_BEECRYPT_API_H
13 #include <beecrypt/api.h>
15 #include <beecrypt/beecrypt.api.h>
21 /* Drag in the beecrypt includes. */
22 #include <beecrypt/beecrypt.h>
23 #include <beecrypt/base64.h>
24 #include <beecrypt/dsa.h>
25 #include <beecrypt/endianness.h>
26 #include <beecrypt/md5.h>
27 #include <beecrypt/mp.h>
28 #include <beecrypt/rsa.h>
29 #include <beecrypt/rsapk.h>
30 #include <beecrypt/sha1.h>
31 #if HAVE_BEECRYPT_API_H
32 #include <beecrypt/sha256.h>
33 #include <beecrypt/sha384.h>
34 #include <beecrypt/sha512.h>
38 * Values parsed from OpenPGP signature/pubkey packet(s).
40 struct pgpDigParams_s {
43 const char * params[4];
46 byte version; /*!< version number. */
47 byte time[4]; /*!< time that the key was created. */
48 byte pubkey_algo; /*!< public key algorithm. */
56 #define PGPDIG_SAVED_TIME (1 << 0)
57 #define PGPDIG_SAVED_ID (1 << 1)
62 * Container for values parsed from an OpenPGP signature and public key.
65 struct pgpDigParams_s signature;
66 struct pgpDigParams_s pubkey;
68 size_t nbytes; /*!< No. bytes of plain text. */
70 DIGEST_CTX sha1ctx; /*!< (dsa) sha1 hash context. */
71 DIGEST_CTX hdrsha1ctx; /*!< (dsa) header sha1 hash context. */
72 void * sha1; /*!< (dsa) V3 signature hash. */
73 size_t sha1len; /*!< (dsa) V3 signature hash length. */
75 DIGEST_CTX md5ctx; /*!< (rsa) md5 hash context. */
76 DIGEST_CTX hdrmd5ctx; /*!< (rsa) header md5 hash context. */
77 void * md5; /*!< (rsa) V3 signature hash. */
78 size_t md5len; /*!< (rsa) V3 signature hash length. */
98 typedef struct _FDSTACK_s {
105 * Identify per-desciptor I/O operation statistics.
107 typedef enum fdOpX_e {
108 FDSTAT_READ = 0, /*!< Read statistics index. */
109 FDSTAT_WRITE = 1, /*!< Write statistics index. */
110 FDSTAT_SEEK = 2, /*!< Seek statistics index. */
111 FDSTAT_CLOSE = 3, /*!< Close statistics index */
112 FDSTAT_DIGEST = 4, /*!< Digest statistics index. */
117 * Cumulative statistics for a descriptor.
120 struct rpmop_s ops[FDSTAT_MAX]; /*!< Cumulative statistics. */
125 typedef struct _FDDIGEST_s {
126 pgpHashAlgo hashalgo;
131 * The FD_t File Handle data structure.
136 #define RPMIO_DEBUG_IO 0x40000000
137 #define RPMIO_DEBUG_REFS 0x20000000
139 #define FDMAGIC 0x04463138
142 int urlType; /* ufdio: */
144 void * url; /* ufdio: URL info */
145 void * req; /* ufdio: HTTP request */
147 int rd_timeoutsecs; /* ufdRead: per FD_t timer */
148 ssize_t bytesRemain; /* ufdio: */
149 ssize_t contentLength; /* ufdio: */
150 int persist; /* ufdio: */
151 int wr_chunked; /* ufdio: */
153 int syserrno; /* last system errno encountered */
154 const void *errcookie; /* gzdio/bzdio/ufdio: */
156 FDSTAT_t stats; /* I/O statistics */
159 #define FDDIGEST_MAX 4
160 struct _FDDIGEST_s digests[FDDIGEST_MAX];
162 int ftpFileDoneNeeded; /* ufdio: (FTP) */
163 unsigned int firstFree; /* fadio: */
164 long int fileSize; /* fadio: */
165 long int fd_cpioPos; /* cpio: */
168 #define FDSANE(fd) assert(fd && fd->magic == FDMAGIC)
170 extern int _rpmio_debug;
172 extern int _ftp_debug;
174 #define DBG(_f, _m, _x) \
176 if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x \
178 #define DBGIO(_f, _x) DBG((_f), RPMIO_DEBUG_IO, _x)
179 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
187 int fdFgets(FD_t fd, char * buf, size_t len);
191 FD_t ftpOpen(const char *url, int flags,
192 mode_t mode, urlinfo *uret);
196 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg);
200 int ftpCmd(const char * cmd, const char * url, const char * arg2);
204 int ufdClose( void * cookie);
209 FDIO_t fdGetIo(FD_t fd)
212 return fd->fps[fd->nfps].io;
217 /* FIX: io may be NULL */
219 void fdSetIo(FD_t fd, FDIO_t io)
222 fd->fps[fd->nfps].io = io;
228 FILE * fdGetFILE(FD_t fd)
231 return ((FILE *)fd->fps[fd->nfps].fp);
237 void * fdGetFp(FD_t fd)
240 return fd->fps[fd->nfps].fp;
245 /* FIX: fp may be NULL */
247 void fdSetFp(FD_t fd, void * fp)
250 fd->fps[fd->nfps].fp = fp;
256 int fdGetFdno(FD_t fd)
259 return fd->fps[fd->nfps].fdno;
265 void fdSetFdno(FD_t fd, int fdno)
268 fd->fps[fd->nfps].fdno = fdno;
274 void fdSetContentLength(FD_t fd, ssize_t contentLength)
277 fd->contentLength = fd->bytesRemain = contentLength;
283 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
286 if (fd->nfps >= (sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
300 if (fd->nfps < 0) return;
310 rpmop fdstat_op(FD_t fd, fdOpX opx)
314 if (fd != NULL && fd->stats != NULL && opx >= 0 && opx < FDSTAT_MAX)
315 op = fd->stats->ops + opx;
322 void fdstat_enter(FD_t fd, int opx)
324 if (fd == NULL) return;
325 if (fd->stats != NULL)
326 (void) rpmswEnter(fdstat_op(fd, opx), 0);
332 void fdstat_exit(FD_t fd, int opx, ssize_t rc)
334 if (fd == NULL) return;
336 fd->syserrno = errno;
337 else if (rc > 0 && fd->bytesRemain > 0)
341 fd->bytesRemain -= rc;
346 if (fd->stats != NULL)
347 (void) rpmswExit(fdstat_op(fd, opx), rc);
353 void fdstat_print(FD_t fd, const char * msg, FILE * fp)
355 static int usec_scale = (1000*1000);
358 if (fd == NULL || fd->stats == NULL) return;
359 for (opx = 0; opx < 4; opx++) {
360 rpmop op = &fd->stats->ops[opx];
361 if (op->count <= 0) continue;
364 if (msg) fprintf(fp, "%s:", msg);
365 fprintf(fp, "%8d reads, %8ld total bytes in %d.%06d secs\n",
366 op->count, (long)op->bytes,
367 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
370 if (msg) fprintf(fp, "%s:", msg);
371 fprintf(fp, "%8d writes, %8ld total bytes in %d.%06d secs\n",
372 op->count, (long)op->bytes,
373 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
386 void fdSetSyserrno(FD_t fd, int syserrno, const void * errcookie)
389 fd->syserrno = syserrno;
390 fd->errcookie = errcookie;
396 int fdGetRdTimeoutSecs(FD_t fd)
399 return fd->rd_timeoutsecs;
405 long int fdGetCpioPos(FD_t fd)
408 return fd->fd_cpioPos;
414 void fdSetCpioPos(FD_t fd, long int cpioPos)
417 fd->fd_cpioPos = cpioPos;
423 FD_t c2f(void * cookie)
425 FD_t fd = (FD_t) cookie;
431 * Attach digest to fd.
434 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
436 FDDIGEST_t fddig = fd->digests + fd->ndigests;
437 if (fddig != (fd->digests + FDDIGEST_MAX)) {
439 fddig->hashalgo = hashalgo;
440 fdstat_enter(fd, FDSTAT_DIGEST);
441 fddig->hashctx = rpmDigestInit(hashalgo, flags);
442 fdstat_exit(fd, FDSTAT_DIGEST, 0);
447 * Update digest(s) attached to fd.
450 void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen)
454 if (buf != NULL && buflen > 0)
455 for (i = fd->ndigests - 1; i >= 0; i--) {
456 FDDIGEST_t fddig = fd->digests + i;
457 if (fddig->hashctx == NULL)
459 fdstat_enter(fd, FDSTAT_DIGEST);
460 (void) rpmDigestUpdate(fddig->hashctx, buf, buflen);
461 fdstat_exit(fd, FDSTAT_DIGEST, buflen);
468 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo,
476 for (i = fd->ndigests - 1; i >= 0; i--) {
477 FDDIGEST_t fddig = fd->digests + i;
478 if (fddig->hashctx == NULL)
480 if (i > imax) imax = i;
481 if (fddig->hashalgo != hashalgo)
483 fdstat_enter(fd, FDSTAT_DIGEST);
484 (void) rpmDigestFinal(fddig->hashctx, datap, lenp, asAscii);
485 fdstat_exit(fd, FDSTAT_DIGEST, 0);
486 fddig->hashctx = NULL;
490 if (datap) *datap = NULL;
496 fd->ndigests++; /* convert index to count */
502 int fdFileno(void * cookie)
505 if (cookie == NULL) return -2;
507 return fd->fps[0].fdno;
511 * Read an entire file into a buffer.
512 * @param fn file name to read
513 * @retval *bp (malloc'd) buffer address
514 * @retval *blenp (malloc'd) buffer length
515 * @return 0 on success
517 int rpmioSlurp(const char * fn,
518 byte ** bp, ssize_t * blenp);
524 #endif /* H_RPMIO_INTERNAL */