return ret;
}
-static void com_setatt_callback(__a_unused int fd, const struct osl_object *query)
+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;
- uint64_t add_mask = 0, del_mask = 0;
int ret;
size_t len;
- struct osl_object obj;
+ 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;
len = strlen(p);
ret = -E_ATTR_SYNTAX;
- if (!*p)
+ if (len == 0)
goto out;
c = p[len - 1];
if (c != '+' && c != '-')
if (ret < 0)
goto out;
if (c == '+')
- add_mask |= (1UL << bitnum);
+ cad.add_mask |= (1UL << bitnum);
else
- del_mask |= (1UL << bitnum);
+ cad.del_mask |= (1UL << bitnum);
}
ret = -E_ATTR_SYNTAX;
- if (!add_mask && !del_mask)
+ if (!cad.add_mask && !cad.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);
- }
+ 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_NOTICE_LOG("%s\n", para_strerror(-ret));
+ 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, NULL, NULL);
+ com_setatt_callback, afs_cb_result_handler, cc);
}
static void afs_stat_callback(int fd, const struct osl_object *query)