rpm  5.2.1
rpmio_internal.h
Go to the documentation of this file.
1 #ifndef H_RPMIO_INTERNAL
2 #define H_RPMIO_INTERNAL
3 
8 #include <rpmiotypes.h>
9 #include <rpmlog.h>
10 #include <rpmio.h>
11 #include <rpmurl.h>
12 
13 #define _RPMPGP_INTERNAL
14 #include <rpmpgp.h>
15 
16 #include <rpmxar.h>
17 
18 /*@access pgpDig @*/ /* XXX FIXME: (by refactoring to foo.c) */
19 /*@access rpmxar @*/ /* XXX FIXME: (by refactoring to foo.c) */
20 
23 typedef struct _FDSTACK_s {
24 /*@exposed@*/
26 /*@dependent@*/
27  void * fp;
28  int fdno;
29 } FDSTACK_t;
30 
34 typedef enum fdOpX_e {
41 } fdOpX;
42 
46 typedef /*@abstract@*/ struct {
48 } * FDSTAT_t;
49 
52 typedef struct _FDDIGEST_s {
55 } * FDDIGEST_t;
56 
60 struct _FD_s {
61  struct rpmioItem_s _item;
62  int flags;
63 #define RPMIO_DEBUG_IO 0x40000000
64 #define RPMIO_DEBUG_REFS 0x20000000
65  int magic;
66 #define FDMAGIC 0x04463138
67  int nfps;
69  int urlType; /* ufdio: */
70 
71 /*@dependent@*/ /*@relnull@*/
72  void * url; /* ufdio: URL info */
73 /*@relnull@*/
74  void * req; /* ufdio: HTTP request */
75 
76  int rd_timeoutsecs; /* ufdRead: per FD_t timer */
77  ssize_t bytesRemain; /* ufdio: */
78  ssize_t contentLength; /* ufdio: */
79  int persist; /* ufdio: */
80  int wr_chunked; /* ufdio: */
81 
82  int syserrno; /* last system errno encountered */
83 /*@observer@*/
84  const void *errcookie; /* gzdio/bzdio/ufdio: */
85 
86 /*null@*/
87  const char *opath; /* open(2) args. */
88  int oflags;
89  mode_t omode;
90 
91 /*@refcounted@*/ /*@relnull@*/
92  rpmxar xar; /* xar archive wrapper */
93 /*@refcounted@*/ /*@relnull@*/
94  pgpDig dig; /* signature parameters */
95 
96  FDSTAT_t stats; /* I/O statistics */
97 
98  int ndigests;
99 #define FDDIGEST_MAX 32
101 
102 /*null@*/
103  const char *contentType; /* ufdio: (HTTP) */
104 /*null@*/
105  const char *contentDisposition; /* ufdio: (HTTP) */
106  time_t lastModified; /* ufdio: (HTTP) */
107  int ftpFileDoneNeeded; /* ufdio: (FTP) */
108  unsigned long long fd_cpioPos; /* cpio: */
109 #if defined(__LCLINT__)
110 /*@refs@*/
111  int nrefs;
112 #endif
113 };
114 /*@access FD_t@*/
115 
116 #define FDSANE(fd) assert(fd != NULL && fd->magic == FDMAGIC)
117 
118 /*@-redecl@*/
119 /*@unchecked@*/
120 extern int _rpmio_debug;
121 /*@=redecl@*/
122 
123 /*@-redecl@*/
124 /*@unchecked@*/
125 extern int _av_debug;
126 /*@=redecl@*/
127 
128 /*@-redecl@*/
129 /*@unchecked@*/
130 extern int _ftp_debug;
131 /*@=redecl@*/
132 
133 /*@-redecl@*/
134 /*@unchecked@*/
135 extern int _dav_debug;
136 /*@=redecl@*/
137 
138 #define DBG(_f, _m, _x) \
139  /*@-modfilesys@*/ \
140  if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x \
141  /*@=modfilesys@*/
142 
143 #if defined(__LCLINT__XXX)
144 #define DBGIO(_f, _x)
145 #define DBGREFS(_f, _x)
146 #else
147 #define DBGIO(_f, _x) DBG((_f), RPMIO_DEBUG_IO, _x)
148 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
149 #endif
150 
151 #ifdef __cplusplus
152 extern "C" {
153 #endif
154 
157 /*@observer@*/ const char * fdbg(/*@null@*/ FD_t fd)
158  /*@*/;
159 
162 int fdFgets(FD_t fd, char * buf, size_t len)
163  /*@globals errno, fileSystem @*/
164  /*@modifies *buf, fd, errno, fileSystem @*/;
165 
168 /*@null@*/ FD_t ftpOpen(const char *url, /*@unused@*/ int flags,
169  /*@unused@*/ mode_t mode, /*@out@*/ urlinfo *uret)
170  /*@globals h_errno, fileSystem, internalState @*/
171  /*@modifies *uret, fileSystem, internalState @*/;
172 
175 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
176  /*@globals fileSystem, internalState @*/
177  /*@modifies data, fileSystem, internalState @*/;
178 
181 int ftpCmd(const char * cmd, const char * url, const char * arg2)
182  /*@globals h_errno, fileSystem, internalState @*/
183  /*@modifies fileSystem, internalState @*/;
184 
187 int ufdClose( /*@only@*/ void * cookie)
188  /*@globals fileSystem, internalState @*/
189  /*@modifies cookie, fileSystem, internalState @*/;
190 
193 /*@unused@*/ static inline
194 void fdSetOpen(FD_t fd, const char * path, int flags, mode_t mode)
195  /*@modifies fd @*/
196 {
197  FDSANE(fd);
198  if (fd->opath != NULL) {
199  free((void *)fd->opath);
200  fd->opath = NULL;
201  }
202  fd->opath = xstrdup(path);
203  fd->oflags = flags;
204  fd->omode = mode;
205 }
206 
209 /*@unused@*/ static inline
210 /*@null@*/ /*@observer@*/ const char * fdGetOPath(FD_t fd)
211  /*@*/
212 {
213  FDSANE(fd);
214  return fd->opath;
215 }
216 
219 /*@unused@*/ static inline
221  /*@*/
222 {
223  FDSANE(fd);
224  return fd->oflags;
225 }
226 
229 /*@unused@*/ static inline
230 mode_t fdGetOMode(FD_t fd)
231  /*@*/
232 {
233  FDSANE(fd);
234  return fd->omode;
235 }
236 
239 /*@unused@*/ static inline
240 void fdSetDig(FD_t fd, pgpDig dig)
241  /*@globals fileSystem @*/
242  /*@modifies fd, dig, fileSystem @*/
243 {
244  FDSANE(fd);
245 /*@-assignexpose -castexpose @*/
246  fd->dig = pgpDigFree(fd->dig, "fdSetDig");
247  fd->dig = pgpDigLink(dig, "fdSetDig");
248 /*@=assignexpose =castexpose @*/
249 }
250 
253 /*@unused@*/ static inline
254 /*@null@*/ pgpDig fdGetDig(FD_t fd)
255  /*@*/
256 {
257  FDSANE(fd);
258  /*@-compdef -retexpose -refcounttrans -usereleased @*/
259  return fd->dig;
260  /*@=compdef =retexpose =refcounttrans =usereleased @*/
261 }
262 
265 /*@unused@*/ static inline
266 void fdSetXAR(FD_t fd, rpmxar xar)
267  /*@globals fileSystem @*/
268  /*@modifies fd, xar, fileSystem @*/
269 {
270  FDSANE(fd);
271 /*@-assignexpose -castexpose @*/
272  fd->xar = rpmxarLink(xar, "fdSetXAR");
273 /*@=assignexpose =castexpose @*/
274 }
275 
278 /*@unused@*/ static inline
279 /*@null@*/ rpmxar fdGetXAR(FD_t fd)
280  /*@*/
281 {
282  FDSANE(fd);
283  /*@-compdef -refcounttrans -retexpose -usereleased @*/
284  return fd->xar;
285  /*@=compdef =refcounttrans =retexpose =usereleased @*/
286 }
287 
290 /*@unused@*/ static inline
291 /*@null@*/ FDIO_t fdGetIo(FD_t fd)
292  /*@*/
293 {
294  FDSANE(fd);
295  return fd->fps[fd->nfps].io;
296 }
297 
300 /*@-nullstate@*/ /* FIX: io may be NULL */
301 /*@unused@*/ static inline
302 void fdSetIo(FD_t fd, /*@kept@*/ /*@null@*/ FDIO_t io)
303  /*@modifies fd @*/
304 {
305  FDSANE(fd);
306  /*@-assignexpose@*/
307  fd->fps[fd->nfps].io = io;
308  /*@=assignexpose@*/
309 }
310 /*@=nullstate@*/
311 
314 /*@unused@*/ static inline
315 /*@exposed@*/ /*@dependent@*/ /*@null@*/ FILE * fdGetFILE(FD_t fd)
316  /*@*/
317 {
318  FDSANE(fd);
319  /*@+voidabstract@*/
320  return ((FILE *)fd->fps[fd->nfps].fp);
321  /*@=voidabstract@*/
322 }
323 
326 /*@unused@*/ static inline
327 /*@exposed@*/ /*@dependent@*/ /*@null@*/ void * fdGetFp(FD_t fd)
328  /*@*/
329 {
330  FDSANE(fd);
331  return fd->fps[fd->nfps].fp;
332 }
333 
336 /*@-nullstate@*/ /* FIX: fp may be NULL */
337 /*@unused@*/ static inline
338 void fdSetFp(FD_t fd, /*@kept@*/ /*@null@*/ void * fp)
339  /*@modifies fd @*/
340 {
341  FDSANE(fd);
342  /*@-assignexpose@*/
343  fd->fps[fd->nfps].fp = fp;
344  /*@=assignexpose@*/
345 }
346 /*@=nullstate@*/
347 
350 /*@unused@*/ static inline
352  /*@*/
353 {
354  FDSANE(fd);
355  return fd->fps[fd->nfps].fdno;
356 }
357 
360 /*@unused@*/ static inline
361 void fdSetFdno(FD_t fd, int fdno)
362  /*@modifies fd @*/
363 {
364  FDSANE(fd);
365  fd->fps[fd->nfps].fdno = fdno;
366 }
367 
370 /*@unused@*/ static inline
371 void fdSetContentLength(FD_t fd, ssize_t contentLength)
372  /*@modifies fd @*/
373 {
374  FDSANE(fd);
375  fd->contentLength = fd->bytesRemain = contentLength;
376 }
377 
380 /*@unused@*/ static inline
381 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
382  /*@modifies fd @*/
383 {
384  FDSANE(fd);
385  if (fd->nfps >= (int)(sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
386  return;
387  fd->nfps++;
388  fdSetIo(fd, io);
389  fdSetFp(fd, fp);
390  fdSetFdno(fd, fdno);
391 }
392 
395 /*@unused@*/ static inline
396 void fdPop(FD_t fd)
397  /*@modifies fd @*/
398 {
399  FDSANE(fd);
400  if (fd->nfps < 0) return;
401  fdSetIo(fd, NULL);
402  fdSetFp(fd, NULL);
403  fdSetFdno(fd, -1);
404  fd->nfps--;
405 }
406 
409 /*@unused@*/ static inline /*@null@*/
410 rpmop fdstat_op(/*@null@*/ FD_t fd, fdOpX opx)
411  /*@*/
412 {
413  rpmop op = NULL;
414 
415  if (fd != NULL && fd->stats != NULL && (int)opx >= 0 && opx < FDSTAT_MAX)
416  op = fd->stats->ops + opx;
417  return op;
418 }
419 
422 /*@unused@*/ static inline
423 void fdstat_enter(/*@null@*/ FD_t fd, int opx)
424  /*@globals internalState @*/
425  /*@modifies internalState @*/
426 {
427  if (fd == NULL) return;
428  if (fd->stats != NULL)
429  (void) rpmswEnter(fdstat_op(fd, opx), 0);
430 }
431 
434 /*@unused@*/ static inline
435 void fdstat_exit(/*@null@*/ FD_t fd, int opx, ssize_t rc)
436  /*@globals internalState @*/
437  /*@modifies fd, internalState @*/
438 {
439  if (fd == NULL) return;
440  if (rc == -1)
441  fd->syserrno = errno;
442  else if (rc > 0 && fd->bytesRemain > 0)
443  switch (opx) {
444  case FDSTAT_READ:
445  case FDSTAT_WRITE:
446  fd->bytesRemain -= rc;
447  break;
448  default:
449  break;
450  }
451  if (fd->stats != NULL)
452  (void) rpmswExit(fdstat_op(fd, opx), rc);
453 }
454 
457 /*@unused@*/ static inline
458 void fdstat_print(/*@null@*/ FD_t fd, const char * msg, FILE * fp)
459  /*@globals fileSystem @*/
460  /*@modifies *fp, fileSystem @*/
461 {
462  static int usec_scale = (1000*1000);
463  int opx;
464 
465  if (fd == NULL || fd->stats == NULL) return;
466  for (opx = 0; opx < 4; opx++) {
467  rpmop op = &fd->stats->ops[opx];
468  if (op->count <= 0) continue;
469  switch (opx) {
470  case FDSTAT_READ:
471  if (msg != NULL) fprintf(fp, "%s:", msg);
472  fprintf(fp, "%8d reads, %8lu total bytes in %d.%06d secs\n",
473  op->count, (unsigned long)op->bytes,
474  (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
475  /*@switchbreak@*/ break;
476  case FDSTAT_WRITE:
477  if (msg != NULL) fprintf(fp, "%s:", msg);
478  fprintf(fp, "%8d writes, %8lu total bytes in %d.%06d secs\n",
479  op->count, (unsigned long)op->bytes,
480  (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
481  /*@switchbreak@*/ break;
482  case FDSTAT_SEEK:
483  /*@switchbreak@*/ break;
484  case FDSTAT_CLOSE:
485  /*@switchbreak@*/ break;
486  }
487  }
488 }
489 
492 /*@unused@*/ static inline
493 void fdSetSyserrno(FD_t fd, int syserrno, /*@kept@*/ const void * errcookie)
494  /*@modifies fd @*/
495 {
496  FDSANE(fd);
497  fd->syserrno = syserrno;
498  /*@-assignexpose@*/
499  fd->errcookie = errcookie;
500  /*@=assignexpose@*/
501 }
502 
505 /*@unused@*/ static inline
507  /*@*/
508 {
509  FDSANE(fd);
510  return fd->rd_timeoutsecs;
511 }
512 
515 /*@unused@*/ static inline
516 unsigned long long fdGetCpioPos(FD_t fd)
517  /*@*/
518 {
519  FDSANE(fd);
520  return fd->fd_cpioPos;
521 }
522 
525 /*@unused@*/ static inline
526 void fdSetCpioPos(FD_t fd, long int cpioPos)
527  /*@modifies fd @*/
528 {
529  FDSANE(fd);
530  fd->fd_cpioPos = cpioPos;
531 }
532 
535 /*@mayexit@*/ /*@unused@*/ static inline
536 FD_t c2f(/*@null@*/ void * cookie)
537  /*@*/
538 {
539  /*@-castexpose@*/
540  FD_t fd = (FD_t) cookie;
541  /*@=castexpose@*/
542  FDSANE(fd);
543  /*@-refcounttrans -retalias@*/ return fd; /*@=refcounttrans =retalias@*/
544 }
545 
549 /*@unused@*/ static inline
550 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
551  /*@globals internalState @*/
552  /*@modifies fd, internalState @*/
553 {
554  FDDIGEST_t fddig = fd->digests + fd->ndigests;
555  if (fddig != (fd->digests + FDDIGEST_MAX)) {
556  fd->ndigests++;
557  fddig->hashalgo = hashalgo;
559  fddig->hashctx = rpmDigestInit(hashalgo, flags);
560  fdstat_exit(fd, FDSTAT_DIGEST, 0);
561  }
562 }
563 
567 /*@unused@*/ static inline
568 void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen)
569  /*@globals internalState @*/
570  /*@modifies fd, internalState @*/
571 {
572  int i;
573 
574  if (buf != NULL && buflen > 0)
575  for (i = fd->ndigests - 1; i >= 0; i--) {
576  FDDIGEST_t fddig = fd->digests + i;
577  if (fddig->hashctx == NULL)
578  continue;
580  (void) rpmDigestUpdate(fddig->hashctx, buf, buflen);
581  fdstat_exit(fd, FDSTAT_DIGEST, buflen);
582  }
583 }
584 
587 /*@unused@*/ static inline
589  /*@null@*/ /*@out@*/ void * datap,
590  /*@null@*/ /*@out@*/ size_t * lenp,
591  int asAscii)
592  /*@globals internalState @*/
593  /*@modifies fd, *datap, *lenp, internalState @*/
594 {
595  int imax = -1;
596  int i;
597 
598  for (i = fd->ndigests - 1; i >= 0; i--) {
599  FDDIGEST_t fddig = fd->digests + i;
600  if (fddig->hashctx == NULL)
601  continue;
602  if (i > imax) imax = i;
603  if (fddig->hashalgo != hashalgo)
604  continue;
606  (void) rpmDigestFinal(fddig->hashctx, datap, lenp, asAscii);
607  fdstat_exit(fd, FDSTAT_DIGEST, 0);
608  fddig->hashctx = NULL;
609  break;
610  }
611  if (i < 0) {
612  if (datap != NULL) *(void **)datap = NULL;
613  if (lenp != NULL) *lenp = 0;
614  }
615 
616  fd->ndigests = imax;
617  if (i < imax)
618  fd->ndigests++; /* convert index to count */
619 }
620 
623 /*@-mustmod@*/
624 /*@unused@*/ static inline
625 void fdStealDigest(FD_t fd, pgpDig dig)
626  /*@modifies fd, dig @*/
627 {
628  int i;
629 /*@-type@*/ /* FIX: getters for pgpDig internals */
630  for (i = fd->ndigests - 1; i >= 0; i--) {
631  FDDIGEST_t fddig = fd->digests + i;
632  if (fddig->hashctx != NULL)
633  switch (fddig->hashalgo) {
634  case PGPHASHALGO_MD5:
635 assert(dig->md5ctx == NULL);
636 /*@-onlytrans@*/
637  dig->md5ctx = fddig->hashctx;
638 /*@=onlytrans@*/
639  fddig->hashctx = NULL;
640  /*@switchbreak@*/ break;
641  case PGPHASHALGO_SHA1:
643 #if defined(HAVE_BEECRYPT_API_H)
644  case PGPHASHALGO_SHA256:
645  case PGPHASHALGO_SHA384:
646  case PGPHASHALGO_SHA512:
647 #endif
648 assert(dig->sha1ctx == NULL);
649 /*@-onlytrans@*/
650  dig->sha1ctx = fddig->hashctx;
651 /*@=onlytrans@*/
652  fddig->hashctx = NULL;
653  /*@switchbreak@*/ break;
654  default:
655  /*@switchbreak@*/ break;
656  }
657  }
658 /*@=type@*/
659 }
660 /*@=mustmod@*/
661 
662 /*@-shadow@*/
665 /*@unused@*/ static inline
666 int fdFileno(/*@null@*/ void * cookie)
667  /*@*/
668 {
669  FD_t fd;
670  if (cookie == NULL) return -2;
671  fd = c2f(cookie);
672  return fd->fps[0].fdno;
673 }
674 /*@=shadow@*/
675 
676 #ifdef __cplusplus
677 }
678 #endif
679 
680 #endif /* H_RPMIO_INTERNAL */