void get_options (int *argc, char ***argv) { gboolean verbose = FALSE; GError *error = NULL; GOptionContext* context = NULL; GOptionEntry opts[] = { {"logfile", 'l', 0, G_OPTION_ARG_FILENAME, &logfile, "Redirect logs to <file>", "<file>"}, {"pidfile", 'P', 0, G_OPTION_ARG_FILENAME, &pidfile, "Save xmms2d pid in <file>", "<file>"}, {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Make xmms2-launcher verbose", NULL}, {NULL} }; int i, j; /* get options */ context = g_option_context_new ("[--] [XMMSD_OPTION] ... - XMMS2 launcher"); g_option_context_set_ignore_unknown_options (context, TRUE); g_option_context_add_main_entries (context, opts, NULL); if (!g_option_context_parse (context, argc, argv, &error)) { g_critical ("%s", error->message); g_clear_error (&error); } g_option_context_free (context); /* process verbose */ if (!verbose) { g_log_set_handler (NULL, G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, empty_log_handler, NULL); } /* Remove first "--" from argv */ for (i = 0; i < *argc; i++) { if (strcmp ((*argv)[i], "--") == 0) { (*argc)--; for (j = i; j < *argc; j++) { (*argv)[j] = (*argv)[j+1]; } break; } } /* Prepare logfile */ if (!logfile) { char cache[XMMS_PATH_MAX]; xmms_usercachedir_get (cache, XMMS_PATH_MAX); logfile = g_build_filename (cache, "xmms2d.log", NULL); if (!g_file_test (cache, G_FILE_TEST_IS_DIR)) { g_mkdir_with_parents (cache, 0755); } } }
configuration_t * configuration_init (const gchar *filename) { configuration_t *config; gchar *history_file; GKeyFile *keyfile; config = g_new0 (configuration_t, 1); /* init hash */ config->values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* init aliases */ config->aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); keyfile = configuration_load (filename); section_to_hash (keyfile, "main", config->values); section_to_hash (keyfile, "alias", config->aliases); g_key_file_free (keyfile); /* load history */ history_file = configuration_get_string (config, "HISTORY_FILE"); if (!*history_file) { gchar cfile[XMMS_PATH_MAX], *key, *value; xmms_usercachedir_get (cfile, XMMS_PATH_MAX); key = g_strdup ("HISTORY_FILE"); value = g_build_filename (cfile, "nyxmms2_history", NULL); g_hash_table_replace (config->values, key, value); } return config; }
int main (int argc, char **argv) { pid_t pid; int i, fd, max_fd; int pipefd[2]; const gchar *logfile = NULL; const gchar *pidfile = NULL; GError *error = NULL; GOptionContext* context = NULL; GOptionEntry opts[] = { {"logfile", 'l', 0, G_OPTION_ARG_FILENAME, &logfile, "Redirect logs to <file>", "<file>"}, {"pidfile", 'P', 0, G_OPTION_ARG_FILENAME, &pidfile, "Save xmms2d pid in <file>", "<file>"}, {NULL} }; context = g_option_context_new ("- XMMS2 launcher"); g_option_context_set_ignore_unknown_options (context, TRUE); g_option_context_add_main_entries (context, opts, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_print ("xmms2-launcher: %s\n", error->message); g_clear_error (&error); } g_option_context_free (context); if (pipe (&pipefd[0]) == -1) { perror ("pipe"); exit (1); } if (!logfile) { char cache[PATH_MAX]; xmms_usercachedir_get (cache, PATH_MAX); logfile = g_build_filename (cache, "xmms2d.log", NULL); if (!g_file_test (cache, G_FILE_TEST_IS_DIR)) { g_mkdir_with_parents (cache, 0755); } } g_print ("Log output will be stored in %s\n", logfile); pid = fork (); if (pid) { char t; int res; close (pipefd[1]); for (;;) { res = read (pipefd[0], &t, 1); if (res != -1 || errno == EINTR) break; } if (res == -1) perror ("read"); if (res == 0) { printf ("startup failed!\n"); exit (1); } printf("xmms2 started\n"); exit(0); } /* Change stdin/out/err */ fd = open ("/dev/null", O_RDONLY); dup2 (fd, STDIN_FILENO); fd = open (logfile, O_WRONLY|O_CREAT|O_APPEND, 0644); write(fd, startup_msg, sizeof (startup_msg) - 1); dup2 (fd, STDOUT_FILENO); dup2 (fd, STDERR_FILENO); /* Close all unused file descriptors */ max_fd = sysconf (_SC_OPEN_MAX); for (i = 3; i <= max_fd; i++) { if (pipefd[1] != i) close (i); } /* make us process group leader */ setsid (); /* fork again to reparent to init */ pid = fork(); if (pid && pidfile) { FILE *pfile = NULL; pfile = g_fopen (pidfile, "w"); if (pfile) { g_fprintf (pfile, "%d", (int) pid); } } if (!pid) { char *args[32]; char buf[32]; int i; args[0] = BINDIR "/xmms2d"; snprintf (buf, 32, "--status-fd=%d", pipefd[1]); args[1] = buf; for (i = 1; i < argc && i < 30; i++) { args[i + 1] = argv[i]; } args[i + 1] = NULL; execvp (args[0], args); exit (1); } exit (0); }