From e752cdeab213b329552e1eecd5687bca512217c5 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 29 Jun 2009 19:34:24 +0200 Subject: [PATCH] Obtain afs status items directly from afs. 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 | 7 +---- aft.c | 93 ++++++++++++------------------------------------------- command.c | 81 ++++++++++++++++++++++++++++++++++++++++++++---- vss.c | 2 -- 4 files changed, 96 insertions(+), 87 deletions(-) diff --git a/afs.h b/afs.h index a58518bb..269927f4 100644 --- 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 23b36a88..7027e7f9 100644 --- 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(¤t_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; } /** diff --git a/command.c b/command.c index 603715b4..e6a16e53 100644 --- 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 458394b8..57e531ea 100644 --- 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; -- 2.39.2