gwenhywfar  4.3.1
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 #include <gwenhywfar/i18n.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   pd->refCount=1;
00063   DBG_MEM_INC("GWEN_PLUGIN_DESCRIPTION", 0);
00064   GWEN_LIST_INIT(GWEN_PLUGIN_DESCRIPTION, pd);
00065   p=GWEN_XMLNode_GetProperty(node, "name", 0);
00066   if (!p) {
00067     DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed plugin");
00068     GWEN_PluginDescription_free(pd);
00069     return 0;
00070   }
00071   pd->name=strdup(p);
00072   pd->xmlNode=GWEN_XMLNode_dup(node);
00073 
00074   p=GWEN_XMLNode_GetProperty(node, "i18n", NULL);
00075   if (!p) {
00076     DBG_WARN(GWEN_LOGDOMAIN, "Plugin has no I18N domain, using GWEN");
00077     p="gwenhywfar";
00078   }
00079   pd->langDomain=strdup(p);
00080 
00081   p=GWEN_XMLNode_GetProperty(node, "type", 0);
00082   if (!p) {
00083     DBG_ERROR(GWEN_LOGDOMAIN, "Plugin has no type");
00084     GWEN_PluginDescription_free(pd);
00085     return 0;
00086   }
00087   pd->type=strdup(p);
00088 
00089   p=GWEN_XMLNode_GetCharValue(node, "version", 0);
00090   if (p)
00091     pd->version=strdup(p);
00092   p=GWEN_XMLNode_GetCharValue(node, "author", 0);
00093   if (p)
00094     pd->author=strdup(p);
00095   p=GWEN_XMLNode_GetCharValue(node, "short", 0);
00096   if (p)
00097     pd->shortDescr=strdup(p);
00098   p=GWEN_XMLNode_GetCharValue(node, "descr", 0);
00099   if (p)
00100     pd->longDescr=strdup(p);
00101   return pd;
00102 }
00103 
00104 
00105 
00106 void GWEN_PluginDescription_free(GWEN_PLUGIN_DESCRIPTION *pd){
00107   if (pd) {
00108     assert(pd->refCount);
00109     if (pd->refCount==1) {
00110       DBG_MEM_DEC("GWEN_PLUGIN_DESCRIPTION");
00111       GWEN_LIST_FINI(GWEN_PLUGIN_DESCRIPTION, pd);
00112       free(pd->path);
00113       GWEN_XMLNode_free(pd->xmlNode);
00114       free(pd->fileName);
00115       free(pd->longDescr);
00116       free(pd->shortDescr);
00117       free(pd->author);
00118       free(pd->version);
00119       free(pd->langDomain);
00120       free(pd->type);
00121       free(pd->name);
00122       pd->refCount=0;
00123       GWEN_FREE_OBJECT(pd);
00124     }
00125     else
00126       pd->refCount--;
00127   }
00128 }
00129 
00130 
00131 
00132 void GWEN_PluginDescription_Attach(GWEN_PLUGIN_DESCRIPTION *pd) {
00133   assert(pd);
00134   assert(pd->refCount);
00135   pd->refCount++;
00136 }
00137 
00138 
00139 
00140 GWEN_PLUGIN_DESCRIPTION*
00141 GWEN_PluginDescription_dup(const GWEN_PLUGIN_DESCRIPTION *pd) {
00142   GWEN_PLUGIN_DESCRIPTION *np;
00143   const char *s;
00144 
00145   assert(pd);
00146   GWEN_NEW_OBJECT(GWEN_PLUGIN_DESCRIPTION, np);
00147   np->refCount=1;
00148   DBG_MEM_INC("GWEN_PLUGIN_DESCRIPTION", 0);
00149   GWEN_LIST_INIT(GWEN_PLUGIN_DESCRIPTION, np);
00150 
00151   s=pd->fileName;
00152   if (s) np->fileName=strdup(s);
00153 
00154   s=pd->path;
00155   if (s) np->path=strdup(s);
00156   s=pd->name;
00157   if (s) np->name=strdup(s);
00158   s=pd->type;
00159   if (s) np->type=strdup(s);
00160   s=pd->langDomain;
00161   if (s) np->langDomain=strdup(s);
00162   s=pd->shortDescr;
00163   if (s) np->shortDescr=strdup(s);
00164   s=pd->author;
00165   if (s) np->author=strdup(s);
00166   s=pd->version;
00167   if (s) np->version=strdup(s);
00168   s=pd->longDescr;
00169   if (s) np->longDescr=strdup(s);
00170   np->isActive=pd->isActive;
00171   if (pd->xmlNode)
00172     np->xmlNode=GWEN_XMLNode_dup(pd->xmlNode);
00173 
00174   return np;
00175 }
00176 
00177 
00178 
00179 GWEN_PLUGIN_DESCRIPTION*
00180 GWEN_PluginDescription_List2_freeAll_cb(GWEN_PLUGIN_DESCRIPTION *pd, 
00181                                         __attribute__((unused)) void *user_data) {
00182   GWEN_PluginDescription_free(pd);
00183   return 0;
00184 }
00185 
00186 
00187 
00188 void GWEN_PluginDescription_List2_freeAll(GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl){
00189   GWEN_PluginDescription_List2_ForEach
00190     (pdl,
00191      GWEN_PluginDescription_List2_freeAll_cb,
00192      0);
00193   GWEN_PluginDescription_List2_free(pdl);
00194 }
00195 
00196 
00197 
00198 const char *GWEN_PluginDescription_GetPath(const GWEN_PLUGIN_DESCRIPTION *pd){
00199   assert(pd);
00200   return pd->path;
00201 }
00202 
00203 
00204 
00205 void GWEN_PluginDescription_SetPath(GWEN_PLUGIN_DESCRIPTION *pd,
00206                                     const char *s){
00207   assert(pd);
00208   free(pd->path);
00209   if (s) pd->path=strdup(s);
00210   else pd->path=0;
00211 }
00212 
00213 
00214 
00215 const char *GWEN_PluginDescription_GetName(const GWEN_PLUGIN_DESCRIPTION *pd){
00216   assert(pd);
00217   return pd->name;
00218 }
00219 
00220 
00221 
00222 const char *GWEN_PluginDescription_GetType(const GWEN_PLUGIN_DESCRIPTION *pd){
00223   assert(pd);
00224   return pd->type;
00225 }
00226 
00227 
00228 
00229 const char*
00230 GWEN_PluginDescription_GetShortDescr(const GWEN_PLUGIN_DESCRIPTION *pd){
00231   assert(pd);
00232   return GWEN_I18N_Translate(pd->langDomain, pd->shortDescr);
00233 }
00234 
00235 
00236 
00237 const char*
00238 GWEN_PluginDescription_GetAuthor(const GWEN_PLUGIN_DESCRIPTION *pd){
00239   assert(pd);
00240   return pd->author;
00241 }
00242 
00243 
00244 
00245 const char*
00246 GWEN_PluginDescription_GetVersion(const GWEN_PLUGIN_DESCRIPTION *pd){
00247   assert(pd);
00248   return pd->version;
00249 }
00250 
00251 
00252 
00253 const char*
00254 GWEN_PluginDescription_GetLongDescr(const GWEN_PLUGIN_DESCRIPTION *pd){
00255   assert(pd);
00256   return GWEN_I18N_Translate(pd->langDomain, pd->longDescr);
00257 }
00258 
00259 
00260 
00261 int
00262 GWEN_PluginDescription__GetLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd,
00263                                              const char *s,
00264                                              GWEN_BUFFER *buf){
00265   GWEN_XMLNODE *n;
00266 
00267   assert(pd);
00268   assert(pd->xmlNode);
00269 
00270   n=GWEN_XMLNode_FindFirstTag(pd->xmlNode, "descr", 0, 0);
00271   if (n) {
00272     n=GWEN_XMLNode_FindFirstTag(n, "text", "format", s);
00273     while (n) {
00274       if (0==GWEN_XMLNode_GetProperty(n, "lang", 0)) {
00275         int rv;
00276 
00277         rv=GWEN_XMLNode_toBuffer(n, buf, GWEN_XML_FLAGS_TOLERANT_ENDTAGS);
00278         if (rv) {
00279           DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00280           return rv;
00281         }
00282         return 0;
00283       }
00284       n=GWEN_XMLNode_FindNextTag(n, "text", "format", s);
00285     } /* while */
00286   }
00287 
00288   return -1;
00289 }
00290 
00291 
00292 
00293 int
00294 GWEN_PluginDescription__GetLocalizedLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd,
00295                                                       const char *s,
00296                                                       const char *lang,
00297                                                       GWEN_BUFFER *buf){
00298   GWEN_XMLNODE *n;
00299 
00300   assert(pd);
00301   assert(pd->xmlNode);
00302 
00303   n=GWEN_XMLNode_FindFirstTag(pd->xmlNode, "descr", 0, 0);
00304   if (n) {
00305     n=GWEN_XMLNode_FindFirstTag(n, "text", "lang", lang);
00306     while (n) {
00307       const char *fmt;
00308 
00309       fmt=GWEN_XMLNode_GetProperty(n, "format", 0);
00310       if (fmt && strcasecmp(fmt, s)==0) {
00311         int rv;
00312 
00313         rv=GWEN_XMLNode_toBuffer(n, buf, GWEN_XML_FLAGS_TOLERANT_ENDTAGS);
00314         if (rv) {
00315           DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00316           return rv;
00317         }
00318         return 0;
00319       }
00320       n=GWEN_XMLNode_FindNextTag(n, "text", "lang", lang);
00321     } /* while */
00322   }
00323 
00324   return -1;
00325 }
00326 
00327 
00328 
00329 int
00330 GWEN_PluginDescription_GetLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd,
00331                                             const char *s,
00332                                             GWEN_BUFFER *buf){
00333   GWEN_STRINGLIST *langl;
00334   int rv;
00335 
00336   langl=GWEN_I18N_GetCurrentLocaleList();
00337   if (langl) {
00338     GWEN_STRINGLISTENTRY *se;
00339 
00340     se=GWEN_StringList_FirstEntry(langl);
00341     while(se) {
00342       const char *l;
00343 
00344       l=GWEN_StringListEntry_Data(se);
00345       DBG_NOTICE(GWEN_LOGDOMAIN, "Trying locale \"%s\"", l);
00346       assert(l);
00347 
00348       rv=GWEN_PluginDescription__GetLocalizedLongDescrByFormat(pd,
00349                                                                s,
00350                                                                l,
00351                                                                buf);
00352       if (rv==0)
00353         return rv;
00354 
00355       se=GWEN_StringListEntry_Next(se);
00356     } /* while */
00357   } /* if language list available */
00358 
00359   /* no localized version found, return text for default language */
00360   rv=GWEN_PluginDescription__GetLongDescrByFormat(pd, s, buf);
00361   if (rv) {
00362     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00363     return rv;
00364   }
00365 
00366   return 0;
00367 }
00368 
00369 
00370 const char*
00371 GWEN_PluginDescription_GetFileName(const GWEN_PLUGIN_DESCRIPTION *pd){
00372   assert(pd);
00373   return pd->fileName;
00374 }
00375 
00376 
00377 
00378 void GWEN_PluginDescription_SetFileName(GWEN_PLUGIN_DESCRIPTION *pd,
00379                                         const char *s){
00380   assert(pd);
00381   free(pd->fileName);
00382   if (s) pd->fileName=strdup(s);
00383   else pd->fileName=0;
00384 }
00385 
00386 
00387 
00388 GWEN_XMLNODE*
00389 GWEN_PluginDescription_GetXmlNode(const GWEN_PLUGIN_DESCRIPTION *pd){
00390   assert(pd);
00391   return pd->xmlNode;
00392 }
00393 
00394 
00395 
00396 GWEN_PLUGIN_DESCRIPTION_LIST2 *GWEN_LoadPluginDescrs(const char *path) {
00397   GWEN_PLUGIN_DESCRIPTION_LIST2 *pl;
00398 
00399   pl=GWEN_PluginDescription_List2_new();
00400 
00401   GWEN_LoadPluginDescrsByType(path, 0, pl);
00402   if (GWEN_PluginDescription_List2_GetSize(pl)==0) {
00403     GWEN_PluginDescription_List2_free(pl);
00404     return 0;
00405   }
00406   return pl;
00407 }
00408 
00409 
00410 
00411 int GWEN_PluginDescription_IsActive(const GWEN_PLUGIN_DESCRIPTION *pd){
00412   assert(pd);
00413   return pd->isActive;
00414 }
00415 
00416 
00417 
00418 void GWEN_PluginDescription_SetIsActive(GWEN_PLUGIN_DESCRIPTION *pd, int i){
00419   assert(pd);
00420   pd->isActive=i;
00421 }
00422 
00423 
00424 
00425 int GWEN_LoadPluginDescrsByType(const char *path,
00426                                 const char *type,
00427                                 GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl){
00428   GWEN_DIRECTORY *d;
00429   GWEN_BUFFER *nbuf;
00430   char nbuffer[64];
00431   unsigned int pathLen;
00432 
00433   if (!path)
00434     path="";
00435 
00436   /* create path */
00437   nbuf=GWEN_Buffer_new(0, 256, 0, 1);
00438   GWEN_Buffer_AppendString(nbuf, path);
00439   pathLen=GWEN_Buffer_GetUsedBytes(nbuf);
00440 
00441   d=GWEN_Directory_new();
00442   if (GWEN_Directory_Open(d, GWEN_Buffer_GetStart(nbuf))) {
00443     DBG_INFO(GWEN_LOGDOMAIN,
00444              "Path \"%s\" is not available",
00445              GWEN_Buffer_GetStart(nbuf));
00446     GWEN_Buffer_free(nbuf);
00447     GWEN_Directory_free(d);
00448     return -1;
00449   }
00450 
00451   while(!GWEN_Directory_Read(d,
00452                              nbuffer,
00453                              sizeof(nbuffer))) {
00454     if (strcmp(nbuffer, ".") &&
00455         strcmp(nbuffer, "..")) {
00456       int nlen;
00457 
00458       nlen=strlen(nbuffer);
00459       if (nlen>3) {
00460         if (strcasecmp(nbuffer+nlen-4, ".xml")==0) {
00461           struct stat st;
00462 
00463           GWEN_Buffer_Crop(nbuf, 0, pathLen);
00464           GWEN_Buffer_SetPos(nbuf, pathLen);
00465           GWEN_Buffer_AppendByte(nbuf, GWEN_DIR_SEPARATOR);
00466           GWEN_Buffer_AppendString(nbuf, nbuffer);
00467 
00468           if (stat(GWEN_Buffer_GetStart(nbuf), &st)) {
00469             DBG_ERROR(GWEN_LOGDOMAIN, "stat(%s): %s",
00470                       GWEN_Buffer_GetStart(nbuf),
00471                       strerror(errno));
00472           }
00473           else {
00474             if (!S_ISDIR(st.st_mode)) {
00475               GWEN_XMLNODE *fileNode;
00476 
00477               fileNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
00478               if (GWEN_XML_ReadFile(fileNode,
00479                                     GWEN_Buffer_GetStart(nbuf),
00480                                     GWEN_XML_FLAGS_DEFAULT |
00481                                     GWEN_XML_FLAGS_HANDLE_HEADERS |
00482                                     GWEN_XML_FLAGS_HANDLE_OPEN_HTMLTAGS)) {
00483                 DBG_WARN(GWEN_LOGDOMAIN,
00484                          "Bad file \"%s\"", GWEN_Buffer_GetStart(nbuf));
00485               }
00486               else {
00487                 GWEN_XMLNODE *node;
00488                 GWEN_XMLNODE *n;
00489                 GWEN_STRINGLIST *langl;
00490 
00491                 n=0;
00492                 node=GWEN_XMLNode_FindFirstTag(fileNode, "PluginDescr", 0, 0);
00493                 if (!node)
00494                   node=fileNode;
00495                 langl=GWEN_I18N_GetCurrentLocaleList();
00496                 if (langl) {
00497                   GWEN_STRINGLISTENTRY *se;
00498 
00499                   se=GWEN_StringList_FirstEntry(langl);
00500                   while(se) {
00501                     const char *l;
00502 
00503                     l=GWEN_StringListEntry_Data(se);
00504                     DBG_DEBUG(GWEN_LOGDOMAIN, "Trying locale \"%s\"", l);
00505                     assert(l);
00506                     n=GWEN_XMLNode_FindFirstTag(node, "plugin", "lang", l);
00507                     if (n)
00508                       break;
00509                     se=GWEN_StringListEntry_Next(se);
00510                   } /* while */
00511                 } /* if language list available */
00512 
00513                 if (!n)
00514                   n=GWEN_XMLNode_FindFirstTag(node, "plugin", 0, 0);
00515                 if (n) {
00516                   GWEN_PLUGIN_DESCRIPTION *pd;
00517                   int loadIt;
00518 
00519                   loadIt=1;
00520                   if (type) {
00521                     const char *ft;
00522 
00523                     ft=GWEN_XMLNode_GetProperty(n, "type", 0);
00524                     if (!ft)
00525                       loadIt=0;
00526                     else if (strcasecmp(ft, type)!=0){
00527                       loadIt=0;
00528                     }
00529                   } /* if type specified */
00530                   if (loadIt) {
00531                     pd=GWEN_PluginDescription_new(n);
00532                     if (!pd) {
00533                       DBG_WARN(GWEN_LOGDOMAIN, "Bad plugin description");
00534                     }
00535                     else {
00536                       GWEN_PluginDescription_SetFileName
00537                         (pd, GWEN_Buffer_GetStart(nbuf));
00538                       GWEN_Buffer_Crop(nbuf, 0, pathLen);
00539                       GWEN_Buffer_SetPos(nbuf, pathLen);
00540                       GWEN_PluginDescription_SetPath
00541                         (pd, GWEN_Buffer_GetStart(nbuf));
00542                       GWEN_PluginDescription_List2_PushBack(pdl, pd);
00543                     }
00544                   } /* if loadIt */
00545                   else {
00546                     DBG_INFO(GWEN_LOGDOMAIN,
00547                              "Ignoring file \"%s\" (bad/missing type)",
00548                              GWEN_Buffer_GetStart(nbuf));
00549                   }
00550                 }
00551                 else {
00552                   DBG_WARN(GWEN_LOGDOMAIN,
00553                            "File \"%s\" does not contain a plugin "
00554                            "description",
00555                            GWEN_Buffer_GetStart(nbuf));
00556                 }
00557               }
00558               GWEN_XMLNode_free(fileNode);
00559             } /* if !dir */
00560           } /* if stat was ok */
00561         } /* if XML */
00562       } /* if name has more than 3 chars */
00563     } /* if not "." and not ".." */
00564   } /* while */
00565   GWEN_Directory_Close(d);
00566   GWEN_Directory_free(d);
00567   GWEN_Buffer_free(nbuf);
00568 
00569   return 0;
00570 }
00571 
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 
00581 
00582