74
is_owned_by_user_and_socket (const char *path)
78
if (stat (path, &s) == -1)
81
if (s.st_uid != geteuid ())
84
if ((s.st_mode & S_IFSOCK) != S_IFSOCK)
90
static gboolean server_cb (GIOChannel *source,
91
GIOCondition condition, gpointer data);
94
setup_connection (BaconMessageConnection *conn)
96
g_return_val_if_fail (conn->chan == NULL, FALSE);
98
conn->chan = g_io_channel_unix_new (conn->fd);
102
g_io_channel_set_line_term (conn->chan, "\n", 1);
103
conn->conn_id = g_io_add_watch (conn->chan, G_IO_IN, server_cb, conn);
109
accept_new_connection (BaconMessageConnection *server_conn)
111
BaconMessageConnection *conn;
114
g_return_if_fail (server_conn->is_server);
116
conn = g_new0 (BaconMessageConnection, 1);
117
conn->is_server = FALSE;
118
conn->func = server_conn->func;
119
conn->data = server_conn->data;
121
conn->fd = accept (server_conn->fd, NULL, (guint *)&alen);
123
server_conn->accepted_connections =
124
g_slist_prepend (server_conn->accepted_connections, conn);
126
setup_connection (conn);
62
130
server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
64
132
BaconMessageConnection *conn = (BaconMessageConnection *)data;
65
char *message, *subs, buf[BUF_SIZE];
66
int cd, alen, rc, offset;
133
char *message, *subs, buf;
67
135
gboolean finished;
71
cd = accept (g_io_channel_unix_get_fd (source), NULL, &alen);
73
memset (buf, sizeof (buf), '\0');
74
rc = read (cd, buf, BUF_SIZE);
75
//FIXME test for the actual errno
138
if (conn->is_server && conn->fd == g_io_channel_unix_get_fd (source)) {
139
accept_new_connection (conn);
142
message = g_malloc (1);
144
rc = read (cd, &buf, 1);
145
while (rc > 0 && buf != '\n')
78
message = g_realloc (message, rc + offset);
79
memcpy (message + offset, buf, MIN(rc, BUF_SIZE));
147
message = g_realloc (message, rc + offset + 1);
148
message[offset] = buf;
81
149
offset = offset + rc;
82
memset (buf, sizeof (buf), '\0');
83
rc = read (cd, buf, BUF_SIZE);
150
rc = read (cd, &buf, 1);
153
g_io_channel_shutdown (conn->chan, FALSE, NULL);
154
g_io_channel_unref (conn->chan);
163
message[offset] = '\0';
89
while (subs != '\0' && finished == FALSE)
168
while (finished == FALSE && *subs != '\0')
91
if (message != NULL && conn->func != NULL)
170
if (conn->func != NULL)
92
171
(*conn->func) (subs, conn->data);
94
173
subs += strlen (subs) + 1;
184
find_file_with_pattern (const char *dir, const char *pattern)
187
char *found_filename;
188
const char *filename;
191
filedir = g_dir_open (dir, 0, NULL);
195
pat = g_pattern_spec_new (pattern);
198
g_dir_close (filedir);
202
found_filename = NULL;
204
while ((filename = g_dir_read_name (filedir)))
206
if (g_pattern_match_string (pat, filename))
208
char *tmp = g_build_filename (dir, filename, NULL);
209
if (is_owned_by_user_and_socket (tmp))
210
found_filename = g_strdup (filename);
214
if (found_filename != NULL)
218
g_pattern_spec_free (pat);
219
g_dir_close (filedir);
221
return found_filename;
225
socket_filename (const char *prefix)
227
char *pattern, *newfile, *path, *filename;
230
pattern = g_strdup_printf ("%s.%s.*", prefix, g_get_user_name ());
231
tmpdir = g_get_tmp_dir ();
232
filename = find_file_with_pattern (tmpdir, pattern);
233
if (filename == NULL)
235
newfile = g_strdup_printf ("%s.%s.%u", prefix,
236
g_get_user_name (), g_random_int ());
237
path = g_build_filename (tmpdir, newfile, NULL);
240
path = g_build_filename (tmpdir, filename, NULL);
105
249
try_server (BaconMessageConnection *conn)
107
251
struct sockaddr_un uaddr;
110
253
uaddr.sun_family = AF_UNIX;
111
254
strncpy (uaddr.sun_path, conn->path,
285
return setup_connection (conn);
150
288
BaconMessageConnection *
151
289
bacon_message_connection_new (const char *prefix)
153
291
BaconMessageConnection *conn;
154
char *filename, *path;
156
293
g_return_val_if_fail (prefix != NULL, NULL);
158
filename = g_strdup_printf (".%s.%s", prefix, g_get_user_name ());
159
path = g_build_filename (g_get_home_dir (), filename, NULL);
162
295
conn = g_new0 (BaconMessageConnection, 1);
296
conn->path = socket_filename (prefix);
165
298
if (test_is_socket (conn->path) == FALSE)
300
if (!try_server (conn))
170
302
bacon_message_connection_free (conn);
197
329
bacon_message_connection_free (BaconMessageConnection *conn)
199
333
g_return_if_fail (conn != NULL);
200
g_return_if_fail (conn->path != NULL);
202
if (conn->is_server != FALSE)
334
/* Only servers can accept other connections */
335
g_return_if_fail (conn->is_server != FALSE ||
336
conn->accepted_connections == NULL);
338
child_conn = conn->accepted_connections;
339
while (child_conn != NULL) {
340
bacon_message_connection_free (child_conn->data);
341
child_conn = g_slist_next (child_conn);
343
g_slist_free (conn->accepted_connections);
346
g_source_remove (conn->conn_id);
204
350
g_io_channel_shutdown (conn->chan, FALSE, NULL);
205
351
g_io_channel_unref (conn->chan);
354
if (conn->is_server != FALSE) {
206
355
unlink (conn->path);
357
if (conn->fd != -1) {
208
358
close (conn->fd);
231
378
const char *message)
233
380
g_return_if_fail (conn != NULL);
234
g_assert (conn->is_server == FALSE);
235
//FIXME test short writes
236
write (conn->fd, message, strlen (message) + 1);
381
g_return_if_fail (message != NULL);
383
g_io_channel_write_chars (conn->chan, message, strlen (message),
385
g_io_channel_write_chars (conn->chan, "\n", 1, NULL, NULL);
386
g_io_channel_flush (conn->chan, NULL);
240
390
bacon_message_connection_get_is_server (BaconMessageConnection *conn)
242
392
g_return_val_if_fail (conn != NULL, FALSE);
243
394
return conn->is_server;