Merge branch 'maint'
authorAndre Noll <maan@tuebingen.mpg.de>
Sun, 21 Feb 2016 10:58:39 +0000 (11:58 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 21 Feb 2016 10:58:39 +0000 (11:58 +0100)
A single fix that avoids to shift 32 bit integers for attribute
bitmasks where 64 bit quantities are necessary.

1  2 
aft.c

diff --cc aft.c
--- 1/aft.c
--- 2/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);
-                       cad.add_mask |= (1UL << bitnum);
 +}
 +
 +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.del_mask |= (1UL << bitnum);
++                      cad.add_mask |= (one << bitnum);
 +              else
++                      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;
  }