diff options
Diffstat (limited to 'tool/sp_initdb/src/syspopup_parser.c')
-rw-r--r-- | tool/sp_initdb/src/syspopup_parser.c | 390 |
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; +} |