00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <sys/param.h>
00027
00028 #include <gdk/gdk.h>
00029 #include <gtk/gtk.h>
00030
00031 #include <libxml/parser.h>
00032 #include <libxml/tree.h>
00033
00034 #include <libermanifest/ermanifest.h>
00035
00036 #include "contentListerLog.h"
00037 #include "erConnect.h"
00038 #include "system.h"
00039 #include "gtkPincodeScreen.h"
00040 #include "control.h"
00041 #include "control_share.h"
00042 #include "erMdsContent.h"
00043 #include "languages.h"
00044
00045
00046
00047 static void fetchSelectionDetails(const xmlNodePtr node, mdsSelection_t* selection);
00048 static void addSelectionCopyMove(mdsSelectionList_t* selectionList);
00049 static int selectionCompareFunc(const void* a, const void* b);
00050 static void fetchSelectionItemDetails(const xmlNodePtr node, mdsSelectionItem_t* item);
00051 static int selectionItemCompareFunc(const void* a, const void* b);
00052
00053
00054
00055 static char* getVerifiedPath(char* szPath, char* szContainerPath)
00056 {
00057 int nPathLength;
00058 char szRealPath[PATH_MAX];
00059 gboolean bUglyHack = FALSE;
00060
00061 char* szReturnPath = malloc(sizeof(char) * ERMDS_MAX_FILENAME_SIZE);
00062
00063
00064 if (szPath[0] == '/')
00065 {
00066 nPathLength = g_snprintf(szReturnPath, ERMDS_MAX_FILENAME_SIZE, "%s", szPath);
00067 }
00068 else if (strcmp(szPath, "dummy.bmp") == 0)
00069 {
00070 CL_WARNPRINTF("Ugly hack for dummy.bmp");
00071 nPathLength = g_snprintf(szReturnPath, ERMDS_MAX_FILENAME_SIZE, "%s", szContainerPath);
00072 bUglyHack = TRUE;
00073 }
00074 else
00075 {
00076 nPathLength = g_snprintf(szReturnPath, ERMDS_MAX_FILENAME_SIZE, "%s/%s", szContainerPath, szPath);
00077 }
00078
00079
00080 if (realpath(szReturnPath, szRealPath) != NULL)
00081 {
00082 if (ctrl_is_trusted_path(szRealPath))
00083 {
00084
00085 nPathLength = g_snprintf(szReturnPath, ERMDS_MAX_FILENAME_SIZE, "%s", szRealPath);
00086 }
00087 else
00088 {
00089
00090 CL_ERRORPRINTF("ctrl_is_trusted_path error for [%s]", szRealPath);
00091 nPathLength = ERMDS_MAX_FILENAME_SIZE + 1;
00092 }
00093 }
00094 else
00095 {
00096
00097 CL_ERRORPRINTF("realpath error for [%s]", szReturnPath);
00098 nPathLength = ERMDS_MAX_FILENAME_SIZE + 1;
00099 }
00100
00101 if (bUglyHack == TRUE)
00102 {
00103 nPathLength = g_snprintf(szReturnPath, ERMDS_MAX_FILENAME_SIZE, "%s/%s", szReturnPath, szPath);
00104 }
00105
00106 if (nPathLength > ERMDS_MAX_FILENAME_SIZE)
00107 {
00108
00109
00110 CL_ERRORPRINTF("content path too long");
00111 free(szReturnPath);
00112 szReturnPath = NULL;
00113 }
00114
00115 return szReturnPath;
00116 }
00117
00118 static void parseModifyEnable(xmlDocPtr doc, xmlNodePtr cur, clDisplayItem_t * displayItem, char *szContainerPath)
00119 {
00120 xmlChar* key;
00121 xmlNodePtr child;
00122 gboolean bDefault;
00123 gboolean bSpecific;
00124
00125
00126 bDefault = FALSE;
00127 key = xmlGetProp(cur, "default");
00128 if (key)
00129 {
00130 if ( xmlStrcmp(key, "true") == 0 )
00131 {
00132 bDefault = TRUE;
00133 }
00134 xmlFree(key);
00135 }
00136 displayItem->modifyEnable.bDefault = bDefault;
00137
00138
00139 bSpecific = bDefault;
00140 child = ermXmlGetChildNode(cur, "delete-enable");
00141 if (child)
00142 {
00143 key = xmlNodeGetContent(child);
00144 if (key)
00145 {
00146 if ( xmlStrcmp(key, "true") == 0 )
00147 {
00148 bSpecific = TRUE;
00149 }
00150 else
00151 {
00152
00153
00154 bSpecific = FALSE;
00155 }
00156 xmlFree(key);
00157 }
00158 }
00159 displayItem->modifyEnable.bDelete = bSpecific;
00160
00161 bSpecific = bDefault;
00162 child = ermXmlGetChildNode(cur, "scribble-enable");
00163 if (child)
00164 {
00165 key = xmlNodeGetContent(child);
00166 if (key)
00167 {
00168 if ( xmlStrcmp(key, "true") == 0 )
00169 {
00170 bSpecific = TRUE;
00171 }
00172 else
00173 {
00174
00175
00176 bSpecific = FALSE;
00177 }
00178 xmlFree(key);
00179 }
00180 }
00181 displayItem->modifyEnable.bScribble = bSpecific;
00182
00183 bSpecific = bDefault;
00184 child = ermXmlGetChildNode(cur, "tagging-enable");
00185 if (child)
00186 {
00187 key = xmlNodeGetContent(child);
00188 if (key)
00189 {
00190 if ( xmlStrcmp(key, "true") == 0 )
00191 {
00192 bSpecific = TRUE;
00193 }
00194 else
00195 {
00196
00197
00198 bSpecific = FALSE;
00199 }
00200 xmlFree(key);
00201 }
00202 }
00203 displayItem->modifyEnable.bTagging = bSpecific;
00204 }
00205
00206 static void parseYMetadata(xmlDocPtr doc, xmlNodePtr cur, clDisplayItem_t * displayItem, char *szContainerPath)
00207 {
00208 xmlChar *key;
00209 char *szFilename;
00210
00211 cur = cur->xmlChildrenNode;
00212 while (cur != NULL)
00213 {
00214 if (!xmlStrcmp(cur->name, (const xmlChar *) "image"))
00215 {
00216 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00217 if (key != NULL)
00218 {
00219 int nPathLength;
00220
00221 CL_LOGPRINTF("image: %s", key);
00222
00223
00224 nPathLength = g_snprintf(displayItem->clIconURL, ERMDS_MAX_FILENAME_SIZE, "%s/%s", szContainerPath, key);
00225
00226 if (nPathLength < ERMDS_MAX_FILENAME_SIZE)
00227 {
00228 displayItem->iconID = clIconUrlDefined;
00229 }
00230 else
00231 {
00232
00233 CL_ERRORPRINTF("IconPath is too long: %d", nPathLength);
00234 displayItem->iconID = clUnknownIcon;
00235 }
00236 xmlFree(key);
00237 }
00238 }
00239 else if (!xmlStrcmp(cur->name, (const xmlChar *) "startpage"))
00240 {
00241 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00242 if (key != NULL)
00243 {
00244 CL_LOGPRINTF("startpage: %s", key);
00245
00246
00247 szFilename = getVerifiedPath(key, szContainerPath);
00248 if (szFilename == NULL)
00249 {
00250
00251 CL_ERRORPRINTF("startpage [%s] is incorrect", key);
00252 strcpy(displayItem->szFilename, szContainerPath);
00253 }
00254 else
00255 {
00256 strcpy(displayItem->szFilename, szFilename);
00257 free(szFilename);
00258 szFilename = NULL;
00259 }
00260
00261 xmlFree(key);
00262 }
00263 }
00264 else if (!xmlStrcmp(cur->name, (const xmlChar *) "ItemSize"))
00265 {
00266 CL_LOGPRINTF("Found node Size");
00267 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00268 if (key != NULL)
00269 {
00270 CL_LOGPRINTF("Size: %s", key);
00271 displayItem->size = atoi(key);
00272 xmlFree(key);
00273 }
00274 }
00275 else if (!xmlStrcmp(cur->name, (const xmlChar *) "modify-enable"))
00276 {
00277 CL_LOGPRINTF("Found node modify-enable");
00278 parseModifyEnable(doc, cur, displayItem, szContainerPath);
00279 }
00280 cur = cur->next;
00281 }
00282 return;
00283 }
00284
00285 static void parseDcMetadata(xmlDocPtr doc, xmlNodePtr cur, clDisplayItem_t * displayItem, char *szContainerPath)
00286 {
00287 xmlChar *key;
00288
00289 cur = cur->xmlChildrenNode;
00290 while (cur != NULL)
00291 {
00292 if (!xmlStrcmp(cur->name, (const xmlChar *) "Description"))
00293 {
00294 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00295 if (key != NULL)
00296 {
00297 int nPathLength;
00298
00299 CL_LOGPRINTF("Description: %s", key);
00300 nPathLength = g_snprintf(displayItem->szDescription, ERCL_MAX_DESCRIPTION_SIZE, "%s", key);
00301 xmlFree(key);
00302 }
00303 }
00304
00305 else if (!xmlStrcmp(cur->name, (const xmlChar *) "Date"))
00306 {
00307 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00308 if (key != NULL)
00309 {
00310 int nPathLength;
00311
00312 CL_LOGPRINTF("Date: %s", key);
00313 nPathLength = g_snprintf(displayItem->szDate, ERCL_MAX_SUBTITLE_SIZE, "%s", key);
00314 xmlFree(key);
00315 }
00316 }
00317
00318 else if (!xmlStrcmp(cur->name, (const xmlChar *) "Title"))
00319 {
00320 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00321 if (key != NULL)
00322 {
00323 int nPathLength;
00324
00325 CL_LOGPRINTF("Title: %s", key);
00326 nPathLength = g_snprintf(displayItem->szTitle, ERCL_MAX_DESCRIPTION_SIZE, "%s", key);
00327 xmlFree(key);
00328 }
00329 }
00330 cur = cur->next;
00331 }
00332 return;
00333 }
00334
00335 static void parseMetadata(xmlDocPtr doc, xmlNodePtr cur, clDisplayItem_t * displayItem, char *szContainerPath)
00336 {
00337 cur = cur->xmlChildrenNode;
00338 while (cur != NULL)
00339 {
00340 if (!xmlStrcmp(cur->name, (const xmlChar *) "dc-metadata"))
00341 {
00342 CL_LOGPRINTF("Found node dc-metadata");
00343 parseDcMetadata(doc, cur, displayItem, szContainerPath);
00344 }
00345 else if (!xmlStrcmp(cur->name, (const xmlChar *) "y-metadata"))
00346 {
00347 CL_LOGPRINTF("Found node y-metadata");
00348 parseYMetadata(doc, cur, displayItem, szContainerPath);
00349 }
00350 cur = cur->next;
00351 }
00352 return;
00353 }
00354
00355 static void parseStoragedata(xmlDocPtr doc, xmlNodePtr cur, clDisplayItem_t * displayItem, char *szContainerPath)
00356 {
00357 xmlChar *key;
00358
00359 cur = cur->xmlChildrenNode;
00360 while (cur != NULL)
00361 {
00362 if (!xmlStrcmp(cur->name, (const xmlChar *) "Identifier"))
00363 {
00364 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00365 if (key != NULL)
00366 {
00367 int nPathLength;
00368
00369 CL_LOGPRINTF("Identifier: %s", key);
00370 nPathLength = g_snprintf(displayItem->szExtID, ERMDS_MAX_EXTENSION_ID_SIZE, "%s", key);
00371 xmlFree(key);
00372 }
00373 }
00374 cur = cur->next;
00375 }
00376 return;
00377 }
00378
00379 static void parseApplicationdata(xmlDocPtr doc, xmlNodePtr cur, clDisplayItem_t * displayItem, char *szContainerPath)
00380 {
00381 xmlChar *key;
00382
00383 cur = cur->xmlChildrenNode;
00384 while (cur != NULL)
00385 {
00386 if (!xmlStrcmp(cur->name, (const xmlChar *) "Identifier"))
00387 {
00388 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00389 if (key != NULL)
00390 {
00391 int nPathLength;
00392
00393 CL_LOGPRINTF("Identifier: %s", key);
00394 nPathLength = g_snprintf(displayItem->szExtID, ERMDS_MAX_EXTENSION_ID_SIZE, "%s", key);
00395 xmlFree(key);
00396 }
00397 }
00398 cur = cur->next;
00399 }
00400 return;
00401 }
00402
00403 static void parseDirectorydata(xmlDocPtr doc, xmlNodePtr cur, clDisplayItem_t * displayItem, char *szContainerPath)
00404 {
00405 xmlChar *key;
00406 char *szFilename;
00407
00408 cur = cur->xmlChildrenNode;
00409 while (cur != NULL)
00410 {
00411 if (!xmlStrcmp(cur->name, (const xmlChar *) "content"))
00412 {
00413 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00414 if (key != NULL)
00415 {
00416 CL_LOGPRINTF("content: %s", key);
00417
00418 szFilename = getVerifiedPath(key, szContainerPath);
00419 if (szFilename == NULL)
00420 {
00421 CL_ERRORPRINTF("directory [%s] is incorrect", key);
00422 strcpy(displayItem->szFilename, szContainerPath);
00423 }
00424 else
00425 {
00426 strcpy(displayItem->szFilename, szFilename);
00427 free(szFilename);
00428 szFilename = NULL;
00429 }
00430
00431 xmlFree(key);
00432 }
00433 }
00434 cur = cur->next;
00435 }
00436 return;
00437 }
00438
00439 int erClXmlParseManifest(char *szContainerPath, clDisplayItem_t * displayItem)
00440 {
00441 int ret = -1;
00442
00443 xmlDoc *doc = NULL;
00444 xmlNode *rootElement = NULL;
00445 xmlNode *cur = NULL;
00446 xmlNode *symlinkElement = NULL;
00447 xmlChar *targetPath = NULL;
00448 xmlChar *key;
00449
00450
00451 int n = strlen(szContainerPath) + 1 + strlen(MANIFEST_FILENAME) + 1;
00452 char *szFilename = alloca(n);
00453 g_assert(szFilename != NULL);
00454 snprintf(szFilename, n, "%s/" MANIFEST_FILENAME, szContainerPath);
00455
00456 LIBXML_TEST_VERSION doc = xmlParseFile(szFilename);
00457
00458 if (doc == NULL)
00459 {
00460 CL_ERRORPRINTF("Document not parsed successfully");
00461 return ret;
00462 }
00463
00464
00465 rootElement = xmlDocGetRootElement(doc);
00466
00467
00468 if (xmlStrcmp(rootElement->name, (const xmlChar *) "package"))
00469 {
00470 CL_ERRORPRINTF("Document of the wrong type, root node != package");
00471 xmlFreeDoc(doc);
00472 return ret;
00473 }
00474
00475
00476
00477 symlinkElement = ermXmlGetChildNode(rootElement, "symlink");
00478 if (symlinkElement)
00479 {
00480
00481 displayItem->fit = mdsFitManifestSymlink;
00482 key = xmlGetProp(symlinkElement, "add-locale");
00483 if (key)
00484 {
00485 if (xmlStrcmp(key, "true") == 0)
00486 {
00487 displayItem->fit = mdsFitManifestSymlinkLocale;
00488 }
00489 xmlFree(key);
00490 }
00491
00492
00493 targetPath = xmlNodeGetContent(symlinkElement);
00494 szFilename = getVerifiedPath(targetPath, szContainerPath);
00495 CL_WARNPRINTF("symlink [%s] [%s] --> [%s]", szContainerPath, targetPath, szFilename);
00496 if (szFilename)
00497 {
00498 strcpy(displayItem->szFilename, szFilename);
00499 free(szFilename);
00500 }
00501 else
00502 {
00503 CL_ERRORPRINTF("directory [%s] [%s] is incorrect", szContainerPath, targetPath);
00504
00505 strcpy(displayItem->szFilename, szContainerPath);
00506 displayItem->fit = mdsFitFolder;
00507 }
00508 }
00509 else
00510 {
00511 cur = rootElement->xmlChildrenNode;
00512 while (cur != NULL)
00513 {
00514 if ((!xmlStrcmp(cur->name, (const xmlChar *) "metadata")))
00515 {
00516 CL_LOGPRINTF("Found node metadata");
00517 parseMetadata(doc, cur, displayItem, szContainerPath);
00518 }
00519
00520 if ((!xmlStrcmp(cur->name, (const xmlChar *) "storage")))
00521 {
00522 CL_LOGPRINTF("Found node storage");
00523 parseStoragedata(doc, cur, displayItem, szContainerPath);
00524
00525 displayItem->fit = mdsFitStorage;
00526 }
00527
00528 if ((!xmlStrcmp(cur->name, (const xmlChar *) "application")))
00529 {
00530 CL_LOGPRINTF("Found node application");
00531 parseApplicationdata(doc, cur, displayItem, szContainerPath);
00532
00533 displayItem->fit = mdsFitApplication;
00534 }
00535
00536 if ((!xmlStrcmp(cur->name, (const xmlChar *) "directory")))
00537 {
00538 CL_LOGPRINTF("Found node directory");
00539 parseDirectorydata(doc, cur, displayItem, szContainerPath);
00540
00541 displayItem->fit = mdsFitManifestDirectory;
00542 }
00543 cur = cur->next;
00544 }
00545 }
00546
00547
00548 xmlFreeDoc(doc);
00549
00550
00551 xmlCleanupParser();
00552
00553 return 0;
00554 }
00555
00556
00557 static int parseMetadataForField(xmlDocPtr doc, xmlNodePtr cur, char *szFieldType, char *szField)
00558 {
00559 xmlChar *key;
00560
00561 cur = cur->xmlChildrenNode;
00562 while (cur != NULL)
00563 {
00564 if (!xmlStrcmp(cur->name, (const xmlChar *) szFieldType))
00565 {
00566 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00567 if (key != NULL)
00568 {
00569 int nPathLength;
00570
00571 CL_LOGPRINTF("szFieldType: %s", key);
00572
00573 nPathLength = g_snprintf(szField, ERCL_MAX_DESCRIPTION_SIZE, "%s", key);
00574 xmlFree(key);
00575 return 1;
00576 }
00577 }
00578 cur = cur->next;
00579 }
00580 return -1;
00581 }
00582
00583
00584
00585 static int parseMetadataForBranch(xmlDocPtr doc, xmlNodePtr cur, char *szFieldType, int nDcBranch, char *szField)
00586 {
00587 cur = cur->xmlChildrenNode;
00588 while (cur != NULL)
00589 {
00590 if (!xmlStrcmp(cur->name, (const xmlChar *) "dc-metadata"))
00591 {
00592 CL_LOGPRINTF("Found node dc-metadata");
00593 if (nDcBranch == 1)
00594 {
00595 return parseMetadataForField(doc, cur, szFieldType, szField);
00596 }
00597 }
00598 else if (!xmlStrcmp(cur->name, (const xmlChar *) "y-metadata"))
00599 {
00600 CL_LOGPRINTF("Found node y-metadata");
00601 if (nDcBranch != 1)
00602 {
00603 return parseMetadataForField(doc, cur, szFieldType, szField);
00604 }
00605 }
00606 cur = cur->next;
00607 }
00608 return -1;
00609 }
00610
00611
00612 void erClXmlFetchField(char *szFilename, mdsFieldType_e fieldType, char *szField)
00613 {
00614 char szFieldType[ERCL_MAX_FIELDNAME_SIZE];
00615 int nDcBranch;
00616 xmlDoc *doc = NULL;
00617 xmlNode *rootElement = NULL;
00618 xmlNode *cur = NULL;
00619
00620 strcpy(szField, "");
00621
00622 switch (fieldType)
00623 {
00624 case mdsFieldDate:
00625 strcpy(szFieldType, "Date");
00626 break;
00627
00628 case mdsFieldDescription:
00629 strcpy(szFieldType, "Description");
00630 break;
00631
00632 case mdsFieldFile:
00633 strcpy(szFieldType, "startpage");
00634 break;
00635
00636 case mdsFieldTitle:
00637 strcpy(szFieldType, "Title");
00638 break;
00639
00640 case mdsFieldSize:
00641 strcpy(szFieldType, "ItemSize");
00642 break;
00643
00644 default:
00645 CL_ERRORPRINTF("FieldType %d can not be retrieved from a manifest file", (int) fieldType);
00646 strcpy(szField, "");
00647 return;
00648 }
00649
00650
00651 switch (fieldType)
00652 {
00653 case mdsFieldFile:
00654 nDcBranch = 0;
00655 break;
00656
00657 default:
00658 nDcBranch = 1;
00659 break;
00660 }
00661
00662 LIBXML_TEST_VERSION doc = xmlParseFile(szFilename);
00663
00664 if (doc == NULL)
00665 {
00666 CL_ERRORPRINTF("Document not parsed successfully");
00667 return;
00668 }
00669
00670
00671 rootElement = xmlDocGetRootElement(doc);
00672
00673
00674 if (xmlStrcmp(rootElement->name, (const xmlChar *) "package"))
00675 {
00676 CL_ERRORPRINTF("Document of the wrong type, root node != package");
00677 xmlFreeDoc(doc);
00678 return;
00679 }
00680
00681 cur = rootElement->xmlChildrenNode;
00682 while (cur != NULL)
00683 {
00684 if ((!xmlStrcmp(cur->name, (const xmlChar *) "metadata")))
00685 {
00686 CL_LOGPRINTF("Found node metadata");
00687 parseMetadataForBranch(doc, cur, szFieldType, nDcBranch, szField);
00688 }
00689 cur = cur->next;
00690 }
00691
00692
00693 xmlFreeDoc(doc);
00694
00695
00696 xmlCleanupParser();
00697
00698 return;
00699 }
00700
00701 gboolean erClXmlSetFieldSize(const gchar* szContainer, int size)
00702 {
00703 CL_LOGPRINTF("entry: manifest [%s], size [%d]", szContainer, size);
00704
00705 g_return_val_if_fail((szContainer != NULL), FALSE);
00706
00707 erManifest manifest;
00708 int nLength;
00709 char szSize[ERMDS_MAX_FILENAME_SIZE];
00710 gboolean retval = FALSE;
00711
00712
00713 if (RET_OK == ermXmlOpenManifest(szContainer, &manifest))
00714 {
00715 nLength = g_snprintf(szSize, ERMDS_MAX_FILENAME_SIZE, "%d", size);
00716 CL_LOGPRINTF("size = %s", szSize);
00717
00718
00719 if (RET_OK == ermXmlExist(&manifest, "/package/metadata/y-metadata/ItemSize"))
00720 {
00721 ermXmlSetString( &manifest,
00722 "/package/metadata/y-metadata/ItemSize",
00723 szSize );
00724 }
00725 else
00726 {
00727 ermXmlNewString( &manifest,
00728 "/package/metadata/y-metadata",
00729 "ItemSize",
00730 szSize );
00731 }
00732
00733
00734 ermXmlSaveAndClose(&manifest);
00735
00736 retval = TRUE;
00737 }
00738 else
00739 {
00740 CL_ERRORPRINTF("Could not open manifest file in [%s]", szContainer);
00741 }
00742
00743 return retval;
00744 }
00745
00746
00747 const mdsSelectionList_t* erClXmlFetchSelectionList(const char* szManifestPath)
00748 {
00749 int rc;
00750 int selNum;
00751 int selIdx;
00752
00753 erManifest* pCtx = NULL;
00754 xmlXPathObjectPtr xpathObj = NULL;
00755 xmlNodePtr* p_node = NULL;
00756 xmlNodeSetPtr selectionNodes = NULL;
00757 xmlNodePtr nodeRoot = NULL;
00758 mdsSelectionList_t* selectionList = NULL;
00759 mdsSelection_t* selection = NULL;
00760
00761 CL_LOGPRINTF("entry: manifest [%s]", szManifestPath);
00762
00763 selectionList = g_new0(mdsSelectionList_t, 1);
00764
00765
00766 pCtx = &(selectionList->manifest);
00767 rc = ermXmlOpenFile(szManifestPath, pCtx);
00768 if (rc != RET_OK)
00769 {
00770 CL_ERRORPRINTF("Cannot read manifest file [%s]", szManifestPath);
00771 goto ERROR_EXIT;
00772 }
00773 else { CL_LOGPRINTF("manifest opened ok"); }
00774
00775
00776
00777 rc = ermXmlValidateManifest(pCtx);
00778 if (rc != RET_OK)
00779 {
00780 CL_ERRORPRINTF("manifest file [%s] NOT validated", szManifestPath);
00781 goto ERROR_EXIT;
00782 }
00783 else { CL_LOGPRINTF("manifest validated ok"); }
00784
00785
00786
00787 xpathObj = ermXmlSelectNodes(pCtx, XMLNODE_SELECTION_LIST);
00788 if (xpathObj == NULL)
00789 {
00790 CL_WARNPRINTF("No selection-list in [%s]", szManifestPath);
00791 goto ERROR_EXIT;
00792 }
00793 else { CL_LOGPRINTF("selection list found"); }
00794
00795
00796 nodeRoot = xpathObj->nodesetval->nodeTab[0];
00797 selectionList->nodeRoot = nodeRoot;
00798
00799 xmlXPathFreeObject(xpathObj);
00800 xpathObj = NULL;
00801
00802
00803 selectionNodes = ermXmlGetChildNodeSet(nodeRoot, "selection");
00804 if (selectionNodes->nodeNr == 0)
00805 {
00806 CL_ERRORPRINTF("Empty selection-list in [%s]", szManifestPath);
00807 selectionList->num_selections = 0;
00808 goto ERROR_EXIT;
00809 }
00810 selNum = selectionNodes->nodeNr;
00811 selectionList->num_selections = selNum;
00812 selectionList->selections = g_new0(mdsSelection_t, selNum);
00813
00814 p_node = selectionNodes->nodeTab;
00815 selection = (mdsSelection_t*) selectionList->selections;
00816 for (selIdx = 0 ; selIdx < selNum ; selIdx++, p_node++, selection++)
00817 {
00818 fetchSelectionDetails(*p_node, selection);
00819 }
00820
00821
00822 qsort( (void*)selectionList->selections,
00823 selectionList->num_selections,
00824 sizeof(selectionList->selections[0]),
00825 selectionCompareFunc );
00826
00827 ERROR_EXIT:
00828
00829 if (selectionList)
00830 {
00831 addSelectionCopyMove(selectionList);
00832 }
00833
00834
00835 if (selectionNodes) { xmlXPathFreeNodeSet(selectionNodes); }
00836 if (xpathObj) { xmlXPathFreeObject(xpathObj); }
00837 return selectionList;
00838 }
00839
00840 static void addSelectionCopyMove(mdsSelectionList_t* selectionList)
00841 {
00842 gboolean found;
00843 int selIdx;
00844
00845 int selNum = selectionList->num_selections;
00846 mdsSelection_t* selection = NULL;
00847 mdsSelectionItem_t* item = NULL;
00848
00849
00850 found = FALSE;
00851 selection = (mdsSelection_t*) selectionList->selections;
00852 for (selIdx = 0 ; selIdx < selNum ; selIdx++, selection++)
00853 {
00854 if (strcmp(selection->id, SELECTION_TRANSFER_MODE) == 0)
00855 {
00856 found = TRUE;
00857 }
00858 }
00859
00860
00861 if ( !found )
00862 {
00863
00864 selection = (mdsSelection_t*) selectionList->selections;
00865 selection = g_renew(mdsSelection_t, selection, selNum + 1);
00866 selectionList->selections = selection;
00867 selectionList->num_selections++;
00868
00869
00870 selection = (mdsSelection_t*) selectionList->selections;
00871 selection += selNum;
00872 for (selIdx = 0 ; selIdx < selNum ; selIdx++, selection--)
00873 {
00874 *selection = *(selection - 1);
00875 }
00876 memset((void*)selection, 0x00, sizeof(*selection));
00877
00878
00879 selection = (mdsSelection_t*) selectionList->selections;
00880 selection->constant = FALSE;
00881 selection->hide = FALSE;
00882 selection->display_as = xmlCharStrdup("textbutton");
00883 selection->title = xmlCharStrdup( _("Transfer mode") );
00884 selection->instruction = xmlCharStrdup( _("Please select how to add this document to your outbox") );
00885 selection->min_selected = 1;
00886 selection->max_selected = 1;
00887 selection->num_items = 2;
00888 selection->items = NULL;
00889 selection->id = xmlCharStrdup(SELECTION_TRANSFER_MODE);
00890 selection->sequence = 0;
00891
00892
00893 selection->items = g_new0(mdsSelectionItem_t, 2);
00894
00895 item = (mdsSelectionItem_t*) selection->items;
00896 item->name = xmlCharStrdup( _("Copy") );
00897 item->id = xmlCharStrdup( "copy" );
00898 item->sequence = 1;
00899 item->state = TRUE;
00900
00901 item++;
00902 item->name = xmlCharStrdup( _("Move") );
00903 item->id = xmlCharStrdup( "move" );
00904 item->sequence = 2;
00905 item->state = FALSE;
00906 }
00907 }
00908
00909 static int selectionCompareFunc(const void* a, const void* b)
00910 {
00911 int ret = 0;
00912 mdsSelection_t* selA = (mdsSelection_t*)a;
00913 mdsSelection_t* selB = (mdsSelection_t*)b;
00914
00915 if (selA && selB)
00916 {
00917 ret = selA->sequence - selB->sequence;
00918 }
00919 else
00920 {
00921 CL_ERRORPRINTF("selA [%p] selB [%p]", selA, selB);
00922 }
00923
00924 return ret;
00925 }
00926
00927 static void fetchSelectionDetails(const xmlNodePtr selectionNode, mdsSelection_t* selection)
00928 {
00929 mdsSelectionItem_t* item = NULL;
00930
00931 int i;
00932 xmlChar* xcp;
00933 xmlNodePtr child = NULL;
00934 xmlNodePtr* p_node = NULL;
00935 xmlNodeSetPtr itemNodes = NULL;
00936 int itemNum;
00937 int itemIdx;
00938
00939
00940 CL_LOGPRINTF("entry");
00941
00942
00943 xcp = xmlGetProp(selectionNode, "id");
00944 if (xcp == NULL)
00945 {
00946 xcp = xmlStrdup("");
00947 }
00948 selection->id = xcp;
00949
00950
00951 selection->constant = FALSE;
00952 xcp = xmlGetProp(selectionNode, "constant");
00953 if (xcp)
00954 {
00955 if (xmlStrcmp(xcp, "true") == 0)
00956 {
00957 selection->constant = TRUE;
00958 }
00959 xmlFree(xcp);
00960 }
00961
00962
00963 selection->hide = FALSE;
00964 xcp = xmlGetProp(selectionNode, "hide");
00965 if (xcp)
00966 {
00967 if (xmlStrcmp(xcp, "true") == 0)
00968 {
00969 selection->hide = TRUE;
00970 }
00971 xmlFree(xcp);
00972 }
00973
00974
00975 selection->sequence = 0;
00976 xcp = xmlGetProp(selectionNode, "sequence");
00977 if (xcp)
00978 {
00979 i = atoi(xcp);
00980 if (i >= 0)
00981 {
00982 selection->sequence = i;
00983 }
00984 xmlFree(xcp);
00985 }
00986
00987
00988 xcp = NULL;
00989 child = ermXmlGetChildNode(selectionNode, "display-as");
00990 if (child)
00991 {
00992 xcp = xmlNodeGetContent(child);
00993 }
00994 if (xcp == NULL)
00995 {
00996 xcp = xmlStrdup("");
00997 }
00998 selection->display_as = xcp;
00999
01000
01001 xcp = NULL;
01002 child = ermXmlGetChildNode(selectionNode, "title");
01003 if (child)
01004 {
01005 xcp = xmlNodeGetContent(child);
01006 }
01007 if (xcp == NULL)
01008 {
01009 xcp = xmlStrdup("");
01010 }
01011 selection->title = xcp;
01012
01013
01014 xcp = NULL;
01015 child = ermXmlGetChildNode(selectionNode, "instruction");
01016 if (child)
01017 {
01018 xcp = xmlNodeGetContent(child);
01019 }
01020 if (xcp == NULL)
01021 {
01022 xcp = xmlStrdup("");
01023 }
01024 selection->instruction = xcp;
01025
01026
01027 selection->min_selected = 1;
01028 child = ermXmlGetChildNode(selectionNode, "min-selected");
01029 if (child)
01030 {
01031 xcp = xmlNodeGetContent(child);
01032 i = atoi(xcp);
01033 if (i >= 0)
01034 {
01035 selection->min_selected = i;
01036 }
01037 xmlFree(xcp);
01038 }
01039
01040
01041 selection->max_selected = 1;
01042 child = ermXmlGetChildNode(selectionNode, "max-selected");
01043 if (child)
01044 {
01045 xcp = xmlNodeGetContent(child);
01046 i = atoi(xcp);
01047 if (i >= 0)
01048 {
01049 selection->max_selected = i;
01050 }
01051 xmlFree(xcp);
01052 }
01053
01054
01055 selection->num_items = 0;
01056 child = ermXmlGetChildNode(selectionNode, "selection-item-list");
01057 if (child)
01058 {
01059 itemNodes = ermXmlGetChildNodeSet(child, "selection-item");
01060 itemNum = itemNodes->nodeNr;
01061 selection->num_items = itemNum;
01062 selection->items = g_new0(mdsSelectionItem_t, itemNum);
01063
01064 p_node = itemNodes->nodeTab;
01065 item = (mdsSelectionItem_t*) selection->items;
01066 for (itemIdx = 0 ; itemIdx < itemNum ; itemIdx++, p_node++, item++)
01067 {
01068 fetchSelectionItemDetails(*p_node, item);
01069 }
01070 }
01071 else { CL_ERRORPRINTF("No selection-item-list"); }
01072
01073
01074 qsort( (void*)selection->items,
01075 selection->num_items,
01076 sizeof(selection->items[0]),
01077 selectionItemCompareFunc );
01078
01079
01080 if (itemNodes) { xmlXPathFreeNodeSet(itemNodes); }
01081 }
01082
01083
01084 static int selectionItemCompareFunc(const void* a, const void* b)
01085 {
01086 int ret = 0;
01087 mdsSelectionItem_t* itemA = (mdsSelectionItem_t*)a;
01088 mdsSelectionItem_t* itemB = (mdsSelectionItem_t*)b;
01089
01090 if (itemA && itemB)
01091 {
01092 ret = itemA->sequence - itemB->sequence;
01093 }
01094 else
01095 {
01096 CL_ERRORPRINTF("itemA [%p] itemB [%p]", itemA, itemB);
01097 }
01098
01099 return ret;
01100 }
01101
01102 static void fetchSelectionItemDetails(const xmlNodePtr itemNode, mdsSelectionItem_t* item)
01103 {
01104 int i;
01105 xmlChar* xcp;
01106 xmlNodePtr child = NULL;
01107
01108
01109 CL_LOGPRINTF("entry");
01110
01111
01112 xcp = xmlGetProp(itemNode, "id");
01113 if (xcp == NULL)
01114 {
01115 xcp = xmlStrdup("");
01116 }
01117 item->id = xcp;
01118
01119
01120 item->sequence = 0;
01121 xcp = xmlGetProp(itemNode, "sequence");
01122 if (xcp)
01123 {
01124 i = atoi(xcp);
01125 if (i >= 0)
01126 {
01127 item->sequence = i;
01128 }
01129 xmlFree(xcp);
01130 }
01131
01132
01133 xcp = NULL;
01134 child = ermXmlGetChildNode(itemNode, "name");
01135 if (child)
01136 {
01137 xcp = xmlNodeGetContent(child);
01138 }
01139 if (xcp == NULL)
01140 {
01141 xcp = xmlStrdup("");
01142 }
01143 item->name = xcp;
01144
01145
01146 item->state = FALSE;
01147 child = ermXmlGetChildNode(itemNode, "state");
01148 if (child)
01149 {
01150 xcp = xmlNodeGetContent(child);
01151 if (xcp)
01152 {
01153 if (xmlStrcmp(xcp, "true") == 0)
01154 {
01155 item->state = TRUE;
01156 }
01157 xmlFree(xcp);
01158 }
01159 }
01160 }
01161
01162
01163 int erClXmlSaveSelectionList(const mdsSelectionList_t* selectionList)
01164 {
01165 int rc;
01166 int ret = RET_ERR;
01167
01168 CL_LOGPRINTF("entry");
01169
01170 if (selectionList == NULL)
01171 {
01172 CL_ERRORPRINTF("no selectionList");
01173 return RET_ERR;
01174 }
01175 if (selectionList->num_selections > 0 && selectionList->selections == NULL)
01176 {
01177 CL_ERRORPRINTF("no selectionList->selections");
01178 return RET_ERR;
01179 }
01180
01181 int selNum;
01182 int selIdx;
01183 int itemNum;
01184 int itemIdx;
01185
01186 erManifest* pCtx = (erManifest*) &(selectionList->manifest);
01187 xmlNodePtr nodeRoot = selectionList->nodeRoot;
01188 xmlNodePtr nodeSelection = NULL;
01189 xmlNodePtr nodeItemList = NULL;
01190 xmlNodePtr node = NULL;
01191 xmlNodePtr child = NULL;
01192 const mdsSelection_t* selection = NULL;
01193 const mdsSelectionItem_t* item = NULL;
01194
01195
01196 selNum = selectionList->num_selections;
01197 selection = selectionList->selections;
01198 for (selIdx = 0 ; selIdx < selNum ; selIdx++, selection++)
01199 {
01200 nodeSelection = ermXmlGetChildNodeWithAttr(nodeRoot, "selection", "id", selection->id);
01201 if (nodeSelection == NULL)
01202 {
01203 CL_ERRORPRINTF("Node selection id=[%s] not found", selection->id);
01204 continue;
01205 }
01206
01207 nodeItemList = ermXmlGetChildNode(nodeSelection, "selection-item-list");
01208 if (nodeItemList == NULL)
01209 {
01210 CL_WARNPRINTF("Node selection-item-list id=[%s] not found", selection->id);
01211 continue;
01212 }
01213
01214
01215 itemNum = selection->num_items;
01216 item = selection->items;
01217 for (itemIdx = 0 ; itemIdx < itemNum ; itemIdx++, item++)
01218 {
01219 node = ermXmlGetChildNodeWithAttr(nodeItemList, "selection-item", "id", item->id);
01220 if (node)
01221 {
01222
01223 child = ermXmlGetChildNode(node, "state");
01224 if (child)
01225 {
01226 xmlNodeSetContent(child, item->state ? "true" : "false");
01227 CL_LOGPRINTF("item id=[%s] state set to [%d] [%s]", item->id, item->state, item->state ? "true" : "false");
01228 }
01229 else
01230 {
01231 CL_ERRORPRINTF("Attribute node id=[%s] has no child 'state'", item->id);
01232 }
01233 }
01234 else
01235 {
01236 CL_ERRORPRINTF("Node selection-item id=[%s] not found", item->id);
01237 }
01238 }
01239 }
01240
01241
01242 rc = ermXmlSave(pCtx);
01243 if (rc == RET_OK)
01244 {
01245 ret = RET_OK;
01246 }
01247 else
01248 {
01249 CL_ERRORPRINTF("error while saving manifest file");
01250 }
01251
01252 return ret;
01253 }
01254
01255 void erClXmlFreeSelectionList(const mdsSelectionList_t* selectionList)
01256 {
01257 CL_LOGPRINTF("entry");
01258
01259 erManifest* pCtx = (erManifest*) &(selectionList->manifest);
01260 const mdsSelection_t* selection = NULL;
01261 const mdsSelectionItem_t* item = NULL;
01262
01263 int selNum;
01264 int selIdx;
01265 int itemNum;
01266 int itemIdx;
01267
01268 if (selectionList)
01269 {
01270 if (selectionList->selections)
01271 {
01272
01273 selNum = selectionList->num_selections;
01274 selection = selectionList->selections;
01275 for (selIdx = 0 ; selIdx < selNum ; selIdx++, selection++)
01276 {
01277 if (selection->items)
01278 {
01279
01280 itemNum = selection->num_items;
01281 item = selection->items;
01282 for (itemIdx = 0 ; itemIdx < itemNum ; itemIdx++, item++)
01283 {
01284 if (item->name) { xmlFree(item->name); }
01285 if (item->id) { xmlFree(item->id); }
01286 }
01287
01288 g_free((void*)(selection->items));
01289 }
01290
01291 if (selection->display_as) { xmlFree(selection->display_as); }
01292 if (selection->title) { xmlFree(selection->title); }
01293 if (selection->instruction) { xmlFree(selection->instruction); }
01294 if (selection->id) { xmlFree(selection->id); }
01295 }
01296
01297 g_free((void*)(selectionList->selections));
01298 }
01299
01300 ermXmlClose(pCtx);
01301 g_free((void*)selectionList);
01302 }
01303 }
01304
01305 int erClXmlSetSelectionItem( const mdsSelectionList_t* selectionList,
01306 const guint selectionIndex,
01307 const guint itemIndex,
01308 const gboolean state )
01309 {
01310
01311 if (selectionList == NULL || selectionList->selections == NULL)
01312 {
01313 CL_ERRORPRINTF( "Invalid selectionList [%p] selections [%p]",
01314 selectionList,
01315 selectionList ? selectionList->selections : NULL );
01316 return RET_ERR;
01317 }
01318 if (selectionIndex >= selectionList->num_selections)
01319 {
01320 CL_ERRORPRINTF( "Invalid selectionIndex [%u] num_selections [%u]",
01321 selectionIndex,
01322 selectionList->num_selections );
01323 return RET_ERR;
01324 }
01325
01326
01327 mdsSelection_t* selection = (mdsSelection_t*) &(selectionList->selections[selectionIndex]);
01328
01329
01330 if (itemIndex >= selection->num_items)
01331 {
01332 CL_ERRORPRINTF( "Invalid itemIndex [%u] num_items [%u]",
01333 itemIndex,
01334 selection->num_items );
01335 return RET_ERR;
01336 }
01337
01338
01339 mdsSelectionItem_t* item = (mdsSelectionItem_t*) &(selection->items[itemIndex]);
01340
01341
01342 item->state = state;
01343
01344 return RET_OK;
01345 }
01346
01347 int erClXmlGetSelectionListItemState( const mdsSelectionList_t* selectionList,
01348 const char* selectionId,
01349 const char* itemId,
01350 gboolean* state )
01351 {
01352 gboolean found = FALSE;
01353
01354 const mdsSelection_t* selection;
01355 int sel_idx;
01356 const mdsSelectionItem_t* item;
01357 int item_idx;
01358
01359
01360 if (selectionList == NULL || selectionList->selections == NULL)
01361 {
01362 CL_ERRORPRINTF( "Invalid selectionList [%p] selections [%p]",
01363 selectionList,
01364 selectionList ? selectionList->selections : NULL );
01365 return RET_ERR;
01366 }
01367
01368
01369 selection = selectionList->selections;
01370 for (sel_idx = 0 ; sel_idx < selectionList->num_selections ; sel_idx++, selection++)
01371 {
01372 if (strcmp(selection->id, selectionId) == 0)
01373 {
01374
01375 item = selection->items;
01376 for (item_idx = 0 ; item_idx < selection->num_items ; item_idx++, item++)
01377 {
01378 if (strcmp(item->id, itemId) == 0)
01379 {
01380
01381 found = TRUE;
01382 if (item->state)
01383 {
01384 *state = TRUE;
01385 }
01386 else
01387 {
01388 *state = FALSE;
01389 }
01390
01391
01392 item_idx = selection->num_items;
01393 }
01394 }
01395
01396
01397 sel_idx = selectionList->num_selections;
01398 }
01399 }
01400
01401 if (found)
01402 {
01403 CL_LOGPRINTF("Found: selection [%s] item [%s] state [%d]", selectionId, itemId, *state);
01404 return RET_OK;
01405 }
01406 else
01407 {
01408 CL_WARNPRINTF("Not found: selection [%s] item [%s] state [%d]", selectionId, itemId, *state);
01409 return RET_ERR;
01410 }
01411 }
01412