]> git.tue.mpg.de Git - paraslash.git/commitdiff
Obtain afs status items directly from afs.
authorAndre Noll <maan@systemlinux.org>
Mon, 29 Jun 2009 17:34:24 +0000 (19:34 +0200)
committerAndre Noll <maan@systemlinux.org>
Mon, 29 Jun 2009 17:34:24 +0000 (19:34 +0200)
This patch changes the way how the afs status items are passed from afs to the stat
command handler. Previously, afs passed the status item string to the server process
whenever a new audio file was loaded. The server process stored the string in the mmd
shared memory area from which it was available to the client process that executed the
stat command.

This approach has the disadvantage that  the size of the string must be restricted to a
fixed number of bytes,  VERBOSE_LS_OUTPUT_SIZE, determined at compile time and
independent of the audio file.  As version 2 id3 tags and vorbis comments do not impose
an upper bound on the size of the tags a rather ugly patch was merged recently to the master
branch which truncated the size of the tags if it exceeded VERBOSE_LS_OUTPUT_SIZE.

This patch gets rid of this restriction by not storing the info string in the mmd structure. Instead,
the stat command requests the information directly from the afs process via the callback
mechanism which is also used by other afs commands.

afs.h
aft.c
command.c
vss.c

diff --git a/afs.h b/afs.h
index a58518bb4e455b2bc909bbf77f77b00408cb7a19..269927f4ec1980bb9ffcab66a1e9af301476920b 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -117,15 +117,10 @@ struct ls_data {
        HASH_TYPE *hash;
 };
 
-void make_empty_status_items(char *buf);
-
-/** At most that many bytes will be passed from afs to para_server. */
-#define VERBOSE_LS_OUTPUT_SIZE 4096
+int send_afs_status(int fd);
 
 /** Data about the current audio file, passed from afs to server. */
 struct audio_file_data {
-       /** Same info as ls -lv -p current audio_file. */
-       char verbose_ls_output[VERBOSE_LS_OUTPUT_SIZE];
        /** The open file descriptor to the current audio file. */
        int fd;
        /** Vss needs this for streaming. */
diff --git a/aft.c b/aft.c
index 23b36a88e51e3469f3b4fd00770a5d4e1881872e..7027e7f95d45104c559cd5720ebd377fc2d047a8 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -24,6 +24,7 @@
 #include "portable_io.h"
 
 static struct osl_table *audio_file_table;
+static char *current_status_items;
 
 /** The different sorting methods of the ls command. */
 enum ls_sorting_method {
@@ -962,72 +963,6 @@ out:
        return ret;
 }
 
-/**
- * Write a list of audio-file related status items with empty values.
- *
- * \param buf Result pointer.
- *
- * This is used by vss when currently no audio file is open.
- */
-void make_empty_status_items(char *buf)
-{
-       sprintf(buf,
-               "%s: \n" /* path */
-               "%s: \n" /* dirname */
-               "%s: \n" /* basename */
-               "%s: \n" /* score */
-               "%s: \n" /* attributes bitmap */
-               "%s: \n" /* attributes txt */
-               "%s: \n" /* hash */
-               "%s: \n" /* image id */
-               "%s: \n" /* image name */
-               "%s: \n" /* lyrics id */
-               "%s: \n" /* lyrics name */
-               "%s: \n" /* bitrate */
-               "%s: \n" /* format */
-               "%s: \n" /* frequency */
-               "%s: \n" /* channels */
-               "%s: \n" /* duration */
-               "%s: \n" /* seconds total */
-               "%s: \n" /* num played */
-               "%s: \n" /* last played */
-               "%s: \n" /* techinfo */
-               "%s: \n" /* artist */
-               "%s: \n" /* title */
-               "%s: \n" /* year */
-               "%s: \n" /* album */
-               "%s: \n" /* comment */
-               "%s: \n" /* amplification */
-               ,
-               status_item_list[SI_PATH],
-               status_item_list[SI_DIRECTORY],
-               status_item_list[SI_BASENAME],
-               status_item_list[SI_SCORE],
-               status_item_list[SI_ATTRIBUTES_BITMAP],
-               status_item_list[SI_ATTRIBUTES_TXT],
-               status_item_list[SI_HASH],
-               status_item_list[SI_IMAGE_ID],
-               status_item_list[SI_IMAGE_NAME],
-               status_item_list[SI_LYRICS_ID],
-               status_item_list[SI_LYRICS_NAME],
-               status_item_list[SI_BITRATE],
-               status_item_list[SI_FORMAT],
-               status_item_list[SI_FREQUENCY],
-               status_item_list[SI_CHANNELS],
-               status_item_list[SI_DURATION],
-               status_item_list[SI_SECONDS_TOTAL],
-               status_item_list[SI_NUM_PLAYED],
-               status_item_list[SI_LAST_PLAYED],
-               status_item_list[SI_TECHINFO],
-               status_item_list[SI_ARTIST],
-               status_item_list[SI_TITLE],
-               status_item_list[SI_YEAR],
-               status_item_list[SI_ALBUM],
-               status_item_list[SI_COMMENT],
-               status_item_list[SI_AMPLIFICATION]
-       );
-}
-
 static int make_status_items(struct audio_file_data *afd,
                struct afs_info *afsi, char *path, long score,
                HASH_TYPE *hash)
@@ -1043,19 +978,17 @@ static int make_status_items(struct audio_file_data *afd,
                .flags = LS_FLAG_FULL_PATH | LS_FLAG_ADMISSIBLE_ONLY,
                .mode = LS_MODE_VERBOSE,
        };
-       struct para_buffer pb = {.max_size = VERBOSE_LS_OUTPUT_SIZE - 1};
+       struct para_buffer pb = {.max_size = SHMMAX - 1};
        time_t current_time;
        int ret;
 
        time(&current_time);
        ret = print_list_item(&d, &opts, &pb, current_time);
        if (ret < 0)
-               goto out;
-       strncpy(afd->verbose_ls_output, pb.buf, VERBOSE_LS_OUTPUT_SIZE);
-       afd->verbose_ls_output[VERBOSE_LS_OUTPUT_SIZE - 1] = '\0';
-out:
-       free(pb.buf);
-       return ret;
+               return ret;
+       free(current_status_items);
+       current_status_items = pb.buf;
+       return 1;
 }
 
 /**
@@ -2444,6 +2377,18 @@ int com_cpsi(int fd, int argc,  char * const * const argv)
        return ret;
 }
 
+void afs_stat_callback(int fd, __a_unused const struct osl_object *query)
+{
+       if (current_status_items)
+               pass_buffer_as_shm(current_status_items,
+                       strlen(current_status_items), &fd);
+}
+
+int send_afs_status(int fd)
+{
+       return send_callback_request(afs_stat_callback, NULL, send_result, &fd);
+}
+
 /* TODO: optionally fix problems by removing offending rows */
 static int check_audio_file(struct osl_row *row, void *data)
 {
@@ -2522,6 +2467,8 @@ static void aft_close(void)
 {
        osl_close_table(audio_file_table, OSL_MARK_CLEAN);
        audio_file_table = NULL;
+       free(current_status_items);
+       current_status_items = NULL;
 }
 
 /**
index 603715b4442006650317d0320d3475eadb6bf760..e6a16e53e5f3367cd9b10bf959ace284d8086ebd 100644 (file)
--- a/command.c
+++ b/command.c
@@ -128,8 +128,7 @@ static char *get_status(struct misc_meta_data *nmmd)
                "%s: %li\n" /* offset */
                "%s: %s\n" /* afs mode */
                "%s: %lu.%lu\n" /* stream start */
-               "%s: %lu.%lu\n" /* current server time */
-               "%s", /* afs status info */
+               "%s: %lu.%lu\n", /* current server time */
                status_item_list[SI_FILE_SIZE], nmmd->size / 1024,
                status_item_list[SI_MTIME], mtime,
                status_item_list[SI_STATUS], status,
@@ -143,10 +142,7 @@ static char *get_status(struct misc_meta_data *nmmd)
                        (long unsigned)nmmd->stream_start.tv_usec,
                status_item_list[SI_CURRENT_TIME],
                        (long unsigned)current_time.tv_sec,
-                       (long unsigned)current_time.tv_usec,
-
-               nmmd->afd.verbose_ls_output
-
+                       (long unsigned)current_time.tv_usec
        );
        free(flags);
        free(status);
@@ -305,6 +301,70 @@ int com_version(int fd, int argc, __a_unused char * const * argv)
        );
 }
 
+/**
+ * Write a list of audio-file related status items with empty values.
+ *
+ * This is used by vss when currently no audio file is open.
+ */
+static char *empty_status_items(void)
+{
+       return make_message(
+               "%s: \n" /* path */
+               "%s: \n" /* dirname */
+               "%s: \n" /* basename */
+               "%s: \n" /* score */
+               "%s: \n" /* attributes bitmap */
+               "%s: \n" /* attributes txt */
+               "%s: \n" /* hash */
+               "%s: \n" /* image id */
+               "%s: \n" /* image name */
+               "%s: \n" /* lyrics id */
+               "%s: \n" /* lyrics name */
+               "%s: \n" /* bitrate */
+               "%s: \n" /* format */
+               "%s: \n" /* frequency */
+               "%s: \n" /* channels */
+               "%s: \n" /* duration */
+               "%s: \n" /* seconds total */
+               "%s: \n" /* num played */
+               "%s: \n" /* last played */
+               "%s: \n" /* techinfo */
+               "%s: \n" /* artist */
+               "%s: \n" /* title */
+               "%s: \n" /* year */
+               "%s: \n" /* album */
+               "%s: \n" /* comment */
+               "%s: \n" /* amplification */
+               ,
+               status_item_list[SI_PATH],
+               status_item_list[SI_DIRECTORY],
+               status_item_list[SI_BASENAME],
+               status_item_list[SI_SCORE],
+               status_item_list[SI_ATTRIBUTES_BITMAP],
+               status_item_list[SI_ATTRIBUTES_TXT],
+               status_item_list[SI_HASH],
+               status_item_list[SI_IMAGE_ID],
+               status_item_list[SI_IMAGE_NAME],
+               status_item_list[SI_LYRICS_ID],
+               status_item_list[SI_LYRICS_NAME],
+               status_item_list[SI_BITRATE],
+               status_item_list[SI_FORMAT],
+               status_item_list[SI_FREQUENCY],
+               status_item_list[SI_CHANNELS],
+               status_item_list[SI_DURATION],
+               status_item_list[SI_SECONDS_TOTAL],
+               status_item_list[SI_NUM_PLAYED],
+               status_item_list[SI_LAST_PLAYED],
+               status_item_list[SI_TECHINFO],
+               status_item_list[SI_ARTIST],
+               status_item_list[SI_TITLE],
+               status_item_list[SI_YEAR],
+               status_item_list[SI_ALBUM],
+               status_item_list[SI_COMMENT],
+               status_item_list[SI_AMPLIFICATION]
+       );
+}
+
 /* stat */
 int com_stat(int fd, int argc, char * const * argv)
 {
@@ -326,6 +386,15 @@ int com_stat(int fd, int argc, char * const * argv)
                free(s);
                if (ret < 0)
                        goto out;
+               if (nmmd->vss_status_flags & VSS_NEXT) {
+                       static char *esi;
+                       if (!esi)
+                               esi = empty_status_items();
+                       ret = send_buffer(fd, esi);
+                       if (ret < 0)
+                               goto out;
+               } else
+                       send_afs_status(fd);
                ret = 1;
                if (num > 0 && !--num)
                        goto out;
diff --git a/vss.c b/vss.c
index 458394b8930186a0e32ff0dc649570a7a57d15b5..57e531ea3fa0143d4a98a0b15f59bafb421d9d4b 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -629,7 +629,6 @@ static void vss_eof(struct vss_task *vsst)
        mmd->afd.afhi.chunk_tv.tv_usec = 0;
        free(mmd->afd.afhi.chunk_table);
        mmd->afd.afhi.chunk_table = NULL;
-       make_empty_status_items(mmd->afd.verbose_ls_output);
        mmd->mtime = 0;
        mmd->size = 0;
        mmd->events++;
@@ -952,7 +951,6 @@ void init_vss_task(int afs_socket)
        free(hn);
        free(home);
        mmd->sender_cmd_data.cmd_num = -1;
-       make_empty_status_items(mmd->afd.verbose_ls_output);
        if (conf.autoplay_given) {
                struct timeval tmp;
                mmd->vss_status_flags |= VSS_PLAYING;