]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 'refs/heads/t/sqrt'
authorAndre Noll <maan@tuebingen.mpg.de>
Sun, 17 Sep 2017 18:13:23 +0000 (20:13 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 17 Sep 2017 18:13:37 +0000 (20:13 +0200)
A significant speedup and a three trivial patches for int_sqrt(). No
user-visible changes. Cooking for seven weeks.

* refs/heads/t/sqrt:
  mood.c: Trivial cosmetics for int_sqrt().
  mood.c: Fix documentation of int_sqrt().
  mood: Speed up int_sqrt().
  mood: Add notice about int_sqrt().

49 files changed:
Makefile.in
NEWS.md
afh_common.c
afh_recv.c
afs.c
aft.c
amp_filter.c
audioc.c
audiod.c
audiod_command.c
autogen.sh
bitstream.c
bitstream.h
blob.c
command.c
command.h
configure.ac
crypt.c
crypt_backend.h
crypt_common.c
error.h
fd.c
filter.c
filter_common.c
gui.c
gui_theme.c
m4/lls/makefile
m4/lls/server_cmd.suite.m4
mood.c
ogg_afh.c
ogg_afh_common.c
ogg_afh_common.h
opus_afh.c
para.h
portable_io.h
server.c
signal.c
spx_afh.c
stdin.c
stdout.c
string.h
t/t0004-server.sh
udp_send.c
user_list.c
vss.c
vss.h
web/manual.md
wma_afh.c
wmadec_filter.c

index b3e3be5cc82deb414f85404af830759ccd0e0963..556a926c235fac68714c877c7fd9bc6f9838d927 100644 (file)
@@ -9,6 +9,7 @@ PACKAGE_TARNAME := @PACKAGE_TARNAME@
 PACKAGE_VERSION := @PACKAGE_VERSION@
 
 M4 := @M4@
+LOPSUBGEN := @LOPSUBGEN@
 
 executables := @executables@
 
diff --git a/NEWS.md b/NEWS.md
index 894922f885ad14ac5c25f3f203706d5246889ad2..6724317d1adfa356de71242934336e8c32343beb 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,17 +1,25 @@
 NEWS
 ====
-
 ---------------------
 current master branch
 ---------------------
 
 - New sort order for the ls command: -s=h sorts the ls output by hash
   value of the audio file.
+- autogen.sh now runs the test suite after a successful build.
 - The contents of overview.pdf have been integrated into the user
   manual.
+- Fixed sized audio format headers for ogg/opus streams.
 - The doxygen source browser has been disabled temporarily. The
   API reference is still online, though.
 - Overhaul of the source code documentation.
+- The deprecated --full-path option of the ls command has been
+  removed. It was a no-op since 0.6.0.
+- The wma decoder has been cleaned up and its bitstream API made
+  more robust.
+- The image/lyrics ID status items of the current audio file are now
+  updated on changes. This affects para_gui, which used to report the
+  old value until EOF.
 
 -------------------------------
 0.6.0 (2017-04-28) "fuzzy flux"
index 1614c27c6c9dd6d7588399ca164a9fd754087e83..dd9b319289f1c6e5da316926fdfafb8eb7ede4fc 100644 (file)
@@ -31,7 +31,7 @@ extern afh_init_func mp3_afh_init, ogg_afh_init, aac_afh_init, wma_afh_init,
        spx_afh_init, flac_afh_init, opus_afh_init;
 
 /** The list of all status items */
-const char *status_item_list[] = {STATUS_ITEM_ARRAY};
+const char *status_item_list[] = {STATUS_ITEMS};
 
 /**
  * The list of supported audio formats.
@@ -464,21 +464,21 @@ unsigned afh_get_afhi_txt(int audio_format_num, struct afh_info *afhi, char **re
                "%s: %s\n" /* year */
                "%s: %s\n" /* album */
                "%s: %s\n", /* comment */
-               status_item_list[SI_BITRATE], afhi->bitrate,
-               status_item_list[SI_FORMAT], audio_format_name(audio_format_num),
-               status_item_list[SI_FREQUENCY], afhi->frequency,
-               status_item_list[SI_CHANNELS], afhi->channels,
-               status_item_list[SI_SECONDS_TOTAL], afhi->seconds_total,
-               status_item_list[SI_CHUNK_TIME], (long unsigned)afhi->chunk_tv.tv_sec,
+               status_item_list[SI_bitrate], afhi->bitrate,
+               status_item_list[SI_format], audio_format_name(audio_format_num),
+               status_item_list[SI_frequency], afhi->frequency,
+               status_item_list[SI_channels], afhi->channels,
+               status_item_list[SI_seconds_total], afhi->seconds_total,
+               status_item_list[SI_chunk_time], (long unsigned)afhi->chunk_tv.tv_sec,
                        (long unsigned)afhi->chunk_tv.tv_usec,
-               status_item_list[SI_NUM_CHUNKS], afhi->chunks_total,
-               status_item_list[SI_MAX_CHUNK_SIZE], afhi->max_chunk_size,
-               status_item_list[SI_TECHINFO], afhi->techinfo? afhi->techinfo : "",
-               status_item_list[SI_ARTIST], afhi->tags.artist? afhi->tags.artist : "",
-               status_item_list[SI_TITLE], afhi->tags.title? afhi->tags.title : "",
-               status_item_list[SI_YEAR], afhi->tags.year? afhi->tags.year : "",
-               status_item_list[SI_ALBUM], afhi->tags.album? afhi->tags.album : "",
-               status_item_list[SI_COMMENT], afhi->tags.comment? afhi->tags.comment : ""
+               status_item_list[SI_num_chunks], afhi->chunks_total,
+               status_item_list[SI_max_chunk_size], afhi->max_chunk_size,
+               status_item_list[SI_techinfo], afhi->techinfo? afhi->techinfo : "",
+               status_item_list[SI_artist], afhi->tags.artist? afhi->tags.artist : "",
+               status_item_list[SI_title], afhi->tags.title? afhi->tags.title : "",
+               status_item_list[SI_year], afhi->tags.year? afhi->tags.year : "",
+               status_item_list[SI_album], afhi->tags.album? afhi->tags.album : "",
+               status_item_list[SI_comment], afhi->tags.comment? afhi->tags.comment : ""
        );
 }
 
index d2d8b52bb86d18d70d356fdcb43044b064590de6..36bc988212d02237e3f8a9484aa993b5b3d5a055 100644 (file)
@@ -200,7 +200,7 @@ static int afh_recv_post_select(__a_unused struct sched *s, void *context)
                                &pard->afh_context);
                        if (ret < 0)
                                goto out;
-                       PARA_INFO_LOG("adding %zu bytes\n", size);
+                       PARA_DEBUG_LOG("adding %zu bytes\n", size);
                        btr_add_output_dont_free(start, size, btrn);
                }
                ret = -E_RECV_EOF;
diff --git a/afs.c b/afs.c
index 59595567fcd6c7b4f7c66c49bfb2e3183cd73283..ef05a473e85a022568a785ecc8da140d2b19d1dc 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -482,7 +482,7 @@ static int activate_mood_or_playlist(const char *arg, int *num_admissible)
                        ret = change_current_mood(arg + 2);
                        mode = PLAY_MODE_MOOD;
                } else
-                       return -E_AFS_SYNTAX;
+                       return -ERRNO_TO_PARA_ERROR(EINVAL);
                if (ret < 0)
                        return ret;
        }
@@ -497,10 +497,12 @@ static int activate_mood_or_playlist(const char *arg, int *num_admissible)
                        strncpy(mmd->afs_mode_string, arg,
                                sizeof(mmd->afs_mode_string));
                        mmd->afs_mode_string[sizeof(mmd->afs_mode_string) - 1] = '\0';
+                       mmd->events++;
                        mutex_unlock(mmd_mutex);
                } else {
                        mutex_lock(mmd_mutex);
                        strcpy(mmd->afs_mode_string, "dummy");
+                       mmd->events++;
                        mutex_unlock(mmd_mutex);
                        current_mop = NULL;
                }
@@ -580,7 +582,7 @@ static int com_select_callback(struct afs_callback_arg *aca)
                goto out;
        /* ignore subsequent errors (but log them) */
        para_printf(&aca->pbout, "could not activate %s\n", arg);
-       if (current_mop) {
+       if (current_mop && strcmp(current_mop, arg) != 0) {
                int ret2;
                para_printf(&aca->pbout, "switching back to %s\n", current_mop);
                ret2 = activate_mood_or_playlist(current_mop, &num_admissible);
@@ -615,8 +617,13 @@ EXPORT_SERVER_CMD_HANDLER(select);
 
 static void init_admissible_files(const char *arg)
 {
-       if (activate_mood_or_playlist(arg, NULL) < 0)
+       int ret = activate_mood_or_playlist(arg, NULL);
+       if (ret < 0) {
+               assert(arg);
+               PARA_WARNING_LOG("could not activate %s: %s\n", arg,
+                       para_strerror(-ret));
                activate_mood_or_playlist(NULL, NULL); /* always successful */
+       }
 }
 
 static int setup_command_socket_or_die(void)
diff --git a/aft.c b/aft.c
index 63a40d790f602c81d6f28e71e02b6d46d907cd5d..1679a5495131117f440a5ee610f677ff14cc5612 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -542,10 +542,12 @@ int get_audio_file_path_of_row(const struct osl_row *row, char **path)
        struct osl_object path_obj;
        int ret = osl(osl_get_object(audio_file_table, row, AFTCOL_PATH,
                &path_obj));
+
        if (ret < 0)
-               return ret;
-       *path = path_obj.data;
-       return 1;
+               *path = NULL;
+       else
+               *path = path_obj.data;
+       return ret;
 }
 
 /**
@@ -754,11 +756,11 @@ static int write_attribute_items(struct para_buffer *b,
        char *att_text;
        int ret;
 
-       WRITE_STATUS_ITEM(b, SI_ATTRIBUTES_BITMAP, "%s\n", att_bitmap);
+       WRITE_STATUS_ITEM(b, SI_attributes_bitmap, "%s\n", att_bitmap);
        ret = get_attribute_text(&afsi->attributes, " ", &att_text);
        if (ret < 0)
                return ret;
-       WRITE_STATUS_ITEM(b, SI_ATTRIBUTES_TXT, "%s\n", att_text);
+       WRITE_STATUS_ITEM(b, SI_attributes_txt, "%s\n", att_text);
        free(att_text);
        return ret;
 }
@@ -767,9 +769,9 @@ static void write_lyrics_items(struct para_buffer *b, struct afs_info *afsi)
 {
        char *lyrics_name;
 
-       WRITE_STATUS_ITEM(b, SI_LYRICS_ID, "%u\n", afsi->lyrics_id);
+       WRITE_STATUS_ITEM(b, SI_lyrics_id, "%u\n", afsi->lyrics_id);
        lyr_get_name_by_id(afsi->lyrics_id, &lyrics_name);
-       WRITE_STATUS_ITEM(b, SI_LYRICS_NAME, "%s\n", lyrics_name?
+       WRITE_STATUS_ITEM(b, SI_lyrics_name, "%s\n", lyrics_name?
                lyrics_name : "(none)");
 }
 
@@ -777,9 +779,9 @@ static void write_image_items(struct para_buffer *b, struct afs_info *afsi)
 {
        char *image_name;
 
-       WRITE_STATUS_ITEM(b, SI_IMAGE_ID, "%u\n", afsi->image_id);
+       WRITE_STATUS_ITEM(b, SI_image_id, "%u\n", afsi->image_id);
        img_get_name_by_id(afsi->image_id, &image_name);
-       WRITE_STATUS_ITEM(b, SI_IMAGE_NAME, "%s\n", image_name?
+       WRITE_STATUS_ITEM(b, SI_image_name, "%s\n", image_name?
                image_name : "(none)");
 }
 
@@ -789,14 +791,14 @@ static void write_filename_items(struct para_buffer *b, const char *path,
        char *val;
 
        if (basename) {
-               WRITE_STATUS_ITEM(b, SI_BASENAME, "%s\n", path);
+               WRITE_STATUS_ITEM(b, SI_basename, "%s\n", path);
                return;
        }
-       WRITE_STATUS_ITEM(b, SI_PATH, "%s\n", path);
+       WRITE_STATUS_ITEM(b, SI_path, "%s\n", path);
        val = para_basename(path);
-       WRITE_STATUS_ITEM(b, SI_BASENAME, "%s\n", val? val : "");
+       WRITE_STATUS_ITEM(b, SI_basename, "%s\n", val? val : "");
        val = para_dirname(path);
-       WRITE_STATUS_ITEM(b, SI_DIRECTORY, "%s\n", val? val : "");
+       WRITE_STATUS_ITEM(b, SI_directory, "%s\n", val? val : "");
        free(val);
 }
 
@@ -913,36 +915,36 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts,
        }
        write_filename_items(b, d->path, lls_opt_given(r_b));
        if (lls_opt_given(r_a))
-               WRITE_STATUS_ITEM(b, SI_SCORE, "%li\n", d->score);
+               WRITE_STATUS_ITEM(b, SI_score, "%li\n", d->score);
        ret = write_attribute_items(b, att_buf, afsi);
        if (ret < 0)
                goto out;
        write_image_items(b, afsi);
        write_lyrics_items(b, afsi);
        hash_to_asc(d->hash, asc_hash);
-       WRITE_STATUS_ITEM(b, SI_HASH, "%s\n", asc_hash);
-       WRITE_STATUS_ITEM(b, SI_BITRATE, "%dkbit/s\n", afhi->bitrate);
-       WRITE_STATUS_ITEM(b, SI_FORMAT, "%s\n",
+       WRITE_STATUS_ITEM(b, SI_hash, "%s\n", asc_hash);
+       WRITE_STATUS_ITEM(b, SI_bitrate, "%dkbit/s\n", afhi->bitrate);
+       WRITE_STATUS_ITEM(b, SI_format, "%s\n",
                audio_format_name(afsi->audio_format_id));
-       WRITE_STATUS_ITEM(b, SI_FREQUENCY, "%dHz\n", afhi->frequency);
-       WRITE_STATUS_ITEM(b, SI_CHANNELS, "%d\n", afhi->channels);
-       WRITE_STATUS_ITEM(b, SI_DURATION, "%s\n", duration_buf);
-       WRITE_STATUS_ITEM(b, SI_SECONDS_TOTAL, "%" PRIu32 "\n",
+       WRITE_STATUS_ITEM(b, SI_frequency, "%dHz\n", afhi->frequency);
+       WRITE_STATUS_ITEM(b, SI_channels, "%d\n", afhi->channels);
+       WRITE_STATUS_ITEM(b, SI_duration, "%s\n", duration_buf);
+       WRITE_STATUS_ITEM(b, SI_seconds_total, "%" PRIu32 "\n",
                afhi->seconds_total);
-       WRITE_STATUS_ITEM(b, SI_LAST_PLAYED, "%s\n", last_played_time);
-       WRITE_STATUS_ITEM(b, SI_NUM_PLAYED, "%u\n", afsi->num_played);
-       WRITE_STATUS_ITEM(b, SI_AMPLIFICATION, "%u\n", afsi->amp);
-       WRITE_STATUS_ITEM(b, SI_CHUNK_TIME, "%lu\n", tv2ms(&afhi->chunk_tv));
-       WRITE_STATUS_ITEM(b, SI_NUM_CHUNKS, "%" PRIu32 "\n",
+       WRITE_STATUS_ITEM(b, SI_last_played, "%s\n", last_played_time);
+       WRITE_STATUS_ITEM(b, SI_num_played, "%u\n", afsi->num_played);
+       WRITE_STATUS_ITEM(b, SI_amplification, "%u\n", afsi->amp);
+       WRITE_STATUS_ITEM(b, SI_chunk_time, "%lu\n", tv2ms(&afhi->chunk_tv));
+       WRITE_STATUS_ITEM(b, SI_num_chunks, "%" PRIu32 "\n",
                afhi->chunks_total);
-       WRITE_STATUS_ITEM(b, SI_MAX_CHUNK_SIZE, "%" PRIu32 "\n",
+       WRITE_STATUS_ITEM(b, SI_max_chunk_size, "%" PRIu32 "\n",
                afhi->max_chunk_size);
-       WRITE_STATUS_ITEM(b, SI_TECHINFO, "%s\n", afhi->techinfo);
-       WRITE_STATUS_ITEM(b, SI_ARTIST, "%s\n", afhi->tags.artist);
-       WRITE_STATUS_ITEM(b, SI_TITLE, "%s\n", afhi->tags.title);
-       WRITE_STATUS_ITEM(b, SI_YEAR, "%s\n", afhi->tags.year);
-       WRITE_STATUS_ITEM(b, SI_ALBUM, "%s\n", afhi->tags.album);
-       WRITE_STATUS_ITEM(b, SI_COMMENT, "%s\n", afhi->tags.comment);
+       WRITE_STATUS_ITEM(b, SI_techinfo, "%s\n", afhi->techinfo);
+       WRITE_STATUS_ITEM(b, SI_artist, "%s\n", afhi->tags.artist);
+       WRITE_STATUS_ITEM(b, SI_title, "%s\n", afhi->tags.title);
+       WRITE_STATUS_ITEM(b, SI_year, "%s\n", afhi->tags.year);
+       WRITE_STATUS_ITEM(b, SI_album, "%s\n", afhi->tags.album);
+       WRITE_STATUS_ITEM(b, SI_comment, "%s\n", afhi->tags.comment);
        if (opts->mode == LS_MODE_MBOX) {
                struct osl_object lyrics_def;
                lyr_get_def_by_id(afsi->lyrics_id, &lyrics_def);
@@ -976,8 +978,8 @@ static void make_inode_status_items(struct para_buffer *pb)
        ret = strftime(mtime_str, 29, "%b %d %Y", &mtime_tm);
        assert(ret > 0); /* number of bytes placed in mtime_str */
 out:
-       WRITE_STATUS_ITEM(pb, SI_MTIME, "%s\n", mtime_str);
-       WRITE_STATUS_ITEM(pb, SI_FILE_SIZE, "%ld\n", statbuf.st_size / 1024);
+       WRITE_STATUS_ITEM(pb, SI_mtime, "%s\n", mtime_str);
+       WRITE_STATUS_ITEM(pb, SI_file_size, "%ld\n", statbuf.st_size / 1024);
 }
 
 static int make_status_items(void)
@@ -989,6 +991,8 @@ static int make_status_items(void)
        time_t current_time;
        int ret;
 
+       if (!status_item_ls_data.path) /* no audio file open */
+               return 0;
        ret = lls_parse(ARRAY_SIZE(argv), argv, cmd, &opts.lpr, NULL);
        assert(ret >= 0);
        time(&current_time);
@@ -2567,6 +2571,16 @@ static int aft_event_handler(enum afs_events event, struct para_buffer *pb,
                        return ret;
                make_status_items();
                return 1;
+       }
+       case BLOB_RENAME:
+       case BLOB_REMOVE:
+       case BLOB_ADD: {
+               /*
+                * These events are rare. We don't bother to check whether the
+                * current status items are affected and simply recreate them
+                * every time.
+                */
+               make_status_items();
        } default:
                return 0;
        }
index f3d0d87d45f077d901d5f4cb98c20dc9a3099547..4f8e04907e6367b221a42230cce9f9cfa0bc5b26 100644 (file)
@@ -39,8 +39,8 @@ static void amp_open(struct filter_node *fn)
 
        fn->private_data = pad;
        fn->min_iqs = 2;
-       if (!given && stat_item_values[SI_AMPLIFICATION])
-               sscanf(stat_item_values[SI_AMPLIFICATION], "%u", &pad->amp);
+       if (!given && stat_item_values[SI_amplification])
+               sscanf(stat_item_values[SI_amplification], "%u", &pad->amp);
        else
                pad->amp = amp_arg;
        PARA_INFO_LOG("amplification: %u (scaling factor: %1.2f)\n",
index 1d69b2c15f7e6f3fb2683d107f04e738ecfc83cf..ed39ce6efa942e58773d891e2ffb28acc39eecf3 100644 (file)
--- a/audioc.c
+++ b/audioc.c
@@ -116,7 +116,7 @@ static void version_completer(struct i9e_completion_info *ci,
 static void stat_completer(struct i9e_completion_info *ci,
                struct i9e_completion_result *cr)
 {
-       char *sia[] = {STATUS_ITEM_ARRAY NULL};
+       char *sia[] = {STATUS_ITEMS NULL};
        char *opts[] = {LSG_AUDIOD_CMD_STAT_OPTS, NULL};
 
        if (ci->word_num <= 2 && ci->word && ci->word[0] == '-')
index defd673d20ba0029aaa228e7d23545fd11a5ce54..42f4c0a3be06b5aad9a00cf6a351f8b4287d0af7 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -666,6 +666,7 @@ static int open_receiver(int format)
                EMBRACE(.name = name, .context = rn));
        ret = r->open(rn);
        if (ret < 0) {
+               PARA_ERROR_LOG("could not open %s receiver\n", name);
                btr_remove_node(&rn->btrn);
                free(rn);
                return ret;
@@ -801,38 +802,38 @@ static int update_item(int itemnum, char *buf)
 {
        long unsigned sec, usec;
 
-       if (stat_task->clock_diff_count && itemnum != SI_CURRENT_TIME)
+       if (stat_task->clock_diff_count && itemnum != SI_current_time)
                return 1;
        free(stat_item_values[itemnum]);
        stat_item_values[itemnum] = para_strdup(buf);
        stat_client_write_item(itemnum);
        switch (itemnum) {
-       case SI_STATUS_FLAGS:
+       case SI_status_flags:
                stat_task->vss_status = 0;
                if (strchr(buf, 'N'))
                        stat_task->vss_status |= VSS_STATUS_FLAG_NEXT;
                if (strchr(buf, 'P'))
                        stat_task->vss_status |= VSS_STATUS_FLAG_PLAYING;
                break;
-       case SI_OFFSET:
+       case SI_offset:
                stat_task->offset_seconds = atoi(buf);
                break;
-       case SI_SECONDS_TOTAL:
+       case SI_seconds_total:
                stat_task->length_seconds = atoi(buf);
                break;
-       case SI_STREAM_START:
+       case SI_stream_start:
                if (sscanf(buf, "%lu.%lu", &sec, &usec) == 2) {
                        stat_task->server_stream_start.tv_sec = sec;
                        stat_task->server_stream_start.tv_usec = usec;
                }
                break;
-       case SI_CURRENT_TIME:
+       case SI_current_time:
                if (sscanf(buf, "%lu.%lu", &sec, &usec) == 2) {
                        struct timeval tv = {sec, usec};
                        compute_time_diff(&tv);
                }
                break;
-       case SI_FORMAT:
+       case SI_format:
                stat_task->current_audio_format_num
                        = get_audio_format_num(buf);
        }
@@ -1384,10 +1385,10 @@ static int status_post_select(struct sched *s, void *context)
                client_open(argc, argv, &st->ct, NULL, NULL, st->btrn, s);
                set_stat_task_restart_barrier(5);
        }
-       free(stat_item_values[SI_BASENAME]);
-       stat_item_values[SI_BASENAME] = para_strdup(
+       free(stat_item_values[SI_basename]);
+       stat_item_values[SI_basename] = para_strdup(
                "no connection to para_server");
-       stat_client_write_item(SI_BASENAME);
+       stat_client_write_item(SI_basename);
        st->last_status_read = *now;
 out:
        start_stop_decoders();
index cccc2a8908d933d0d5ef2f41bb6b79dc11602baf..a6a49b7461d818b36a12b2eee0f30fbf359b3ed9 100644 (file)
@@ -82,7 +82,7 @@ static INITIALIZED_LIST_HEAD(client_list);
 static int num_clients;
 
 /** The list of all status items used by para_{server,audiod,gui}. */
-const char *status_item_list[] = {STATUS_ITEM_ARRAY};
+const char *status_item_list[] = {STATUS_ITEMS};
 
 static void dump_stat_client_list(void)
 {
@@ -481,41 +481,41 @@ void audiod_status_dump(bool force)
 {
        char *old, *new;
 
-       old = stat_item_values[SI_PLAY_TIME];
+       old = stat_item_values[SI_play_time];
        new = get_time_string();
        if (new) {
                if (force || !old || strcmp(old, new)) {
                        free(old);
-                       stat_item_values[SI_PLAY_TIME] = new;
-                       stat_client_write_item(SI_PLAY_TIME);
+                       stat_item_values[SI_play_time] = new;
+                       stat_client_write_item(SI_play_time);
                } else
                        free(new);
        }
 
        new = daemon_get_uptime_str(now);
-       old = stat_item_values[SI_AUDIOD_UPTIME];
+       old = stat_item_values[SI_audiod_uptime];
        if (force || !old || strcmp(old, new)) {
                free(old);
-               stat_item_values[SI_AUDIOD_UPTIME] = new;
-               stat_client_write_item(SI_AUDIOD_UPTIME);
+               stat_item_values[SI_audiod_uptime] = new;
+               stat_client_write_item(SI_audiod_uptime);
        } else
                free(new);
 
-       old = stat_item_values[SI_AUDIOD_STATUS];
+       old = stat_item_values[SI_audiod_status];
        new = audiod_status_string();
        if (force || !old || strcmp(old, new)) {
                free(old);
-               stat_item_values[SI_AUDIOD_STATUS] = new;
-               stat_client_write_item(SI_AUDIOD_STATUS);
+               stat_item_values[SI_audiod_status] = new;
+               stat_client_write_item(SI_audiod_status);
        } else
                free(new);
 
-       old = stat_item_values[SI_DECODER_FLAGS];
+       old = stat_item_values[SI_decoder_flags];
        new = audiod_get_decoder_flags();
        if (force || !old || strcmp(old, new)) {
                free(old);
-               stat_item_values[SI_DECODER_FLAGS] = new;
-               stat_client_write_item(SI_DECODER_FLAGS);
+               stat_item_values[SI_decoder_flags] = new;
+               stat_client_write_item(SI_decoder_flags);
        } else
                free(new);
 }
index 708602e7e04c073ff510be8584235fe198ac128e..caf1401d8bf02e2d299bdcdf58ae902cfb260092 100755 (executable)
@@ -25,4 +25,4 @@ echo configuring...
 ./configure $@ > /dev/null
 echo compiling...
 make clean > /dev/null 2>&1
-make -j $n > /dev/null
+make -j $n > /dev/null && make check
index 9cd1273cfd578cf89492012b41cf236ecd32a38d..c2018b56f593264b15034b639c4103045220ab96 100644 (file)
@@ -47,7 +47,7 @@ static void alloc_table(struct vlc *vlc, int size)
        if (vlc->table_size > vlc->table_allocated) {
                vlc->table_allocated += (1 << vlc->bits);
                vlc->table = para_realloc(vlc->table,
-                       sizeof(VLC_TYPE) * 2 * vlc->table_allocated);
+                       sizeof(int16_t) * 2 * vlc->table_allocated);
        }
 }
 
@@ -57,7 +57,7 @@ static int build_table(struct vlc *vlc, int table_nb_bits, int nb_codes,
 {
        int i, j, k, n, table_size, table_index, nb, n1, idx;
        uint32_t code;
-       VLC_TYPE(*table)[2];
+       int16_t (*table)[2];
 
        table_size = 1 << table_nb_bits;
        table_index = vlc->table_size;
@@ -165,33 +165,29 @@ void free_vlc(struct vlc *vlc)
  * Parse a vlc code.
  *
  * \param gbc The getbit context structure.
- * \param table The vlc tables to use.
- * \param bits The number of bits which will be read at once.
- *
- * The \a bits parameter must be identical to the \a nb_bits value supplied to
- * \ref init_vlc().
+ * \param vlc The vlc tables to use.
  *
  * \return The vlc code.
  */
-int get_vlc(struct getbit_context *gbc, VLC_TYPE(*table)[2], int bits)
+int get_vlc(struct getbit_context *gbc, const struct vlc *vlc)
 {
        int n, idx, nb_bits, code;
 
-       idx = show_bits(gbc, bits);
-       code = table[idx][0];
-       n = table[idx][1];
+       idx = show_bits(gbc, vlc->bits);
+       code = vlc->table[idx][0];
+       n = vlc->table[idx][1];
        if (n < 0) {
-               skip_bits(gbc, bits);
+               skip_bits(gbc, vlc->bits);
                nb_bits = -n;
                idx = show_bits(gbc, nb_bits) + code;
-               code = table[idx][0];
-               n = table[idx][1];
+               code = vlc->table[idx][0];
+               n = vlc->table[idx][1];
                if (n < 0) {
                        skip_bits(gbc, nb_bits);
                        nb_bits = -n;
                        idx = show_bits(gbc, nb_bits) + code;
-                       code = table[idx][0];
-                       n = table[idx][1];
+                       code = vlc->table[idx][0];
+                       n = vlc->table[idx][1];
                }
        }
        skip_bits(gbc, n);
index a6349861a55092fcdc1f957d7570621fd51e6834..4d81fa3b25521053c8cafcf49a4b14542b83e74a 100644 (file)
 struct getbit_context {
        /** Start of the internal buffer. */
        const uint8_t *buffer;
-       /** End of the internal buffer. */
-       const uint8_t *buffer_end;
+       /** Length of buffer in bits (always a multiple of 8). */
+       uint32_t num_bits;
        /** Bit counter. */
        int index;
 };
 
-#define VLC_TYPE int16_t
-
 /** A variable length code table. */
 struct vlc {
        /** Number of bits of the table. */
        int bits;
        /** The code and the bits table. */
-       VLC_TYPE(*table)[2];
+       int16_t (*table)[2];
        /** The size of the table. */
        int table_size;
        /** Amount of memory allocated so far. */
@@ -36,8 +34,12 @@ struct vlc {
 static inline uint32_t show_bits(struct getbit_context *gbc, int num)
 {
        int idx = gbc->index;
-       const char *p = (const char *)gbc->buffer + (idx >> 3);
-       uint32_t x = read_u32_be(p);
+       const char *p;
+       uint32_t x;
+
+       assert(idx + num <= gbc->num_bits);
+       p = (const char *)gbc->buffer + (idx >> 3);
+       x = read_u32_be(p);
        return (x << (idx & 7)) >> (32 - num);
 }
 
@@ -48,12 +50,13 @@ static inline int get_bits_count(struct getbit_context *gbc)
 
 static inline void skip_bits(struct getbit_context *gbc, int n)
 {
+       assert(gbc->index + n <= gbc->num_bits);
        gbc->index += n;
 }
 
 static inline unsigned int get_bits(struct getbit_context *gbc, int n)
 {
-       unsigned int ret = show_bits(gbc, n);
+       unsigned int ret = show_bits(gbc, n); /* checks n */
        skip_bits(gbc, n);
        return ret;
 }
@@ -61,8 +64,13 @@ static inline unsigned int get_bits(struct getbit_context *gbc, int n)
 /* This is rather hot, we can do better than get_bits(gbc, 1). */
 static inline unsigned int get_bit(struct getbit_context *gbc)
 {
-       int idx = gbc->index++;
-       uint8_t tmp = gbc->buffer[idx >> 3], mask = 1 << (7 - (idx & 7));
+       int idx;
+       uint8_t tmp, mask;
+
+       assert(gbc->index < gbc->num_bits);
+       idx = gbc->index++;
+       tmp = gbc->buffer[idx >> 3];
+       mask = 1 << (7 - (idx & 7));
        return !!(tmp & mask);
 }
 
@@ -81,11 +89,11 @@ static inline void init_get_bits(struct getbit_context *gbc,
                const uint8_t *buffer, int size)
 {
        gbc->buffer = buffer;
-       gbc->buffer_end = buffer + size;
+       gbc->num_bits = size * 8;
        gbc->index = 0;
 }
 
 void init_vlc(struct vlc *vlc, int nb_bits, int nb_codes, const void *bits,
                const void *codes, int codes_size);
 void free_vlc(struct vlc *vlc);
-int get_vlc(struct getbit_context *gbc, VLC_TYPE(*table)[2], int bits);
+int get_vlc(struct getbit_context *gbc, const struct vlc *vlc);
diff --git a/blob.c b/blob.c
index 2d7c6050cfb18c198675c1ce4a534dd824983310..7798a4939b9d0859b5fe7d4939feb0d237b36b8b 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -33,8 +33,8 @@
  */
 static int uint32_compare(const struct osl_object *obj1, const struct osl_object *obj2)
 {
-       uint32_t d1 = read_u32((const char *)obj1->data);
-       uint32_t d2 = read_u32((const char *)obj2->data);
+       uint32_t d1 = read_u32(obj1->data);
+       uint32_t d2 = read_u32(obj2->data);
 
        if (d1 < d2)
                return 1;
index 5802d37ab7a7353c545bc5dbc9c998f297a2f576..69564336c6f8228a072f699ad83dbbe19d154338 100644 (file)
--- a/command.c
+++ b/command.c
@@ -111,14 +111,14 @@ static unsigned get_status(struct misc_meta_data *nmmd, bool parser_friendly,
         * clang is not smart enough to prove this and complains nevertheless.
         * Casting the return value to void silences clang.
         */
-       (void)WRITE_STATUS_ITEM(&b, SI_STATUS, "%s\n", status);
-       (void)WRITE_STATUS_ITEM(&b, SI_STATUS_FLAGS, "%s\n", flags);
-       (void)WRITE_STATUS_ITEM(&b, SI_OFFSET, "%li\n", offset);
-       (void)WRITE_STATUS_ITEM(&b, SI_AFS_MODE, "%s\n", mmd->afs_mode_string);
-       (void)WRITE_STATUS_ITEM(&b, SI_STREAM_START, "%lu.%lu\n",
+       (void)WRITE_STATUS_ITEM(&b, SI_status, "%s\n", status);
+       (void)WRITE_STATUS_ITEM(&b, SI_status_flags, "%s\n", flags);
+       (void)WRITE_STATUS_ITEM(&b, SI_offset, "%li\n", offset);
+       (void)WRITE_STATUS_ITEM(&b, SI_afs_mode, "%s\n", mmd->afs_mode_string);
+       (void)WRITE_STATUS_ITEM(&b, SI_stream_start, "%lu.%lu\n",
                (long unsigned)nmmd->stream_start.tv_sec,
                (long unsigned)nmmd->stream_start.tv_usec);
-       (void)WRITE_STATUS_ITEM(&b, SI_CURRENT_TIME, "%lu.%lu\n",
+       (void)WRITE_STATUS_ITEM(&b, SI_current_time, "%lu.%lu\n",
                (long unsigned)current_time.tv_sec,
                (long unsigned)current_time.tv_usec);
        free(flags);
@@ -227,7 +227,7 @@ static int check_sender_args(struct command_context *cc,
                struct lls_parse_result *lpr, struct sender_command_data *scd)
 {
        int i, ret;
-       const char *subcmds[] = {SENDER_SUBCOMMANDS};
+       const char * const subcmds[] = {SENDER_SUBCOMMANDS};
        const char *arg;
        char *errctx;
        unsigned num_inputs = lls_num_inputs(lpr);
@@ -246,10 +246,10 @@ static int check_sender_args(struct command_context *cc,
                return -E_COMMAND_SYNTAX;
        scd->sender_num = i;
        arg = lls_input(1, lpr);
-       for (i = 0; subcmds[i]; i++)
+       for (i = 0; i < NUM_SENDER_CMDS; i++)
                if (!strcmp(subcmds[i], arg))
                        break;
-       if (!subcmds[i])
+       if (i == NUM_SENDER_CMDS)
                return -E_COMMAND_SYNTAX;
        scd->cmd_num = i;
        if (!senders[scd->sender_num].client_cmds[scd->cmd_num])
@@ -426,41 +426,40 @@ EXPORT_SERVER_CMD_HANDLER(version);
 
 /** These status items are cleared if no audio file is currently open. */
 #define EMPTY_STATUS_ITEMS \
-       ITEM(PATH) \
-       ITEM(DIRECTORY) \
-       ITEM(BASENAME) \
-       ITEM(SCORE) \
-       ITEM(ATTRIBUTES_BITMAP) \
-       ITEM(ATTRIBUTES_TXT) \
-       ITEM(HASH) \
-       ITEM(IMAGE_ID) \
-       ITEM(IMAGE_NAME) \
-       ITEM(LYRICS_ID) \
-       ITEM(LYRICS_NAME) \
-       ITEM(BITRATE) \
-       ITEM(FORMAT) \
-       ITEM(FREQUENCY) \
-       ITEM(CHANNELS) \
-       ITEM(DURATION) \
-       ITEM(SECONDS_TOTAL) \
-       ITEM(NUM_PLAYED) \
-       ITEM(LAST_PLAYED) \
-       ITEM(TECHINFO) \
-       ITEM(ARTIST) \
-       ITEM(TITLE) \
-       ITEM(YEAR) \
-       ITEM(ALBUM) \
-       ITEM(COMMENT) \
-       ITEM(MTIME) \
-       ITEM(FILE_SIZE) \
-       ITEM(CHUNK_TIME) \
-       ITEM(NUM_CHUNKS) \
-       ITEM(AMPLIFICATION) \
+       ITEM(path) \
+       ITEM(directory) \
+       ITEM(basename) \
+       ITEM(score) \
+       ITEM(attributes_bitmap) \
+       ITEM(attributes_txt) \
+       ITEM(hash) \
+       ITEM(image_id) \
+       ITEM(image_name) \
+       ITEM(lyrics_id) \
+       ITEM(lyrics_name) \
+       ITEM(bitrate) \
+       ITEM(format) \
+       ITEM(frequency) \
+       ITEM(channels) \
+       ITEM(duration) \
+       ITEM(seconds_total) \
+       ITEM(num_played) \
+       ITEM(last_played) \
+       ITEM(techinfo) \
+       ITEM(artist) \
+       ITEM(title) \
+       ITEM(year) \
+       ITEM(album) \
+       ITEM(comment) \
+       ITEM(mtime) \
+       ITEM(file_size) \
+       ITEM(chunk_time) \
+       ITEM(num_chunks) \
+       ITEM(amplification) \
 
-/**
- * Write a list of audio-file related status items with empty values.
- *
- * This is used by vss when currently no audio file is open.
+/*
+ * Create a set of audio-file related status items with empty values. These are
+ * written to stat clients when no audio file is open.
  */
 static unsigned empty_status_items(bool parser_friendly, char **result)
 {
@@ -893,7 +892,7 @@ __noreturn void handle_connect(int fd, const char *peername)
        unsigned char challenge_hash[HASH_SIZE];
        char *command = NULL, *buf = para_malloc(HANDSHAKE_BUFSIZE) /* must be on the heap */;
        size_t numbytes;
-       struct command_context cc_struct = {.peer = peername}, *cc = &cc_struct;
+       struct command_context cc_struct = {.u = NULL}, *cc = &cc_struct;
        struct iovec iov;
        struct connection_features cf;
 
index 5b01eb79e3500f34d135d1bdc8db6ac8ec4ad59c..0265f056d999ff1322b639493ad5503bc847dd6e 100644 (file)
--- a/command.h
+++ b/command.h
@@ -2,8 +2,6 @@
 
 /** Per connection data available to command handlers. */
 struct command_context {
-       /** Network address of the peer. */
-       const char *peer;
        /** The paraslash user that executes this command. */
        struct user *u;
        /** File descriptor and crypto keys. */
index c2cb47e6f993c6cbbad343208ce634af8bf80173..83375559516396cf3a052fbc4f90871a344f732b 100644 (file)
@@ -54,10 +54,6 @@ AC_PATH_PROG([M4], [m4])
 test -z "$M4" && AC_MSG_ERROR(
        [The m4 macro processor is required to build this package])
 
-AC_PATH_PROG([lopsubgen], [lopsubgen])
-test -z "$lopsubgen" && AC_MSG_ERROR(
-       [lopsubgen is required to build this package])
-
 AC_PROG_CC
 AC_PROG_CPP
 
@@ -71,9 +67,11 @@ AC_CHECK_LIB([osl], [osl_open_table], [], [HAVE_OSL=no])
 LIB_SUBST_FLAGS(osl)
 UNSTASH_FLAGS
 ######################################################################## lopsub
+HAVE_LOPSUB=yes
+AC_PATH_PROG([LOPSUBGEN], [lopsubgen])
+test -z "$LOPSUBGEN" && HAVE_LOPSUB=no
 STASH_FLAGS
 LIB_ARG_WITH([lopsub], [-llopsub])
-HAVE_LOPSUB=yes
 AC_CHECK_HEADER(lopsub.h, [], [HAVE_LOPSUB=no])
 AC_CHECK_LIB([lopsub], [lls_merge], [], [HAVE_LOPSUB=no])
 if test $HAVE_LOPSUB = no; then AC_MSG_ERROR([
@@ -165,17 +163,12 @@ AC_DEFINE_UNQUOTED(ICONV_CAST, $cast, [cast for second arg to iconv()])
 AC_MSG_RESULT($msg)
 UNSTASH_FLAGS
 ########################################################################### ucred
-AC_MSG_CHECKING(for struct ucred)
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+AC_CHECK_TYPE([struct ucred], [
+       AC_DEFINE(HAVE_UCRED, 1, define to 1 you have struct ucred)
+], [], [
        #include <sys/types.h>
        #include <sys/socket.h>
-]], [[
-       struct ucred sucred; sucred.pid=0;
-]])],[have_ucred=yes],[have_ucred=no])
-AC_MSG_RESULT($have_ucred)
-if test ${have_ucred} = yes; then
-       AC_DEFINE(HAVE_UCRED, 1, define to 1 you have struct ucred)
-fi
+])
 ########################################################################### curses
 STASH_FLAGS
 LIB_ARG_WITH([curses], [])
@@ -186,18 +179,12 @@ curses_ldflags="$curses_ldflags $LIBS"
 LIB_SUBST_FLAGS(curses)
 UNSTASH_FLAGS
 ########################################################################### ip_mreqn
-AC_MSG_CHECKING(for struct ip_mreqn (UDPv4 multicast))
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+AC_CHECK_TYPE([struct ip_mreqn], [
+       AC_DEFINE(HAVE_IP_MREQN, 1, define to 1 if you have struct ip_mreqn)
+], [], [
        #include <netdb.h>
        #include <net/if.h>
-]], [[
-       struct ip_mreqn mn;
-       mn.imr_ifindex = 0;
-]])],[have_ip_mreqn=yes],[have_ip_mreqn=no])
-AC_MSG_RESULT($have_ip_mreqn)
-if test ${have_ip_mreqn} = yes; then
-       AC_DEFINE(HAVE_IP_MREQN, 1, define to 1 if you have struct ip_mreqn)
-fi
+])
 ########################################################################### ogg
 STASH_FLAGS
 LIB_ARG_WITH([ogg], [-logg])
@@ -803,33 +790,9 @@ if test $HAVE_READLINE = yes; then
 fi
 audioc_objs="$audioc_errlist_objs"
 AC_SUBST(audioc_objs, add_dot_o($audioc_objs))
-################################################################## status items
-
-status_items="basename status num_played mtime bitrate frequency file_size
-status_flags format score techinfo afs_mode
-attributes_txt decoder_flags audiod_status play_time attributes_bitmap
-offset seconds_total stream_start current_time audiod_uptime image_id
-lyrics_id duration directory lyrics_name image_name path hash channels
-last_played num_chunks chunk_time amplification artist title year album
-comment max_chunk_size"
-
-result=
-for i in $status_items; do
-       result="$result SI_$(echo $i | tr 'a-z' 'A-Z'), "
-done
-AC_DEFINE_UNQUOTED(STATUS_ITEM_ENUM, [$result],
-       [enum of all status items])
-
-result=
-for i in $status_items; do
-       result="$result \"$i\", "
-done
-AC_DEFINE_UNQUOTED(STATUS_ITEM_ARRAY, [$result],
-       [char * array of all status items])
 
 AC_DEFINE_UNQUOTED(AUDIO_FORMAT_HANDLERS, "$audio_format_handlers",
        [formats supported by para_server and para_afh])
-
 AC_SUBST(executables)
 
 AC_OUTPUT
diff --git a/crypt.c b/crypt.c
index f1e42d4a228f7c0c498ac505575b6a0f3667bf27..d4ffdf864234e393b6ae1971a7714f763394780b 100644 (file)
--- a/crypt.c
+++ b/crypt.c
@@ -23,6 +23,7 @@
 #include "fd.h"
 #include "crypt_backend.h"
 #include "base64.h"
+#include "portable_io.h"
 
 struct asymmetric_key {
        RSA *rsa;
@@ -96,7 +97,7 @@ static int read_bignum(const unsigned char *buf, size_t len, BIGNUM **result)
                return -E_BIGNUM;
        if (p + 4 > end)
                return -E_BIGNUM;
-       bnsize = read_ssh_u32(p);
+       bnsize = read_u32_be(p);
        PARA_DEBUG_LOG("bnsize: %u\n", bnsize);
        p += 4;
        if (p + bnsize < p)
index fccdd2efbda6da1f8dac7a3a4731885e4e8f7290..85008979d4b56a38c26c520bb8868da5cacc48ef 100644 (file)
@@ -12,6 +12,5 @@
 #define AES_CRT128_BLOCK_SIZE 16
 
 size_t is_ssh_rsa_key(char *data, size_t size);
-uint32_t read_ssh_u32(const void *vp);
 int check_ssh_key_header(const unsigned char *blob, int blen);
 int check_private_key_file(const char *file);
index 1fd8189ca3c5a201bd2d227bb366bd800757a5a5..ac8564ebafbede53415866446ecfc78549a987de 100644 (file)
@@ -13,6 +13,7 @@
 #include "string.h"
 #include "crypt.h"
 #include "crypt_backend.h"
+#include "portable_io.h"
 
 /** If the key begins with this text, we treat it as an ssh key. */
 #define KEY_TYPE_TXT "ssh-rsa"
@@ -45,29 +46,6 @@ size_t is_ssh_rsa_key(char *data, size_t size)
        return cp - data;
 }
 
-/**
- * Read a 4-byte number from a buffer in big-endian format.
- *
- * \param vp The buffer.
- *
- * The byte-order of the buffer is expected to be big-endian, unlike read_u32()
- * of portable_io.h which expects little endian.
- *
- * \return The 32 bit number given by \a vp.
- */
-uint32_t read_ssh_u32(const void *vp)
-{
-       const unsigned char *p = (const unsigned char *)vp;
-       uint32_t v;
-
-       v  = (uint32_t)p[0] << 24;
-       v |= (uint32_t)p[1] << 16;
-       v |= (uint32_t)p[2] << 8;
-       v |= (uint32_t)p[3];
-
-       return v;
-}
-
 /**
  * Sanity checks for the header of an ssh key.
  *
@@ -88,7 +66,7 @@ int check_ssh_key_header(const unsigned char *blob, int blen)
 
        if (p + 4 > end)
                return -E_SSH_KEY_HEADER;
-       rlen = read_ssh_u32(p);
+       rlen = read_u32_be(p);
        p += 4;
        if (p + rlen < p)
                return -E_SSH_KEY_HEADER;
diff --git a/error.h b/error.h
index e5d2469bd5492986c231eeded9b311f0753c804f..e792b0581b6c79d70a189ef7000c782b000af763 100644 (file)
--- a/error.h
+++ b/error.h
@@ -17,7 +17,6 @@
        PARA_ERROR(AFS_SHORT_READ, "short read from afs socket"), \
        PARA_ERROR(AFS_SIGNAL, "afs caught deadly signal"), \
        PARA_ERROR(AFS_SOCKET, "afs socket not writable"), \
-       PARA_ERROR(AFS_SYNTAX, "afs syntax error"), \
        PARA_ERROR(AFT_SYNTAX, "audio file table syntax error"), \
        PARA_ERROR(ALSA, "alsa error"), \
        PARA_ERROR(ALSA_MIX_GET_VAL, "could not read control element state"), \
diff --git a/fd.c b/fd.c
index dc4fd59c93320929bd7e7f781a37f3e903a13c8f..49736448a7fe3013a69596525ea4d815358bd226 100644 (file)
--- a/fd.c
+++ b/fd.c
@@ -573,20 +573,6 @@ close_cwd:
        return ret;
 }
 
-/**
- * A wrapper for fchdir().
- *
- * \param fd An open file descriptor.
- *
- * \return Standard.
- */
-static int para_fchdir(int fd)
-{
-       if (fchdir(fd) < 0)
-               return -ERRNO_TO_PARA_ERROR(errno);
-       return 1;
-}
-
 /**
  * A wrapper for mkdir(2).
  *
@@ -749,7 +735,7 @@ int for_each_file_in_dir(const char *dirname,
 {
        DIR *dir;
        struct dirent *entry;
-       int cwd_fd, ret2, ret = para_opendir(dirname, &dir, &cwd_fd);
+       int cwd_fd, ret = para_opendir(dirname, &dir, &cwd_fd);
 
        if (ret < 0)
                return ret == -ERRNO_TO_PARA_ERROR(EACCES)? 1 : ret;
@@ -785,9 +771,8 @@ int for_each_file_in_dir(const char *dirname,
        ret = 1;
 out:
        closedir(dir);
-       ret2 = para_fchdir(cwd_fd);
-       if (ret2 < 0 && ret >= 0)
-               ret = ret2;
+       if (fchdir(cwd_fd) < 0 && ret >= 0)
+               ret = -ERRNO_TO_PARA_ERROR(errno);
        close(cwd_fd);
        return ret;
 }
index d5dac6758cc1a2e2041a97bf8cba4b2abe75e90a..156e049b5c932884266a7acfc16ca73776ff9c73 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -34,7 +34,7 @@ static struct lls_parse_result *lpr; /* command line options */
 #define OPT_UINT32_VAL(_name) (lls_uint32_val(0, OPT_RESULT(_name)))
 
 /** The list of all status items used by para_{server,audiod,gui}. */
-const char *status_item_list[] = {STATUS_ITEM_ARRAY};
+const char *status_item_list[] = {STATUS_ITEMS};
 
 /**
  * Dummy version which only contains NULL pointers.
index b406951e8ff145542e9ad579bde5311b7e3be1aa..5533d4dcd6d25fba87a242b2c09efa4b2c76e940 100644 (file)
@@ -21,7 +21,7 @@
 #include "string.h"
 
 /** Iterate over all filters. */
-#define FOR_EACH_FILTER(j) for (j = 1; lls_cmd(j, filter_cmd_suite); j++)
+#define FOR_EACH_FILTER(j) for (j = 1; FILTER_CMD(j); j++)
 
 /**
  * Obtain a reference to a filter structure.
diff --git a/gui.c b/gui.c
index 5bad7e14616f505eddb0545f51658f70759fe996..493bc3c9781d6cfac42b91878d52153f2243910c 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -569,19 +569,19 @@ static int update_item(int item_num, char *buf)
        if (buf && buf[0])
                goto dup;
        switch (item_num) {
-       case SI_ARTIST:
+       case SI_artist:
                *c = para_strdup("(artist tag not set)");
                goto print;
-       case SI_TITLE:
+       case SI_title:
                *c = para_strdup("(title tag not set)");
                goto print;
-       case SI_YEAR:
+       case SI_year:
                *c = para_strdup("????");
                goto print;
-       case SI_ALBUM:
+       case SI_album:
                *c = para_strdup("(album tag not set)");
                goto print;
-       case SI_COMMENT:
+       case SI_comment:
                *c = para_strdup("(comment tag not set)");
                goto print;
        }
@@ -680,8 +680,8 @@ static int status_post_select(struct sched *s, void *context)
                close(st->fd);
                st->fd = -1;
                clear_all_items();
-               free(stat_content[SI_BASENAME]);
-               stat_content[SI_BASENAME] =
+               free(stat_content[SI_basename]);
+               stat_content[SI_basename] =
                        para_strdup("stat command terminated!?");
                print_all_items();
                return 0;
index fb8f2f9c367101eb3b4111fe133df9c8806b72c0..78527efeabc9e3143a5dcc911cd7c5e322eaf40c 100644 (file)
@@ -34,32 +34,32 @@ static void init_theme_simple(struct gui_theme *t)
        t->dflt.bg = COLOR_BLUE;
        t->sep_char = '*';
 
-       d[SI_BASENAME].prefix = "";
-       d[SI_BASENAME].postfix = "";
-       d[SI_BASENAME].color.fg = COLOR_WHITE;
-       d[SI_BASENAME].color.bg = COLOR_BLUE;
-       d[SI_BASENAME].align = CENTER;
-       d[SI_BASENAME].x = 0;
-       d[SI_BASENAME].y = 7;
-       d[SI_BASENAME].len = 100;
-
-       d[SI_STATUS].prefix = "para_server: ";
-       d[SI_STATUS].postfix = "";
-       d[SI_STATUS].color.fg = COLOR_WHITE;
-       d[SI_STATUS].color.bg = COLOR_BLUE;
-       d[SI_STATUS].align = CENTER;
-       d[SI_STATUS].x = 0;
-       d[SI_STATUS].y = 60;
-       d[SI_STATUS].len = 50;
-
-       d[SI_AUDIOD_STATUS].prefix = "para_audiod: ";
-       d[SI_AUDIOD_STATUS].postfix = "";
-       d[SI_AUDIOD_STATUS].color.fg = COLOR_WHITE;
-       d[SI_AUDIOD_STATUS].color.bg = COLOR_BLUE;
-       d[SI_AUDIOD_STATUS].align = CENTER;
-       d[SI_AUDIOD_STATUS].x = 50;
-       d[SI_AUDIOD_STATUS].y = 60;
-       d[SI_AUDIOD_STATUS].len = 50;
+       d[SI_basename].prefix = "";
+       d[SI_basename].postfix = "";
+       d[SI_basename].color.fg = COLOR_WHITE;
+       d[SI_basename].color.bg = COLOR_BLUE;
+       d[SI_basename].align = CENTER;
+       d[SI_basename].x = 0;
+       d[SI_basename].y = 7;
+       d[SI_basename].len = 100;
+
+       d[SI_status].prefix = "para_server: ";
+       d[SI_status].postfix = "";
+       d[SI_status].color.fg = COLOR_WHITE;
+       d[SI_status].color.bg = COLOR_BLUE;
+       d[SI_status].align = CENTER;
+       d[SI_status].x = 0;
+       d[SI_status].y = 60;
+       d[SI_status].len = 50;
+
+       d[SI_audiod_status].prefix = "para_audiod: ";
+       d[SI_audiod_status].postfix = "";
+       d[SI_audiod_status].color.fg = COLOR_WHITE;
+       d[SI_audiod_status].color.bg = COLOR_BLUE;
+       d[SI_audiod_status].align = CENTER;
+       d[SI_audiod_status].x = 50;
+       d[SI_audiod_status].y = 60;
+       d[SI_audiod_status].len = 50;
 
 }
 
@@ -92,266 +92,266 @@ static void init_theme_colorful_blackness(struct gui_theme *t)
        t->dflt.fg = COLOR_MAGENTA;
 
 
-       d[SI_PLAY_TIME].prefix = "";
-       d[SI_PLAY_TIME].postfix = "";
-       d[SI_PLAY_TIME].color.fg = COLOR_CYAN;
-       d[SI_PLAY_TIME].color.bg = COLOR_BLACK;
-       d[SI_PLAY_TIME].align = CENTER;
-       d[SI_PLAY_TIME].x = 0;
-       d[SI_PLAY_TIME].y = 7;
-       d[SI_PLAY_TIME].len = 35;
-
-       d[SI_BASENAME].prefix = "";
-       d[SI_BASENAME].postfix = "";
-       d[SI_BASENAME].color.fg = COLOR_CYAN;
-       d[SI_BASENAME].color.bg = COLOR_BLACK;
-       d[SI_BASENAME].align = LEFT;
-       d[SI_BASENAME].x = 35;
-       d[SI_BASENAME].y = 7;
-       d[SI_BASENAME].len = 65;
-
-       d[SI_STATUS].prefix = "";
-       d[SI_STATUS].postfix = " ";
-       d[SI_STATUS].color.fg = COLOR_RED;
-       d[SI_STATUS].color.bg = COLOR_BLACK;
-       d[SI_STATUS].align = RIGHT;
-       d[SI_STATUS].x = 0;
-       d[SI_STATUS].y = 17;
-       d[SI_STATUS].len = 11;
-
-       d[SI_STATUS_FLAGS].prefix = "(";
-       d[SI_STATUS_FLAGS].postfix = ")";
-       d[SI_STATUS_FLAGS].color.fg = COLOR_RED;
-       d[SI_STATUS_FLAGS].color.bg = COLOR_BLACK;
-       d[SI_STATUS_FLAGS].align = LEFT;
-       d[SI_STATUS_FLAGS].x = 11;
-       d[SI_STATUS_FLAGS].y = 17;
-       d[SI_STATUS_FLAGS].len = 10;
-
-       d[SI_IMAGE_ID].prefix = "img: ";
-       d[SI_IMAGE_ID].postfix = "";
-       d[SI_IMAGE_ID].color.fg = COLOR_RED;
-       d[SI_IMAGE_ID].color.bg = COLOR_BLACK;
-       d[SI_IMAGE_ID].align = CENTER;
-       d[SI_IMAGE_ID].x = 21;
-       d[SI_IMAGE_ID].y = 17;
-       d[SI_IMAGE_ID].len = 10;
-
-       d[SI_LYRICS_ID].prefix = "lyr: ";
-       d[SI_LYRICS_ID].postfix = "";
-       d[SI_LYRICS_ID].color.fg = COLOR_RED;
-       d[SI_LYRICS_ID].color.bg = COLOR_BLACK;
-       d[SI_LYRICS_ID].align = CENTER;
-       d[SI_LYRICS_ID].x = 31;
-       d[SI_LYRICS_ID].y = 17;
-       d[SI_LYRICS_ID].len = 11;
-
-       d[SI_FORMAT].prefix = "format: ";
-       d[SI_FORMAT].postfix = "";
-       d[SI_FORMAT].color.fg = COLOR_RED;
-       d[SI_FORMAT].color.bg = COLOR_BLACK;
-       d[SI_FORMAT].align = CENTER;
-       d[SI_FORMAT].x = 42;
-       d[SI_FORMAT].y = 17;
-       d[SI_FORMAT].len = 18;
-
-       d[SI_NUM_PLAYED].prefix = "#";
-       d[SI_NUM_PLAYED].postfix = "";
-       d[SI_NUM_PLAYED].color.fg = COLOR_RED;
-       d[SI_NUM_PLAYED].color.bg = COLOR_BLACK;
-       d[SI_NUM_PLAYED].align = LEFT;
-       d[SI_NUM_PLAYED].x = 60;
-       d[SI_NUM_PLAYED].y = 17;
-       d[SI_NUM_PLAYED].len = 5;
-
-       d[SI_BITRATE].prefix = "";
-       d[SI_BITRATE].postfix = "";
-       d[SI_BITRATE].color.fg = COLOR_RED;
-       d[SI_BITRATE].color.bg = COLOR_BLACK;
-       d[SI_BITRATE].align = CENTER;
-       d[SI_BITRATE].x = 65;
-       d[SI_BITRATE].y = 17;
-       d[SI_BITRATE].len = 13;
-
-       d[SI_FREQUENCY].prefix = "";
-       d[SI_FREQUENCY].postfix = "";
-       d[SI_FREQUENCY].color.fg = COLOR_RED;
-       d[SI_FREQUENCY].color.bg = COLOR_BLACK;
-       d[SI_FREQUENCY].align = CENTER;
-       d[SI_FREQUENCY].x = 78;
-       d[SI_FREQUENCY].y = 17;
-       d[SI_FREQUENCY].len = 10;
-
-       d[SI_SCORE].prefix = "sc: ";
-       d[SI_SCORE].postfix = "";
-       d[SI_SCORE].color.fg = COLOR_RED;
-       d[SI_SCORE].color.bg = COLOR_BLACK;
-       d[SI_SCORE].align = CENTER;
-       d[SI_SCORE].x = 88;
-       d[SI_SCORE].y = 17;
-       d[SI_SCORE].len = 10;
-
-       d[SI_AUDIOD_STATUS].prefix = "";
-       d[SI_AUDIOD_STATUS].postfix = "";
-       d[SI_AUDIOD_STATUS].color.fg = COLOR_MAGENTA;
-       d[SI_AUDIOD_STATUS].color.bg = COLOR_BLACK;
-       d[SI_AUDIOD_STATUS].align = CENTER;
-       d[SI_AUDIOD_STATUS].x = 0;
-       d[SI_AUDIOD_STATUS].y = 27;
-       d[SI_AUDIOD_STATUS].len = 5;
-
-       d[SI_DECODER_FLAGS].prefix = "[";
-       d[SI_DECODER_FLAGS].postfix = "]";
-       d[SI_DECODER_FLAGS].color.fg = COLOR_MAGENTA;
-       d[SI_DECODER_FLAGS].color.bg = COLOR_BLACK;
-       d[SI_DECODER_FLAGS].align = CENTER;
-       d[SI_DECODER_FLAGS].x = 5;
-       d[SI_DECODER_FLAGS].y = 27;
-       d[SI_DECODER_FLAGS].len = 10;
-
-       d[SI_MTIME].prefix = "mod: ";
-       d[SI_MTIME].postfix = "";
-       d[SI_MTIME].color.fg = COLOR_MAGENTA;
-       d[SI_MTIME].color.bg = COLOR_BLACK;
-       d[SI_MTIME].align = CENTER;
-       d[SI_MTIME].x = 15;
-       d[SI_MTIME].y = 27;
-       d[SI_MTIME].len = 22;
-
-       d[SI_FILE_SIZE].prefix = "";
-       d[SI_FILE_SIZE].postfix = "kb";
-       d[SI_FILE_SIZE].color.fg = COLOR_MAGENTA;
-       d[SI_FILE_SIZE].color.bg = COLOR_BLACK;
-       d[SI_FILE_SIZE].align = CENTER;
-       d[SI_FILE_SIZE].x = 37;
-       d[SI_FILE_SIZE].y = 27;
-       d[SI_FILE_SIZE].len = 10;
-
-       d[SI_CHANNELS].prefix = "";
-       d[SI_CHANNELS].postfix = "ch";
-       d[SI_CHANNELS].color.fg = COLOR_MAGENTA;
-       d[SI_CHANNELS].color.bg = COLOR_BLACK;
-       d[SI_CHANNELS].align = CENTER;
-       d[SI_CHANNELS].x = 47;
-       d[SI_CHANNELS].y = 27;
-       d[SI_CHANNELS].len = 5;
-
-       d[SI_LAST_PLAYED].prefix = "lp: ";
-       d[SI_LAST_PLAYED].postfix = "";
-       d[SI_LAST_PLAYED].color.fg = COLOR_MAGENTA;
-       d[SI_LAST_PLAYED].color.bg = COLOR_BLACK;
-       d[SI_LAST_PLAYED].align = CENTER;
-       d[SI_LAST_PLAYED].x = 52;
-       d[SI_LAST_PLAYED].y = 27;
-       d[SI_LAST_PLAYED].len = 21;
-
-       d[SI_NUM_CHUNKS].prefix = "";
-       d[SI_NUM_CHUNKS].postfix = "x";
-       d[SI_NUM_CHUNKS].color.fg = COLOR_MAGENTA;
-       d[SI_NUM_CHUNKS].color.bg = COLOR_BLACK;
-       d[SI_NUM_CHUNKS].align = RIGHT;
-       d[SI_NUM_CHUNKS].x = 73;
-       d[SI_NUM_CHUNKS].y = 27;
-       d[SI_NUM_CHUNKS].len = 11;
-
-       d[SI_CHUNK_TIME].prefix = "";
-       d[SI_CHUNK_TIME].postfix = "ms";
-       d[SI_CHUNK_TIME].color.fg = COLOR_MAGENTA;
-       d[SI_CHUNK_TIME].color.bg = COLOR_BLACK;
-       d[SI_CHUNK_TIME].align = LEFT;
-       d[SI_CHUNK_TIME].x = 84;
-       d[SI_CHUNK_TIME].y = 27;
-       d[SI_CHUNK_TIME].len = 8;
-
-       d[SI_AMPLIFICATION].prefix = "amp:";
-       d[SI_AMPLIFICATION].postfix = "";
-       d[SI_AMPLIFICATION].color.fg = COLOR_MAGENTA;
-       d[SI_AMPLIFICATION].color.bg = COLOR_BLACK;
-       d[SI_AMPLIFICATION].align = RIGHT;
-       d[SI_AMPLIFICATION].x = 92;
-       d[SI_AMPLIFICATION].y = 27;
-       d[SI_AMPLIFICATION].len = 8;
-
-       d[SI_TECHINFO].prefix = "";
-       d[SI_TECHINFO].postfix = "";
-       d[SI_TECHINFO].color.fg = COLOR_GREEN;
-       d[SI_TECHINFO].color.bg = COLOR_BLACK;
-       d[SI_TECHINFO].align = CENTER;
-       d[SI_TECHINFO].x = 0;
-       d[SI_TECHINFO].y = 43;
-       d[SI_TECHINFO].len = 100;
-
-       d[SI_TITLE].prefix = "";
-       d[SI_TITLE].postfix = ",";
-       d[SI_TITLE].color.fg = COLOR_GREEN;
-       d[SI_TITLE].color.bg = COLOR_BLACK;
-       d[SI_TITLE].align = RIGHT;
-       d[SI_TITLE].x = 0;
-       d[SI_TITLE].y = 53;
-       d[SI_TITLE].len = 45;
-
-       d[SI_ARTIST].prefix = " by ";
-       d[SI_ARTIST].postfix = "";
-       d[SI_ARTIST].color.fg = COLOR_GREEN;
-       d[SI_ARTIST].color.bg = COLOR_BLACK;
-       d[SI_ARTIST].align = LEFT;
-       d[SI_ARTIST].x = 45;
-       d[SI_ARTIST].y = 53;
-       d[SI_ARTIST].len = 45;
-
-       d[SI_YEAR].prefix = "(";
-       d[SI_YEAR].postfix = ")";
-       d[SI_YEAR].color.fg = COLOR_GREEN;
-       d[SI_YEAR].color.bg = COLOR_BLACK;
-       d[SI_YEAR].align = RIGHT;
-       d[SI_YEAR].x = 90;
-       d[SI_YEAR].y = 53;
-       d[SI_YEAR].len = 10;
-
-       d[SI_ALBUM].prefix = "A: ";
-       d[SI_ALBUM].postfix = ",";
-       d[SI_ALBUM].color.fg = COLOR_GREEN;
-       d[SI_ALBUM].color.bg = COLOR_BLACK;
-       d[SI_ALBUM].align = RIGHT;
-       d[SI_ALBUM].x = 0;
-       d[SI_ALBUM].y = 63;
-       d[SI_ALBUM].len = 50;
-
-       d[SI_COMMENT].prefix = " C: ";
-       d[SI_COMMENT].postfix = "";
-       d[SI_COMMENT].color.fg = COLOR_GREEN;
-       d[SI_COMMENT].color.bg = COLOR_BLACK;
-       d[SI_COMMENT].align = LEFT;
-       d[SI_COMMENT].x = 50;
-       d[SI_COMMENT].y = 63;
-       d[SI_COMMENT].len = 50;
-
-       d[SI_AFS_MODE].prefix = "";
-       d[SI_AFS_MODE].postfix = "";
-       d[SI_AFS_MODE].color.fg = COLOR_YELLOW;
-       d[SI_AFS_MODE].color.bg = COLOR_BLACK;
-       d[SI_AFS_MODE].align = CENTER;
-       d[SI_AFS_MODE].x = 0;
-       d[SI_AFS_MODE].y = 77;
-       d[SI_AFS_MODE].len = 100;
-
-       d[SI_ATTRIBUTES_TXT].prefix = "";
-       d[SI_ATTRIBUTES_TXT].postfix = "";
-       d[SI_ATTRIBUTES_TXT].color.fg = COLOR_YELLOW;
-       d[SI_ATTRIBUTES_TXT].color.bg = COLOR_BLACK;
-       d[SI_ATTRIBUTES_TXT].align = CENTER;
-       d[SI_ATTRIBUTES_TXT].x = 0;
-       d[SI_ATTRIBUTES_TXT].y = 87;
-       d[SI_ATTRIBUTES_TXT].len = 100;
-
-       d[SI_DIRECTORY].prefix = "dir: ";
-       d[SI_DIRECTORY].postfix = "";
-       d[SI_DIRECTORY].color.fg = COLOR_YELLOW;
-       d[SI_DIRECTORY].color.bg = COLOR_BLACK;
-       d[SI_DIRECTORY].align = CENTER;
-       d[SI_DIRECTORY].x = 0;
-       d[SI_DIRECTORY].y = 97;
-       d[SI_DIRECTORY].len = 100;
+       d[SI_play_time].prefix = "";
+       d[SI_play_time].postfix = "";
+       d[SI_play_time].color.fg = COLOR_CYAN;
+       d[SI_play_time].color.bg = COLOR_BLACK;
+       d[SI_play_time].align = CENTER;
+       d[SI_play_time].x = 0;
+       d[SI_play_time].y = 7;
+       d[SI_play_time].len = 35;
+
+       d[SI_basename].prefix = "";
+       d[SI_basename].postfix = "";
+       d[SI_basename].color.fg = COLOR_CYAN;
+       d[SI_basename].color.bg = COLOR_BLACK;
+       d[SI_basename].align = LEFT;
+       d[SI_basename].x = 35;
+       d[SI_basename].y = 7;
+       d[SI_basename].len = 65;
+
+       d[SI_status].prefix = "";
+       d[SI_status].postfix = " ";
+       d[SI_status].color.fg = COLOR_RED;
+       d[SI_status].color.bg = COLOR_BLACK;
+       d[SI_status].align = RIGHT;
+       d[SI_status].x = 0;
+       d[SI_status].y = 17;
+       d[SI_status].len = 11;
+
+       d[SI_status_flags].prefix = "(";
+       d[SI_status_flags].postfix = ")";
+       d[SI_status_flags].color.fg = COLOR_RED;
+       d[SI_status_flags].color.bg = COLOR_BLACK;
+       d[SI_status_flags].align = LEFT;
+       d[SI_status_flags].x = 11;
+       d[SI_status_flags].y = 17;
+       d[SI_status_flags].len = 10;
+
+       d[SI_image_id].prefix = "img: ";
+       d[SI_image_id].postfix = "";
+       d[SI_image_id].color.fg = COLOR_RED;
+       d[SI_image_id].color.bg = COLOR_BLACK;
+       d[SI_image_id].align = CENTER;
+       d[SI_image_id].x = 21;
+       d[SI_image_id].y = 17;
+       d[SI_image_id].len = 10;
+
+       d[SI_lyrics_id].prefix = "lyr: ";
+       d[SI_lyrics_id].postfix = "";
+       d[SI_lyrics_id].color.fg = COLOR_RED;
+       d[SI_lyrics_id].color.bg = COLOR_BLACK;
+       d[SI_lyrics_id].align = CENTER;
+       d[SI_lyrics_id].x = 31;
+       d[SI_lyrics_id].y = 17;
+       d[SI_lyrics_id].len = 11;
+
+       d[SI_format].prefix = "format: ";
+       d[SI_format].postfix = "";
+       d[SI_format].color.fg = COLOR_RED;
+       d[SI_format].color.bg = COLOR_BLACK;
+       d[SI_format].align = CENTER;
+       d[SI_format].x = 42;
+       d[SI_format].y = 17;
+       d[SI_format].len = 18;
+
+       d[SI_num_played].prefix = "#";
+       d[SI_num_played].postfix = "";
+       d[SI_num_played].color.fg = COLOR_RED;
+       d[SI_num_played].color.bg = COLOR_BLACK;
+       d[SI_num_played].align = LEFT;
+       d[SI_num_played].x = 60;
+       d[SI_num_played].y = 17;
+       d[SI_num_played].len = 5;
+
+       d[SI_bitrate].prefix = "";
+       d[SI_bitrate].postfix = "";
+       d[SI_bitrate].color.fg = COLOR_RED;
+       d[SI_bitrate].color.bg = COLOR_BLACK;
+       d[SI_bitrate].align = CENTER;
+       d[SI_bitrate].x = 65;
+       d[SI_bitrate].y = 17;
+       d[SI_bitrate].len = 13;
+
+       d[SI_frequency].prefix = "";
+       d[SI_frequency].postfix = "";
+       d[SI_frequency].color.fg = COLOR_RED;
+       d[SI_frequency].color.bg = COLOR_BLACK;
+       d[SI_frequency].align = CENTER;
+       d[SI_frequency].x = 78;
+       d[SI_frequency].y = 17;
+       d[SI_frequency].len = 10;
+
+       d[SI_score].prefix = "sc: ";
+       d[SI_score].postfix = "";
+       d[SI_score].color.fg = COLOR_RED;
+       d[SI_score].color.bg = COLOR_BLACK;
+       d[SI_score].align = CENTER;
+       d[SI_score].x = 88;
+       d[SI_score].y = 17;
+       d[SI_score].len = 10;
+
+       d[SI_audiod_status].prefix = "";
+       d[SI_audiod_status].postfix = "";
+       d[SI_audiod_status].color.fg = COLOR_MAGENTA;
+       d[SI_audiod_status].color.bg = COLOR_BLACK;
+       d[SI_audiod_status].align = CENTER;
+       d[SI_audiod_status].x = 0;
+       d[SI_audiod_status].y = 27;
+       d[SI_audiod_status].len = 5;
+
+       d[SI_decoder_flags].prefix = "[";
+       d[SI_decoder_flags].postfix = "]";
+       d[SI_decoder_flags].color.fg = COLOR_MAGENTA;
+       d[SI_decoder_flags].color.bg = COLOR_BLACK;
+       d[SI_decoder_flags].align = CENTER;
+       d[SI_decoder_flags].x = 5;
+       d[SI_decoder_flags].y = 27;
+       d[SI_decoder_flags].len = 10;
+
+       d[SI_mtime].prefix = "mod: ";
+       d[SI_mtime].postfix = "";
+       d[SI_mtime].color.fg = COLOR_MAGENTA;
+       d[SI_mtime].color.bg = COLOR_BLACK;
+       d[SI_mtime].align = CENTER;
+       d[SI_mtime].x = 15;
+       d[SI_mtime].y = 27;
+       d[SI_mtime].len = 22;
+
+       d[SI_file_size].prefix = "";
+       d[SI_file_size].postfix = "kb";
+       d[SI_file_size].color.fg = COLOR_MAGENTA;
+       d[SI_file_size].color.bg = COLOR_BLACK;
+       d[SI_file_size].align = CENTER;
+       d[SI_file_size].x = 37;
+       d[SI_file_size].y = 27;
+       d[SI_file_size].len = 10;
+
+       d[SI_channels].prefix = "";
+       d[SI_channels].postfix = "ch";
+       d[SI_channels].color.fg = COLOR_MAGENTA;
+       d[SI_channels].color.bg = COLOR_BLACK;
+       d[SI_channels].align = CENTER;
+       d[SI_channels].x = 47;
+       d[SI_channels].y = 27;
+       d[SI_channels].len = 5;
+
+       d[SI_last_played].prefix = "lp: ";
+       d[SI_last_played].postfix = "";
+       d[SI_last_played].color.fg = COLOR_MAGENTA;
+       d[SI_last_played].color.bg = COLOR_BLACK;
+       d[SI_last_played].align = CENTER;
+       d[SI_last_played].x = 52;
+       d[SI_last_played].y = 27;
+       d[SI_last_played].len = 21;
+
+       d[SI_num_chunks].prefix = "";
+       d[SI_num_chunks].postfix = "x";
+       d[SI_num_chunks].color.fg = COLOR_MAGENTA;
+       d[SI_num_chunks].color.bg = COLOR_BLACK;
+       d[SI_num_chunks].align = RIGHT;
+       d[SI_num_chunks].x = 73;
+       d[SI_num_chunks].y = 27;
+       d[SI_num_chunks].len = 11;
+
+       d[SI_chunk_time].prefix = "";
+       d[SI_chunk_time].postfix = "ms";
+       d[SI_chunk_time].color.fg = COLOR_MAGENTA;
+       d[SI_chunk_time].color.bg = COLOR_BLACK;
+       d[SI_chunk_time].align = LEFT;
+       d[SI_chunk_time].x = 84;
+       d[SI_chunk_time].y = 27;
+       d[SI_chunk_time].len = 8;
+
+       d[SI_amplification].prefix = "amp:";
+       d[SI_amplification].postfix = "";
+       d[SI_amplification].color.fg = COLOR_MAGENTA;
+       d[SI_amplification].color.bg = COLOR_BLACK;
+       d[SI_amplification].align = RIGHT;
+       d[SI_amplification].x = 92;
+       d[SI_amplification].y = 27;
+       d[SI_amplification].len = 8;
+
+       d[SI_techinfo].prefix = "";
+       d[SI_techinfo].postfix = "";
+       d[SI_techinfo].color.fg = COLOR_GREEN;
+       d[SI_techinfo].color.bg = COLOR_BLACK;
+       d[SI_techinfo].align = CENTER;
+       d[SI_techinfo].x = 0;
+       d[SI_techinfo].y = 43;
+       d[SI_techinfo].len = 100;
+
+       d[SI_title].prefix = "";
+       d[SI_title].postfix = ",";
+       d[SI_title].color.fg = COLOR_GREEN;
+       d[SI_title].color.bg = COLOR_BLACK;
+       d[SI_title].align = RIGHT;
+       d[SI_title].x = 0;
+       d[SI_title].y = 53;
+       d[SI_title].len = 45;
+
+       d[SI_artist].prefix = " by ";
+       d[SI_artist].postfix = "";
+       d[SI_artist].color.fg = COLOR_GREEN;
+       d[SI_artist].color.bg = COLOR_BLACK;
+       d[SI_artist].align = LEFT;
+       d[SI_artist].x = 45;
+       d[SI_artist].y = 53;
+       d[SI_artist].len = 45;
+
+       d[SI_year].prefix = "(";
+       d[SI_year].postfix = ")";
+       d[SI_year].color.fg = COLOR_GREEN;
+       d[SI_year].color.bg = COLOR_BLACK;
+       d[SI_year].align = RIGHT;
+       d[SI_year].x = 90;
+       d[SI_year].y = 53;
+       d[SI_year].len = 10;
+
+       d[SI_album].prefix = "A: ";
+       d[SI_album].postfix = ",";
+       d[SI_album].color.fg = COLOR_GREEN;
+       d[SI_album].color.bg = COLOR_BLACK;
+       d[SI_album].align = RIGHT;
+       d[SI_album].x = 0;
+       d[SI_album].y = 63;
+       d[SI_album].len = 50;
+
+       d[SI_comment].prefix = " C: ";
+       d[SI_comment].postfix = "";
+       d[SI_comment].color.fg = COLOR_GREEN;
+       d[SI_comment].color.bg = COLOR_BLACK;
+       d[SI_comment].align = LEFT;
+       d[SI_comment].x = 50;
+       d[SI_comment].y = 63;
+       d[SI_comment].len = 50;
+
+       d[SI_afs_mode].prefix = "";
+       d[SI_afs_mode].postfix = "";
+       d[SI_afs_mode].color.fg = COLOR_YELLOW;
+       d[SI_afs_mode].color.bg = COLOR_BLACK;
+       d[SI_afs_mode].align = CENTER;
+       d[SI_afs_mode].x = 0;
+       d[SI_afs_mode].y = 77;
+       d[SI_afs_mode].len = 100;
+
+       d[SI_attributes_txt].prefix = "";
+       d[SI_attributes_txt].postfix = "";
+       d[SI_attributes_txt].color.fg = COLOR_YELLOW;
+       d[SI_attributes_txt].color.bg = COLOR_BLACK;
+       d[SI_attributes_txt].align = CENTER;
+       d[SI_attributes_txt].x = 0;
+       d[SI_attributes_txt].y = 87;
+       d[SI_attributes_txt].len = 100;
+
+       d[SI_directory].prefix = "dir: ";
+       d[SI_directory].postfix = "";
+       d[SI_directory].color.fg = COLOR_YELLOW;
+       d[SI_directory].color.bg = COLOR_BLACK;
+       d[SI_directory].align = CENTER;
+       d[SI_directory].x = 0;
+       d[SI_directory].y = 97;
+       d[SI_directory].len = 100;
 }
 
 struct theme_description {
index cf3965e6fb09bcaea4015618e8ffe7346738473f..dd86b51def8cfbeff487def5d883e3a88e0f9078 100644 (file)
@@ -3,27 +3,27 @@ lls_m4_include_dir := $(lls_m4_dir)/include
 
 $(lls_suite_dir)/%.m4d: $(lls_m4_dir)/%.suite.m4 | $(lls_suite_dir)
        @[ -z "$(Q)" ] || echo 'M4D $<'
-
        $(Q) $(M4) -Pg -I $(lls_m4_include_dir) -s $< \
        | awk '{if ($$1 ~ /#line/) {gsub(/"/, "", $$3); if ($$3 != "$<") \
        print "$(lls_suite_dir)/$(*F).suite: " $$3}}' | sort | uniq > $@
 
 $(lls_suite_dir)/%.suite: $(lls_m4_dir)/%.suite.m4 | $(lls_suite_dir)
+       @[ -z "$(Q)" ] || echo 'M4 $<'
        $(Q) $(M4) -Pg -I $(lls_m4_include_dir) -D GIT_VERSION=$(GIT_VERSION) \
                -D COPYRIGHT_YEAR=$(COPYRIGHT_YEAR) -D LOGLEVELS=$(LOGLEVELS) \
                $< > $@
 
 $(lls_suite_dir)/%.lsg.c: $(lls_suite_dir)/%.suite
        @[ -z "$(Q)" ] || echo 'LSGC $<'
-       $(Q) lopsubgen --gen-c --output-dir $(lls_suite_dir) < $<
+       $(Q) $(LOPSUBGEN) --gen-c --output-dir $(lls_suite_dir) < $<
 
 $(lls_suite_dir)/%.lsg.h: $(lls_suite_dir)/%.suite
        @[ -z "$(Q)" ] || echo 'LSGH $<'
-       $(Q) lopsubgen --gen-header --output-dir $(lls_suite_dir) < $<
+       $(Q) $(LOPSUBGEN) --gen-header --output-dir $(lls_suite_dir) < $<
 
 $(lls_suite_dir)/%.lsg.man: $(lls_suite_dir)/%.suite
        @[ -z "$(Q)" ] || echo 'LSGM $<'
-       $(Q) lopsubgen --gen-man --output-dir $(lls_suite_dir) < $<
+       $(Q) $(LOPSUBGEN) --gen-man --output-dir $(lls_suite_dir) < $<
 
 $(object_dir)/%.o: $(lls_suite_dir)/%.c | $(object_dir)
        @[ -z "$(Q)" ] || echo 'CC $<'
index 5ac7f16afa6888f97488e8c5d4dd6a7db0d94a64..2145c516a5a5f0f0666bf75419ffd44d38ce311a 100644 (file)
@@ -219,13 +219,6 @@ aux_info_prefix = Permissions:
                        also given), chunk time and chunk offsets.
 
                [/help]
-       [option full-path]
-               short_opt = F
-               summary = list full paths, match full paths against patterns
-               [help]
-                       This option is the default, so it does nothing. Deprecated as of
-                       v0.6.0, scheduled for removal in v0.6.1.
-               [/help]
        [option basename]
                short_opt = b
                summary = list and match basenames only
diff --git a/mood.c b/mood.c
index e9c5bd6e0e60ca55e5fc3bb4e67234bdf51fc193..bbe3a8ae08c65748c1414b6f16fe91bda669b32e 100644 (file)
--- a/mood.c
+++ b/mood.c
 #include "afh.h"
 #include "afs.h"
 #include "list.h"
-#include "ipc.h"
 #include "mm.h"
-#include "sideband.h"
 #include "mood.h"
-#include "sched.h"
 
 /**
  * Contains statistical data of the currently admissible audio files.
@@ -391,9 +388,7 @@ success:
        ret = 1;
 out:
        free_argv(argv);
-       if (ret >= 0)
-               return ret;
-       if (mi) {
+       if (mi && (ret < 0 || !mlpd->m)) { /* mi was not added to any list */
                free(mi->parser_data);
                free(mi);
        }
index cb0611e01440a2a1e23e4c586a602c16cb7bbc16..8d8cadc7c81d8a7030778ee17e6bff6ba01f9a83 100644 (file)
--- a/ogg_afh.c
+++ b/ogg_afh.c
@@ -66,45 +66,24 @@ static int ogg_vorbis_get_file_info(char *map, size_t numbytes, __a_unused int f
 {
        int ret;
        struct private_vorbis_data pvd;
-       struct ogg_afh_callback_info vorbis_callback_info = {
+       struct oac_callback_info vorbis_callback_info = {
                .packet_callback = vorbis_packet_callback,
                .private_data = &pvd,
        };
 
        vorbis_info_init(&pvd.vi);
        vorbis_comment_init(&pvd.vc);
-       ret = ogg_get_file_info(map, numbytes, afhi, &vorbis_callback_info);
+       ret = oac_get_file_info(map, numbytes, afhi, &vorbis_callback_info);
        vorbis_info_clear(&pvd.vi);
        vorbis_comment_clear(&pvd.vc);
        return ret;
 }
 
-struct vorbis_get_header_data {
-       ogg_stream_state os;
-       char *buf;
-       size_t len;
-};
-
-static void add_ogg_page(ogg_page *og, struct vorbis_get_header_data *vghd)
-{
-       size_t old_len = vghd->len;
-       size_t new_len = vghd->len + og->header_len + og->body_len;
-       char *buf = para_realloc(vghd->buf, new_len), *p = buf + old_len;
-
-       memcpy(p, og->header, og->header_len);
-       memcpy(p + og->header_len, og->body, og->body_len);
-       vghd->buf = buf;
-       vghd->len = new_len;
-       PARA_DEBUG_LOG("header/body/old/new: %li/%li/%zu/%zu\n",
-               og->header_len, og->body_len, old_len, new_len);
-}
-
 static int vorbis_get_header_callback(ogg_packet *packet, int packet_num,
                int serial, __a_unused struct afh_info *afhi, void *private_data)
 {
        int ret;
-       struct vorbis_get_header_data *vghd = private_data;
-       ogg_page og;
+       struct oac_custom_header *h = private_data;
        static unsigned char dummy_packet[] = {
                0x03,
                'v', 'o', 'r', 'b', 'i', 's',
@@ -115,17 +94,12 @@ static int vorbis_get_header_callback(ogg_packet *packet, int packet_num,
        };
 
        PARA_DEBUG_LOG("processing ogg packet #%d\n", packet_num);
-       if (packet_num > 2)
-               return 0;
        if (packet_num == 0) {
-               ogg_stream_init(&vghd->os, serial);
-               ret = ogg_stream_packetin(&vghd->os, packet);
+               oac_custom_header_init(serial, h);
+               ret = oac_custom_header_append(packet, h);
                if (ret < 0)
-                       goto out;
-               ret = -E_OGG_STREAM_FLUSH;
-               if (ogg_stream_flush(&vghd->os, &og) == 0)
-                       goto out;
-               add_ogg_page(&og, vghd);
+                       return ret;
+               oac_custom_header_flush(h);
                return 1;
        }
        if (packet_num == 1) {
@@ -133,42 +107,37 @@ static int vorbis_get_header_callback(ogg_packet *packet, int packet_num,
                PARA_INFO_LOG("replacing metadata packet\n");
                replacement.packet = dummy_packet;
                replacement.bytes = sizeof(dummy_packet);
-               ret = ogg_stream_packetin(&vghd->os, &replacement);
-               if (ret >= 0)
-                       return 1;
-               ret = -E_OGG_PACKET_IN;
-               goto out;
+               ret = oac_custom_header_append(&replacement, h);
+               return ret < 0? ret : 1;
        }
-       ret = -E_OGG_PACKET_IN;
-       if (ogg_stream_packetin(&vghd->os, packet) < 0)
-               goto out;
-       while (ogg_stream_flush(&vghd->os, &og))
-               add_ogg_page(&og, vghd);
-       ret = 0;
-out:
-       ogg_stream_clear(&vghd->os);
-       return ret;
+       assert(packet_num == 2);
+       ret = oac_custom_header_append(packet, h);
+       if (ret < 0)
+               return ret;
+       oac_custom_header_flush(h);
+       return 0;
 }
 
 static void vorbis_get_header(void *map, size_t mapsize, char **buf,
                size_t *len)
 {
        int ret;
-       struct vorbis_get_header_data vghd = {.len = 0};
-       struct ogg_afh_callback_info cb = {
+       struct oac_custom_header *h = oac_custom_header_new();
+       struct oac_callback_info cb = {
                .packet_callback = vorbis_get_header_callback,
-               .private_data = &vghd,
+               .private_data = h,
        };
 
-       ret = ogg_get_file_info(map, mapsize, NULL, &cb);
-       if (ret < 0)
-               goto fail;
-       *buf = vghd.buf;
-       *len = vghd.len;
-       PARA_INFO_LOG("created %zu byte ogg vorbis header\n", *len);
-       return;
-fail:
-       PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+       ret = oac_get_file_info(map, mapsize, NULL, &cb);
+       *len = oac_custom_header_get(buf, h);
+       if (ret < 0) {
+               PARA_ERROR_LOG("could not create ogg/vorbis header: %s\n",
+                       para_strerror(-ret));
+               free(*buf);
+               *buf = NULL;
+               *len = 0;
+       } else
+               PARA_INFO_LOG("created %zu byte ogg vorbis header\n", *len);
 }
 
 static int vorbis_make_meta_packet(struct taginfo *tags, ogg_packet *result)
@@ -199,7 +168,7 @@ static int vorbis_rewrite_tags(const char *map, size_t mapsize,
        ret = vorbis_make_meta_packet(tags, &packet);
        if (ret < 0)
                return ret;
-       ret = ogg_rewrite_tags(map, mapsize, output_fd, (char *)packet.packet,
+       ret = oac_rewrite_tags(map, mapsize, output_fd, (char *)packet.packet,
                packet.bytes);
        free(packet.packet);
        return ret;
index 734fd58680b1f944f6adf51c76aebb19d1b5b5c7..eb90c5f729d9f6d8271dbcb71942a835dea6d5a8 100644 (file)
@@ -19,7 +19,7 @@
 /* Taken from decoder_example.c of libvorbis-1.2.3. */
 static int process_packets_2_and_3(ogg_sync_state *oss,
                ogg_stream_state *stream, struct afh_info *afhi,
-               struct ogg_afh_callback_info *ci)
+               struct oac_callback_info *ci)
 {
        ogg_page page;
        ogg_packet packet;
@@ -60,7 +60,7 @@ static int process_packets_2_and_3(ogg_sync_state *oss,
 }
 
 static int process_ogg_packets(ogg_sync_state *oss, struct afh_info *afhi,
-               struct ogg_afh_callback_info *ci)
+               struct oac_callback_info *ci)
 {
        ogg_packet packet;
        ogg_stream_state stream;
@@ -122,8 +122,8 @@ static void set_chunk_tv(int frames_per_chunk, int frequency,
  *
  * \return Standard.
  */
-int ogg_get_file_info(char *map, size_t numbytes, struct afh_info *afhi,
-               struct ogg_afh_callback_info *ci)
+int oac_get_file_info(char *map, size_t numbytes, struct afh_info *afhi,
+               struct oac_callback_info *ci)
 {
        ogg_sync_state oss;
        ogg_page op;
@@ -216,7 +216,7 @@ static int write_ogg_page(int fd, const ogg_page *op)
  *
  * \return Standard.
  */
-int ogg_rewrite_tags(const char *map, size_t map_sz, int fd,
+int oac_rewrite_tags(const char *map, size_t map_sz, int fd,
                char *meta_packet, size_t meta_sz)
 {
        ogg_sync_state oss_in, oss_out;
@@ -332,3 +332,108 @@ out:
                ogg_stream_clear(so);
        return ret;
 }
+
+/* Structure for providing custom headers for streaming. */
+struct oac_custom_header {
+       char *buf;
+       size_t len;
+       ogg_stream_state oss;
+};
+
+/**
+ * Allocate and return a custom header structure.
+ *
+ * For some audio codecs which employ the ogg container format, the server side
+ * wants to replace the meta tags at the beginning of the file because they are
+ * not needed for streaming and can be arbitrary large. The structure returned
+ * by this function is typically used as the ->private field of struct \ref
+ * oac_callback_info for \ref oac_get_file_info(). This allows the audio format
+ * handler to set up a custom header which is identical to the original header,
+ * but with the meta data part replaced by fixed length dummy contents.
+ *
+ * \return The returned memory must be initialized with the serial number of
+ * the ogg stream before ogg packets can be submitted to it. This is not done
+ * here because the header structure is allocated before \ref
+ * oac_get_file_info() is called, and the serial number is not known at this
+ * point.
+ *
+ * \sa \ref oac_custom_header_init().
+ */
+struct oac_custom_header *oac_custom_header_new(void)
+{
+       return para_calloc(sizeof(struct oac_custom_header));
+}
+
+/**
+ * Set the serial number of an allocated header structure.
+ *
+ * \param serial Passed to the callback function.
+ * \param h As returned from \ref oac_custom_header_new().
+ *
+ * This function must be called before any packets are submitted.
+ */
+void oac_custom_header_init(int serial, struct oac_custom_header *h)
+{
+       ogg_stream_init(&h->oss, serial);
+}
+
+/**
+ * Submit an ogg packet to a custom header structure.
+ *
+ * \param op The packet to append.
+ * \param h Must be initialized.
+ *
+ * The packet may be the one which was passed to the callback, or a completely
+ * different one, like a dummy metadata packet.
+ *
+ * \return Standard.
+ */
+int oac_custom_header_append(ogg_packet *op, struct oac_custom_header *h)
+{
+       return ogg_stream_packetin(&h->oss, op) < 0? -E_OGG_PACKET_IN : 1;
+}
+
+/**
+ * Force remaining packets into an ogg page.
+ *
+ * \param h Should contain submitted but not yet flushed packets.
+ *
+ * This is called after the first packet has been submitted with \ref
+ * oac_custom_header_append() to make sure the first ogg page contains only
+ * this packet. Also when header processing is complete, the callbacks call
+ * this to force the previously submitted packets into a page.
+ */
+void oac_custom_header_flush(struct oac_custom_header *h)
+{
+       ogg_page og;
+
+       while (ogg_stream_flush(&h->oss, &og)) {
+               size_t len = og.header_len + og.body_len;
+               h->buf = para_realloc(h->buf, h->len + len);
+               memcpy(h->buf + h->len, og.header, og.header_len);
+               memcpy(h->buf + h->len + og.header_len, og.body, og.body_len);
+               h->len += len;
+       }
+}
+
+/**
+ * Return the custom header buffer and deallocate resources.
+ *
+ * This is called after the ogg packets which comprise the header have been
+ * submitted and flushed.
+ *
+ * \param buf Result pointer.
+ * \param h Must not be used any more after the call.
+ *
+ * \return The size of the header. This is the sum of the sizes of all ogg
+ * pages that have been flushed out.
+ */
+size_t oac_custom_header_get(char **buf, struct oac_custom_header *h)
+{
+       size_t ret = h->len;
+
+       *buf = h->buf;
+       ogg_stream_clear(&h->oss);
+       free(h);
+       return ret;
+}
index 7b9d1313af4816b79d1177c7898b94a70ee24775..8f3494a6689b2966e5d9e8e03c8c20276c35515e 100644 (file)
@@ -9,6 +9,12 @@
  * handlers that use the ogg container format.
  */
 
+struct oac_custom_header *oac_custom_header_new(void);
+void oac_custom_header_init(int serial, struct oac_custom_header *h);
+int oac_custom_header_append(ogg_packet *op, struct oac_custom_header *h);
+void oac_custom_header_flush(struct oac_custom_header *h);
+size_t oac_custom_header_get(char **buf, struct oac_custom_header *h);
+
 /**
  * Callback structure provided by audio format handlers.
  *
@@ -16,7 +22,7 @@
  * function whose purpose is to extract the meta information about the audio
  * file from the first few ogg packets of the bitstream.
  */
-struct ogg_afh_callback_info {
+struct oac_callback_info {
        /**
         * ogg_get_file_info() calls this function for the first three ogg
         * packets, or until the callback returns a non-positive value. If it
@@ -33,7 +39,7 @@ struct ogg_afh_callback_info {
        void *private_data;
 };
 
-int ogg_get_file_info(char *map, size_t numbytes, struct afh_info *afhi,
-               struct ogg_afh_callback_info *ci);
-int ogg_rewrite_tags(const char *map, size_t mapsize, int fd,
+int oac_get_file_info(char *map, size_t numbytes, struct afh_info *afhi,
+               struct oac_callback_info *ci);
+int oac_rewrite_tags(const char *map, size_t mapsize, int fd,
                char *meta_packet, size_t meta_sz);
index 64eeb03c1a4bd89bb64488495ed5d76c3ca322e9..53419243657e4d0e219d362693de0c55c52a2d5d 100644 (file)
@@ -84,6 +84,14 @@ static int opus_get_comments(char *comments, int length,
        return 1;
 }
 
+/*
+ * Ogg/Opus has two mandatory header packets:
+ *
+ * 1. ID header (identifies the stream as Opus). Dedicated "BOS" ogg page.
+ * 2. Comment header (metadata). May span multiple pages.
+ *
+ * See doc/draft-ietf-codec-oggopus.xml in the opus source tree for details.
+ */
 static int opus_packet_callback(ogg_packet *packet, int packet_num,
                __a_unused int serial, struct afh_info *afhi,
                void *private_data)
@@ -123,11 +131,11 @@ static int opus_get_file_info(char *map, size_t numbytes, __a_unused int fd,
        int ret, ms;
        struct opus_header oh = {.version = 0};
 
-       struct ogg_afh_callback_info opus_callback_info = {
+       struct oac_callback_info opus_callback_info = {
                .packet_callback = opus_packet_callback,
                .private_data = &oh,
        };
-       ret = ogg_get_file_info(map, numbytes, afhi, &opus_callback_info);
+       ret = oac_get_file_info(map, numbytes, afhi, &opus_callback_info);
        if (ret < 0)
                return ret;
        ret = (afhi->chunk_table[afhi->chunks_total] - afhi->chunk_table[0]) * 8; /* bits */
@@ -222,11 +230,70 @@ static int opus_rewrite_tags(const char *map, size_t mapsize,
        int ret;
 
        meta_sz = opus_make_meta_packet(tags, &meta_packet);
-       ret = ogg_rewrite_tags(map, mapsize, output_fd, meta_packet, meta_sz);
+       ret = oac_rewrite_tags(map, mapsize, output_fd, meta_packet, meta_sz);
        free(meta_packet);
        return ret;
 }
 
+/*
+ * See doc/draft-ietf-codec-oggopus.xml in the opus source tree for details
+ * about the format of the comment header.
+ */
+static int opus_get_header_callback(ogg_packet *packet, int packet_num,
+               int serial, __a_unused struct afh_info *afhi, void *private_data)
+{
+       struct oac_custom_header *h = private_data;
+       int ret;
+       static unsigned char dummy_tags[] = { /* a minimal comment header */
+               'O', 'p', 'u', 's', 'T', 'a', 'g', 's',
+               0x06, 0x00, 0x00, 0x00, /* vendor string length */
+               'd', 'u', 'm', 'm', 'y', '\0', /* vendor string */
+               0x00, 0x00, 0x00, 0x00, /* user comment list length */
+       };
+       ogg_packet replacement;
+
+       if (packet_num == 0) {
+               oac_custom_header_init(serial, h);
+               ret = oac_custom_header_append(packet, h);
+               if (ret < 0)
+                       return ret;
+               oac_custom_header_flush(h);
+               return 1;
+       }
+       assert(packet_num == 1);
+       PARA_INFO_LOG("replacing metadata packet\n");
+       replacement = *packet;
+       replacement.packet = dummy_tags;
+       replacement.bytes = sizeof(dummy_tags);
+       ret = oac_custom_header_append(&replacement, h);
+       if (ret < 0)
+               return ret;
+       oac_custom_header_flush(h);
+       return 0;
+}
+
+static void opus_get_header(void *map, size_t mapsize, char **buf,
+               size_t *len)
+{
+       int ret;
+       struct oac_custom_header *h = oac_custom_header_new();
+       struct oac_callback_info cb = {
+               .packet_callback = opus_get_header_callback,
+               .private_data = h,
+       };
+
+       ret = oac_get_file_info(map, mapsize, NULL, &cb);
+       *len = oac_custom_header_get(buf, h);
+       if (ret < 0) {
+               PARA_ERROR_LOG("could not create custom header: %s\n",
+                       para_strerror(-ret));
+               free(*buf);
+               *buf = NULL;
+               *len = 0;
+       } else
+               PARA_INFO_LOG("created %zu byte ogg/opus header\n", *len);
+}
+
 /**
  * The init function of the ogg/opus audio format handler.
  *
@@ -235,6 +302,7 @@ static int opus_rewrite_tags(const char *map, size_t mapsize,
 void opus_afh_init(struct audio_format_handler *afh)
 {
        afh->get_file_info = opus_get_file_info,
+       afh->get_header = opus_get_header;
        afh->suffixes = opus_suffixes;
        afh->rewrite_tags = opus_rewrite_tags;
 }
diff --git a/para.h b/para.h
index 3cd1b1621509330f0df7d6d6f7f1b02095a09153..323a4fb5bce74bac7a04448a0d6581296fd7c3e4 100644 (file)
--- a/para.h
+++ b/para.h
@@ -103,15 +103,6 @@ void compute_chunk_time(long unsigned chunk_num,
                struct timeval *result);
 struct timeval *clock_get_realtime(struct timeval *tv);
 
-/** The enum of all status items. */
-enum status_items {STATUS_ITEM_ENUM NUM_STAT_ITEMS};
-extern const char *status_item_list[];
-/** Loop over each status item. */
-#define FOR_EACH_STATUS_ITEM(i) for (i = 0; i < NUM_STAT_ITEMS; i++)
-int for_each_stat_item(char *item_buf, size_t num_bytes,
-       int (*item_handler)(int, char *));
-
-
 /**
  * Return a random non-negative integer in an interval.
  *
@@ -233,3 +224,57 @@ enum loglevels {LOGLEVELS, NUM_LOGLEVELS};
 #define PARA_ERROR_LOG(f,...) para_log(LL_ERROR, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
 #define PARA_CRIT_LOG(f,...) para_log(LL_CRIT, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
 #define PARA_EMERG_LOG(f,...) para_log(LL_EMERG, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
+
+#define STATUS_ITEMS \
+       STATUS_ITEM(basename) \
+       STATUS_ITEM(status) \
+       STATUS_ITEM(num_played) \
+       STATUS_ITEM(mtime) \
+       STATUS_ITEM(bitrate) \
+       STATUS_ITEM(frequency) \
+       STATUS_ITEM(file_size) \
+       STATUS_ITEM(status_flags) \
+       STATUS_ITEM(format) \
+       STATUS_ITEM(score) \
+       STATUS_ITEM(techinfo) \
+       STATUS_ITEM(afs_mode) \
+       STATUS_ITEM(attributes_txt) \
+       STATUS_ITEM(decoder_flags) \
+       STATUS_ITEM(audiod_status) \
+       STATUS_ITEM(play_time) \
+       STATUS_ITEM(attributes_bitmap) \
+       STATUS_ITEM(offset) \
+       STATUS_ITEM(seconds_total) \
+       STATUS_ITEM(stream_start) \
+       STATUS_ITEM(current_time) \
+       STATUS_ITEM(audiod_uptime) \
+       STATUS_ITEM(image_id) \
+       STATUS_ITEM(lyrics_id) \
+       STATUS_ITEM(duration) \
+       STATUS_ITEM(directory) \
+       STATUS_ITEM(lyrics_name) \
+       STATUS_ITEM(image_name) \
+       STATUS_ITEM(path) \
+       STATUS_ITEM(hash) \
+       STATUS_ITEM(channels) \
+       STATUS_ITEM(last_played) \
+       STATUS_ITEM(num_chunks) \
+       STATUS_ITEM(chunk_time) \
+       STATUS_ITEM(amplification) \
+       STATUS_ITEM(artist) \
+       STATUS_ITEM(title) \
+       STATUS_ITEM(year) \
+       STATUS_ITEM(album) \
+       STATUS_ITEM(comment) \
+       STATUS_ITEM(max_chunk_size) \
+
+#define STATUS_ITEM(_name) SI_ ##_name,
+enum status_items {STATUS_ITEMS NUM_STAT_ITEMS};
+#undef STATUS_ITEM
+#define STATUS_ITEM(_name) #_name,
+
+extern const char *status_item_list[];
+/** Loop over each status item. */
+#define FOR_EACH_STATUS_ITEM(i) for (i = 0; i < NUM_STAT_ITEMS; i++)
+int for_each_stat_item(char *item_buf, size_t num_bytes,
+       int (*item_handler)(int, char *));
index 4e10c2e3386d1511ac6f71bbfc47210d02852e3a..00704b29309a2edf1125221530940789d51c0053 100644 (file)
@@ -6,61 +6,63 @@
 
 /** \file portable_io.h Inline functions for binary IO. */
 
-static inline uint64_t read_portable(unsigned bits, const char *buf)
+static inline uint64_t read_portable(unsigned bits, const void *buf)
 {
        uint64_t ret = 0;
        int i, num_bytes = bits / 8;
+       const uint8_t *p = (typeof(p))buf;
 
        for (i = 0; i < num_bytes; i++) {
-               unsigned char c = buf[i];
+               unsigned char c = p[i];
                ret += ((uint64_t)c << (8 * i));
        }
        return ret;
 }
 
-static inline uint64_t read_portable_be(unsigned bits, const char *buf)
+static inline uint64_t read_portable_be(unsigned bits, const void *buf)
 {
        uint64_t ret = 0;
        int i, num_bytes = bits / 8;
+       const uint8_t *p = (typeof(p))buf;
 
        for (i = 0; i < num_bytes; i++) {
-               unsigned char c = buf[i];
+               unsigned char c = p[i];
                ret += ((uint64_t)c << (8 * (num_bytes - i - 1)));
        }
        return ret;
 }
 
-static inline uint64_t read_u64(const char *buf)
+static inline uint64_t read_u64(const void *buf)
 {
        return read_portable(64, buf);
 }
 
-static inline uint32_t read_u32(const char *buf)
+static inline uint32_t read_u32(const void *buf)
 {
        return read_portable(32, buf);
 }
 
-static inline uint16_t read_u16(const char *buf)
+static inline uint16_t read_u16(const void *buf)
 {
        return read_portable(16, buf);
 }
 
-static inline uint8_t read_u8(const char *buf)
+static inline uint8_t read_u8(const void *buf)
 {
        return read_portable(8, buf);
 }
 
-static inline uint64_t read_u64_be(const char *buf)
+static inline uint64_t read_u64_be(const void *buf)
 {
        return read_portable_be(64, buf);
 }
 
-static inline uint32_t read_u32_be(const char *buf)
+static inline uint32_t read_u32_be(const void *buf)
 {
        return read_portable_be(32, buf);
 }
 
-static inline uint16_t read_u16_be(const char *buf)
+static inline uint16_t read_u16_be(const void *buf)
 {
        return read_portable_be(16, buf);
 }
@@ -68,8 +70,10 @@ static inline uint16_t read_u16_be(const char *buf)
 static inline void write_portable(unsigned bits, char *buf, uint64_t val)
 {
        int i, num_bytes = bits / 8;
+       uint8_t *p = (typeof(p))buf;
+
        for (i = 0; i < num_bytes; i++) {
-               buf[i] = val & 0xff;
+               p[i] = val & 0xff;
                val = val >> 8;
        }
 }
@@ -77,43 +81,45 @@ static inline void write_portable(unsigned bits, char *buf, uint64_t val)
 static inline void write_portable_be(unsigned bits, char *buf, uint64_t val)
 {
        int i, num_bytes = bits / 8;
+       uint8_t *p = (typeof(p))buf;
+
        for (i = 0; i < num_bytes; i++) {
-               buf[num_bytes - i - 1] = val & 0xff;
+               p[num_bytes - i - 1] = val & 0xff;
                val = val >> 8;
        }
 }
 
-static inline void write_u64(char *buf, uint64_t val)
+static inline void write_u64(void *buf, uint64_t val)
 {
        write_portable(64, buf, val);
 }
 
-static inline void write_u32(char *buf, uint32_t val)
+static inline void write_u32(void *buf, uint32_t val)
 {
        write_portable(32, buf, (uint64_t) val);
 }
 
-static inline void write_u16(char *buf, uint16_t val)
+static inline void write_u16(void *buf, uint16_t val)
 {
        write_portable(16, buf, (uint64_t) val);
 }
 
-static inline void write_u8(char *buf, uint8_t val)
+static inline void write_u8(void *buf, uint8_t val)
 {
        write_portable(8, buf, (uint64_t) val);
 }
 
-static inline void write_u64_be(char *buf, uint64_t val)
+static inline void write_u64_be(void *buf, uint64_t val)
 {
        write_portable_be(64, buf, val);
 }
 
-static inline void write_u32_be(char *buf, uint32_t val)
+static inline void write_u32_be(void *buf, uint32_t val)
 {
        write_portable_be(32, buf, (uint64_t) val);
 }
 
-static inline void write_u16_be(char *buf, uint16_t val)
+static inline void write_u16_be(void *buf, uint16_t val)
 {
        write_portable_be(16, buf, (uint64_t) val);
 }
index 43ede2a91b752667ad4090e2742c4a844bf66250..c5f9ede61a92be19c4a8580b0eaf01ca4bf4e319 100644 (file)
--- a/server.c
+++ b/server.c
@@ -196,7 +196,6 @@ void parse_config_or_die(bool reload)
                        goto free_cf;
                if (ret == -ERRNO_TO_PARA_ERROR(ENOENT) && OPT_GIVEN(CONFIG_FILE))
                        goto free_cf;
-               ret = 0;
                server_lpr = cmdline_lpr;
                goto success;
        }
@@ -212,7 +211,7 @@ void parse_config_or_die(bool reload)
        if (reload) /* config file overrides command line */
                ret = lls(lls_merge(cf_lpr, cmdline_lpr, CMD_PTR, &merged_lpr,
                        &errctx));
-       else /* command line options overrride config file options */
+       else /* command line options override config file options */
                ret = lls(lls_merge(cmdline_lpr, cf_lpr, CMD_PTR, &merged_lpr,
                        &errctx));
        lls_free_parse_result(cf_lpr, CMD_PTR);
@@ -357,8 +356,6 @@ static int command_post_select(struct sched *s, void *context)
        ret = para_accept(sct->listen_fd, &s->rfds, NULL, 0, &new_fd);
        if (ret <= 0)
                goto out;
-       peer_name = remote_name(new_fd);
-       PARA_INFO_LOG("got connection from %s, forking\n", peer_name);
        mmd->num_connects++;
        mmd->active_connections++;
        /*
@@ -384,6 +381,8 @@ static int command_post_select(struct sched *s, void *context)
                /* parent keeps accepting connections */
                return 0;
        }
+       peer_name = remote_name(new_fd);
+       PARA_INFO_LOG("accepted connection from %s\n", peer_name);
        /* mmd might already have changed at this point */
        free(chunk_table);
        alarm(ALARM_TIMEOUT);
@@ -534,7 +533,7 @@ static void server_init(int argc, char **argv)
        init_signal_task();
        para_unblock_signal(SIGCHLD);
        PARA_NOTICE_LOG("initializing virtual streaming system\n");
-       init_vss_task(afs_socket, &sched);
+       vss_init(afs_socket, &sched);
        init_server_command_task(argc, argv);
        if (daemon_pipe >= 0) {
                if (write(daemon_pipe, "\0", 1) < 0) {
index 5d6e6e45dcd8e728c1bfcc6e08899bf08d4fc512..9153349fa8b20e96e56dfac3522aebdc2a6ebaff 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -25,7 +25,7 @@ static int signal_pipe[2];
  * This function creates a pipe, the signal pipe, to deliver pending
  * signals to the application (Bernstein's trick). It should be called
  * during the application's startup part, followed by subsequent calls
- * to para_install_sighandler() for each signal that should be caught.
+ * to \ref para_install_sighandler() for each signal that should be caught.
  *
  * A generic signal handler is used for all signals simultaneously. When a
  * signal arrives, the signal handler writes the number of the signal received
@@ -33,7 +33,7 @@ static int signal_pipe[2];
  * by checking if the file descriptor of the other end of the signal pipe is
  * ready for reading, see select(2).
  *
- * \return This function either succeeds or calls exit(2) to terminate the
+ * \return This function either succeeds or calls exit(3) to terminate the
  * current process. On success, a signal task structure is returned.
  */
 struct signal_task *signal_init_or_die(void)
index 4e318af19af8940570887ac3ebf8edb7a4c25b85..cd65ac519c0673c0b9df997f7608e2c86b5920dd 100644 (file)
--- a/spx_afh.c
+++ b/spx_afh.c
@@ -152,13 +152,13 @@ static int spx_get_file_info(char *map, size_t numbytes, __a_unused int fd,
                struct afh_info *afhi)
 {
        struct private_spx_data psd;
-       struct ogg_afh_callback_info spx_callback_info = {
+       struct oac_callback_info spx_callback_info = {
                .packet_callback = spx_packet_callback,
                .private_data = &psd,
        };
 
        memset(&psd, 0, sizeof(psd));
-       return ogg_get_file_info(map, numbytes, afhi, &spx_callback_info);
+       return oac_get_file_info(map, numbytes, afhi, &spx_callback_info);
 }
 
 static size_t spx_make_meta_packet(struct taginfo *tags, char **result)
@@ -244,7 +244,7 @@ static int spx_rewrite_tags(const char *map, size_t mapsize,
        int ret;
 
        meta_sz = spx_make_meta_packet(tags, &meta_packet);
-       ret = ogg_rewrite_tags(map, mapsize, output_fd, meta_packet, meta_sz);
+       ret = oac_rewrite_tags(map, mapsize, output_fd, meta_packet, meta_sz);
        free(meta_packet);
        return ret;
 }
diff --git a/stdin.c b/stdin.c
index e5c40bcb092a1faa59a91a33bd2d7b1975f1f3e7..7b70690b9a5f80626ad979595ee211bcf0037ded 100644 (file)
--- a/stdin.c
+++ b/stdin.c
@@ -114,6 +114,7 @@ void stdin_task_register(struct stdin_task *sit, struct sched *s)
                exit(EXIT_FAILURE);
        }
        sit->fd_flags = ret;
-       sit->must_set_nonblock_flag = (sit->fd_flags & O_NONBLOCK) == 0;
+       sit->must_set_nonblock_flag = (sit->fd_flags & O_NONBLOCK) == 0
+               && !isatty(STDIN_FILENO);
        sit->task = task_register(&ti, s);
 }
index 43e194dbca5d672936997ac97b94820892ca5a12..9fc20ed0253d91f9ecb3fe3591843feb48b82eb3 100644 (file)
--- a/stdout.c
+++ b/stdout.c
@@ -96,6 +96,7 @@ void stdout_task_register(struct stdout_task *sot, struct sched *s)
                exit(EXIT_FAILURE);
        }
        sot->fd_flags = ret;
-       sot->must_set_nonblock_flag = (sot->fd_flags & O_NONBLOCK) == 0;
+       sot->must_set_nonblock_flag = (sot->fd_flags & O_NONBLOCK) == 0
+               && !isatty(STDOUT_FILENO);
        sot->task = task_register(&ti, s);
 }
index 93bb6cba57ca6d1bee17358281ff774538793e39..a4093003d2d42cecb0be8cf75701a3ef30d96886 100644 (file)
--- a/string.h
+++ b/string.h
@@ -52,14 +52,14 @@ int for_each_line(unsigned flags, char *buf, size_t size,
                line_handler_t *line_handler, void *private_data);
 
 /**
 * Write the contents of a status item to a para_buffer.
 *
 * \param b The para_buffer.
 * \param n The number of the status item.
 * \param f A format string.
 *
 * \return The return value of the underlying call to para_printf().
 */
+ * Write the contents of a status item to a para_buffer.
+ *
+ * \param b The para_buffer.
+ * \param n The number of the status item.
+ * \param f A format string.
+ *
* \return The return value of the underlying call to \ref para_printf().
+ */
 #define WRITE_STATUS_ITEM(b, n, f, ...) (\
 { \
        if ((b)->flags & PBF_SIZE_PREFIX) { \
index 5329ef0f3aaf85b7f50f0b460e28026ca4067378..6a8e5bf1d77522658674a27e5370df26527f5c11 100755 (executable)
@@ -69,7 +69,7 @@ bad[$i]='.'
 let i++
 commands[$i]="ls"
 required_objects[$i]='ogg_afh'
-cmdline[$i]="ls -l=v -F ${oggs[@]}"
+cmdline[$i]="ls -l=v ${oggs[@]}"
 good[$i]='^attributes_txt: 33'
 
 let i++
index 8c9eebc94c3a5ef684ef86340b70d3140cd6fcda..0ea95e41993c0c3442ff0fc219c2111f73e5e0f1 100644 (file)
@@ -65,8 +65,9 @@ static void udp_close_target(struct sender_client *sc)
        PARA_NOTICE_LOG("sending FEC EOF\n");
        len = vss_get_fec_eof_packet(&buf);
        /* Ignore write() errors since we are closing the target anyway. */
-       if (write(sc->fd, buf, len) == len)
-               ut->sent_fec_eof = true;
+       if (write(sc->fd, buf, len))
+               do_nothing; /* avoid "ignoring return value" warning */
+       ut->sent_fec_eof = true;
 }
 
 static void udp_delete_target(struct sender_client *sc, const char *msg)
index 23fe086f189e89b3a729aa5afe145006446371bb..b2d2ff5ec0a30ebcefd93278d5db24e545e72232 100644 (file)
@@ -98,7 +98,7 @@ err:
 }
 
 /**
- * Initialize the list of users allowed to connect to to para_server.
+ * Initialize the list of users allowed to connect to para_server.
  *
  * \param user_list_file The file containing access information.
  *
diff --git a/vss.c b/vss.c
index 4a1db40d716c9022c7a38e0653ee50a515a53e4f..f225aa74568fb057058cea5d3590aae0ffeffaf1 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -1024,7 +1024,8 @@ err:
  */
 static void vss_send(struct vss_task *vsst)
 {
-       int i, fec_active = 0;
+       int i;
+       bool fec_active = false;
        struct timeval due;
        struct fec_client *fc, *tmp_fc;
 
@@ -1032,14 +1033,13 @@ static void vss_send(struct vss_task *vsst)
                return;
        if (chk_barrier("eof", &vsst->eof_barrier, &due, 1) < 0)
                return;
-       if (chk_barrier("data send", &vsst->data_send_barrier,
-                       &due, 1) < 0)
+       if (chk_barrier("data send", &vsst->data_send_barrier, &due, 1) < 0)
                return;
        list_for_each_entry_safe(fc, tmp_fc, &fec_client_list, node) {
                if (fc->state == FEC_STATE_DISABLED)
                        continue;
                if (!next_slice_is_due(fc, NULL)) {
-                       fec_active = 1;
+                       fec_active = true;
                        continue;
                }
                if (compute_next_fec_slice(fc, vsst) <= 0)
@@ -1049,7 +1049,7 @@ static void vss_send(struct vss_task *vsst)
                fc->current_slice_num++;
                fc->fcp->send_fec(fc->sc, (char *)fc->enc_buf,
                        fc->group.slice_bytes + FEC_HEADER_SIZE);
-               fec_active = 1;
+               fec_active = true;
        }
        if (mmd->current_chunk >= mmd->afd.afhi.chunks_total) { /* eof */
                if (!fec_active)
@@ -1067,37 +1067,17 @@ static void vss_send(struct vss_task *vsst)
                        mmd->events++;
                        set_mmd_offset();
                }
-               /*
-                * We call the send function also in case of empty chunks as
-                * they might have still some data queued which can be sent in
-                * this case.
-                */
                vss_get_chunk(mmd->current_chunk, vsst, &buf, &len);
                for (i = 0; senders[i].name; i++) {
+                       /*
+                        * We call ->send() even if len is zero because senders
+                        * might have data queued which can be sent now.
+                        */
                        if (!senders[i].send)
                                continue;
                        senders[i].send(mmd->current_chunk, mmd->chunks_sent,
                                buf, len, vsst->header_buf, vsst->header_len);
                }
-               /*
-                * Prefault next chunk(s)
-                *
-                * If the backing device of the memory-mapped audio file is
-                * slow and read-ahead is turned off or prevented for some
-                * reason, e.g. due to memory pressure, it may take much longer
-                * than the chunk interval to get the next chunk on the wire,
-                * causing buffer underruns on the client side. Mapping the
-                * file with MAP_POPULATE seems to help a bit, but it does not
-                * eliminate the delays completely. Moreover, it is supported
-                * only on Linux. So we do our own read-ahead here.
-                */
-               if (mmd->current_chunk > 0) { /* chunk 0 might be on the heap */
-                       buf += len;
-                       for (i = 0; i < 5 && buf < vsst->map + vsst->mapsize; i++) {
-                               __a_unused volatile char x = *buf;
-                               buf += 4096;
-                       }
-               }
                mmd->chunks_sent++;
                mmd->current_chunk++;
        }
@@ -1178,11 +1158,10 @@ static int vss_post_select(struct sched *s, void *context)
  * This also initializes all supported senders and starts streaming
  * if the --autoplay command line flag was given.
  */
-void init_vss_task(int afs_socket, struct sched *s)
+void vss_init(int afs_socket, struct sched *s)
 {
        static struct vss_task vss_task_struct, *vsst = &vss_task_struct;
        int i;
-       char *hn = para_hostname(), *home = para_homedir();
        long unsigned announce_time = OPT_UINT32_VAL(ANNOUNCE_TIME),
                autoplay_delay = OPT_UINT32_VAL(AUTOPLAY_DELAY);
        vsst->header_interval.tv_sec = 5; /* should this be configurable? */
@@ -1194,8 +1173,6 @@ void init_vss_task(int afs_socket, struct sched *s)
                PARA_NOTICE_LOG("initializing %s sender\n", senders[i].name);
                senders[i].init(&senders[i]);
        }
-       free(hn);
-       free(home);
        mmd->sender_cmd_data.cmd_num = -1;
        if (OPT_GIVEN(AUTOPLAY)) {
                struct timeval tmp;
diff --git a/vss.h b/vss.h
index d2b1ad1dd2d008420462f7f7c4b53f9ff34ab243..bf1357864e4a967952d0764d3e0175b11b8dc182 100644 (file)
--- a/vss.h
+++ b/vss.h
@@ -6,7 +6,7 @@
 
 /** \file vss.h Exported functions from vss.c (para_server). */
 
-void init_vss_task(int afs_socket, struct sched *s);
+void vss_init(int afs_socket, struct sched *s);
 unsigned int vss_playing(void);
 unsigned int vss_next(void);
 unsigned int vss_repos(void);
index 96d724c939ee13f1dd640ee98a47f1421bc1d85f..5e41174220656e5dc6034d9606d452fc57377c87 100644 (file)
@@ -330,7 +330,7 @@ code repository, execute
 
                git clone git://git.tuebingen.mpg.de/osl
 
-- [openssl](http://www.openssl.org/) or
+- [openssl](https://www.openssl.org/) or
 [libgcrypt](ftp://ftp.gnupg.org/gcrypt/libgcrypt/).  At least one
 of these two libraries is needed as the backend for cryptographic
 routines on both the server and the client side. Both openssl and
@@ -344,12 +344,12 @@ is called `libmad0-dev` on debian-based systems. Note that libmad is
 not necessary on the server side, i.e., for sending MP3 files.
 
 - [libid3tag](http://www.underbit.com/products/mad/). For version-2
-ID3 tag support, you willl need the libid3tag development package
+ID3 tag support, you will need the libid3tag development package
 `libid3tag0-dev`. Without libid3tag, only version-1 tags are
 recognized. The mp3 tagger also needs this library for modifying
 (id3v1 and id3v2) tags.
 
-- [ogg vorbis](http://www.xiph.org/downloads/). For ogg vorbis streams
+- [ogg vorbis](https://www.xiph.org/downloads/). For ogg vorbis streams
 you need libogg, libvorbis, libvorbisfile. The corresponding Debian
 packages are called `libogg-dev` and `libvorbis-dev`.
 
@@ -359,10 +359,10 @@ that for some distributions, e.g. Ubuntu, mp4ff is not part of the
 libfaad package. Install the faad library from sources (available
 through the above link) to get the mp4ff library and header files.
 
-- [speex](http://www.speex.org/). In order to stream or decode speex
+- [speex](https://www.speex.org/). In order to stream or decode speex
 files, libspeex (`libspeex-dev`) is required.
 
-- [flac](http://flac.sourceforge.net/). To stream or decode files
+- [flac](https://xiph.org/flac/). To stream or decode files
 encoded with the _Free Lossless Audio Codec_, libFLAC (`libFLAC-dev`)
 must be installed.
 
@@ -373,7 +373,7 @@ installed. Debian package: `libsamplerate-dev`.
 - [alsa-lib](ftp://ftp.alsa-project.org/pub/lib/). On Linux, you will
 need to have the ALSA development package `libasound2-dev` installed.
 
-- [libao](http://downloads.xiph.org/releases/ao/). Needed to build
+- [libao](https://ftp.osuosl.org/pub/xiph/releases/ao/). Needed to build
 the ao writer (ESD, PulseAudio,...).  Debian package: `libao-dev`.
 
 - [curses](ftp://ftp.gnu.org/pub/gnu/ncurses). Needed for
@@ -1439,7 +1439,7 @@ only for Linux.
 
 - UDP. Recommended for multicast LAN streaming.
 
-See the Appendix on [network protocols](/#Network.protocols)
+See the Appendix on [network protocols](#Network.protocols)
 for brief descriptions of the various protocols relevant for network
 audio streaming with paraslash.
 
@@ -2007,7 +2007,7 @@ and for getting updates.
 the configure file which is shipped in the tarballs but has to be
 generated when compiling from git.
 
-- [discount](http://www.pell.portland.or.us/~orc/Code/discount). The
+- [discount](http://www.pell.portland.or.us/~orc/Code/discount/). The
 HTML version of this manual and some of the paraslash web pages are
 written in the Markdown markup language and are translated into html
 with the converter of the *Discount* package.
@@ -2111,7 +2111,7 @@ Coding Style
 
 The preferred coding style for paraslash coincides more or less
 with the style of the Linux kernel. So rather than repeating what is
-written [there](http://www.kernel.org/doc/Documentation/process/coding-style.rst),
+written [there](https://www.kernel.org/doc/Documentation/process/coding-style.rst),
 here are the most important points.
 
 - Burn the GNU coding standards.
@@ -2374,17 +2374,17 @@ Application web pages
 ---------------------
 
 - [paraslash](http://people.tuebingen.mpg.de/maan/paraslash/)
-- [xmms](http://xmms2.org/wiki/Main_Page)
+- [xmms](https://xmms2.org/wiki/Main_Page)
 - [mpg123](http://www.mpg123.de/)
-- [gstreamer](http://gstreamer.freedesktop.org/)
+- [gstreamer](https://gstreamer.freedesktop.org/)
 - [icecast](http://www.icecast.org/)
-- [Audio Compress](http://beesbuzz.biz/code/audiocompress.php)
+- [Audio Compress](https://beesbuzz.biz/code/audiocompress.php)
 
 External documentation
 ----------------------
 
 - [The mathematics of
-Raid6](http://kernel.org/pub/linux/kernel/people/hpa/raid6.pdf)
+Raid6](https://www.kernel.org/pub/linux/kernel/people/hpa/raid6.pdf)
 by H. Peter Anvin
 
 - [Effective Erasure Codes for reliable Computer Communication
index ebb2f9c34c97dbb445b312dd1e8ab2004b0d5bc6..01674f1a1dc1edfa500046f031b436cd83348635 100644 (file)
--- a/wma_afh.c
+++ b/wma_afh.c
@@ -377,14 +377,17 @@ static int make_cdo(struct taginfo *tags, const struct asf_object *cdo,
        ret = convert_utf8_to_utf16(tags->artist, &artist);
        if (ret < 0)
                return ret;
+       assert(artist);
        artist_bytes = ret;
        ret = convert_utf8_to_utf16(tags->title, &title);
        if (ret < 0)
                goto out;
+       assert(title);
        title_bytes = ret;
        ret = convert_utf8_to_utf16(tags->comment, &comment);
        if (ret < 0)
                goto out;
+       assert(comment);
        comment_bytes = ret;
 
        if (cdo) {
@@ -458,10 +461,12 @@ static int make_ecdo(struct taginfo *tags, struct asf_object *result)
        ret = convert_utf8_to_utf16(tags->album, &album);
        if (ret < 0)
                return ret;
+       assert(album);
        album_bytes = ret;
        ret = convert_utf8_to_utf16(tags->year, &year);
        if (ret < 0)
                goto out;
+       assert(year);
        year_bytes = ret;
        result->size = 16 + 8 + 2; /* GUID, size, count */
        /* name_length + name + null + data type + val length + val */
index 525ed3150cda5affb9b479029b7e9aa5f461a0aa..b96f1460f45c77928214a884195d85b4eff04a56 100644 (file)
@@ -15,8 +15,6 @@
  * This decoder handles Microsoft Windows Media Audio data version 2.
  */
 
-#define _XOPEN_SOURCE 600
-
 #include <math.h>
 #include <regex.h>
 #include <sys/select.h>
@@ -81,7 +79,6 @@ struct private_wmadec_data {
        struct vlc coef_vlc[2];
        uint16_t *run_table[2];
        uint16_t *level_table[2];
-       const struct coef_vlc_table *coef_vlcs[2];
        /** Frame length in samples. */
        int frame_len;
        /** log2 of frame_len. */
@@ -100,8 +97,6 @@ struct private_wmadec_data {
        int block_len;
        /** Current position in frame. */
        int block_pos;
-       /** True if mid/side stereo mode. */
-       uint8_t ms_stereo;
        /** True if channel is coded. */
        uint8_t channel_coded[MAX_CHANNELS];
        /** log2 ratio frame/exp. length. */
@@ -159,51 +154,27 @@ static void sine_window_init(float *window, int n)
                window[i] = sinf((i + 0.5) * (M_PI / (2.0 * n)));
 }
 
-static void wmadec_cleanup(struct private_wmadec_data *pwd)
-{
-       int i;
-
-       for (i = 0; i < pwd->nb_block_sizes; i++)
-               imdct_end(pwd->mdct_ctx[i]);
-       if (pwd->ahi.use_exp_vlc)
-               free_vlc(&pwd->exp_vlc);
-       if (pwd->use_noise_coding)
-               free_vlc(&pwd->hgain_vlc);
-       for (i = 0; i < 2; i++) {
-               free_vlc(&pwd->coef_vlc[i]);
-               free(pwd->run_table[i]);
-               free(pwd->level_table[i]);
-       }
-}
-
-static void init_coef_vlc(struct vlc *vlc, uint16_t **prun_table,
-               uint16_t **plevel_table, const struct coef_vlc_table *vlc_table)
+static void init_coef_vlc(struct private_wmadec_data *pwd, int sidx, int didx)
 {
-       int n = vlc_table->n;
-       const uint8_t *table_bits = vlc_table->huffbits;
-       const uint32_t *table_codes = vlc_table->huffcodes;
-       const uint16_t *levels_table = vlc_table->levels;
-       uint16_t *run_table, *level_table;
-       int i, l, j, k, level;
+       const struct coef_vlc_table *src = coef_vlcs + sidx;
+       struct vlc *dst = pwd->coef_vlc + didx;
+       int i, l, j, k, level, n = src->n;
 
-       init_vlc(vlc, VLCBITS, n, table_bits, table_codes, 4);
-
-       run_table = para_malloc(n * sizeof(uint16_t));
-       level_table = para_malloc(n * sizeof(uint16_t));
+       init_vlc(dst, VLCBITS, n, src->huffbits, src->huffcodes, 4);
+       pwd->run_table[didx] = para_malloc(n * sizeof(uint16_t));
+       pwd->level_table[didx] = para_malloc(n * sizeof(uint16_t));
        i = 2;
        level = 1;
        k = 0;
        while (i < n) {
-               l = levels_table[k++];
+               l = src->levels[k++];
                for (j = 0; j < l; j++) {
-                       run_table[i] = j;
-                       level_table[i] = level;
+                       pwd->run_table[didx][i] = j;
+                       pwd->level_table[didx][i] = level;
                        i++;
                }
                level++;
        }
-       *prun_table = run_table;
-       *plevel_table = level_table;
 }
 
 /* compute the scale factor band sizes for each MDCT block size */
@@ -413,19 +384,15 @@ static int wma_init(struct private_wmadec_data *pwd)
        }
 
        /* choose the VLC tables for the coefficients */
-       coef_vlc_table = 2;
+       coef_vlc_table = 4;
        if (ahi->sample_rate >= 32000) {
                if (bps1 < 0.72)
                        coef_vlc_table = 0;
                else if (bps1 < 1.16)
-                       coef_vlc_table = 1;
+                       coef_vlc_table = 2;
        }
-       pwd->coef_vlcs[0] = &coef_vlcs[coef_vlc_table * 2];
-       pwd->coef_vlcs[1] = &coef_vlcs[coef_vlc_table * 2 + 1];
-       init_coef_vlc(&pwd->coef_vlc[0], &pwd->run_table[0], &pwd->level_table[0],
-               pwd->coef_vlcs[0]);
-       init_coef_vlc(&pwd->coef_vlc[1], &pwd->run_table[1], &pwd->level_table[1],
-               pwd->coef_vlcs[1]);
+       init_coef_vlc(pwd, coef_vlc_table, 0);
+       init_coef_vlc(pwd, coef_vlc_table + 1, 1);
        return 0;
 }
 
@@ -581,7 +548,7 @@ static int decode_exp_vlc(struct private_wmadec_data *pwd, int ch)
        last_exp = 36;
 
        while (q < q_end) {
-               code = get_vlc(&pwd->gb, pwd->exp_vlc.table, EXPVLCBITS);
+               code = get_vlc(&pwd->gb, &pwd->exp_vlc);
                if (code < 0)
                        return code;
                /* NOTE: this offset is the same as MPEG4 AAC ! */
@@ -708,8 +675,7 @@ static int compute_high_band_values(struct private_wmadec_data *pwd,
                        if (val == (int)0x80000000)
                                val = get_bits(&pwd->gb, 7) - 19;
                        else {
-                               int code = get_vlc(&pwd->gb,
-                                       pwd->hgain_vlc.table, HGAINVLCBITS);
+                               int code = get_vlc(&pwd->gb, &pwd->hgain_vlc);
                                if (code < 0)
                                        return code;
                                val += code - 18;
@@ -828,6 +794,7 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
        int ret, n, v, ch, code, bsize;
        int coef_nb_bits, total_gain;
        int nb_coefs[MAX_CHANNELS];
+       bool ms_stereo = false; /* mid/side stereo mode */
 
        /* compute current block length */
        if (pwd->ahi.use_variable_block_len) {
@@ -865,7 +832,7 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
                return -E_INCOHERENT_BLOCK_LEN;
 
        if (pwd->ahi.channels == 2)
-               pwd->ms_stereo = get_bit(&pwd->gb);
+               ms_stereo = get_bit(&pwd->gb);
        v = 0;
        for (ch = 0; ch < pwd->ahi.channels; ch++) {
                int a = get_bit(&pwd->gb);
@@ -931,7 +898,7 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
                 * special VLC tables are used for ms stereo because there is
                 * potentially less energy there
                 */
-               tindex = (ch == 1 && pwd->ms_stereo);
+               tindex = ch == 1 && ms_stereo;
                coef_vlc = &pwd->coef_vlc[tindex];
                run_table = pwd->run_table[tindex];
                level_table = pwd->level_table[tindex];
@@ -940,7 +907,7 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
                eptr = ptr + nb_coefs[ch];
                memset(ptr, 0, pwd->block_len * sizeof(int16_t));
                for (;;) {
-                       code = get_vlc(&pwd->gb, coef_vlc->table, VLCBITS);
+                       code = get_vlc(&pwd->gb, coef_vlc);
                        if (code < 0)
                                return code;
                        if (code == 1) /* EOB */
@@ -966,7 +933,7 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
                }
        }
        compute_mdct_coefficients(pwd, bsize, total_gain, nb_coefs);
-       if (pwd->ms_stereo && pwd->channel_coded[1]) {
+       if (ms_stereo && pwd->channel_coded[1]) {
                float a, b;
                int i;
                /*
@@ -994,7 +961,7 @@ next:
                n4 = pwd->block_len / 2;
                if (pwd->channel_coded[ch])
                        imdct(pwd->mdct_ctx[bsize], pwd->output, pwd->coefs[ch]);
-               else if (!(pwd->ms_stereo && ch == 1))
+               else if (!(ms_stereo && ch == 1))
                        memset(pwd->output, 0, sizeof(pwd->output));
 
                /* multiply by the window and add in the frame */
@@ -1058,24 +1025,13 @@ static int wma_decode_frame(struct private_wmadec_data *pwd, int16_t *samples)
        return 0;
 }
 
-static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data,
-               int *data_size, const uint8_t *buf, int buf_size)
+static int wma_decode_superframe(struct private_wmadec_data *pwd, void *out,
+               int *out_size, const uint8_t *in)
 {
-       int ret;
-       int16_t *samples;
+       int ret, in_size = pwd->ahi.packet_size - WMA_FRAME_SKIP;
+       int16_t *samples = out;
 
-       if (buf_size == 0) {
-               pwd->last_superframe_len = 0;
-               *data_size = 0;
-               return 0;
-       }
-       if (buf_size < pwd->ahi.block_align) {
-               *data_size = 0;
-               return 0;
-       }
-       buf_size = pwd->ahi.block_align;
-       samples = data;
-       init_get_bits(&pwd->gb, buf, buf_size);
+       init_get_bits(&pwd->gb, in, in_size);
        if (pwd->ahi.use_bit_reservoir) {
                int i, nb_frames, bit_offset, pos, len;
                uint8_t *q;
@@ -1086,7 +1042,7 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data,
                // PARA_DEBUG_LOG("have %d frames\n", nb_frames);
                ret = -E_WMA_OUTPUT_SPACE;
                if ((nb_frames + 1) * pwd->ahi.channels * pwd->frame_len
-                               * sizeof(int16_t) > *data_size)
+                               * sizeof(int16_t) > *out_size)
                        goto fail;
 
                bit_offset = get_bits(&pwd->gb, pwd->byte_offset_bits + 3);
@@ -1124,7 +1080,7 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data,
 
                /* read each frame starting from bit_offset */
                pos = bit_offset + 4 + 4 + pwd->byte_offset_bits + 3;
-               init_get_bits(&pwd->gb, buf + (pos >> 3),
+               init_get_bits(&pwd->gb, in + (pos >> 3),
                        (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3)));
                len = pos & 7;
                if (len > 0)
@@ -1143,16 +1099,16 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data,
                        ((bit_offset + 4 + 4 + pwd->byte_offset_bits + 3) & ~7);
                pwd->last_bitoffset = pos & 7;
                pos >>= 3;
-               len = buf_size - pos;
+               len = in_size - pos;
                ret = -E_WMA_BAD_SUPERFRAME;
                if (len > MAX_CODED_SUPERFRAME_SIZE || len < 0)
                        goto fail;
                pwd->last_superframe_len = len;
-               memcpy(pwd->last_superframe, buf + pos, len);
+               memcpy(pwd->last_superframe, in + pos, len);
        } else {
                PARA_DEBUG_LOG("not using bit reservoir\n");
                ret = -E_WMA_OUTPUT_SPACE;
-               if (pwd->ahi.channels * pwd->frame_len * sizeof(int16_t) > *data_size)
+               if (pwd->ahi.channels * pwd->frame_len * sizeof(int16_t) > *out_size)
                        goto fail;
                /* single frame decode */
                ret = wma_decode_frame(pwd, samples);
@@ -1162,8 +1118,8 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data,
        }
        PARA_DEBUG_LOG("frame_len: %d, block_len: %d, outbytes: %d, eaten: %d\n",
                pwd->frame_len, pwd->block_len,
-               (int)((int8_t *)samples - (int8_t *)data), pwd->ahi.block_align);
-       *data_size = (int8_t *)samples - (int8_t *)data;
+               (int)((int8_t *)samples - (int8_t *)out), pwd->ahi.block_align);
+       *out_size = (int8_t *)samples - (int8_t *)out;
        return pwd->ahi.block_align;
 fail:
        /* reset the bit reservoir on errors */
@@ -1174,10 +1130,21 @@ fail:
 static void wmadec_close(struct filter_node *fn)
 {
        struct private_wmadec_data *pwd = fn->private_data;
+       int i;
 
        if (!pwd)
                return;
-       wmadec_cleanup(pwd);
+       for (i = 0; i < pwd->nb_block_sizes; i++)
+               imdct_end(pwd->mdct_ctx[i]);
+       if (pwd->ahi.use_exp_vlc)
+               free_vlc(&pwd->exp_vlc);
+       if (pwd->use_noise_coding)
+               free_vlc(&pwd->hgain_vlc);
+       for (i = 0; i < 2; i++) {
+               free_vlc(&pwd->coef_vlc[i]);
+               free(pwd->run_table[i]);
+               free(pwd->level_table[i]);
+       }
        free(fn->private_data);
        fn->private_data = NULL;
 }
@@ -1233,7 +1200,7 @@ next_buffer:
        out_size = WMA_OUTPUT_BUFFER_SIZE;
        out = para_malloc(out_size);
        ret = wma_decode_superframe(pwd, out, &out_size,
-               (uint8_t *)in + WMA_FRAME_SKIP, len - WMA_FRAME_SKIP);
+               (uint8_t *)in + WMA_FRAME_SKIP);
        if (ret < 0) {
                free(out);
                goto err;