/*
- * 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.
*/
/** -lv */
LS_MODE_VERBOSE,
/** -lm */
- LS_MODE_MBOX
+ LS_MODE_MBOX,
+ /** -lc */
+ LS_MODE_CHUNKS
};
/** The flags accepted by the ls command. */
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)
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:
+ free(afd->afhi.chunk_table);
osl_close_disk_object(&chunk_table_obj);
return ret;
}
static char *make_filename_lines(const char *path, unsigned flags)
{
- char *basename, *dirname;
- char *ret;
+ char *dirname, *ret;
+ const char *basename;
if (!(flags & LS_FLAG_FULL_PATH))
return make_message("%s: %s\n",
dirname = para_dirname(path);
ret = make_message("%s: %s\n%s: %s\n%s: %s\n",
status_item_list[SI_PATH], path,
- status_item_list[SI_DIRECTORY], dirname,
- status_item_list[SI_BASENAME], basename);
- free(basename);
+ status_item_list[SI_DIRECTORY], dirname? dirname : "?",
+ status_item_list[SI_BASENAME], basename? basename : "?");
free(dirname);
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;
+ 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
+ );
+ buf = chunk_table_obj.data;
+ 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)
{
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);
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,
- d->path);
+ bn? bn : "?");
+ }
para_printf(b,
"%s" /* filename stuff */
"%s%s%s%s" /* score */
ret = 1;
out:
ls_output->data = b.buf;
- ls_output->size = b.size;
+ ls_output->size = b.offset;
free(opts->data);
free(opts->data_ptr);
free(opts->patterns);
enum ls_sorting_method sort = LS_SORT_BY_PATH;
enum ls_listing_mode mode = LS_MODE_SHORT;
struct ls_options opts = {.patterns = NULL};
- struct osl_object query = {.data = &opts, .size = sizeof(opts)},
- ls_output;
+ struct osl_object query = {.data = &opts, .size = sizeof(opts)};
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
case 'm':
mode = LS_MODE_MBOX;
continue;
+ case 'c':
+ mode = LS_MODE_CHUNKS;
+ continue;
default:
return -E_AFT_SYNTAX;
}
opts.mode = mode;
opts.num_patterns = argc - i;
ret = send_option_arg_callback_request(&query, opts.num_patterns,
- argv + i, com_ls_callback, &ls_output);
- if (ret > 0) {
- ret = send_buffer(fd, (char *)ls_output.data);
- free(ls_output.data);
- }
+ argv + i, com_ls_callback, send_result, &fd);
return ret;
}
if (!msg.buf)
return 0;
result->data = msg.buf;
- result->size = msg.size;
+ result->size = msg.offset;
return 1;
}
return 1;
}
-static int add_one_audio_file(const char *path, const void *private_data)
+int get_row_pointer_from_result(struct osl_object *result, void *private)
+{
+ struct osl_row **row = private;
+ *row = result->data;
+ return 1;
+}
+
+static int add_one_audio_file(const char *path, void *private_data)
{
int ret, send_ret = 1;
uint8_t format_num = -1;
- const struct private_add_data *pad = private_data;
+ struct private_add_data *pad = private_data;
struct afh_info afhi, *afhi_ptr = NULL;
struct osl_row *pb = NULL, *hs = NULL; /* path brother/hash sister */
- struct osl_object map, obj = {.data = NULL}, query, result = {.data = NULL};
+ struct osl_object map, obj = {.data = NULL}, query;
HASH_TYPE hash[HASH_SIZE];
- afhi.header_offset = 0;
- afhi.header_len = 0;
ret = guess_audio_format(path);
if (ret < 0 && !(pad->flags & ADD_FLAG_ALL))
goto out_free;
query.data = (char *)path;
query.size = strlen(path) + 1;
- ret = send_callback_request(path_brother_callback, &query, &result);
+ ret = send_callback_request(path_brother_callback, &query,
+ get_row_pointer_from_result, &pb);
if (ret < 0 && ret != -E_RB_KEY_NOT_FOUND)
goto out_free;
- if (ret >= 0) {
- pb = *(struct osl_row **)result.data;
- free(result.data);
- }
ret = 1;
if (pb && (pad->flags & ADD_FLAG_LAZY)) { /* lazy is really cheap */
if (pad->flags & ADD_FLAG_VERBOSE)
/* Check whether the database contains a file with the same hash. */
query.data = hash;
query.size = HASH_SIZE;
- ret = send_callback_request(hash_sister_callback, &query, &result);
+ ret = send_callback_request(hash_sister_callback, &query,
+ get_row_pointer_from_result, &hs);
if (ret < 0 && ret != -E_RB_KEY_NOT_FOUND)
goto out_unmap;
- if (ret >= 0) {
- hs = *(struct osl_row **)result.data;
- free(result.data);
- }
/* Return success if we already know this file. */
ret = 1;
if (pb && hs && hs == pb && !(pad->flags & ADD_FLAG_FORCE)) {
}
save_add_callback_buffer(hash, path, afhi_ptr, pad->flags, format_num, &obj);
/* Ask afs to consider this entry for adding. */
- ret = send_callback_request(com_add_callback, &obj, &result);
- if (ret > 0) {
- send_ret = send_va_buffer(pad->fd, "%s", (char *)result.data);
- free(result.data);
- }
+ ret = send_callback_request(com_add_callback, &obj, send_result, &pad->fd);
goto out_free;
out_unmap:
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,
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;
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;
+ result->size = tad.pb.offset;
return 1;
}
return ret < 0? ret : 0;
.lyrics_id = -1,
.image_id = -1
};
- struct osl_object query = {.data = &cto, .size = sizeof(cto)},
- result;
+ struct osl_object query = {.data = &cto, .size = sizeof(cto)};
int i, ret;
if (i >= argc)
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)
+ argv + i, com_touch_callback, send_result, &fd);
+ if (ret < 0)
send_va_buffer(fd, "%s\n", para_strerror(-ret));
return ret;
}
}
static int com_rm_callback(const struct osl_object *query,
- __a_unused struct osl_object *result)
+ struct osl_object *result)
{
struct com_rm_action_data crd = {.flags = *(uint32_t *)query->data};
int ret;
}
if (crd.pb.buf) {
result->data = crd.pb.buf;
- result->size = crd.pb.size;
+ result->size = crd.pb.offset;
return 1;
}
return ret < 0? ret : 0;
int com_rm(int fd, int argc, char * const * const argv)
{
uint32_t flags = 0;
- struct osl_object query = {.data = &flags, .size = sizeof(flags)},
- result;
+ struct osl_object query = {.data = &flags, .size = sizeof(flags)};
int i, ret;
for (i = 1; i < argc; i++) {
if (i >= argc)
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)
+ com_rm_callback, send_result, &fd);
+ if (ret < 0)
send_va_buffer(fd, "%s\n", para_strerror(-ret));
return ret;
}
}
if (cad.pb.buf) {
result->data = cad.pb.buf;
- result->size = cad.pb.size;
+ result->size = cad.pb.offset;
return 1;
}
return ret < 0? ret : 0;
{
unsigned flags = 0;
int i, ret;
- struct osl_object options = {.data = &flags, .size = sizeof(flags)},
- result;
+ struct osl_object options = {.data = &flags, .size = sizeof(flags)};
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!(flags & ~CPSI_FLAG_VERBOSE)) /* no copy flags given */
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
+ com_cpsi_callback, send_result, &fd);
+ if (ret < 0)
send_va_buffer(fd, "%s\n", para_strerror(-ret));
return ret;
}
para_printf(&pb, "checking audio file table...\n");
audio_file_loop(&pb, check_audio_file);
result->data = pb.buf;
- result->size = pb.size;
+ result->size = pb.offset;
return 1;
}