1 /*
2 	ctrlproxy: A modular IRC proxy
3 	admin: module for remote administration.
4 
5 	(c) 2003-2007 Jelmer Vernooij <jelmer@nl.linux.org>
6 
7 	This program is free software; you can redistribute it and/or modify
8 	it under the terms of the GNU General Public License as published by
9 	the Free Software Foundation; either version 3 of the License, or
10 	(at your option) any later version.
11 
12 	This program is distributed in the hope that it will be useful,
13 	but WITHOUT ANY WARRANTY; without even the implied warranty of
14 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 	GNU General Public License for more details.
16 
17 	You should have received a copy of the GNU General Public License
18 	along with this program; if not, write to the Free Software
19 	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 
22 #include "internals.h"
23 #include <sys/un.h>
24 #ifdef HAVE_READLINE
25 #include <readline/readline.h>
26 #endif
27 
admin_socket_prompt(const char * config_dir)28 gboolean admin_socket_prompt(const char *config_dir)
29 {
30 	char *admin_dir = g_build_filename(config_dir, "admin", NULL);
31 	int sock = socket(PF_UNIX, SOCK_STREAM, 0);
32 	GIOChannel *ch;
33 	struct sockaddr_un un;
34 	GIOStatus status;
35 	GError *error = NULL;
36 
37 	un.sun_family = AF_UNIX;
38 	strncpy(un.sun_path, admin_dir, sizeof(un.sun_path));
39 
40 	if (connect(sock, (struct sockaddr *)&un, sizeof(un)) < 0) {
41 		fprintf(stderr, "unable to connect to %s: %s\n", un.sun_path, strerror(errno));
42 		g_free(admin_dir);
43 		return FALSE;
44 	}
45 
46 	ch = g_io_channel_unix_new(sock);
47 
48 	g_io_channel_set_flags(ch, G_IO_FLAG_NONBLOCK, NULL);
49 
50 	while (1) {
51 		char *data = readline("ctrlproxy> ");
52 		char *raw;
53 
54 		if (data == NULL)
55 			break;
56 
57 		status = g_io_channel_write_chars(ch, data, -1, NULL, &error);
58 		if (status != G_IO_STATUS_NORMAL) {
59 			fprintf(stderr, "Error writing to admin socket: %s\n", error->message);
60 			return FALSE;
61 		}
62 
63 		status = g_io_channel_write_chars(ch, "\n", -1, NULL, &error);
64 		if (status != G_IO_STATUS_NORMAL) {
65 			fprintf(stderr, "Error writing to admin socket: %s\n", error->message);
66 			return FALSE;
67 		}
68 
69 		g_io_channel_flush(ch, &error);
70 
71 		g_free(data);
72 
73 		g_usleep(G_USEC_PER_SEC / 10);
74 
75 		while (g_io_channel_read_line(ch, &raw, NULL, NULL, &error) == G_IO_STATUS_NORMAL)
76 		{
77 			printf("%s", raw);
78 			g_free(raw);
79 		}
80 	}
81 	g_free(admin_dir);
82 
83 	return TRUE;
84 }
85 
main(int argc,char ** argv)86 int main(int argc, char **argv)
87 {
88 	char *config_dir = NULL;
89 	GError *error = NULL;
90 	GOptionContext *pc;
91 	GOptionEntry options[] = {
92 		{"config-dir", 'c', 0, G_OPTION_ARG_STRING, &config_dir, ("Override configuration directory"), ("DIR")},
93 		{ NULL }
94 	};
95 
96 	pc = g_option_context_new("");
97 	g_option_context_add_main_entries(pc, options, NULL);
98 	if (!g_option_context_parse(pc, &argc, &argv, &error)) {
99 		fprintf(stderr, "%s\n", error->message);
100 		return 1;
101 	}
102 
103 	if (config_dir == NULL)
104 		config_dir = g_build_filename(g_get_home_dir(), ".ctrlproxy", NULL);
105 
106 	g_option_context_free(pc);
107 
108 	if (admin_socket_prompt(config_dir))
109 		return 0;
110 
111 	return 1;
112 }
113