int conf_file_merge(void) { GDir *confdir; struct stat fileinfo, dir; const gchar *filename, *mode = 0; gchar *filename_full; GString *keyfile_string = NULL; GKeyFile *settingsfile; int ret = 0, test = 0; #ifdef UDEV const gchar *udev = 0; #endif /* UDEV */ confdir = g_dir_open(CONFIG_FILE_DIR, 0, NULL); if(!confdir) { log_debug("No configuration. Creating defaults.\n"); create_conf_file(); return (ret); } if (stat(FS_MOUNT_CONFIG_FILE, &fileinfo) == -1) { /* conf file not created yet, make default and merge all */ create_conf_file(); } /* config file is created, so the dir must exists */ stat(CONFIG_FILE_DIR, &dir); /* st_mtime is changed by file modifications, st_mtime of a directory is changed by the creation or deletion of files in that directory. So if the st_mtime of the config file is equal to the directory time we can be sure the config is untouched and we do not need to re-merge the config. */ if(fileinfo.st_mtime == dir.st_mtime) return 0; log_debug("Merging/creating configuration.\n"); keyfile_string = g_string_new(NULL); /* check each ini file and get contents */ while((filename = g_dir_read_name(confdir)) != NULL) { log_debug("filename = %s\n", filename); filename_full = g_strconcat(CONFIG_FILE_DIR, "/", filename, NULL); if(!strcmp(filename_full, FS_MOUNT_CONFIG_FILE)) { /* store mode info to add it later as we want to keep it */ mode = get_mode_setting(); #ifdef UDEV /* store udev path (especially important for the upgrade path */ udev = find_udev_path(); #endif /* UDEV */ break; } /* load contents of file, if it fails skip to next one */ settingsfile = g_key_file_new(); test = g_key_file_load_from_file(settingsfile, filename_full, G_KEY_FILE_KEEP_COMMENTS, NULL); if(!test) { log_debug("%d failed loading config file %s\n", test, filename_full); g_free(filename_full); break; } g_free(filename_full); log_debug("file data = %s\n", g_key_file_to_data(settingsfile, NULL, NULL)); keyfile_string = g_string_append(keyfile_string, g_key_file_to_data(settingsfile, NULL, NULL)); log_debug("keyfile_string = %s\n", keyfile_string->str); g_key_file_free(settingsfile); } if(keyfile_string) { /* write out merged config file */ /* g_file_set_contents returns 1 on succes, this function returns 0 */ ret = !g_file_set_contents(FS_MOUNT_CONFIG_FILE, keyfile_string->str, -1, NULL); g_string_free(keyfile_string, TRUE); if(mode) { set_mode_setting(mode); } #ifdef UDEV if(udev) { set_config_setting(UDEV_PATH_ENTRY, UDEV_PATH_KEY, udev); } #endif /* UDEV */ } else ret = 1; if(mode) free((void *)mode); #ifdef UDEV if(udev) free((void *)udev); #endif /* UDEV */ g_dir_close(confdir); return(ret); }
int conf_file_merge(void) { GDir *confdir; struct stat fileinfo, dir; char *mode = 0, *ip = 0, *gateway = 0, *udev = 0; gchar *filename_full; const gchar *filename; GString *keyfile_string = NULL; GKeyFile *settingsfile; int ret = 0, test = 0, conffile_created = 0; confdir = g_dir_open(CONFIG_FILE_DIR, 0, NULL); if(!confdir) { log_debug("No configuration. Creating defaults.\n"); create_conf_file(); /* since there was no configuration at all there is no info to be merged */ return (ret); } if (stat(FS_MOUNT_CONFIG_FILE, &fileinfo) == -1) { /* conf file not created yet, make default and merge all */ create_conf_file(); conffile_created = 1; } /* config file is created, so the dir must exists */ if(stat(CONFIG_FILE_DIR, &dir)) { log_warning("Directory still does not exists. FS might be ro/corrupted!\n"); ret = 1; goto end; } /* st_mtime is changed by file modifications, st_mtime of a directory is changed by the creation or deletion of files in that directory. So if the st_mtime of the config file is equal to the directory time we can be sure the config is untouched and we do not need to re-merge the config. */ if(fileinfo.st_mtime == dir.st_mtime) { /* if a conffile was created, the st_mtime would have been updated so this check will miss information that might be there already, like after a config file removal for example. So we run a merge anyway if we needed to create the conf file */ if(!conffile_created) goto end; } log_debug("Merging/creating configuration.\n"); keyfile_string = g_string_new(NULL); /* check each ini file and get contents */ while((filename = g_dir_read_name(confdir)) != NULL) { if(!strstr(filename, ".ini")) { /* skip this file as it might be a dir or not an ini file */ continue; } filename_full = g_strconcat(CONFIG_FILE_DIR, "/", filename, NULL); log_debug("filename = %s\n", filename_full); if(!strcmp(filename_full, FS_MOUNT_CONFIG_FILE)) { /* store mode info to add it later as we want to keep it */ mode = get_mode_setting(); /* store udev path (especially important for the upgrade path */ udev = find_udev_path(); ip = get_conf_string(NETWORK_ENTRY, NETWORK_IP_KEY); gateway = get_conf_string(NETWORK_ENTRY, NETWORK_GATEWAY_KEY); continue; } /* load contents of file, if it fails skip to next one */ settingsfile = g_key_file_new(); test = g_key_file_load_from_file(settingsfile, filename_full, G_KEY_FILE_KEEP_COMMENTS, NULL); if(!test) { log_debug("%d failed loading config file %s\n", test, filename_full); goto next; } log_debug("file data = %s\n", g_key_file_to_data(settingsfile, NULL, NULL)); keyfile_string = g_string_append(keyfile_string, g_key_file_to_data(settingsfile, NULL, NULL)); log_debug("keyfile_string = %s\n", keyfile_string->str); g_key_file_free(settingsfile); next: g_free(filename_full); } if(keyfile_string) { /* write out merged config file */ /* g_file_set_contents returns 1 on succes, this function returns 0 */ ret = !g_file_set_contents(FS_MOUNT_CONFIG_FILE, keyfile_string->str, -1, NULL); g_string_free(keyfile_string, TRUE); if(mode) { set_mode_setting(mode); } if(udev) { set_config_setting(UDEV_PATH_ENTRY, UDEV_PATH_KEY, udev); } /* check if no network data came from an ini file */ if( get_conf_string(NETWORK_ENTRY, NETWORK_IP_KEY)) goto cleanup; if(ip) set_network_setting(NETWORK_IP_KEY, ip); if(gateway) set_network_setting(NETWORK_GATEWAY_KEY, gateway); } else ret = 1; cleanup: if(mode) free(mode); if(udev) free(udev); if(ip) free(ip); if(gateway) free(gateway); end: g_dir_close(confdir); return(ret); }
static DBusHandlerResult msg_handler(DBusConnection *const connection, DBusMessage *const msg, gpointer const user_data) { DBusHandlerResult status = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; DBusMessage *reply = 0; const char *interface = dbus_message_get_interface(msg); const char *member = dbus_message_get_member(msg); const char *object = dbus_message_get_path(msg); int type = dbus_message_get_type(msg); const char *xml = "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" " "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n" "<node name=\"/com/meego/usb_moded\">\n" " <interface name=\"com.meego.usb_moded\">\n" " <method name=\"mode_request\">\n" " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n" " </method>\n" " <method name=\"set_mode\">\n" " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n" " </method>\n" " <signal name=\"sig_usb_state_ind\">\n" " <arg name=\"mode\" type=\"s\"/>\n" " </signal>\n" " </interface>\n" " </node>\n"; (void)user_data; if(!interface || !member || !object) goto EXIT; if( type == DBUS_MESSAGE_TYPE_METHOD_CALL && !strcmp(interface, USB_MODE_INTERFACE) && !strcmp(object, USB_MODE_OBJECT)) { status = DBUS_HANDLER_RESULT_HANDLED; if(!strcmp(member, USB_MODE_STATE_REQUEST)) { const char *mode = get_usb_mode(); if((reply = dbus_message_new_method_return(msg))) dbus_message_append_args (reply, DBUS_TYPE_STRING, &mode, DBUS_TYPE_INVALID); } else if(!strcmp(member, USB_MODE_STATE_SET)) { char *use = 0; DBusError err = DBUS_ERROR_INIT; if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &use, DBUS_TYPE_INVALID)) reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member); else { /* check if usb is connected, since it makes no sense to change mode if it isn't */ if(!get_usb_connection_state()) { log_warning("USB not connected, not changing mode!\n"); goto error_reply; } /* check if the mode exists */ if(valid_mode(use)) goto error_reply; /* do not change mode if the mode requested is the one already set */ if(strcmp(use, get_usb_mode()) != 0) set_usb_mode(use); if((reply = dbus_message_new_method_return(msg))) dbus_message_append_args (reply, DBUS_TYPE_STRING, &use, DBUS_TYPE_INVALID); else error_reply: reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member); } dbus_error_free(&err); } else if(!strcmp(member, USB_MODE_CONFIG_SET)) { char *config = 0; DBusError err = DBUS_ERROR_INIT; if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID)) reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member); else { /* error checking is done when setting configuration */ if(!set_mode_setting(config)) { if((reply = dbus_message_new_method_return(msg))) dbus_message_append_args (reply, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID); } else reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, config); } dbus_error_free(&err); } else if(!strcmp(member, USB_MODE_NETWORK_SET)) { char *config = 0, *setting = 0; DBusError err = DBUS_ERROR_INIT; if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_STRING, &setting, DBUS_TYPE_INVALID)) reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member); else { /* error checking is done when setting configuration */ if(!set_network_setting(config, setting)) { if((reply = dbus_message_new_method_return(msg))) dbus_message_append_args (reply, DBUS_TYPE_STRING, &config, DBUS_TYPE_STRING, &setting, DBUS_TYPE_INVALID); usb_network_update(); } else reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, config); } dbus_error_free(&err); } else if(!strcmp(member, USB_MODE_NETWORK_GET)) { char *config = 0; const char *setting = 0; DBusError err = DBUS_ERROR_INIT; if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID)) { reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member); } else { setting = get_network_setting(config); if(setting) { if((reply = dbus_message_new_method_return(msg))) dbus_message_append_args (reply, DBUS_TYPE_STRING, &config, DBUS_TYPE_STRING, &setting, DBUS_TYPE_INVALID); free((void *)setting); } else reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, config); } } else if(!strcmp(member, USB_MODE_CONFIG_GET)) { const char *config = get_mode_setting(); if((reply = dbus_message_new_method_return(msg))) dbus_message_append_args (reply, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID); free((void *)config); } else if(!strcmp(member, USB_MODE_LIST)) { gchar *mode_list = get_mode_list(); if((reply = dbus_message_new_method_return(msg))) dbus_message_append_args (reply, DBUS_TYPE_STRING, (const char *) &mode_list, DBUS_TYPE_INVALID); g_free(mode_list); } else if(!strcmp(member, USB_MODE_RESCUE_OFF)) { rescue_mode = FALSE; log_debug("Rescue mode off\n "); reply = dbus_message_new_method_return(msg); } else { /*unknown methods are handled here */ reply = dbus_message_new_error(msg, DBUS_ERROR_UNKNOWN_METHOD, member); } if( !reply ) { reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, member); } } else if( type == DBUS_MESSAGE_TYPE_METHOD_CALL && !strcmp(interface, "org.freedesktop.DBus.Introspectable") && !strcmp(object, USB_MODE_OBJECT) && !strcmp(member, "Introspect")) { status = DBUS_HANDLER_RESULT_HANDLED; if((reply = dbus_message_new_method_return(msg))) dbus_message_append_args (reply, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID); } EXIT: if(reply) { if( !dbus_message_get_no_reply(msg) ) { if( !dbus_connection_send(connection, reply, 0) ) log_debug("Failed sending reply. Out Of Memory!\n"); } dbus_message_unref(reply); } return status; }