From: Andre Noll Date: Fri, 2 Oct 2015 21:22:01 +0000 (+0000) Subject: server: Convert com_setatt() to lopsub. X-Git-Tag: v0.6.0~2^2~68 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=f57f71019a272c7e5a29a10da55a8ef2bed5de71;hp=db8b6df30d17d9f93c60758e156699067121cbb5 server: Convert com_setatt() to lopsub. Introduces ->input_skip for struct pattern_match data. The setatt command uses this to strip the attribute modifies off the unnamed arguments in the lopsub parse result. The remaining arguments are the patterns which are to be matched against each file in the audio file table. --- diff --git a/afs.c b/afs.c index 21035cda..92c58cc8 100644 --- a/afs.c +++ b/afs.c @@ -401,7 +401,7 @@ static int action_if_pattern_matches(struct osl_row *row, void *data) } } p = pattern_txt; - i = 0; + i = pmd->input_skip; for (;;) { if (pmd->lpr) { if (i >= lls_num_inputs(pmd->lpr)) diff --git a/afs.cmd b/afs.cmd index 5a3615bf..2b9e4f8e 100644 --- a/afs.cmd +++ b/afs.cmd @@ -52,18 +52,6 @@ H: b: by bit rate H: d: by duration H: a: by audio format --- -N: setatt -P: AFS_READ | AFS_WRITE -D: Set attribute(s) for all files matching a pattern. -U: setatt attribute{+|-}... pattern -H: Set ('+') or unset ('-') the given attributes for all audio files matching -H: pattern. Example: -H: -H: setatt rock+ punk+ pop- '*foo.mp3' -H: -H: sets the 'rock' and the 'punk' attribute and unsets the 'pop' -H: attribute of all files ending with 'foo.mp3'. ---- N: addatt P: AFS_READ | AFS_WRITE D: Add new attribute(s). diff --git a/afs.h b/afs.h index c73eb736..3d13aea2 100644 --- a/afs.h +++ b/afs.h @@ -149,6 +149,8 @@ struct pattern_match_data { struct lls_parse_result *lpr; /** Null-terminated array of patterns. */ struct osl_object patterns; + /** Do not try to match the first inputs of lpr */ + unsigned input_skip; /** Data pointer passed to the action function. */ void *data; /** Gets increased by one for each match. */ diff --git a/aft.c b/aft.c index 628f98fb..f1864081 100644 --- a/aft.c +++ b/aft.c @@ -2401,9 +2401,8 @@ static int change_atts(__a_unused struct osl_table *table, static int com_setatt_callback(struct afs_callback_arg *aca) { - char *p; - int ret; - size_t len; + const struct lls_command *cmd = SERVER_CMD_CMD_PTR(SETATT); + int i, ret; struct change_atts_data cad = {.aca = aca}; struct pattern_match_data pmd = { .table = audio_file_table, @@ -2413,27 +2412,36 @@ static int com_setatt_callback(struct afs_callback_arg *aca) .data = &cad, .action = change_atts }; + unsigned num_inputs; + + ret = lls_deserialize_parse_result(aca->query.data, cmd, &aca->lpr); + assert(ret >= 0); + pmd.lpr = aca->lpr; - for ( - p = aca->query.data; - p < (char *)aca->query.data + aca->query.size; - p += len + 1 - ) { - char c; + num_inputs = lls_num_inputs(aca->lpr); + for (i = 0; i < num_inputs; i++) { unsigned char bitnum; uint64_t one = 1; + const char *arg = lls_input(i, aca->lpr); + char c, *p; + size_t len = strlen(arg); - len = strlen(p); ret = -E_ATTR_SYNTAX; if (len == 0) goto out; - c = p[len - 1]; - if (c != '+' && c != '-') - break; + c = arg[len - 1]; + if (c != '+' && c != '-') { + if (cad.add_mask == 0 && cad.del_mask == 0) + goto out; /* no attribute modifier given */ + goto set_atts; + } + p = para_malloc(len); + memcpy(p, arg, len - 1); p[len - 1] = '\0'; ret = get_attribute_bitnum_by_name(p, &bitnum); + free(p); if (ret < 0) { - para_printf(&aca->pbout, "attribute not found: %s\n", p); + para_printf(&aca->pbout, "invalid argument: %s\n", arg); goto out; } if (c == '+') @@ -2441,29 +2449,32 @@ static int com_setatt_callback(struct afs_callback_arg *aca) else cad.del_mask |= (one << bitnum); } + /* no pattern given */ ret = -E_ATTR_SYNTAX; - if (!cad.add_mask && !cad.del_mask) - goto out; - pmd.patterns.data = p; - if (p >= (char *)aca->query.data + aca->query.size) - goto out; - pmd.patterns.size = (char *)aca->query.data + aca->query.size - p; + goto out; +set_atts: + pmd.input_skip = i; ret = for_each_matching_row(&pmd); - if (ret < 0) - goto out; - if (pmd.num_matches == 0) + if (ret >= 0 && pmd.num_matches == 0) ret = -E_NO_MATCH; out: + lls_free_parse_result(aca->lpr, cmd); return ret; } -int com_setatt(struct command_context *cc) +static int com_setatt(struct command_context *cc, struct lls_parse_result *lpr) { - if (cc->argc < 3) - return -E_ATTR_SYNTAX; - return send_standard_callback_request(cc->argc - 1, cc->argv + 1, - com_setatt_callback, afs_cb_result_handler, cc); + const struct lls_command *cmd = SERVER_CMD_CMD_PTR(SETATT); + char *errctx; + int ret = lls(lls_check_arg_count(lpr, 2, INT_MAX, &errctx)); + + if (ret < 0) { + send_errctx(cc, errctx); + return ret; + } + return send_lls_callback_request(com_setatt_callback, cmd, lpr, cc); } +EXPORT_SERVER_CMD_HANDLER(setatt); static int afs_stat_callback(struct afs_callback_arg *aca) { diff --git a/m4/lls/server_cmd.suite.m4 b/m4/lls/server_cmd.suite.m4 index b10f3553..b1139341 100644 --- a/m4/lls/server_cmd.suite.m4 +++ b/m4/lls/server_cmd.suite.m4 @@ -193,6 +193,20 @@ aux_info_prefix = Permissions: [/description] +[subcommand setatt] + purpose = set or unset attributes + synopsis = attribute{+|-}... pattern... + aux_info = AFS_READ | AFS_WRITE + [description] + Set ('+') or unset ('-') the given attributes for all audio files + matching the given pattern. Example: + + setatt rock+ punk+ pop- '*foo.mp3' + + sets the 'rock' and the 'punk' attribute and unsets the 'pop' attribute + of all files ending with 'foo.mp3'. + [/description] + [subcommand si] purpose = print server info aux_info = NO_PERMISSION_REQUIRED