rpm 5.3.12
rpmio/rpmmg.c
Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #if defined(HAVE_MAGIC_H)
00008 #include "magic.h"
00009 #endif
00010 
00011 #include <rpmiotypes.h>
00012 #include <rpmio.h>      /* for *Pool methods */
00013 #include <rpmlog.h>
00014 #include <rpmurl.h>
00015 #define _RPMMG_INTERNAL
00016 #include <rpmmg.h>
00017 
00018 #include "debug.h"
00019 
00020 /*@unchecked@*/
00021 int _rpmmg_debug = 0;
00022 
00023 /*@-mustmod@*/  /* XXX splint on crack */
00024 static void rpmmgFini(void * _mg)
00025         /*@globals fileSystem @*/
00026         /*@modifies *_mg, fileSystem @*/
00027 {
00028     rpmmg mg = _mg;
00029 
00030 #if defined(HAVE_MAGIC_H)
00031     if (mg->ms) {
00032         magic_close(mg->ms);
00033         mg->ms = NULL;
00034     }
00035 #endif
00036     mg->fn = _free(mg->fn);
00037 }
00038 /*@=mustmod@*/
00039 
00040 /*@unchecked@*/ /*@only@*/ /*@null@*/
00041 rpmioPool _rpmmgPool = NULL;
00042 
00043 static rpmmg rpmmgGetPool(/*@null@*/ rpmioPool pool)
00044         /*@globals _rpmmgPool, fileSystem @*/
00045         /*@modifies pool, _rpmmgPool, fileSystem @*/
00046 {
00047     rpmmg mg;
00048 
00049     if (_rpmmgPool == NULL) {
00050         _rpmmgPool = rpmioNewPool("mg", sizeof(*mg), -1, _rpmmg_debug,
00051                         NULL, NULL, rpmmgFini);
00052         pool = _rpmmgPool;
00053     }
00054     return (rpmmg) rpmioGetPool(pool, sizeof(*mg));
00055 }
00056 
00057 rpmmg rpmmgNew(const char * fn, int flags)
00058 {
00059     rpmmg mg = rpmmgGetPool(_rpmmgPool);
00060     int xx;
00061 
00062     if (fn)
00063         mg->fn = xstrdup(fn);
00064 #if defined(HAVE_MAGIC_H)
00065     mg->flags = (flags ? flags : MAGIC_CHECK);/* XXX MAGIC_COMPRESS flag? */
00066     mg->ms = magic_open(flags);
00067     if (mg->ms == NULL) {
00068         rpmlog(RPMLOG_ERR, _("magic_open(0x%x) failed: %s\n"),
00069                 flags, strerror(errno));
00070         return rpmmgFree(mg);
00071     }
00072     xx = magic_load(mg->ms, mg->fn);
00073     if (xx == -1) {
00074         rpmlog(RPMLOG_ERR, _("magic_load(ms, %s) failed: %s\n"),
00075                 (fn ? fn : "(nil)"), magic_error(mg->ms));
00076         return rpmmgFree(mg);
00077     }
00078 #endif
00079 
00080     return rpmmgLink(mg);
00081 }
00082 
00083 const char * rpmmgFile(rpmmg mg, const char *fn)
00084 {
00085     const char * t = NULL;
00086 
00087 if (_rpmmg_debug)
00088 fprintf(stderr, "--> rpmmgFile(%p, %s)\n", mg, (fn ? fn : "(nil)"));
00089 #if defined(HAVE_MAGIC_H)
00090     if (mg->ms) {
00091         const char * lpath = NULL;
00092         int ut = urlPath(fn, &lpath);
00093 
00094         switch (ut) {
00095         case URL_IS_FTP:
00096         case URL_IS_HKP:
00097         case URL_IS_HTTP:
00098         case URL_IS_HTTPS:
00099         {   char b[512];
00100             size_t nb = 0;
00101             FD_t fd;
00102             
00103             fd = Fopen(fn, "r.ufdio");
00104             if (fd != NULL && !Ferror(fd)) {
00105                 nb = Fread(b, 1, sizeof(b), fd);
00106                 (void) Fclose(fd);
00107             }
00108             if (nb > 0)
00109                 return rpmmgBuffer(mg, b, nb);
00110         }   break;
00111         case URL_IS_DASH:
00112             break;
00113         case URL_IS_PATH:
00114             fn = lpath;
00115             /*@fallthrough@*/
00116         case URL_IS_UNKNOWN:
00117         default:
00118             t = magic_file(mg->ms, fn);
00119             /* XXX HACK: libmagic compiled without <pcreposix.h> spews here. */
00120             if (t == NULL) {
00121                 const char * msg = magic_error(mg->ms);
00122                 if (strstr(msg, "regexec error 17, (match failed)") == NULL)
00123                     rpmlog(RPMLOG_ERR, _("magic_file(ms, %s) failed: %s\n"),
00124                             (fn ? fn : "(nil)"), msg);
00125             }
00126             break;
00127         }
00128     }
00129 #endif
00130 
00131     if (t == NULL) t = "";
00132     t = xstrdup(t);
00133 
00134 if (_rpmmg_debug)
00135 fprintf(stderr, "<-- rpmmgFile(%p, %s) %s\n", mg, (fn ? fn : "(nil)"), t);
00136     return t;
00137 }
00138 
00139 const char * rpmmgBuffer(rpmmg mg, const char * b, size_t nb)
00140 {
00141     const char * t = NULL;
00142 
00143 if (_rpmmg_debug)
00144 fprintf(stderr, "--> rpmmgBuffer(%p, %p[%d])\n", mg, b, (int)nb);
00145     if (nb == 0) nb = strlen(b);
00146 #if defined(HAVE_MAGIC_H)
00147     if (mg->ms) {
00148         t = magic_buffer(mg->ms, b, nb);
00149         /* XXX HACK: libmagic compiled without <pcreposix.h> spews here. */
00150         if (t == NULL) {
00151             const char * msg = magic_error(mg->ms);
00152             if (strstr(msg, "regexec error 17, (match failed)") == NULL)
00153                 rpmlog(RPMLOG_ERR, _("magic_buffer(ms, %p[%u]) failed: %s\n"),
00154                         b, (unsigned)nb, msg);
00155         }
00156     }
00157 #endif
00158 
00159     if (t == NULL) t = "";
00160     t = xstrdup(t);
00161 
00162 if (_rpmmg_debug)
00163 fprintf(stderr, "<-- rpmmgBuffer(%p, %p[%d]) %s\n", mg, b, (int)nb, t);
00164     return t;
00165 }