rpm  5.4.10
rpmmg.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #if defined(HAVE_MAGIC_H)
8 #include "magic.h"
9 #endif
10 
11 #include <rpmiotypes.h>
12 #include <rpmio.h> /* for *Pool methods */
13 #include <rpmlog.h>
14 #include <rpmurl.h>
15 #define _RPMMG_INTERNAL
16 #include <rpmmg.h>
17 
18 #include "debug.h"
19 
20 /*@unchecked@*/
21 int _rpmmg_debug = 0;
22 
23 /*@-mustmod@*/ /* XXX splint on crack */
24 static void rpmmgFini(void * _mg)
25  /*@globals fileSystem @*/
26  /*@modifies *_mg, fileSystem @*/
27 {
28  rpmmg mg = (rpmmg) _mg;
29 
30 #if defined(HAVE_MAGIC_H)
31  if (mg->ms) {
32  magic_close(mg->ms);
33  mg->ms = NULL;
34  }
35 #endif
36  mg->fn = _free(mg->fn);
37 }
38 /*@=mustmod@*/
39 
40 /*@unchecked@*/ /*@only@*/ /*@null@*/
42 
43 static rpmmg rpmmgGetPool(/*@null@*/ rpmioPool pool)
44  /*@globals _rpmmgPool, fileSystem @*/
45  /*@modifies pool, _rpmmgPool, fileSystem @*/
46 {
47  rpmmg mg;
48 
49  if (_rpmmgPool == NULL) {
50  _rpmmgPool = rpmioNewPool("mg", sizeof(*mg), -1, _rpmmg_debug,
51  NULL, NULL, rpmmgFini);
52  pool = _rpmmgPool;
53  }
54  return (rpmmg) rpmioGetPool(pool, sizeof(*mg));
55 }
56 
57 rpmmg rpmmgNew(const char * fn, int flags)
58 {
59  rpmmg mg = rpmmgGetPool(_rpmmgPool);
60  int xx;
61 
62  if (fn)
63  mg->fn = xstrdup(fn);
64 #if defined(HAVE_MAGIC_H)
65  mg->flags = (flags ? flags : MAGIC_CHECK);/* XXX MAGIC_COMPRESS flag? */
66  mg->ms = magic_open(flags);
67  if (mg->ms) {
68  xx = magic_load(mg->ms, mg->fn);
69  if (xx == -1) {
70  rpmlog(RPMLOG_ERR, _("magic_load(ms, %s) failed: %s\n"),
71  (fn ? fn : "(nil)"), magic_error(mg->ms));
72  return rpmmgFree(mg);
73  }
74  } else {
75  rpmlog(RPMLOG_ERR, _("magic_open(0x%x) failed: %s\n"),
76  flags, strerror(errno));
77  return rpmmgFree(mg);
78  }
79 #endif
80 
81  return rpmmgLink(mg);
82 }
83 
84 const char * rpmmgFile(rpmmg mg, const char *fn)
85 {
86  const char * t = NULL;
87 
88 if (_rpmmg_debug)
89 fprintf(stderr, "--> rpmmgFile(%p, %s)\n", mg, (fn ? fn : "(nil)"));
90 
91 #if defined(HAVE_MAGIC_H)
92  if (mg->ms) {
93  const char * lpath = NULL;
94  int ut = urlPath(fn, &lpath);
95 
96  switch (ut) {
97  case URL_IS_FTP:
98  case URL_IS_HKP:
99  case URL_IS_HTTP:
100  case URL_IS_HTTPS:
101  { char b[512];
102  size_t nb = 0;
103  FD_t fd;
104 
105  fd = Fopen(fn, "r.ufdio");
106  if (fd != NULL && !Ferror(fd)) {
107  nb = Fread(b, 1, sizeof(b), fd);
108  (void) Fclose(fd);
109  }
110  if (nb > 0)
111  return rpmmgBuffer(mg, b, nb);
112  } break;
113  case URL_IS_DASH:
114  case URL_IS_MONGO: /* XXX FIXME */
115  break;
116  case URL_IS_PATH:
117  fn = lpath;
118  /*@fallthrough@*/
119  case URL_IS_UNKNOWN:
120  default:
121  t = magic_file(mg->ms, fn);
122  /* XXX HACK: libmagic compiled without <pcreposix.h> spews here. */
123  if (t == NULL) {
124  const char * msg = magic_error(mg->ms);
125  if (strstr(msg, "regexec error 17, (match failed)") == NULL)
126  rpmlog(RPMLOG_ERR, _("magic_file(ms, %s) failed: %s\n"),
127  (fn ? fn : "(nil)"), msg);
128  }
129  break;
130  }
131  }
132 #endif
133 
134  if (t == NULL) t = "";
135  t = xstrdup(t);
136 
137 if (_rpmmg_debug)
138 fprintf(stderr, "<-- rpmmgFile(%p, %s) %s\n", mg, (fn ? fn : "(nil)"), t);
139  return t;
140 }
141 
142 const char * rpmmgBuffer(rpmmg mg, const char * b, size_t nb)
143 {
144  const char * t = NULL;
145 
146 if (_rpmmg_debug)
147 fprintf(stderr, "--> rpmmgBuffer(%p, %p[%d])\n", mg, b, (int)nb);
148  if (nb == 0) nb = strlen(b);
149 #if defined(HAVE_MAGIC_H)
150  if (mg->ms) {
151  t = magic_buffer(mg->ms, b, nb);
152  /* XXX HACK: libmagic compiled without <pcreposix.h> spews here. */
153  if (t == NULL) {
154  const char * msg = magic_error(mg->ms);
155  if (strstr(msg, "regexec error 17, (match failed)") == NULL)
156  rpmlog(RPMLOG_ERR, _("magic_buffer(ms, %p[%u]) failed: %s\n"),
157  b, (unsigned)nb, msg);
158  }
159  }
160 #endif
161 
162  if (t == NULL) t = "";
163  t = xstrdup(t);
164 
165 if (_rpmmg_debug)
166 fprintf(stderr, "<-- rpmmgBuffer(%p, %p[%d]) %s\n", mg, b, (int)nb, t);
167  return t;
168 }