From 15151d60026dfe17cfaad02284d0abbb8b9389b2 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 23 Sep 2007 19:34:17 +0200 Subject: [PATCH] Implement check for invalid playlist entries. Also some minor improvements for the audio file table checks. --- afs.c | 19 +++++++++- afs.h | 2 + aft.c | 9 +++-- blob.c | 1 + playlist.c | 109 +++++++++++++++++++++++++++++++++++++---------------- 5 files changed, 102 insertions(+), 38 deletions(-) diff --git a/afs.c b/afs.c index 44eeacc9..a95ca415 100644 --- a/afs.c +++ b/afs.c @@ -860,8 +860,8 @@ int com_init(int fd, int argc, char * const * const argv) enum com_check_flags { CHECK_AFT = 1, - CHECK_MOODS_TABLE = 8, - CHECK_PLAYLISTS = 16 + CHECK_MOODS = 2, + CHECK_PLAYLISTS = 4 }; int com_check(int fd, int argc, char * const * const argv) @@ -886,6 +886,10 @@ int com_check(int fd, int argc, char * const * const argv) flags |= CHECK_PLAYLISTS; continue; } + if (!strcmp(arg, "-m")) { + flags |= CHECK_MOODS; + continue; + } return -E_AFS_SYNTAX; } if (i < argc) @@ -903,5 +907,16 @@ int com_check(int fd, int argc, char * const * const argv) return ret; } } + if (flags & CHECK_PLAYLISTS) { + ret = send_callback_request(playlist_check_callback, NULL, &result); + if (ret < 0) + return ret; + if (ret > 0) { + ret = send_buffer(fd, (char *) result.data); + free(result.data); + if (ret < 0) + return ret; + } + } return 1; } diff --git a/afs.h b/afs.h index 7adb54bd..d6d0a86e 100644 --- a/afs.h +++ b/afs.h @@ -151,6 +151,8 @@ int mood_delete_audio_file(const struct osl_row *aft_row); int playlist_open(char *name); void playlist_close(void); int playlist_update_audio_file(struct osl_row *aft_row); +int playlist_check_callback(__a_unused const struct osl_object *query, + struct osl_object *result); /** evaluates to 1 if x < y, to -1 if x > y and to 0 if x == y */ #define NUM_COMPARE(x, y) ((int)((x) < (y)) - (int)((x) > (y))) diff --git a/aft.c b/aft.c index 1a0fdc79..0f15cd28 100644 --- a/aft.c +++ b/aft.c @@ -1722,10 +1722,12 @@ static int check_audio_file(struct osl_row *row, void *data) } ret = lyr_get_name_by_id(afsi.lyrics_id, &blob_name); if (ret < 0) - para_printf(pb, "%s lyrics id: %s\n", path, PARA_STRERROR(-ret)); + para_printf(pb, "%s lyrics id %u: %s\n", path, afsi.lyrics_id, + PARA_STRERROR(-ret)); ret = img_get_name_by_id(afsi.image_id, &blob_name); if (ret < 0) - para_printf(pb, "%s image id: %s\n", path, PARA_STRERROR(-ret)); + para_printf(pb, "%s image id %u: %s\n", path, afsi.image_id, + PARA_STRERROR(-ret)); return 1; } @@ -1733,9 +1735,8 @@ int aft_check_callback(__a_unused const struct osl_object *query, struct osl_obj { struct para_buffer pb = {.buf = NULL}; + para_printf(&pb, "checking audio file table...\n"); audio_file_loop(&pb, check_audio_file); - if (!pb.size) - return 0; result->data = pb.buf; result->size = pb.size; return 1; diff --git a/blob.c b/blob.c index b396ef79..20151241 100644 --- a/blob.c +++ b/blob.c @@ -338,6 +338,7 @@ static int blob_get_name_by_id(struct osl_table *table, uint32_t id, *name = (char *)obj.data; return 1; } + /** Define the \p get_name_by_id function for this blob type. */ #define DEFINE_GET_NAME_BY_ID(table_name, cmd_prefix) \ int cmd_prefix ## _get_name_by_id(uint32_t id, char **name) \ diff --git a/playlist.c b/playlist.c index 272f25ac..429ad2b5 100644 --- a/playlist.c +++ b/playlist.c @@ -28,72 +28,72 @@ int playlist_update_audio_file(struct osl_row *aft_row) return score_update(aft_row, 0); } -static int add_playlist_entry(char *line, void *data) +static int add_playlist_entry(char *path, void *data) { struct playlist_info *playlist = data; struct osl_row *aft_row; - int ret = aft_get_row_of_path(line, &aft_row); + int ret = aft_get_row_of_path(path, &aft_row); if (ret < 0) { - PARA_NOTICE_LOG("path not found in audio file table: %s\n", - line); + PARA_NOTICE_LOG("%s: %s\n", path, PARA_STRERROR(-ret)); return 1; } ret = score_add(aft_row, -playlist->length); if (ret < 0) { - PARA_ERROR_LOG("failed to add %s: %d\n", line, ret); + PARA_ERROR_LOG("failed to add %s: %d\n", path, ret); return ret; } playlist->length++; return 1; } -static int load_playlist(struct osl_row *row, struct playlist_info *playlist) +static int get_playlist_data(struct osl_row *row, char **playlist_name, + struct osl_object *playlist_def) { struct osl_object obj; - int ret; - - ret = osl_get_object(playlists_table, row, BLOBCOL_NAME, &obj); + int ret = osl_get_object(playlists_table, row, BLOBCOL_NAME, &obj); if (ret < 0) return ret; - playlist->name = para_strdup(obj.data); - playlist->length = 0; - ret = osl_open_disk_object(playlists_table, row, BLOBCOL_DEF, &obj); + *playlist_name = obj.data; + return osl_open_disk_object(playlists_table, row, BLOBCOL_DEF, + playlist_def); +} + +/* returns -E_PLAYLIST_LOADED on _success_ to terminate the loop */ +static int load_playlist(struct osl_row *row, void *data) +{ + struct playlist_info *playlist = data; + struct osl_object playlist_def; + char *playlist_name; + int ret; + + ret = get_playlist_data(row, &playlist_name, &playlist_def); if (ret < 0) goto err; - ret = for_each_line_ro(obj.data, obj.size, add_playlist_entry, - playlist); - osl_close_disk_object(&obj); + playlist->length = 0; + ret = for_each_line_ro(playlist_def.data, playlist_def.size, + add_playlist_entry, playlist); + osl_close_disk_object(&playlist_def); if (ret < 0) goto err; ret = -E_PLAYLIST_EMPTY; if (!playlist->length) goto err; + playlist->name = para_strdup(playlist_name); PARA_NOTICE_LOG("loaded playlist %s (%u files)\n", playlist->name, playlist->length); - return 1; -err: - free(playlist->name); - return ret; -} - -/* returns -E_PLAYLIST_LOADED on _success_ to terminate the loop */ -static int playlist_loop(struct osl_row *row, void *data) -{ - struct playlist_info *playlist = data; - int ret = load_playlist(row, playlist); - if (ret < 0) { - if (ret != -E_DUMMY_ROW) - PARA_NOTICE_LOG("unable to load playlist, trying next\n"); - return 1; - } return -E_PLAYLIST_LOADED; +err: + if (ret != -E_DUMMY_ROW) + PARA_NOTICE_LOG("unable to load playlist (%s)\n", + PARA_STRERROR(-ret)); + return 1; } static int load_first_available_playlist(struct playlist_info *playlist) { int ret = osl_rbtree_loop(playlists_table, BLOBCOL_NAME, playlist, - playlist_loop); + load_playlist); if (ret == -E_PLAYLIST_LOADED) /* success */ return 1; if (ret < 0) @@ -102,6 +102,51 @@ static int load_first_available_playlist(struct playlist_info *playlist) return -E_NO_PLAYLIST; } +static int check_playlist_path(char *path, void *data) +{ + struct para_buffer *pb = data; + struct osl_row *aft_row; + int ret = aft_get_row_of_path(path, &aft_row); + + if (ret < 0) + para_printf(pb, "%s: %s\n", path, PARA_STRERROR(-ret)); + return 1; +} + +static int check_playlist(struct osl_row *row, void *data) +{ + struct para_buffer *pb = data; + struct osl_object playlist_def; + char *playlist_name; + int ret = get_playlist_data(row, &playlist_name, &playlist_def); + + if (ret < 0) { + para_printf(pb, "failed to get playlist data: %s\n", + PARA_STRERROR(-ret)); + return 1; + } + if (*playlist_name) { /* skip dummy row */ + para_printf(pb, "checking playlist %s...\n", playlist_name); + for_each_line_ro(playlist_def.data, playlist_def.size, + check_playlist_path, pb); + } + osl_close_disk_object(&playlist_def); + return 1; +} + +int playlist_check_callback(__a_unused const struct osl_object *query, + struct osl_object *result) +{ + struct para_buffer pb = {.buf = NULL}; + + para_printf(&pb, "checking playlists...\n"); + osl_rbtree_loop(playlists_table, BLOBCOL_ID, &pb, + check_playlist); + result->data = pb.buf; + result->size = pb.size; + return 1; +} + /** * Close the current playlist. * -- 2.39.5