X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=aft.c;h=2b7a7af7efaa8d8fb72b55eb48616103c04cf1eb;hp=40c7e106b3b91bbee11b49d1d1c9b3ccf617b0ab;hb=ddae5908a9f0554d9eea303f3c8a97d7e8b754a1;hpb=c195a65dc54ef2ad7f0e96fa63d45a580a3dac37 diff --git a/aft.c b/aft.c index 40c7e106..2b7a7af7 100644 --- a/aft.c +++ b/aft.c @@ -804,8 +804,8 @@ static char *make_image_lines(struct afs_info *afsi) 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", @@ -814,9 +814,8 @@ static char *make_filename_lines(const char *path, unsigned flags) 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; } @@ -887,13 +886,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); - 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 */ @@ -909,7 +910,9 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts, "%s: %lu\n" /* seconds total */ "%s: %s\n" /* last played time */ "%s: %d\n" /* num_played */ - "%s\n", /* tag info */ + "%s" /* tag info */ + "%s: %lu\n" /* chunk time */ + "%s: %lu\n", /* num chunks */ filename_lines, have_score? status_item_list[SI_SCORE] : "", have_score? ": " : "", @@ -927,7 +930,9 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts, status_item_list[SI_SECONDS_TOTAL], afhi->seconds_total, status_item_list[SI_LAST_PLAYED], last_played_time, status_item_list[SI_NUM_PLAYED], afsi->num_played, - afhi->info_string + afhi->info_string, + status_item_list[SI_CHUNK_TIME], tv2ms(&afhi->chunk_tv), + status_item_list[SI_NUM_CHUNKS], afhi->chunks_total ); if (opts->mode == LS_MODE_MBOX) { struct osl_object lyrics_def; @@ -952,7 +957,7 @@ void make_empty_status_items(char *buf) "%s: \n" /* dirname */ "%s: \n" /* basename */ "%s: \n" /* score */ - "%s: \n" /* attributes bitnmap */ + "%s: \n" /* attributes bitmap */ "%s: \n" /* attributes txt */ "%s: \n" /* hash */ "%s: \n" /* image id */ @@ -1391,44 +1396,56 @@ static struct osl_row *find_hash_sister(HASH_TYPE *hash) return row; } -enum aft_row_offsets { - AFTROW_AFHI_OFFSET_POS = 0, - AFTROW_CHUNKS_OFFSET_POS = 2, - AFTROW_AUDIO_FORMAT_OFFSET = 4, - AFTROW_FLAGS_OFFSET = 5, - AFTROW_HASH_OFFSET = 9, - AFTROW_PATH_OFFSET = (AFTROW_HASH_OFFSET + HASH_SIZE), +/** The format of the data stored by save_audio_file_data(). */ +enum com_add_buffer_offsets { + /** afhi (if present) starts here. */ + CAB_AFHI_OFFSET_POS = 0, + /** Start of the chunk table (if present). */ + CAB_CHUNKS_OFFSET_POS = 2, + /** Audio format id. */ + CAB_AUDIO_FORMAT_OFFSET = 4, + /** Flags given to the add command. */ + CAB_FLAGS_OFFSET = 5, + /** The hash of the audio file being added. */ + CAB_HASH_OFFSET = 9, + /** Start of the path of the audio file. */ + CAB_PATH_OFFSET = (CAB_HASH_OFFSET + HASH_SIZE), }; -/* never save the afsi, as the server knows it too. Note that afhi might be NULL. - * In this case, afhi won't be stored in the buffer */ -static void save_audio_file_info(HASH_TYPE *hash, const char *path, +/* + * Store the given data to a single buffer. Doesn't need the audio file selector + * info struct as the server knows it as well. + * + * It's OK to call this with afhi == NULL. In this case, the audio format + * handler info won't be stored in the buffer. + */ +static void save_add_callback_buffer(HASH_TYPE *hash, const char *path, struct afh_info *afhi, uint32_t flags, uint8_t audio_format_num, struct osl_object *obj) { size_t path_len = strlen(path) + 1; size_t afhi_size = sizeof_afhi_buf(afhi); - size_t size = AFTROW_PATH_OFFSET + path_len + afhi_size + size_t size = CAB_PATH_OFFSET + path_len + afhi_size + sizeof_chunk_table(afhi); char *buf = para_malloc(size); uint16_t pos; - write_u8(buf + AFTROW_AUDIO_FORMAT_OFFSET, audio_format_num); - write_u32(buf + AFTROW_FLAGS_OFFSET, flags); + write_u8(buf + CAB_AUDIO_FORMAT_OFFSET, audio_format_num); + write_u32(buf + CAB_FLAGS_OFFSET, flags); - memcpy(buf + AFTROW_HASH_OFFSET, hash, HASH_SIZE); - strcpy(buf + AFTROW_PATH_OFFSET, path); + memcpy(buf + CAB_HASH_OFFSET, hash, HASH_SIZE); + strcpy(buf + CAB_PATH_OFFSET, path); - pos = AFTROW_PATH_OFFSET + path_len; + pos = CAB_PATH_OFFSET + path_len; PARA_DEBUG_LOG("size: %zu, afhi starts at %d\n", size, pos); PARA_DEBUG_LOG("last afhi byte: %p, pos %zu\n", buf + pos + afhi_size - 1, pos + afhi_size - 1); - write_u16(buf + AFTROW_AFHI_OFFSET_POS, pos); + write_u16(buf + CAB_AFHI_OFFSET_POS, pos); save_afhi(afhi, buf + pos); pos += afhi_size; PARA_DEBUG_LOG("size: %zu, chunks start at %d\n", size, pos); - write_u16(buf + AFTROW_CHUNKS_OFFSET_POS, pos); + write_u16(buf + CAB_CHUNKS_OFFSET_POS, pos); if (afhi) save_chunk_table(afhi, buf + pos); PARA_DEBUG_LOG("last byte in buf: %p\n", buf + size - 1); @@ -1437,43 +1454,53 @@ static void save_audio_file_info(HASH_TYPE *hash, const char *path, } /* -input: + +Overview of the add command. + +Input: What was passed to the callback by the command handler. ~~~~~~ -HS: hash sister -PB: path brother -F: force flag given +HS: Hash sister. Whether an audio file with identical hash + already exists in the osl database. + +PB: Path brother. Whether a file with the given path exists + in the table. -output: +F: Force flag given. Whether add was called with -f. + +output: Action performed by the callback. ~~~~~~~ -AFHI: whether afhi and chunk table are computed and sent -ACTION: table modifications to be performed - -+---+----+-----+------+---------------------------------------------------+ -| HS | PB | F | AFHI | ACTION -+---+----+-----+------+---------------------------------------------------+ -| Y | Y | Y | Y | if HS != PB: remove PB. HS: force afhi update, -| | update path, keep afsi -+---+----+-----+------+---------------------------------------------------+ -| Y | Y | N | N | if HS == PB: do not send callback request at all. -| | otherwise: remove PB, HS: update path, keep afhi, -| | afsi. -+---+----+-----+------+---------------------------------------------------+ -| Y | N | Y | Y | (rename) force afhi update of HS, update path of -| | HS, keep afsi -+---+----+-----+------+---------------------------------------------------+ -| Y | N | N | N | (file rename) update path of HS, keep afsi, afhi -+---+----+-----+------+---------------------------------------------------+ -| N | Y | Y | Y | (file change) update afhi, hash, of PB, keep afsi -| | (force has no effect) -+---+----+-----+------+---------------------------------------------------+ -| N | Y | N | Y | (file change) update afhi, hash of PB, keep afsi -+---+----+-----+------+---------------------------------------------------+ -| N | N | Y | Y | (new file) create new entry (force has no effect) -+---+----+-----+------+---------------------------------------------------+ -| N | N | N | Y | (new file) create new entry -+---+----+-----+------+---------------------------------------------------+ - -afhi <=> force or no HS +AFHI: Whether afhi and chunk table are computed and sent. +ACTION: Table modifications to be done by the callback. + ++----+----+---+------+---------------------------------------------------+ +| HS | PB | F | AFHI | ACTION ++----+----+---+------+---------------------------------------------------+ +| Y | Y | Y | Y | if HS != PB: remove PB. HS: force afhi update, +| | update path, keep afsi ++----+----+---+------+---------------------------------------------------+ +| Y | Y | N | N | if HS == PB: do not send callback request at all. +| | otherwise: remove PB, HS: update path, keep afhi, +| | afsi. ++----+----+---+------+---------------------------------------------------+ +| Y | N | Y | Y | (rename) force afhi update of HS, update path of +| | HS, keep afsi ++----+----+---+------+---------------------------------------------------+ +| Y | N | N | N | (file rename) update path of HS, keep afsi, afhi ++----+----+---+------+---------------------------------------------------+ +| N | Y | Y | Y | (file change) update afhi, hash, of PB, keep afsi +| | (force has no effect) ++----+----+---+------+---------------------------------------------------+ +| N | Y | N | Y | (file change) update afhi, hash of PB, keep afsi ++----+----+---+------+---------------------------------------------------+ +| N | N | Y | Y | (new file) create new entry (force has no effect) ++----+----+---+------+---------------------------------------------------+ +| N | N | N | Y | (new file) create new entry ++----+----+---+------+---------------------------------------------------+ + +Notes: + + afhi <=> force or no HS + F => AFHI */ @@ -1500,16 +1527,16 @@ static int com_add_callback(const struct osl_object *query, char asc[2 * HASH_SIZE + 1]; int ret; char afsi_buf[AFSI_SIZE]; - uint32_t flags = read_u32(buf + AFTROW_FLAGS_OFFSET); + uint32_t flags = read_u32(buf + CAB_FLAGS_OFFSET); struct afs_info default_afsi = {.last_played = 0}; struct para_buffer msg = {.buf = NULL}; - hash = (HASH_TYPE *)buf + AFTROW_HASH_OFFSET; + hash = (HASH_TYPE *)buf + CAB_HASH_OFFSET; hash_to_asc(hash, asc);; - objs[AFTCOL_HASH].data = buf + AFTROW_HASH_OFFSET; + objs[AFTCOL_HASH].data = buf + CAB_HASH_OFFSET; objs[AFTCOL_HASH].size = HASH_SIZE; - path = buf + AFTROW_PATH_OFFSET; + path = buf + CAB_PATH_OFFSET; objs[AFTCOL_PATH].data = path; objs[AFTCOL_PATH].size = strlen(path) + 1; @@ -1551,8 +1578,8 @@ static int com_add_callback(const struct osl_object *query, goto out; } /* no hs or force mode, child must have sent afhi */ - uint16_t afhi_offset = read_u16(buf + AFTROW_AFHI_OFFSET_POS); - uint16_t chunks_offset = read_u16(buf + AFTROW_CHUNKS_OFFSET_POS); + uint16_t afhi_offset = read_u16(buf + CAB_AFHI_OFFSET_POS); + uint16_t chunks_offset = read_u16(buf + CAB_CHUNKS_OFFSET_POS); objs[AFTCOL_AFHI].data = buf + afhi_offset; objs[AFTCOL_AFHI].size = chunks_offset - afhi_offset; @@ -1596,7 +1623,7 @@ static int com_add_callback(const struct osl_object *query, if (flags & ADD_FLAG_VERBOSE) para_printf(&msg, "new file\n"); default_afsi.last_played = time(NULL) - 365 * 24 * 60 * 60; - default_afsi.audio_format_id = read_u8(buf + AFTROW_AUDIO_FORMAT_OFFSET); + default_afsi.audio_format_id = read_u8(buf + CAB_AUDIO_FORMAT_OFFSET); objs[AFTCOL_AFSI].data = &afsi_buf; objs[AFTCOL_AFSI].size = AFSI_SIZE; @@ -1605,7 +1632,7 @@ static int com_add_callback(const struct osl_object *query, afs_event(AUDIO_FILE_ADD, &msg, aft_row); out: if (ret < 0) - para_printf(&msg, "%s\n", PARA_STRERROR(-ret)); + para_printf(&msg, "%s\n", para_strerror(-ret)); if (!msg.buf) return 0; result->data = msg.buf; @@ -1652,7 +1679,7 @@ static int hash_sister_callback(const struct osl_object *query, static int add_one_audio_file(const char *path, const void *private_data) { - int ret, ret2; + int ret, send_ret = 1; uint8_t format_num = -1; const struct private_add_data *pad = private_data; struct afh_info afhi, *afhi_ptr = NULL; @@ -1677,7 +1704,7 @@ static int add_one_audio_file(const char *path, const void *private_data) ret = 1; if (pb && (pad->flags & ADD_FLAG_LAZY)) { /* lazy is really cheap */ if (pad->flags & ADD_FLAG_VERBOSE) - ret = send_va_buffer(pad->fd, "lazy-ignore: %s\n", path); + send_ret = send_va_buffer(pad->fd, "lazy-ignore: %s\n", path); goto out_free; } /* We still want to add this file. Compute its hash. */ @@ -1686,27 +1713,27 @@ static int add_one_audio_file(const char *path, const void *private_data) goto out_free; hash_function(map.data, map.size, hash); - /* Check whether database contains file with the same hash. */ + /* 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); if (ret < 0 && ret != -E_RB_KEY_NOT_FOUND) - goto out_free; + 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))) { + if (pb && hs && hs == pb && !(pad->flags & ADD_FLAG_FORCE)) { if (pad->flags & ADD_FLAG_VERBOSE) - ret = send_va_buffer(pad->fd, + send_ret = send_va_buffer(pad->fd, "%s exists, not forcing update\n", path); goto out_unmap; } /* - * we won't recalculate the audio format info and the chunk table if - * there is a hash sister unless in FORCE mode. + * We won't recalculate the audio format info and the chunk table if + * there is a hash sister and FORCE was not given. */ if (!hs || (pad->flags & ADD_FLAG_FORCE)) { ret = compute_afhi(path, map.data, map.size, &afhi); @@ -1715,34 +1742,32 @@ static int add_one_audio_file(const char *path, const void *private_data) format_num = ret; afhi_ptr = &afhi; } + munmap(map.data, map.size); if (pad->flags & ADD_FLAG_VERBOSE) { - ret = send_va_buffer(pad->fd, "adding %s\n", path); - if (ret < 0) - goto out_unmap; + send_ret = send_va_buffer(pad->fd, "adding %s\n", path); + if (send_ret < 0) + goto out_free; } - munmap(map.data, map.size); - save_audio_file_info(hash, path, afhi_ptr, pad->flags, format_num, &obj); + 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) { - ret2 = send_va_buffer(pad->fd, "%s", (char *)result.data); + send_ret = send_va_buffer(pad->fd, "%s", (char *)result.data); free(result.data); - if (ret >= 0 && ret2 < 0) - ret = ret2; } goto out_free; out_unmap: munmap(map.data, map.size); out_free: - if (ret < 0 && ret != -E_SEND) - send_va_buffer(pad->fd, "failed to add %s (%s)\n", path, - PARA_STRERROR(-ret)); + if (ret < 0 && send_ret >= 0) + send_ret = send_va_buffer(pad->fd, "failed to add %s (%s)\n", path, + para_strerror(-ret)); free(obj.data); if (afhi_ptr) free(afhi_ptr->chunk_table); - /* it's not an error if not all files could be added */ - return ret == -E_SEND? ret : 1; + /* Stop adding files only on send errors. */ + return send_ret; } int com_add(int fd, int argc, char * const * const argv) @@ -1782,7 +1807,8 @@ int com_add(int fd, int argc, char * const * const argv) char *path; ret = verify_path(argv[i], &path); if (ret < 0) { - ret = send_va_buffer(fd, "%s: %s\n", argv[i], PARA_STRERROR(-ret)); + ret = send_va_buffer(fd, "%s: %s\n", argv[i], + para_strerror(-ret)); if (ret < 0) return ret; continue; @@ -1802,7 +1828,7 @@ int com_add(int fd, int argc, char * const * const argv) else ret = add_one_audio_file(path, &pad); if (ret < 0) { - send_va_buffer(fd, "%s: %s\n", path, PARA_STRERROR(-ret)); + send_va_buffer(fd, "%s: %s\n", path, para_strerror(-ret)); free(path); return ret; } @@ -1858,12 +1884,12 @@ static int touch_audio_file(__a_unused struct osl_table *table, ret = get_afsi_object_of_row(row, &obj); if (ret < 0) { - para_printf(&tad->pb, "%s: %s\n", name, PARA_STRERROR(-ret)); + para_printf(&tad->pb, "%s: %s\n", name, para_strerror(-ret)); return 1; } ret = load_afsi(&old_afsi, &obj); if (ret < 0) { - para_printf(&tad->pb, "%s: %s\n", name, PARA_STRERROR(-ret)); + para_printf(&tad->pb, "%s: %s\n", name, para_strerror(-ret)); return 1; } new_afsi = old_afsi; @@ -1911,7 +1937,7 @@ static int com_touch_callback(const struct osl_object *query, pmd.fnmatch_flags |= FNM_PATHNAME; ret = for_each_matching_row(&pmd); if (ret < 0) - para_printf(&tad.pb, "%s\n", PARA_STRERROR(-ret)); + para_printf(&tad.pb, "%s\n", para_strerror(-ret)); if (tad.pb.buf) { result->data = tad.pb.buf; result->size = tad.pb.size; @@ -1983,7 +2009,7 @@ int com_touch(int fd, int argc, char * const * const argv) send_buffer(fd, (char *)result.data); free(result.data); } else if (ret < 0) - send_va_buffer(fd, "%s\n", PARA_STRERROR(-ret)); + send_va_buffer(fd, "%s\n", para_strerror(-ret)); return ret; } @@ -2018,7 +2044,7 @@ static int remove_audio_file(__a_unused struct osl_table *table, afs_event(AUDIO_FILE_REMOVE, &crd->pb, row); ret = osl_del_row(audio_file_table, row); if (ret < 0) - para_printf(&crd->pb, "%s: %s\n", name, PARA_STRERROR(-ret)); + para_printf(&crd->pb, "%s: %s\n", name, para_strerror(-ret)); else crd->num_removed++; return 1; @@ -2042,7 +2068,7 @@ static int com_rm_callback(const struct osl_object *query, pmd.fnmatch_flags |= FNM_PATHNAME; ret = for_each_matching_row(&pmd); if (ret < 0) - para_printf(&crd.pb, "%s\n", PARA_STRERROR(-ret)); + para_printf(&crd.pb, "%s\n", para_strerror(-ret)); if (!crd.num_removed && !(crd.flags & RM_FLAG_FORCE)) para_printf(&crd.pb, "no matches -- nothing removed\n"); else { @@ -2095,7 +2121,7 @@ int com_rm(int fd, int argc, char * const * const argv) send_buffer(fd, (char *)result.data); free(result.data); } else if (ret < 0) - send_va_buffer(fd, "%s\n", PARA_STRERROR(-ret)); + send_va_buffer(fd, "%s\n", para_strerror(-ret)); return ret; } @@ -2188,7 +2214,7 @@ static int com_cpsi_callback(const struct osl_object *query, ret = for_each_matching_row(&pmd); out: if (ret < 0) - para_printf(&cad.pb, "%s\n", PARA_STRERROR(-ret)); + para_printf(&cad.pb, "%s\n", para_strerror(-ret)); if (cad.flags & CPSI_FLAG_VERBOSE) { if (cad.num_copied) para_printf(&cad.pb, "copied requested afsi from %s " @@ -2256,7 +2282,7 @@ int com_cpsi(int fd, int argc, char * const * const argv) send_buffer(fd, (char *)result.data); free(result.data); } else - send_va_buffer(fd, "%s\n", PARA_STRERROR(-ret)); + send_va_buffer(fd, "%s\n", para_strerror(-ret)); return ret; } @@ -2271,7 +2297,7 @@ static int check_audio_file(struct osl_row *row, void *data) char *blob_name; if (ret < 0) { - para_printf(pb, "%s\n", PARA_STRERROR(-ret)); + para_printf(pb, "%s\n", para_strerror(-ret)); return 1; } if (stat(path, &statbuf) < 0) @@ -2282,17 +2308,17 @@ static int check_audio_file(struct osl_row *row, void *data) } ret = get_afsi_of_row(row, &afsi); if (ret < 0) { - para_printf(pb, "%s: %s\n", path, PARA_STRERROR(-ret)); + para_printf(pb, "%s: %s\n", path, para_strerror(-ret)); return 1; } ret = lyr_get_name_by_id(afsi.lyrics_id, &blob_name); if (ret < 0) para_printf(pb, "%s lyrics id %u: %s\n", path, afsi.lyrics_id, - PARA_STRERROR(-ret)); + para_strerror(-ret)); ret = img_get_name_by_id(afsi.image_id, &blob_name); if (ret < 0) para_printf(pb, "%s image id %u: %s\n", path, afsi.image_id, - PARA_STRERROR(-ret)); + para_strerror(-ret)); return 1; }