Mercurial > ~mikael > mcabber > hg
comparison mcabber/mcabber/fifo.c @ 1668:41c26b7d2890
Install mcabber headers
* Change mcabber headers naming scheme
* Move 'src/' -> 'mcabber/'
* Add missing include <mcabber/config.h>'s
* Create and install clean config.h version in 'include/'
* Move "dirty" config.h version to 'mcabber/'
* Add $(top_srcdir) to compiler include path
* Update modules HOWTO
author | Myhailo Danylenko <isbear@ukrpost.net> |
---|---|
date | Mon, 18 Jan 2010 15:36:19 +0200 |
parents | mcabber/src/fifo.c@fca9a4c17432 |
children | e6d355e50d7a |
comparison
equal
deleted
inserted
replaced
1667:8af0e0ad20ad | 1668:41c26b7d2890 |
---|---|
1 /* | |
2 * fifo.c -- Read commands from a named pipe | |
3 * | |
4 * Copyright (C) 2008,2009 Mikael Berthe <mikael@lilotux.net> | |
5 * Copyrigth (C) 2009 Myhailo Danylenko <isbear@ukrpost.net> | |
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 2 of the License, or (at | |
10 * your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | |
20 * USA | |
21 */ | |
22 | |
23 #include <stdlib.h> | |
24 #include <glib.h> | |
25 #include <sys/types.h> | |
26 #include <sys/stat.h> | |
27 #include <fcntl.h> | |
28 #include <unistd.h> | |
29 #include <errno.h> | |
30 #include <fcntl.h> | |
31 | |
32 #include "commands.h" | |
33 #include "logprint.h" | |
34 #include "utils.h" | |
35 #include "settings.h" | |
36 #include "main.h" | |
37 | |
38 static char *fifo_name = NULL; | |
39 static GIOChannel *fifo_channel = NULL; | |
40 | |
41 static const char *FIFO_ENV_NAME = "MCABBER_FIFO"; | |
42 | |
43 static gboolean attach_fifo(const char *name); | |
44 | |
45 static guint fifo_callback(GIOChannel *channel, | |
46 GIOCondition condition, | |
47 gpointer data) | |
48 { | |
49 if (condition & (G_IO_IN|G_IO_PRI)) { | |
50 GIOStatus chstat; | |
51 gchar *buf; | |
52 gsize endpos; | |
53 | |
54 chstat = g_io_channel_read_line(channel, &buf, NULL, &endpos, NULL); | |
55 if (chstat == G_IO_STATUS_ERROR || chstat == G_IO_STATUS_EOF) { | |
56 if (!attach_fifo(fifo_name)) | |
57 scr_LogPrint(LPRINT_LOGNORM, | |
58 "Reopening fifo failed! Fifo will not work from now!"); | |
59 return FALSE; | |
60 } | |
61 if (buf) { | |
62 guint logflag; | |
63 guint fifo_ignore = settings_opt_get_int("fifo_ignore"); | |
64 | |
65 if (endpos) | |
66 buf[endpos] = '\0'; | |
67 | |
68 if (settings_opt_get_int("fifo_hide_commands")) | |
69 logflag = LPRINT_LOG; | |
70 else | |
71 logflag = LPRINT_LOGNORM; | |
72 scr_LogPrint(logflag, "%s FIFO command: %s", | |
73 (fifo_ignore ? "Ignoring" : "Executing"), buf); | |
74 if (!fifo_ignore) { | |
75 if (process_command(buf, TRUE) == 255) | |
76 mcabber_set_terminate_ui(); | |
77 } | |
78 | |
79 g_free(buf); | |
80 } | |
81 } else if (condition & (G_IO_ERR|G_IO_NVAL|G_IO_HUP)) { | |
82 if (!attach_fifo(fifo_name)) | |
83 scr_LogPrint(LPRINT_LOGNORM, | |
84 "Reopening fifo failed! Fifo will not work from now!"); | |
85 return FALSE; | |
86 } | |
87 return TRUE; | |
88 } | |
89 | |
90 static void fifo_destroy_callback(gpointer data) | |
91 { | |
92 GIOChannel *channel = (GIOChannel *)data; | |
93 g_io_channel_unref(channel); | |
94 } | |
95 | |
96 static gboolean check_fifo(const char *name) | |
97 { | |
98 struct stat finfo; | |
99 if (stat(name, &finfo) == -1) { | |
100 /* some unknown error */ | |
101 if (errno != ENOENT) | |
102 return FALSE; | |
103 /* fifo not yet exists */ | |
104 if (mkfifo(name, S_IRUSR|S_IWUSR) != -1) | |
105 return check_fifo(name); | |
106 else | |
107 return FALSE; | |
108 } | |
109 | |
110 /* file exists */ | |
111 if (S_ISFIFO(finfo.st_mode)) | |
112 return TRUE; | |
113 else | |
114 return FALSE; | |
115 } | |
116 | |
117 static gboolean attach_fifo(const char *name) | |
118 { | |
119 GSource *source; | |
120 int fd = open (name, O_RDONLY|O_NONBLOCK); | |
121 if (fd == -1) | |
122 return FALSE; | |
123 | |
124 fifo_channel = g_io_channel_unix_new(fd); | |
125 | |
126 g_io_channel_set_flags(fifo_channel, G_IO_FLAG_NONBLOCK, NULL); | |
127 g_io_channel_set_encoding(fifo_channel, NULL, NULL); | |
128 g_io_channel_set_close_on_unref(fifo_channel, TRUE); | |
129 | |
130 source = g_io_create_watch(fifo_channel, | |
131 G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL); | |
132 g_source_set_callback(source, (GSourceFunc)fifo_callback, | |
133 (gpointer)fifo_channel, | |
134 (GDestroyNotify)fifo_destroy_callback); | |
135 g_source_attach(source, main_context); | |
136 | |
137 return TRUE; | |
138 } | |
139 | |
140 int fifo_init(const char *fifo_path) | |
141 { | |
142 if (fifo_path) { | |
143 fifo_name = expand_filename(fifo_path); | |
144 | |
145 if (!check_fifo(fifo_name)) { | |
146 scr_LogPrint(LPRINT_LOGNORM, "WARNING: Cannot create the FIFO. " | |
147 "%s already exists and is not a pipe", fifo_name); | |
148 g_free(fifo_name); | |
149 return -1; | |
150 } | |
151 } else if (fifo_name) | |
152 g_source_remove_by_user_data(fifo_channel); | |
153 else | |
154 return -1; | |
155 | |
156 if (!attach_fifo(fifo_name)) { | |
157 scr_LogPrint(LPRINT_LOGNORM, "Error: Cannot open fifo"); | |
158 return -1; | |
159 } | |
160 | |
161 setenv(FIFO_ENV_NAME, fifo_name, 1); | |
162 | |
163 scr_LogPrint(LPRINT_LOGNORM, "FIFO initialized (%s)", fifo_path); | |
164 return 1; | |
165 } | |
166 | |
167 void fifo_deinit(void) | |
168 { | |
169 unsetenv(FIFO_ENV_NAME); | |
170 | |
171 /* destroy open fifo */ | |
172 unlink(fifo_name); | |
173 g_source_remove_by_user_data(fifo_channel); | |
174 /* channel itself should be destroyed by destruction callback */ | |
175 g_free(fifo_name); | |
176 } | |
177 | |
178 /* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */ |