From: Andre Noll Date: Sun, 21 Feb 2016 10:58:39 +0000 (+0100) Subject: Merge branch 'maint' X-Git-Tag: v0.5.6~59 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=642445e95fea1c548c79f80ad3b5d6f30ba572f3 Merge branch 'maint' A single fix that avoids to shift 32 bit integers for attribute bitmasks where 64 bit quantities are necessary. --- 642445e95fea1c548c79f80ad3b5d6f30ba572f3 diff --cc aft.c index f5830dac,301da7c7..261054df --- a/aft.c +++ b/aft.c @@@ -2345,94 -2496,10 +2345,95 @@@ int com_cpsi(struct command_context *cc return -E_AFT_SYNTAX; if (!(flags & ~CPSI_FLAG_VERBOSE)) /* no copy flags given */ flags = ~(unsigned)CPSI_FLAG_VERBOSE | flags; - ret = send_option_arg_callback_request(&options, cc->argc - i, + return send_option_arg_callback_request(&options, cc->argc - i, cc->argv + i, com_cpsi_callback, afs_cb_result_handler, cc); +} + +struct change_atts_data { + uint64_t add_mask, del_mask; + struct afs_callback_arg *aca; +}; + +static int change_atts(__a_unused struct osl_table *table, + struct osl_row *row, __a_unused const char *name, void *data) +{ + int ret; + struct osl_object obj; + struct afs_info old_afsi, new_afsi; + struct afsi_change_event_data aced = { + .aft_row = row, + .old_afsi = &old_afsi + }; + struct change_atts_data *cad = data; + + ret = get_afsi_object_of_row(row, &obj); + if (ret < 0) + return ret; + ret = load_afsi(&old_afsi, &obj); + if (ret < 0) + return ret; + new_afsi = old_afsi; + new_afsi.attributes |= cad->add_mask; + new_afsi.attributes &= ~cad->del_mask; + save_afsi(&new_afsi, &obj); /* in-place update */ + return afs_event(AFSI_CHANGE, &cad->aca->pbout, &aced); +} + +static int com_setatt_callback(struct afs_callback_arg *aca) +{ + char *p; + int ret; + size_t len; + struct change_atts_data cad = {.aca = aca}; + struct pattern_match_data pmd = { + .table = audio_file_table, + .loop_col_num = AFTCOL_HASH, + .match_col_num = AFTCOL_PATH, + .pm_flags = PM_SKIP_EMPTY_NAME, + .data = &cad, + .action = change_atts + }; + + for ( + p = aca->query.data; + p < (char *)aca->query.data + aca->query.size; + p += len + 1 + ) { + char c; + unsigned char bitnum; ++ uint64_t one = 1; + + len = strlen(p); + ret = -E_ATTR_SYNTAX; + if (len == 0) + goto out; + c = p[len - 1]; + if (c != '+' && c != '-') + break; + p[len - 1] = '\0'; + ret = get_attribute_bitnum_by_name(p, &bitnum); + if (ret < 0) { + para_printf(&aca->pbout, "attribute not found: %s\n", p); + goto out; + } + if (c == '+') - cad.add_mask |= (1UL << bitnum); ++ cad.add_mask |= (one << bitnum); + else - cad.del_mask |= (1UL << bitnum); ++ cad.del_mask |= (one << bitnum); + } + 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; + ret = for_each_matching_row(&pmd); if (ret < 0) - send_strerror(cc, -ret); + goto out; + if (pmd.num_matches == 0) + ret = -E_NO_MATCH; +out: return ret; }