2 nterfaced UNIX domain socket module
3 Copyright (C) 2003-2004 Chris Porter.
11 #include <sys/socket.h>
14 #include <sys/ioctl.h>
16 #include "../core/config.h"
17 #include "../core/events.h"
19 #include "nterfaced_uds.h"
20 #include "nterfaced.h"
23 #include "transports.h"
26 struct transport
*otu
;
27 struct esocket_events uds_events
;
28 unsigned short uds_token
;
31 otu
= register_transport("uds");
34 otu
->on_line
= uds_transport_line_event
;
35 otu
->on_disconnect
= uds_transport_disconnect_event
;
38 socket_path
= getcopyconfigitem("nterfaced", "socketpath", "/tmp/nterfaced", 100);
39 MemCheck(socket_path
);
43 nterface_log(ndl
, NL_ERROR
, "UDS: Unable to create domain socket!");
45 freesstring(socket_path
);
52 uds_events
.on_line
= uds_buffer_line_event
;
53 uds_events
.on_accept
= uds_buffer_accept_event
;
54 uds_events
.on_disconnect
= NULL
;
56 uds_token
= esocket_token();
57 esocket_add(uds
, ESOCKET_UNIX_DOMAIN
, &uds_events
, uds_token
);
59 /* UDS must not have a disconnect event */
60 uds_events
.on_disconnect
= uds_buffer_disconnect_event
;
65 esocket_clean_by_token(uds_token
);
67 if(socket_path
&& (unlink(socket_path
->content
) == -1))
68 nterface_log(ndl
, NL_WARNING
, "UDS: Unable to delete socket %s.", socket_path
->content
);
72 freesstring(socket_path
);
75 deregister_transport(otu
);
79 int create_uds(void) {
81 struct sockaddr_un sa
;
83 sock
= socket(PF_UNIX
, SOCK_STREAM
, 0);
86 nterface_log(ndl
, NL_ERROR
, "UDS: Unable to create UNIX domain socket!");
90 memset(&sa
, 0, sizeof(sa
));
91 sa
.sun_family
= AF_UNIX
;
92 strncpy(sa
.sun_path
, socket_path
->content
, sizeof(sa
.sun_path
) - 1);
93 sa
.sun_path
[sizeof(sa
.sun_path
) - 1] = '\0';
95 if((unlink(socket_path
->content
) == -1) && (errno
!= ENOENT
)) {
96 nterface_log(ndl
, NL_ERROR
, "UDS: Unable to delete already existing socket (%s)!", socket_path
->content
);
101 if(bind(sock
, (struct sockaddr
*)&sa
, sizeof(sa
))) {
102 nterface_log(ndl
, NL_ERROR
, "UDS: Unable to bind socket to %s!", socket_path
->content
);
107 if(chmod(socket_path
->content
, S_IRUSR
| S_IWUSR
| S_IROTH
| S_IWOTH
) == -1) {
108 nterface_log(ndl
, NL_ERROR
, "UDS: Unable to change permissions of socket %s!", socket_path
->content
);
110 if(unlink(socket_path
->content
) == -1)
111 nterface_log(ndl
, NL_WARNING
, "UDS: Unable to delete socket %s.", socket_path
->content
);
115 if(listen(sock
, 5)) {
116 nterface_log(ndl
, NL_ERROR
, "UDS: Unable to listen on socket!");
118 if(unlink(socket_path
->content
) == -1)
119 nterface_log(ndl
, NL_WARNING
, "UDS: Unable to delete socket %s.", socket_path
->content
);
126 void uds_buffer_accept_event(struct esocket
*active
) {
127 int newfd
= accept(active
->fd
, NULL
, 0);
128 unsigned short opt
= 1;
130 nterface_log(ndl
, NL_WARNING
, "UDS: Unable to accept new UNIX domain socket!");
134 nterface_log(ndl
, NL_INFO
|NL_LOG_ONLY
, "UDS: New connection");
135 if(ioctl(newfd
, FIONBIO
, &opt
)) {
140 if(!esocket_add(newfd
, ESOCKET_UNIX_DOMAIN_CONNECTED
, &uds_events
, uds_token
)) {
146 int uds_buffer_line_event(struct esocket
*socket
, char *newline
) {
149 nterface_log(ndl
, NL_INFO
|NL_LOG_ONLY
, "UDS: L: %s", newline
);
150 reason
= new_request(otu
, socket
->fd
, newline
, &number
);
152 if(reason
== RE_BAD_LINE
) {
155 int ret
= esocket_write_line(socket
, "%s,%d,E%d,%s", newline
, number
, reason
, request_error(reason
));
163 int uds_transport_line_event(struct request
*request
, char *buf
) {
165 es
= find_esocket_from_fd(request
->input
.tag
);
170 return esocket_write_line(es
, "%s,%d,%s", request
->service
->service
->content
, request
->input
.token
, buf
);
173 void uds_transport_disconnect_event(struct request
*req
) {
174 struct esocket
*es
= find_esocket_from_fd(req
->input
.tag
);
178 esocket_write_line(es
, "%s,%d,E%d,%s", req
->service
->service
->content
, req
->input
.token
, RE_CONNECTION_CLOSED
, request_error(RE_CONNECTION_CLOSED
));
181 void uds_buffer_disconnect_event(struct esocket
*socket
) {
182 transport_disconnect(otu
, socket
->fd
);