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;
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;
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;
+}
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
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);
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.
*
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 \