gwenhywfar
4.3.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 #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