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