TOUCH_FLAG_VERBOSE = 2
};
-/** Options used by com_touch(). */
-struct com_touch_options {
- /** New num_played value. */
- int32_t num_played;
- /** New last played count. */
- int64_t last_played;
- /** New lyrics id. */
- int32_t lyrics_id;
- /** New image id. */
- int32_t image_id;
- /** New amplification value. */
- int32_t amp;
- /** Command line flags (see \ref touch_flags). */
- unsigned flags;
-};
-
static int touch_audio_file(__a_unused struct osl_table *table,
struct osl_row *row, const char *name, void *data)
{
struct afs_callback_arg *aca = data;
- struct com_touch_options *cto = aca->query.data;
+ bool v_given = SERVER_CMD_OPT_GIVEN(TOUCH, VERBOSE, aca->lpr);
+ const struct lls_opt_result *r_n, *r_l, *r_i, *r_y, *r_a;
+ int ret;
struct osl_object obj;
struct afs_info old_afsi, new_afsi;
- int ret, no_options = cto->num_played < 0 && cto->last_played < 0 &&
- cto->lyrics_id < 0 && cto->image_id < 0 && cto->amp < 0;
+ bool no_options;
struct afsi_change_event_data aced;
+ r_n = SERVER_CMD_OPT_RESULT(TOUCH, NUMPLAYED, aca->lpr);
+ r_l = SERVER_CMD_OPT_RESULT(TOUCH, LASTPLAYED, aca->lpr);
+ r_i = SERVER_CMD_OPT_RESULT(TOUCH, IMAGE_ID, aca->lpr);
+ r_y = SERVER_CMD_OPT_RESULT(TOUCH, LYRICS_ID, aca->lpr);
+ r_a = SERVER_CMD_OPT_RESULT(TOUCH, AMP, aca->lpr);
+ no_options = !lls_opt_given(r_n) && !lls_opt_given(r_l) && !lls_opt_given(r_i)
+ && !lls_opt_given(r_y) && !lls_opt_given(r_a);
+
ret = get_afsi_object_of_row(row, &obj);
if (ret < 0) {
para_printf(&aca->pbout, "cannot touch %s\n", name);
if (no_options) {
new_afsi.num_played++;
new_afsi.last_played = time(NULL);
- if (cto->flags & TOUCH_FLAG_VERBOSE)
+ if (v_given)
para_printf(&aca->pbout, "%s: num_played = %u, "
"last_played = now()\n", name,
new_afsi.num_played);
} else {
- if (cto->flags & TOUCH_FLAG_VERBOSE)
+ if (lls_opt_given(r_l))
+ new_afsi.last_played = lls_uint64_val(0, r_l);
+ if (lls_opt_given(r_n))
+ new_afsi.num_played = lls_uint32_val(0, r_n);
+ if (lls_opt_given(r_i))
+ new_afsi.image_id = lls_uint32_val(0, r_i);
+ if (lls_opt_given(r_y))
+ new_afsi.lyrics_id = lls_uint32_val(0, r_y);
+ if (lls_opt_given(r_a))
+ new_afsi.amp = lls_uint32_val(0, r_a);
+ if (v_given)
para_printf(&aca->pbout, "touching %s\n", name);
- if (cto->lyrics_id >= 0)
- new_afsi.lyrics_id = cto->lyrics_id;
- if (cto->image_id >= 0)
- new_afsi.image_id = cto->image_id;
- if (cto->num_played >= 0)
- new_afsi.num_played = cto->num_played;
- if (cto->last_played >= 0)
- new_afsi.last_played = cto->last_played;
- if (cto->amp >= 0)
- new_afsi.amp = cto->amp;
}
save_afsi(&new_afsi, &obj); /* in-place update */
aced.aft_row = row;
static int com_touch_callback(struct afs_callback_arg *aca)
{
+ const struct lls_command *cmd = SERVER_CMD_CMD_PTR(TOUCH);
+ bool p_given;
+ const struct lls_opt_result *r_i, *r_y;
int ret;
- struct com_touch_options *cto = aca->query.data;
struct pattern_match_data pmd = {
.table = audio_file_table,
.loop_col_num = AFTCOL_HASH,
.match_col_num = AFTCOL_PATH,
- .patterns = {
- .data = (char *)aca->query.data
- + sizeof(struct com_touch_options),
- .size = aca->query.size
- - sizeof(struct com_touch_options)
- },
.data = aca,
.action = touch_audio_file
};
- if (cto->image_id >= 0) {
- ret = img_get_name_by_id(cto->image_id, NULL);
+
+ ret = lls_deserialize_parse_result(aca->query.data, cmd, &aca->lpr);
+ assert(ret >= 0);
+ pmd.lpr = aca->lpr;
+
+ r_i = SERVER_CMD_OPT_RESULT(TOUCH, IMAGE_ID, aca->lpr);
+ if (lls_opt_given(r_i)) {
+ uint32_t id = lls_uint32_val(0, r_i);
+ ret = img_get_name_by_id(id, NULL);
if (ret < 0) {
- para_printf(&aca->pbout, "invalid image ID: %d\n",
- cto->image_id);
+ para_printf(&aca->pbout, "invalid image ID: %u\n", id);
return ret;
}
}
- if (cto->lyrics_id >= 0) {
- ret = lyr_get_name_by_id(cto->lyrics_id, NULL);
+ r_y = SERVER_CMD_OPT_RESULT(TOUCH, LYRICS_ID, aca->lpr);
+ if (lls_opt_given(r_y)) {
+ uint32_t id = lls_uint32_val(0, r_y);
+ ret = lyr_get_name_by_id(id, NULL);
if (ret < 0) {
- para_printf(&aca->pbout, "invalid lyrics ID: %d\n",
- cto->lyrics_id);
+ para_printf(&aca->pbout, "invalid lyrics ID: %u\n", id);
return ret;
}
}
- if (cto->flags & TOUCH_FLAG_FNM_PATHNAME)
+ p_given = SERVER_CMD_OPT_GIVEN(TOUCH, PATHNAME_MATCH, aca->lpr);
+ if (p_given)
pmd.fnmatch_flags |= FNM_PATHNAME;
ret = for_each_matching_row(&pmd);
if (ret >= 0 && pmd.num_matches == 0)
ret = -E_NO_MATCH;
+ lls_free_parse_result(aca->lpr, cmd);
return ret;
}
-int com_touch(struct command_context *cc)
+static int com_touch(struct command_context *cc, struct lls_parse_result *lpr)
{
- struct com_touch_options cto = {
- .num_played = -1,
- .last_played = -1,
- .lyrics_id = -1,
- .image_id = -1,
- .amp = -1,
- };
- struct osl_object query = {.data = &cto, .size = sizeof(cto)};
- int i, ret;
-
+ const struct lls_command *cmd = SERVER_CMD_CMD_PTR(TOUCH);
+ int ret;
+ char *errctx;
- for (i = 1; i < cc->argc; i++) {
- const char *arg = cc->argv[i];
- if (arg[0] != '-')
- break;
- if (!strcmp(arg, "--")) {
- i++;
- break;
- }
- if (!strncmp(arg, "-n=", 3)) {
- ret = para_atoi32(arg + 3, &cto.num_played);
- if (ret < 0)
- return ret;
- continue;
- }
- if (!strncmp(arg, "-l=", 3)) {
- ret = para_atoi64(arg + 3, &cto.last_played);
- if (ret < 0)
- return ret;
- continue;
- }
- if (!strncmp(arg, "-y=", 3)) {
- ret = para_atoi32(arg + 3, &cto.lyrics_id);
- if (ret < 0)
- return ret;
- continue;
- }
- if (!strncmp(arg, "-i=", 3)) {
- ret = para_atoi32(arg + 3, &cto.image_id);
- if (ret < 0)
- return ret;
- continue;
- }
- if (!strncmp(arg, "-a=", 3)) {
- int32_t val;
- ret = para_atoi32(arg + 3, &val);
- if (ret < 0)
- return ret;
- if (val < 0 || val > 255)
- return -ERRNO_TO_PARA_ERROR(EINVAL);
- cto.amp = val;
- continue;
- }
- if (!strcmp(arg, "-p")) {
- cto.flags |= TOUCH_FLAG_FNM_PATHNAME;
- continue;
- }
- if (!strcmp(arg, "-v")) {
- cto.flags |= TOUCH_FLAG_VERBOSE;
- continue;
- }
- break; /* non-option starting with dash */
+ ret = lls(lls_check_arg_count(lpr, 1, INT_MAX, &errctx));
+ if (ret < 0) {
+ send_errctx(cc, errctx);
+ return ret;
}
- if (i >= cc->argc)
- return -E_AFT_SYNTAX;
- return send_option_arg_callback_request(&query, cc->argc - i,
- cc->argv + i, com_touch_callback, afs_cb_result_handler, cc);
+ return send_lls_callback_request(com_touch_callback, cmd, lpr, cc);
}
+EXPORT_SERVER_CMD_HANDLER(touch);
static int remove_audio_file(__a_unused struct osl_table *table,
struct osl_row *row, const char *name, void *data)