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