Logo Search packages:      
Sourcecode: ldb version File versions  Download package

struct ldb_ldif* ldb_ldif_read ( struct ldb_context *  ldb,
int(*)(void *)  fgetc_fn,
void *  private_data 
) [read]

Read an LDIF message

This function creates an LDIF message using a caller supplied read function.

Parameters:
ldb the ldb context (from ldb_init())
fgetc_fn a function pointer for the read function. This must take a private data pointer, and must return a pointer to an integer corresponding to the next byte read (or EOF if there is no more data to be read).
private_data pointer that will be provided back to the read function. This is udeful for maintaining state or context.
Returns:
the LDIF message that has been read in
Note:
You must free the LDIF message when no longer required, using ldb_ldif_read_free().
See also:
ldb_ldif_read_file for a more convenient way to read from a file stream.

ldb_ldif_read_string for a more convenient way to read from a string (char array).

ldb_ldif_write for the writer equivalent to this function.

Definition at line 519 of file ldb_ldif.c.

References ldb_ldif::changetype, ldb_val::data, ldb_message::dn, ldb_message::elements, ldb_message_element::flags, ldb_attr_cmp, LDB_FLAG_MOD_ADD, LDB_FLAG_MOD_DELETE, LDB_FLAG_MOD_REPLACE, ldb_val::length, ldb_ldif::msg, ldb_message_element::name, ldb_message::num_elements, ldb_message_element::num_values, and ldb_message_element::values.

{
      struct ldb_ldif *ldif;
      struct ldb_message *msg;
      const char *attr=NULL;
      char *chunk=NULL, *s;
      struct ldb_val value;
      unsigned flags = 0;

      value.data = NULL;

      ldif = talloc(ldb, struct ldb_ldif);
      if (!ldif) return NULL;

      ldif->msg = talloc(ldif, struct ldb_message);
      if (ldif->msg == NULL) {
            talloc_free(ldif);
            return NULL;
      }

      ldif->changetype = LDB_CHANGETYPE_NONE;
      msg = ldif->msg;

      msg->dn = NULL;
      msg->elements = NULL;
      msg->num_elements = 0;

      chunk = next_chunk(ldb, fgetc_fn, private_data);
      if (!chunk) {
            goto failed;
      }
      talloc_steal(ldif, chunk);

      s = chunk;

      if (next_attr(ldif, &s, &attr, &value) != 0) {
            goto failed;
      }
      
      /* first line must be a dn */
      if (ldb_attr_cmp(attr, "dn") != 0) {
            ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'\n", 
                    attr);
            goto failed;
      }

      msg->dn = ldb_dn_new(msg, ldb, (char *)value.data);

      if ( ! ldb_dn_validate(msg->dn)) {
            ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'\n", 
                          value.data);
            goto failed;
      }

      while (next_attr(ldif, &s, &attr, &value) == 0) {
            const struct ldb_schema_attribute *a;
            struct ldb_message_element *el;
            int ret, empty = 0;

            if (ldb_attr_cmp(attr, "changetype") == 0) {
                  int i;
                  for (i=0;ldb_changetypes[i].name;i++) {
                        if (ldb_attr_cmp((char *)value.data, ldb_changetypes[i].name) == 0) {
                              ldif->changetype = ldb_changetypes[i].changetype;
                              break;
                        }
                  }
                  if (!ldb_changetypes[i].name) {
                        ldb_debug(ldb, LDB_DEBUG_ERROR, 
                                "Error: Bad ldif changetype '%s'\n",(char *)value.data);
                  }
                  flags = 0;
                  continue;
            }

            if (ldb_attr_cmp(attr, "add") == 0) {
                  flags = LDB_FLAG_MOD_ADD;
                  empty = 1;
            }
            if (ldb_attr_cmp(attr, "delete") == 0) {
                  flags = LDB_FLAG_MOD_DELETE;
                  empty = 1;
            }
            if (ldb_attr_cmp(attr, "replace") == 0) {
                  flags = LDB_FLAG_MOD_REPLACE;
                  empty = 1;
            }
            if (ldb_attr_cmp(attr, "-") == 0) {
                  flags = 0;
                  continue;
            }

            if (empty) {
                  if (ldb_msg_add_empty(msg, (char *)value.data, flags, NULL) != 0) {
                        goto failed;
                  }
                  continue;
            }
            
            el = &msg->elements[msg->num_elements-1];

            a = ldb_schema_attribute_by_name(ldb, attr);

            if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 &&
                flags == el->flags) {
                  /* its a continuation */
                  el->values = 
                        talloc_realloc(msg->elements, el->values, 
                                     struct ldb_val, el->num_values+1);
                  if (!el->values) {
                        goto failed;
                  }
                  ret = a->syntax->ldif_read_fn(ldb, ldif, &value, &el->values[el->num_values]);
                  if (ret != 0) {
                        goto failed;
                  }
                  if (value.length == 0) {
                        ldb_debug(ldb, LDB_DEBUG_ERROR,
                                "Error: Attribute value cannot be empty for attribute '%s'\n", el->name);
                        goto failed;
                  }
                  if (value.data != el->values[el->num_values].data) {
                        talloc_steal(el->values, el->values[el->num_values].data);
                  }
                  el->num_values++;
            } else {
                  /* its a new attribute */
                  msg->elements = talloc_realloc(ldif, msg->elements, 
                                           struct ldb_message_element, 
                                           msg->num_elements+1);
                  if (!msg->elements) {
                        goto failed;
                  }
                  el = &msg->elements[msg->num_elements];
                  el->flags = flags;
                  el->name = talloc_strdup(msg->elements, attr);
                  el->values = talloc(msg->elements, struct ldb_val);
                  if (!el->values || !el->name) {
                        goto failed;
                  }
                  el->num_values = 1;
                  ret = a->syntax->ldif_read_fn(ldb, ldif, &value, &el->values[0]);
                  if (ret != 0) {
                        goto failed;
                  }
                  if (value.data != el->values[0].data) {
                        talloc_steal(el->values, el->values[0].data);
                  }
                  msg->num_elements++;
            }
      }

      return ldif;

failed:
      talloc_free(ldif);
      return NULL;
}


Generated by  Doxygen 1.6.0   Back to index