struct audio_file_data afd;
int ret, shmid;
char buf[8];
-
+ long score;
+again:
PARA_NOTICE_LOG("getting next audio file\n");
- ret = score_get_best(&aft_row, &afd.score);
- if (ret < 0)
- return ret;
- ret = open_and_update_audio_file(aft_row, &afd);
- if (ret < 0)
- return ret;
+ ret = score_get_best(&aft_row, &score);
+ if (ret < 0) {
+ PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ goto no_admissible_files;
+ }
+ ret = open_and_update_audio_file(aft_row, score, &afd);
+ if (ret < 0) {
+ PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ ret = score_delete(aft_row);
+ if (ret < 0) {
+ PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ goto no_admissible_files;
+ }
+ goto again;
+ }
shmid = ret;
if (!write_ok(server_socket)) {
- PARA_EMERG_LOG("afs_socket not writable\n");
+ ret = -E_AFS_SOCKET;
goto destroy;
}
*(uint32_t *)buf = NEXT_AUDIO_FILE;
close(afd.fd);
if (ret >= 0)
return ret;
- PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
destroy:
shm_destroy(shmid);
return ret;
+no_admissible_files:
+ *(uint32_t *)buf = NO_ADMISSIBLE_FILES;
+ *(uint32_t *)(buf + 4) = (uint32_t)0;
+ return send_bin_buffer(server_socket, buf, 8);
}
/* Never fails if arg == NULL */
ret = change_current_mood(arg + 2);
mode = PLAY_MODE_MOOD;
} else
- ret = -E_AFS_SYNTAX;
+ return -E_AFS_SYNTAX;
if (ret < 0)
return ret;
}
if (arg) {
current_mop = para_strdup(arg);
mmd_lock();
- strcpy(mmd->afs_mode_string, arg); /* FIXME: check length */
+ strncpy(mmd->afs_mode_string, arg,
+ sizeof(mmd->afs_mode_string));
+ mmd->afs_mode_string[sizeof(mmd->afs_mode_string) - 1] = '\0';
mmd_unlock();
} else {
mmd_lock();
static int setup_command_socket_or_die(void)
{
- int ret;
+ int ret, socket_fd;
char *socket_name = conf.afs_socket_arg;
struct sockaddr_un unix_addr;
PARA_EMERG_LOG("%s: %s\n", PARA_STRERROR(-ret), socket_name);
exit(EXIT_FAILURE);
}
- if (listen(ret , 5) < 0) {
- PARA_EMERG_LOG("%s", "can not listen on socket\n");
+ socket_fd = ret;
+ if (listen(socket_fd , 5) < 0) {
+ PARA_EMERG_LOG("can not listen on socket\n");
exit(EXIT_FAILURE);
}
- PARA_INFO_LOG("listening on command socket %s (fd %d)\n", socket_name,
- ret);
- return ret;
+ ret = mark_fd_nonblocking(socket_fd);
+ if (ret < 0) {
+ close(socket_fd);
+ return ret;
+ }
+ PARA_INFO_LOG("listening on socket %s (fd %d)\n", socket_name, ret);
+ return socket_fd;
}
static void close_afs_tables(void)
static struct list_head afs_client_list;
+/** Describes on connected afs client. */
struct afs_client {
+ /** Position in the afs client list. */
struct list_head node;
+ /** The socket file descriptor for this client. */
int fd;
+ /** The time the client connected. */
struct timeval connect_time;
};
PARA_DEBUG_LOG("received: %s\n", buf);
if (!strcmp(buf, "new")) {
ret = open_next_audio_file();
- if (ret < 0)
- PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ if (ret < 0) {
+ PARA_EMERG_LOG("%s\n", PARA_STRERROR(-ret));
+ unregister_tasks();
+ }
return;
}
PARA_ERROR_LOG("unknown command\n");
struct command_task *ct = t->private_data;
struct sockaddr_un unix_addr;
struct afs_client *client, *tmp;
-
+ int fd;
if (FD_ISSET(server_socket, &s->rfds))
execute_server_command();
PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret));
goto out;
}
+ fd = t->ret;
+ t->ret = mark_fd_nonblocking(fd);
+ if (t->ret < 0) {
+ PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret));
+ close(fd);
+ goto out;
+ }
client = para_malloc(sizeof(*client));
- client->fd = t->ret;
+ client->fd = fd;
client->connect_time = *now;
para_list_add(&client->node, &afs_client_list);
out:
exit(EXIT_FAILURE);
}
server_socket = socket_fd;
- ret = mark_fd_nonblock(server_socket);
+ ret = mark_fd_nonblocking(server_socket);
if (ret < 0)
exit(EXIT_FAILURE);
PARA_INFO_LOG("server_socket: %d, afs_socket_cookie: %u\n",
register_tasks(cookie);
s.default_timeout.tv_sec = 0;
s.default_timeout.tv_usec = 999 * 1000;
- ret = sched(&s);
+ ret = schedule(&s);
if (ret < 0)
PARA_EMERG_LOG("%s\n", PARA_STRERROR(-ret));
close_afs_tables();