1.1 --- a/c++/domain-socket-bridge/domain-socket-bridge.c Sun Nov 20 18:22:56 2016 +0100
1.2 +++ b/c++/domain-socket-bridge/domain-socket-bridge.c Sun Nov 20 20:39:08 2016 +0100
1.3 @@ -3,6 +3,8 @@
1.4 #include <stdio.h>
1.5 #include <signal.h>
1.6 #include <stdlib.h>
1.7 +#include <string>
1.8 +#include <regex>
1.9
1.10 #include <event2/bufferevent.h>
1.11 #include <event2/buffer.h>
1.12 @@ -13,18 +15,23 @@
1.13 #include <sys/un.h>
1.14 #include <unistd.h>
1.15
1.16 +using namespace std;
1.17 +
1.18 static const char MESSAGE[] = "Hello, World!\n";
1.19
1.20 static const char PATH[] = "./roura";
1.21
1.22 +static const string COMMAND_EXIT("exit\n");
1.23 +
1.24 static void listener_cb(evutil_socket_t, short, void *);
1.25 static void conn_read_cb(struct bufferevent *, void *);
1.26 static void conn_write_cb(struct bufferevent *, void *);
1.27 static void conn_event_cb(struct bufferevent *, short, void *);
1.28 static void signal_cb(evutil_socket_t, short, void *);
1.29 -static void print_socket_info(int);
1.30 +static void print_socket_info(int, int);
1.31
1.32 int main(int argc, char **argv) {
1.33 + printf("%4s %8s\n", "*", "STARTED");
1.34 struct event_base *base;
1.35 evutil_socket_t listener;
1.36 struct event *listener_event;
1.37 @@ -36,7 +43,7 @@
1.38
1.39 base = event_base_new();
1.40 if (!base) {
1.41 - fprintf(stderr, "Could not initialize libevent!\n");
1.42 + printf("%4s %8s %s\n", "*", "ERROR", "unable to initialize libevent");
1.43 return 1;
1.44 }
1.45
1.46 @@ -48,22 +55,22 @@
1.47 evutil_make_socket_nonblocking(listener);
1.48
1.49 if (bind(listener, (struct sockaddr*) &sun, sizeof (sun)) < 0) {
1.50 - fprintf(stderr, "Could not create domain socket: %s!\n", PATH);
1.51 + printf("%4s %8s %s: %s\n", "*", "ERROR", "unable to create domain socket:", PATH);
1.52 return 1;
1.53 }
1.54
1.55 if (listen(listener, 16) < 0) {
1.56 - fprintf(stderr, "Could not listen\n");
1.57 + printf("%4s %8s %s\n", "*", "ERROR", "unable to listen");
1.58 return 1;
1.59 }
1.60
1.61 // identifikátor serverového soketu (v současnosti číslo FD)
1.62 - printf("Nasloucháme: sun_path = %s → socketId = %d\n", sun.sun_path, listener);
1.63 + printf("%4s %8s listening at: sun_path = %s → socketId = %d\n", "*", "SOCKET", sun.sun_path, listener);
1.64
1.65 listener_event = event_new(base, listener, EV_READ | EV_PERSIST, listener_cb, (void*) base);
1.66
1.67 if (!listener_event) {
1.68 - fprintf(stderr, "Could not do event_new\n");
1.69 + printf("%4s %8s %s\n", "*", "ERROR", "unable to do event_new()");
1.70 return 1;
1.71 }
1.72
1.73 @@ -72,7 +79,7 @@
1.74 signal_event = evsignal_new(base, SIGINT, signal_cb, (void *) base);
1.75
1.76 if (!signal_event || event_add(signal_event, NULL) < 0) {
1.77 - fprintf(stderr, "Could not create/add a signal event!\n");
1.78 + printf("%4s %8s %s\n", "*", "ERROR", "unable to create/add a signal event");
1.79 return 1;
1.80 }
1.81
1.82 @@ -86,7 +93,7 @@
1.83 // TODO: co když soket někdo přesune a místo něj dá jiný soubor?
1.84 unlink(PATH);
1.85
1.86 - printf("done\n");
1.87 + printf("%4s %8s\n", "*", "FINISHED");
1.88 return 0;
1.89 }
1.90
1.91 @@ -97,42 +104,45 @@
1.92 struct sockaddr_storage ss;
1.93 socklen_t slen = sizeof (ss);
1.94 int fd = accept(listener, (struct sockaddr*) &ss, &slen);
1.95 +
1.96 + // identifikátor navázaného spojení (v současnosti číslo FD)
1.97 + int * connectionId = (int*) malloc(sizeof (fd));
1.98 + *connectionId = fd;
1.99 +
1.100 if (fd < 0) {
1.101 - fprintf(stderr, "Unable to accept(): %d", fd);
1.102 + printf("%4d %8s %s\n", *connectionId, "ERROR", "unable to accept()");
1.103 return;
1.104 } else if (fd > FD_SETSIZE) {
1.105 // FD_SETSIZE = 1024 -- Proč? Co když bude spojení víc?
1.106 - fprintf(stderr, "fd (%d) > FD_SETSIZE (%d)", fd, FD_SETSIZE);
1.107 + printf("%4d %8s fd (%d) > FD_SETSIZE (%d)\n", *connectionId, "ERROR", fd, FD_SETSIZE);
1.108 close(fd);
1.109 return;
1.110 }
1.111
1.112 evutil_make_socket_nonblocking(fd);
1.113
1.114 - print_socket_info(fd);
1.115
1.116 bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
1.117 if (!bev) {
1.118 - fprintf(stderr, "Error constructing bufferevent!");
1.119 + printf("%4d %8s %s\n", *connectionId, "ERROR", "constructing bufferevent");
1.120 event_base_loopbreak(base);
1.121 return;
1.122 }
1.123
1.124 - // identifikátor navázaného spojení (v současnosti číslo FD)
1.125 - int * connectionId = (int*) malloc(sizeof (fd));
1.126 - *connectionId = fd;
1.127 +
1.128
1.129
1.130 bufferevent_setcb(bev, conn_read_cb, conn_write_cb, conn_event_cb, (void*) connectionId);
1.131 bufferevent_enable(bev, EV_READ | EV_WRITE);
1.132
1.133 - printf("někdo se k nám připojil! socketId = %d → connectionId = %d / bev = %p\n", listener, *connectionId, bev);
1.134 + printf("%4d %8s somebody has connected: socketId = %d → connectionId = %d\n", *connectionId, "CONN", listener, *connectionId);
1.135 + print_socket_info(*connectionId, fd);
1.136
1.137 bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
1.138 }
1.139
1.140 static void conn_read_cb(struct bufferevent *bev, void *user_data) {
1.141 - printf("conn_read_cb: connectionId = %d\n", *((int*) user_data));
1.142 + int connectionId = *((int*) user_data);
1.143
1.144 /* This callback is invoked when there is data to read on bev. */
1.145 struct evbuffer *input = bufferevent_get_input(bev);
1.146 @@ -142,11 +152,15 @@
1.147 size_t len = evbuffer_get_length(input);
1.148 char *data = (char*) malloc(len);
1.149 evbuffer_copyout(input, data, len);
1.150 - printf("we got some data: %s\n", data);
1.151
1.152 - if (memcmp(data, "exit\n", len) == 0) {
1.153 +
1.154 + string dataFormated(data);
1.155 + dataFormated = regex_replace(dataFormated, regex("\\n"), "\\n");
1.156 + printf("%4d %8s '%s'\n", connectionId, "IN", dataFormated.c_str());
1.157 +
1.158 + if (COMMAND_EXIT.compare(data) == 0) {
1.159 struct timeval delay = {2, 123};
1.160 - printf("Klient říká, že máme končit; ukončuji program během %ld sekund a %ld mikrosekund.\n", delay.tv_sec, delay.tv_usec);
1.161 + printf("%4d %8s client asks us to terminate; finishing in %ld sesonds and %ld microseconds\n", connectionId, "EXIT", delay.tv_sec, delay.tv_usec);
1.162 event_base_loopexit(base, &delay);
1.163 }
1.164
1.165 @@ -157,28 +171,36 @@
1.166 }
1.167
1.168 static void conn_write_cb(struct bufferevent *bev, void *user_data) {
1.169 - printf("conn_write_cb: connectionId = %d\n", *((int*) user_data));
1.170 + int connectionId = *((int*) user_data);
1.171
1.172 struct evbuffer *output = bufferevent_get_output(bev);
1.173 if (evbuffer_get_length(output) == 0) {
1.174 - printf("flushed answer / %p\n", bev);
1.175 + printf("%4d %8s\n", connectionId, "FLUSH");
1.176 /* nebudeme ukončovat spojení
1.177 bufferevent_free(bev);
1.178 */
1.179 + } else {
1.180 + // FIXME: sem to nikdy nepřijde
1.181 + size_t len = evbuffer_get_length(output);
1.182 + char *data = (char*) malloc(len);
1.183 + evbuffer_copyout(output, data, len);
1.184 + printf("%4d %8s '%s'\n", connectionId, "OUT", data);
1.185 + free(data);
1.186 }
1.187 }
1.188
1.189 static void conn_event_cb(struct bufferevent *bev, short events, void *user_data) {
1.190 int connectionId = *((int*) user_data);
1.191 - printf("conn_event_cb: connectionId = %d\n", connectionId);
1.192
1.193 if (events & BEV_EVENT_EOF) {
1.194 - printf("Connection closed: connectionId = %d\n", connectionId);
1.195 + printf("%4d %8s\n", connectionId, "CLOSE");
1.196 } else if (events & BEV_EVENT_ERROR) {
1.197 - printf("Got an error on the connectionId = %d: %s\n", connectionId, strerror(errno));
1.198 + printf("%4d %8s %s\n", connectionId, "ERROR", strerror(errno));
1.199 + } else {
1.200 + printf("%4d %8s\n", connectionId, "OTHER");
1.201 + // None of the other events can happen here, since we haven't enabled timeouts
1.202 }
1.203
1.204 - // None of the other events can happen here, since we haven't enabled timeouts
1.205 bufferevent_free(bev);
1.206 free(user_data);
1.207 }
1.208 @@ -187,16 +209,16 @@
1.209 struct event_base *base = (event_base *) user_data;
1.210 struct timeval delay = {2, 123};
1.211
1.212 - printf("Zachycen SIGINT (Ctrl+C); ukončuji program během %ld sekund a %ld mikrosekund.\n", delay.tv_sec, delay.tv_usec);
1.213 + printf("\n%4s %8s got SIGINT (Ctrl+C); finishing in %ld sesonds and %ld microseconds\n", "*", "SIGNAL", delay.tv_sec, delay.tv_usec);
1.214
1.215 event_base_loopexit(base, &delay);
1.216 }
1.217
1.218 -static void print_socket_info(int fd) {
1.219 +static void print_socket_info(int connectionId, int fd) {
1.220 struct ucred cr;
1.221 unsigned int cl = sizeof (cr);
1.222
1.223 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) == 0) {
1.224 - printf("připojený klient: pid=%d, uid=%d, gid=%d\n", cr.pid, cr.uid, cr.gid);
1.225 + printf("%4d %8s client identification: pid=%d, uid=%d, gid=%d\n", connectionId, "CONN", cr.pid, cr.uid, cr.gid);
1.226 }
1.227 }
1.228 \ No newline at end of file