free(pb->buf);
}
-static int com_select_callback(int fd, const struct osl_object *query)
+static int com_select_callback(struct afs_callback_arg *aca)
{
struct para_buffer pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler,
};
- char *arg = query->data;
+ char *arg = aca->query.data;
int num_admissible, ret;
ret = clear_score_table();
{
void *query_shm;
struct callback_query *cq;
- struct osl_object query;
int ret, ret2;
+ struct afs_callback_arg aca = {.fd = fd};
ret = shm_attach(query_shmid, ATTACH_RW, &query_shm);
if (ret < 0)
return ret;
cq = query_shm;
- query.data = (char *)query_shm + sizeof(*cq);
- query.size = cq->query_size;
- ret = cq->handler(fd, &query);
+ aca.query.data = (char *)query_shm + sizeof(*cq);
+ aca.query.size = cq->query_size;
+ ret = cq->handler(&aca);
ret2 = shm_detach(query_shm);
if (ret2 < 0) {
if (ret < 0) /* ignore (but log) detach error */
exit(EXIT_FAILURE);
}
-static int com_init_callback(int fd, const struct osl_object *query)
+static int com_init_callback(struct afs_callback_arg *aca)
{
- uint32_t table_mask = *(uint32_t *)query->data;
+ uint32_t table_mask = *(uint32_t *)aca->query.data;
int i, ret;
struct para_buffer pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
}
};
int (*action)(struct osl_table *table, struct osl_row *row, const char *name, void *data);
};
+/** Arguments passed to each afs callback. */
+struct afs_callback_arg {
+ /** The local socket connecting afs and the command handler. */
+ int fd;
+ /** Callback-specific data. */
+ struct osl_object query;
+};
/**
* Afs command handlers run as a process which is not related to the afs
*
* \sa send_callback_request().
*/
-typedef int afs_callback(int fd, const struct osl_object *);
+typedef int afs_callback(struct afs_callback_arg *aca);
/**
* Callbacks send chunks to data back to the command handler. Pointers to
void get_attribute_bitmap(const uint64_t *atts, char *buf); /* needed by com_ls() */
int get_attribute_bitnum_by_name(const char *att_name, unsigned char *bitnum);
int get_attribute_text(uint64_t *atts, const char *delim, char **text);
-int attribute_check_callback(int fd, __a_unused const struct osl_object *query);
+int attribute_check_callback(struct afs_callback_arg *aca);
/* aft */
void aft_init(struct afs_table *t);
int get_afhi_of_row(const struct osl_row *row, struct afh_info *afhi);
int get_audio_file_path_of_row(const struct osl_row *row, char **path);
int audio_file_loop(void *private_data, osl_rbtree_loop_func *func);
-int aft_check_callback(int fd, __a_unused const struct osl_object *query);
+int aft_check_callback(struct afs_callback_arg *aca);
/* playlist */
int playlist_open(char *name);
void playlist_close(void);
-int playlist_check_callback(int fd, __a_unused const struct osl_object *query);
+int playlist_check_callback(struct afs_callback_arg *aca);
/** 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)))
return ret;
}
-static int com_ls_callback(int fd, const struct osl_object *query)
+static int com_ls_callback(struct afs_callback_arg *aca)
{
- struct ls_options *opts = query->data;
- char *p, *pattern_start = (char *)query->data + sizeof(*opts);
+ struct ls_options *opts = aca->query.data;
+ char *p, *pattern_start = (char *)aca->query.data + sizeof(*opts);
struct para_buffer b = {
.max_size = shm_get_shmmax(),
.flags = (opts->mode == LS_MODE_PARSER)? PBF_SIZE_PREFIX : 0,
.max_size_handler = afs_max_size_handler,
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
}
};
ADD_FLAG_ALL = 8,
};
-static int com_add_callback(int fd, const struct osl_object *query)
+static int com_add_callback(struct afs_callback_arg *aca)
{
- char *buf = query->data, *path;
+ char *buf = aca->query.data, *path;
struct osl_row *pb, *aft_row;
struct osl_row *hs;
struct osl_object objs[NUM_AFT_COLUMNS];
.max_size = shm_get_shmmax(),
.max_size_handler = afs_max_size_handler,
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
}
};
if (!objs[AFTCOL_AFHI].size) /* "impossible" */
goto out;
objs[AFTCOL_CHUNKS].data = buf + chunks_offset;
- objs[AFTCOL_CHUNKS].size = query->size - chunks_offset;
+ objs[AFTCOL_CHUNKS].size = aca->query.size - chunks_offset;
if (pb && !hs) { /* update pb's hash */
char old_asc[2 * HASH_SIZE + 1];
unsigned char *old_hash;
uint32_t flags;
};
-static int path_brother_callback(int fd, const struct osl_object *query)
+static int path_brother_callback(struct afs_callback_arg *aca)
{
- char *path = query->data;
+ char *path = aca->query.data;
struct osl_row *path_brother;
int ret = aft_get_row_of_path(path, &path_brother);
if (ret < 0)
return ret;
- return pass_buffer_as_shm(fd, SBD_OUTPUT, (char *)&path_brother,
+ return pass_buffer_as_shm(aca->fd, SBD_OUTPUT, (char *)&path_brother,
sizeof(path_brother));
}
-static int hash_sister_callback(int fd, const struct osl_object *query)
+static int hash_sister_callback(struct afs_callback_arg *aca)
{
- unsigned char *hash = query->data;
+ unsigned char *hash = aca->query.data;
struct osl_row *hash_sister;
hash_sister = find_hash_sister(hash);
if (!hash_sister)
return 0;
- return pass_buffer_as_shm(fd, SBD_OUTPUT, (char *)&hash_sister,
+ return pass_buffer_as_shm(aca->fd, SBD_OUTPUT, (char *)&hash_sister,
sizeof(hash_sister));
}
return afs_event(AFSI_CHANGE, &tad->pb, &aced);
}
-static int com_touch_callback(int fd, const struct osl_object *query)
+static int com_touch_callback(struct afs_callback_arg *aca)
{
- struct touch_action_data tad = {.cto = query->data,
+ struct touch_action_data tad = {.cto = aca->query.data,
.pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler
.table = audio_file_table,
.loop_col_num = AFTCOL_HASH,
.match_col_num = AFTCOL_PATH,
- .patterns = {.data = (char *)query->data + sizeof(*tad.cto),
- .size = query->size - sizeof(*tad.cto)},
+ .patterns = {.data = (char *)aca->query.data + sizeof(*tad.cto),
+ .size = aca->query.size - sizeof(*tad.cto)},
.data = &tad,
.action = touch_audio_file
};
return ret;
}
-static int com_rm_callback(int fd, const struct osl_object *query)
+static int com_rm_callback(struct afs_callback_arg *aca)
{
- struct com_rm_action_data crd = {.flags = *(uint32_t *)query->data,
+ struct com_rm_action_data crd = {.flags = *(uint32_t *)aca->query.data,
.pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler
.table = audio_file_table,
.loop_col_num = AFTCOL_HASH,
.match_col_num = AFTCOL_PATH,
- .patterns = {.data = (char *)query->data + sizeof(uint32_t),
- .size = query->size - sizeof(uint32_t)},
+ .patterns = {.data = (char *)aca->query.data + sizeof(uint32_t),
+ .size = aca->query.size - sizeof(uint32_t)},
.data = &crd,
.action = remove_audio_file
};
return afs_event(AFSI_CHANGE, &cad->pb, &aced);
}
-static int com_cpsi_callback(int fd, const struct osl_object *query)
+static int com_cpsi_callback(struct afs_callback_arg *aca)
{
struct cpsi_action_data cad = {
- .flags = *(unsigned *)query->data,
+ .flags = *(unsigned *)aca->query.data,
.pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler
}
};
int ret;
- char *source_path = (char *)query->data + sizeof(cad.flags);
+ char *source_path = (char *)aca->query.data + sizeof(cad.flags);
struct pattern_match_data pmd = {
.table = audio_file_table,
.loop_col_num = AFTCOL_HASH,
.match_col_num = AFTCOL_PATH,
.patterns = {.data = source_path + strlen(source_path) + 1,
- .size = query->size - sizeof(cad.flags)
+ .size = aca->query.size - sizeof(cad.flags)
- strlen(source_path) - 1},
.data = &cad,
.action = copy_selector_info
return afs_event(AFSI_CHANGE, &cad->pb, &aced);
}
-static int com_setatt_callback(int fd, const struct osl_object *query)
+static int com_setatt_callback(struct afs_callback_arg *aca)
{
char *p;
int ret;
.max_size = shm_get_shmmax(),
.max_size_handler = afs_max_size_handler,
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
}
}
.action = change_atts
};
- for (p = query->data; p < (char *)query->data + query->size; p += len + 1) {
+ for (
+ p = aca->query.data;
+ p < (char *)aca->query.data + aca->query.size;
+ p += len + 1
+ ) {
char c;
unsigned char bitnum;
if (!cad.add_mask && !cad.del_mask)
goto out;
pmd.patterns.data = p;
- assert(p < (char *)query->data + query->size);
- pmd.patterns.size = (char *)query->data + query->size - p;
+ assert(p < (char *)aca->query.data + aca->query.size);
+ pmd.patterns.size = (char *)aca->query.data + aca->query.size - p;
ret = for_each_matching_row(&pmd);
if (ret < 0)
goto out;
com_setatt_callback, afs_cb_result_handler, cc);
}
-static int afs_stat_callback(int fd, const struct osl_object *query)
+static int afs_stat_callback(struct afs_callback_arg *aca)
{
- int *parser_friendly = query->data;
+ int *parser_friendly = aca->query.data;
char *buf = *parser_friendly?
parser_friendly_status_items : status_items;
if (!buf)
return 0;
- return pass_buffer_as_shm(fd, SBD_OUTPUT, buf, strlen(buf));
+ return pass_buffer_as_shm(aca->fd, SBD_OUTPUT, buf, strlen(buf));
}
/**
/**
* Check the audio file table for inconsistencies.
*
- * \param fd The afs socket.
- * \param query Unused.
+ * \param aca Only ->pbout is used for diagnostics.
*
* \return Standard. Inconsistencies are reported but not regarded as an error.
*
* \sa com_check().
*/
-int aft_check_callback(int fd, __a_unused const struct osl_object *query)
+int aft_check_callback(struct afs_callback_arg *aca)
{
int ret;
struct para_buffer pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler
return 1;
}
-static int com_lsatt_callback(int fd, const struct osl_object *query)
+static int com_lsatt_callback(struct afs_callback_arg *aca)
{
int ret;
struct lsatt_action_data laad = {
- .flags = *(unsigned *) query->data,
+ .flags = *(unsigned *)aca->query.data,
.pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler
.table = attribute_table,
.loop_col_num = ATTCOL_BITNUM,
.match_col_num = ATTCOL_NAME,
- .patterns = {.data = (char *)query->data + sizeof(laad.flags),
- .size = query->size - sizeof(laad.flags)},
+ .patterns = {.data = (char *)aca->query.data + sizeof(laad.flags),
+ .size = aca->query.size - sizeof(laad.flags)},
.pm_flags = PM_NO_PATTERN_MATCHES_EVERYTHING,
.data = &laad,
.action = print_attribute
};
-static int com_addatt_callback(int fd, const struct osl_object *query)
+static int com_addatt_callback(struct afs_callback_arg *aca)
{
char *p;
int ret = 1;
struct para_buffer pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler
};
size_t len;
- for (p = query->data; p < (char *)query->data + query->size; p += len + 1) {
+ for (
+ p = aca->query.data;
+ p < (char *)aca->query.data + aca->query.size;
+ p += len + 1
+ ) {
struct osl_object objs[NUM_ATT_COLUMNS];
struct osl_row *row;
unsigned char bitnum;
return ret;
}
-static int com_mvatt_callback(int fd, const struct osl_object *query)
+static int com_mvatt_callback(struct afs_callback_arg *aca)
{
- char *old = query->data;
+ char *old = aca->query.data;
size_t size = strlen(old) + 1;
char *new = old + size;
struct osl_object obj = {.data = old, .size = size};
struct para_buffer pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler,
return afs_event(ATTRIBUTE_REMOVE, pb, &red);
}
-static int com_rmatt_callback(int fd, const struct osl_object *query)
+static int com_rmatt_callback(struct afs_callback_arg *aca)
{
struct para_buffer pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler,
int ret;
struct pattern_match_data pmd = {
.table = attribute_table,
- .patterns = *query,
+ .patterns = aca->query,
.loop_col_num = ATTCOL_BITNUM,
.match_col_num = ATTCOL_NAME,
.data = &pb,
/**
* Compute the attribute bit mask and check each afs info bitmap.
*
- * \param fd Needed for the para buffer.
- * \param query Unused.
+ * \param aca The query field of \a aca is ignored.
*
* This iterates over all attributes in the attribute table and computes the
* logical or of 1 << b where b is the bit number of the attribute. The
*
* \sa \ref aft_check_attributes().
*/
-int attribute_check_callback(int fd, __a_unused const struct osl_object *query)
+int attribute_check_callback(struct afs_callback_arg *aca)
{
int ret;
uint64_t att_mask = 0; /* bits corresponding to a attributes */
struct para_buffer pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler,
}
static int com_lsblob_callback(struct osl_table *table,
- int fd, const struct osl_object *query)
+ struct afs_callback_arg *aca)
{
struct lsblob_action_data lbad = {
- .flags = *(uint32_t *)query->data,
+ .flags = *(uint32_t *)aca->query.data,
.pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler,
};
struct pattern_match_data pmd = {
.table = table,
- .patterns = {.data = (char *)query->data + sizeof(uint32_t),
- .size = query->size - sizeof(uint32_t)},
+ .patterns = {.data = (char *)aca->query.data + sizeof(uint32_t),
+ .size = aca->query.size - sizeof(uint32_t)},
.pm_flags = PM_NO_PATTERN_MATCHES_EVERYTHING | PM_SKIP_EMPTY_NAME,
.match_col_num = BLOBCOL_NAME,
.data = &lbad,
return (ret < 0)? ret : ret2;
}
-static int com_catblob_callback(struct osl_table *table, int fd,
- const struct osl_object *query)
+static int com_catblob_callback(struct osl_table *table,
+ struct afs_callback_arg *aca)
{
int ret;
struct pattern_match_data pmd = {
.table = table,
- .patterns = *query,
+ .patterns = aca->query,
.loop_col_num = BLOBCOL_NAME,
.match_col_num = BLOBCOL_NAME,
.pm_flags = PM_SKIP_EMPTY_NAME,
- .data = &fd,
+ .data = &aca->fd,
.action = cat_blob
};
ret = for_each_matching_row(&pmd);
return 1;
}
-static int com_rmblob_callback(struct osl_table *table, int fd,
- const struct osl_object *query)
+static int com_rmblob_callback(struct osl_table *table,
+ struct afs_callback_arg *aca)
{
int ret;
struct para_buffer pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler,
};
struct pattern_match_data pmd = {
.table = table,
- .patterns = *query,
+ .patterns = aca->query,
.loop_col_num = BLOBCOL_NAME,
.match_col_num = BLOBCOL_NAME,
.pm_flags = PM_SKIP_EMPTY_NAME,
afs_cb_result_handler, cc);
}
-static int com_addblob_callback(struct osl_table *table, int fd,
- const struct osl_object *query)
+static int com_addblob_callback(struct osl_table *table,
+ struct afs_callback_arg *aca)
{
struct osl_object objs[NUM_BLOB_COLUMNS];
- char *name = query->data, *msg;
+ char *name = aca->query.data, *msg;
size_t name_len = strlen(name) + 1, msg_len;
uint32_t id;
unsigned num_rows;
goto out;
id = *(uint32_t *)obj.data;
obj.data = name + name_len;
- obj.size = query->size - name_len;
+ obj.size = aca->query.size - name_len;
ret = osl(osl_update_object(table, row, BLOBCOL_DEF, &obj));
goto out;
}
objs[BLOBCOL_NAME].data = name;
objs[BLOBCOL_NAME].size = name_len;
objs[BLOBCOL_DEF].data = name + name_len;
- objs[BLOBCOL_DEF].size = query->size - name_len;
+ objs[BLOBCOL_DEF].size = aca->query.size - name_len;
ret = osl(osl_add_row(table, objs));
if (ret < 0)
goto out;
msg_len = xasprintf(&msg, "cannot add %s\n", name);
else
msg_len = xasprintf(&msg, "added %s as id %u\n", name, id);
- pass_buffer_as_shm(fd, SBD_OUTPUT, msg, msg_len);
+ pass_buffer_as_shm(aca->fd, SBD_OUTPUT, msg, msg_len);
free(msg);
return ret;
}
return stdin_command(cc, &arg_obj, f);
}
-static int com_mvblob_callback(struct osl_table *table, int fd,
- const struct osl_object *query)
+static int com_mvblob_callback(struct osl_table *table,
+ struct afs_callback_arg *aca)
{
- char *src = (char *) query->data;
+ char *src = (char *)aca->query.data;
struct osl_object obj = {.data = src, .size = strlen(src) + 1};
char *dest = src + obj.size;
struct osl_row *row;
struct para_buffer pb = {
.max_size = shm_get_shmmax(),
- .private_data = &fd,
+ .private_data = &aca->fd,
.max_size_handler = afs_max_size_handler
};
int ret = osl(osl_get_row(table, BLOBCOL_NAME, &obj, &row));
}
#define DEFINE_BLOB_COMMAND(cmd_name, table_name, cmd_prefix) \
- static int com_ ## cmd_name ## cmd_prefix ## _callback(int fd, const struct osl_object *query) \
+ static int com_ ## cmd_name ## cmd_prefix ## _callback(struct afs_callback_arg *aca) \
{ \
- return com_ ## cmd_name ## blob_callback(table_name ## _table, fd, query); \
+ return com_ ## cmd_name ## blob_callback(table_name ## _table, aca); \
} \
int com_ ## cmd_name ## cmd_prefix(struct command_context *cc) \
{ \
/**
* Check all moods for syntax errors.
*
- * \param fd The afs socket.
- * \param query Unused.
+ * \param aca Only ->pbout is used for diagnostics.
*
* \return Negative on fatal errors. Inconsistent mood definitions are not
* considered an error.
*/
-int mood_check_callback(int fd, __a_unused const struct osl_object *query)
+int mood_check_callback(struct afs_callback_arg *aca)
{
int ret;
struct para_buffer pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler
int change_current_mood(char *mood_name);
void close_current_mood(void);
-int mood_check_callback(int fd, __a_unused const struct osl_object *query);
+int mood_check_callback(struct afs_callback_arg *aca);
/**
* Check the playlist table for inconsistencies.
*
- * \param fd The afs socket.
- * \param query Unused.
+ * \param aca This callback ignores ->query.
*
* \return Standard. Invalid paths are reported, but are not considered an
* error.
*/
-int playlist_check_callback(int fd, __a_unused const struct osl_object *query)
+int playlist_check_callback(struct afs_callback_arg *aca)
{
int ret;
struct para_buffer pb = {
.max_size = shm_get_shmmax(),
.private_data = &(struct afs_max_size_handler_data) {
- .fd = fd,
+ .fd = aca->fd,
.band = SBD_OUTPUT
},
.max_size_handler = afs_max_size_handler,