1.1 --- a/c++/domain-socket-bridge/domain-socket-bridge.c Sat Nov 19 18:27:08 2016 +0100
1.2 +++ b/c++/domain-socket-bridge/domain-socket-bridge.c Sat Nov 19 19:29:54 2016 +0100
1.3 @@ -18,19 +18,24 @@
1.4
1.5 static const char PATH[] = "./roura";
1.6
1.7 -static void listener_cb(struct evconnlistener *, evutil_socket_t, struct sockaddr *, int socklen, void *);
1.8 +static void listener_cb(evutil_socket_t, short, void *);
1.9 static void conn_read_cb(struct bufferevent *, void *);
1.10 static void conn_write_cb(struct bufferevent *, void *);
1.11 static void conn_event_cb(struct bufferevent *, short, void *);
1.12 static void signal_cb(evutil_socket_t, short, void *);
1.13
1.14 +static char rot13_char(char);
1.15 +
1.16 int main(int argc, char **argv) {
1.17 struct event_base *base;
1.18 - struct evconnlistener *listener;
1.19 + evutil_socket_t listener;
1.20 + struct event *listener_event;
1.21 struct event *signal_event;
1.22
1.23 struct sockaddr_un sun;
1.24
1.25 + setvbuf(stdout, NULL, _IONBF, 0);
1.26 +
1.27 base = event_base_new();
1.28 if (!base) {
1.29 fprintf(stderr, "Could not initialize libevent!\n");
1.30 @@ -41,16 +46,28 @@
1.31 sun.sun_family = AF_UNIX;
1.32 strcpy(sun.sun_path, PATH);
1.33
1.34 - listener = evconnlistener_new_bind(base, listener_cb, (void *) base,
1.35 - LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1,
1.36 - (struct sockaddr*) &sun,
1.37 - sizeof (sun));
1.38 + listener = socket(AF_UNIX, SOCK_STREAM, 0);
1.39 + evutil_make_socket_nonblocking(listener);
1.40
1.41 - if (!listener) {
1.42 + if (bind(listener, (struct sockaddr*) &sun, sizeof (sun)) < 0) {
1.43 fprintf(stderr, "Could not create domain socket: %s!\n", PATH);
1.44 return 1;
1.45 }
1.46
1.47 + if (listen(listener, 16) < 0) {
1.48 + fprintf(stderr, "Could not listen\n");
1.49 + return 1;
1.50 + }
1.51 +
1.52 + listener_event = event_new(base, listener, EV_READ | EV_PERSIST, listener_cb, (void*) base);
1.53 +
1.54 + if (!listener_event) {
1.55 + fprintf(stderr, "Could not do event_new\n");
1.56 + return 1;
1.57 + }
1.58 +
1.59 + event_add(listener_event, NULL);
1.60 +
1.61 signal_event = evsignal_new(base, SIGINT, signal_cb, (void *) base);
1.62
1.63 if (!signal_event || event_add(signal_event, NULL) < 0) {
1.64 @@ -60,7 +77,7 @@
1.65
1.66 event_base_dispatch(base);
1.67
1.68 - evconnlistener_free(listener);
1.69 + event_free(listener_event);
1.70 event_free(signal_event);
1.71 event_base_free(base);
1.72
1.73 @@ -71,12 +88,24 @@
1.74 return 0;
1.75 }
1.76
1.77 -static void listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data) {
1.78 +static void listener_cb(evutil_socket_t listener, short event, void *user_data) {
1.79 struct event_base *base = (event_base *) user_data;
1.80 struct bufferevent *bev;
1.81
1.82 - //bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); // zavírá spojení
1.83 - bev = bufferevent_socket_new(base, fd, 0); // nezavírá spojení
1.84 + struct sockaddr_storage ss;
1.85 + socklen_t slen = sizeof (ss);
1.86 + int fd = accept(listener, (struct sockaddr*) &ss, &slen);
1.87 + if (fd < 0) {
1.88 + fprintf(stderr, "Unable to accept(): %d", fd);
1.89 + return;
1.90 + } else if (fd > FD_SETSIZE) {
1.91 + close(fd);
1.92 + return;
1.93 + }
1.94 +
1.95 + evutil_make_socket_nonblocking(fd);
1.96 +
1.97 + bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
1.98 if (!bev) {
1.99 fprintf(stderr, "Error constructing bufferevent!");
1.100 event_base_loopbreak(base);
1.101 @@ -99,26 +128,57 @@
1.102
1.103 size_t len = evbuffer_get_length(input);
1.104 char *data;
1.105 + /*
1.106 data = (char*) malloc(len);
1.107 evbuffer_copyout(input, data, len);
1.108 + */
1.109
1.110 - printf("we got some data: %s / %d\n", data, memcmp(data, "exit", len));
1.111 + size_t n;
1.112 + int i;
1.113 + while ((data = evbuffer_readln(input, &n, EVBUFFER_EOL_LF))) {
1.114 + for (i = 0; i < n; ++i)
1.115 + data[i] = rot13_char(data[i]);
1.116 + evbuffer_add(output, data, n);
1.117 + evbuffer_add(output, "\n", 1);
1.118 + free(data);
1.119 + }
1.120
1.121 + printf("we got some data...\n");
1.122 +
1.123 + /*
1.124 if (memcmp(data, "exit\n", len) == 0) {
1.125 struct timeval delay = {2, 123};
1.126 event_base_loopexit(base, &delay);
1.127 }
1.128 + */
1.129 +
1.130 + if (evbuffer_get_length(input) >= MAX_LINE) {
1.131 + /* Too long; just process what there is and go on so that the buffer
1.132 + * doesn't grow infinitely long. */
1.133 + char buf[1024];
1.134 + while (evbuffer_get_length(input)) {
1.135 + int n = evbuffer_remove(input, buf, sizeof (buf));
1.136 + for (i = 0; i < n; ++i)
1.137 + buf[i] = rot13_char(buf[i]);
1.138 + evbuffer_add(output, buf, n);
1.139 + }
1.140 + evbuffer_add(output, "\n", 1);
1.141 + }
1.142
1.143 /* Copy all the data from the input buffer to the output buffer. */
1.144 + /*
1.145 evbuffer_add_buffer(output, input);
1.146 free(data);
1.147 + */
1.148 }
1.149
1.150 static void conn_write_cb(struct bufferevent *bev, void *user_data) {
1.151 struct evbuffer *output = bufferevent_get_output(bev);
1.152 if (evbuffer_get_length(output) == 0) {
1.153 printf("flushed answer / %p\n", bev);
1.154 + /* nebudeme ukončovat spojení
1.155 bufferevent_free(bev);
1.156 + */
1.157 }
1.158 }
1.159
1.160 @@ -141,3 +201,14 @@
1.161
1.162 event_base_loopexit(base, &delay);
1.163 }
1.164 +
1.165 +static char rot13_char(char c) {
1.166 + /* We don't want to use isalpha here; setting the locale would change
1.167 + * which characters are considered alphabetical. */
1.168 + if ((c >= 'a' && c <= 'm') || (c >= 'A' && c <= 'M'))
1.169 + return c + 13;
1.170 + else if ((c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z'))
1.171 + return c - 13;
1.172 + else
1.173 + return c;
1.174 +}