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

Last change on this file since 2614 was 2614, checked in by Pascal Terjan, 12 years ago
  • Factorize some code in attach.c
  • Property svn:eol-style set to native
File size: 5.0 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, enum socket_type socktype)
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, socktype?"":".srv");
32    return path;
33}
34
35int create_socket(struct screen_list* screen_list, enum socket_type socktype)
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_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->socket_path[socktype], sizeof(myaddr.sun_path) - 1);
52
53    unlink(screen_list->socket_path[socktype]);
54
55    if(bind(sock, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_un)) < 0)
56    {
57        free(screen_list->socket_path[socktype]);
58        screen_list->socket_path[socktype] = NULL;
59        close(sock);
60        perror("create_socket:bind");
61        return errno;
62    }
63    fcntl(sock, F_SETFL, O_NONBLOCK);
64
65    debug("Listening on %s (%d)", screen_list->socket_path[socktype], sock);
66
67    screen_list->socket[socktype] = sock;
68
69    return 0;
70}
71
72char ** list_sockets(char *socket_dir, char *session_name)
73{
74    char *pattern, *dir;
75    glob_t globbuf;
76
77    globbuf.gl_pathv = NULL;
78
79    pattern = (char *)malloc(PATH_MAX+1);
80
81    dir = socket_dir;
82    if(!dir)
83        dir = getenv("NEERCSDIR");
84    if(!dir)
85        dir = getenv("TMPDIR");
86    if(!dir)
87        dir = "/tmp";
88
89    if(!pattern)
90        return globbuf.gl_pathv;
91
92    if(session_name && strlen(session_name)+strlen(dir)+13<PATH_MAX)
93        sprintf(pattern, "%s/neercs.%s.srv.sock", dir, session_name);
94    else
95        snprintf(pattern, PATH_MAX, "%s/neercs.*.srv.sock", dir);
96    pattern[PATH_MAX] = '\0';
97
98    debug("Looking for sockets in the form %s", pattern);
99
100    glob(pattern, 0, NULL, &globbuf);
101
102    free(pattern);
103
104    return globbuf.gl_pathv;
105}
106
107char * connect_socket(struct screen_list* screen_list, enum socket_type socktype)
108{
109    int sock;
110    struct sockaddr_un addr;
111    char *p, *s;
112
113    debug("Connecting to %s", screen_list->socket_path[socktype]);
114
115    /* Open the socket */
116    if ((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
117        perror("connect_server:socket");
118        return NULL;
119    }
120
121    memset(&addr,0,sizeof(addr));
122    addr.sun_family = AF_UNIX;
123    strcpy(addr.sun_path,screen_list->socket_path[socktype]);
124    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
125    {
126        fprintf(stderr, "Failed to connect to %s: %s\n", screen_list->socket_path[socktype], strerror(errno));
127        return NULL;
128    }
129    fcntl(sock, F_SETFL, O_NONBLOCK);
130
131    screen_list->socket[socktype] = sock;
132
133    if(socktype == SOCK_SERVER)
134    {
135        p = strrchr(screen_list->socket_path[socktype], '/');
136        p+=8; /* skip neercs. */
137        s = strdup(p);
138        p = strrchr(s, '.');
139        *p = '\0'; /* drop .sock */
140        p = strrchr(s, '.');
141        *p = '\0'; /* drop .srv */
142        p = strdup(s);
143        free(s);
144        return p;
145    }
146    else
147        return NULL;
148}
149
150int request_attach(struct screen_list* screen_list)
151{
152    char buf[32];
153    int bytes;
154
155    bytes = snprintf(buf, sizeof(buf)-1, "ATTACH %10d%c%10d",
156                     cucul_get_canvas_width(screen_list->cv),
157                     ' ',
158                     cucul_get_canvas_height(screen_list->cv));
159    buf[bytes] = '\0';
160    debug("Requesting attach: %s", buf);
161    return write(screen_list->socket[SOCK_SERVER], buf, strlen(buf)) <= 0;
162}
163
164int send_event(caca_event_t ev, struct screen_list* screen_list)
165{
166    enum caca_event_type t;
167
168    t = caca_get_event_type(&ev);
169
170    if(t & CACA_EVENT_KEY_PRESS)
171    {
172        char buf[16];
173        int bytes;
174        bytes = snprintf(buf, sizeof(buf)-1, "KEY %d", caca_get_event_key_ch(&ev));
175        buf[bytes] = '\0';
176        debug("Sending key press to server: %s", buf);
177        return write(screen_list->socket[SOCK_SERVER], buf, strlen(buf)) <= 0;
178    }
179    else if(t & CACA_EVENT_RESIZE)
180    {
181        char buf[32];
182        int bytes;
183        bytes = snprintf(buf, sizeof(buf)-1, "RESIZE %10d%c%10d",
184                         caca_get_event_resize_width(&ev),
185                         ' ',
186                         caca_get_event_resize_height(&ev));
187        buf[bytes] = '\0';
188        debug("Sending resize to server: %s", buf);
189        return write(screen_list->socket[SOCK_SERVER], buf, strlen(buf)) <= 0;
190    }
191    else if(t & CACA_EVENT_QUIT)
192        return write(screen_list->socket[SOCK_SERVER], "QUIT", strlen("QUIT")) <= 0;
193
194    return 0;
195}
196
Note: See TracBrowser for help on using the repository browser.