source: neercs/trunk/src/attach.c @ 2611

Last change on this file since 2611 was 2611, checked in by Pascal Terjan, 13 years ago
  • Fix copy/paste errors
  • Property svn:eol-style set to native
File size: 6.3 KB
Line 
1#include <errno.h>
2#include <fcntl.h>
3#include <glob.h>
4#include <limits.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <unistd.h>
8
9#include <sys/socket.h>
10#include <sys/un.h>
11#include <sys/types.h>
12#include <sys/stat.h>
13
14#include <caca.h>
15
16#include "config.h"
17#include "neercs.h"
18
19char * build_socket_path(char *socket_dir, char *session_name, int client)
20{
21    char *path, *dir;
22    path = (char *)malloc(PATH_MAX+1);
23    dir = socket_dir;
24    if(!dir)
25        dir = getenv("NEERCSDIR");
26    if(!dir)
27        dir = getenv("TMPDIR");
28    if(!dir)
29        dir = "/tmp";
30    if(path)
31        snprintf(path, PATH_MAX+1, "%s/neercs.%s%s.sock", dir, session_name, client?"":".srv");
32    return path;
33}
34
35int create_client_socket(struct screen_list* screen_list)
36{
37    int sock;
38    struct sockaddr_un myaddr;
39
40    sock = socket(AF_UNIX, SOCK_DGRAM, 0);
41
42    if(sock < 0)
43    {
44        perror("create_client_socket:socket");
45        return errno;
46    }
47
48    memset(&myaddr, 0, sizeof(struct sockaddr_un));
49
50    myaddr.sun_family = AF_UNIX;
51    strncpy(myaddr.sun_path, screen_list->c_socket_path, sizeof(myaddr.sun_path) - 1);
52
53    unlink(screen_list->c_socket_path);
54
55    if(bind(sock, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_un)) < 0)
56    {
57        free(screen_list->c_socket_path);
58        screen_list->c_socket_path = NULL;
59        close(sock);
60        perror("create_client_socket:bind");
61        return errno;
62    }
63    fcntl(sock, F_SETFL, O_NONBLOCK);
64
65    debug("Client listening on %s (%d)", screen_list->c_socket_path, sock);
66
67    screen_list->c_socket = sock;
68
69    return 0;
70}
71
72int create_server_socket(struct screen_list* screen_list)
73{
74    int sock;
75    struct sockaddr_un myaddr;
76
77    sock = socket(AF_UNIX, SOCK_DGRAM, 0);
78
79    if(sock < 0)
80    {
81        perror("create_server_socket:socket");
82        return errno;
83    }
84
85    memset(&myaddr, 0, sizeof(struct sockaddr_un));
86
87    myaddr.sun_family = AF_UNIX;
88    strncpy(myaddr.sun_path, screen_list->s_socket_path, sizeof(myaddr.sun_path) - 1);
89
90    unlink(screen_list->s_socket_path);
91
92    if(bind(sock, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_un)) < 0)
93    {
94        free(screen_list->s_socket_path);
95        screen_list->s_socket_path = NULL;
96        close(sock);
97        perror("create_socket:bind");
98        return errno;
99    }
100    fcntl(sock, F_SETFL, O_NONBLOCK);
101
102    debug("Server listening on %s (%d)", screen_list->s_socket_path, sock);
103
104    screen_list->s_socket = sock;
105
106    return 0;
107}
108
109char ** list_sockets(char *socket_dir, char *session_name)
110{
111    char *pattern, *dir;
112    glob_t globbuf;
113
114    globbuf.gl_pathv = NULL;
115
116    pattern = (char *)malloc(PATH_MAX+1);
117
118    dir = socket_dir;
119    if(!dir)
120        dir = getenv("NEERCSDIR");
121    if(!dir)
122        dir = getenv("TMPDIR");
123    if(!dir)
124        dir = "/tmp";
125
126    if(!pattern)
127        return globbuf.gl_pathv;
128
129    if(session_name && strlen(session_name)+strlen(dir)+13<PATH_MAX)
130        sprintf(pattern, "%s/neercs.%s.srv.sock", dir, session_name);
131    else
132        snprintf(pattern, PATH_MAX, "%s/neercs.*.srv.sock", dir);
133    pattern[PATH_MAX] = '\0';
134
135    debug("Looking for sockets in the form %s", pattern);
136
137    glob(pattern, 0, NULL, &globbuf);
138
139    free(pattern);
140
141    return globbuf.gl_pathv;
142}
143
144char * connect_server(struct screen_list* screen_list)
145{
146    int sock;
147    struct sockaddr_un addr;
148    char *p, *s;
149
150    debug("Connecting to %s", screen_list->s_socket_path);
151
152    /* Open the socket */
153    if ((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
154        perror("connect_server:socket");
155        return NULL;
156    }
157
158    memset(&addr,0,sizeof(addr));
159    addr.sun_family = AF_UNIX;
160    strcpy(addr.sun_path,screen_list->s_socket_path);
161    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
162    {
163        fprintf(stderr, "Failed to connect to %s: %s\n", screen_list->s_socket_path, strerror(errno));
164        return NULL;
165    }
166    fcntl(sock, F_SETFL, O_NONBLOCK);
167
168    screen_list->s_socket = sock;
169
170    p = strrchr(screen_list->s_socket_path, '/');
171    p+=8; /* skip neercs. */
172    s = strdup(p);
173    p = strrchr(s, '.');
174    *p = '\0'; /* drop .sock */
175    p = strrchr(s, '.');
176    *p = '\0'; /* drop .srv */
177    p = strdup(s);
178    free(s);
179    return p;
180}
181
182int connect_client(struct screen_list* screen_list)
183{
184    int sock;
185    struct sockaddr_un addr;
186
187    debug("Connecting to %s", screen_list->c_socket_path);
188
189    /* Open the socket */
190    if ((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
191        perror("connect_client:socket");
192        return 1;
193    }
194
195    memset(&addr,0,sizeof(addr));
196    addr.sun_family = AF_UNIX;
197    strcpy(addr.sun_path,screen_list->c_socket_path);
198    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
199    {
200        fprintf(stderr, "Failed to connect to %s: %s\n", screen_list->c_socket_path, strerror(errno));
201        return 1;
202    }
203    fcntl(sock, F_SETFL, O_NONBLOCK);
204
205    screen_list->c_socket = sock;
206
207    return 0;
208}
209
210int request_attach(struct screen_list* screen_list)
211{
212    char buf[32];
213    int bytes;
214
215    bytes = snprintf(buf, sizeof(buf)-1, "ATTACH %10d%c%10d",
216                     cucul_get_canvas_width(screen_list->cv),
217                     ' ',
218                     cucul_get_canvas_height(screen_list->cv));
219    buf[bytes] = '\0';
220    debug("Requesting attach: %s", buf);
221    return write(screen_list->s_socket, buf, strlen(buf)) <= 0;
222}
223
224int send_event(caca_event_t ev, struct screen_list* screen_list)
225{
226    enum caca_event_type t;
227
228    t = caca_get_event_type(&ev);
229
230    if(t & CACA_EVENT_KEY_PRESS)
231    {
232        char buf[16];
233        int bytes;
234        bytes = snprintf(buf, sizeof(buf)-1, "KEY %d", caca_get_event_key_ch(&ev));
235        buf[bytes] = '\0';
236        debug("Sending key press to server: %s", buf);
237        return write(screen_list->s_socket, buf, strlen(buf)) <= 0;
238    }
239    else if(t & CACA_EVENT_RESIZE)
240    {
241        char buf[32];
242        int bytes;
243        bytes = snprintf(buf, sizeof(buf)-1, "RESIZE %10d%c%10d",
244                         caca_get_event_resize_width(&ev),
245                         ' ',
246                         caca_get_event_resize_height(&ev));
247        buf[bytes] = '\0';
248        debug("Sending resize to server: %s", buf);
249        return write(screen_list->s_socket, buf, strlen(buf)) <= 0;
250    }
251    else if(t & CACA_EVENT_QUIT)
252        return write(screen_list->s_socket, "QUIT", strlen("QUIT")) <= 0;
253
254    return 0;
255}
256
Note: See TracBrowser for help on using the repository browser.