]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - attribute.c
Replace struct table_info by struct afs_table.
[paraslash.git] / attribute.c
index e0a7392fdc99d86f6225c5ac43e1ab690e0bce50..48f108c7fe8be8a96ac6b4d77b7d7737bb46db1c 100644 (file)
@@ -7,9 +7,9 @@
 /** \file attribute.c Attribute handling functions. */
 #include "para.h"
 #include "error.h"
+#include "string.h"
 #include "afh.h"
 #include "afs.h"
-#include "string.h"
 #include "net.h"
 
 static struct osl_table *attribute_table;
@@ -299,26 +299,34 @@ static int logical_and_attribute(struct osl_row *aft_row, void *attribute_ptr)
 }
 
 static int com_addatt_callback(const struct osl_object *query,
-               __a_unused struct osl_object *result)
+               struct osl_object *result)
 {
        char *p = query->data;
-       unsigned atts_added = 0;
-       int ret;
+       int ret = 1;
+       struct para_buffer pb = {.size = 0};
+       size_t len;
 
-       while (p < (char *)query->data + query->size) {
+       for (p = query->data; p < (char *)query->data + query->size; p += len + 1) {
                struct osl_object objs[NUM_ATT_COLUMNS];
                struct osl_row *row;
                unsigned char bitnum;
+               len = strlen(p);
 
+               if (!len || p[len - 1] == '-' || p[len - 1] == '+') {
+                       para_printf(&pb, "invalid attribute name: %s\n", p);
+                       continue;
+               }
                objs[ATTCOL_BITNUM].size = 1;
                objs[ATTCOL_NAME].data = p;
-               objs[ATTCOL_NAME].size = strlen(p) + 1;
+               objs[ATTCOL_NAME].size = len + 1;
                ret = osl_get_row(attribute_table, ATTCOL_NAME,
                        &objs[ATTCOL_NAME], &row); /* expected to fail */
-               if (ret >= 0)
-                       return -E_ATTR_EXISTS;
+               if (ret >= 0) {
+                       para_printf(&pb, "attribute %s already exists\n", p);
+                       continue;
+               }
                if (ret != -E_RB_KEY_NOT_FOUND) /* error */
-                       return ret;
+                       goto out;
                /* find smallest non-used attribute */
                for (bitnum = 0; bitnum < 64; bitnum++) {
                        objs[ATTCOL_BITNUM].data = &bitnum;
@@ -327,31 +335,46 @@ static int com_addatt_callback(const struct osl_object *query,
                        if (ret == -E_RB_KEY_NOT_FOUND)
                                break; /* this bitnum is unused, use it */
                        if (ret < 0) /* error */
-                               return ret;
+                               goto out;
                        /* this bit is already in use, try next bit */
                }
-               if (bitnum == 64)
-                       return -E_ATTR_TABLE_FULL;
+               if (bitnum == 64) {
+                       para_printf(&pb, "attribute table full\n");
+                       goto out;
+               }
                ret = osl_add_row(attribute_table, objs);
                if (ret < 0)
-                       return ret;
+                       goto out;
                greatest_att_bitnum = PARA_MAX(greatest_att_bitnum, bitnum);
-               atts_added++;
-               p += strlen(p) + 1;
        }
-       if (!atts_added)
-               return 1;
-       find_greatest_att_bitnum();
-       return reload_current_mood(); /* FIXME: returns an error */
+out:
+       if (ret < 0)
+               para_printf(&pb, "%s: %s\n", p, PARA_STRERROR(-ret));
+       result->data = pb.buf;
+       result->size = pb.size;
+       return result->data? 0 : 1;
 }
 
-int com_addatt(__a_unused int fd, int argc, char * const * const argv)
+int com_addatt(int fd, int argc, char * const * const argv)
 {
+       struct osl_object result;
+       int ret;
+
        if (argc < 2)
                return -E_ATTR_SYNTAX;
-       return send_standard_callback_request(argc - 1, argv + 1, com_addatt_callback,
-               NULL);
+       ret = send_standard_callback_request(argc - 1, argv + 1, com_addatt_callback,
+               &result);
+       if (!ret)
+               return 1;
+       if (ret < 0)
+               return ret;
+       if (!result.data || !result.size)
+               return 1;
+       ret =  send_va_buffer(fd, "%s", (char *) result.data);
+       free(result.data);
+       return ret;
 }
+
 struct remove_attribute_action_data {
        struct para_buffer pb;
        int num_removed;
@@ -509,9 +532,9 @@ err:
  *
  * \sa osl_close_table().
  */
-void attribute_shutdown(enum osl_close_flags flags)
+void attribute_close(void)
 {
-       osl_close_table(attribute_table, flags);
+       osl_close_table(attribute_table, OSL_MARK_CLEAN);
        attribute_table = NULL;
 }
 
@@ -525,13 +548,12 @@ void attribute_shutdown(enum osl_close_flags flags)
  *
  * \sa osl_open_table().
  */
-int attribute_init(struct table_info *ti, const char *db)
+static int attribute_open(const char *dir)
 {
        int ret;
 
-       attribute_table_desc.dir = db;
-       ti->desc = &attribute_table_desc;
-       ret = osl_open_table(ti->desc, &attribute_table);
+       attribute_table_desc.dir = dir;
+       ret = osl_open_table(&attribute_table_desc, &attribute_table);
        greatest_att_bitnum = -1; /* no atts available */
        if (ret >= 0) {
                find_greatest_att_bitnum();
@@ -542,3 +564,18 @@ int attribute_init(struct table_info *ti, const char *db)
                return 1;
        return ret;
 }
+
+static int attribute_create(const char *dir)
+{
+       attribute_table_desc.dir = dir;
+       return osl_create_table(&attribute_table_desc);
+}
+
+
+void attribute_init(struct afs_table *t)
+{
+       t->name = attribute_table_desc.name;
+       t->open = attribute_open;
+       t->close = attribute_close;
+       t->create = attribute_create;
+}