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 }
const char * rpmmgFile(rpmmg mg, const char *fn)
Return magic string for a file.
Definition: rpmmg.c:84
char * xstrdup(const char *str)
Definition: rpmmalloc.c:322
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
Definition: rpmio.c:2833
int errno
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
static rpmmg rpmmgGetPool(rpmioPool pool)
Definition: rpmmg.c:43
int _rpmmg_debug
Definition: rpmmg.c:21
Yet Another syslog(3) API clone.
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
Definition: rpmmalloc.c:221
rpmioPool _rpmmgPool
Definition: rpmmg.c:41
static void rpmmgFini(void *_mg)
Definition: rpmmg.c:24
The FD_t File Handle data structure.
rpmmg rpmmgLink(rpmmg mg)
Reference a magic wrapper instance.
rpmmg rpmmgNew(const char *fn, int flags)
Create and load a magic wrapper.
Definition: rpmmg.c:57
size_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd)
fread(3) clone.
Definition: rpmio.c:2412
const char * rpmmgBuffer(rpmmg mg, const char *b, size_t nb)
Return magic string for a buffer.
Definition: rpmmg.c:142
int Fclose(FD_t fd)
fclose(3) clone.
Definition: rpmio.c:2534
int Ferror(FD_t fd)
ferror(3) clone.
Definition: rpmio.c:2944
urltype urlPath(const char *url, const char **pathp)
Return path component of URL.
Definition: url.c:429
rpmioPool rpmioNewPool(const char *name, size_t size, int limit, int flags, char *(*dbg)(void *item), void(*init)(void *item), void(*fini)(void *item))
Create a memory pool.
Definition: rpmmalloc.c:110
struct rpmmg_s * rpmmg
Definition: rpmmg.h:15
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
#define _(Text)
Definition: system.h:30
rpmmg rpmmgFree(rpmmg mg)
Destroy a magic wrapper.