Merge branch 't/setatt_fnmatch'
authorAndre Noll <maan@systemlinux.org>
Wed, 21 Aug 2013 18:49:06 +0000 (20:49 +0200)
committerAndre Noll <maan@systemlinux.org>
Wed, 21 Aug 2013 18:51:32 +0000 (20:51 +0200)
Was cooking for about two weeks and seems to work fine.

73299e com_setatt(): Allow to specify a file name pattern.
fd5f94 Move com_setatt() from attribute.c to aft.c.
a8573c com_setatt(): Use get_attribute_bitnum_by_name().
47dbd9 Mark buffer pointer of pass_buffer_as_shm() as const.

1  2 
NEWS
afs.c
aft.c
attribute.c

diff --combined NEWS
index 55b0277f0f5b9217c63d8e2d886105b5bc2aa12f,4127e38bcdf0434be750aed7da7fee83acad872e..035a23f0d1731b71fc925241a665ff6813a1668c
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,15 -1,7 +1,17 @@@
  ---------------------------------------------
 -0.?.? (to be announced) "invertible validity"
 +0.5.0 (to be announced) "invertible validity"
  ---------------------------------------------
  
 +      - The sideband compatibility code has been removed, hence
 +        sideband connections (introduced in 0.4.11) are now mandatory.
 +      - Addblob commands can produce output.
 +      - The stat command no longer sends garbage when para_server was
 +        compiled against libgcrypt.
 +      - Dependencies for gengetopt files are computed automatically.
 +        This eliminates a constant source of build bugs.
++      - The setatt command now accepts file name patterns rather than only
++        path names.
 +
  --------------------------------------
  0.4.13 (2013-07-29) "spectral gravity"
  --------------------------------------
diff --combined afs.c
index 49ce13ebe1eec3dce17727af33bb51444f3a3108,989b3261fbb129139c27c21f4b2ef1b8ff9d2794..2f9df84581ee53685bbdb2282b6398a133fbf37f
--- 1/afs.c
--- 2/afs.c
+++ b/afs.c
@@@ -565,7 -565,10 +565,7 @@@ int afs_cb_result_handler(struct osl_ob
        assert(cc);
        if (!result->size)
                return 1;
 -      if (cc->use_sideband)
 -              return send_sb(&cc->scc, result->data, result->size, band,
 -                      true);
 -      return sc_send_bin_buffer(&cc->scc, result->data, result->size);
 +      return send_sb(&cc->scc, result->data, result->size, band, true);
  }
  
  static void com_select_callback(int fd, const struct osl_object *query)
@@@ -804,7 -807,7 +804,7 @@@ static void command_pre_select(struct s
   * \return Zero if \a buf is \p NULL or \a size is zero. Negative on errors,
   * and positive on success.
   */
- int pass_buffer_as_shm(int fd, uint8_t band, char *buf, size_t size)
+ int pass_buffer_as_shm(int fd, uint8_t band, const char *buf, size_t size)
  {
        int ret, shmid;
        void *shm;
@@@ -1065,6 -1068,9 +1065,6 @@@ int com_init(struct command_context *cc
        }
        ret = send_callback_request(create_tables_callback, &query,
                afs_cb_result_handler, cc);
 -      if (ret < 0 && !cc->use_sideband)
 -              /* ignore return value */
 -              sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret));
        return ret;
  }
  
diff --combined aft.c
index adc9a6f2ad92b212790feb59cc7e66aa12506307,1d2d6d8dae69d152df2d9db6ec05988c4cac7f5b..377740d132b831d126e0015f241ed65095c2e661
--- 1/aft.c
--- 2/aft.c
+++ b/aft.c
@@@ -1876,8 -1876,12 +1876,8 @@@ static int add_one_audio_file(const cha
        ret = 1;
        if (pb && (pad->flags & ADD_FLAG_LAZY)) { /* lazy is really cheap */
                if (pad->flags & ADD_FLAG_VERBOSE)
 -                      send_ret = pad->cc->use_sideband?
 -                              send_sb_va(&pad->cc->scc, SBD_OUTPUT,
 -                                      "lazy-ignore: %s\n", path)
 -                      :
 -                              sc_send_va_buffer(&pad->cc->scc,
 -                                      "lazy-ignore: %s\n", path);
 +                      send_ret = send_sb_va(&pad->cc->scc, SBD_OUTPUT,
 +                              "lazy-ignore: %s\n", path);
                goto out_free;
        }
        /* We still want to add this file. Compute its hash. */
        ret = 1;
        if (pb && hs && hs == pb && !(pad->flags & ADD_FLAG_FORCE)) {
                if (pad->flags & ADD_FLAG_VERBOSE)
 -                      send_ret = pad->cc->use_sideband?
 -                              send_sb_va(&pad->cc->scc, SBD_OUTPUT,
 -                                      "%s exists, not forcing update\n", path)
 -                      :
 -                              sc_send_va_buffer(&pad->cc->scc,
 -                                      "%s exists, not forcing update\n", path);
 +                      send_ret = send_sb_va(&pad->cc->scc, SBD_OUTPUT,
 +                              "%s exists, not forcing update\n", path);
                goto out_unmap;
        }
        /*
        munmap(map.data, map.size);
        close(fd);
        if (pad->flags & ADD_FLAG_VERBOSE) {
 -              send_ret = pad->cc->use_sideband?
 -                      send_sb_va(&pad->cc->scc, SBD_OUTPUT,
 -                              "adding %s\n", path)
 -              :
 -                      sc_send_va_buffer(&pad->cc->scc,
 -                              "adding %s\n", path);
 +              send_ret = send_sb_va(&pad->cc->scc, SBD_OUTPUT,
 +                      "adding %s\n", path);
                if (send_ret < 0)
                        goto out_free;
        }
@@@ -1931,8 -1943,14 +1931,8 @@@ out_unmap
        munmap(map.data, map.size);
  out_free:
        if (ret < 0 && send_ret >= 0)
 -              send_ret = pad->cc->use_sideband?
 -                      send_sb_va(&pad->cc->scc, SBD_ERROR_LOG,
 -                              "failed to add %s (%s)\n", path,
 -                              para_strerror(-ret))
 -              :
 -                      sc_send_va_buffer(&pad->cc->scc,
 -                              "failed to add %s (%s)\n", path,
 -                              para_strerror(-ret));
 +              send_ret = send_sb_va(&pad->cc->scc, SBD_ERROR_LOG,
 +                      "failed to add %s (%s)\n", path, para_strerror(-ret));
        free(obj.data);
        clear_afhi(afhi_ptr);
        /* Stop adding files only on send errors. */
@@@ -1976,7 -1994,11 +1976,7 @@@ int com_add(struct command_context *cc
                char *path;
                ret = verify_path(cc->argv[i], &path);
                if (ret < 0) {
 -                      ret = cc->use_sideband?
 -                              send_sb_va(&cc->scc, SBD_ERROR_LOG, "%s: %s\n",
 -                              cc->argv[i], para_strerror(-ret))
 -                      :
 -                              sc_send_va_buffer(&cc->scc, "%s: %s\n",
 +                      ret = send_sb_va(&cc->scc, SBD_ERROR_LOG, "%s: %s\n",
                                cc->argv[i], para_strerror(-ret));
                        if (ret < 0)
                                return ret;
                }
                ret = stat(path, &statbuf);
                if (ret < 0) {
 -                      ret = cc->use_sideband?
 -                              send_sb_va(&cc->scc, SBD_ERROR_LOG,
 -                                      "failed to stat %s (%s)\n", path,
 -                                      strerror(errno))
 -                              :
 -                              sc_send_va_buffer(&cc->scc,
 -                                      "failed to stat %s (%s)\n", path,
 -                                      strerror(errno));
 +                      ret = send_sb_va(&cc->scc, SBD_ERROR_LOG,
 +                              "failed to stat %s (%s)\n", path,
 +                              strerror(errno));
                        free(path);
                        if (ret < 0)
                                return ret;
                else
                        ret = add_one_audio_file(path, &pad);
                if (ret < 0) {
 -                      if (cc->use_sideband)
 -                              send_sb_va(&cc->scc, SBD_OUTPUT, "%s: %s\n", path,
 -                                      para_strerror(-ret));
 -                      else
 -                              sc_send_va_buffer(&cc->scc, "%s: %s\n", path,
 -                                      para_strerror(-ret));
 +                      send_sb_va(&cc->scc, SBD_OUTPUT, "%s: %s\n", path,
 +                              para_strerror(-ret));
                        free(path);
                        return ret;
                }
@@@ -2471,6 -2502,108 +2471,108 @@@ int com_cpsi(struct command_context *cc
        return ret;
  }
  
+ struct change_atts_data {
+       uint64_t add_mask, del_mask;
+       struct para_buffer pb;
+ };
+ 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 */
+       afs_event(AFSI_CHANGE, &cad->pb, &aced);
+       return 1;
+ }
+ static void com_setatt_callback(int fd, const struct osl_object *query)
+ {
+       char *p;
+       int ret;
+       size_t len;
+       struct change_atts_data cad = {
+               .pb = {
+                       .max_size = shm_get_shmmax(),
+                       .max_size_handler = afs_max_size_handler,
+                       .private_data = &(struct afs_max_size_handler_data) {
+                               .fd = fd,
+                               .band = SBD_OUTPUT
+                       }
+               }
+       };
+       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 = query->data; p < (char *)query->data + query->size; p += len + 1) {
+               char c;
+               unsigned char bitnum;
+               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)
+                       goto out;
+               if (c == '+')
+                       cad.add_mask |= (1UL << bitnum);
+               else
+                       cad.del_mask |= (1UL << bitnum);
+       }
+       ret = -E_ATTR_SYNTAX;
+       if (!cad.add_mask && !cad.del_mask)
+               goto out;
+       pmd.patterns.data = p;
+       assert(p < (char *)query->data + query->size);
+       pmd.patterns.size = (char *)query->data + query->size - p;
+       ret = for_each_matching_row(&pmd);
+       if (ret < 0)
+               goto out;
+       if (pmd.num_matches == 0)
+               para_printf(&cad.pb, "no matches\n");
+ out:
+       if (ret < 0)
+               para_printf(&cad.pb, "%s\n", para_strerror(-ret));
+       if (cad.pb.offset)
+               pass_buffer_as_shm(fd, SBD_OUTPUT, cad.pb.buf, cad.pb.offset);
+       free(cad.pb.buf);
+ }
+ int com_setatt(struct command_context *cc)
+ {
+       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);
+ }
  static void afs_stat_callback(int fd, const struct osl_object *query)
  {
        int *parser_friendly = query->data;
diff --combined attribute.c
index 5a3861bed37ff9689ef171091b009db71df5ad28,8c1f5c535e5b42460b1b4a0fe41fb426b16cc3cb..867e24b9ee705561a18ee5460a2a4f92438c56a2
@@@ -212,82 -212,13 +212,10 @@@ int com_lsatt(struct command_context *c
        if (ret < 0)
                send_strerror(cc, -ret);
        else if (ret == 0 && cc->argc > 1)
 -              ret = cc->use_sideband?
 -                      send_sb_va(&cc->scc, SBD_ERROR_LOG, "no matches\n")
 -              :
 -                      sc_send_va_buffer(&cc->scc, "no matches\n");
 +              ret = send_sb_va(&cc->scc, SBD_ERROR_LOG, "no matches\n");
        return ret;
  }
  
- static void com_setatt_callback(__a_unused int fd, const struct osl_object *query)
- {
-       char *p;
-       uint64_t add_mask = 0, del_mask = 0;
-       int ret;
-       size_t len;
-       struct osl_object obj;
-       struct osl_row *row;
-       for (p = query->data; p < (char *)query->data + query->size; p += len + 1) {
-               char c;
-               len = strlen(p);
-               ret = -E_ATTR_SYNTAX;
-               if (!*p)
-                       goto out;
-               c = p[len - 1];
-               if (c != '+' && c != '-')
-                       break;
-               p[len - 1] = '\0';
-               obj.data = p;
-               obj.size = len + 1;
-               ret = osl(osl_get_row(attribute_table, ATTCOL_NAME, &obj, &row));
-               if (ret < 0)
-                       goto out;
-               ret = osl(osl_get_object(attribute_table, row, ATTCOL_BITNUM,
-                       &obj));
-               if (ret < 0)
-                       goto out;
-               if (c == '+')
-                       add_mask |= (1UL << *(unsigned char *)obj.data);
-               else
-                       del_mask |= (1UL << *(unsigned char *)obj.data);
-       }
-       ret = -E_ATTR_SYNTAX;
-       if (!add_mask && !del_mask)
-               goto out;
-       PARA_DEBUG_LOG("masks: %llx:%llx\n",(long long unsigned)add_mask,
-               (long long unsigned)del_mask);
-       for (; p < (char *)query->data + query->size; p += len + 1) { /* TODO: fnmatch */
-               struct afs_info old_afsi, new_afsi;
-               struct afsi_change_event_data aced = {.old_afsi = &old_afsi};
-               len = strlen(p);
-               ret = aft_get_row_of_path(p, &aced.aft_row);
-               if (ret < 0)
-                       goto out;
-               ret = get_afsi_object_of_row(aced.aft_row, &obj);
-               if (ret < 0)
-                       goto out;
-               ret = load_afsi(&old_afsi, &obj);
-               if (ret < 0)
-                       goto out;
-               new_afsi = old_afsi;
-               new_afsi.attributes |= add_mask;
-               new_afsi.attributes &= ~del_mask;
-               save_afsi(&new_afsi, &obj); /* in-place update */
-               afs_event(AFSI_CHANGE, NULL, &aced);
-       }
- out:
-       if (ret < 0)
-               PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
- }
- int com_setatt(struct command_context *cc)
- {
-       if (cc->argc < 3)
-               return -E_ATTR_SYNTAX;
-       return send_standard_callback_request(cc->argc - 1, cc->argv + 1,
-               com_setatt_callback, NULL, NULL);
- }
  struct addatt_event_data {
        const char *name;
        unsigned char bitnum;