Exemplo n.º 1
0
END_TEST

START_TEST(remove_test)
{
  dpl_dict_t *dict;
  int i;
  dpl_status_t r;
  char valbuf[128];

  /* create with a small table to ensure we have some chains */
  dict = dpl_dict_new(5);
  dpl_assert_ptr_not_null(dict);

  /* add all the keys */
  for (i = 0 ; i < nkeys ; i++)
    {
      dpl_dict_add(dict, keys[i],
			 make_value(i, valbuf, sizeof(valbuf)),
			 /* lowered */0);
    }
  dpl_assert_int_eq(nkeys, dpl_dict_count(dict));

  /* remove the keys again */
  for (i = 0 ; i < nkeys ; i++)
    {
      dpl_dict_var_t *var = dpl_dict_get(dict, keys[i]);
      dpl_assert_ptr_not_null(var);
      dpl_assert_str_eq(var->key, keys[i]);
      dpl_dict_remove(dict, var);
      dpl_assert_int_eq(nkeys-1-i, dpl_dict_count(dict));
    }

  /* add all the keys back again */
  for (i = 0 ; i < nkeys ; i++)
    {
      dpl_dict_add(dict, keys[i],
			 make_value(i, valbuf, sizeof(valbuf)),
			 /* lowered */0);
    }
  dpl_assert_int_eq(nkeys, dpl_dict_count(dict));

  /* remove the keys again in reverse order; we do
   * this to exercise some hash chain manipulation
   * corner cases */
  for (i = nkeys-1 ; i >= 0 ; i--)
    {
      dpl_dict_var_t *var = dpl_dict_get(dict, keys[i]);
      dpl_assert_ptr_not_null(var);
      dpl_assert_str_eq(var->key, keys[i]);
      dpl_dict_remove(dict, var);
      dpl_assert_int_eq(i, dpl_dict_count(dict));
    }

  dpl_dict_free(dict);
}
Exemplo n.º 2
0
void
cb_get_metadata(void *handle)
{
  dpl_async_task_t *atask = (dpl_async_task_t *) handle;
  dpl_dict_var_t *metadatum = NULL;

  if (DPL_SUCCESS != atask->ret)
    {
      fprintf(stderr, "error getting metadata: %s (%d)\n", dpl_status_str(atask->ret), atask->ret);
      exit(1);
    }

  fprintf(stderr, "checking metadata\n");

  metadatum = dpl_dict_get(atask->u.head.metadata, "foo");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      exit(1);
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "bar2"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      exit(1);
    }

  metadatum = dpl_dict_get(atask->u.head.metadata, "foo2");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      exit(1);
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "qux"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      exit(1);
    }

  dpl_async_task_free(atask);

  list_bucket();
}
Exemplo n.º 3
0
dpl_status_t
dpl_srws_get_metadata_from_headers(const dpl_dict_t *headers,
                                   dpl_dict_t *metadata)
{
  int ret;
  dpl_var_t *var;
  int value_len;
  char *orig;
  int orig_len;
  struct mdparse_data arg;

  DPRINTF("srws_get_metadata_from_headers\n");

  memset(&arg, 0, sizeof (arg));

  var = dpl_dict_get(headers, DPL_SRWS_X_BIZ_USERMD);
  if (NULL == var)
    {
      //no metadata;
      ret = DPL_SUCCESS;
      goto end;
    }

  DPRINTF("val=%s\n", var->value);

  //decode base64
  value_len = strlen(var->value);
  if (value_len == 0)
    return DPL_EINVAL;

  orig_len = DPL_BASE64_ORIG_LENGTH(value_len);
  orig = alloca(orig_len);

  orig_len = dpl_base64_decode((u_char *) var->value, value_len, (u_char *) orig);
  
  //dpl_dump_simple(orig, orig_len);

  arg.metadata = metadata;
  arg.orig = orig;
  arg.orig_len = orig_len;
  ret = dpl_ntinydb_list(orig, orig_len, cb_ntinydb, &arg);
  if (DPL_SUCCESS != ret)
    goto end;

  ret = DPL_SUCCESS;
  
 end:

  return ret;
}
Exemplo n.º 4
0
void
fill_stat_from_metadata(struct stat *st,
                        dpl_dict_t *dict)
{
        STORE_META(st, dict, size, size_t);
        STORE_META(st, dict, mode, mode_t);
        STORE_META(st, dict, uid, uid_t);
        STORE_META(st, dict, gid, gid_t);
        STORE_META(st, dict, atime, time_t);
        STORE_META(st, dict, ctime, time_t);
        STORE_META(st, dict, mtime, time_t);

        if (dpl_dict_get(dict, "symlink"))
                st->st_mode |= S_IFLNK;
}
Exemplo n.º 5
0
dpl_ino_t
dpl_cwd(dpl_ctx_t *ctx,
        char *bucket)
{
  dpl_var_t *var;
  dpl_ino_t cwd;

  var = dpl_dict_get(ctx->cwds, bucket);
  if (NULL != var)
    strcpy(cwd.key, var->value); //XXX check overflow
  else
    cwd = DPL_ROOT_INO;

  return cwd;
}
Exemplo n.º 6
0
static dpl_status_t
add_payload_signature_to_headers(const dpl_req_t *req, dpl_dict_t *headers)
{
  uint8_t               digest[SHA256_DIGEST_LENGTH];
  char                  digest_hex[DPL_HEX_LENGTH(sizeof digest) + 1];
  int                   i;
  dpl_dict_var_t        *var;

  var = dpl_dict_get(headers, "x-amz-content-sha256");
  if (var != NULL)
    return DPL_SUCCESS;

  if (req->data_enabled)
    dpl_sha256((uint8_t *) req->data_buf, req->data_len, digest);
  else
    dpl_sha256((uint8_t *) "", 0, digest);

  for (i = 0; i < sizeof digest; i++)
    sprintf(digest_hex + 2 * i, "%02x", (u_char) digest[i]);

  return dpl_dict_add(headers, "x-amz-content-sha256", digest_hex, 0);
}
Exemplo n.º 7
0
/** 
 * parse a value into a suitable metadata or sysmd
 * 
 * @param key 
 * @param val 
 * @param metadatum_func
 * @param cb_arg
 * @param metadata 
 * @param sysmdp 
 * 
 * @return 
 */
dpl_status_t
dpl_cdmi_get_metadatum_from_value(const char *key,
                                  dpl_value_t *val,
                                  dpl_metadatum_func_t metadatum_func,
                                  void *cb_arg,
                                  dpl_dict_t *metadata,
                                  dpl_sysmd_t *sysmdp)
{
  dpl_status_t ret, ret2;
  dpl_dict_var_t *var;
  dpl_cdmi_object_id_t obj_id;

  DPRINTF("key=%s val.type=%d\n", key, val->type);

  if (val == NULL)
   {
     ret = DPL_EINVAL;
	 goto end;
   }
  if (sysmdp)
    {
      if (!strcmp(key, "objectID"))
        {
          if (DPL_VALUE_STRING != val->type)
            {
              ret = DPL_EINVAL;
              goto end;
            }
          
          ret2 = dpl_cdmi_string_to_object_id(dpl_sbuf_get_str(val->string),
                                              &obj_id);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
          
          ret2 = dpl_cdmi_opaque_to_string(&obj_id, sysmdp->id);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
          
          sysmdp->mask |= DPL_SYSMD_MASK_ID;
          
          sysmdp->enterprise_number = obj_id.enterprise_number;
          sysmdp->mask |= DPL_SYSMD_MASK_ENTERPRISE_NUMBER;
        }
      else if (!strcmp(key, "parentID"))
        {
          if (DPL_VALUE_STRING != val->type)
            {
              ret = DPL_EINVAL;
              goto end;
            }

          if (strcmp(dpl_sbuf_get_str(val->string), ""))
            {
              ret2 = dpl_cdmi_string_to_object_id(dpl_sbuf_get_str(val->string), &obj_id);
              if (DPL_SUCCESS != ret2)
                {
                  ret = ret2;
                  goto end;
                }
              
              ret2 = dpl_cdmi_opaque_to_string(&obj_id, sysmdp->parent_id);
              if (DPL_SUCCESS != ret2)
                {
                  ret = ret2;
                  goto end;
                }
              
              sysmdp->mask |= DPL_SYSMD_MASK_PARENT_ID;
            }
        }
      else if (!strcmp(key, "objectType"))
        {
          if (DPL_VALUE_STRING != val->type)
            {
              ret = DPL_EINVAL;
              goto end;
            }
          
          sysmdp->mask |= DPL_SYSMD_MASK_FTYPE;
          sysmdp->ftype = dpl_cdmi_content_type_to_ftype(dpl_sbuf_get_str(val->string));
        }
    }

  if (!strcmp(key, "metadata"))
    {
      //this is the metadata object
      if (DPL_VALUE_SUBDICT != val->type)
        {
          ret = DPL_EINVAL;
          goto end;
        }

      if (sysmdp)
        {
          //some sysmds are stored in metadata
          
          var = dpl_dict_get(val->subdict, "cdmi_mtime");
          if (NULL != var)
            {
              if (DPL_VALUE_STRING != var->val->type)
                {
                  ret = DPL_EINVAL;
                  goto end;
                }
              
              sysmdp->mask |= DPL_SYSMD_MASK_MTIME;
              sysmdp->mtime = dpl_iso8601totime(dpl_sbuf_get_str(var->val->string));
            }
          
          var = dpl_dict_get(val->subdict, "cdmi_atime");
          if (NULL != var)
            {
              if (DPL_VALUE_STRING != var->val->type)
                {
                  ret = DPL_EINVAL;
                  goto end;
                }
              
              sysmdp->mask |= DPL_SYSMD_MASK_ATIME;
              sysmdp->atime = dpl_iso8601totime(dpl_sbuf_get_str(var->val->string));
            }
          
          var = dpl_dict_get(val->subdict, "cdmi_size");
          if (NULL != var)
            {
              if (DPL_VALUE_STRING != var->val->type)
                {
                  ret = DPL_EINVAL;
                  goto end;
                }
              
              sysmdp->mask |= DPL_SYSMD_MASK_SIZE;
              sysmdp->size = strtoull(dpl_sbuf_get_str(var->val->string), NULL, 0);
            }
        }

      if (metadata)
        {
          struct metadata_list_arg arg;
          
          arg.metadatum_func = metadatum_func;
          arg.metadata = metadata;
          arg.cb_arg = cb_arg;

          //iterate metadata object
          ret2 = dpl_dict_iterate(val->subdict, cb_metadata_list, &arg);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
        }
    }
  
  ret = DPL_SUCCESS;
  
 end:

  return ret;
}
Exemplo n.º 8
0
void
cb_get_object(void *handle)
{
  dpl_async_task_t *atask = (dpl_async_task_t *) handle;
  int i;
  dpl_dict_var_t *metadatum = NULL;

  if (DPL_SUCCESS != atask->ret)
    {
      fprintf(stderr, "dpl_get failed: %s (%d)\n", dpl_status_str(atask->ret), atask->ret);
      exit(1);
    }

  fprintf(stderr, "checking object\n");

  if (DATA_LEN != atask->u.get.buf->size)
    {
      fprintf(stderr, "data lengths mismatch\n");
      exit(1);
    }

  for (i = 0;i < DATA_LEN;i++)
    if (atask->u.get.buf->ptr[i] != 'z')
      {
        fprintf(stderr, "data content mismatch\n");
        exit(1);
      }

  fprintf(stderr, "checking metadata\n");

  metadatum = dpl_dict_get(atask->u.get.metadata, "foo");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      exit(1);
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "bar"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      exit(1);
    }
  
  metadatum = dpl_dict_get(atask->u.get.metadata, "foo2");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      exit(1);
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "qux"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      exit(1);
    }

  dpl_async_task_free(atask);

  update_metadata();
}
Exemplo n.º 9
0
int
main(int argc,
     char **argv)
{
  int ret;
  dpl_ctx_t *ctx;
  dpl_dict_t *metadata = NULL;
  char *data_buf = NULL;
  size_t data_len;
  char *data_buf_returned = NULL;
  u_int data_len_returned;
  dpl_dict_t *metadata_returned = NULL;
  dpl_dict_t *metadata2_returned = NULL;
  dpl_dict_var_t *metadatum = NULL;
  dpl_option_t option;
  dpl_sysmd_t sysmd;
  char *force_id = NULL;
  
  if (2 == argc)
    {
      force_id = argv[1];
    }
  else if (1 != argc)
    {
      fprintf(stderr, "usage: idtest [id]\n");
      ret = 1;
      goto end;
    }

  ret = dpl_init();           //init droplet library
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "dpl_init failed\n");
      ret = 1;
      goto end;
    }

  //open default profile
  ctx = dpl_ctx_new(NULL,     //droplet directory, default: "~/.droplet"
                    NULL);    //droplet profile, default:   "default"
  if (NULL == ctx)
    {
      fprintf(stderr, "dpl_ctx_new failed\n");
      ret = 1;
      goto free_dpl;
    }

  //ctx->trace_level = ~0;
  //ctx->trace_buffers = 1;

  data_len = 10000;
  data_buf = malloc(data_len);
  if (NULL == data_buf)
    {
      fprintf(stderr, "alloc data failed\n");
      ret = 1;
      goto free_all;
    }

  memset(data_buf, 'z', data_len);

  metadata = dpl_dict_new(13);
  if (NULL == metadata)
    {
      fprintf(stderr, "dpl_dict_new failed\n");
      ret = 1;
      goto free_all;
    }
 
  ret = dpl_dict_add(metadata, "foo", "bar", 0);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "dpl_dict_add failed\n");
      ret = 1;
      goto free_all;
    }

  ret = dpl_dict_add(metadata, "foo2", "qux", 0);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "dpl_dict_add failed\n");
      ret = 1;
      goto free_all;
    }

  /**/
  
  fprintf(stderr, "setting object+MD\n");

  if (force_id)
    {
      //we have a broken cloud storage with no POST
      ret = dpl_put_id(ctx,           //the context
                       NULL,          //no bucket
                       force_id,      //the id
                       NULL,          //no option
                       DPL_FTYPE_REG, //regular object
                       NULL,          //no condition
                       NULL,          //no range
                       metadata,      //the metadata
                       NULL,          //no sysmd
                       data_buf,      //object body
                       data_len);     //object length
      if (DPL_SUCCESS != ret)
        {
          fprintf(stderr, "dpl_put_id failed: %s (%d)\n", dpl_status_str(ret), ret);
          ret = 1;
          goto free_all;
        }

      //emulate returned sysmd
      memset(&sysmd, 0, sizeof (sysmd));
      strncpy(sysmd.id, force_id, sizeof (sysmd.id));
    }
  else
    {
      ret = dpl_post_id(ctx,           //the context
                        NULL,          //no bucket
                        NULL,          //no id
                        NULL,          //no option
                        DPL_FTYPE_REG, //regular object
                        NULL,          //condition
                        NULL,          //range
                        metadata,      //the metadata
                        NULL,          //no sysmd
                        data_buf,      //object body
                        data_len,      //object length
                        NULL,          //no query params
                        &sysmd);       //the returned sysmd
      if (DPL_SUCCESS != ret)
        {
          fprintf(stderr, "dpl_post_id failed: %s (%d)\n", dpl_status_str(ret), ret);
          ret = 1;
          goto free_all;
        }
      
      if (!(sysmd.mask & DPL_SYSMD_MASK_ID))
        {
          fprintf(stderr, "backend is not capable of retrieving resource id\n");
          exit(1);
        }
      
      fprintf(stderr, "id=%s\n", sysmd.id);
    }

  /**/

  fprintf(stderr, "getting object+MD\n");

  option.mask = DPL_OPTION_LAZY; //enable this for faster GETs

  ret = dpl_get_id(ctx,           //the context
                   NULL,          //no bucket
                   sysmd.id,      //the key
                   &option,       //options
                   DPL_FTYPE_REG, //object type
                   NULL,          //no condition
                   NULL,          //no range
                   &data_buf_returned,  //data object
                   &data_len_returned,  //data object length
                   &metadata_returned, //metadata
                   NULL);              //sysmd
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "dpl_get_id failed: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  fprintf(stderr, "checking object\n");

  if (data_len != data_len_returned)
    {
      fprintf(stderr, "data lengths mismatch\n");
      ret = 1;
      goto free_all;
    }

  if (0 != memcmp(data_buf, data_buf_returned, data_len))
    {
      fprintf(stderr, "data content mismatch\n");
      ret = 1;
      goto free_all;
    }

  fprintf(stderr, "checking metadata\n");

  metadatum = dpl_dict_get(metadata_returned, "foo");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      ret = 1;
      goto free_all;
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "bar"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      ret = 1;
      goto free_all;
    }

  metadatum = dpl_dict_get(metadata_returned, "foo2");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      ret = 1;
      goto free_all;
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "qux"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      ret = 1;
      goto free_all;
    }

  /**/

  fprintf(stderr, "setting MD only\n");

  ret = dpl_dict_add(metadata, "foo", "bar2", 0);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error updating metadatum: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  ret = dpl_copy_id(ctx,           //the context
                    NULL,          //no src bucket
                    sysmd.id,      //the key
                    NULL,          //no dst bucket
                    sysmd.id,      //the same key
                    NULL,          //no option
                    DPL_FTYPE_REG, //object type
                    DPL_COPY_DIRECTIVE_METADATA_REPLACE,  //tell server to replace metadata
                    metadata,      //the updated metadata
                    NULL,          //no sysmd
                    NULL);         //no condition
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error updating metadata: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  /**/

  fprintf(stderr, "getting MD only\n");

  ret = dpl_head_id(ctx,      //the context
                    NULL,     //no bucket,
                    sysmd.id, //the key
                    NULL,     //option
                    DPL_FTYPE_UNDEF, //no matter the file type
                    NULL,     //no condition,
                    &metadata2_returned,
                    NULL);    //no sysmd
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error getting metadata: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  fprintf(stderr, "checking metadata\n");

  metadatum = dpl_dict_get(metadata2_returned, "foo");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      ret = 1;
      goto free_all;
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "bar2"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      ret = 1;
      goto free_all;
    }

  metadatum = dpl_dict_get(metadata2_returned, "foo2");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      ret = 1;
      goto free_all;
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "qux"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      ret = 1;
      goto free_all;
    }

  /**/

  fprintf(stderr, "delete object+MD\n");

  ret = dpl_delete_id(ctx,       //the context
                      NULL,      //no bucket
                      sysmd.id,  //the key
                      NULL,      //no option
                      DPL_FTYPE_UNDEF, //no matter the file type
                      NULL);     //no condition
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error deleting object: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  ret = 0;

 free_all:

  if (NULL != metadata2_returned)
    dpl_dict_free(metadata2_returned);

  if (NULL != metadata_returned)
    dpl_dict_free(metadata_returned);

  if (NULL != data_buf_returned)
    free(data_buf_returned);

  if (NULL != metadata)
    dpl_dict_free(metadata);

  if (NULL != data_buf)
    free(data_buf);

  dpl_ctx_free(ctx); //free context

 free_dpl:
  dpl_free();        //free droplet library

 end:
  return ret;
}
Exemplo n.º 10
0
int
main(int argc,
     char **argv)
{
  int ret;
  dpl_ctx_t *ctx;
  char *folder = NULL;
  int folder_len;
  dpl_dict_t *metadata = NULL;
  char *data_buf = NULL;
  size_t data_len;
  char *data_buf_returned = NULL;
  u_int data_len_returned;
  dpl_dict_t *metadata_returned = NULL;
  dpl_dict_t *metadata2_returned = NULL;
  dpl_dict_var_t *metadatum = NULL;
  dpl_sysmd_t sysmd;
  char new_path[MAXPATHLEN];
  dpl_vec_t *files = NULL;
  dpl_vec_t *sub_directories = NULL;
  int i;

  if (2 != argc)
    {
      fprintf(stderr, "usage: restrest folder\n");
      ret = 1;
      goto end;
    }

  folder = argv[1];
  folder_len = strlen(folder);
  if (folder_len < 1)
    {
      fprintf(stderr, "bad folder\n");
      ret = 1;
      goto end;
    }
  if (folder[folder_len-1] != '/')
    {
      fprintf(stderr, "folder name must end with a slash\n");
      ret = 1;
      goto end;
    }

  ret = dpl_init();           //init droplet library
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "dpl_init failed\n");
      ret = 1;
      goto end;
    }

  //open default profile
  ctx = dpl_ctx_new(NULL,     //droplet directory, default: "~/.droplet"
                    NULL);    //droplet profile, default:   "default"
  if (NULL == ctx)
    {
      fprintf(stderr, "dpl_ctx_new failed\n");
      ret = 1;
      goto free_dpl;
    }

  //ctx->trace_level = ~0;
  //ctx->trace_buffers = 1;

  /**/

  fprintf(stderr, "creating folder\n");

  ret = dpl_put(ctx,           //the context
                NULL,          //no bucket
                folder,        //the folder
                NULL,          //no option
                DPL_FTYPE_DIR, //directory
                NULL,          //no condition
                NULL,          //no range
                NULL,          //no metadata
                NULL,          //no sysmd
                NULL,          //object body
                0);            //object length
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "dpl_put failed: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  /**/

  data_len = 10000;
  data_buf = malloc(data_len);
  if (NULL == data_buf)
    {
      fprintf(stderr, "alloc data failed\n");
      ret = 1;
      goto free_all;
    }

  memset(data_buf, 'z', data_len);

  metadata = dpl_dict_new(13);
  if (NULL == metadata)
    {
      fprintf(stderr, "dpl_dict_new failed\n");
      ret = 1;
      goto free_all;
    }
 
  ret = dpl_dict_add(metadata, "foo", "bar", 0);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "dpl_dict_add failed\n");
      ret = 1;
      goto free_all;
    }

  ret = dpl_dict_add(metadata, "foo2", "qux", 0);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "dpl_dict_add failed\n");
      ret = 1;
      goto free_all;
    }

  /**/
  
  fprintf(stderr, "atomic creation of an object+MD\n");

  ret = dpl_post(ctx,           //the context
                 NULL,          //no bucket
                 folder,        //the folder
                 NULL,          //no option
                 DPL_FTYPE_REG, //regular object
                 NULL,          //condition
                 NULL,          //range
                 metadata,      //the metadata
                 NULL,          //no sysmd
                 data_buf,      //object body
                 data_len,      //object length
                 NULL,          //no query params
                 &sysmd);       //the returned sysmd
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "dpl_post failed: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  if (!(sysmd.mask & DPL_SYSMD_MASK_PATH))
    {
      fprintf(stderr, "path is absent from sysmd\n");
      ret = 1;
      goto free_all;
    }

  fprintf(stderr, "resource path %s\n", sysmd.path);

  snprintf(new_path, sizeof (new_path), "%su.1", folder);

  ret = dpl_copy(ctx,
                 NULL,          //no src bucket
                 sysmd.path,    //the src resource
                 NULL,          //no dst bucket
                 new_path,      //dst resource
                 NULL,          //no option
                 DPL_FTYPE_REG, //regular file
                 DPL_COPY_DIRECTIVE_MOVE, //rename
                 NULL,          //no metadata
                 NULL,          //no sysmd
                 NULL);         //no server side condition
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "dpl_move %s to %s failed: %s (%d)\n", sysmd.path, new_path, dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  /**/

  fprintf(stderr, "getting object+MD\n");

  ret = dpl_get(ctx,           //the context
                NULL,          //no bucket
                new_path,      //the key
                NULL,          //no opion
                DPL_FTYPE_REG, //object type
                NULL,          //no condition
                NULL,          //no range
                &data_buf_returned,  //data object
                &data_len_returned,  //data object length
                &metadata_returned, //metadata
                NULL);              //sysmd
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "dpl_get_id failed: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  fprintf(stderr, "checking object\n");

  if (data_len != data_len_returned)
    {
      fprintf(stderr, "data lengths mismatch\n");
      ret = 1;
      goto free_all;
    }

  if (0 != memcmp(data_buf, data_buf_returned, data_len))
    {
      fprintf(stderr, "data content mismatch\n");
      ret = 1;
      goto free_all;
    }

  fprintf(stderr, "checking metadata\n");

  metadatum = dpl_dict_get(metadata_returned, "foo");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      ret = 1;
      goto free_all;
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(metadatum->val->string, "bar"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      ret = 1;
      goto free_all;
    }

  metadatum = dpl_dict_get(metadata_returned, "foo2");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      ret = 1;
      goto free_all;
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(metadatum->val->string, "qux"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      ret = 1;
      goto free_all;
    }

  /**/

  fprintf(stderr, "setting MD only\n");

  ret = dpl_dict_add(metadata, "foo", "bar2", 0);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error updating metadatum: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  ret = dpl_copy(ctx,           //the context
                 NULL,          //no src bucket
                 new_path,      //the key
                 NULL,          //no dst bucket
                 new_path,      //the same key
                 NULL,          //no option
                 DPL_FTYPE_REG, //object type
                 DPL_COPY_DIRECTIVE_METADATA_REPLACE,  //tell server to replace metadata
                 metadata,      //the updated metadata
                 NULL,          //no sysmd
                 NULL);         //no condition
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error updating metadata: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  /**/

  fprintf(stderr, "getting MD only\n");

  ret = dpl_head(ctx,      //the context
                 NULL,     //no bucket,
                 new_path, //the key
                 NULL,     //no option
                 DPL_FTYPE_UNDEF, //no matter the file type
                 NULL,     //no condition,
                 &metadata2_returned,
                 NULL);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error getting metadata: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  fprintf(stderr, "checking metadata\n");

  metadatum = dpl_dict_get(metadata2_returned, "foo");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      ret = 1;
      goto free_all;
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(metadatum->val->string, "bar2"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      ret = 1;
      goto free_all;
    }

  metadatum = dpl_dict_get(metadata2_returned, "foo2");
  if (NULL == metadatum)
    {
      fprintf(stderr, "missing metadatum\n");
      ret = 1;
      goto free_all;
    }

  assert(metadatum->val->type == DPL_VALUE_STRING);
  if (strcmp(metadatum->val->string, "qux"))
    {
      fprintf(stderr, "bad value in metadatum\n");
      ret = 1;
      goto free_all;
    }

  /**/

  fprintf(stderr, "listing of folder\n");

  ret = dpl_list_bucket(ctx, 
                        NULL,
                        folder,
                        "/",
                        -1,
                        &files,
                        &sub_directories);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error listing folder: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  for (i = 0;i < files->n_items;i++)
    {
      dpl_object_t *obj = (dpl_object_t *) dpl_vec_get(files, i);
      dpl_sysmd_t obj_sysmd;
      dpl_dict_t *obj_md = NULL;
      
      ret = dpl_head(ctx, 
                     NULL, //no bucket
                     obj->path, 
                     NULL, //option
                     DPL_FTYPE_UNDEF, //no matter the file type
                     NULL, //condition
                     &obj_md, //user metadata
                     &obj_sysmd); //system metadata
      if (DPL_SUCCESS != ret)
        {
          fprintf(stderr, "getattr error on %s: %s (%d)\n", obj->path, dpl_status_str(ret), ret);
          ret = 1;
          goto free_all;
        }

      fprintf(stderr, "file %s: size=%ld mtime=%lu\n", obj->path, obj_sysmd.size, obj_sysmd.mtime);
      //dpl_dict_print(obj_md, stderr, 5);
      dpl_dict_free(obj_md);
    }

  for (i = 0;i < sub_directories->n_items;i++)
    {
      dpl_common_prefix_t *dir = (dpl_common_prefix_t *) dpl_vec_get(sub_directories, i);

      fprintf(stderr, "dir %s\n", dir->prefix);
    }

  /**/

  fprintf(stderr, "delete object+MD\n");

  ret = dpl_delete(ctx,       //the context
                   NULL,      //no bucket
                   new_path,  //the key
                   NULL,      //no option
                   DPL_FTYPE_UNDEF, //no matter the file type
                   NULL);     //no condition
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error deleting object: %s (%d)\n", dpl_status_str(ret), ret);
      ret = 1;
      goto free_all;
    }

  ret = 0;

 free_all:

  if (NULL != sub_directories)
    dpl_vec_common_prefixes_free(sub_directories);

  if (NULL != files)
    dpl_vec_objects_free(files);

  if (NULL != metadata2_returned)
    dpl_dict_free(metadata2_returned);

  if (NULL != metadata_returned)
    dpl_dict_free(metadata_returned);

  if (NULL != data_buf_returned)
    free(data_buf_returned);

  if (NULL != metadata)
    dpl_dict_free(metadata);

  if (NULL != data_buf)
    free(data_buf);

  dpl_ctx_free(ctx); //free context

 free_dpl:
  dpl_free();        //free droplet library

 end:
  return ret;
}