From 98d02ddb1a4b4bf4b0879fb189707543d06bc6bf Mon Sep 17 00:00:00 2001 From: MyoungJune Park Date: Mon, 27 Mar 2017 13:37:59 +0900 Subject: init code Change-Id: Ie6cb5cdbcabca325d23d3a230027d40f67c09644 Signed-off-by: MyoungJune Park --- src/ccerror.h | 14 ++ src/factory-reset-util.c | 382 +++++++++++++++++++++++++++++++++++++++++++++++ src/factory-reset-util.h | 52 +++++++ src/factory-reset.c | 341 ++++++++++++++++++++++++++++++++++++++++++ src/resetCCMode.c | 72 +++++++++ src/rstsmack.c | 148 ++++++++++++++++++ 6 files changed, 1009 insertions(+) create mode 100755 src/ccerror.h create mode 100755 src/factory-reset-util.c create mode 100644 src/factory-reset-util.h create mode 100644 src/factory-reset.c create mode 100755 src/resetCCMode.c create mode 100644 src/rstsmack.c (limited to 'src') diff --git a/src/ccerror.h b/src/ccerror.h new file mode 100755 index 0000000..e9d0d6c --- /dev/null +++ b/src/ccerror.h @@ -0,0 +1,14 @@ +#ifndef CC_ERROR_H +#define CC_ERROR_H + +#define CC_ERROR_BASE 500 +#define CC_ERROR_FILE_BASE 100 +#define CC_ERROR_FUNCTION_BASE 20 +#define CC_ERROR_NONE 0 + +#define CC_ERROR_UTIL_GETCCMODE CC_ERROR_BASE //500 +#define CC_ERROR_UTIL_RESETSBFCCM CC_ERROR_UTIL_GETCCMODE+CC_ERROR_FUNCTION_BASE +#define CC_ERROR_ZEROISE CC_ERROR_UTIL_GETCCMODE+CC_ERROR_FILE_BASE +#define CC_ERROR_VERIFY 100 //100 + +#endif diff --git a/src/factory-reset-util.c b/src/factory-reset-util.c new file mode 100755 index 0000000..508ebe2 --- /dev/null +++ b/src/factory-reset-util.c @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. + * + * Contact: MyoungJune Park + * Created by Wonil Choi + * + * 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. + * + */ + +#include +#include + +#if 0 +#ifndef TELEPHONY_DISABLE +#include +#include +#include +#include +#endif +#endif + +//#include +//#include +#include + +#include "factory-reset-util.h" + +#ifndef FACTORY_RESET_FONT_SIZE +#define FACTORY_RESET_FONT_SIZE 34 /* default font size */ +#endif + +#define FACTORY_RESET_PROCESS_MSG dgettext("factory-reset",\ + "IDS_ST_BODY_PERFORMING_FACTORY_DATA_RESET_PLEASE_WAIT_ING") + +static void win_del(void *data, Evas_Object *obj, void *event) +{ + elm_exit(); +} + +static void main_quit_cb(void *data, Evas_Object *obj, + const char *emission, const char *source) +{ + elm_exit(); +} + +static Evas_Object* create_win(const char *name) +{ + Evas_Object *eo; + //Ecore_X_Window xwin; + int w, h; + + w = 200; + h = 400; + + eo = elm_win_add(NULL, name, ELM_WIN_BASIC); + if (!eo) + return NULL; + + elm_win_title_set(eo, name); + elm_win_borderless_set(eo, EINA_TRUE); + evas_object_smart_callback_add(eo, "delete,request", win_del, NULL); + //ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h); + evas_object_resize(eo, w, h); + + /* For default color */ + //ea_theme_changeable_ui_enabled_set(EINA_TRUE); + +#if 0 + /* Get x-window */ + xwin = elm_win_xwindow_get(eo); + if (xwin == 0) { + FR_LOGD("elm_win_xwindow_get() failed\n"); + return eo; + } +#endif + + /* set notification type */ + //ecore_x_netwm_window_type_set(xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION); + + /* set notification's priority */ + //utilx_set_system_notification_level(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_LEVEL_NORMAL); + + return eo; +} + +static Evas_Object* load_edj(Evas_Object *parent, const char *file, + const char *group) +{ + Evas_Object *eo; + int r; + + eo = elm_layout_add(parent); + if (eo) { + r = elm_layout_file_set(eo, file, group); + if (!r) { + evas_object_del(eo); + return NULL; + } + + evas_object_size_hint_weight_set(eo, + EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + } + + return eo; +} + +#if 0 +static Evas_Object* _create_progressbar(Evas_Object* parent) +{ + Evas_Object *progressbar; + Evas_Object *layout = parent; + + /* pending_list style */ + progressbar = elm_progressbar_add(layout); + elm_object_style_set(progressbar, "pending"); + elm_progressbar_horizontal_set(progressbar, EINA_TRUE); + evas_object_size_hint_align_set(progressbar, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(progressbar, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_progressbar_pulse(progressbar, EINA_TRUE); + elm_object_part_content_set(layout,"pending_pbar", progressbar); + evas_object_show(progressbar); + + return layout; +} +#endif + +static Evas_Object* _create_label(Evas_Object* parent) +{ + Evas_Object *label, *layout = parent; + char mesg[1024]; + + if (parent == NULL) + return NULL; + + snprintf(mesg, sizeof(mesg), + "%s", + FACTORY_RESET_FONT_SIZE, FACTORY_RESET_PROCESS_MSG); + + label = elm_label_add(layout); + elm_label_line_wrap_set(label, ELM_WRAP_MIXED); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_content_set(layout, "txt_mesg", label); + elm_object_text_set(label, mesg); + evas_object_show(label); + + return layout; +} + +static int app_create(void *data) +{ + struct appdata *ad = data; + Evas_Object *win; + Evas_Object *ly; + int r; + + /* create window */ + win = create_win(PACKAGE); + if (win == NULL) + return -1; + ad->win = win; + + elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_HIDE); + evas_object_show(win); + + /* load edje */ + ly = load_edj(win, EDJ_FILE, GRP_MAIN); + if (ly == NULL) + return -1; + elm_win_resize_object_add(win, ly); + edje_object_signal_callback_add(elm_layout_edje_get(ly), + "EXIT", "*", main_quit_cb, NULL); + ad->ly_main = ly; + + /* init internationalization */ + r = appcore_set_i18n(PACKAGE, LOCALEDIR); + if (r) + return -1; + + //_create_progressbar(ly); + _create_label(ly); + + evas_object_show(ly); + evas_object_show(win); + + return 0; +} + +static int app_terminate(void *data) +{ + struct appdata *ad = data; + + if (ad->ly_main) + evas_object_del(ad->ly_main); + + if (ad->win) + evas_object_del(ad->win); + + return 0; +} + +static int app_pause(void *data) +{ + return 0; +} + +static int app_resume(void *data) +{ + return 0; +} + +static int app_reset(bundle *b, void *data) +{ + struct appdata *ad = data; + + if (ad->win) + elm_win_activate(ad->win); + + return 0; +} + +#if 0 +#ifndef TELEPHONY_DISABLE +#define CP_OFF_TIMEOUT 15 +static Ecore_Timer *timer_id; + +static void cp_shutdown_exit(TapiHandle *handle, const char *noti_id, + void *data, void *user_data) +{ + tel_deinit(handle); + ecore_main_loop_quit(); +} + +static void tapi_response(TapiHandle *handle, int result, + void *data, void *user_data) +{ + if (result != TAPI_API_SUCCESS) { + tel_deinit(handle); + ecore_main_loop_quit(); + } +} + +static Eina_Bool timeout_exit(void *data) +{ + perror("no notification from telephony!!"); + ecore_main_loop_quit(); + return EINA_TRUE; +} + +static int cp_shutdown(void) +{ + int ret = 0; + TapiHandle *tapi_handle = 0; + + tapi_handle = tel_init(0); + + if (tapi_handle == NULL) + return -1; + + FR_LOGD("CP shutdown\n"); + + ret = tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER, + cp_shutdown_exit, NULL); + if (ret != TAPI_API_SUCCESS) + goto out; + + ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF, + tapi_response, NULL); + if (ret != TAPI_API_SUCCESS) + goto out; + + timer_id = ecore_timer_add(CP_OFF_TIMEOUT, timeout_exit, NULL); + if (timer_id == NULL) + ret = -1; +out: + if (ret < 0) { + tel_deinit(tapi_handle); + return -1; + } + return 0; +} + +/* reset modem configs */ +static int cp_resetcfg(int reset_config) +{ + int ret = 0; + + ret = tel_sec_init(); + if (ret != TAPI_SEC_API_SUCCESS) + return -1; + /* + * Full reset: Initialize all configuration data. + * Factory reset (AT+FACTORST=0,0): except IMEI(or ESN, MEID), RF + * calibration date, MAC address. + * Service reset (Settings -> Back up and reset -> Factory data reset): + * except IMEI(or ESN, MEID), RF calibration date, MAC address, Life + * time. + * Custom reset: except IMEI(or ESN, MEID), RF calibration date, MAC + * address, Life time, connection settings, WAP settings. + */ + /* we use the Service reset currently. (except verizon) */ + ret = tel_set_cfg_default_configuration(reset_config); + FR_LOGD("request cp reset with the flag value: %d\n", reset_config); + tel_sec_deinit(); + return ret; +} +#else /* TELEPHONY_DISABLE */ +static int cp_shutdown(void) { return -1;} /* in order to avoid main loop */ +static int cp_resetcfg(int reset_config) { return 0;} +#endif /* TELEPHONY_DISABLE */ + +#endif + + +int main(int argc, char *argv[]) +{ + struct appdata ad; + struct appcore_ops ops = { + .create = app_create, + .terminate = app_terminate, + .pause = app_pause, + .resume = app_resume, + .reset = app_reset, + }; + int opt; + int index = -1; + struct option options[] = { + {"displayui", 0, 0, 0}, + {"svcrstcp", 0, 0, 0}, /* modem service reset */ + {"ftrrstcp", 0, 0, 0}, /* modem factory reset */ + {"", 0, 0, 0}, + {"", 0, 0, 0}, + {0, 0, 0, 0} + }; + + + opt = getopt_long(argc, argv, "", options, &index); + if(opt == -1) + return 0; + + switch(index) { + case 0 : + memset(&ad, 0x0, sizeof(struct appdata)); + ops.data = &ad; + return appcore_efl_main(PACKAGE, &argc, &argv, &ops); + case 1 : + ecore_init(); + //cp_resetcfg(TAPI_CFG_DEFAULT_SERVICE); + //if ( cp_shutdown() == 0) ecore_main_loop_begin(); + ecore_shutdown(); + break; + case 2 : + ecore_init(); + //cp_resetcfg(TAPI_CFG_DEFAULT_FACTORY); + //if ( cp_shutdown() == 0) ecore_main_loop_begin(); + ecore_shutdown(); + break; + break; + case 3 : + + break; + case 4 : + + break; + default : + ; + } + + return 0; +} + diff --git a/src/factory-reset-util.h b/src/factory-reset-util.h new file mode 100644 index 0000000..3f60557 --- /dev/null +++ b/src/factory-reset-util.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. + * + * Contact: MyoungJune Park + * Created by Wonil Choi + * + * 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. + * + */ + +#include + +#if !defined(PACKAGE) +# define PACKAGE "factory-reset-util" +#endif +#undef PACKAGE +#define PACKAGE "factory-reset-util" +#if !defined(LOCALEDIR) +# define LOCALEDIR "/usr/share/locale" +#endif + +#if !defined(EDJDIR) +# define EDJDIR "/usr/share/edje" +#endif + +#define EDJ_FILE "/usr/share/edje/factory-reset-util.edj" +#define GRP_MAIN "main" + +struct appdata +{ + Evas_Object *win; + Evas_Object *ly_main; + + /* add more variables here */ +}; + +#ifdef DEBUG +# define FR_LOGD(fmt, arg...) printf(fmt, ##arg) +#else +# define FR_LOGD(fmt, arg...) +#endif + diff --git a/src/factory-reset.c b/src/factory-reset.c new file mode 100644 index 0000000..a0de792 --- /dev/null +++ b/src/factory-reset.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. + * + * Contact: MyoungJune Park + * Created by Wonil Choi + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RESET_FLAG_FILE "/opt/.factoryreset" +static const char RESET_BACKUP_FILE[2][40] = { + "/usr/system/RestoreDir/opt.tar.gz", + "/usr/system/RestoreDir/opt.zip" +}; + +static const char *RUN_SCRIPT_FILE = "/usr/bin/run-factory-reset.sh"; +static const char *LOG_FILE = "/opt/.factoryreset.log"; +static const char *LOG_OLD = "/opt/.factoryreset.log.1"; + +static char *reset_flag; + +void usage() +{ + printf("Options: \n"); + printf(" -b, --dbus Start with dbus signal message\n"); + printf("\n"); + + exit(0); +} + +//extern int csc_svc_config_set_pre_config_for_factory_reset( void ); +/*================================================================================== +* CSC API Code (12/10/11 applied) + - Include header : #include "csc-dispatch.h" + - API : int csc_svc_config_set_pre_config_for_factory_reset( void ); + - Return value : 1 (Success), 0 (Failure, 미리 저장해놓은 거래선 코드가 없을 경우 발생) +====================================================================================*/ +int __system(const char *argv[]) +{ + int status; + pid_t cpid; + + cpid = fork(); + + if (cpid == -1) { + perror("fork"); + return -1; + } + + if (cpid == 0) { + execvp(argv[0], (char *const *)argv); + _exit(-1); + } else { + if (waitpid(cpid, &status, 0) == -1) { + perror("waitpid failed"); + return -1; + } + if (WIFSIGNALED(status)) { + perror("exit by signal"); + return -1; + } + if (!WIFEXITED(status)) { + perror("exit abnormally"); + return -1; + } + if (WIFEXITED(status) && WEXITSTATUS(status)) { + perror("child return error"); + return -1; + } + } + return 0; +} + + +#define RESET_DBUS_SERVICE "org.tizen.factoryreset" +#define RESET_DBUS_INTERFACE RESET_DBUS_SERVICE".start" + +static const char granted_caller[6][16] = { + "setting", + "cscmgr", + "wms", + "bt", /* when the host device is changed */ + "omadmagent", + "testmode" +}; + +static const char list_reset_flags[2][16] = { + "ftrrstcp", + "withoutcp" +}; + + +static GMainLoop* loop; +static DBusConnection *bus_conn = NULL; +static const char *dbus_obj_path = "/org/tizen/factoryreset"; + +static void unregistered_func (DBusConnection *connection, void *user_data) +{ + perror("factory-reset dbus unregistered\n"); +} + +static DBusHandlerResult message_func (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + /* store the name of factory reset caller. */ + char caller_name[NAME_MAX]; + FILE *fp = NULL; + int i = 0; + + if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL) { + perror("Not a dbus-signal\n"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (strncmp(dbus_message_get_interface(message), RESET_DBUS_INTERFACE, + strlen(RESET_DBUS_INTERFACE)) != 0) { + printf("Not correct interface: \"%s\"\n", + dbus_message_get_interface (message)); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + strncpy(caller_name, dbus_message_get_member(message), + sizeof(caller_name)); + caller_name[NAME_MAX - 1] = '\0'; + + while (strncmp(granted_caller[i], caller_name, + strlen(granted_caller[i]))) { + if ((++i) >= sizeof(granted_caller) / sizeof(granted_caller[0])) { + printf("Not a granted caller, %s\n", caller_name); + /* XXX Warning: Comparing granted caller list cannot + * grant good caller or not. Security is and should be + * protected by the SMACK rule. This code is only for + * preventing that a new unknown caller use factory + * reset without confirmation of the factory reset + * developer. + */ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + } + fp = fopen(LOG_FILE, "a"); + if (fp != NULL) { + fprintf(fp, "Requested by %s, %s\n", caller_name, + dbus_message_get_sender(message)); + fclose(fp); + } + + /* member name of dbus signal message may contains reset flags */ + for (i = 0; i < sizeof(list_reset_flags) / sizeof(list_reset_flags[0]); + i++) { + if (strstr(caller_name, list_reset_flags[i])) { + snprintf(caller_name, NAME_MAX, "--%s", + list_reset_flags[i]); + reset_flag = strdup(caller_name); + break; + } + } + + g_main_loop_quit(loop); + return DBUS_HANDLER_RESULT_HANDLED; +} + + +static DBusHandlerResult filter_func (DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, + "Disconnected")) { + /* Exit cleanly. */ + printf("Disconnected"); + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusObjectPathVTable dbus_vtable = { + unregistered_func, + message_func, + NULL, +}; + +static int process_dbus(void) +{ + int ret; + DBusError error; + + loop = g_main_loop_new (NULL, FALSE); + + dbus_error_init (&error); + bus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (!bus_conn) { + perror("failed to get dbus system bus"); + dbus_error_free(&error); + return -1; + } + /* Add message filter to handle Disconnected. */ + dbus_connection_add_filter(bus_conn, (DBusHandleMessageFunction) filter_func, + NULL, NULL); + + ret = dbus_bus_request_name(bus_conn, RESET_DBUS_SERVICE, 0, &error); + + /* Should be ret == -1, if error is set */ + if (ret == -1 && dbus_error_is_set(&error)) { + dbus_error_free (&error); + return -1; + } + + if (!dbus_connection_register_object_path(bus_conn, dbus_obj_path, + &dbus_vtable, NULL)) { + return -1; + } + + dbus_connection_setup_with_g_main(bus_conn, NULL); + g_main_loop_run(loop); + return 0; +} + + +int main(int argc, char **argv) +{ + FILE *fp; + int ret, i = 0, c; + const char *reset_cmd[] = {RUN_SCRIPT_FILE, NULL, NULL}; + time_t t = time(NULL); + struct tm tm2 = *localtime(&t); + + static struct option long_options[] = { + {"dbus", no_argument, NULL, 'b'}, + {0, 0, 0, 0} + }; + + ret = setuid(0); + if (ret < 0) { + perror("wrong permission"); + return -1; + } + + /* If there is no factory-reset backup file, don't try to reset. */ + while (!(fp = fopen(RESET_BACKUP_FILE[i++], "r"))) { + if (i >= sizeof(RESET_BACKUP_FILE) / + sizeof(RESET_BACKUP_FILE[0])) { + perror("backup file is not exist"); + return -1; + } + } + if (fp != NULL) fclose(fp); + + if (rename(LOG_FILE, LOG_OLD) < 0) + perror("can't rename the old log file"); + + while (1) { + + int option_index = -1; + c = getopt_long(argc, argv, "b", long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'b': + + if (process_dbus() < 0) { + perror("dbus has some errors."); + return -1; + } + break; + + default: + usage(); + break; + } + } + + if (optind < argc) + usage(); + +#if 0 + fp = fopen(RESET_FLAG_FILE, "w"); + if (fp == NULL) { + perror("reset flg file open error"); + return -1; + } + fclose(fp); +#endif + + // Factory Reset Run + reset_cmd[1] = reset_flag; + __system(reset_cmd); + + // open log file (add local time) + fp = fopen(LOG_FILE, "a"); + if (fp == NULL) { + perror("reset log file open error"); + return -2; + } + + // write finish log file + fprintf(fp, "End Factory Reset\n%d-%02d-%02d %02d:%02d:%02d\n", + tm2.tm_year + 1900, tm2.tm_mon + 1, tm2.tm_mday, + tm2.tm_hour, tm2.tm_min, tm2.tm_sec); + fclose(fp); + + // remove reset flag file, sync and reboot +#if 0 + unlink(RESET_FLAG_FILE); +#endif + sync(); + +#ifdef DEBUG_BINARY + reboot(LINUX_REBOOT_CMD_RESTART); +#else + const char *reboot_cmd[] = {"/usr/sbin/reboot", "debug0x4f4c", NULL}; + __system(reboot_cmd); +#endif + + return 0; +} diff --git a/src/resetCCMode.c b/src/resetCCMode.c new file mode 100755 index 0000000..2d3e8fe --- /dev/null +++ b/src/resetCCMode.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. + * + * Contact: MyoungJune Park + * Created by Wonil Choi + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "ccerror.h" + +#define PARAM_CC_ENC_RAW_SIZE 64 +#define PARAM_CC_FLAG_OFFSET 0x800 + +static const char dev_params[] = { + "/dev/disk/by-partlabel/param" +}; + +int resetSBFCCM(void) +{ + int ret, fd; + uint8_t eraw[PARAM_CC_ENC_RAW_SIZE]; + + memset(eraw, 0, PARAM_CC_ENC_RAW_SIZE); + if ((fd = open(dev_params, O_WRONLY)) == -1) { + ret = -CC_ERROR_UTIL_RESETSBFCCM; + goto open_fail; + } + + if (lseek(fd, -(PARAM_CC_FLAG_OFFSET), SEEK_END) == -1) { + ret = -(CC_ERROR_UTIL_RESETSBFCCM + 2); + goto out; + } + + if (write(fd, eraw, PARAM_CC_ENC_RAW_SIZE) != PARAM_CC_ENC_RAW_SIZE) { + ret = -(CC_ERROR_UTIL_RESETSBFCCM + 3); + goto out; + } + + ret = CC_ERROR_NONE; +out: + close(fd); +open_fail: + return ret; +} + +int main(void) +{ + int ret = resetSBFCCM(); + printf("resetSBFCCM() returns %d\n", ret); + return ret; +} + diff --git a/src/rstsmack.c b/src/rstsmack.c new file mode 100644 index 0000000..38d18d5 --- /dev/null +++ b/src/rstsmack.c @@ -0,0 +1,148 @@ +/* + * rstsmack - Restore smack attributes on files + * + * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. + * + * Contact: MyoungJune Park + * Created by Wonil Choi + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG +# define LOGINFO(fmt, arg...) printf(fmt, ##arg) +#else +# define LOGINFO(fmt, arg...) +#endif + +void print_help(const char *cmd) +{ + printf("Usage: %s \n", cmd); + printf(" INPUT FILE should be same format as generated by" + " chsmack.\n\n"); + printf(" Ex) # chsmack /usr/bin/* > /tmp/rstsmack_input.txt\n"); +} + +static inline int abandonqm(char *label) +{ + int ret = 0; + /* ignore last character which must be a quotation mark */ + ret = (int) strlen(label); + ret--; + if (ret > SMACK_LABEL_LEN || ret <= 0) + return -1; + label[ret] = '\0'; + return 0; +} + +static void set_label(const char *pathname, char *label, int type) +{ + int ret = -1; + + if (abandonqm(label) == 0) { + ret = smack_lsetlabel(pathname, label, type); + if (ret < 0) + perror(pathname); + } else + fprintf(stderr, "The input file has wrong format, %s\n", + pathname); +} + +static int parse_and_set(const char *srcfile) +{ + /* We assume the text format of input file is same as chsmack output */ + FILE *fp; + int ret = 0; + char linebuf[PATH_MAX + 5 * SMACK_LABEL_LEN], pathname[PATH_MAX]; + char label[SMACK_LABEL_LEN + 1]; + char *plabel; /* pointer of beginning smack label */ + fp = fopen(srcfile, "r"); + if (fp == NULL) + return -1; + + while (fgets(linebuf, sizeof(linebuf), fp)) { + plabel = strstr(linebuf, " access="); + if (plabel && linebuf != plabel) { + *plabel = '\0'; + strncpy(pathname, linebuf, sizeof(pathname)); + pathname[sizeof(pathname) - 1] = '\0'; + plabel++; + } else { + linebuf[strlen(linebuf) - 1] = '\0'; + LOGINFO("no label, set label: %s, access=\"_\"(floor)\n", linebuf); + strncpy(label, "_\"", SMACK_LABEL_LEN); + set_label(linebuf, label, SMACK_LABEL_ACCESS); + /* TODO: If file name contains " access=" then it would + * not be processed */ + continue; + } + + LOGINFO("set label: %s,", pathname); + + ret = sscanf(plabel, "access=\"%s", label); + if (ret > 0) { + LOGINFO(" access: \"%s", label); + set_label(pathname, label, SMACK_LABEL_ACCESS); + plabel = plabel + sizeof(" access=\"") + strlen(label); + } + + ret = sscanf(plabel, "execute=\"%s", label); + if (ret > 0) { + LOGINFO(", exec: \"%s", label); + set_label(pathname, label, SMACK_LABEL_EXEC); + plabel = plabel + sizeof(" execute=\"") + strlen(label); + } + + ret = sscanf(plabel, "mmap=\"%s", label); + if (ret > 0) { + LOGINFO(", mmap: \"%s", label); + set_label(pathname, label, SMACK_LABEL_MMAP); + plabel = plabel + sizeof(" mmap=\"") + strlen(label); + } + + ret = sscanf(plabel, "transmute=\"%s", label); + if (ret > 0) { + LOGINFO(", transmute: \"%s", label); + strncpy(label, "1\"", SMACK_LABEL_LEN); + set_label(pathname, label, SMACK_LABEL_TRANSMUTE); + } + LOGINFO("\n"); + + } + fclose(fp); + return 0; +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) { + print_help(argv[0]); + return -1; + } + if (parse_and_set(argv[1]) < 0) { + print_help(argv[0]); + return -1; + } + return 0; +} -- cgit v1.2.3