Fix documentation of select command.
[paraslash.git] / aft.c
diff --git a/aft.c b/aft.c
index 6481f3e4d6b031351b4b4ae09c410b3c4c0fc771..0efd285c2eb716df2aeeb47e4dfd06aa1d293e5f 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2007 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2007-2008 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -58,7 +58,9 @@ enum ls_listing_mode {
        /** -lv */
        LS_MODE_VERBOSE,
        /** -lm */
        /** -lv */
        LS_MODE_VERBOSE,
        /** -lm */
-       LS_MODE_MBOX
+       LS_MODE_MBOX,
+       /** -lc */
+       LS_MODE_CHUNKS
 };
 
 /** The flags accepted by the ls command. */
 };
 
 /** The flags accepted by the ls command. */
@@ -660,6 +662,7 @@ int open_and_update_audio_file(struct osl_row *aft_row, long score,
                AFTCOL_CHUNKS, &chunk_table_obj);
        if (ret < 0)
                return ret;
                AFTCOL_CHUNKS, &chunk_table_obj);
        if (ret < 0)
                return ret;
+       afd->afhi.chunk_table = NULL;
        ret = mmap_full_file(path, O_RDONLY, &map.data,
                &map.size, &afd->fd);
        if (ret < 0)
        ret = mmap_full_file(path, O_RDONLY, &map.data,
                &map.size, &afd->fd);
        if (ret < 0)
@@ -697,10 +700,8 @@ int open_and_update_audio_file(struct osl_row *aft_row, long score,
        aced.old_afsi = &old_afsi;
        afs_event(AFSI_CHANGE, NULL, &aced);
        ret = save_afd(afd);
        aced.old_afsi = &old_afsi;
        afs_event(AFSI_CHANGE, NULL, &aced);
        ret = save_afd(afd);
-       free(afd->afhi.chunk_table);
-       if (ret < 0)
-               goto err;
 err:
 err:
+       free(afd->afhi.chunk_table);
        osl_close_disk_object(&chunk_table_obj);
        return ret;
 }
        osl_close_disk_object(&chunk_table_obj);
        return ret;
 }
@@ -820,6 +821,35 @@ static char *make_filename_lines(const char *path, unsigned flags)
        return ret;
 }
 
        return ret;
 }
 
+static int print_chunk_table(struct ls_data *d, struct para_buffer *b)
+{
+       struct osl_object chunk_table_obj;
+       struct osl_row *aft_row;
+       int ret, i;
+       char *buf;
+
+       ret = aft_get_row_of_hash(d->hash, &aft_row);
+       if (ret < 0)
+               return ret;
+       ret = osl_open_disk_object(audio_file_table, aft_row,
+               AFTCOL_CHUNKS, &chunk_table_obj);
+       if (ret < 0)
+               return ret;
+       buf = chunk_table_obj.data;
+       para_printf(b, "%s\n"
+               "chunk_time: %lu:%lu\nchunk_offsets: ",
+               d->path,
+               (long unsigned) d->afhi.chunk_tv.tv_sec,
+               (long unsigned) d->afhi.chunk_tv.tv_usec
+       );
+       for (i = 0; i <= d->afhi.chunks_total; i++)
+               para_printf(b, "%u ",
+                       (unsigned) read_u32(buf + 4 * i));
+       osl_close_disk_object(&chunk_table_obj);
+       para_printf(b, "\n");
+       return 1;
+}
+
 static int print_list_item(struct ls_data *d, struct ls_options *opts,
        struct para_buffer *b, time_t current_time)
 {
 static int print_list_item(struct ls_data *d, struct ls_options *opts,
        struct para_buffer *b, time_t current_time)
 {
@@ -839,6 +869,8 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts,
                para_printf(b, "%s\n", d->path);
                return 1;
        }
                para_printf(b, "%s\n", d->path);
                return 1;
        }
+       if (opts->mode == LS_MODE_CHUNKS)
+               return print_chunk_table(d, b);
        get_attribute_bitmap(&afsi->attributes, att_buf);
        ret = get_local_time(&afsi->last_played, last_played_time,
                sizeof(last_played_time), current_time, opts->mode);
        get_attribute_bitmap(&afsi->attributes, att_buf);
        ret = get_local_time(&afsi->last_played, last_played_time,
                sizeof(last_played_time), current_time, opts->mode);
@@ -886,13 +918,15 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts,
        lyrics_lines = make_lyrics_lines(afsi);
        image_lines = make_image_lines(afsi);
        filename_lines = make_filename_lines(d->path, opts->flags);
        lyrics_lines = make_lyrics_lines(afsi);
        image_lines = make_image_lines(afsi);
        filename_lines = make_filename_lines(d->path, opts->flags);
-       if (opts->mode == LS_MODE_MBOX)
+       if (opts->mode == LS_MODE_MBOX) {
+               const char *bn = para_basename(d->path);
                para_printf(b,
                        "From foo@localhost %s\n"
                        "Received: from\nTo: bar\nFrom: a\n"
                        "Subject: %s\n\n",
                        last_played_time,
                para_printf(b,
                        "From foo@localhost %s\n"
                        "Received: from\nTo: bar\nFrom: a\n"
                        "Subject: %s\n\n",
                        last_played_time,
-                       d->path);
+                       bn? bn : "?");
+       }
        para_printf(b,
                "%s" /* filename stuff */
                "%s%s%s%s" /* score */
        para_printf(b,
                "%s" /* filename stuff */
                "%s%s%s%s" /* score */
@@ -1298,6 +1332,9 @@ int com_ls(int fd, int argc, char * const * const argv)
                        case 'm':
                                mode = LS_MODE_MBOX;
                                continue;
                        case 'm':
                                mode = LS_MODE_MBOX;
                                continue;
+                       case 'c':
+                               mode = LS_MODE_CHUNKS;
+                               continue;
                        default:
                                return -E_AFT_SYNTAX;
                        }
                        default:
                                return -E_AFT_SYNTAX;
                        }
@@ -1868,6 +1905,8 @@ struct touch_action_data {
        struct com_touch_options *cto;
        /** Message buffer. */
        struct para_buffer pb;
        struct com_touch_options *cto;
        /** Message buffer. */
        struct para_buffer pb;
+       /** How many audio files matched the given pattern. */
+       unsigned num_matches;
 };
 
 static int touch_audio_file(__a_unused struct osl_table *table,
 };
 
 static int touch_audio_file(__a_unused struct osl_table *table,
@@ -1910,6 +1949,7 @@ static int touch_audio_file(__a_unused struct osl_table *table,
                if (tad->cto->last_played >= 0)
                        new_afsi.last_played = tad->cto->last_played;
        }
                if (tad->cto->last_played >= 0)
                        new_afsi.last_played = tad->cto->last_played;
        }
+       tad->num_matches++;
        save_afsi(&new_afsi, &obj); /* in-place update */
        aced.aft_row = row;
        aced.old_afsi = &old_afsi;
        save_afsi(&new_afsi, &obj); /* in-place update */
        aced.aft_row = row;
        aced.old_afsi = &old_afsi;
@@ -1936,6 +1976,9 @@ static int com_touch_callback(const struct osl_object *query,
        ret = for_each_matching_row(&pmd);
        if (ret < 0)
                para_printf(&tad.pb, "%s\n", para_strerror(-ret));
        ret = for_each_matching_row(&pmd);
        if (ret < 0)
                para_printf(&tad.pb, "%s\n", para_strerror(-ret));
+       else
+               if (!tad.num_matches)
+                       para_printf(&tad.pb, "no matches\n");
        if (tad.pb.buf) {
                result->data = tad.pb.buf;
                result->size = tad.pb.size;
        if (tad.pb.buf) {
                result->data = tad.pb.buf;
                result->size = tad.pb.size;
@@ -2003,11 +2046,14 @@ int com_touch(int fd, int argc, char * const * const argv)
                return -E_AFT_SYNTAX;
        ret = send_option_arg_callback_request(&query, argc - i,
                argv + i, com_touch_callback, &result);
                return -E_AFT_SYNTAX;
        ret = send_option_arg_callback_request(&query, argc - i,
                argv + i, com_touch_callback, &result);
-       if (ret > 0) {
-               send_buffer(fd, (char *)result.data);
-               free(result.data);
-       } else if (ret < 0)
+       if (!ret)
+               return 0;
+       if (ret < 0) {
                send_va_buffer(fd, "%s\n", para_strerror(-ret));
                send_va_buffer(fd, "%s\n", para_strerror(-ret));
+               return ret;
+       }
+       ret = send_buffer(fd, (char *)result.data);
+       free(result.data);
        return ret;
 }
 
        return ret;
 }
 
@@ -2115,11 +2161,14 @@ int com_rm(int fd, int argc,  char * const * const argv)
                return -E_AFT_SYNTAX;
        ret = send_option_arg_callback_request(&query, argc - i, argv + i,
                com_rm_callback, &result);
                return -E_AFT_SYNTAX;
        ret = send_option_arg_callback_request(&query, argc - i, argv + i,
                com_rm_callback, &result);
-       if (ret > 0) {
-               send_buffer(fd, (char *)result.data);
-               free(result.data);
-       } else if (ret < 0)
+       if (!ret)
+               return 0;
+       if (ret < 0) {
                send_va_buffer(fd, "%s\n", para_strerror(-ret));
                send_va_buffer(fd, "%s\n", para_strerror(-ret));
+               return ret;
+       }
+       ret = send_buffer(fd, (char *)result.data);
+       free(result.data);
        return ret;
 }
 
        return ret;
 }
 
@@ -2276,11 +2325,14 @@ int com_cpsi(int fd, int argc,  char * const * const argv)
                flags = ~(unsigned)CPSI_FLAG_VERBOSE | flags;
        ret = send_option_arg_callback_request(&options, argc - i, argv + i,
                com_cpsi_callback, &result);
                flags = ~(unsigned)CPSI_FLAG_VERBOSE | flags;
        ret = send_option_arg_callback_request(&options, argc - i, argv + i,
                com_cpsi_callback, &result);
-       if (ret > 0) {
-               send_buffer(fd, (char *)result.data);
-               free(result.data);
-       } else
+       if (!ret)
+               return 0;
+       if (ret < 0) {
                send_va_buffer(fd, "%s\n", para_strerror(-ret));
                send_va_buffer(fd, "%s\n", para_strerror(-ret));
+               return ret;
+       }
+       ret = send_buffer(fd, (char *)result.data);
+       free(result.data);
        return ret;
 }
 
        return ret;
 }