summaryrefslogtreecommitdiff
path: root/tool/sp_initdb/src/syspopup_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'tool/sp_initdb/src/syspopup_parser.c')
-rw-r--r--tool/sp_initdb/src/syspopup_parser.c390
1 files changed, 390 insertions, 0 deletions
diff --git a/tool/sp_initdb/src/syspopup_parser.c b/tool/sp_initdb/src/syspopup_parser.c
new file mode 100644
index 0000000..1e74186
--- /dev/null
+++ b/tool/sp_initdb/src/syspopup_parser.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/smack.h>
+
+#include <glib.h>
+#include <libxml/parser.h>
+#include <libxml/xmlschemas.h>
+
+#include "syspopup_private.h"
+#include "syspopup_parser.h"
+#include "syspopup_type.h"
+
+#define SCHEMA_FILE SYSCONFDIR "/syspopup/preload/manifest.xsd"
+
+typedef enum {
+ SYSPOPUP_ATTR_NONE,
+ SYSPOPUP_ATTR_NAME,
+ SYSPOPUP_ATTR_APPID,
+ SYSPOPUP_ATTR_PRIORITY,
+ SYSPOPUP_ATTR_FOCUS,
+ SYSPOPUP_ATTR_TIMEOUT,
+ SYSPOPUP_ATTR_TERM_ACTION,
+ SYSPOPUP_ATTR_ENDKEY_ACTION,
+ SYSPOPUP_ATTR_MAX,
+} syspopup_attr_e;
+
+typedef int (*syspopup_parser_func)(xmlNodePtr node, void *user_data);
+
+static int __check_manifest_validation(const char *manifest)
+{
+ xmlSchemaParserCtxtPtr ctx;
+ xmlSchemaValidCtxtPtr vctx;
+ xmlSchemaPtr xschema;
+ int ret;
+
+ if (!manifest) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ ctx = xmlSchemaNewParserCtxt(SCHEMA_FILE);
+ if (!ctx) {
+ _E("xmlSchemaNewParserCtxt() is failed. manifest(%s)",
+ manifest);
+ return -1;
+ }
+
+ xschema = xmlSchemaParse(ctx);
+ if (!xschema) {
+ _E("xmlSchemaParse() is failed. manifest(%s)", manifest);
+ xmlSchemaFreeParserCtxt(ctx);
+ return -1;
+ }
+
+ vctx = xmlSchemaNewValidCtxt(xschema);
+ if (!vctx) {
+ _E("xmlSchemaNewValidCtxt() is failed. manifest(%s)",
+ manifest);
+ xmlSchemaFree(xschema);
+ xmlSchemaFreeParserCtxt(ctx);
+ return -1;
+ }
+
+ xmlSchemaSetValidErrors(vctx, (xmlSchemaValidityErrorFunc)fprintf,
+ (xmlSchemaValidityWarningFunc)fprintf, stderr);
+
+ ret = xmlSchemaValidateFile(vctx, manifest, 0);
+ if (ret == -1) {
+ _E("xmlSchemaValidateFile() is failed. manifest(%s)", manifest);
+ } else if (ret == 0) {
+ _D("Manifest is valid. manifest(%s)", manifest);
+ } else {
+ _E("Manifest Validation Failed with error code %d", ret);
+ ret = -1;
+ }
+
+ xmlSchemaFreeValidCtxt(vctx);
+ xmlSchemaFree(xschema);
+ xmlSchemaFreeParserCtxt(ctx);
+
+ return ret;
+}
+
+static char *__get_attr(xmlNodePtr node, const char *name)
+{
+ xmlChar *val;
+ char *attr = NULL;
+
+ val = xmlGetProp(node, (const xmlChar *)name);
+ if (val) {
+ attr = strdup((char *)val);
+ xmlFree(val);
+ }
+
+ return attr;
+}
+
+static int __syspopup_attr_name(xmlNodePtr node, void *user_data)
+{
+ syspopup_t *info = (syspopup_t *)user_data;
+ char *name;
+
+ name = __get_attr(node, "name");
+ if (!name) {
+ _E("Failed to get attribute name");
+ return -1;
+ }
+
+ info->name = name;
+
+ return 0;
+}
+
+static int __syspopup_attr_appid(xmlNodePtr node, void *user_data)
+{
+ syspopup_t *info = (syspopup_t *)user_data;
+ char *appid;
+
+ appid = __get_attr(node, "appid");
+ if (!appid) {
+ _E("Failed to get attribute appid");
+ return -1;
+ }
+
+ info->appid = appid;
+
+ return 0;
+}
+
+static int __priority_to_integer(const char *priority)
+{
+ if (!strcasecmp(priority, "default"))
+ return 0;
+ else if (!strcasecmp(priority, "medium"))
+ return 1;
+ else if (!strcasecmp(priority, "high"))
+ return 2;
+ else if (!strcasecmp(priority, "top"))
+ return 3;
+
+ return -1;
+}
+
+static int __syspopup_attr_priority(xmlNodePtr node, void *user_data)
+{
+ syspopup_t *info = (syspopup_t *)user_data;
+ char *priority;
+
+ priority = __get_attr(node, "priority");
+ if (!priority) {
+ _E("Failed to get attribute priority");
+ return -1;
+ }
+
+ info->priority = __priority_to_integer(priority);
+ if (info->priority < 0) {
+ _E("Priority(%s) attribute must be 'default' or 'medium' or "
+ "'high' or 'top'", priority);
+ free(priority);
+ return -1;
+ }
+ free(priority);
+
+ return 0;
+}
+
+static bool __is_boolean(const char *value)
+{
+ if (!strcasecmp(value, "true") || !strcasecmp(value, "false"))
+ return true;
+
+ return false;
+}
+
+static int __syspopup_attr_focus(xmlNodePtr node, void *user_data)
+{
+ syspopup_t *info = (syspopup_t *)user_data;
+ char *focus;
+
+ focus = __get_attr(node, "focus");
+ if (!focus) {
+ _E("Failed to get attribute focus");
+ return -1;
+ }
+
+ if (!__is_boolean(focus)) {
+ _E("focus(%s) attribute must be 'true' or 'false'", focus);
+ free(focus);
+ return -1;
+ }
+
+ if (!strcasecmp(focus, "true"))
+ info->focus = 0;
+ else
+ info->focus = 1;
+
+ free(focus);
+
+ return 0;
+}
+
+static int __syspopup_attr_timeout(xmlNodePtr node, void *user_data)
+{
+ syspopup_t *info = (syspopup_t *)user_data;
+ char *timeout;
+
+ timeout = __get_attr(node, "timeout");
+ if (!timeout) {
+ _E("Failed to get attribute timeout");
+ return -1;
+ }
+
+ info->timeout = atoi(timeout);
+ free(timeout);
+
+ return 0;
+}
+
+static int __action_to_integer(const char *action)
+{
+ if (!strcasecmp(action, "term"))
+ return 0;
+ else if (!strcasecmp(action, "hide"))
+ return 1;
+ else if (!strcasecmp(action, "ignore"))
+ return 2;
+
+ return -1;
+}
+
+static int __syspopup_attr_term_action(xmlNodePtr node, void *user_data)
+{
+ syspopup_t *info = (syspopup_t *)user_data;
+ char *term_action;
+
+ term_action = __get_attr(node, "term-action");
+ if (!term_action) {
+ _E("Failed to get attribute term-action");
+ return -1;
+ }
+
+ info->term_action = __action_to_integer(term_action);
+ if (info->term_action < 0) {
+ _E("term-action(%s) attribute must be 'term' or 'hide' or "
+ "'ignore'", term_action);
+ free(term_action);
+ return -1;
+ }
+ free(term_action);
+
+ return 0;
+}
+
+static int __syspopup_attr_endkey_action(xmlNodePtr node, void *user_data)
+{
+ syspopup_t *info = (syspopup_t *)user_data;
+ char *endkey_action;
+
+ endkey_action = __get_attr(node, "endkey-action");
+ if (!endkey_action) {
+ _E("Failed to get attribute term-action");
+ return -1;
+ }
+
+ info->endkey_action = __action_to_integer(endkey_action);
+ if (info->endkey_action < 0) {
+ _E("endkey-action(%s) attribute must be 'term' or 'hide' or "
+ "'ignore'", endkey_action);
+ free(endkey_action);
+ return -1;
+ }
+ free(endkey_action);
+
+ return 0;
+}
+
+static syspopup_parser_func __attr_table[] = {
+ [SYSPOPUP_ATTR_NAME] = __syspopup_attr_name,
+ [SYSPOPUP_ATTR_APPID] = __syspopup_attr_appid,
+ [SYSPOPUP_ATTR_PRIORITY] = __syspopup_attr_priority,
+ [SYSPOPUP_ATTR_FOCUS] = __syspopup_attr_focus,
+ [SYSPOPUP_ATTR_TIMEOUT] = __syspopup_attr_timeout,
+ [SYSPOPUP_ATTR_TERM_ACTION] = __syspopup_attr_term_action,
+ [SYSPOPUP_ATTR_ENDKEY_ACTION] = __syspopup_attr_endkey_action,
+};
+
+static int __parse_syspopup(xmlNodePtr node, syspopup_t **syspopup)
+{
+ syspopup_t *info;
+ int ret;
+ int i;
+
+ info = calloc(1, sizeof(syspopup_t));
+ if (!info) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ for (i = SYSPOPUP_ATTR_NONE; i < SYSPOPUP_ATTR_MAX; i++) {
+ if (!__attr_table[i])
+ continue;
+
+ ret = __attr_table[i](node, info);
+ if (ret < 0) {
+ _E("Failed to parse attribute %d", i);
+ syspopup_free(info);
+ return -1;
+ }
+ }
+
+ *syspopup = info;
+
+ return 0;
+}
+
+int syspopup_parser_parse(const char *manifest, GList **syspopup_list)
+{
+ GList *list = NULL;
+ xmlDocPtr doc;
+ xmlNodePtr root;
+ xmlNodePtr node;
+ syspopup_t *info;
+ int ret;
+
+ if (!manifest || !syspopup_list) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ ret = __check_manifest_validation(manifest);
+ if (ret < 0)
+ return -1;
+
+ doc = xmlParseFile(manifest);
+ if (!doc) {
+ _E("Failed to parse %s", manifest);
+ return -1;
+ }
+
+ root = xmlDocGetRootElement(doc);
+ if (!root) {
+ _E("Failed to get root element %s", manifest);
+ xmlFreeDoc(doc);
+ return -1;
+ }
+
+ for (node = root->children; node; node = node->next) {
+ if (!node->name)
+ continue;
+
+ if (strcmp((char *)node->name, "syspopup") != 0)
+ continue;
+
+ info = NULL;
+ ret = __parse_syspopup(node, &info);
+ if (ret < 0) {
+ _E("Failed to parse syspopup");
+ continue;
+ }
+
+ list = g_list_append(list, info);
+ }
+
+ *syspopup_list = list;
+ xmlFreeDoc(doc);
+
+ return 0;
+}