1 #ifndef H_RPMIO_INTERNAL
2 #define H_RPMIO_INTERNAL
5 * \file rpmio/rpmio_internal.h
12 #include <beecrypt/types.h>
16 /* Drag in the beecrypt includes. */
17 #include <beecrypt/beecrypt.h>
18 #include <beecrypt/base64.h>
19 #include <beecrypt/dsa.h>
20 #include <beecrypt/endianness.h>
21 #include <beecrypt/md5.h>
22 #include <beecrypt/mp32.h>
23 #include <beecrypt/rsa.h>
24 #include <beecrypt/rsapk.h>
25 #include <beecrypt/sha1.h>
28 * Values parsed from OpenPGP signature/pubkey packet(s).
30 struct pgpDigParams_s {
35 const char * params[4];
38 byte version; /*!< version number. */
39 byte time[4]; /*!< time that the key was created. */
40 byte pubkey_algo; /*!< public key algorithm. */
48 #define PGPDIG_SAVED_TIME (1 << 0)
49 #define PGPDIG_SAVED_ID (1 << 1)
54 * Container for values parsed from an OpenPGP signature and public key.
57 struct pgpDigParams_s signature;
58 struct pgpDigParams_s pubkey;
60 size_t nbytes; /*!< No. bytes of plain text. */
63 DIGEST_CTX sha1ctx; /*!< (dsa) sha1 hash context. */
65 DIGEST_CTX hdrsha1ctx; /*!< (dsa) header sha1 hash context. */
67 void * sha1; /*!< (dsa) V3 signature hash. */
68 size_t sha1len; /*!< (dsa) V3 signature hash length. */
71 DIGEST_CTX md5ctx; /*!< (rsa) md5 hash context. */
74 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 {
100 /*@dependent@*/ void * fp;
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.
119 typedef /*@abstract@*/ struct {
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.
137 #define RPMIO_DEBUG_IO 0x40000000
138 #define RPMIO_DEBUG_REFS 0x20000000
140 #define FDMAGIC 0x04463138
143 int urlType; /* ufdio: */
146 void * url; /* ufdio: URL info */
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 */
155 const void *errcookie; /* gzdio/bzdio/ufdio: */
157 FDSTAT_t stats; /* I/O statistics */
160 #define FDDIGEST_MAX 4
161 struct _FDDIGEST_s digests[FDDIGEST_MAX];
163 int ftpFileDoneNeeded; /* ufdio: (FTP) */
164 unsigned int firstFree; /* fadio: */
165 long int fileSize; /* fadio: */
166 long int fd_cpioPos; /* cpio: */
170 #define FDSANE(fd) assert(fd && fd->magic == FDMAGIC)
174 extern int _rpmio_debug;
179 extern int _ftp_debug;
182 #define DBG(_f, _m, _x) \
183 if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x
185 #if defined(__LCLINT__XXX)
186 #define DBGIO(_f, _x)
187 #define DBGREFS(_f, _x)
189 #define DBGIO(_f, _x) DBG((_f), RPMIO_DEBUG_IO, _x)
190 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
199 int fdFgets(FD_t fd, char * buf, size_t len)
200 /*@globals errno, fileSystem @*/
201 /*@modifies *buf, fd, errno, fileSystem @*/;
205 /*@null@*/ FD_t ftpOpen(const char *url, /*@unused@*/ int flags,
206 /*@unused@*/ mode_t mode, /*@out@*/ urlinfo *uret)
207 /*@globals fileSystem, internalState @*/
208 /*@modifies *uret, fileSystem, internalState @*/;
212 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
213 /*@globals fileSystem, internalState @*/
214 /*@modifies data, fileSystem, internalState @*/;
218 int ftpCmd(const char * cmd, const char * url, const char * arg2)
219 /*@globals fileSystem, internalState @*/
220 /*@modifies fileSystem, internalState @*/;
224 int ufdClose( /*@only@*/ void * cookie)
225 /*@globals fileSystem, internalState @*/
226 /*@modifies cookie, fileSystem, internalState @*/;
230 /*@unused@*/ static inline
231 /*@null@*/ FDIO_t fdGetIo(FD_t fd)
236 return fd->fps[fd->nfps].io;
242 /*@-nullstate@*/ /* FIX: io may be NULL */
243 /*@unused@*/ static inline
244 void fdSetIo(FD_t fd, /*@kept@*/ /*@null@*/ FDIO_t io)
250 fd->fps[fd->nfps].io = io;
258 /*@unused@*/ static inline
259 /*@exposed@*/ /*@dependent@*/ /*@null@*/ FILE * fdGetFILE(FD_t fd)
265 return ((FILE *)fd->fps[fd->nfps].fp);
272 /*@unused@*/ static inline
273 /*@exposed@*/ /*@dependent@*/ /*@null@*/ void * fdGetFp(FD_t fd)
278 return fd->fps[fd->nfps].fp;
284 /*@-nullstate@*/ /* FIX: fp may be NULL */
285 /*@unused@*/ static inline
286 void fdSetFp(FD_t fd, /*@kept@*/ /*@null@*/ void * fp)
292 fd->fps[fd->nfps].fp = fp;
300 /*@unused@*/ static inline
301 int fdGetFdno(FD_t fd)
306 return fd->fps[fd->nfps].fdno;
312 /*@unused@*/ static inline
313 void fdSetFdno(FD_t fd, int fdno)
318 fd->fps[fd->nfps].fdno = fdno;
324 /*@unused@*/ static inline
325 void fdSetContentLength(FD_t fd, ssize_t contentLength)
329 fd->contentLength = fd->bytesRemain = contentLength;
334 /*@unused@*/ static inline
335 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
339 if (fd->nfps >= (sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
349 /*@unused@*/ static inline
354 if (fd->nfps < 0) return;
363 /*@unused@*/ static inline /*@null@*/
364 rpmop fdstat_op(/*@null@*/ FD_t fd, fdOpX opx)
370 if (fd != NULL && fd->stats != NULL && opx >= 0 && opx < FDSTAT_MAX)
371 op = fd->stats->ops + opx;
378 /*@unused@*/ static inline
379 void fdstat_enter(/*@null@*/ FD_t fd, int opx)
380 /*@globals internalState @*/
381 /*@modifies internalState @*/
383 if (fd == NULL) return;
384 if (fd->stats != NULL)
385 (void) rpmswEnter(fdstat_op(fd, opx), 0);
390 /*@unused@*/ static inline
391 void fdstat_exit(/*@null@*/ FD_t fd, int opx, ssize_t rc)
392 /*@globals internalState @*/
393 /*@modifies fd, internalState @*/
395 if (fd == NULL) return;
397 fd->syserrno = errno;
398 else if (rc > 0 && fd->bytesRemain > 0)
399 fd->bytesRemain -= rc;
400 if (fd->stats != NULL)
401 (void) rpmswExit(fdstat_op(fd, opx), rc);
407 /*@unused@*/ static inline
408 void fdstat_print(/*@null@*/ FD_t fd, const char * msg, FILE * fp)
409 /*@globals fileSystem @*/
410 /*@modifies *fp, fileSystem @*/
412 static int usec_scale = (1000*1000);
415 if (fd == NULL || fd->stats == NULL) return;
416 for (opx = 0; opx < 4; opx++) {
417 rpmop op = &fd->stats->ops[opx];
418 if (op->count <= 0) continue;
421 if (msg) fprintf(fp, "%s:", msg);
422 fprintf(fp, "%8d reads, %8ld total bytes in %d.%06d secs\n",
423 op->count, (long)op->bytes,
424 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
425 /*@switchbreak@*/ break;
427 if (msg) fprintf(fp, "%s:", msg);
428 fprintf(fp, "%8d writes, %8ld total bytes in %d.%06d secs\n",
429 op->count, (long)op->bytes,
430 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
431 /*@switchbreak@*/ break;
433 /*@switchbreak@*/ break;
435 /*@switchbreak@*/ break;
443 /*@unused@*/ static inline
444 void fdSetSyserrno(FD_t fd, int syserrno, /*@kept@*/ const void * errcookie)
448 fd->syserrno = syserrno;
450 fd->errcookie = errcookie;
456 /*@unused@*/ static inline
457 int fdGetRdTimeoutSecs(FD_t fd)
461 return fd->rd_timeoutsecs;
466 /*@unused@*/ static inline
467 long int fdGetCpioPos(FD_t fd)
471 return fd->fd_cpioPos;
476 /*@unused@*/ static inline
477 void fdSetCpioPos(FD_t fd, long int cpioPos)
481 fd->fd_cpioPos = cpioPos;
486 /*@mayexit@*/ /*@unused@*/ static inline
487 FD_t c2f(/*@null@*/ void * cookie)
491 FD_t fd = (FD_t) cookie;
494 /*@-refcounttrans -retalias@*/ return fd; /*@=refcounttrans =retalias@*/
498 * Attach digest to fd.
500 /*@unused@*/ static inline
501 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
502 /*@globals internalState @*/
503 /*@modifies fd, internalState @*/
505 FDDIGEST_t fddig = fd->digests + fd->ndigests;
506 if (fddig != (fd->digests + FDDIGEST_MAX)) {
508 fddig->hashalgo = hashalgo;
509 fdstat_enter(fd, FDSTAT_DIGEST);
510 fddig->hashctx = rpmDigestInit(hashalgo, flags);
511 fdstat_exit(fd, FDSTAT_DIGEST, 0);
516 * Update digest(s) attached to fd.
518 /*@unused@*/ static inline
519 void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen)
520 /*@globals internalState @*/
521 /*@modifies fd, internalState @*/
525 if (buf != NULL && buflen > 0)
526 for (i = fd->ndigests - 1; i >= 0; i--) {
527 FDDIGEST_t fddig = fd->digests + i;
528 if (fddig->hashctx == NULL)
530 fdstat_enter(fd, FDSTAT_DIGEST);
531 (void) rpmDigestUpdate(fddig->hashctx, buf, buflen);
532 fdstat_exit(fd, FDSTAT_DIGEST, buflen);
538 /*@unused@*/ static inline
539 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo,
540 /*@null@*/ /*@out@*/ void ** datap,
541 /*@null@*/ /*@out@*/ size_t * lenp,
543 /*@globals internalState @*/
544 /*@modifies fd, *datap, *lenp, internalState @*/
549 for (i = fd->ndigests - 1; i >= 0; i--) {
550 FDDIGEST_t fddig = fd->digests + i;
551 if (fddig->hashctx == NULL)
553 if (i > imax) imax = i;
554 if (fddig->hashalgo != hashalgo)
556 fdstat_enter(fd, FDSTAT_DIGEST);
557 (void) rpmDigestFinal(fddig->hashctx, datap, lenp, asAscii);
558 fdstat_exit(fd, FDSTAT_DIGEST, 0);
559 fddig->hashctx = NULL;
564 if (datap) *datap = NULL;
571 fd->ndigests++; /* convert index to count */
577 /*@unused@*/ static inline
578 int fdFileno(/*@null@*/ void * cookie)
582 if (cookie == NULL) return -2;
585 return fd->fps[0].fdno;
591 * Read an entire file into a buffer.
592 * @param fn file name to read
593 * @retval *bp (malloc'd) buffer address
594 * @retval *blenp (malloc'd) buffer length
595 * @return 0 on success
597 int rpmioSlurp(const char * fn,
598 /*@out@*/ const unsigned char ** bp, /*@out@*/ ssize_t * blenp)
599 /*@globals fileSystem, internalState @*/
600 /*@modifies *bp, *blenp, fileSystem, internalState @*/;
606 #endif /* H_RPMIO_INTERNAL */