void openInterface(Interface * interface, int fd) { int flags; assert(interface->open==0); interface->bufferLength = 0; interface->bufferPos = 0; interface->fd = fd; /* fcntl(interface->fd,F_SETOWN,(int)getpid()); */ while((flags = fcntl(fd,F_GETFL))<0 && errno==EINTR); flags|=O_NONBLOCK; while(fcntl(interface->fd,F_SETFL,flags)<0 && errno==EINTR); while((interface->fp = fdopen(fd,"rw"))==NULL && errno==EINTR); interface->open = 1; interface->lastTime = time(NULL); interface->commandList = NULL; interface->bufferList = NULL; interface->expired = 0; interface->outputBufferSize = 0; interface->outBuflen = 0; interface->permission = getDefaultPermissions(); interface->outBufSize = INTERFACE_DEFAULT_OUT_BUFFER_SIZE; #ifdef SO_SNDBUF { int getSize; int sockOptLen = sizeof(int); if(getsockopt(interface->fd,SOL_SOCKET,SO_SNDBUF, (char *)&getSize,&sockOptLen) < 0) { DEBUG("problem getting sockets send buffer size\n"); } else if(getSize<=0) { DEBUG("sockets send buffer size is not positive\n"); } else interface->outBufSize = getSize; } #endif interface->outBuffer = malloc(interface->outBufSize); myfprintf(interface->fp, "%s %s\n", GREETING, VERSION); printInterfaceOutBuffer(interface); }
static void client_init(struct client *client, int fd) { static unsigned int next_client_num; assert(fd >= 0); client->cmd_list_size = 0; client->cmd_list_OK = -1; #ifndef G_OS_WIN32 client->channel = g_io_channel_unix_new(fd); #else client->channel = g_io_channel_win32_new_socket(fd); #endif /* GLib is responsible for closing the file descriptor */ g_io_channel_set_close_on_unref(client->channel, true); /* NULL encoding means the stream is binary safe; the MPD protocol is UTF-8 only, but we are doing this call anyway to prevent GLib from messing around with the stream */ g_io_channel_set_encoding(client->channel, NULL, NULL); /* we prefer to do buffering */ g_io_channel_set_buffered(client->channel, false); client->source_id = g_io_add_watch(client->channel, G_IO_IN|G_IO_ERR|G_IO_HUP, client_in_event, client); client->input = fifo_buffer_new(4096); client->lastTime = time(NULL); client->cmd_list = NULL; client->deferred_send = g_queue_new(); client->deferred_bytes = 0; client->num = next_client_num++; client->send_buf_used = 0; client->permission = getDefaultPermissions(); (void)write(fd, GREETING, sizeof(GREETING) - 1); }
void client_new(struct player_control *player_control, int fd, const struct sockaddr *sa, size_t sa_length, int uid) { static unsigned int next_client_num; struct client *client; char *remote; assert(player_control != NULL); assert(fd >= 0); #ifdef HAVE_LIBWRAP if (sa->sa_family != AF_UNIX) { char *hostaddr = sockaddr_to_string(sa, sa_length, NULL); const char *progname = g_get_prgname(); struct request_info req; request_init(&req, RQ_FILE, fd, RQ_DAEMON, progname, 0); fromhost(&req); if (!hosts_access(&req)) { /* tcp wrappers says no */ g_log(G_LOG_DOMAIN, LOG_LEVEL_SECURE, "libwrap refused connection (libwrap=%s) from %s", progname, hostaddr); g_free(hostaddr); close_socket(fd); return; } g_free(hostaddr); } #endif /* HAVE_WRAP */ if (client_list_is_full()) { g_warning("Max Connections Reached!"); close_socket(fd); return; } client = g_new0(struct client, 1); client->player_control = player_control; client->channel = g_io_channel_new_socket(fd); /* GLib is responsible for closing the file descriptor */ g_io_channel_set_close_on_unref(client->channel, true); /* NULL encoding means the stream is binary safe; the MPD protocol is UTF-8 only, but we are doing this call anyway to prevent GLib from messing around with the stream */ g_io_channel_set_encoding(client->channel, NULL, NULL); /* we prefer to do buffering */ g_io_channel_set_buffered(client->channel, false); client->source_id = g_io_add_watch(client->channel, G_IO_IN|G_IO_ERR|G_IO_HUP, client_in_event, client); client->input = fifo_buffer_new(4096); client->permission = getDefaultPermissions(); client->uid = uid; client->last_activity = g_timer_new(); client->cmd_list = NULL; client->cmd_list_OK = -1; client->cmd_list_size = 0; client->deferred_send = g_queue_new(); client->deferred_bytes = 0; client->num = next_client_num++; client->send_buf_used = 0; client->subscriptions = NULL; client->messages = NULL; client->num_messages = 0; (void)send(fd, GREETING, sizeof(GREETING) - 1, 0); client_list_add(client); remote = sockaddr_to_string(sa, sa_length, NULL); g_log(G_LOG_DOMAIN, LOG_LEVEL_SECURE, "[%u] opened from %s", client->num, remote); g_free(remote); }