From: Andre Noll Date: Sun, 11 Oct 2015 00:17:55 +0000 (+0000) Subject: server: Convert com_rm() to lopsub. X-Git-Tag: v0.6.0~2^2~63 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=f2d9fcc2aad0df59ae5a635564760c1cff4fcfc6 server: Convert com_rm() to lopsub. This gets rid of the open-coded command line parser in com_rm() and of enum rm_flags. Patterns are now passed to for_each_matching_row() and from there to the action handler remove_audio_file() via ->lpr of struct pattern_match_data. --- diff --git a/afs.cmd b/afs.cmd index 5a8ff3c1..bf6d4734 100644 --- a/afs.cmd +++ b/afs.cmd @@ -59,26 +59,6 @@ U: addatt attribute1... H: This adds new attributes to the attribute table. At most 64 H: attributes may be defined. --- -N: rm -P: AFS_READ | AFS_WRITE -D: Remove entries from the audio file table. -U: rm [-v] [-f] [-p] pattern... -H: Delete all entries in the audio file table that match any given pattern. Note -H: that this affects the table entries only; the command won't touch your audio -H: files on disk. -H: -H: Options: -H: -H: -v Verbose mode. Explain what is being done. -H: -H: -f Force mode. Ignore nonexistent files. Don't complain if nothing -H: was removed. -H: -H: -p Pathname match. Match a slash in the path only with a slash -H: in pattern and not by an asterisk (*) or a question mark -H: (?) metacharacter, nor by a bracket expression ([]) containing -H: a slash (see fnmatch(3)). ---- N: touch P: AFS_READ | AFS_WRITE D: Manipulate the afs entry of audio files. diff --git a/aft.c b/aft.c index b442de8e..7141e3fa 100644 --- a/aft.c +++ b/aft.c @@ -2133,24 +2133,14 @@ int com_touch(struct command_context *cc) cc->argv + i, com_touch_callback, afs_cb_result_handler, cc); } -/** Flags for com_rm(). */ -enum rm_flags { - /** -v */ - RM_FLAG_VERBOSE = 1, - /** -f */ - RM_FLAG_FORCE = 2, - /** -p */ - RM_FLAG_FNM_PATHNAME = 4 -}; - static int remove_audio_file(__a_unused struct osl_table *table, struct osl_row *row, const char *name, void *data) { struct afs_callback_arg *aca = data; - uint32_t flags =*(uint32_t *)aca->query.data; + bool v_given = SERVER_CMD_OPT_GIVEN(RM, VERBOSE, aca->lpr); int ret; - if (flags & RM_FLAG_VERBOSE) + if (v_given) para_printf(&aca->pbout, "removing %s\n", name); ret = afs_event(AUDIO_FILE_REMOVE, &aca->pbout, row); if (ret < 0) @@ -2163,66 +2153,55 @@ static int remove_audio_file(__a_unused struct osl_table *table, static int com_rm_callback(struct afs_callback_arg *aca) { + const struct lls_command *cmd = SERVER_CMD_CMD_PTR(RM); int ret; - uint32_t flags = *(uint32_t *)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(uint32_t), - .size = aca->query.size - sizeof(uint32_t)}, .data = aca, .action = remove_audio_file }; - if (flags & RM_FLAG_FNM_PATHNAME) + bool v_given, p_given, f_given; + + ret = lls_deserialize_parse_result(aca->query.data, cmd, &aca->lpr); + assert(ret >= 0); + pmd.lpr = aca->lpr; + v_given = SERVER_CMD_OPT_GIVEN(RM, VERBOSE, aca->lpr); + p_given = SERVER_CMD_OPT_GIVEN(RM, PATHNAME_MATCH, aca->lpr); + f_given = SERVER_CMD_OPT_GIVEN(RM, FORCE, aca->lpr); + + if (p_given) pmd.fnmatch_flags |= FNM_PATHNAME; ret = for_each_matching_row(&pmd); if (ret < 0) goto out; if (pmd.num_matches == 0) { - if (!(flags & RM_FLAG_FORCE)) + if (!f_given) ret = -E_NO_MATCH; - } else if (flags & RM_FLAG_VERBOSE) + } else if (v_given) para_printf(&aca->pbout, "removed %u file(s)\n", pmd.num_matches); out: + lls_free_parse_result(aca->lpr, cmd); return ret; } /* TODO options: -r (recursive) */ -int com_rm(struct command_context *cc) +static int com_rm(struct command_context *cc, struct lls_parse_result *lpr) { - uint32_t flags = 0; - struct osl_object query = {.data = &flags, .size = sizeof(flags)}; - int i; + const struct lls_command *cmd = SERVER_CMD_CMD_PTR(RM); + char *errctx; + int ret; - for (i = 1; i < cc->argc; i++) { - const char *arg = cc->argv[i]; - if (arg[0] != '-') - break; - if (!strcmp(arg, "--")) { - i++; - break; - } - if (!strcmp(arg, "-f")) { - flags |= RM_FLAG_FORCE; - continue; - } - if (!strcmp(arg, "-p")) { - flags |= RM_FLAG_FNM_PATHNAME; - continue; - } - if (!strcmp(arg, "-v")) { - flags |= RM_FLAG_VERBOSE; - continue; - } - break; + 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_rm_callback, afs_cb_result_handler, cc); + return send_lls_callback_request(com_rm_callback, cmd, lpr, cc); } +EXPORT_SERVER_CMD_HANDLER(rm); /** Data passed to the action handler of com_cpsi(). */ struct cpsi_action_data { diff --git a/m4/lls/server_cmd.suite.m4 b/m4/lls/server_cmd.suite.m4 index e1d6037f..71beaa3d 100644 --- a/m4/lls/server_cmd.suite.m4 +++ b/m4/lls/server_cmd.suite.m4 @@ -246,6 +246,30 @@ aux_info_prefix = Permissions: Set the 'P' (playing) bit of the vss status flags. [/description] +[subcommand rm] + purpose = remove rows from the audio file table + non-opts-name = pattern... + aux_info = AFS_READ | AFS_WRITE + [description] + Remove all rows of the audio file table which match any of the given + patterns. Note that this affects only the database table; the command + won't touch your audio files on disk. + [/description] + [option verbose] + short_opt = v + summary = print paths of deleted rows + [option force] + short_opt = f + summary = don't complain if nothing was removed + [option pathname-match] + short_opt = p + summary = modify matching behaviour + [help] + Match a slash in the path only with a slash in pattern and not by an + asterisk (*) or a question mark (?) metacharacter, nor by a bracket + expression ([]) containing a slash (see fnmatch(3)). + [/help] + [subcommand rmatt] purpose = remove attribute(s) non-opts-name = pattern...