From: Andre Noll Date: Sun, 23 Sep 2007 15:17:45 +0000 (+0200) Subject: Implement check command. X-Git-Tag: v0.3.0~374 X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=a044e78188411351d798842df1778316c881f5ed;p=paraslash.git Implement check command. Currently it only checks the audio file table. Checking moods and playlists will be implemented in a subsequent patch. --- diff --git a/afs.c b/afs.c index 6d51d4f5..44eeacc9 100644 --- a/afs.c +++ b/afs.c @@ -144,11 +144,12 @@ int send_callback_request(callback_function *f, struct osl_object *query, int ret, fd = -1, query_shmid, result_shmid; void *query_shm, *result_shm; char buf[sizeof(afs_socket_cookie) + sizeof(int)]; -// char *tmpsocket_name; struct sockaddr_un unix_addr; + size_t query_shm_size = sizeof(*cq); - assert(query->data && query->size); - ret = shm_new(query->size + sizeof(*cq)); + if (query) + query_shm_size += query->size; + ret = shm_new(query_shm_size); if (ret < 0) return ret; query_shmid = ret; @@ -157,9 +158,10 @@ int send_callback_request(callback_function *f, struct osl_object *query, goto out; cq = query_shm; cq->handler = f; - cq->query_size = query->size; + cq->query_size = query_shm_size - sizeof(*cq); - memcpy(query_shm + sizeof(*cq), query->data, query->size); + if (query) + memcpy(query_shm + sizeof(*cq), query->data, query->size); ret = shm_detach(query_shm); if (ret < 0) goto out; @@ -855,3 +857,51 @@ int com_init(int fd, int argc, char * const * const argv) return ret; return send_va_buffer(fd, "successfully created afs table(s)\n"); } + +enum com_check_flags { + CHECK_AFT = 1, + CHECK_MOODS_TABLE = 8, + CHECK_PLAYLISTS = 16 +}; + +int com_check(int fd, int argc, char * const * const argv) +{ + unsigned flags = 0; + int i, ret; + struct osl_object result; + + for (i = 1; i < argc; i++) { + const char *arg = argv[i]; + if (arg[0] != '-') + break; + if (!strcmp(arg, "--")) { + i++; + break; + } + if (!strcmp(arg, "-a")) { + flags |= CHECK_AFT; + continue; + } + if (!strcmp(arg, "-p")) { + flags |= CHECK_PLAYLISTS; + continue; + } + return -E_AFS_SYNTAX; + } + if (i < argc) + return -E_AFS_SYNTAX; + if (!flags) + flags = ~0U; + if (flags & CHECK_AFT) { + ret = send_callback_request(aft_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.cmd b/afs.cmd index 9a4bbdcd..b3d3ec91 100644 --- a/afs.cmd +++ b/afs.cmd @@ -101,6 +101,12 @@ U: addatt attribute1 [attribute2 ...] H: This adds new attributes to the attribute table. At most 64 attributes H: may be defined. --- +N: check +P: AFS_READ +D: Run integrity checks for the osl tables. +U: check [-a] [-m] [-p] +H: FIXME +--- N: rmatt P: AFS_READ | AFS_WRITE D: FIXME diff --git a/afs.h b/afs.h index ba8964c7..7adb54bd 100644 --- a/afs.h +++ b/afs.h @@ -137,6 +137,7 @@ int get_afsi_of_row(const struct osl_row *row, struct afs_info *afsi); int get_audio_file_path_of_row(const struct osl_row *row, char **path); int get_afsi_object_of_row(const struct osl_row *row, struct osl_object *obj); int audio_file_loop(void *private_data, osl_rbtree_loop_func *func); +int aft_check_callback(const struct osl_object *query, struct osl_object *result); /* mood */ int mood_open(char *mood_name); diff --git a/aft.c b/aft.c index 423731f6..1a0fdc79 100644 --- a/aft.c +++ b/aft.c @@ -1695,6 +1695,53 @@ err: return ret; } +/* TODO: optionally fix problems by removing offending rows */ +static int check_audio_file(struct osl_row *row, void *data) +{ + char *path; + struct para_buffer *pb = data; + struct stat statbuf; + int ret = get_audio_file_path_of_row(row, &path); + struct afs_info afsi; + char *blob_name; + + if (ret < 0) { + para_printf(pb, "%s\n", PARA_STRERROR(-ret)); + return 1; + } + if (stat(path, &statbuf) < 0) + para_printf(pb, "%s: stat error (%s)\n", path, strerror(errno)); + else { + if (!S_ISREG(statbuf.st_mode)) + para_printf(pb, "%s: not a regular file\n", path); + } + ret = get_afsi_of_row(row, &afsi); + if (ret < 0) { + 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: %s\n", path, 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)); + return 1; +} + +int aft_check_callback(__a_unused const struct osl_object *query, struct osl_object *result) +{ + struct para_buffer pb = {.buf = NULL}; + + audio_file_loop(&pb, check_audio_file); + if (!pb.size) + return 0; + result->data = pb.buf; + result->size = pb.size; + return 1; + +} + /** * Close the audio file table. * diff --git a/error.h b/error.h index 7d2424cf..ca97dba6 100644 --- a/error.h +++ b/error.h @@ -154,6 +154,7 @@ extern const char **para_errlist[]; PARA_ERROR(INPUT_TOO_LARGE, "input too large for stdin command"), \ PARA_ERROR(READ, "read error"), \ PARA_ERROR(ATOL, "failed to convert to long"), \ + PARA_ERROR(AFS_SYNTAX, "afs syntax error"), \ #define MOOD_ERRORS \