1 /*
2 	Copyright (C) 2004, 2005 Stephen Bach
3 	This file is part of the Viewglob package.
4 
5 	Viewglob is free software; you can redistribute it and/or modify
6 	it under the terms of the GNU General Public License as published by
7 	the Free Software Foundation; either version 2 of the License, or
8 	(at your option) any later version.
9 
10 	Viewglob is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 	GNU General Public License for more details.
14 
15 	You should have received a copy of the GNU General Public License
16 	along with Viewglob; if not, write to the Free Software
17 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 #include "common.h"
21 #include "child.h"
22 #include "hardened-io.h"
23 #include "conf-to-args.h"
24 
conf_to_args(int * argc,char *** argv,gchar * file)25 gboolean conf_to_args(int* argc, char*** argv, gchar* file) {
26 	g_return_val_if_fail(argc != NULL, FALSE);
27 	g_return_val_if_fail(argv != NULL, FALSE);
28 	g_return_val_if_fail(file != NULL, FALSE);
29 
30 	struct child conf_to_args;
31 
32 	GString* arg_str = NULL;
33 
34 	gchar buf[1024];
35 	gint nread;
36 
37 	gchar* home = getenv("HOME");
38 	if (!home) {
39 		g_warning("User has no home!");
40 		return FALSE;
41 	}
42 
43 	/* Call conf-to-args.sh with the configuration file as an argument. */
44 	child_init(&conf_to_args);
45 	conf_to_args.exec_name = VG_LIB_DIR "/conf-to-args.sh";
46 	args_add(&conf_to_args.args,
47 			g_strconcat(home, "/", file, NULL));
48 	if (!child_fork(&conf_to_args))
49 		return FALSE;
50 
51 	arg_str = g_string_new(NULL);
52 
53 	/* Get all the output from conf-to-args.sh into one buffer. */
54 	gboolean in_loop = TRUE;
55 	while (in_loop) {
56 		switch (hardened_read(conf_to_args.fd_in, buf, sizeof buf, &nread)) {
57 			case IOR_OK:
58 				arg_str = g_string_append_len(arg_str, buf, nread);
59 				break;
60 			case IOR_ERROR:
61 				g_warning("Error reading from configuration file: %s",
62 						g_strerror(errno));
63 				goto fail;
64 				break;
65 			case IOR_EOF:
66 				in_loop = FALSE;
67 				break;
68 		}
69 	}
70 
71 	/* It's probably already dead, but just to be sure. */
72 	(void) child_terminate(&conf_to_args);
73 
74 	if (arg_str->len == 0) {
75 		g_string_free(arg_str, TRUE);
76 		return FALSE;
77 	}
78 
79 	/* Remove a trailing newline. */
80 	if (arg_str->str[arg_str->len - 1] == '\n')
81 		arg_str = g_string_truncate(arg_str, arg_str->len - 1);
82 
83 	/* Setup the argument array. */
84 	*argv = g_strsplit(arg_str->str, " ", -1);
85 	gint i;
86 	for (i = 0; *(*argv + i) != NULL; i++)
87 		;
88 	*argc = i;
89 
90 	/*for (i = 0; i < *argc; i++)
91 		g_printerr("%s\n", *(*argv + i));*/
92 
93 	g_string_free(arg_str, TRUE);
94 	return TRUE;
95 
96 fail:
97 	// TODO free child args
98 	g_string_free(arg_str, TRUE);
99 	(void) child_terminate(&conf_to_args);
100 	return FALSE;
101 }
102 
103