summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
db8b6df)
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.
for (;;) {
if (pmd->lpr) {
if (i >= lls_num_inputs(pmd->lpr))
for (;;) {
if (pmd->lpr) {
if (i >= lls_num_inputs(pmd->lpr))
H: d: by duration
H: a: by audio format
---
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).
N: addatt
P: AFS_READ | AFS_WRITE
D: Add new attribute(s).
struct lls_parse_result *lpr;
/** Null-terminated array of patterns. */
struct osl_object patterns;
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. */
/** Data pointer passed to the action function. */
void *data;
/** Gets increased by one for each match. */
static int com_setatt_callback(struct afs_callback_arg *aca)
{
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,
struct change_atts_data cad = {.aca = aca};
struct pattern_match_data pmd = {
.table = audio_file_table,
.data = &cad,
.action = change_atts
};
.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;
unsigned char bitnum;
uint64_t one = 1;
+ const char *arg = lls_input(i, aca->lpr);
+ char c, *p;
+ size_t len = strlen(arg);
ret = -E_ATTR_SYNTAX;
if (len == 0)
goto out;
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);
p[len - 1] = '\0';
ret = get_attribute_bitnum_by_name(p, &bitnum);
- para_printf(&aca->pbout, "attribute not found: %s\n", p);
+ para_printf(&aca->pbout, "invalid argument: %s\n", arg);
goto out;
}
if (c == '+')
goto out;
}
if (c == '+')
else
cad.del_mask |= (one << bitnum);
}
else
cad.del_mask |= (one << bitnum);
}
- 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);
ret = for_each_matching_row(&pmd);
- if (ret < 0)
- goto out;
- if (pmd.num_matches == 0)
+ if (ret >= 0 && pmd.num_matches == 0)
+ lls_free_parse_result(aca->lpr, cmd);
-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)
{
static int afs_stat_callback(struct afs_callback_arg *aca)
{
+[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
[subcommand si]
purpose = print server info
aux_info = NO_PERMISSION_REQUIRED