1 /* check-sources:disable-copyright-check */
2 /*
3  * simple example which operates into a folder (creation of a folder, atomic
4  * file creation + get/set data/metadata + listing of a folder + getattr +
5  * deletion)
6  */
7 
8 #include <droplet.h>
9 #include <assert.h>
10 #include <sys/param.h>
11 
main(int argc,char ** argv)12 int main(int argc, char** argv)
13 {
14   int ret;
15   dpl_ctx_t* ctx;
16   char* folder = NULL;
17   int folder_len;
18   dpl_dict_t* metadata = NULL;
19   char* data_buf = NULL;
20   size_t data_len;
21   char* data_buf_returned = NULL;
22   u_int data_len_returned;
23   dpl_dict_t* metadata_returned = NULL;
24   dpl_dict_t* metadata2_returned = NULL;
25   dpl_dict_var_t* metadatum = NULL;
26   dpl_sysmd_t sysmd;
27   char new_path[MAXPATHLEN];
28   dpl_vec_t* files = NULL;
29   dpl_vec_t* sub_directories = NULL;
30   int i;
31 
32   if (2 != argc) {
33     fprintf(stderr, "usage: restrest folder\n");
34     ret = 1;
35     goto end;
36   }
37 
38   folder = argv[1];
39   folder_len = strlen(folder);
40   if (folder_len < 1) {
41     fprintf(stderr, "bad folder\n");
42     ret = 1;
43     goto end;
44   }
45   if (folder[folder_len - 1] != '/') {
46     fprintf(stderr, "folder name must end with a slash\n");
47     ret = 1;
48     goto end;
49   }
50 
51   ret = dpl_init();  // init droplet library
52   if (DPL_SUCCESS != ret) {
53     fprintf(stderr, "dpl_init failed\n");
54     ret = 1;
55     goto end;
56   }
57 
58   // open default profile
59   ctx = dpl_ctx_new(NULL,   // droplet directory, default: "~/.droplet"
60                     NULL);  // droplet profile, default:   "default"
61   if (NULL == ctx) {
62     fprintf(stderr, "dpl_ctx_new failed\n");
63     ret = 1;
64     goto free_dpl;
65   }
66 
67   // ctx->trace_level = ~0;
68   // ctx->trace_buffers = 1;
69 
70   /**/
71 
72   fprintf(stderr, "creating folder\n");
73 
74   ret = dpl_put(ctx,            // the context
75                 NULL,           // no bucket
76                 folder,         // the folder
77                 NULL,           // no option
78                 DPL_FTYPE_DIR,  // directory
79                 NULL,           // no condition
80                 NULL,           // no range
81                 NULL,           // no metadata
82                 NULL,           // no sysmd
83                 NULL,           // object body
84                 0);             // object length
85   if (DPL_SUCCESS != ret) {
86     fprintf(stderr, "dpl_put failed: %s (%d)\n", dpl_status_str(ret), ret);
87     ret = 1;
88     goto free_all;
89   }
90 
91   /**/
92 
93   data_len = 10000;
94   data_buf = malloc(data_len);
95   if (NULL == data_buf) {
96     fprintf(stderr, "alloc data failed\n");
97     ret = 1;
98     goto free_all;
99   }
100 
101   memset(data_buf, 'z', data_len);
102 
103   metadata = dpl_dict_new(13);
104   if (NULL == metadata) {
105     fprintf(stderr, "dpl_dict_new failed\n");
106     ret = 1;
107     goto free_all;
108   }
109 
110   ret = dpl_dict_add(metadata, "foo", "bar", 0);
111   if (DPL_SUCCESS != ret) {
112     fprintf(stderr, "dpl_dict_add failed\n");
113     ret = 1;
114     goto free_all;
115   }
116 
117   ret = dpl_dict_add(metadata, "foo2", "qux", 0);
118   if (DPL_SUCCESS != ret) {
119     fprintf(stderr, "dpl_dict_add failed\n");
120     ret = 1;
121     goto free_all;
122   }
123 
124   /**/
125 
126   fprintf(stderr, "atomic creation of an object+MD\n");
127 
128   ret = dpl_post(ctx,            // the context
129                  NULL,           // no bucket
130                  folder,         // the folder
131                  NULL,           // no option
132                  DPL_FTYPE_REG,  // regular object
133                  NULL,           // condition
134                  NULL,           // range
135                  metadata,       // the metadata
136                  NULL,           // no sysmd
137                  data_buf,       // object body
138                  data_len,       // object length
139                  NULL,           // no query params
140                  &sysmd);        // the returned sysmd
141   if (DPL_SUCCESS != ret) {
142     fprintf(stderr, "dpl_post failed: %s (%d)\n", dpl_status_str(ret), ret);
143     ret = 1;
144     goto free_all;
145   }
146 
147   if (!(sysmd.mask & DPL_SYSMD_MASK_PATH)) {
148     fprintf(stderr, "path is absent from sysmd\n");
149     ret = 1;
150     goto free_all;
151   }
152 
153   fprintf(stderr, "resource path %s\n", sysmd.path);
154 
155   snprintf(new_path, sizeof(new_path), "%su.1", folder);
156 
157   ret = dpl_copy(ctx,
158                  NULL,                     // no src bucket
159                  sysmd.path,               // the src resource
160                  NULL,                     // no dst bucket
161                  new_path,                 // dst resource
162                  NULL,                     // no option
163                  DPL_FTYPE_REG,            // regular file
164                  DPL_COPY_DIRECTIVE_MOVE,  // rename
165                  NULL,                     // no metadata
166                  NULL,                     // no sysmd
167                  NULL);                    // no server side condition
168   if (DPL_SUCCESS != ret) {
169     fprintf(stderr, "dpl_move %s to %s failed: %s (%d)\n", sysmd.path, new_path,
170             dpl_status_str(ret), ret);
171     ret = 1;
172     goto free_all;
173   }
174 
175   /**/
176 
177   fprintf(stderr, "getting object+MD\n");
178 
179   ret = dpl_get(ctx,                 // the context
180                 NULL,                // no bucket
181                 new_path,            // the key
182                 NULL,                // no opion
183                 DPL_FTYPE_REG,       // object type
184                 NULL,                // no condition
185                 NULL,                // no range
186                 &data_buf_returned,  // data object
187                 &data_len_returned,  // data object length
188                 &metadata_returned,  // metadata
189                 NULL);               // sysmd
190   if (DPL_SUCCESS != ret) {
191     fprintf(stderr, "dpl_get_id failed: %s (%d)\n", dpl_status_str(ret), ret);
192     ret = 1;
193     goto free_all;
194   }
195 
196   fprintf(stderr, "checking object\n");
197 
198   if (data_len != data_len_returned) {
199     fprintf(stderr, "data lengths mismatch\n");
200     ret = 1;
201     goto free_all;
202   }
203 
204   if (0 != memcmp(data_buf, data_buf_returned, data_len)) {
205     fprintf(stderr, "data content mismatch\n");
206     ret = 1;
207     goto free_all;
208   }
209 
210   fprintf(stderr, "checking metadata\n");
211 
212   metadatum = dpl_dict_get(metadata_returned, "foo");
213   if (NULL == metadatum) {
214     fprintf(stderr, "missing metadatum\n");
215     ret = 1;
216     goto free_all;
217   }
218 
219   assert(metadatum->val->type == DPL_VALUE_STRING);
220   if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "bar")) {
221     fprintf(stderr, "bad value in metadatum\n");
222     ret = 1;
223     goto free_all;
224   }
225 
226   metadatum = dpl_dict_get(metadata_returned, "foo2");
227   if (NULL == metadatum) {
228     fprintf(stderr, "missing metadatum\n");
229     ret = 1;
230     goto free_all;
231   }
232 
233   assert(metadatum->val->type == DPL_VALUE_STRING);
234   if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "qux")) {
235     fprintf(stderr, "bad value in metadatum\n");
236     ret = 1;
237     goto free_all;
238   }
239 
240   /**/
241 
242   fprintf(stderr, "setting MD only\n");
243 
244   ret = dpl_dict_add(metadata, "foo", "bar2", 0);
245   if (DPL_SUCCESS != ret) {
246     fprintf(stderr, "error updating metadatum: %s (%d)\n", dpl_status_str(ret),
247             ret);
248     ret = 1;
249     goto free_all;
250   }
251 
252   ret = dpl_copy(
253       ctx,                                  // the context
254       NULL,                                 // no src bucket
255       new_path,                             // the key
256       NULL,                                 // no dst bucket
257       new_path,                             // the same key
258       NULL,                                 // no option
259       DPL_FTYPE_REG,                        // object type
260       DPL_COPY_DIRECTIVE_METADATA_REPLACE,  // tell server to replace metadata
261       metadata,                             // the updated metadata
262       NULL,                                 // no sysmd
263       NULL);                                // no condition
264   if (DPL_SUCCESS != ret) {
265     fprintf(stderr, "error updating metadata: %s (%d)\n", dpl_status_str(ret),
266             ret);
267     ret = 1;
268     goto free_all;
269   }
270 
271   /**/
272 
273   fprintf(stderr, "getting MD only\n");
274 
275   ret = dpl_head(ctx,              // the context
276                  NULL,             // no bucket,
277                  new_path,         // the key
278                  NULL,             // no option
279                  DPL_FTYPE_UNDEF,  // no matter the file type
280                  NULL,             // no condition,
281                  &metadata2_returned, NULL);
282   if (DPL_SUCCESS != ret) {
283     fprintf(stderr, "error getting metadata: %s (%d)\n", dpl_status_str(ret),
284             ret);
285     ret = 1;
286     goto free_all;
287   }
288 
289   fprintf(stderr, "checking metadata\n");
290 
291   metadatum = dpl_dict_get(metadata2_returned, "foo");
292   if (NULL == metadatum) {
293     fprintf(stderr, "missing metadatum\n");
294     ret = 1;
295     goto free_all;
296   }
297 
298   assert(metadatum->val->type == DPL_VALUE_STRING);
299   if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "bar2")) {
300     fprintf(stderr, "bad value in metadatum\n");
301     ret = 1;
302     goto free_all;
303   }
304 
305   metadatum = dpl_dict_get(metadata2_returned, "foo2");
306   if (NULL == metadatum) {
307     fprintf(stderr, "missing metadatum\n");
308     ret = 1;
309     goto free_all;
310   }
311 
312   assert(metadatum->val->type == DPL_VALUE_STRING);
313   if (strcmp(dpl_sbuf_get_str(metadatum->val->string), "qux")) {
314     fprintf(stderr, "bad value in metadatum\n");
315     ret = 1;
316     goto free_all;
317   }
318 
319   /**/
320 
321   fprintf(stderr, "listing of folder\n");
322 
323   ret = dpl_list_bucket(ctx, NULL, folder, "/", -1, &files, &sub_directories);
324   if (DPL_SUCCESS != ret) {
325     fprintf(stderr, "error listing folder: %s (%d)\n", dpl_status_str(ret),
326             ret);
327     ret = 1;
328     goto free_all;
329   }
330 
331   for (i = 0; i < files->n_items; i++) {
332     dpl_object_t* obj = (dpl_object_t*)dpl_vec_get(files, i);
333     dpl_sysmd_t obj_sysmd;
334     dpl_dict_t* obj_md = NULL;
335 
336     ret = dpl_head(ctx,
337                    NULL,  // no bucket
338                    obj->path,
339                    NULL,             // option
340                    DPL_FTYPE_UNDEF,  // no matter the file type
341                    NULL,             // condition
342                    &obj_md,          // user metadata
343                    &obj_sysmd);      // system metadata
344     if (DPL_SUCCESS != ret) {
345       fprintf(stderr, "getattr error on %s: %s (%d)\n", obj->path,
346               dpl_status_str(ret), ret);
347       ret = 1;
348       goto free_all;
349     }
350 
351     fprintf(stderr, "file %s: size=%ld mtime=%lu\n", obj->path, obj_sysmd.size,
352             obj_sysmd.mtime);
353     // dpl_dict_print(obj_md, stderr, 5);
354     dpl_dict_free(obj_md);
355   }
356 
357   for (i = 0; i < sub_directories->n_items; i++) {
358     dpl_common_prefix_t* dir
359         = (dpl_common_prefix_t*)dpl_vec_get(sub_directories, i);
360 
361     fprintf(stderr, "dir %s\n", dir->prefix);
362   }
363 
364   /**/
365 
366   fprintf(stderr, "delete object+MD\n");
367 
368   ret = dpl_delete(ctx,              // the context
369                    NULL,             // no bucket
370                    new_path,         // the key
371                    NULL,             // no option
372                    DPL_FTYPE_UNDEF,  // no matter the file type
373                    NULL);            // no condition
374   if (DPL_SUCCESS != ret) {
375     fprintf(stderr, "error deleting object: %s (%d)\n", dpl_status_str(ret),
376             ret);
377     ret = 1;
378     goto free_all;
379   }
380 
381   ret = 0;
382 
383 free_all:
384 
385   if (NULL != sub_directories) dpl_vec_common_prefixes_free(sub_directories);
386 
387   if (NULL != files) dpl_vec_objects_free(files);
388 
389   if (NULL != metadata2_returned) dpl_dict_free(metadata2_returned);
390 
391   if (NULL != metadata_returned) dpl_dict_free(metadata_returned);
392 
393   if (NULL != data_buf_returned) free(data_buf_returned);
394 
395   if (NULL != metadata) dpl_dict_free(metadata);
396 
397   if (NULL != data_buf) free(data_buf);
398 
399   dpl_ctx_free(ctx);  // free context
400 
401 free_dpl:
402   dpl_free();  // free droplet library
403 
404 end:
405   return ret;
406 }
407