00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <sys/types.h>
00020 #include <sys/socket.h>
00021 #include <unistd.h>
00022 #include <sys/un.h>
00023 #include <errno.h>
00024 #include <string.h>
00025 #include <fcntl.h>
00026 #include <unistd.h>
00027 #include <stdlib.h>
00028 #include <signal.h>
00029 #include <syslog.h>
00030
00031 #include "xmmsc/xmmsc_ipc_transport.h"
00032 #include "xmmsc/xmmsc_util.h"
00033 #include "url.h"
00034
00035 void
00036 xmms_ipc_usocket_destroy (xmms_ipc_transport_t *ipct)
00037 {
00038 free (ipct->path);
00039 close (ipct->fd);
00040 }
00041
00042 int
00043 xmms_ipc_usocket_read (xmms_ipc_transport_t *ipct, char *buffer, int len)
00044 {
00045 int fd;
00046 int ret;
00047 x_return_val_if_fail (ipct, -1);
00048 x_return_val_if_fail (buffer, -1);
00049
00050 fd = ipct->fd;
00051
00052 ret = recv (fd, buffer, len, 0);
00053
00054 return ret;
00055 }
00056
00057 int
00058 xmms_ipc_usocket_write (xmms_ipc_transport_t *ipct, char *buffer, int len)
00059 {
00060 int fd;
00061 x_return_val_if_fail (ipct, -1);
00062 x_return_val_if_fail (buffer, -1);
00063
00064 fd = ipct->fd;
00065
00066 return send (fd, buffer, len, 0);
00067
00068 }
00069
00070 xmms_ipc_transport_t *
00071 xmms_ipc_usocket_client_init (const xmms_url_t *url)
00072 {
00073 int fd;
00074 int flags;
00075 xmms_ipc_transport_t *ipct;
00076 struct sockaddr_un saddr;
00077
00078
00079 fd = socket (AF_UNIX, SOCK_STREAM, 0);
00080 if (fd == -1) {
00081 return NULL;
00082 }
00083
00084 saddr.sun_family = AF_UNIX;
00085 snprintf (saddr.sun_path, 108, "/%s", url->path);
00086
00087 if (connect (fd, (struct sockaddr *) &saddr, sizeof (saddr)) == -1) {
00088 close (fd);
00089 return NULL;
00090 }
00091
00092 flags = fcntl (fd, F_GETFL, 0);
00093
00094 if (flags == -1) {
00095 close (fd);
00096 return NULL;
00097 }
00098
00099 flags |= O_NONBLOCK;
00100
00101 flags = fcntl (fd, F_SETFL, flags);
00102 if (flags == -1) {
00103 close (fd);
00104 return NULL;
00105 }
00106
00107 ipct = x_new0 (xmms_ipc_transport_t, 1);
00108 ipct->fd = fd;
00109 ipct->path = strdup (url->path);
00110 ipct->read_func = xmms_ipc_usocket_read;
00111 ipct->write_func = xmms_ipc_usocket_write;
00112 ipct->destroy_func = xmms_ipc_usocket_destroy;
00113
00114 return ipct;
00115 }
00116
00117 xmms_ipc_transport_t *
00118 xmms_ipc_usocket_accept (xmms_ipc_transport_t *transport)
00119 {
00120 int fd;
00121 struct sockaddr_un sin;
00122 socklen_t sin_len;
00123
00124 x_return_val_if_fail (transport, NULL);
00125
00126 sin_len = sizeof (sin);
00127
00128 fd = accept (transport->fd, (struct sockaddr *)&sin, &sin_len);
00129 if (fd >= 0) {
00130 int flags;
00131 xmms_ipc_transport_t *ret;
00132
00133 flags = fcntl (fd, F_GETFL, 0);
00134
00135 if (flags == -1) {
00136 close (fd);
00137 return NULL;
00138 }
00139
00140 flags |= O_NONBLOCK;
00141
00142 flags = fcntl (fd, F_SETFL, flags);
00143 if (flags == -1) {
00144 close (fd);
00145 return NULL;
00146 }
00147
00148
00149 ret = x_new0 (xmms_ipc_transport_t, 1);
00150 ret->fd = fd;
00151 ret->read_func = xmms_ipc_usocket_read;
00152 ret->write_func = xmms_ipc_usocket_write;
00153 ret->destroy_func = xmms_ipc_usocket_destroy;
00154
00155 return ret;
00156 }
00157
00158 return NULL;
00159 }
00160
00161 xmms_ipc_transport_t *
00162 xmms_ipc_usocket_server_init (const xmms_url_t *url)
00163 {
00164 int fd;
00165 int flags;
00166 xmms_ipc_transport_t *ipct;
00167 struct sockaddr_un saddr;
00168
00169
00170 fd = socket (AF_UNIX, SOCK_STREAM, 0);
00171 if (fd == -1) {
00172 return NULL;
00173 }
00174
00175 saddr.sun_family = AF_UNIX;
00176 snprintf (saddr.sun_path, 108, "/%s", url->path);
00177
00178 if (access (saddr.sun_path, F_OK) == 0) {
00179 if (connect (fd, (struct sockaddr *) &saddr, sizeof (saddr)) != -1) {
00180
00181 close (fd);
00182 return NULL;
00183 }
00184
00185 unlink (saddr.sun_path);
00186 }
00187
00188 if (bind (fd, (struct sockaddr *) &saddr, sizeof (saddr)) == -1) {
00189 close (fd);
00190 return NULL;
00191 }
00192
00193 listen (fd, 5);
00194
00195 flags = fcntl (fd, F_GETFL, 0);
00196
00197 if (flags == -1) {
00198 close (fd);
00199 return NULL;
00200 }
00201
00202 flags |= O_NONBLOCK;
00203
00204 flags = fcntl (fd, F_SETFL, flags);
00205 if (flags == -1) {
00206 close (fd);
00207 return NULL;
00208 }
00209
00210 ipct = x_new0 (xmms_ipc_transport_t, 1);
00211 ipct->fd = fd;
00212 ipct->path = strdup (url->path);
00213 ipct->read_func = xmms_ipc_usocket_read;
00214 ipct->write_func = xmms_ipc_usocket_write;
00215 ipct->accept_func = xmms_ipc_usocket_accept;
00216 ipct->destroy_func = xmms_ipc_usocket_destroy;
00217
00218 return ipct;
00219 }
00220