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