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

Last change on this file since 2995 was 2995, checked in by sam, 6 years ago

Port neercs to the unified libcaca 0.99.beta15 API.

  • 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        close(sock);
128        return NULL;
129    }
130    fcntl(sock, F_SETFL, O_NONBLOCK);
131
132    screen_list->socket[socktype] = sock;
133
134    if(socktype == SOCK_SERVER)
135    {
136        p = strrchr(screen_list->socket_path[socktype], '/');
137        p+=8; /* skip neercs. */
138        s = strdup(p);
139        p = strrchr(s, '.');
140        *p = '\0'; /* drop .sock */
141        p = strrchr(s, '.');
142        *p = '\0'; /* drop .srv */
143        p = strdup(s);
144        free(s);
145        return p;
146    }
147    else
148        return NULL;
149}
150
151int request_attach(struct screen_list* screen_list)
152{
153    char buf[32];
154    int bytes;
155
156    bytes = snprintf(buf, sizeof(buf)-1, "ATTACH %10d%c%10d",
157                     caca_get_canvas_width(screen_list->cv),
158                     ' ',
159                     caca_get_canvas_height(screen_list->cv));
160    buf[bytes] = '\0';
161    debug("Requesting attach: %s", buf);
162    return write(screen_list->socket[SOCK_SERVER], buf, strlen(buf)) <= 0;
163}
164
165int send_event(caca_event_t ev, struct screen_list* screen_list)
166{
167    enum caca_event_type t;
168
169    t = caca_get_event_type(&ev);
170
171    if(t & CACA_EVENT_KEY_PRESS)
172    {
173        char buf[16];
174        int bytes;
175        bytes = snprintf(buf, sizeof(buf)-1, "KEY %d", caca_get_event_key_ch(&ev));
176        buf[bytes] = '\0';
177        debug("Sending key press to server: %s", buf);
178        return write(screen_list->socket[SOCK_SERVER], buf, strlen(buf)) <= 0;
179    }
180    else if(t & CACA_EVENT_RESIZE)
181    {
182        char buf[32];
183        int bytes;
184        bytes = snprintf(buf, sizeof(buf)-1, "RESIZE %10d%c%10d",
185                         caca_get_event_resize_width(&ev),
186                         ' ',
187                         caca_get_event_resize_height(&ev));
188        buf[bytes] = '\0';
189        debug("Sending resize to server: %s", buf);
190        return write(screen_list->socket[SOCK_SERVER], buf, strlen(buf)) <= 0;
191    }
192    else if(t & CACA_EVENT_QUIT)
193        return write(screen_list->socket[SOCK_SERVER], "QUIT", strlen("QUIT")) <= 0;
194
195    return 0;
196}
197
Note: See TracBrowser for help on using the repository browser.