Example #1
0
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);
		}
	}
}
Example #2
0
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);
}