gwenhywfar 4.0.3
|
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