plugindescr.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003  -------------------
00004  cvs         : $Id$
00005  begin       : Thu Apr 03 2003
00006  copyright   : (C) 2003 by Martin Preuss
00007  email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
00025  *                                                                         *
00026  ***************************************************************************/
00027 
00028 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031 
00032 #include "plugindescr_p.h"
00033 #include "i18n_l.h"
00034 #include <gwenhywfar/buffer.h>
00035 #include <gwenhywfar/debug.h>
00036 #include <gwenhywfar/directory.h>
00037 #include <gwenhywfar/bio_buffer.h>
00038 
00039 #include <sys/types.h>
00040 #include <sys/stat.h>
00041 #ifdef HAVE_UNISTD_H
00042 # include <unistd.h>
00043 #endif
00044 #include <errno.h>
00045 #include <string.h>
00046 #ifdef HAVE_STRINGS_H
00047 # include <strings.h>
00048 #endif
00049 
00050 
00051 
00052 GWEN_LIST_FUNCTIONS(GWEN_PLUGIN_DESCRIPTION, GWEN_PluginDescription)
00053 GWEN_LIST2_FUNCTIONS(GWEN_PLUGIN_DESCRIPTION, GWEN_PluginDescription)
00054 
00055 
00056 
00057 GWEN_PLUGIN_DESCRIPTION *GWEN_PluginDescription_new(GWEN_XMLNODE *node){
00058   GWEN_PLUGIN_DESCRIPTION *pd;
00059   const char *p;
00060 
00061   GWEN_NEW_OBJECT(GWEN_PLUGIN_DESCRIPTION, pd);
00062   DBG_MEM_INC("GWEN_PLUGIN_DESCRIPTION", 0);
00063   GWEN_LIST_INIT(GWEN_PLUGIN_DESCRIPTION, pd);
00064   p=GWEN_XMLNode_GetProperty(node, "name", 0);
00065   if (!p) {
00066     DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed plugin");
00067     GWEN_PluginDescription_free(pd);
00068     return 0;
00069   }
00070   pd->name=strdup(p);
00071   pd->xmlNode=GWEN_XMLNode_dup(node);
00072   p=GWEN_XMLNode_GetProperty(node, "type", 0);
00073   if (!p) {
00074     DBG_ERROR(GWEN_LOGDOMAIN, "Plugin has no type");
00075     GWEN_PluginDescription_free(pd);
00076     return 0;
00077   }
00078   pd->type=strdup(p);
00079   p=GWEN_XMLNode_GetLocalizedCharValue(node, "version", 0);
00080   if (p)
00081     pd->version=strdup(p);
00082   p=GWEN_XMLNode_GetLocalizedCharValue(node, "author", 0);
00083   if (p)
00084     pd->author=strdup(p);
00085   p=GWEN_XMLNode_GetLocalizedCharValue(node, "short", 0);
00086   if (p)
00087     pd->shortDescr=strdup(p);
00088   p=GWEN_XMLNode_GetLocalizedCharValue(node, "descr", 0);
00089   if (p)
00090     pd->longDescr=strdup(p);
00091   return pd;
00092 }
00093 
00094 
00095 
00096 void GWEN_PluginDescription_free(GWEN_PLUGIN_DESCRIPTION *pd){
00097   if (pd) {
00098     DBG_MEM_DEC("GWEN_PLUGIN_DESCRIPTION");
00099     GWEN_LIST_FINI(GWEN_PLUGIN_DESCRIPTION, pd);
00100     free(pd->path);
00101     GWEN_XMLNode_free(pd->xmlNode);
00102     free(pd->fileName);
00103     free(pd->longDescr);
00104     free(pd->shortDescr);
00105     free(pd->author);
00106     free(pd->version);
00107     free(pd->type);
00108     free(pd->name);
00109     GWEN_FREE_OBJECT(pd);
00110   }
00111 }
00112 
00113 
00114 
00115 GWEN_PLUGIN_DESCRIPTION*
00116 GWEN_PluginDescription_dup(const GWEN_PLUGIN_DESCRIPTION *pd) {
00117   GWEN_PLUGIN_DESCRIPTION *np;
00118   const char *s;
00119 
00120   assert(pd);
00121   GWEN_NEW_OBJECT(GWEN_PLUGIN_DESCRIPTION, np);
00122   DBG_MEM_INC("GWEN_PLUGIN_DESCRIPTION", 0);
00123   GWEN_LIST_INIT(GWEN_PLUGIN_DESCRIPTION, np);
00124 
00125   s=pd->fileName;
00126   if (s) np->fileName=strdup(s);
00127 
00128   s=pd->path;
00129   if (s) np->path=strdup(s);
00130   s=pd->name;
00131   if (s) np->name=strdup(s);
00132   s=pd->type;
00133   if (s) np->type=strdup(s);
00134   s=pd->shortDescr;
00135   if (s) np->shortDescr=strdup(s);
00136   s=pd->author;
00137   if (s) np->author=strdup(s);
00138   s=pd->version;
00139   if (s) np->version=strdup(s);
00140   s=pd->longDescr;
00141   if (s) np->longDescr=strdup(s);
00142   np->isActive=pd->isActive;
00143   if (pd->xmlNode)
00144     np->xmlNode=GWEN_XMLNode_dup(pd->xmlNode);
00145 
00146   return np;
00147 }
00148 
00149 
00150 
00151 GWEN_PLUGIN_DESCRIPTION*
00152 GWEN_PluginDescription_List2_freeAll_cb(GWEN_PLUGIN_DESCRIPTION *pd, 
00153                                         __attribute__((unused)) void *user_data) {
00154   GWEN_PluginDescription_free(pd);
00155   return 0;
00156 }
00157 
00158 
00159 
00160 void GWEN_PluginDescription_List2_freeAll(GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl){
00161   GWEN_PluginDescription_List2_ForEach
00162     (pdl,
00163      GWEN_PluginDescription_List2_freeAll_cb,
00164      0);
00165   GWEN_PluginDescription_List2_free(pdl);
00166 }
00167 
00168 
00169 
00170 const char *GWEN_PluginDescription_GetPath(const GWEN_PLUGIN_DESCRIPTION *pd){
00171   assert(pd);
00172   return pd->path;
00173 }
00174 
00175 
00176 
00177 void GWEN_PluginDescription_SetPath(GWEN_PLUGIN_DESCRIPTION *pd,
00178                                     const char *s){
00179   assert(pd);
00180   free(pd->path);
00181   if (s) pd->path=strdup(s);
00182   else pd->path=0;
00183 }
00184 
00185 
00186 
00187 const char *GWEN_PluginDescription_GetName(const GWEN_PLUGIN_DESCRIPTION *pd){
00188   assert(pd);
00189   return pd->name;
00190 }
00191 
00192 
00193 
00194 const char *GWEN_PluginDescription_GetType(const GWEN_PLUGIN_DESCRIPTION *pd){
00195   assert(pd);
00196   return pd->type;
00197 }
00198 
00199 
00200 
00201 const char*
00202 GWEN_PluginDescription_GetShortDescr(const GWEN_PLUGIN_DESCRIPTION *pd){
00203   assert(pd);
00204   return pd->shortDescr;
00205 }
00206 
00207 
00208 
00209 const char*
00210 GWEN_PluginDescription_GetAuthor(const GWEN_PLUGIN_DESCRIPTION *pd){
00211   assert(pd);
00212   return pd->author;
00213 }
00214 
00215 
00216 
00217 const char*
00218 GWEN_PluginDescription_GetVersion(const GWEN_PLUGIN_DESCRIPTION *pd){
00219   assert(pd);
00220   return pd->version;
00221 }
00222 
00223 
00224 
00225 const char*
00226 GWEN_PluginDescription_GetLongDescr(const GWEN_PLUGIN_DESCRIPTION *pd){
00227   assert(pd);
00228   return pd->longDescr;
00229 }
00230 
00231 
00232 
00233 int
00234 GWEN_PluginDescription__GetLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd,
00235                                              const char *s,
00236                                              GWEN_BUFFER *buf){
00237   GWEN_XMLNODE *n;
00238 
00239   assert(pd);
00240   assert(pd->xmlNode);
00241 
00242   n=GWEN_XMLNode_FindFirstTag(pd->xmlNode, "descr", 0, 0);
00243   if (n) {
00244     n=GWEN_XMLNode_FindFirstTag(n, "text", "format", s);
00245     while (n) {
00246       if (0==GWEN_XMLNode_GetProperty(n, "lang", 0)) {
00247         int rv;
00248 
00249         rv=GWEN_XMLNode_toBuffer(n, buf, GWEN_XML_FLAGS_TOLERANT_ENDTAGS);
00250         if (rv) {
00251           DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00252           return rv;
00253         }
00254         return 0;
00255       }
00256       n=GWEN_XMLNode_FindNextTag(n, "text", "format", s);
00257     } /* while */
00258   }
00259 
00260   return -1;
00261 }
00262 
00263 
00264 
00265 int
00266 GWEN_PluginDescription__GetLocalizedLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd,
00267                                                       const char *s,
00268                                                       const char *lang,
00269                                                       GWEN_BUFFER *buf){
00270   GWEN_XMLNODE *n;
00271 
00272   assert(pd);
00273   assert(pd->xmlNode);
00274 
00275   n=GWEN_XMLNode_FindFirstTag(pd->xmlNode, "descr", 0, 0);
00276   if (n) {
00277     n=GWEN_XMLNode_FindFirstTag(n, "text", "lang", lang);
00278     while (n) {
00279       const char *fmt;
00280 
00281       fmt=GWEN_XMLNode_GetProperty(n, "format", 0);
00282       if (fmt && strcasecmp(fmt, s)==0) {
00283         int rv;
00284 
00285         rv=GWEN_XMLNode_toBuffer(n, buf, GWEN_XML_FLAGS_TOLERANT_ENDTAGS);
00286         if (rv) {
00287           DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00288           return rv;
00289         }
00290         return 0;
00291       }
00292       n=GWEN_XMLNode_FindNextTag(n, "text", "lang", lang);
00293     } /* while */
00294   }
00295 
00296   return -1;
00297 }
00298 
00299 
00300 
00301 int
00302 GWEN_PluginDescription_GetLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd,
00303                                             const char *s,
00304                                             GWEN_BUFFER *buf){
00305   GWEN_STRINGLIST *langl;
00306   int rv;
00307 
00308   langl=GWEN_I18N_GetCurrentLocaleList();
00309   if (langl) {
00310     GWEN_STRINGLISTENTRY *se;
00311 
00312     se=GWEN_StringList_FirstEntry(langl);
00313     while(se) {
00314       const char *l;
00315 
00316       l=GWEN_StringListEntry_Data(se);
00317       DBG_NOTICE(GWEN_LOGDOMAIN, "Trying locale \"%s\"", l);
00318       assert(l);
00319 
00320       rv=GWEN_PluginDescription__GetLocalizedLongDescrByFormat(pd,
00321                                                                s,
00322                                                                l,
00323                                                                buf);
00324       if (rv==0)
00325         return rv;
00326 
00327       se=GWEN_StringListEntry_Next(se);
00328     } /* while */
00329   } /* if language list available */
00330 
00331   /* no localized version found, return text for default language */
00332   rv=GWEN_PluginDescription__GetLongDescrByFormat(pd, s, buf);
00333   if (rv) {
00334     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00335     return rv;
00336   }
00337 
00338   return 0;
00339 }
00340 
00341 
00342 const char*
00343 GWEN_PluginDescription_GetFileName(const GWEN_PLUGIN_DESCRIPTION *pd){
00344   assert(pd);
00345   return pd->fileName;
00346 }
00347 
00348 
00349 
00350 void GWEN_PluginDescription_SetFileName(GWEN_PLUGIN_DESCRIPTION *pd,
00351                                         const char *s){
00352   assert(pd);
00353   free(pd->fileName);
00354   if (s) pd->fileName=strdup(s);
00355   else pd->fileName=0;
00356 }
00357 
00358 
00359 
00360 GWEN_XMLNODE*
00361 GWEN_PluginDescription_GetXmlNode(const GWEN_PLUGIN_DESCRIPTION *pd){
00362   assert(pd);
00363   return pd->xmlNode;
00364 }
00365 
00366 
00367 
00368 GWEN_PLUGIN_DESCRIPTION_LIST2 *GWEN_LoadPluginDescrs(const char *path) {
00369   GWEN_PLUGIN_DESCRIPTION_LIST2 *pl;
00370   int rv;
00371 
00372   pl=GWEN_PluginDescription_List2_new();
00373 
00374   rv=GWEN_LoadPluginDescrsByType(path, 0, pl);
00375   if (GWEN_PluginDescription_List2_GetSize(pl)==0) {
00376     GWEN_PluginDescription_List2_free(pl);
00377     return 0;
00378   }
00379   return pl;
00380 }
00381 
00382 
00383 
00384 int GWEN_PluginDescription_IsActive(const GWEN_PLUGIN_DESCRIPTION *pd){
00385   assert(pd);
00386   return pd->isActive;
00387 }
00388 
00389 
00390 
00391 void GWEN_PluginDescription_SetIsActive(GWEN_PLUGIN_DESCRIPTION *pd, int i){
00392   assert(pd);
00393   pd->isActive=i;
00394 }
00395 
00396 
00397 
00398 int GWEN_LoadPluginDescrsByType(const char *path,
00399                                 const char *type,
00400                                 GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl){
00401   GWEN_DIRECTORY *d;
00402   GWEN_BUFFER *nbuf;
00403   char nbuffer[64];
00404   unsigned int pathLen;
00405 
00406   if (!path)
00407     path="";
00408 
00409   /* create path */
00410   nbuf=GWEN_Buffer_new(0, 256, 0, 1);
00411   GWEN_Buffer_AppendString(nbuf, path);
00412   pathLen=GWEN_Buffer_GetUsedBytes(nbuf);
00413 
00414   d=GWEN_Directory_new();
00415   if (GWEN_Directory_Open(d, GWEN_Buffer_GetStart(nbuf))) {
00416     DBG_INFO(GWEN_LOGDOMAIN,
00417              "Path \"%s\" is not available",
00418              GWEN_Buffer_GetStart(nbuf));
00419     GWEN_Buffer_free(nbuf);
00420     GWEN_Directory_free(d);
00421     return -1;
00422   }
00423 
00424   while(!GWEN_Directory_Read(d,
00425                              nbuffer,
00426                              sizeof(nbuffer))) {
00427     if (strcmp(nbuffer, ".") &&
00428         strcmp(nbuffer, "..")) {
00429       int nlen;
00430 
00431       nlen=strlen(nbuffer);
00432       if (nlen>3) {
00433         if (strcasecmp(nbuffer+nlen-4, ".xml")==0) {
00434           struct stat st;
00435 
00436           GWEN_Buffer_Crop(nbuf, 0, pathLen);
00437           GWEN_Buffer_SetPos(nbuf, pathLen);
00438           GWEN_Buffer_AppendByte(nbuf, GWEN_DIR_SEPARATOR);
00439           GWEN_Buffer_AppendString(nbuf, nbuffer);
00440 
00441           if (stat(GWEN_Buffer_GetStart(nbuf), &st)) {
00442             DBG_ERROR(GWEN_LOGDOMAIN, "stat(%s): %s",
00443                       GWEN_Buffer_GetStart(nbuf),
00444                       strerror(errno));
00445           }
00446           else {
00447             if (!S_ISDIR(st.st_mode)) {
00448               GWEN_XMLNODE *fileNode;
00449 
00450               fileNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
00451               if (GWEN_XML_ReadFile(fileNode,
00452                                     GWEN_Buffer_GetStart(nbuf),
00453                                     GWEN_XML_FLAGS_DEFAULT |
00454                                     GWEN_XML_FLAGS_HANDLE_HEADERS |
00455                                     GWEN_XML_FLAGS_HANDLE_OPEN_HTMLTAGS)) {
00456                 DBG_WARN(GWEN_LOGDOMAIN,
00457                          "Bad file \"%s\"", GWEN_Buffer_GetStart(nbuf));
00458               }
00459               else {
00460                 GWEN_XMLNODE *node;
00461                 GWEN_XMLNODE *n;
00462                 GWEN_STRINGLIST *langl;
00463 
00464                 n=0;
00465                 node=GWEN_XMLNode_FindFirstTag(fileNode, "PluginDescr", 0, 0);
00466                 if (!node)
00467                   node=fileNode;
00468                 langl=GWEN_I18N_GetCurrentLocaleList();
00469                 if (langl) {
00470                   GWEN_STRINGLISTENTRY *se;
00471 
00472                   se=GWEN_StringList_FirstEntry(langl);
00473                   while(se) {
00474                     const char *l;
00475 
00476                     l=GWEN_StringListEntry_Data(se);
00477                     DBG_DEBUG(GWEN_LOGDOMAIN, "Trying locale \"%s\"", l);
00478                     assert(l);
00479                     n=GWEN_XMLNode_FindFirstTag(node, "plugin", "lang", l);
00480                     if (n)
00481                       break;
00482                     se=GWEN_StringListEntry_Next(se);
00483                   } /* while */
00484                 } /* if language list available */
00485 
00486                 if (!n)
00487                   n=GWEN_XMLNode_FindFirstTag(node, "plugin", 0, 0);
00488                 if (n) {
00489                   GWEN_PLUGIN_DESCRIPTION *pd;
00490                   int loadIt;
00491 
00492                   loadIt=1;
00493                   if (type) {
00494                     const char *ft;
00495 
00496                     ft=GWEN_XMLNode_GetProperty(n, "type", 0);
00497                     if (!ft)
00498                       loadIt=0;
00499                     else if (strcasecmp(ft, type)!=0){
00500                       loadIt=0;
00501                     }
00502                   } /* if type specified */
00503                   if (loadIt) {
00504                     pd=GWEN_PluginDescription_new(n);
00505                     if (!pd) {
00506                       DBG_WARN(GWEN_LOGDOMAIN, "Bad plugin description");
00507                     }
00508                     else {
00509                       GWEN_PluginDescription_SetFileName
00510                         (pd, GWEN_Buffer_GetStart(nbuf));
00511                       GWEN_Buffer_Crop(nbuf, 0, pathLen);
00512                       GWEN_Buffer_SetPos(nbuf, pathLen);
00513                       GWEN_PluginDescription_SetPath
00514                         (pd, GWEN_Buffer_GetStart(nbuf));
00515                       GWEN_PluginDescription_List2_PushBack(pdl, pd);
00516                     }
00517                   } /* if loadIt */
00518                   else {
00519                     DBG_INFO(GWEN_LOGDOMAIN,
00520                              "Ignoring file \"%s\" (bad/missing type)",
00521                              GWEN_Buffer_GetStart(nbuf));
00522                   }
00523                 }
00524                 else {
00525                   DBG_WARN(GWEN_LOGDOMAIN,
00526                            "File \"%s\" does not contain a plugin "
00527                            "description",
00528                            GWEN_Buffer_GetStart(nbuf));
00529                 }
00530               }
00531               GWEN_XMLNode_free(fileNode);
00532             } /* if !dir */
00533           } /* if stat was ok */
00534         } /* if XML */
00535       } /* if name has more than 3 chars */
00536     } /* if not "." and not ".." */
00537   } /* while */
00538   GWEN_Directory_Close(d);
00539   GWEN_Directory_free(d);
00540   GWEN_Buffer_free(nbuf);
00541 
00542   return 0;
00543 }
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 
00555 
Generated on Mon Jul 5 22:51:15 2010 for gwenhywfar by  doxygen 1.6.3