]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge commit 'remotes/meins/v0.3' into v0.3
authorAndre Noll <maan@systemlinux.org>
Mon, 19 Nov 2007 09:08:58 +0000 (10:08 +0100)
committerAndre Noll <maan@systemlinux.org>
Mon, 19 Nov 2007 09:08:58 +0000 (10:08 +0100)
REQUIREMENTS
afs.c
afs.h
aft.c
command.c
error.h
fade.c
osl.c
stat.c
vss.c
vss.h

index ca5040a0d3c2053c2968a61319bd0ac2c3502b7a..b8a09058c18a38751ebbe3cddf8b52066bc4fc99 100644 (file)
@@ -25,7 +25,6 @@ Optional features:
          libvorbis, libvorbisfile: http://www.xiph.org/downloads/.
          The corresponding Debian packages are called libogg-dev
          libvorbis-dev, other distributors chose similar names.
-         The source of these is also available at
 
        - *aac*:
          For aac files (m4a) you'll need libfaad. Get it at
@@ -39,6 +38,7 @@ Hacking the source:
 
        - gengetopt: ftp://ftp.gnu.org/pub/gnu/gengetopt/
        - autoconf: ftp://ftp.gnu.org/pub/gnu/autoconf/
+       - git
        - grutatxt
        - help2man
        - doxygen
diff --git a/afs.c b/afs.c
index 355400874377a82cd1b5c085f6d3c729411ce540..8a60166fe7e42d5f5762cb46547a9413df6bd342 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -487,17 +487,26 @@ int open_next_audio_file(void)
        int ret, shmid;
        char buf[8];
        long score;
-
+again:
        PARA_NOTICE_LOG("getting next audio file\n");
        ret = score_get_best(&aft_row, &score);
-       if (ret < 0)
-               return ret;
-       ret = open_and_update_audio_file(aft_row, &afd, score);
-       if (ret < 0)
-               return ret;
+       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;
@@ -506,10 +515,13 @@ int open_next_audio_file(void)
        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 */
@@ -846,8 +858,10 @@ static void execute_server_command(void)
        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");
diff --git a/afs.h b/afs.h
index f15b8c559bf8b442674e42409bc0fcea8b65930a..977fc40b6591dd778294ce7a796a6edcb4746f18 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -126,6 +126,7 @@ struct audio_file_data {
 
 enum afs_server_code {
        NEXT_AUDIO_FILE,
+       NO_ADMISSIBLE_FILES,
        AFD_CHANGE
 };
 
@@ -199,8 +200,8 @@ int get_attribute_text(uint64_t *atts, const char *delim, char **text);
 /* aft */
 void aft_init(struct afs_table *t);
 int aft_get_row_of_path(const char *path, struct osl_row **row);
-int open_and_update_audio_file(struct osl_row *aft_row,
-       struct audio_file_data *afd, long score);
+int open_and_update_audio_file(struct osl_row *aft_row, long score,
+       struct audio_file_data *afd);
 int load_afd(int shmid, struct audio_file_data *afd);
 int load_afsi(struct afs_info *afsi, struct osl_object *obj);
 void save_afsi(struct afs_info *afsi, struct osl_object *obj);
diff --git a/aft.c b/aft.c
index df6c2592cd40c7bebcc0969b7292981ddf09a5d0..7af50f9de8dfe25ffe70356edd0d5ceaabd79bf4 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -622,6 +622,7 @@ int load_afd(int shmid, struct audio_file_data *afd)
  * Mmap the given audio file and update statistics.
  *
  * \param aft_row Determines the audio file to be opened and updated.
+ * \param score The score of the audio file.
  * \param afd Result pointer.
  *
  * On success, the numplayed field of the audio file selector info is increased
@@ -630,8 +631,8 @@ int load_afd(int shmid, struct audio_file_data *afd)
  *
  * \return Positive shmid on success, negative on errors.
  */
-int open_and_update_audio_file(struct osl_row *aft_row,
-       struct audio_file_data *afd, long score)
+int open_and_update_audio_file(struct osl_row *aft_row, long score,
+       struct audio_file_data *afd)
 {
        HASH_TYPE *aft_hash, file_hash[HASH_SIZE];
        struct osl_object afsi_obj;
@@ -807,9 +808,8 @@ static char *make_filename_lines(const char *path, unsigned flags)
        char *ret;
 
        if (!(flags & LS_FLAG_FULL_PATH))
-               return make_message("%s: %s\n%s:\n",
-                       status_item_list[SI_BASENAME], path,
-                       status_item_list[SI_DIRECTORY]);
+               return make_message("%s: %s\n",
+                       status_item_list[SI_BASENAME], path);
        basename = para_basename(path),
        dirname = para_dirname(path);
        ret = make_message("%s: %s\n%s: %s\n%s: %s\n",
@@ -887,82 +887,56 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts,
        lyrics_lines = make_lyrics_lines(afsi);
        image_lines = make_image_lines(afsi);
        filename_lines = make_filename_lines(d->path, opts->flags);
-       if (opts->mode == LS_MODE_VERBOSE) {
-               para_printf(b,
-                       "%s" /* filename stuff */
-                       "%s%s%s%s" /* score */
-                       "%s\n" /* attributes */
-                       "%s: %s\n" /* hash */
-                       "%s" /* image id, image name */
-                       "%s" /* lyrics */
-                       "%s: %dkbit/s\n" /* bitrate */
-                       "%s: %s\n" /* format */
-                       "%s: %dHz\n" /* frequency */
-                       "%s: %d\n" /* channels */
-                       "%s: %s\n" /* duration */
-                       "%s: %lu\n" /* seconds total */
-                       "%s: %d\n" /* num_played */
-                       "%s: %s\n" /* last_played */
-                       "%s", /* tag info */
-                       filename_lines,
-                       have_score? status_item_list[SI_SCORE] : "",
-                               have_score? ": " : "",
-                               score_buf,
-                               have_score? "\n" : "",
-                       att_lines,
-                       status_item_list[SI_HASH], asc_hash,
-                       image_lines,
-                       lyrics_lines,
-                       status_item_list[SI_BITRATE], afhi->bitrate,
-                       status_item_list[SI_FORMAT], audio_format_name(afsi->audio_format_id),
-                       status_item_list[SI_FREQUENCY], afhi->frequency,
-                       status_item_list[SI_CHANNELS], afhi->channels,
-                       status_item_list[SI_DURATION], duration_buf,
-                       status_item_list[SI_SECONDS_TOTAL], afhi->seconds_total,
-                       status_item_list[SI_NUM_PLAYED], afsi->num_played,
-                       status_item_list[SI_LAST_PLAYED], last_played_time,
-                       afhi->info_string
-               );
-       } else { /* mbox mode */ /* FIXME: merge with verbose output */
-               struct osl_object lyrics_def;
-               lyr_get_def_by_id(afsi->lyrics_id, &lyrics_def);
+       if (opts->mode == LS_MODE_MBOX)
                para_printf(b,
                        "From foo@localhost %s\n"
                        "Received: from\nTo: bar\nFrom: a\n"
-                       "Subject: %s\n\n" /* path */
-                       "%s%s%s" /* score */
-                       "%s\n" /* attributes */
-                       "hash: %s\n"
-                       "%s\n" /* image id, image name */
-                       "lyrics_id: %s\n"
-                       "bitrate: %dkbit/s\n"
-                       "format: %s\n"
-                       "frequency: %dHz\n"
-                       "channels: %d\n"
-                       "duration: %s\n"
-                       "num_played: %d\n"
-                       "%s\n" /* tag info */
-                       "%s%s\n",
+                       "Subject: %s\n\n",
                        last_played_time,
-                       d->path,
-                       have_score? "score: " : "", score_buf,
-                               have_score? "\n" : "",
-                       att_lines,
-                       asc_hash,
-                       image_lines,
-                       lyrics_lines,
-                       afhi->bitrate,
-                       audio_format_name(afsi->audio_format_id),
-                       afhi->frequency,
-                       afhi->channels,
-                       duration_buf,
-                       afsi->num_played,
-                       afhi->info_string,
-                       lyrics_def.data? "Lyrics:\n~~~~~~~\n" : "",
-                       lyrics_def.data? (char *)lyrics_def.data : ""
-               );
-               if (lyrics_def.data)
-                       osl_close_disk_object(lyrics_def.data);
+                       d->path);
+       para_printf(b,
+               "%s" /* filename stuff */
+               "%s%s%s%s" /* score */
+               "%s\n" /* attributes */
+               "%s: %s\n" /* hash */
+               "%s" /* image id, image name */
+               "%s" /* lyrics */
+               "%s: %dkbit/s\n" /* bitrate */
+               "%s: %s\n" /* format */
+               "%s: %dHz\n" /* frequency */
+               "%s: %d\n" /* channels */
+               "%s: %s\n" /* duration */
+               "%s: %lu\n" /* seconds total */
+               "%s: %s\n" /* last played time */
+               "%s: %d\n" /* num_played */
+               "%s\n", /* tag info */
+               filename_lines,
+               have_score? status_item_list[SI_SCORE] : "",
+                       have_score? ": " : "",
+                       score_buf,
+                       have_score? "\n" : "",
+               att_lines,
+               status_item_list[SI_HASH], asc_hash,
+               image_lines,
+               lyrics_lines,
+               status_item_list[SI_BITRATE], afhi->bitrate,
+               status_item_list[SI_FORMAT], audio_format_name(afsi->audio_format_id),
+               status_item_list[SI_FREQUENCY], afhi->frequency,
+               status_item_list[SI_CHANNELS], afhi->channels,
+               status_item_list[SI_DURATION], duration_buf,
+               status_item_list[SI_SECONDS_TOTAL], afhi->seconds_total,
+               status_item_list[SI_LAST_PLAYED], last_played_time,
+               status_item_list[SI_NUM_PLAYED], afsi->num_played,
+               afhi->info_string
+       );
+       if (opts->mode == LS_MODE_MBOX) {
+               struct osl_object lyrics_def;
+               lyr_get_def_by_id(afsi->lyrics_id, &lyrics_def);
+               if (lyrics_def.data) {
+                       para_printf(b, "Lyrics:\n~~~~~~~\n%s",
+                               (char *)lyrics_def.data);
+                       osl_close_disk_object(&lyrics_def);
+               }
        }
        free(att_lines);
        free(lyrics_lines);
index 8bafcc0418995c0bb8c42b92fa08d996a4f2f8e1..c1bbba9aef86d7fccc936d2230f591ce3eb734d4 100644 (file)
--- a/command.c
+++ b/command.c
@@ -463,10 +463,11 @@ int com_pause(__a_unused int fd, int argc, __a_unused char * const * argv)
        if (argc != 1)
                return -E_COMMAND_SYNTAX;
        mmd_lock();
-       if (!vss_paused())
+       if (!vss_paused() && !vss_stopped()) {
                mmd->events++;
-       mmd->new_vss_status_flags &= ~VSS_PLAYING;
-       mmd->new_vss_status_flags &= ~VSS_NEXT;
+               mmd->new_vss_status_flags &= ~VSS_PLAYING;
+               mmd->new_vss_status_flags &= ~VSS_NEXT;
+       }
        mmd_unlock();
        return 1;
 }
diff --git a/error.h b/error.h
index 3e4911bf6c07ca85e4e675b1d3acacec37b24163..f1a3e41dd7ef84b54280b54d3a759a08e4397845 100644 (file)
--- a/error.h
+++ b/error.h
@@ -84,6 +84,7 @@ extern const char **para_errlist[];
        PARA_ERROR(INPUT_TOO_LARGE, "input too large for stdin command"), \
        PARA_ERROR(AFS_SYNTAX, "afs syntax error"), \
        PARA_ERROR(AFS_SIGNAL, "afs caught deadly signal"), \
+       PARA_ERROR(AFS_SOCKET, "afs socket not writable"), \
        PARA_ERROR(AFS_PARENT_DIED, "fatal: server process terminated"), \
 
 
@@ -314,7 +315,7 @@ extern const char **para_errlist[];
        PARA_ERROR(AUDIO_FORMAT, "audio format not recognized"), \
        PARA_ERROR(CHUNK, "unable to get chunk"), \
        PARA_ERROR(SHORT_AFS_READ, "short read from afs socket"), \
-       PARA_ERROR(BAD_AFS_CODE, "received junk from afs"), \
+       PARA_ERROR(NOFD, "did not receive open fd from afs"), \
 
 
 #define CRYPT_ERRORS \
diff --git a/fade.c b/fade.c
index f269f0292fbf31be9f48673314beee6c14cb8c05..c86b938532022b4aea628cfb0299e4a6510b4d2e 100644 (file)
--- a/fade.c
+++ b/fade.c
@@ -149,7 +149,7 @@ out:
        close(mixer_fd);
 }
 
-static int client_cmd(const char *cmd,...)
+static void client_cmd(const char *cmd)
 {
        int ret, fds[3] = {0, 0, 0};
        pid_t pid;
@@ -158,7 +158,11 @@ static int client_cmd(const char *cmd,...)
        PARA_INFO_LOG("%s\n", cmdline);
        ret = para_exec_cmdline_pid(&pid, cmdline, fds);
        free(cmdline);
-       return ret;
+       if (ret < 0)
+               exit(EXIT_FAILURE);
+       do
+               ret = wait(NULL);
+       while (ret != -1 && errno != ECHILD);
 }
 
 static void change_afs_mode_and_play(char *afs_mode)
diff --git a/osl.c b/osl.c
index 7b4f91f59470089182b21b62d57a0bad5e324e54..9843a02034fc8927bdcce36be4bc6f7959d6f88d 100644 (file)
--- a/osl.c
+++ b/osl.c
@@ -1575,7 +1575,7 @@ int osl_del_row(struct osl_table *t, struct osl_row *row)
                        mark_mapped_object_invalid(t, r->num, i);
                        continue;
                }
-               if (st == OSL_NO_STORAGE)
+               if (st == OSL_NO_STORAGE && !(cd->storage_flags & OSL_DONT_FREE))
                        free(r->volatile_objects[col->volatile_num].data);
        }
        if (t->num_mapped_columns) {
@@ -2013,8 +2013,17 @@ int osl_get_nth_row(const struct osl_table *t, unsigned col_num,
 {
        struct osl_column *col;
        struct rb_node *node;
-       int ret = check_rbtree_col(t, col_num, &col);
+       unsigned num_rows;
+       int ret;
 
+       if (n == 0)
+               return -E_RB_KEY_NOT_FOUND;
+       ret = osl_get_num_rows(t, &num_rows);
+       if (ret < 0)
+               return ret;
+       if (n > num_rows)
+               return -E_RB_KEY_NOT_FOUND;
+       ret = check_rbtree_col(t, col_num, &col);
        if (ret < 0)
                return ret;
        node = rb_nth(col->rbtree.rb_node, n);
diff --git a/stat.c b/stat.c
index 59ac4235eb28da84ac2cd154a4425ca539f3b16b..89a1f49b9f823120c36e8c3f29922d45497a9225 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -5,8 +5,8 @@
  */
 
 /**
- *  \file stat.c functions used for sending/receiving the status of para_server
- *  and para_audiod
+ *  \file stat.c Functions used for sending/receiving the status of para_server
+ *  and para_audiod.
  */
 
 
 #include "string.h"
 #include "fd.h"
 
-/** the maximal number of simultaneous connections */
+/** The maximal number of simultaneous connections. */
 #define MAX_STAT_CLIENTS 50
 
 /**
- * describes a status client of para_audiod
+ * Describes a status client of para_audiod.
  *
  * There's one such structure per audiod client that sent the 'stat' command.
  *
  * keeps a list of connected status clients.
  */
 struct stat_client {
-       /** the stat client's file descriptor */
+       /** The stat client's file descriptor. */
        int fd;
-       /** bitmask of those status items the client is interested in */
+       /** Bitmask of those status items the client is interested in. */
        long unsigned item_mask;
-       /** its entry in the list of stat clients */
+       /** Its entry in the list of stat clients. */
        struct list_head node;
 };
 
@@ -57,10 +57,10 @@ static void dump_stat_client_list(void)
                PARA_INFO_LOG("stat client on fd %d\n", sc->fd);
 }
 /**
- * add a status client to the list
+ * Add a status client to the list.
  *
- * \param fd the file descriptor of the client
- * \param mask bitfield of status items for this client
+ * \param fd The file descriptor of the client.
+ * \param mask Bitfield of status items for this client.
  *
  * Only those status items having the bit set in \a mask will be
  * sent to the client.
@@ -91,10 +91,10 @@ int stat_client_add(int fd, long unsigned mask)
        return 1;
 }
 /**
- * write a message to all connected status clients
+ * Write a message to all connected status clients.
  *
- * \param msg a \p NULL terminated buffer
- * \param itemnum The number of the status item of \a msg
+ * \param msg A \p NULL terminated buffer.
+ * \param itemnum The number of the status item of \a msg.
  *
  * On write errors, remove the status client from the client list and close its
  * file descriptor.
@@ -115,12 +115,11 @@ void stat_client_write(const char *msg, int itemnum)
                        continue;
                FD_ZERO(&wfds);
                FD_SET(fd, &wfds);
-//             PARA_DEBUG_LOG("%s: p=%lx\n", __func__, (long)p);
                ret = para_select(fd + 1, NULL, &wfds, &tv);
                if (ret > 0) {
                        ret = write(fd, msg, len);
                        PARA_DEBUG_LOG("dumped %s to fd %d, ret = %d\n", msg, fd, ret);
-                       if (ret == len )
+                       if (ret == len)
                                continue;
                }
                /* write error or fd not ready for writing */
@@ -135,9 +134,9 @@ void stat_client_write(const char *msg, int itemnum)
 }
 
 /**
- * check if string is a known status item.
+ * Check if string is a known status item.
  *
- * \param item buffer containing the text to check
+ * \param item Buffer containing the text to check.
  *
  * \return If \a item is a valid status item, the number of that status item is
  * returned. Otherwise, this function returns \p -E_UNKNOWN_STAT_ITEM.
@@ -157,9 +156,9 @@ int stat_item_valid(const char *item)
 }
 
 /**
- * check if line starts with known status item.
+ * Check if line starts with known status item.
  *
- * \param line buffer containing the line
+ * \param line Buffer containing the line.
  *
  * \return If the beginning of \a line matches any paraslash status item and is
  * followed by a colon, the number of that status item is returned. Otherwise,
diff --git a/vss.c b/vss.c
index e470a737d4c9224bf06336c02f02c77ff1c8fa24..efd0c5ea8e43402fc85f801fc87f039674cf91a8 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -84,6 +84,18 @@ unsigned int vss_paused(void)
                && !(mmd->new_vss_status_flags & VSS_PLAYING);
 }
 
+/**
+ * Check if the vss is currently stopped.
+ *
+ * \return Greater than zero if paused, zero otherwise.
+ *
+ */
+unsigned int vss_stopped(void)
+{
+       return (mmd->new_vss_status_flags & VSS_NEXT)
+               && !(mmd->new_vss_status_flags & VSS_PLAYING);
+}
+
 /**
  * Initialize the virtual streaming system.
  *
@@ -333,6 +345,7 @@ static int recv_afs_msg(int *fd, uint32_t *code, uint32_t *data)
        struct iovec iov;
        int ret = 0;
 
+       *fd = -1;
        iov.iov_base = buf;
        iov.iov_len = sizeof(buf);
        msg.msg_iov = &iov;
@@ -343,6 +356,7 @@ static int recv_afs_msg(int *fd, uint32_t *code, uint32_t *data)
        ret = recvmsg(afs_socket, &msg, 0);
        if (ret < 0)
                return -ERRNO_TO_PARA_ERROR(errno);
+       afsss = AFS_SOCKET_READY;
        if (iov.iov_len != sizeof(buf))
                return -E_SHORT_AFS_READ;
        *code = *(uint32_t*)buf;
@@ -360,7 +374,7 @@ static int recv_afs_msg(int *fd, uint32_t *code, uint32_t *data)
 
 static void recv_afs_result(void)
 {
-       int ret, passed_fd = -1, shmid;
+       int ret, passed_fd, shmid;
        uint32_t afs_code = 0, afs_data = 0;
        struct stat statbuf;
        struct timeval now;
@@ -368,12 +382,13 @@ static void recv_afs_result(void)
        ret = recv_afs_msg(&passed_fd, &afs_code, &afs_data);
        if (ret < 0)
                goto err;
-       PARA_DEBUG_LOG("got the fd: %d, code: %u, shmid: %u\n",
-               passed_fd, afs_code, afs_data);
-       ret = -E_BAD_AFS_CODE;
+       PARA_DEBUG_LOG("fd: %d, code: %u, shmid: %u\n", passed_fd, afs_code,
+               afs_data);
+       ret = -E_NOFD;
        if (afs_code != NEXT_AUDIO_FILE)
                goto err;
-       afsss = AFS_SOCKET_READY;
+       if (passed_fd < 0)
+               goto err;
        shmid = afs_data;
        ret = load_afd(shmid, &mmd->afd);
        if (ret < 0)
@@ -403,6 +418,7 @@ err:
        if (passed_fd >= 0)
                close(passed_fd);
        PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+       mmd->new_vss_status_flags = VSS_NEXT;
 }
 
 void vss_post_select(fd_set *rfds, fd_set *wfds)
diff --git a/vss.h b/vss.h
index c521e0dd919a87ac4a7a9c8a1d2cb570834df943..eb3685fecb0900f01ab8bd609ffa110913fe5029 100644 (file)
--- a/vss.h
+++ b/vss.h
@@ -13,6 +13,7 @@ unsigned int vss_playing(void);
 unsigned int vss_next(void);
 unsigned int vss_repos(void);
 unsigned int vss_paused(void);
+unsigned int vss_stopped(void);
 char *vss_get_header(size_t *header_len);
 struct timeval *vss_chunk_time(void);
 const char *supported_audio_formats(void);