Fix some bugs in blob handling.
authorAndre Noll <maan@systemlinux.org>
Sat, 22 Sep 2007 12:45:21 +0000 (14:45 +0200)
committerAndre Noll <maan@systemlinux.org>
Sat, 22 Sep 2007 12:45:21 +0000 (14:45 +0200)
- make fd2buf() decrypt the received data.
- stdin_command() has to read from the socket fd rather than from stdin.
  Moreover, it must send the AWAITING_DATA_MSG to the client.
- com_catblob() really needs to use send_bin_buffer() rather than send_buffer().
- com_addblob() has to pass the socket fd to stdin_command().

afs.c
blob.c

diff --git a/afs.c b/afs.c
index a40948f..6d51d4f 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -333,41 +333,33 @@ out:
 
 
 /*
- * write input from fd to dynamically allocated char array,
- * but maximal max_size byte. Return size.
+ * write input from fd to dynamically allocated buffer,
+ * but maximal max_size byte.
  */
-static int fd2buf(int fd, char **buf, int max_size)
+static int fd2buf(int fd, unsigned max_size, struct osl_object *obj)
 {
        const size_t chunk_size = 1024;
-       size_t size = 2048;
-       char *p;
+       size_t size = 2048, received = 0;
        int ret;
+       char *buf = para_malloc(size);
 
-       *buf = para_malloc(size * sizeof(char));
-       p = *buf;
-       while ((ret = read(fd, p, chunk_size)) > 0) {
-               p += ret;
-               if ((p - *buf) + chunk_size >= size) {
-                       char *tmp;
-
+       for (;;) {
+               ret = recv_bin_buffer(fd, buf + received, chunk_size);
+               if (ret <= 0)
+                       break;
+               received += ret;
+               if (received + chunk_size >= size) {
                        size *= 2;
-                       if (size > max_size) {
-                               ret = -E_INPUT_TOO_LARGE;
-                               goto out;
-                       }
-                       tmp = para_realloc(*buf, size);
-                       p = (p - *buf) + tmp;
-                       *buf = tmp;
+                       ret = -E_INPUT_TOO_LARGE;
+                       if (size > max_size)
+                               break;
+                       buf = para_realloc(buf, size);
                }
        }
-       if (ret < 0) {
-               ret = -E_READ;
-               goto out;
-       }
-       ret = p - *buf;
-out:
-       if (ret < 0 && *buf)
-               free(*buf);
+       obj->data = buf;
+       obj->size = received;
+       if (ret < 0)
+               free(buf);
        return ret;
 }
 
@@ -388,22 +380,23 @@ out:
  * \return Negative on errors, the return value of the underlying call to
  * send_callback_request() otherwise.
  */
-int stdin_command(struct osl_object *arg_obj, callback_function *f,
+int stdin_command(int fd, struct osl_object *arg_obj, callback_function *f,
                unsigned max_len, struct osl_object *result)
 {
-       char *stdin_buf;
-       size_t stdin_len;
-       struct osl_object query;
-       int ret = fd2buf(STDIN_FILENO, &stdin_buf, max_len);
+       struct osl_object query, stdin_obj;
+       int ret;
 
+       ret = send_buffer(fd, AWAITING_DATA_MSG);
+       if (ret < 0)
+               return ret;
+       ret = fd2buf(fd, max_len, &stdin_obj);
        if (ret < 0)
                return ret;
-       stdin_len = ret;
-       query.size = arg_obj->size + stdin_len;
+       query.size = arg_obj->size + stdin_obj.size;
        query.data = para_malloc(query.size);
        memcpy(query.data, arg_obj->data, arg_obj->size);
-       memcpy((char *)query.data + arg_obj->size, stdin_buf, stdin_len);
-       free(stdin_buf);
+       memcpy((char *)query.data + arg_obj->size, stdin_obj.data, stdin_obj.size);
+       free(stdin_obj.data);
        ret = send_callback_request(f, &query, result);
        free(query.data);
        return ret;
diff --git a/blob.c b/blob.c
index c6b05b2..b396ef7 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -163,6 +163,7 @@ static int com_catblob_callback(struct osl_table *table,
        memcpy(output->data, obj.data, obj.size);
        return osl_close_disk_object(&obj);
 }
+
 static int com_catblob(callback_function *f, int fd, int argc,
                char * const * const argv)
 {
@@ -174,8 +175,8 @@ static int com_catblob(callback_function *f, int fd, int argc,
        if (!*argv[1]) /* empty name is reserved of the dummy row */
                return -E_BLOB_SYNTAX;
        ret = send_standard_callback_request(1, argv + 1, f, &cat_output);
-       if (ret >= 0 && cat_output.data)
-               ret = send_buffer(fd, (char *)cat_output.data);
+       if (ret > 0)
+               ret = send_bin_buffer(fd, (char *)cat_output.data, cat_output.size);
        free(cat_output.data);
        return ret;
 
@@ -232,7 +233,7 @@ static int com_addblob_callback(struct osl_table *table,
        return osl_add_row(table, objs);
 }
 
-static int com_addblob(callback_function *f, __a_unused int fd, int argc,
+static int com_addblob(callback_function *f, int fd, int argc,
                char * const * const argv)
 {
        struct osl_object arg_obj;
@@ -244,7 +245,7 @@ static int com_addblob(callback_function *f, __a_unused int fd, int argc,
        PARA_NOTICE_LOG("argv[1]: %s\n", argv[1]);
        arg_obj.size = strlen(argv[1]) + 1;
        arg_obj.data = (char *)argv[1];
-       return stdin_command(&arg_obj, f, 10 * 1024 * 1024, NULL);
+       return stdin_command(fd, &arg_obj, f, 10 * 1024 * 1024, NULL);
 }
 
 static int com_rmblob_callback(struct osl_table *table,