Beispiel #1
0
static unsigned char * handle_get_quad_freq (fs_backend *be, fs_segment segment,
                                             unsigned int length,
                                             unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length != 8) {
    fs_error(LOG_ERR, "get_quad_freq(%d) wrong length %u", segment, length);
    return fsp_error_new(segment, "wrong length");
  }

  int index, count;
  memcpy(&index, content, sizeof(int));
  memcpy(&count, content + sizeof(int), sizeof(int));

  const char *filename;

  /* this branch has no frequency data */
  filename = "";
  int fd = open(filename, FS_O_NOATIME | O_RDONLY, 0);
  unsigned char *reply =  message_new(FS_QUAD_FREQ, segment, count * sizeof(fs_quad_freq));
  //ssize_t bytes = read(fd, reply + FS_HEADER, count * sizeof(fs_quad_freq));
  ssize_t bytes = 0;

  unsigned int *l = (unsigned int *) (reply + 4);
  *l = bytes;
  close(fd);

  return reply;
}
Beispiel #2
0
static unsigned char * handle_commit_quad (fs_backend *be, fs_segment segment,
                                             unsigned int length,
                                             unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length != sizeof(int)) {
    fs_error(LOG_ERR, "commit_quad(%d) missing flags", segment);
    return fsp_error_new(segment, "missing flags");
  }

  int flags;

  memcpy(&flags, content, sizeof (flags));
  int ret = fs_quad_import_commit(be, segment, flags, 1);
  if (ret) {
    fs_error(LOG_ERR, "commit_quad(%d) failed", segment);
    return fsp_error_new(segment, "quad commit failed");
  }

  return message_new(FS_DONE_OK, segment, 0);
}
Beispiel #3
0
static unsigned char * handle_new_models (fs_backend *be, fs_segment segment,
                                          unsigned int length,
                                          unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length < sizeof(fs_rid)) {
    fs_error(LOG_ERR, "new_models(%d) missing model RIDs", segment);
    return fsp_error_new(segment, "missing model RIDs");
  }

  fs_rid *models = (fs_rid *) content;

  int invalid_count = 0;
  for (int k= 0; k < (length / sizeof(fs_rid)); ++k) {
    if (FS_IS_URI(models[k])) {
      fs_backend_model_set_usage(be, segment, models[k], 0);
    } else {
      invalid_count++;
    }
  }
  fs_mhash_flush(be->models);

  if (invalid_count > 0) {
    return fsp_error_new(segment, "one or more model RIDs is not a URI");
  }
  return message_new(FS_DONE_OK, segment, 0);
}
Beispiel #4
0
static unsigned char * handle_insert_quad (fs_backend *be, fs_segment segment,
                                             unsigned int length,
                                             unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length < 40) {
    fs_error(LOG_ERR, "insert_quad(%d) too short", segment);
    return fsp_error_new(segment, "too short");
  }

  int flags;
  int count = (length - 8) / 32;
  fs_rid (*buffer)[4] = (fs_rid (*)[4]) (content + 8);

  memcpy(&flags, content, sizeof (flags));
  int ret = fs_quad_import(be, segment, flags, count, buffer);
  if (ret) {
    fs_error(LOG_ERR, "insert_quad(%d) failed", segment);
    return fsp_error_new(segment, "quad insert failed");
  }

  return NULL; /* no reply - semi-async */
}
Beispiel #5
0
static unsigned char * handle_get_data_size (fs_backend *be, fs_segment segment,
                                             unsigned int length,
                                             unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length > 0) {
    fs_error(LOG_ERR, "get_data_size(%d) extraneous content", segment);
    return fsp_error_new(segment, "extraneous content");
  }

  fs_data_size size = fs_get_data_size(be, segment);

  fs_old_data_size old_size;
  old_size.quads_s = size.quads_s;
  old_size.quads_o = size.quads_o;
  old_size.resources = size.resources;
  old_size.models_s = size.models_s;
  old_size.models_o = size.models_o;
  unsigned char *reply =  message_new(FS_SIZE, segment, sizeof(old_size));

  memcpy(reply + FS_HEADER, &old_size, sizeof(old_size));
  return reply;
}
Beispiel #6
0
static unsigned char * handle_resolve_attr (fs_backend *be, fs_segment segment,
                                            unsigned int length,
                                            unsigned char *content)
{
  unsigned int count = length / sizeof(fs_rid);

  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length < sizeof(fs_rid)) {
    fs_error(LOG_ERR, "resolve_attr(%d) too short", segment);
    return fsp_error_new(segment, "too short");
  }

  unsigned char *reply;

  fs_rid_vector v;
  fs_resource resources[count];
  v.size = v.length = count; 
  v.data = (fs_rid *) content;

  fs_resolve(be, segment, &v, resources);

  unsigned int k, serial_length = 0;
  for (k = 0; k < count; ++k) {
    if (resources[k].lex) {
      serial_length+= ((28 + strlen(resources[k].lex)) / 8);
    } else {
      serial_length+= 3;
    }
  }

  reply = message_new(FS_RESOURCE_ATTR_LIST, segment, 8 * serial_length);
  unsigned char *record = reply + FS_HEADER;

  for (k = 0; k < count; ++k) {
    unsigned int one_length;
    if (resources[k].lex) {
      one_length = ((28 + strlen(resources[k].lex)) / 8) * 8;
    } else {
      one_length = 24;
    }
    memcpy(record, &(resources[k].rid), sizeof (fs_rid));
    memcpy(record + 8, &(resources[k].attr), sizeof (fs_rid));
    memcpy(record + 16, &one_length, sizeof(one_length));

/* ASCII NUL is used to terminate strings on the wire */
    if (resources[k].lex) {
      strcpy((char *) record + 20, resources[k].lex);
    } else {
      *(record + 20) = '\0';
    }
    record += one_length;
  }

  return reply;
}
Beispiel #7
0
static unsigned char * handle_bind_next (fs_backend *be, fs_segment segment,
                                          unsigned int length,
                                          unsigned char *content)
{
  unsigned char *reply;

  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length != 8) {
    fs_error(LOG_ERR, "bind_next(%d) wrong length %u", segment, length);
    return fsp_error_new(segment, "wrong length");
  }

  unsigned int flags;
  int count;

  memcpy(&flags, content, sizeof (flags));
  memcpy(&count, content + 4, sizeof (count));

  fs_rid_vector **bindings;
  bindings = fs_bind_next(be, segment, flags, count);

  int k, cols = 0;
  for (k = 0; k < 4; ++k) {
    if (flags & 1 << k) cols++;
  }

  if (bindings == NULL) {
    /* NULL => no match */
    reply = message_new(FS_NO_MATCH, segment, 0);
    cols = 0;
  } else if (cols == 0) {
    /* Zero columns => match with no binding */
    reply = message_new(FS_BIND_LIST, segment, 0);
  } else {
    /* otherwise return bindings */
    reply = message_new(FS_BIND_LIST, segment, bindings[0]->length * 8 * cols);
    unsigned char *data = reply + FS_HEADER;

    for (k= 0; k < cols; ++k) {
      memcpy(data, bindings[k]->data, bindings[k]->length * 8);
      data += bindings[k]->length * 8;
    }
  }

  for (k = 0; k < cols; ++k) {
    fs_rid_vector_free(bindings[k]);
  }
  free(bindings);

  return reply;
}
Beispiel #8
0
static unsigned char * handle_price (fs_backend *be, fs_segment segment,
                                     unsigned int length,
                                     unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length < 24) {
    fs_error(LOG_ERR, "price(%d) much too short", segment);
    return fsp_error_new(segment, "much too short");
  }

  unsigned char *reply;
  unsigned long long int rows = 0;
  fs_rid_vector models, subjects, predicates, objects;
  unsigned int flags, value;

  memcpy(&flags, content, sizeof (flags));
  memcpy(&value, content + 4, sizeof (models.length));
  models.size = models.length = value / 8;
  memcpy(&value, content + 8, sizeof (subjects.length));
  subjects.size = subjects.length = value / 8;
  memcpy(&value, content + 12, sizeof (predicates.length));
  predicates.size = predicates.length = value / 8;
  memcpy(&value, content + 16, sizeof (objects.length));
  objects.size = objects.length = value / 8;
  content += 24;

  if (length < (models.size + subjects.size + predicates.size + objects.size) * 8 + 24) {
    fs_error(LOG_ERR, "price(%d) too short", segment);
    return fsp_error_new(segment, "too short");
  }

  models.data = (fs_rid *) content;
  content += models.length * 8;

  subjects.data = (fs_rid *) content;
  content += subjects.length * 8;

  predicates.data = (fs_rid *) content;
  content += predicates.length * 8;

  objects.data = (fs_rid *) content;

  rows = fs_bind_price(be, segment, flags, &models, &subjects, &predicates, &objects);

  reply = message_new(FS_ESTIMATED_ROWS, segment, 8);
  memcpy(reply + FS_HEADER, &rows, sizeof(rows));
  return reply;
}
Beispiel #9
0
static unsigned char * handle_lock (fs_backend *be,
                                    fs_segment segment,
                                    unsigned int length,
                                    unsigned char *content)
{
  return fsp_error_new(segment, "radix backend does not support/require locking");
}
Beispiel #10
0
static unsigned char * handle_commit_resource (fs_backend *be, fs_segment segment,
                                               unsigned int length,
                                               unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length > 0) {
    fs_error(LOG_ERR, "commit_resource(%d) extraneous content", segment);
    return fsp_error_new(segment, "extraneous content");
  }

  fs_res_import_commit(be, segment, 1);

  return message_new(FS_DONE_OK, segment, 0);
}
Beispiel #11
0
static unsigned char * handle_delete_quads (fs_backend *be, fs_segment segment,
                                          unsigned int length,
                                          unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length < 32) {
    fs_error(LOG_ERR, "delete_quads(%d) much too short", segment);
    return fsp_error_new(segment, "much too short");
  }

  fs_rid_vector models, subjects, predicates, objects;

  models.size = models.length = length / 32;
  subjects.size = subjects.length = length / 32;
  predicates.size = predicates.length = length / 32;
  objects.size = objects.length = length / 32;

  if (length < (models.size + subjects.size + predicates.size + objects.size) * 8) {
    fs_error(LOG_ERR, "delete_quads(%d) too short (%d < %d)", segment, length,
	     (models.size + subjects.size + predicates.size + objects.size) * 8);
    return fsp_error_new(segment, "too short");
  }

  models.data = (fs_rid *) content;
  content += models.length * 8;

  subjects.data = (fs_rid *) content;
  content += subjects.length * 8;

  predicates.data = (fs_rid *) content;
  content += predicates.length * 8;

  objects.data = (fs_rid *) content;

  fs_rid_vector *args[4] = { &models, &subjects, &predicates, &objects };
  fs_delete_quads(be, args);
  /* FIXME, should check return value */

  return message_new(FS_DONE_OK, 0, 0);
}
Beispiel #12
0
static unsigned char * handle_get_size_reverse (fs_backend *be, fs_segment segment,
                                             unsigned int length,
                                             unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length > 0) {
    fs_error(LOG_ERR, "get_data_size(%d) extraneous content", segment);
    return fsp_error_new(segment, "extraneous content");
  }

  fs_data_size size = fs_get_data_size(be, segment);
  unsigned char *reply =  message_new(FS_SIZE_REVERSE, segment, sizeof(size.quads_sr));

  memcpy(reply + FS_HEADER, &size.quads_sr, sizeof(size.quads_sr));
  return reply;
}
Beispiel #13
0
static unsigned char * handle_auth (fs_backend *be,
                                    fs_segment segment,
                                    unsigned int length,
                                    unsigned char *content)
{
  md5_state_t md5;

  if (length <= 16) {
    fs_error(LOG_ERR, "auth(%d) missing kbname", segment);
    return fsp_error_new(segment, "missing kbname");
  }

  if (strncmp(be->db_name, (char *) content + 16, length - 16)) {
    fs_error(LOG_ERR, "auth(%d) wrong kbname", segment);
    return fsp_error_new(segment, "wrong kbname");
  }

  if (be->salt) {
    unsigned char data[20], hash[16];
    char string[33];
    memcpy(data, (&be->salt), sizeof(be->salt));

    memcpy(data + 4, content, 16);
    md5_init(&md5);
    md5_append(&md5, data, sizeof(data));
    md5_finish(&md5, hash);
    sprintf(string, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7],
            hash[8], hash[9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]);

    if (strcmp(string, be->hash)) {
      fs_error(LOG_ERR, "auth(%d) invalid password", segment);
      return fsp_error_new(segment, "invalid password");
    }
  }
  
  /* in-band signal, string of features */
  unsigned char *reply = message_new(FS_DONE_OK, 0, sizeof(feature_string));
  memcpy(reply + FS_HEADER, feature_string, sizeof(feature_string));
  return reply;
}
Beispiel #14
0
static unsigned char * handle_choose_segment (fs_backend *be, fs_segment segment,
                                              unsigned int length,
                                              unsigned char *content)
{
  if (fs_backend_open_files(be, segment, O_RDWR | O_CREAT, FS_OPEN_ALL)) {
    fs_error(LOG_ERR, "failed to open files for segment %d", segment);

    return fsp_error_new(segment, "cannot open indexes");
  }

  return message_new(FS_DONE_OK, 0, 0);
}
Beispiel #15
0
static unsigned char * handle_get_query_times (fs_backend *be,
                                                fs_segment segment,
                                                unsigned int length,
                                                unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length > 0) {
    fs_error(LOG_ERR, "get_query_times(%d) extraneous content", segment);
    return fsp_error_new(segment, "extraneous content");
  }

  fs_query_timing timing = fs_get_query_times(be, segment);
  unsigned char *reply =  message_new(FS_QUERY_TIMES, segment, sizeof(timing));

  memcpy(reply + FS_HEADER, &timing, sizeof(timing));
  return reply;
}
Beispiel #16
0
static unsigned char * handle_delete_models (fs_backend *be, fs_segment segment,
                                             unsigned int length,
                                             unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length < sizeof(fs_rid)) {
    fs_error(LOG_ERR, "delete_models(%d) missing model RIDs", segment);
    return fsp_error_new(segment, "missing model RIDs");
  }

  fs_rid_vector models;
  models.size = models.length  = length / sizeof(fs_rid);
  models.data = (fs_rid *) content;

  fs_delete_models(be, segment, &models);

  return message_new(FS_DONE_OK, segment, 0);
}
Beispiel #17
0
static unsigned char * handle_stop_import (fs_backend *be, fs_segment segment,
                                           unsigned int length,
                                           unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length > 0) {
    fs_error(LOG_ERR, "stop_import(%d) extraneous content", segment);
    return fsp_error_new(segment, "extraneous content");
  }

  int ret = fs_stop_import(be, segment);

  if (ret) {
    return fsp_error_new(segment, "insert failed");
  }

  return message_new(FS_DONE_OK, segment, 0);
}
Beispiel #18
0
static unsigned char * handle_node_segments (fs_backend *be,
                                             fs_segment segment,
                                             unsigned int length,
                                             unsigned char *content)
{
  if (segment != 0) {
    fs_error(LOG_ERR, "segments(%d) should only be sent with segment = 0", segment);
    return fsp_error_new(segment, "only to be sent to segment = 0");
  }

  if (length > 0) {
    fs_error(LOG_ERR, "segments(%d) extraneous content", segment);
    return fsp_error_new(segment, "extraneous content");
  }

  char segments[be->segments];
  fs_node_segments(be, segments);
  unsigned char *reply =  message_new(FS_NODE_SEGMENT_LIST, be->segments, be->segments);

  memcpy(reply + FS_HEADER, segments, be->segments);
  return reply;
}
Beispiel #19
0
static unsigned char * handle_or_fail(const char *name,
                                      fsp_backend_fn handle_fn,
                                      fs_backend *be,
                                      fs_segment segment,
                                      unsigned int length,
                                      unsigned char *content)
{
  if (handle_fn) {
    return handle_fn(be, segment, length, content);
  } else {
    kb_error(LOG_ERR, "no implementation for %s", name);
    return fsp_error_new(segment, "not implemented");
  }
}
Beispiel #20
0
static unsigned char * handle_bnode_alloc (fs_backend *be,
                                           fs_segment segment,
                                           unsigned int length,
                                           unsigned char *content)
{
  if (segment != 0) {
    fs_error(LOG_ERR, "bnode_alloc(%d) should only be sent to segment zero", segment);
    return fsp_error_new(segment, "only to be sent to segment zero");
  }

  if (length != sizeof(int)) {
    fs_error(LOG_ERR, "bnode_alloc(%d) missing count", segment);
    return fsp_error_new(segment, "missing count");
  }

  int count;

  memcpy(&count, content, sizeof(count));
  unsigned char *reply = message_new(FS_BNODE_RANGE, 0, 16);
  unsigned char *range = reply + FS_HEADER;
  fs_bnode_alloc(be, count, (fs_rid *) range, (fs_rid *) (range + sizeof(fs_rid)));
  
  return reply;
}
Beispiel #21
0
static unsigned char * handle_start_import (fs_backend *be, fs_segment segment,
                                            unsigned int length,
                                            unsigned char *content)
{
  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length > 0) {
    fs_error(LOG_ERR, "start_import(%d) extraneous content", segment);
    return fsp_error_new(segment, "extraneous content");
  }

  float free_space = fs_free_disk(fs_backend_get_kb(be));
  if (free_space < be->min_free) {
    fs_error(LOG_ERR, "segment %d only has %.1f%% free space", segment, free_space);
    return fsp_error_new(segment, "low disk space");
  }

  fs_start_import(be, segment);

  return message_new(FS_DONE_OK, segment, 0);
}
Beispiel #22
0
static unsigned char * handle_transaction (fs_backend *be,
                                    fs_segment segment,
                                    unsigned int length,
                                    unsigned char *content)
{
  if (length != 1) {
    fs_error(LOG_ERR, "transaction(%d), missing flag", segment);
    return fsp_error_new(segment, "missing flag");
  }

  int ret = fs_backend_transaction(be, segment, *content);

  if (ret == 2) {
    if (*content == FS_TRANS_BEGIN) {
      return fsp_error_new(segment, "transaction already begun");
   } else {
      return fsp_error_new(segment, "transaction not begun");
   }
  } else if (ret) {
    return fsp_error_new(segment, "transaction error");
  }

  return message_new(FS_DONE_OK, 0, 0);
}
Beispiel #23
0
static void child (int conn, fsp_backend *backend, fs_backend *be)
{
  int auth = 0;

  while (1) {
    fs_segment segment;
    unsigned int length;
    unsigned char *msg = message_recv(conn, &segment, &length);
    unsigned char *reply = NULL;
    unsigned char *content = msg + FS_HEADER;

    if (!msg) {
      /* if the connection is in fact closed, this won't matter,
         but otherwise this error might help */
      reply = fsp_error_new(segment, "protocol mismatch");
      unsigned int* const l = (unsigned int *) (reply + 4);
      unsigned int length = *l;
      if (write(conn, reply, FS_HEADER + length) != (FS_HEADER+length)) {
        fs_error(LOG_ERR, "write failed: %s", strerror(errno));
      }
      break;
    }

    if (auth) {
      switch (msg[3]) {
        case FS_NO_OP:
          reply = fsp_handle_no_op(segment, length, content);
          break;
        case FS_RESOLVE:
          reply = handle(backend->resolve, be, segment, length, content);
          break;
        case FS_BIND:
          reply = handle(backend->bind, be, segment, length, content);
          break;
        case FS_PRICE_BIND:
          reply = handle(backend->price, be, segment, length, content);
          break;
        case FS_DELETE_MODEL:
          reply = handle(backend->delete_models, be, segment, length, content);
          break;
        case FS_INSERT_RESOURCE:
          reply = handle(backend->insert_resource, be, segment, length, content);
          break;
        case FS_SEGMENTS:
          reply = handle(backend->segments, be, segment, length, content);
          break;
        case FS_COMMIT_RESOURCE:
          reply = handle(backend->commit_resource, be, segment, length, content);
          break;
        case FS_START_IMPORT:
          reply = handle(backend->start_import, be, segment, length, content);
          break;
        case FS_STOP_IMPORT:
          reply = handle(backend->stop_import, be, segment, length, content);
          break;
        case FS_GET_SIZE:
          reply = handle(backend->get_data_size, be, segment, length, content);
          break;
        case FS_GET_IMPORT_TIMES:
          reply = handle(backend->get_import_times, be, segment, length, content);
          break;
        case FS_INSERT_QUAD:
          reply = handle(backend->insert_quad, be, segment, length, content);
          break;
        case FS_COMMIT_QUAD:
          reply = handle(backend->commit_quad, be, segment, length, content);
          break;
        case FS_GET_QUERY_TIMES:
          reply = handle(backend->get_query_times, be, segment, length, content);
          break;
        case FS_BIND_LIMIT:
          reply = handle(backend->bind_limit, be, segment, length, content);
          break;
        case FS_BNODE_ALLOC:
          reply = handle(backend->bnode_alloc, be, segment, length, content);
          break;
        case FS_RESOLVE_ATTR:
          reply = handle(backend->resolve_attr, be, segment, length, content);
          break;
        case FS_DELETE_MODELS:
          reply = handle(backend->delete_models, be, segment, length, content);
          break;
        case FS_NEW_MODELS:
          reply = handle(backend->new_models, be, segment, length, content);
          break;
        case FS_BIND_FIRST:
          reply = handle(backend->bind_first, be, segment, length, content);
          break;
        case FS_BIND_NEXT:
          reply = handle(backend->bind_next, be, segment, length, content);
          break;
        case FS_BIND_DONE:
          reply = handle(backend->bind_done, be, segment, length, content);
          break;
        case FS_TRANSACTION:
          reply = handle(backend->transaction, be, segment, length, content);
          break;
        case FS_NODE_SEGMENTS:
          reply = handle(backend->node_segments, be, segment, length, content);
          break;
        case FS_REVERSE_BIND:
          reply = handle(backend->reverse_bind, be, segment, length, content);
          break;
        case FS_LOCK:
          reply = handle(backend->lock, be, segment, length, content);
          break;
        case FS_UNLOCK:
          reply = handle(backend->unlock, be, segment, length, content);
          break;
        case FS_GET_SIZE_REVERSE:
          reply = handle(backend->get_size_reverse, be, segment, length, content);
          break;
        case FS_GET_QUAD_FREQ:
          reply = handle(backend->get_quad_freq, be, segment, length, content);
          break;
        case FS_CHOOSE_SEGMENT:
          reply = handle(backend->choose_segment, be, segment, length, content);
          break;
	case FS_DELETE_QUADS:
	  reply = handle(backend->delete_quads, be, segment, length, content);
	  break;
	case FS_GET_UUID:
	  reply = handle(backend->get_uuid, be, segment, length, content);
	  break;
        default:
          kb_error(LOG_WARNING, "unexpected message type (%d)", msg[3]);
          reply = fsp_error_new(segment, "unexpected message type");
          break;
      }
    } else if (msg[3] == FS_AUTH) {
      if (backend->auth) {
        reply = backend->auth(be, segment, length, content);
      } else {
        reply = message_new(FS_DONE_OK, segment, 0);
      }
      if (reply[3] == FS_DONE_OK) auth = 1;
    } else  {
      reply = fsp_error_new(segment, "authenticate before continuing");
    }

    if (reply) {
      unsigned int* const l = (unsigned int *) (reply + 4);
      unsigned int length = *l;
      if (write(conn, reply, FS_HEADER + length) <= 0) {
        kb_error(LOG_WARNING, "write reply failed");
      }
      free(reply);
    }
    free(msg);
  }
}
Beispiel #24
0
static unsigned char * handle_bind_first (fs_backend *be, fs_segment segment,
                                          unsigned int length,
                                          unsigned char *content)
{
  unsigned char *reply;

  if (segment > be->segments) {
    fs_error(LOG_ERR, "invalid segment number: %d", segment);
    return fsp_error_new(segment, "invalid segment number");
  }

  if (length < 32) {
    fs_error(LOG_ERR, "bind_first(%d) much too short", segment);
    return fsp_error_new(segment, "much too short");
  }

  fs_rid_vector models, subjects, predicates, objects;
  unsigned int flags, value;
  int count;

  memcpy(&flags, content, sizeof (flags));
  memcpy(&count, content + 4, sizeof (count));
  memcpy(&value, content + 12, sizeof (models.length));
  models.size = models.length = value / 8;
  memcpy(&value, content + 16, sizeof (subjects.length));
  subjects.size = subjects.length = value / 8;
  memcpy(&value, content + 20, sizeof (predicates.length));
  predicates.size = predicates.length = value / 8;
  memcpy(&value, content + 24, sizeof (objects.length));
  objects.size = objects.length = value / 8;
  content += 32;

  if (length < (models.size + subjects.size + predicates.size + objects.size) * 8 + 32) {
    fs_error(LOG_ERR, "bind_first(%d) too short", segment);
    return fsp_error_new(segment, "too short");
  }

  models.data = (fs_rid *) content;
  content += models.length * 8;

  subjects.data = (fs_rid *) content;
  content += subjects.length * 8;

  predicates.data = (fs_rid *) content;
  content += predicates.length * 8;

  objects.data = (fs_rid *) content;

  fs_rid_vector **bindings;
  bindings = fs_bind_first(be, segment, flags, &models, &subjects,
                           &predicates, &objects, count);

  int k, cols = 0;
  for (k = 0; k < 4; ++k) {
    if (flags & 1 << k) cols++;
  }

  if (bindings == NULL) {
    /* NULL => no match */
    reply = message_new(FS_NO_MATCH, segment, 0);
    cols = 0;
  } else if (cols == 0) {
    /* Zero columns => match with no binding */
    reply = message_new(FS_BIND_LIST, segment, 0);
  } else {
    /* otherwise return bindings */
    reply = message_new(FS_BIND_LIST, segment, bindings[0]->length * 8 * cols);
    unsigned char *data = reply + FS_HEADER;

    for (k= 0; k < cols; ++k) {
      memcpy(data, bindings[k]->data, bindings[k]->length * 8);
      data += bindings[k]->length * 8;
    }
  }

  for (k = 0; k < cols; ++k) {
    fs_rid_vector_free(bindings[k]);
  }
  free(bindings);

  return reply;
}