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

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