/** * Prepare SQL queries and perform them. * * @param format printf-like string of SQL query * @param callback pointer to function to be called on results of SQL query * @param firstarg pointer to buffer for callback returned data * @return 0 (always, due to SQLite policy) */ int tagsistant_real_query( dbi_conn dbi, const char *format, int (*callback)(void *, dbi_result), char *file, int line, void *firstarg, ...) { va_list ap; va_start(ap, firstarg); /* check if connection has been created */ if (NULL == dbi) { dbg('s', LOG_ERR, "ERROR! DBI connection was not initialized!"); return(0); } #if TAGSISTANT_USE_QUERY_MUTEX /* lock the connection mutex */ g_mutex_lock(&tagsistant_query_mutex); #endif /* check if the connection is alive */ if (!dbi_conn_ping(dbi) && dbi_conn_connect(dbi) < 0) { #if TAGSISTANT_USE_QUERY_MUTEX g_mutex_unlock(&tagsistant_query_mutex); #endif dbg('s', LOG_ERR, "ERROR! DBI Connection has gone!"); return(0); } /* replace all the single or double quotes with "<><>" in the format */ gchar *escaped_format = g_regex_replace_literal(RX1, format, -1, 0, "<><>", 0, NULL); /* format the statement */ gchar *statement = g_strdup_vprintf(escaped_format, ap); if (NULL == statement) { #if TAGSISTANT_USE_QUERY_MUTEX /* lock the connection mutex */ g_mutex_unlock(&tagsistant_query_mutex); #endif dbg('s', LOG_ERR, "Null SQL statement"); g_free(escaped_format); return(0); } /* prepend a backslash to all the single quotes inside the arguments */ gchar *escaped_statement_tmp = g_regex_replace_literal(RX2, statement, -1, 0, "''", 0, NULL); /* replace "<><>" with a single quote */ gchar *escaped_statement = g_regex_replace_literal(RX3, escaped_statement_tmp, -1, 0, "'", 0, NULL); /* log and do the query */ dbg('s', LOG_INFO, "SQL from %s:%d: [%s]", file, line, escaped_statement); dbi_result result = dbi_conn_query(dbi, escaped_statement); tagsistant_dirty_logging(escaped_statement); tagsistant_wal(dbi, escaped_statement); g_free_null(escaped_format); g_free_null(escaped_statement_tmp); g_free_null(escaped_statement); /* call the callback function on results or report an error */ int rows = 0; if (result) { if (callback) { while (dbi_result_next_row(result)) { callback(firstarg, result); rows++; } } dbi_result_free(result); } else { /* get the error message */ const char *errmsg = NULL; dbi_conn_error(dbi, &errmsg); if (errmsg) dbg('s', LOG_ERR, "Error: %s.", errmsg); } #if TAGSISTANT_USE_QUERY_MUTEX g_mutex_unlock(&tagsistant_query_mutex); #endif return(rows); }
/** * Tagsistant main function, where everything starts... * * @param argc command line argument number * @param argv command line argument list * @return 0 when unmounted, a positive error number if something prevents the mount */ int main(int argc, char *argv[]) { struct fuse_args args = { 0, NULL, 0 }; int res; #ifndef MACOSX char *destfile = getenv("MALLOC_TRACE"); if (destfile != NULL && strlen(destfile)) { fprintf(stderr, "\n *** logging g_malloc() calls to %s ***\n", destfile); mtrace(); } #endif /* * set some values inside tagsistant context structure */ tagsistant.progname = argv[0]; tagsistant.debug = FALSE; /* * zero all the debug options */ int i = 0; for (; i < 128; i++) tagsistant.dbg[i] = 0; /* * parse command line options */ GError *error = NULL; GOptionContext *context = g_option_context_new ("[repository path] <mount point>"); g_option_context_add_main_entries (context, tagsistant_options, NULL); g_option_context_set_help_enabled (context, FALSE); if (!g_option_context_parse (context, &argc, &argv, &error)) { fprintf(stderr, "\n *** option parsing failed: %s\n", error->message); exit (1); } /* * print the help screen */ if (tagsistant.show_help) { tagsistant_usage(argv[0], tagsistant.verbose); if (tagsistant.verbose) { fuse_opt_add_arg(&args, argv[0]); fuse_opt_add_arg(&args, "--help"); tagsistant_fuse_main(&args, &tagsistant_oper); } exit(0); } /* * show Tagsistant and FUSE version */ if (tagsistant.show_version) { fprintf(stderr, "Tagsistant (tagfs) v.%s (codename: %s)\nBuild: %s FUSE_USE_VERSION: %d\n", PACKAGE_VERSION, TAGSISTANT_CODENAME, TAGSISTANT_BUILDNUMBER, FUSE_USE_VERSION); fuse_opt_add_arg(&args, "-V"); fuse_opt_add_arg(&args, "--version"); tagsistant_fuse_main(&args, &tagsistant_oper); exit(0); } /* * look for a mount point (and a repository too) */ if (tagsistant.remaining_opts && *tagsistant.remaining_opts) { if (tagsistant.remaining_opts[1] && *(tagsistant.remaining_opts[1])) { tagsistant.repository = *tagsistant.remaining_opts; tagsistant.mountpoint = *(tagsistant.remaining_opts + 1); // fprintf(stderr, "\n *** repository %s *** \n\n", tagsistant.repository); // fprintf(stderr, "\n *** mountpoint %s *** \n\n", tagsistant.mountpoint); } else { tagsistant.mountpoint = *tagsistant.remaining_opts; // fprintf(stderr, "\n *** mountpoint %s *** \n\n", tagsistant.mountpoint); } } else { fprintf(stderr, "\n *** No mountpoint provided *** \n"); tagsistant_usage(argv[0], 0); exit(2); } /* * default repository */ if (!tagsistant.repository) { tagsistant.repository = g_strdup_printf("%s/.tagsistant/", g_getenv("HOME")); } /* * default tag-listing suffix */ if (!tagsistant.tags_suffix) { tagsistant.tags_suffix = g_strdup(TAGSISTANT_DEFAULT_TAGS_SUFFIX); } /* * compute the triple tag detector regexp */ if (tagsistant.namespace_suffix) { tagsistant.triple_tag_regex = g_strdup_printf("\\%s$", tagsistant.namespace_suffix); } else { tagsistant.triple_tag_regex = g_strdup(TAGSISTANT_DEFAULT_TRIPLE_TAG_REGEX); } /* do some tuning on FUSE options */ // fuse_opt_add_arg(&args, "-s"); // fuse_opt_add_arg(&args, "-odirect_io"); fuse_opt_add_arg(&args, "-obig_writes"); fuse_opt_add_arg(&args, "-omax_write=32768"); fuse_opt_add_arg(&args, "-omax_read=32768"); fuse_opt_add_arg(&args, "-ofsname=tagsistant"); // fuse_opt_add_arg(&args, "-ofstype=tagsistant"); // fuse_opt_add_arg(&args, "-ouse_ino,readdir_ino"); // fuse_opt_add_arg(&args, "-oallow_other"); #ifdef MACOSX fuse_opt_add_arg(&args, "-odefer_permissions"); gchar *volname = g_strdup_printf("-ovolname=%s", tagsistant.mountpoint); fuse_opt_add_arg(&args, volname); g_free_null(volname); #else /* fuse_opt_add_arg(&args, "-odefault_permissions"); */ #endif /* * parse debugging flags */ if (tagsistant.debug_flags) { char *dbg_ptr = tagsistant.debug_flags; while (*dbg_ptr) { tagsistant.dbg[(int) *dbg_ptr] = 1; dbg_ptr++; } } /* * Will run as a single threaded application? */ if (tagsistant.singlethread) { if (!tagsistant.quiet) fprintf(stderr, " *** operating in single thread mode ***\n"); fuse_opt_add_arg(&args, "-s"); } /* * Will run readonly? */ if (tagsistant.readonly) { if (!tagsistant.quiet) fprintf(stderr, " *** mounting tagsistant read-only ***\n"); fuse_opt_add_arg(&args, "-r"); } /* * Will run in foreground? * * A little explanation is required here. Many users reported tha autotagging * does not work when Tagsistant is started without -f. FUSE -f switch just * tells FUSE to not fork in the background. This means that Tagsistant keeps * the console busy and never detaches. It's very useful for debugging but * very annoying in everyday life. However when FUSE send Tagsistant in the * background, something wrong happens with the scheduling of the autotagging * thread. On the other hand, when the -f switch is used, autotagging works * as expected. * * As a workaround, FUSE is always provided with the -f switch, while the * background is reached by Tagsistant itself with a fork() call. */ fuse_opt_add_arg(&args, "-f"); if (tagsistant.foreground) { if (!tagsistant.quiet) fprintf(stderr, " *** will run in foreground ***\n"); } /* * Will be verbose? */ if (tagsistant.verbose) { if (!tagsistant.quiet) fprintf(stderr, " *** will log verbosely ***\n"); fuse_opt_add_arg(&args, "-d"); } /* * Have received DB options? */ if (tagsistant.dboptions) { if (!tagsistant.quiet) fprintf(stderr, " *** connecting to %s\n", tagsistant.dboptions); } /* * The repository was provided? */ if (tagsistant.repository) { if (!tagsistant.quiet) fprintf(stderr, " *** saving repository in %s\n", tagsistant.repository); } /* * add FUSE options */ gchar **fuse_opt = tagsistant.fuse_opts; while (fuse_opt && *fuse_opt) { fprintf(stderr, " *** Adding FUSE options %s\n", *fuse_opt); gchar *fuse_opt_string = g_strdup_printf("-o%s", *fuse_opt); fuse_opt_add_arg(&args, fuse_opt_string); fuse_opt++; } /* * checking if mount point exists or can be created */ struct stat mst; if ((lstat(tagsistant.mountpoint, &mst) == -1) && (errno == ENOENT)) { if (mkdir(tagsistant.mountpoint, S_IRWXU|S_IRGRP|S_IXGRP) != 0) { // tagsistant_usage(tagsistant.progname); if (!tagsistant.quiet) fprintf(stderr, "\n *** Mountpoint %s does not exists and can't be created! ***\n", tagsistant.mountpoint); if (!tagsistant.show_config) exit(1); } } if (!tagsistant.quiet) fprintf(stderr, "\n" " Tagsistant (tagfs) v.%s (codename: %s)\n" " Build: %s FUSE_USE_VERSION: %d\n" " (c) 2006-2014 Tx0 <*****@*****.**>\n" " For license informations, see %s -h\n\n" , PACKAGE_VERSION, TAGSISTANT_CODENAME, TAGSISTANT_BUILDNUMBER , FUSE_USE_VERSION, tagsistant.progname ); /* checking repository */ if (!tagsistant.repository || (strcmp(tagsistant.repository, "") == 0)) { if (strlen(getenv("HOME"))) { g_free_null(tagsistant.repository); tagsistant.repository = g_strdup_printf("%s/.tagsistant", getenv("HOME")); if (!tagsistant.quiet) fprintf(stderr, " Using default repository %s\n", tagsistant.repository); } else { // tagsistant_usage(tagsistant.progname); if (!tagsistant.show_config) { if (!tagsistant.quiet) fprintf(stderr, "\n *** No repository provided with -r ***\n"); exit(2); } } } /* removing last slash */ int replength = strlen(tagsistant.repository) - 1; if (tagsistant.repository[replength] == '/') { tagsistant.repository[replength] = '\0'; } /* checking if repository path begings with ~ */ if (tagsistant.repository[0] == '~') { char *home_path = getenv("HOME"); if (home_path != NULL) { char *relative_path = g_strdup(tagsistant.repository + 1); g_free_null(tagsistant.repository); tagsistant.repository = g_strdup_printf("%s%s", home_path, relative_path); g_free_null(relative_path); dbg('b', LOG_INFO, "Repository path is %s", tagsistant.repository); } else { dbg('b', LOG_ERR, "Repository path starts with '~', but $HOME was not available!"); } } else /* checking if repository is a relative path */ if (tagsistant.repository[0] != '/') { dbg('b', LOG_ERR, "Repository path is relative [%s]", tagsistant.repository); char *cwd = getcwd(NULL, 0); if (cwd == NULL) { dbg('b', LOG_ERR, "Error getting working directory, will leave repository path as is"); } else { gchar *absolute_repository = g_strdup_printf("%s/%s", cwd, tagsistant.repository); g_free_null(tagsistant.repository); tagsistant.repository = absolute_repository; dbg('b', LOG_ERR, "Repository path is %s", tagsistant.repository); } } struct stat repstat; if (lstat(tagsistant.repository, &repstat) == -1) { if(mkdir(tagsistant.repository, 755) == -1) { if (!tagsistant.quiet) fprintf(stderr, "\n *** REPOSITORY: Can't mkdir(%s): %s ***\n", tagsistant.repository, strerror(errno)); exit(2); } } chmod(tagsistant.repository, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); /* opening (or creating) SQL tags database */ tagsistant.tags = g_strdup_printf("%s/tags.sql", tagsistant.repository); /* tags.sql is also used by getattr() as a guaranteed file when asked for stats/ files */ struct stat tags_st; if (-1 == stat(tagsistant.tags, &tags_st)) { int tags_fd = creat(tagsistant.tags, S_IRUSR|S_IWUSR); if (tags_fd) close(tags_fd); } /* checking file archive directory */ tagsistant.archive = g_strdup_printf("%s/archive/", tagsistant.repository); if (lstat(tagsistant.archive, &repstat) == -1) { if(mkdir(tagsistant.archive, 755) == -1) { if (!tagsistant.quiet) fprintf(stderr, "\n *** ARCHIVE: Can't mkdir(%s): %s ***\n", tagsistant.archive, strerror(errno)); exit(2); } } chmod(tagsistant.archive, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); dbg('b', LOG_INFO, "Debug is enabled: %s", tagsistant.debug ? "yes" : "no"); umask(0); #ifdef _DEBUG_SYSLOG tagsistant_init_syslog(); #endif #if REGISTER_CLEANUP signal(2, cleanup); /* SIGINT */ signal(11, cleanup); /* SIGSEGV */ signal(15, cleanup); /* SIGTERM */ #endif #if !(GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 32) /* * init the threading library */ g_thread_init(NULL); #endif /* * load repository.ini */ tagsistant_manage_repository_ini(); /* * loading plugins */ tagsistant_plugin_loader(); /* * fix the archive */ tagsistant_fix_archive(); dbg('b', LOG_INFO, "Mounting filesystem"); dbg('b', LOG_INFO, "Fuse options:"); int fargc = args.argc; while (fargc) { dbg('b', LOG_INFO, "%.2d: %s", fargc, args.argv[fargc]); fargc--; } /* * Send Tagsistant in the background, if applies */ if (!tagsistant.foreground) { pid_t pid = fork(); if (pid) { if (!tagsistant.quiet) fprintf(stderr, "\n *** going in the background (PID: %d) ***\n", pid); exit(0); } } /* * initialize db connection, SQL schema, * an other subsystems */ tagsistant_db_init(); tagsistant_create_schema(); tagsistant_wal_sync(); tagsistant_path_resolution_init(); tagsistant_reasoner_init(); tagsistant_utils_init(); tagsistant_deduplication_init(); /* SQLite requires tagsistant to run in single thread mode */ if (tagsistant.sql_database_driver == TAGSISTANT_DBI_SQLITE_BACKEND) { // tagsistant.singlethread = TRUE; // fuse_opt_add_arg(&args, "-s"); } /* * print configuration if requested */ if (tagsistant.show_config) tagsistant_show_config(); /* add the mount point */ fuse_opt_add_arg(&args, tagsistant.mountpoint); #if HAVE_SYS_XATTR_H if (tagsistant.enable_xattr) { tagsistant_oper.setxattr = tagsistant_setxattr; tagsistant_oper.getxattr = tagsistant_getxattr; tagsistant_oper.listxattr = tagsistant_listxattr; tagsistant_oper.removexattr = tagsistant_removexattr; } #endif /* * run FUSE main event loop */ res = tagsistant_fuse_main(&args, &tagsistant_oper); fuse_opt_free_args(&args); /* * unloading plugins */ tagsistant_plugin_unloader(); /* free memory to better perform memory leak profiling */ g_free_null(tagsistant.dboptions); g_free_null(tagsistant.repository); g_free_null(tagsistant.archive); g_free_null(tagsistant.tags); return(res); }
/** * magmad main function. * * @param argc number of arguments on command line * @param argv vector of arguments on command line * @return 0 on success, positive number on error */ int main(int argc, char **argv) { #if GLIB_MAJOR_VERSION < 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 34) /* init GLib thread and type system */ g_type_init(); #endif /* blank umask */ umask(0); #ifdef MAGMA_DEBUG_SYSLOG /* open syslog connection */ openlog(magma_environment.progname, LOG_PID, LOG_DAEMON); #endif /* init the log system */ magma_init_log(); /* allowing core dumps */ struct rlimit rlim; rlim.rlim_cur = RLIM_INFINITY; rlim.rlim_max = RLIM_INFINITY; /* read command line */ magma_parse_args(argc, argv, &magma_environment); /* setup process resources */ int resout = setrlimit(RLIMIT_CORE, &rlim); if (-1 == resout) { dbg(LOG_ERR, DEBUG_ERR, "While setting core dump size: %s", strerror(errno)); } #ifdef MAGMA_ENABLE_DUMP_TO_FILE init_dump_to_file("/tmp/magmad.dump"); #endif /* MAGMA_ENABLE_DUMP_TO_FILE */ /* print debug mask */ char *dmask = magma_print_log_mask(magma_environment.log); dbg(LOG_INFO, DEBUG_BOOT, "Enabled log channels: %s", dmask); g_free_null(dmask); dbg(LOG_INFO, DEBUG_BOOT, "PID: %d", getpid()); dbg(LOG_INFO, DEBUG_BOOT, " sizeof(ino_t) == %lu [expecting 8] [config.h says %d]", sizeof(ino_t), SIZEOF_INO_T); dbg(LOG_INFO, DEBUG_BOOT, "sizeof(size_t) == %lu [expecting 4] [config.h says %d]", sizeof(size_t), SIZEOF_SIZE_T); dbg(LOG_INFO, DEBUG_BOOT, " sizeof(dev_t) == %lu [expecting 8] [config.h says %d]", sizeof(dev_t), SIZEOF_DEV_T); dbg(LOG_INFO, DEBUG_BOOT, "sizeof(mode_t) == %lu [expecting 4] [config.h says %d]", sizeof(mode_t), SIZEOF_MODE_T); /* * if debug mask includes DEBUG_MALLOC, * memory debugging is enabled. ENV variable MALLOC_TRACE should * contain the name of stack trace file to be later analyzed with * mtrace command line utility. filename is set to failsafe value * here but can be overwritten on program start */ if (magma_environment.log[DEBUG_MALLOC]) { gchar *tracefile = g_strdup_printf("/tmp/magmad.memorytrace.%s", magma_environment.nickname); if (getenv("MALLOC_TRACE") == NULL) setenv("MALLOC_TRACE", tracefile, 1); dbg(LOG_INFO, DEBUG_BOOT, "Enabling memory trace in file %s", getenv("MALLOC_TRACE")); mtrace(); g_free_null(tracefile); } /* creates the first node representing this node */ magma_config_myself( magma_environment.nickname, magma_environment.servername, magma_environment.ipaddr, magma_environment.port, magma_environment.bandwidth, magma_environment.storage, magma_environment.hashpath); dbg(LOG_INFO, DEBUG_BOOT, "Myself created as follow:"); dbg(LOG_INFO, DEBUG_BOOT, "...ip address: %s", magma_environment.ipaddr); dbg(LOG_INFO, DEBUG_BOOT, "....node port: %d", magma_environment.port); dbg(LOG_INFO, DEBUG_BOOT, "....node name: %s", magma_environment.nickname); dbg(LOG_INFO, DEBUG_BOOT, "....fqdn name: %s", magma_environment.servername); dbg(LOG_INFO, DEBUG_BOOT, "....bandwidth: %d", magma_environment.bandwidth); dbg(LOG_INFO, DEBUG_BOOT, "......storage: %d", magma_environment.storage); /* * initialize the flare system */ magma_flare_system_init(); /* * Enable node protocol */ magma_open_node_socket(); /* * Build the network */ magma_build_network( magma_environment.bootstrap, magma_environment.bootserver, MAGMA_NODE_PORT, MAGMA_START_BALANCER); dbg(LOG_INFO, DEBUG_BOOT, "lava ring created! first node is %s", lava->first_node->node_name); /* * report on syslog about network */ magma_volcano *nodep = lava->first_node; dbg(LOG_INFO, DEBUG_BOOT, "MAGMA network is formed by %d nodes", lava->participants); do { dbg(LOG_INFO, DEBUG_BOOT, "Node %s has sector: ", nodep->node_name); dbg(LOG_INFO, DEBUG_BOOT, " [%s", nodep->start_key); dbg(LOG_INFO, DEBUG_BOOT, " %s]", nodep->stop_key); nodep = nodep->next; } while (nodep && nodep != lava->first_node); #ifdef MAGMA_ENABLE_NFS_INTERFACE magma_start_nfs_interface(); #endif /* * Enable console protocol */ magma_open_console_socket(); /* * Enable flare protocol TCP socket */ magma_open_flare_socket(); /* * Create the GLib main loop */ GMainLoop *loop = g_main_loop_new(NULL, FALSE); g_timeout_add(2000, magma_save_this_node, NULL); /* start event cycle */ g_main_loop_run(loop); g_main_loop_unref(loop); dbg(LOG_INFO, DEBUG_BOOT, "terminating. Good bye ;-)"); return(0); }
/** * magmad command line parsing code * * @param argc number of command line arguments * @param argv vector of command line arguments */ void magma_parse_args(int argc, char **argv) { memset(magma_environment.log, 0, 255); magma_environment.progname = *argv; /* saving program name */ magma_environment.port = MAGMA_PORT; /* default port */ magma_environment.servername = g_strdup(""); /* default server name */ magma_environment.nickname = g_strdup(""); /* default server nickname */ magma_environment.ipaddr = g_strdup(""); /* default server IP address */ magma_environment.hashpath = g_strdup(""); /* default server path for local storage */ magma_environment.bootserver = NULL; /* default remote boot server */ magma_environment.secretkey = NULL; magma_environment.bandwidth = MAGMA_DEFAULT_BANDWIDTH; /* Declared bandwidth */ magma_environment.storage = MAGMA_DEFAULT_STORAGE; /* Declared storage */ magma_environment.bootstrap = 0; /* If true, this node should bootstrap a new network, if false this node should join an existing one */ /* * cycling through options */ char c; while ((c = getopt(argc, argv, "blhHA?D:Tp:i:n:s:d:w:r:k:" )) != -1) { switch (c) { case 'b': if (magma_environment.bootserver) { dbg(LOG_ERR, DEBUG_BOOT, "Bootstrap and remote server can't be specified together. Exiting now."); exit(1); } magma_environment.bootstrap = 1; break; case 'h': case 'H': magma_usage(NULL); break; case 'A': memset(magma_environment.log, 1, 255); dbg(LOG_INFO, DEBUG_BOOT, "Enabling all debug statements"); break; case 'D': if (optarg) { magma_environment.logstring = g_strdup(optarg); dbg(LOG_INFO, DEBUG_BOOT, "Setting debug mask to %s", magma_environment.logstring); } break; case 'p': if (optarg) { magma_environment.port = atol(optarg); dbg(LOG_INFO, DEBUG_BOOT, "port: %d", magma_environment.port); } break; case 'i': if (optarg) { g_free_null(magma_environment.ipaddr); magma_environment.ipaddr = g_strdup(optarg); dbg(LOG_INFO, DEBUG_BOOT, "Server local IP addr: %s", magma_environment.ipaddr); } break; case 'n': if (optarg) { g_free_null(magma_environment.nickname); magma_environment.nickname = g_strndup(optarg, 255); dbg(LOG_INFO, DEBUG_BOOT, "Server Nickname: %s", magma_environment.nickname); } break; case 's': if (optarg) { g_free_null(magma_environment.servername); magma_environment.servername = g_strndup(optarg, 255); dbg(LOG_INFO, DEBUG_BOOT, "Server FQDN name: %s", magma_environment.servername); } break; case 'd': if (optarg) { g_free_null(magma_environment.hashpath); magma_environment.hashpath = g_strdup(optarg); if (magma_environment.hashpath[strlen(magma_environment.hashpath) - 1] == '/') { magma_environment.hashpath[strlen(magma_environment.hashpath) - 1] = '\0'; } dbg(LOG_INFO, DEBUG_BOOT, "Hash Dir Path: %s", magma_environment.hashpath); } break; case 'w': if (optarg) { magma_environment.bandwidth = atol(optarg); dbg(LOG_INFO, DEBUG_BOOT, "Declared Bandwidth: %dKbit/s", magma_environment.bandwidth); } break; case 'r': if (optarg) { if (magma_environment.bootstrap) { dbg(LOG_ERR, DEBUG_BOOT, "Bootstrap and remote server can't be specified together. Exiting now."); exit(1); } g_free_null(magma_environment.bootserver); char *portp = NULL; if ((portp = rindex(optarg,':')) != NULL) { *portp = '\0'; portp++; magma_environment.bootport = atoi(portp); } else { magma_environment.bootport = MAGMA_PORT; } magma_environment.bootserver = g_strdup(optarg); magma_environment.bootstrap = 0; dbg(LOG_INFO, DEBUG_BOOT, "Remote boot server: %s:%u", magma_environment.bootserver, magma_environment.bootport); } break; case 'k': if (optarg) { magma_environment.secretkey = g_strdup(optarg); dbg(LOG_INFO, DEBUG_BOOT, "Secret Key is [%s]", magma_environment.secretkey); } break; case '?': if (isprint(optopt)) { dbg(LOG_ERR, DEBUG_ERR, "Unknown option -%c", optopt); magma_usage(NULL); } else { dbg(LOG_INFO, DEBUG_BOOT, "Unknown option character \\x%x", optopt); } break; default: break; } } magma_expand_log_channels(&magma_environment); GResolver *resolver = g_resolver_get_default(); /* * try to replace default nickname with a valid one from the DNS */ if (!strlen(magma_environment.nickname)) { char *hostname = malloc(HOST_NAME_MAX); if (hostname != NULL) { if (gethostname(hostname, HOST_NAME_MAX) == 0) { g_free_null(magma_environment.nickname); magma_environment.nickname = g_strdup(hostname); } g_free_null(hostname); } } /* * try to replace default server name with a valid one from the DNS */ if (!strlen(magma_environment.servername)) { /* struct hostent *h = gethostbyname(magma_environment.nickname); if (h != NULL) { g_free_null(magma_environment.servername); magma_environment.servername = g_strdup(h->h_name); if (index(magma_environment.servername, '.') == NULL) { // server name should be a fully qualified name!!! magma_usage("Server Fully Qualified Name is not Fully Qualified!"); } } */ GList *addr = g_resolver_lookup_by_name(resolver, magma_environment.nickname, NULL, NULL); gchar *addr_string = g_list_nth_data(addr, 0); if (!addr_string) { gchar *string = g_strdup_printf( "No FQDN provided and magmad was unable to resolve one from %s", magma_environment.nickname); magma_usage(string); } else { if (!index(magma_environment.servername, '.')) { magma_usage("Server Fully Qualified Name is not Fully Qualified!"); } } } /* * Without a valid IP address the server can't start. * Try to resolve magma_environment.servername and exit * if the operation fails */ if (inet_aton(magma_environment.ipaddr, NULL) == 0) { GList *addr = g_resolver_lookup_by_name(resolver, magma_environment.servername, NULL, NULL); gchar *addr_string = g_list_nth_data(addr, 0); if (!addr_string) { gchar *string = g_strdup_printf("No IP address provided and can't resolve %s", magma_environment.servername); magma_usage(string); } else { magma_environment.ipaddr = addr_string; } } /* * if neither boot server or bootstrap has been specified, the * server should load its state from last saved lava topology */ if (!magma_environment.bootstrap && !magma_environment.bootserver) { if (!magma_environment.nickname || !strlen(magma_environment.nickname)) { magma_usage("Please specify server nickname to allow status loading from disk!"); } } else if (magma_environment.secretkey == NULL ) { magma_usage("No secret key specified! Network can't be created or joined!"); } g_object_unref(resolver); }