rpm  5.4.4
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         case URL_IS_MONGO:      /* XXX FIXME */
00113             break;
00114         case URL_IS_PATH:
00115             fn = lpath;
00116             /*@fallthrough@*/
00117         case URL_IS_UNKNOWN:
00118         default:
00119             t = magic_file(mg->ms, fn);
00120             /* XXX HACK: libmagic compiled without <pcreposix.h> spews here. */
00121             if (t == NULL) {
00122                 const char * msg = magic_error(mg->ms);
00123                 if (strstr(msg, "regexec error 17, (match failed)") == NULL)
00124                     rpmlog(RPMLOG_ERR, _("magic_file(ms, %s) failed: %s\n"),
00125                             (fn ? fn : "(nil)"), msg);
00126             }
00127             break;
00128         }
00129     }
00130 #endif
00131 
00132     if (t == NULL) t = "";
00133     t = xstrdup(t);
00134 
00135 if (_rpmmg_debug)
00136 fprintf(stderr, "<-- rpmmgFile(%p, %s) %s\n", mg, (fn ? fn : "(nil)"), t);
00137     return t;
00138 }
00139 
00140 const char * rpmmgBuffer(rpmmg mg, const char * b, size_t nb)
00141 {
00142     const char * t = NULL;
00143 
00144 if (_rpmmg_debug)
00145 fprintf(stderr, "--> rpmmgBuffer(%p, %p[%d])\n", mg, b, (int)nb);
00146     if (nb == 0) nb = strlen(b);
00147 #if defined(HAVE_MAGIC_H)
00148     if (mg->ms) {
00149         t = magic_buffer(mg->ms, b, nb);
00150         /* XXX HACK: libmagic compiled without <pcreposix.h> spews here. */
00151         if (t == NULL) {
00152             const char * msg = magic_error(mg->ms);
00153             if (strstr(msg, "regexec error 17, (match failed)") == NULL)
00154                 rpmlog(RPMLOG_ERR, _("magic_buffer(ms, %p[%u]) failed: %s\n"),
00155                         b, (unsigned)nb, msg);
00156         }
00157     }
00158 #endif
00159 
00160     if (t == NULL) t = "";
00161     t = xstrdup(t);
00162 
00163 if (_rpmmg_debug)
00164 fprintf(stderr, "<-- rpmmgBuffer(%p, %p[%d]) %s\n", mg, b, (int)nb, t);
00165     return t;
00166 }