gwenhywfar 4.0.3

plugindescr.c

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