2 * Copyright (c) 2011 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <sys/types.h>
28 #include <libxml/parser.h>
29 #include <libxml/tree.h>
35 #define DbgPrint(format, arg...) SECURE_LOGD("[
\e[32m%s/%s
\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
36 #define ErrPrint(format, arg...) SECURE_LOGE("[
\e[32m%s/%s
\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
43 * +----+-------+-------+------+---------+-----------+------------+
44 * | id | pkgid | appid | Icon | Name | extra_key | extra_data |
45 * +----+-------+-------+------+---------+-----------+------------+
46 * | id | - | - | - | - | - | - |
47 * +----+-------+-------+------+---------+-----------+------------+
49 * +----+-------+------+------+------+
50 * | fk | pkgid | lang | name | icon |
51 * +----+-------+------+------+------+
52 * | id | - | - | | - |
53 * +----+-------+------+------+------+
56 #if !defined(LIBXML_TREE_ENABLED)
57 #error "LIBXML is not supporting the tree"
76 static inline int begin_transaction(void)
81 ret = sqlite3_prepare_v2(s_info.handle, "BEGIN TRANSACTION", -1, &stmt, NULL);
82 if (ret != SQLITE_OK) {
83 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
87 if (sqlite3_step(stmt) != SQLITE_DONE) {
88 DbgPrint("Failed to do update (%s)\n",
89 sqlite3_errmsg(s_info.handle));
90 sqlite3_finalize(stmt);
94 sqlite3_finalize(stmt);
98 static inline int rollback_transaction(void)
103 ret = sqlite3_prepare_v2(s_info.handle, "ROLLBACK TRANSACTION", -1, &stmt, NULL);
104 if (ret != SQLITE_OK) {
105 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
109 if (sqlite3_step(stmt) != SQLITE_DONE) {
110 DbgPrint("Failed to do update (%s)\n",
111 sqlite3_errmsg(s_info.handle));
112 sqlite3_finalize(stmt);
116 sqlite3_finalize(stmt);
120 static inline int commit_transaction(void)
125 ret = sqlite3_prepare_v2(s_info.handle, "COMMIT TRANSACTION", -1, &stmt, NULL);
126 if (ret != SQLITE_OK) {
127 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
131 if (sqlite3_step(stmt) != SQLITE_DONE) {
132 DbgPrint("Failed to do update (%s)\n",
133 sqlite3_errmsg(s_info.handle));
134 sqlite3_finalize(stmt);
138 sqlite3_finalize(stmt);
142 static void db_create_version(void)
144 static const char *ddl = "CREATE TABLE version (version INTEGER)";
147 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
148 ErrPrint("Failed to execute the DDL (%s)\n", err);
152 if (sqlite3_changes(s_info.handle) == 0) {
153 ErrPrint("No changes to DB\n");
157 static int set_version(int version)
159 static const char *dml = "INSERT INTO version (version) VALUES (?)";
163 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
164 if (ret != SQLITE_OK) {
165 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
169 if (sqlite3_bind_int(stmt, 1, version) != SQLITE_OK) {
170 ErrPrint("Failed to bind a id(%s)\n", sqlite3_errmsg(s_info.handle));
175 ret = sqlite3_step(stmt);
176 if (ret != SQLITE_DONE) {
177 ErrPrint("Failed to execute the DML for version: %d\n", ret);
185 sqlite3_clear_bindings(stmt);
186 sqlite3_finalize(stmt);
190 static int update_version(int version)
192 static const char *dml = "UPDATE version SET version = ?";
196 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
197 if (ret != SQLITE_OK) {
198 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
202 if (sqlite3_bind_int(stmt, 1, version) != SQLITE_OK) {
203 ErrPrint("Failed to bind a version: %s\n", sqlite3_errmsg(s_info.handle));
208 ret = sqlite3_step(stmt);
209 if (ret != SQLITE_DONE) {
210 ErrPrint("Failed to execute DML: %d\n", ret);
218 sqlite3_clear_bindings(stmt);
219 sqlite3_finalize(stmt);
223 static int get_version(void)
225 static const char *dml = "SELECT version FROM version";
229 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
230 if (ret != SQLITE_OK) {
234 if (sqlite3_step(stmt) != SQLITE_ROW) {
237 ret = sqlite3_column_int(stmt, 0);
241 sqlite3_clear_bindings(stmt);
242 sqlite3_finalize(stmt);
246 static void db_create_table(void)
249 static const char *ddl =
250 "CREATE TABLE shortcut_service ("
251 "id INTEGER PRIMARY KEY AUTOINCREMENT, "
259 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
260 ErrPrint("Failed to execute the DDL (%s)\n", err);
264 if (sqlite3_changes(s_info.handle) == 0) {
265 ErrPrint("No changes to DB\n");
268 ddl = "CREATE TABLE shortcut_name (id INTEGER, pkgid TEXT, lang TEXT, name TEXT, icon TEXT)";
269 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
270 ErrPrint("Failed to execute the DDL (%s)\n", err);
274 if (sqlite3_changes(s_info.handle) == 0) {
275 ErrPrint("No changes to DB\n");
281 static void alter_shortcut_icon(void)
284 static const char *ddl = "ALTER TABLE shortcut_name ADD icon TEXT";
286 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
287 ErrPrint("Failed to execute the DDL (%s)\n", err);
291 if (sqlite3_changes(s_info.handle) == 0) {
292 ErrPrint("No changes to DB\n");
296 static void alter_shortcut_name(void)
299 static const char *ddl = "ALTER TABLE shortcut_name ADD pkgid TEXT";
301 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
302 ErrPrint("Failed to execute the DDL (%s)\n", err);
306 if (sqlite3_changes(s_info.handle) == 0) {
307 ErrPrint("No changes to DB\n");
311 static void alter_shortcut_service(void)
314 static const char *ddl = "ALTER TABLE shortcut_service ADD pkgid TEXT";
316 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
317 ErrPrint("Failed to execute the DDL (%s)\n", err);
321 if (sqlite3_changes(s_info.handle) == 0) {
322 ErrPrint("No changes to DB\n");
326 static int db_remove_by_pkgid(const char *pkgid)
328 static const char *dml = "DELETE FROM shortcut_service WHERE pkgid = ?";
333 ErrPrint("Invalid argument\n");
337 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
338 if (ret != SQLITE_OK) {
339 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
344 if (sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
345 ErrPrint("Failed to bind a pkgid(%s)\n", sqlite3_errmsg(s_info.handle));
350 if (sqlite3_step(stmt) != SQLITE_DONE) {
352 ErrPrint("Failed to execute the DML for %s\n", pkgid);
354 if (sqlite3_changes(s_info.handle) == 0) {
355 DbgPrint("No changed\n");
361 sqlite3_clear_bindings(stmt);
362 sqlite3_finalize(stmt);
366 static void do_upgrade_db_schema(void)
370 version = get_version();
375 /* Need to create version table */
377 if (set_version(1) < 0) {
378 ErrPrint("Failed to set version\n");
380 /* Need to set version */
381 alter_shortcut_name();
382 alter_shortcut_service();
384 alter_shortcut_icon();
385 if (update_version(2) < 0) {
386 ErrPrint("Failed to update version\n");
391 /* Need to update version */
392 DbgPrint("Old version: %d\n", version);
393 if (update_version(2) < 0) {
394 ErrPrint("Failed to update version\n");
397 alter_shortcut_name();
398 alter_shortcut_service();
400 alter_shortcut_icon();
405 static int db_remove_record(const char *pkgid, const char *appid, const char *key, const char *data)
407 static const char *dml = "DELETE FROM shortcut_service WHERE appid = ? AND extra_key = ? AND extra_data = ? AND pkgid = ?";
411 if (!appid || !key || !data) {
412 ErrPrint("Invalid argument\n");
416 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
417 if (ret != SQLITE_OK) {
418 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
423 if (sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
424 ErrPrint("Failed to bind a appid(%s)\n", sqlite3_errmsg(s_info.handle));
428 if (sqlite3_bind_text(stmt, 2, key, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
429 ErrPrint("Failed to bind a key(%s)\n", sqlite3_errmsg(s_info.handle));
433 if (sqlite3_bind_text(stmt, 3, data, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
434 ErrPrint("Failed to bind a data(%s)\n", sqlite3_errmsg(s_info.handle));
438 if (sqlite3_bind_text(stmt, 4, pkgid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
439 ErrPrint("Failed to bind a pkgid(%s)\n", sqlite3_errmsg(s_info.handle));
444 if (sqlite3_step(stmt) != SQLITE_DONE) {
446 ErrPrint("Failed to execute the DML for %s - %s(%s)\n", appid, key, data);
449 if (sqlite3_changes(s_info.handle) == 0) {
450 DbgPrint("No changes\n");
455 sqlite3_clear_bindings(stmt);
456 sqlite3_finalize(stmt);
460 static int db_remove_name_by_pkgid(const char *pkgid)
462 static const char *dml = "DELETE FROM shortcut_name WHERE pkgid = ?";
467 ErrPrint("Invalid id\n");
471 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
472 if (ret != SQLITE_OK) {
473 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
477 if (sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
478 ErrPrint("Failed to bind pkgid(%s)\n", pkgid);
483 if (sqlite3_step(stmt) != SQLITE_DONE) {
485 ErrPrint("Failed to execute the DML for %s\n", pkgid);
489 if (sqlite3_changes(s_info.handle) == 0) {
490 DbgPrint("No chnages\n");
495 sqlite3_clear_bindings(stmt);
496 sqlite3_finalize(stmt);
500 static int db_remove_name(int id)
502 static const char *dml = "DELETE FROM shortcut_name WHERE id = ?";
507 ErrPrint("Inavlid id\n");
511 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
512 if (ret != SQLITE_OK) {
513 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
517 if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
518 ErrPrint("Failed to bind id(%d)\n", id);
524 if (sqlite3_step(stmt) != SQLITE_DONE) {
526 ErrPrint("Failed to execute the DML for %d\n", id);
530 if (sqlite3_changes(s_info.handle) == 0) {
531 DbgPrint("No changes\n");
536 sqlite3_clear_bindings(stmt);
537 sqlite3_finalize(stmt);
541 static int db_insert_record(const char *pkgid, const char *appid, const char *icon, const char *name, const char *key, const char *data)
543 static const char *dml = "INSERT INTO shortcut_service (pkgid, appid, icon, name, extra_key, extra_data) VALUES (?, ?, ?, ?, ?, ?)";
548 ErrPrint("Failed to get pkgid\n");
553 ErrPrint("Failed to get appid\n");
558 ErrPrint("Failed to get name\n");
563 ErrPrint("Failed to get key\n");
568 ErrPrint("Faield to get key\n");
572 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
573 if (ret != SQLITE_OK) {
574 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
579 if (sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
580 ErrPrint("Failed to bind a pkgid(%s)\n", sqlite3_errmsg(s_info.handle));
584 if (sqlite3_bind_text(stmt, 2, appid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
585 ErrPrint("Failed to bind a appid(%s)\n", sqlite3_errmsg(s_info.handle));
589 if (sqlite3_bind_text(stmt, 3, icon, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
590 ErrPrint("Failed to bind a icon(%s)\n", sqlite3_errmsg(s_info.handle));
594 if (sqlite3_bind_text(stmt, 4, name, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
595 ErrPrint("Failed to bind a name(%s)\n", sqlite3_errmsg(s_info.handle));
599 if (sqlite3_bind_text(stmt, 5, key, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
600 ErrPrint("Failed to bind a service(%s)\n", sqlite3_errmsg(s_info.handle));
604 if (sqlite3_bind_text(stmt, 6, data, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
605 ErrPrint("Failed to bind a service(%s)\n", sqlite3_errmsg(s_info.handle));
610 if (sqlite3_step(stmt) != SQLITE_DONE) {
611 ErrPrint("Failed to execute the DML for %s - %s\n", appid, name);
617 sqlite3_clear_bindings(stmt);
618 sqlite3_finalize(stmt);
622 static int db_insert_name(int id, const char *pkgid, const char *lang, const char *name, const char *icon)
624 static const char *dml = "INSERT INTO shortcut_name (id, pkgid, lang, name, icon) VALUES (?, ?, ?, ?, ?)";
628 if (id < 0 || !lang) {
629 ErrPrint("Invalid parameters\n");
633 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
634 if (ret != SQLITE_OK) {
635 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
639 if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
640 ErrPrint("Failed to bind a id(%s)\n", sqlite3_errmsg(s_info.handle));
645 if (sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
646 ErrPrint("Failed to bind a pkgid(%s)\n", sqlite3_errmsg(s_info.handle));
651 if (sqlite3_bind_text(stmt, 3, lang, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
652 ErrPrint("Failed to bind a id(%s)\n", sqlite3_errmsg(s_info.handle));
657 if (sqlite3_bind_text(stmt, 4, name, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
658 ErrPrint("Failed to bind a id(%s)\n", sqlite3_errmsg(s_info.handle));
663 if (sqlite3_bind_text(stmt, 5, icon, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
664 ErrPrint("Failed to bind a id(%s)\n", sqlite3_errmsg(s_info.handle));
670 if (sqlite3_step(stmt) != SQLITE_DONE) {
671 ErrPrint("Failed to execute the DML for %d %s %s\n", id, lang, name);
677 sqlite3_clear_bindings(stmt);
678 sqlite3_finalize(stmt);
682 static int db_get_id(const char *pkgid, const char *appid, const char *key, const char *data)
684 static const char *dml = "SELECT id FROM shortcut_service WHERE pkgid = ? AND appid = ? AND extra_key = ? AND extra_data = ?";
688 if (!appid || !key || !data) {
689 ErrPrint("Invalid argument\n");
693 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
694 if (ret != SQLITE_OK) {
695 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
700 if (sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
701 ErrPrint("Failed to bind a pkgid(%s) - %s\n", pkgid, sqlite3_errmsg(s_info.handle));
705 if (sqlite3_bind_text(stmt, 2, appid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
706 ErrPrint("Failed to bind a appid(%s) - %s\n", appid, sqlite3_errmsg(s_info.handle));
710 if (sqlite3_bind_text(stmt, 3, key, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
711 ErrPrint("Failed to bind a key(%s) - %s\n", key, sqlite3_errmsg(s_info.handle));
715 if (sqlite3_bind_text(stmt, 4, data, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
716 ErrPrint("Failed to bind a data(%s) - %s\n", data, sqlite3_errmsg(s_info.handle));
720 if (sqlite3_step(stmt) != SQLITE_ROW) {
721 ErrPrint("Failed to execute the DML for %s - %s, %s\n", appid, key, data);
726 ret = sqlite3_column_int(stmt, 0);
730 sqlite3_clear_bindings(stmt);
731 sqlite3_finalize(stmt);
735 static int db_init(void)
740 ret = db_util_open(s_info.dbfile, &s_info.handle, DB_UTIL_REGISTER_HOOK_METHOD);
741 if (ret != SQLITE_OK) {
742 ErrPrint("Failed to open a DB\n");
746 if (lstat(s_info.dbfile, &stat) < 0) {
747 ErrPrint("%d\n", errno);
748 db_util_close(s_info.handle);
749 s_info.handle = NULL;
753 if (!S_ISREG(stat.st_mode)) {
754 ErrPrint("Invalid file\n");
755 db_util_close(s_info.handle);
756 s_info.handle = NULL;
767 static int db_fini(void)
769 if (!s_info.handle) {
773 db_util_close(s_info.handle);
774 s_info.handle = NULL;
779 static int do_uninstall(const char *appid)
783 ret = db_remove_by_pkgid(appid);
785 ErrPrint("Failed to remove a record: %s\n", appid);
789 ret = db_remove_name_by_pkgid(appid);
791 ErrPrint("Failed to remove name records: %s\n", appid);
798 static inline struct i18n_name *find_i18n_name(struct dlist *i18n_list, xmlChar *lang)
801 struct i18n_name *i18n;
803 dlist_foreach(i18n_list, l, i18n) {
804 if (!xmlStrcasecmp(i18n->lang, lang)) {
812 static inline struct i18n_name *create_i18n_name(xmlChar *lang, xmlChar *name, xmlChar *icon)
814 struct i18n_name *i18n;
816 i18n = malloc(sizeof(*i18n));
818 ErrPrint("Heap: %d\n", errno);
829 static inline void destroy_i18n_name(struct i18n_name *i18n)
837 static int do_install(xmlDocPtr docPtr, const char *appid)
839 xmlNodePtr node = NULL;
840 xmlNodePtr child = NULL;
846 xmlChar *shortcut_appid;
848 struct i18n_name *i18n;
849 struct dlist *i18n_list = NULL;
854 root = xmlDocGetRootElement(docPtr);
856 ErrPrint("Invalid node ptr\n");
860 for (root = root->children; root; root = root->next) {
861 if (!xmlStrcasecmp(root->name, (const xmlChar *)"shortcut-list")) {
867 ErrPrint("Root has no children\n");
871 DbgPrint("AppID: %s\n", appid);
873 root = root->children; /* Jump to children node */
874 for (node = root; node; node = node->next) {
875 if (node->type == XML_ELEMENT_NODE) {
876 DbgPrint("Element %s\n", node->name);
879 if (xmlStrcasecmp(node->name, (const xmlChar *)"shortcut")) {
883 if (!xmlHasProp(node, (xmlChar *)"extra_key") || !xmlHasProp(node, (xmlChar *)"extra_data")) {
884 DbgPrint("Invalid element %s\n", node->name);
888 key = xmlGetProp(node, (xmlChar *)"extra_key");
889 data = xmlGetProp(node, (xmlChar *)"extra_data");
890 shortcut_appid = xmlGetProp(node, (xmlChar *)"appid");
894 for (child = node->children; child; child = child->next) {
895 if (!xmlStrcasecmp(child->name, (const xmlChar *)"icon")) {
896 lang = xmlNodeGetLang(child);
899 DbgPrint("Default icon is duplicated\n");
901 icon = xmlNodeGetContent(child);
902 DbgPrint("Default icon is %s\n", icon);
908 i18n = find_i18n_name(i18n_list, lang);
913 DbgPrint("%s is duplicated\n", i18n->icon);
917 i18n->icon = xmlNodeGetContent(child);
919 i18n = create_i18n_name(lang, NULL, xmlNodeGetContent(child));
921 ErrPrint("Failed to create a new i18n_name\n");
924 i18n_list = dlist_append(i18n_list, i18n);
930 if (!xmlStrcasecmp(child->name, (const xmlChar *)"label")) {
931 lang = xmlNodeGetLang(child);
934 DbgPrint("Default name is duplicated\n");
936 name = xmlNodeGetContent(child);
937 DbgPrint("Default name is %s\n", name);
943 i18n = find_i18n_name(i18n_list, lang);
948 DbgPrint("%s is duplicated\n", i18n->name);
952 i18n->name = xmlNodeGetContent(child);
954 i18n = create_i18n_name(lang, xmlNodeGetContent(child), NULL);
956 ErrPrint("Failed to create a new i18n_name\n");
959 i18n_list = dlist_append(i18n_list, i18n);
966 DbgPrint("appid: %s\n", appid);
967 DbgPrint("shortcut appid: %s\n", shortcut_appid);
968 DbgPrint("key: %s\n", key);
969 DbgPrint("data: %s\n", data);
970 DbgPrint("icon: %s\n", icon);
971 DbgPrint("Default name: %s\n", name);
973 if (!shortcut_appid) {
974 shortcut_appid = xmlStrdup((xmlChar *)appid);
975 DbgPrint("Use the default appid\n");
979 if (db_insert_record(appid, (char *)shortcut_appid, (char *)icon, (char *)name, (char *)key, (char *)data) < 0) {
980 ErrPrint("Failed to insert a new record\n");
981 rollback_transaction();
983 dlist_foreach_safe(i18n_list, l, n, i18n) {
984 i18n_list = dlist_remove(i18n_list, l);
985 destroy_i18n_name(i18n);
988 id = db_get_id((char *)appid, (char *)shortcut_appid, (char *)key, (char *)data);
990 ErrPrint("Failed to insert a new record\n");
991 rollback_transaction();
993 dlist_foreach_safe(i18n_list, l, n, i18n) {
994 i18n_list = dlist_remove(i18n_list, l);
995 destroy_i18n_name(i18n);
998 dlist_foreach_safe(i18n_list, l, n, i18n) {
999 i18n_list = dlist_remove(i18n_list, l);
1000 if (db_insert_name(id, appid, (char *)i18n->lang, (char *)i18n->name, (char *)i18n->icon) < 0) {
1001 ErrPrint("Failed to add i18n name: %s(%s)\n", i18n->name, i18n->lang);
1003 destroy_i18n_name(i18n);
1005 commit_transaction();
1013 xmlFree(shortcut_appid);
1019 int PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL(const char *appid)
1021 if (!s_info.handle) {
1022 if (db_init() < 0) {
1027 do_upgrade_db_schema();
1031 int PKGMGR_PARSER_PLUGIN_POST_UNINSTALL(const char *appid)
1035 begin_transaction();
1036 ret = do_uninstall(appid);
1038 rollback_transaction();
1041 commit_transaction();
1047 int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr docPtr, const char *_appid)
1049 xmlNodePtr node = NULL;
1057 DbgPrint("Package manager doesn't support the docPtr (%s)\n", _appid);
1061 root = xmlDocGetRootElement(docPtr);
1063 ErrPrint("Invalid node ptr\n");
1067 for (root = root->children; root; root = root->next) {
1068 if (!xmlStrcasecmp(root->name, (const xmlChar *)"shortcut-list")) {
1074 ErrPrint("Root has no shortcut-list\n");
1078 DbgPrint("AppID: %s\n", _appid);
1079 root = root->children;
1080 for (node = root; node; node = node->next) {
1081 if (node->type == XML_ELEMENT_NODE) {
1082 DbgPrint("Element %s\n", node->name);
1085 if (xmlStrcasecmp(node->name, (const xmlChar *)"shortcut")) {
1089 if (!xmlHasProp(node, (xmlChar *)"extra_data")
1090 || !xmlHasProp(node, (xmlChar *)"extra_key")
1091 || !xmlHasProp(node, (xmlChar *)"appid")) {
1092 DbgPrint("Invalid element %s\n", node->name);
1096 appid = xmlGetProp(node, (xmlChar *)"appid");
1097 key = xmlGetProp(node, (xmlChar *)"extra_key");
1098 data = xmlGetProp(node, (xmlChar *)"extra_data");
1100 DbgPrint("appid: %s\n", appid);
1101 DbgPrint("key: %s\n", key);
1102 DbgPrint("data: %s\n", data);
1104 id = db_get_id(NULL, (char *)appid, (char *)key, (char *)data);
1106 ErrPrint("No records found\n");
1113 begin_transaction();
1114 if (db_remove_record(NULL, (char *)appid, (char *)key, (char *)data) < 0) {
1115 ErrPrint("Failed to remove a record\n");
1116 rollback_transaction();
1123 if (db_remove_name(id) < 0) {
1124 ErrPrint("Failed to remove name records\n");
1125 rollback_transaction();
1131 commit_transaction();
1139 * if (node->children)
1140 * DbgPrint("Skip this node's children\n");
1147 int PKGMGR_PARSER_PLUGIN_PRE_INSTALL(const char *appid)
1151 if (!s_info.handle) {
1152 if (db_init() < 0) {
1157 do_upgrade_db_schema();
1159 begin_transaction();
1160 ret = do_uninstall(appid);
1162 ErrPrint("Failed to remove record: %s\n", appid);
1165 commit_transaction();
1169 int PKGMGR_PARSER_PLUGIN_POST_INSTALL(const char *appid)
1175 int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr docPtr, const char *appid)
1177 return do_install(docPtr, appid);
1180 int PKGMGR_PARSER_PLUGIN_PRE_UPGRADE(const char *appid)
1184 if (!s_info.handle) {
1185 if (db_init() < 0) {
1190 do_upgrade_db_schema();
1192 begin_transaction();
1193 ret = do_uninstall(appid);
1195 ErrPrint("Failed to remove a record: %s\n", appid);
1198 commit_transaction();
1202 int PKGMGR_PARSER_PLUGIN_POST_UPGRADE(const char *appid)
1208 int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr docPtr, const char *appid)
1211 return do_install(docPtr, appid);
1215 int main(int argc, char *argv[])
1221 ErrPRint("Invalid argument: %s XML_FILENAME\n", argv[0]);
1225 doc = xmlReadFile(argv[1], NULL, 0);
1227 ErrPrint("Failed to parse %s\n", argv[1]);
1231 root = xmlDocGetRootElement(doc);
1234 install_shortcut("", root);