ruby-libstorj 0.0.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1173 @@
1
+ #include "cli_callback.h"
2
+
3
+ //#define debug_enable
4
+
5
+ #define MAX_UPLOAD_FILES 256
6
+
7
+ static inline void noop() {};
8
+
9
+ static void get_input(char *line)
10
+ {
11
+ if (fgets(line, BUFSIZ, stdin) == NULL) {
12
+ line[0] = '\0';
13
+ } else {
14
+ int len = strlen(line);
15
+ if (len > 0) {
16
+ char *last = strrchr(line, '\n');
17
+ if (last) {
18
+ last[0] = '\0';
19
+ }
20
+ last = strrchr(line, '\r');
21
+ if (last) {
22
+ last[0] = '\0';
23
+ }
24
+ }
25
+ }
26
+ }
27
+
28
+ /* inserts into subject[] at position pos */
29
+ void append(char subject[], const char insert[], int pos)
30
+ {
31
+ char buf[256] = { };
32
+
33
+ /* copy at most first pos characters */
34
+ strncpy(buf, subject, pos);
35
+ int len = strlen(buf);
36
+
37
+ /* copy all of insert[] at the end */
38
+ strcpy(buf + len, insert);
39
+
40
+ /* increase the length by length of insert[] */
41
+ len += strlen(insert);
42
+
43
+ /* copy the rest */
44
+ strcpy(buf + len, subject + pos);
45
+
46
+ /* copy it back to subject */
47
+ strcpy(subject, buf);
48
+ }
49
+
50
+ char* replace_char(char* str, char find, char replace)
51
+ {
52
+ char *current_pos = strchr(str, find);
53
+ while (current_pos) {
54
+ *current_pos = replace;
55
+ append(current_pos, "_", 0);
56
+ current_pos = strchr(current_pos, find);
57
+ }
58
+ return (str);
59
+ }
60
+
61
+ static void printdir(char *dir, int depth, FILE *src_fd, void *handle)
62
+ {
63
+ DIR *dp;
64
+ struct dirent *entry;
65
+ struct stat statbuf;
66
+ int spaces = depth*4;
67
+ char tmp_dir[800] = {};
68
+ char *full_path = NULL;
69
+ char *s;
70
+ char * start;
71
+ cli_api_t *cli_api = handle;
72
+
73
+ if ((dp = opendir(dir)) == NULL) {
74
+ fprintf(stderr,"cannot open directory: %s\n", dir);
75
+ return;
76
+ }
77
+
78
+ int ret = chdir(dir);
79
+ while ((entry = readdir(dp)) != NULL) {
80
+ lstat(entry->d_name, &statbuf);
81
+ if (S_ISDIR(statbuf.st_mode)) {
82
+ /* Found a directory, but ignore . and .. */
83
+ if (strcmp(".", entry->d_name) == 0 ||
84
+ strcmp("..", entry->d_name) == 0) continue;
85
+
86
+ /* Recurse at a new indent level */
87
+ printdir(entry->d_name, depth + 1, src_fd, handle);
88
+ } else {
89
+ full_path = realpath(entry->d_name, NULL);
90
+ /* write to src file */
91
+ fprintf(src_fd, "%s%s\n", "", full_path);
92
+ }
93
+ }
94
+ ret = chdir("..");
95
+ closedir(dp);
96
+ free(full_path);
97
+ }
98
+
99
+ static int file_exists(void *handle)
100
+ {
101
+ struct stat sb;
102
+ gid_t st_grpid;
103
+ cli_api_t *cli_api = handle;
104
+
105
+ FILE *src_fd, *dst_fd;
106
+
107
+ if (stat(cli_api->file_path, &sb) == -1) {
108
+ perror("stat");
109
+ return CLI_NO_SUCH_FILE_OR_DIR;
110
+ }
111
+
112
+ switch (sb.st_mode & S_IFMT) {
113
+ case S_IFBLK:
114
+ printf("block device\n");
115
+ break;
116
+ case S_IFCHR:
117
+ printf("character device\n");
118
+ break;
119
+ case S_IFDIR:
120
+ if ((src_fd = fopen(cli_api->src_list, "w")) == NULL) {
121
+ return CLI_UPLOAD_FILE_LOG_ERR;
122
+ }
123
+ printdir(cli_api->file_path, 0, src_fd, handle);
124
+ fclose(src_fd);
125
+ return CLI_VALID_DIR;
126
+ break;
127
+ case S_IFIFO:
128
+ printf("FIFO/pipe\n");
129
+ break;
130
+ case S_IFLNK:
131
+ printf("symlink\n");
132
+ break;
133
+ case S_IFREG:
134
+ return CLI_VALID_REGULAR_FILE;
135
+ break;
136
+ case S_IFSOCK:
137
+ printf("socket\n");
138
+ break;
139
+ default:
140
+ printf("unknown?\n");
141
+ break;
142
+ }
143
+
144
+ return CLI_UNKNOWN_FILE_ATTR;
145
+ }
146
+
147
+ static const char *get_filename_separator(const char *file_path)
148
+ {
149
+ const char *file_name = NULL;
150
+ #ifdef _WIN32
151
+ file_name = strrchr(file_path, '\\');
152
+ if (!file_name) {
153
+ file_name = strrchr(file_path, '/');
154
+ }
155
+ if (!file_name && file_path) {
156
+ file_name = file_path;
157
+ }
158
+ if (!file_name) {
159
+ return NULL;
160
+ }
161
+ if (file_name[0] == '\\' || file_name[0] == '/') {
162
+ file_name++;
163
+ }
164
+ #else
165
+ file_name = strrchr(file_path, '/');
166
+ if (!file_name && file_path) {
167
+ file_name = file_path;
168
+ }
169
+ if (!file_name) {
170
+ return NULL;
171
+ }
172
+ if (file_name[0] == '/') {
173
+ file_name++;
174
+ }
175
+ #endif
176
+ return file_name;
177
+ }
178
+
179
+ static void close_signal(uv_handle_t *handle)
180
+ {
181
+ ((void)0);
182
+ }
183
+
184
+ static void file_progress(double progress,
185
+ uint64_t downloaded_bytes,
186
+ uint64_t total_bytes,
187
+ void *handle)
188
+ {
189
+ int bar_width = 70;
190
+
191
+ if (progress == 0 && downloaded_bytes == 0) {
192
+ printf("Preparing File...");
193
+ fflush(stdout);
194
+ return;
195
+ }
196
+
197
+ printf("\r[");
198
+ int pos = bar_width * progress;
199
+ for (int i = 0; i < bar_width; ++i) {
200
+ if (i < pos) {
201
+ printf("=");
202
+ }
203
+ else if (i == pos) {
204
+ printf(">");
205
+ } else {
206
+ printf(" ");
207
+ }
208
+ }
209
+ printf("] %.*f%%", 2, progress * 100);
210
+
211
+ fflush(stdout);
212
+ }
213
+
214
+ static void upload_file_complete(int status, storj_file_meta_t *file, void *handle)
215
+ {
216
+ cli_api_t *cli_api = handle;
217
+ cli_api->rcvd_cmd_resp = "upload-file-resp";
218
+
219
+ printf("\n");
220
+ if (status != 0) {
221
+ printf("Upload failure: %s\n", storj_strerror(status));
222
+ exit(status);
223
+ }
224
+
225
+ printf("Upload Success! File ID: %s\n", file->id);
226
+
227
+ storj_free_uploaded_file_info(file);
228
+
229
+ queue_next_cmd_req(cli_api);
230
+ }
231
+
232
+ static void upload_signal_handler(uv_signal_t *req, int signum)
233
+ {
234
+ storj_upload_state_t *state = req->data;
235
+ storj_bridge_store_file_cancel(state);
236
+ if (uv_signal_stop(req)) {
237
+ printf("Unable to stop signal\n");
238
+ }
239
+ uv_close((uv_handle_t *)req, close_signal);
240
+ }
241
+
242
+ static int upload_file(storj_env_t *env, char *bucket_id, const char *file_path, void *handle)
243
+ {
244
+ cli_api_t *cli_api = handle;
245
+
246
+ FILE *fd = fopen(file_path, "r");
247
+
248
+ if (!fd) {
249
+ printf("Invalid file path: %s\n", file_path);
250
+ exit(0);
251
+ }
252
+
253
+ const char *file_name = get_filename_separator(file_path);
254
+
255
+ if (cli_api->dst_file == NULL) {
256
+ if (!file_name) {
257
+ file_name = file_path;
258
+ }
259
+ } else {
260
+ file_name = cli_api->dst_file;
261
+ }
262
+
263
+ // Upload opts env variables:
264
+ char *prepare_frame_limit = getenv("STORJ_PREPARE_FRAME_LIMIT");
265
+ char *push_frame_limit = getenv("STORJ_PUSH_FRAME_LIMIT");
266
+ char *push_shard_limit = getenv("STORJ_PUSH_SHARD_LIMIT");
267
+ char *rs = getenv("STORJ_REED_SOLOMON");
268
+
269
+ storj_upload_opts_t upload_opts = {
270
+ .prepare_frame_limit = (prepare_frame_limit) ? atoi(prepare_frame_limit) : 1,
271
+ .push_frame_limit = (push_frame_limit) ? atoi(push_frame_limit) : 64,
272
+ .push_shard_limit = (push_shard_limit) ? atoi(push_shard_limit) : 64,
273
+ .rs = (!rs) ? true : (strcmp(rs, "false") == 0) ? false : true,
274
+ .bucket_id = bucket_id,
275
+ .file_name = file_name,
276
+ .fd = fd
277
+ };
278
+
279
+ uv_signal_t *sig = malloc(sizeof(uv_signal_t));
280
+ if (!sig) {
281
+ return 1;
282
+ }
283
+ uv_signal_init(env->loop, sig);
284
+ uv_signal_start(sig, upload_signal_handler, SIGINT);
285
+
286
+
287
+
288
+ storj_progress_cb progress_cb = (storj_progress_cb)noop;
289
+ if (env->log_options->level == 0) {
290
+ progress_cb = file_progress;
291
+ }
292
+
293
+ storj_upload_state_t *state = storj_bridge_store_file(env,
294
+ &upload_opts,
295
+ handle,
296
+ progress_cb,
297
+ upload_file_complete);
298
+
299
+ if (!state) {
300
+ return 1;
301
+ }
302
+
303
+ sig->data = state;
304
+
305
+ return state->error_status;
306
+ }
307
+
308
+ static void upload_files_complete(int status, storj_file_meta_t *file, void *handle)
309
+ {
310
+ cli_api_t *cli_api = handle;
311
+ cli_api->rcvd_cmd_resp = "upload-files-resp";
312
+
313
+ printf("\n");
314
+ if (status != 0) {
315
+ printf("[%s][%d]Upload failure: %s\n",
316
+ __FUNCTION__, __LINE__, storj_strerror(status));
317
+ } else {
318
+ printf("Upload Success! File ID: %s\n", file->id);
319
+ storj_free_uploaded_file_info(file);
320
+ }
321
+
322
+ queue_next_cmd_req(cli_api);
323
+ }
324
+
325
+ static int upload_files(storj_env_t *env, char *bucket_id, const char *file_path, void *handle)
326
+ {
327
+ cli_api_t *cli_api = handle;
328
+
329
+ FILE *fd = fopen(file_path, "r");
330
+
331
+ if (!fd) {
332
+ printf("[%s][%d]Invalid file : %s\n", __FUNCTION__, __LINE__, file_path);
333
+ exit(0);
334
+ }
335
+
336
+ printf("Uploading[%d]of[%d] src file = %s as ",
337
+ cli_api->xfer_count, cli_api->total_files, file_path);
338
+
339
+ /* replace the dir with __ */
340
+ char *s = strstr(cli_api->src_file, cli_api->file_path);
341
+ char *start = s + strlen(cli_api->file_path);
342
+ char tmp_dir[256];
343
+ start = replace_char(start, '/', '_');
344
+ memset(tmp_dir, 0x00, sizeof(tmp_dir));
345
+ strcat(tmp_dir, cli_api->file_path);
346
+ strcat(tmp_dir, start);
347
+ cli_api->dst_file = tmp_dir;
348
+
349
+ const char *file_name = get_filename_separator(cli_api->dst_file);
350
+
351
+ if (!file_name) {
352
+ file_name = file_path;
353
+ }
354
+ printf(" %s\n", file_name);
355
+
356
+ // Upload opts env variables:
357
+ char *prepare_frame_limit = getenv("STORJ_PREPARE_FRAME_LIMIT");
358
+ char *push_frame_limit = getenv("STORJ_PUSH_FRAME_LIMIT");
359
+ char *push_shard_limit = getenv("STORJ_PUSH_SHARD_LIMIT");
360
+ char *rs = getenv("STORJ_REED_SOLOMON");
361
+
362
+ storj_upload_opts_t upload_opts = {
363
+ .prepare_frame_limit = (prepare_frame_limit) ? atoi(prepare_frame_limit) : 1,
364
+ .push_frame_limit = (push_frame_limit) ? atoi(push_frame_limit) : 64,
365
+ .push_shard_limit = (push_shard_limit) ? atoi(push_shard_limit) : 64,
366
+ .rs = (!rs) ? true : (strcmp(rs, "false") == 0) ? false : true,
367
+ .bucket_id = bucket_id,
368
+ .file_name = file_name,
369
+ .fd = fd
370
+ };
371
+
372
+ uv_signal_t *sig = malloc(sizeof(uv_signal_t));
373
+ if (!sig) {
374
+ return 1;
375
+ }
376
+ uv_signal_init(env->loop, sig);
377
+ uv_signal_start(sig, upload_signal_handler, SIGINT);
378
+
379
+ storj_progress_cb progress_cb = (storj_progress_cb)noop;
380
+ if (env->log_options->level == 0) {
381
+ progress_cb = file_progress;
382
+ }
383
+
384
+ storj_upload_state_t *state = storj_bridge_store_file(env,
385
+ &upload_opts,
386
+ handle,
387
+ progress_cb,
388
+ upload_files_complete);
389
+
390
+ if (!state) {
391
+ return 1;
392
+ }
393
+
394
+ sig->data = state;
395
+
396
+ return state->error_status;
397
+ }
398
+
399
+ static void verify_upload_files(void *handle)
400
+ {
401
+ cli_api_t *cli_api = handle;
402
+ int total_src_files = 0x00;
403
+ int total_dst_files = 0x00;
404
+ int ret = 0x00;
405
+
406
+ /* upload list file previously not created? */
407
+ if (cli_api->dst_file == NULL)
408
+ {
409
+ char pwd_path[256]= {};
410
+ memset(pwd_path, 0x00, sizeof(pwd_path));
411
+ char *upload_list_file = pwd_path;
412
+
413
+ /* create upload files list based on the file path */
414
+ if ((upload_list_file = getenv("TMPDIR")) != NULL) {
415
+ if (upload_list_file[(strlen(upload_list_file) - 1)] == '/') {
416
+ strcat(upload_list_file, "STORJ_output_list.txt");
417
+ } else {
418
+ strcat(upload_list_file, "/STORJ_output_list.txt");
419
+ }
420
+
421
+ /* check the directory and create the path to upload list file */
422
+ memset(cli_api->src_list, 0x00, sizeof(cli_api->src_list));
423
+ memcpy(cli_api->src_list, upload_list_file, sizeof(pwd_path));
424
+ cli_api->dst_file = cli_api->src_list;
425
+ }
426
+
427
+ /* create a upload list file src_list.txt */
428
+ int file_attr = file_exists(handle);
429
+ }
430
+
431
+ /* create a upload list file src_list.txt */
432
+ cli_api->src_fd = fopen(cli_api->src_list, "r");
433
+
434
+ if (!cli_api->src_fd) {
435
+ printf("[%s][%d]Invalid file path: %s\n",
436
+ __FUNCTION__, __LINE__, cli_api->src_list);
437
+ exit(0);
438
+ } else {
439
+ /* count total src_list files */
440
+ char line[MAX_UPLOAD_FILES][256];
441
+ char *temp;
442
+ int i = 0x00;
443
+
444
+ memset(line, 0x00, sizeof(line));
445
+
446
+ /* read a line from a file */
447
+ while (fgets(line[i], sizeof(line), cli_api->src_fd) != NULL) {
448
+ if (i <= MAX_UPLOAD_FILES) {
449
+ i++;
450
+ } else {
451
+ i = (i - 1);
452
+ printf("[%s][%d] Upload files limit set to %d \n",
453
+ __FUNCTION__, __LINE__, (MAX_UPLOAD_FILES));
454
+ break;
455
+ }
456
+ }
457
+
458
+ total_src_files = i;
459
+ }
460
+
461
+ cli_api->total_files = total_src_files;
462
+ cli_api->xfer_count = 0x01;
463
+
464
+ cli_api->rcvd_cmd_resp = "verify-upload-files-resp";
465
+ queue_next_cmd_req(cli_api);
466
+ }
467
+
468
+ static void download_file_complete(int status, FILE *fd, void *handle)
469
+ {
470
+ cli_api_t *cli_api = handle;
471
+ cli_api->rcvd_cmd_resp = "download-file-resp";
472
+
473
+ printf("\n");
474
+ fclose(fd);
475
+ if (status) {
476
+ // TODO send to stderr
477
+ switch(status) {
478
+ case STORJ_FILE_DECRYPTION_ERROR:
479
+ printf("Unable to properly decrypt file, please check " \
480
+ "that the correct encryption key was " \
481
+ "imported correctly.\n\n");
482
+ break;
483
+ default:
484
+ printf("[%s][%d]Download failure: %s\n",
485
+ __FUNCTION__, __LINE__, storj_strerror(status));
486
+ }
487
+ } else {
488
+ printf("Download Success!\n");
489
+ }
490
+
491
+ queue_next_cmd_req(cli_api);
492
+ }
493
+
494
+ static void download_signal_handler(uv_signal_t *req, int signum)
495
+ {
496
+ storj_download_state_t *state = req->data;
497
+ storj_bridge_resolve_file_cancel(state);
498
+ if (uv_signal_stop(req)) {
499
+ printf("Unable to stop signal\n");
500
+ }
501
+ uv_close((uv_handle_t *)req, close_signal);
502
+ }
503
+
504
+ static int download_file(storj_env_t *env, char *bucket_id,
505
+ char *file_id, char *path, void *handle)
506
+ {
507
+ FILE *fd = NULL;
508
+
509
+ if (path) {
510
+ char user_input[BUFSIZ];
511
+ memset(user_input, '\0', BUFSIZ);
512
+
513
+ if (access(path, F_OK) != -1 ) {
514
+ printf("Warning: File already exists at path [%s].\n", path);
515
+ while (strcmp(user_input, "y") != 0 && strcmp(user_input, "n") != 0) {
516
+ memset(user_input, '\0', BUFSIZ);
517
+ printf("Would you like to overwrite [%s]: [y/n] ", path);
518
+ get_input(user_input);
519
+ }
520
+
521
+ if (strcmp(user_input, "n") == 0) {
522
+ printf("\nCanceled overwriting of [%s].\n", path);
523
+ cli_api_t *cli_api = handle;
524
+ cli_api->rcvd_cmd_resp = "download-file-resp";
525
+ queue_next_cmd_req(cli_api);
526
+ return 1;
527
+ }
528
+
529
+ unlink(path);
530
+ }
531
+
532
+ fd = fopen(path, "w+");
533
+ } else {
534
+ fd = stdout;
535
+ }
536
+
537
+ if (fd == NULL) {
538
+ // TODO send to stderr
539
+ printf("Unable to open %s: %s\n", path, strerror(errno));
540
+ return 1;
541
+ }
542
+
543
+ uv_signal_t *sig = malloc(sizeof(uv_signal_t));
544
+ uv_signal_init(env->loop, sig);
545
+ uv_signal_start(sig, download_signal_handler, SIGINT);
546
+
547
+ storj_progress_cb progress_cb = (storj_progress_cb)noop;
548
+ if (path && env->log_options->level == 0) {
549
+ progress_cb = file_progress;
550
+ }
551
+
552
+ storj_download_state_t *state = storj_bridge_resolve_file(env, bucket_id,
553
+ file_id, fd, handle,
554
+ progress_cb,
555
+ download_file_complete);
556
+ if (!state) {
557
+ return 1;
558
+ }
559
+ sig->data = state;
560
+
561
+ return state->error_status;
562
+ }
563
+
564
+ static void list_mirrors_callback(uv_work_t *work_req, int status)
565
+ {
566
+ assert(status == 0);
567
+ json_request_t *req = work_req->data;
568
+
569
+ cli_api_t *cli_api = req->handle;
570
+ cli_api->last_cmd_req = cli_api->curr_cmd_req;
571
+ cli_api->rcvd_cmd_resp = "list-mirrors-resp";
572
+
573
+ if (req->status_code != 200) {
574
+ printf("Request failed with status code: %i\n",
575
+ req->status_code);
576
+ goto cleanup;
577
+ }
578
+
579
+ if (req->response == NULL) {
580
+ free(req);
581
+ free(work_req);
582
+ printf("Failed to list mirrors.\n");
583
+ goto cleanup;
584
+ }
585
+
586
+ int num_mirrors = json_object_array_length(req->response);
587
+
588
+ struct json_object *shard;
589
+ struct json_object *established;
590
+ struct json_object *available;
591
+ struct json_object *item;
592
+ struct json_object *hash;
593
+ struct json_object *contract;
594
+ struct json_object *address;
595
+ struct json_object *port;
596
+ struct json_object *node_id;
597
+
598
+ for (int i = 0; i < num_mirrors; i++) {
599
+ shard = json_object_array_get_idx(req->response, i);
600
+ json_object_object_get_ex(shard, "established",
601
+ &established);
602
+ int num_established =
603
+ json_object_array_length(established);
604
+ for (int j = 0; j < num_established; j++) {
605
+ item = json_object_array_get_idx(established, j);
606
+ if (j == 0) {
607
+ json_object_object_get_ex(item, "shardHash",
608
+ &hash);
609
+ printf("Shard %i: %s\n", i, json_object_get_string(hash));
610
+ }
611
+ json_object_object_get_ex(item, "contract", &contract);
612
+ json_object_object_get_ex(contract, "farmer_id", &node_id);
613
+
614
+ const char *node_id_str = json_object_get_string(node_id);
615
+ printf("\tnodeID: %s\n", node_id_str);
616
+ }
617
+ printf("\n\n");
618
+ }
619
+
620
+ json_object_put(req->response);
621
+
622
+ queue_next_cmd_req(cli_api);
623
+ cleanup:
624
+ free(req->path);
625
+ free(req);
626
+ free(work_req);
627
+ }
628
+
629
+ static void delete_file_callback(uv_work_t *work_req, int status)
630
+ {
631
+ assert(status == 0);
632
+ json_request_t *req = work_req->data;
633
+
634
+ cli_api_t *cli_api = req->handle;
635
+ cli_api->last_cmd_req = cli_api->curr_cmd_req;
636
+ cli_api->rcvd_cmd_resp = "remove-file-resp";
637
+
638
+ if (req->status_code == 200 || req->status_code == 204) {
639
+ printf("File was successfully removed from bucket.\n");
640
+ } else if (req->status_code == 401) {
641
+ printf("Invalid user credentials.\n");
642
+ goto cleanup;
643
+ } else if (req->status_code == 403) {
644
+ printf("Forbidden, user not active.\n");
645
+ goto cleanup;
646
+ } else {
647
+ printf("Failed to remove file from bucket. (%i)\n", req->status_code);
648
+ goto cleanup;
649
+ }
650
+
651
+ json_object_put(req->response);
652
+
653
+ queue_next_cmd_req(cli_api);
654
+ cleanup:
655
+ free(req->path);
656
+ free(req);
657
+ free(work_req);
658
+ }
659
+
660
+ static void delete_bucket_callback(uv_work_t *work_req, int status)
661
+ {
662
+ assert(status == 0);
663
+ json_request_t *req = work_req->data;
664
+
665
+ cli_api_t *cli_api = req->handle;
666
+ cli_api->last_cmd_req = cli_api->curr_cmd_req;
667
+ cli_api->rcvd_cmd_resp = "remove-bucket-resp";
668
+
669
+ if (req->status_code == 200 || req->status_code == 204) {
670
+ printf("Bucket was successfully removed.\n");
671
+ } else if (req->status_code == 401) {
672
+ printf("Invalid user credentials.\n");
673
+ goto cleanup;
674
+ } else if (req->status_code == 403) {
675
+ printf("Forbidden, user not active.\n");
676
+ goto cleanup;
677
+ } else {
678
+ printf("Failed to destroy bucket. (%i)\n", req->status_code);
679
+ goto cleanup;
680
+ }
681
+
682
+ json_object_put(req->response);
683
+
684
+ queue_next_cmd_req(cli_api);
685
+ cleanup:
686
+ free(req->path);
687
+ free(req);
688
+ free(work_req);
689
+ }
690
+
691
+ void get_buckets_callback(uv_work_t *work_req, int status)
692
+ {
693
+ assert(status == 0);
694
+ get_buckets_request_t *req = work_req->data;
695
+
696
+ if (req->status_code == 401) {
697
+ printf("Invalid user credentials.\n");
698
+ } else if (req->status_code == 403) {
699
+ printf("Forbidden, user not active.\n");
700
+ } else if (req->status_code != 200 && req->status_code != 304) {
701
+ printf("Request failed with status code: %i\n", req->status_code);
702
+ } else if (req->total_buckets == 0) {
703
+ printf("No buckets.\n");
704
+ }
705
+
706
+ for (int i = 0; i < req->total_buckets; i++) {
707
+ storj_bucket_meta_t *bucket = &req->buckets[i];
708
+ printf("ID: %s \tDecrypted: %s \tCreated: %s \tName: %s\n",
709
+ bucket->id, bucket->decrypted ? "true" : "false",
710
+ bucket->created, bucket->name);
711
+ }
712
+
713
+ storj_free_get_buckets_request(req);
714
+ free(work_req);
715
+ }
716
+
717
+ void get_bucket_id_callback(uv_work_t *work_req, int status)
718
+ {
719
+ int ret_status = 0x00;
720
+ assert(status == 0);
721
+ get_bucket_id_request_t *req = work_req->data;
722
+ cli_api_t *cli_api = req->handle;
723
+
724
+ cli_api->last_cmd_req = cli_api->curr_cmd_req;
725
+ cli_api->rcvd_cmd_resp = "get-bucket-id-resp";
726
+
727
+ if (req->status_code == 401) {
728
+ printf("Invalid user credentials.\n");
729
+ goto cleanup;
730
+ } else if (req->status_code == 403) {
731
+ printf("Forbidden, user not active.\n");
732
+ goto cleanup;
733
+ } else if (req->status_code != 200 && req->status_code != 304) {
734
+ printf("Request failed with status code: %i\n", req->status_code);
735
+ goto cleanup;
736
+ }
737
+
738
+ /* store the bucket id */
739
+ memset(cli_api->bucket_id, 0x00, sizeof(cli_api->bucket_id));
740
+ strcpy(cli_api->bucket_id, (char *)req->bucket_id);
741
+ printf("ID: %s \tName: %s\n", req->bucket_id, req->bucket_name);
742
+
743
+ queue_next_cmd_req(cli_api);
744
+
745
+ cleanup:
746
+ free(req);
747
+ free(work_req);
748
+ }
749
+
750
+ void get_file_id_callback(uv_work_t *work_req, int status)
751
+ {
752
+ int ret_status = 0x00;
753
+ assert(status == 0);
754
+ get_file_id_request_t *req = work_req->data;
755
+ cli_api_t *cli_api = req->handle;
756
+
757
+ cli_api->last_cmd_req = cli_api->curr_cmd_req;
758
+ cli_api->rcvd_cmd_resp = "get-file-id-resp";
759
+
760
+ if (req->status_code == 401) {
761
+ printf("Invalid user credentials.\n");
762
+ goto cleanup;
763
+ } else if (req->status_code == 403) {
764
+ printf("Forbidden, user not active.\n");
765
+ goto cleanup;
766
+ } else if (req->status_code != 200 && req->status_code != 304) {
767
+ printf("Request failed with status code: %i\n", req->status_code);
768
+ goto cleanup;
769
+ }
770
+
771
+ /* store the bucket id */
772
+ memset(cli_api->file_id, 0x00, sizeof(cli_api->file_id));
773
+ strcpy(cli_api->file_id, (char *)req->file_id);
774
+ printf("ID: %s \tName: %s\n", req->file_id, req->file_name);
775
+
776
+ queue_next_cmd_req(cli_api);
777
+
778
+ cleanup:
779
+ free(req);
780
+ free(work_req);
781
+ }
782
+
783
+ void list_files_callback(uv_work_t *work_req, int status)
784
+ {
785
+ int ret_status = 0;
786
+ assert(status == 0);
787
+ list_files_request_t *req = work_req->data;
788
+
789
+ cli_api_t *cli_api = req->handle;
790
+ cli_api->last_cmd_req = cli_api->curr_cmd_req;
791
+ cli_api->rcvd_cmd_resp = "list-files-resp";
792
+
793
+ if (req->status_code == 404) {
794
+ printf("Bucket id [%s] does not exist\n", req->bucket_id);
795
+ goto cleanup;
796
+ } else if (req->status_code == 400) {
797
+ printf("Bucket id [%s] is invalid\n", req->bucket_id);
798
+ goto cleanup;
799
+ } else if (req->status_code == 401) {
800
+ printf("Invalid user credentials.\n");
801
+ goto cleanup;
802
+ } else if (req->status_code == 403) {
803
+ printf("Forbidden, user not active.\n");
804
+ goto cleanup;
805
+ } else if (req->status_code != 200) {
806
+ printf("Request failed with status code: %i\n", req->status_code);
807
+ }
808
+
809
+ if (req->total_files == 0) {
810
+ printf("No files for bucket.\n");
811
+ goto cleanup;
812
+ }
813
+
814
+
815
+ FILE *dwnld_list_fd = stdout;
816
+ if ((dwnld_list_fd = fopen("/tmp/dwnld_list.txt", "w")) == NULL) {
817
+ printf("[%s][%d] Unable to create download list file\n",
818
+ __FUNCTION__, __LINE__);
819
+ goto cleanup;
820
+ }
821
+
822
+ for (int i = 0; i < req->total_files; i++) {
823
+ storj_file_meta_t *file = &req->files[i];
824
+
825
+ if ((cli_api->file_name != NULL) &&
826
+ (strcmp(cli_api->file_name, file->filename)) == 0x00) {
827
+ /* store the file id */
828
+ memset(cli_api->file_id, 0x00, sizeof(cli_api->file_id));
829
+ strcpy(cli_api->file_id, (char *)file->id);
830
+ }
831
+
832
+ printf("ID: %s \tSize: %" PRIu64 " bytes \tDecrypted: %s \tType: %s \tCreated: %s \tName: %s\n",
833
+ file->id,
834
+ file->size,
835
+ file->decrypted ? "true" : "false",
836
+ file->mimetype,
837
+ file->created,
838
+ file->filename);
839
+
840
+ fprintf(dwnld_list_fd, "%s:%s\n",file->id, file->filename);
841
+ }
842
+
843
+ cli_api->total_files = req->total_files;
844
+ cli_api->xfer_count = 0x01;
845
+ fclose(dwnld_list_fd);
846
+ queue_next_cmd_req(cli_api);
847
+
848
+ cleanup:
849
+
850
+ storj_free_list_files_request(req);
851
+ free(work_req);
852
+ }
853
+
854
+ void queue_next_cmd_req(cli_api_t *cli_api)
855
+ {
856
+ void *handle = cli_api->handle;
857
+
858
+ #ifdef debug_enable
859
+ printf("[%s][%d]start !!!! expt resp = %s; rcvd resp = %s \n",
860
+ __FUNCTION__, __LINE__,
861
+ cli_api->excp_cmd_resp, cli_api->rcvd_cmd_resp );
862
+ printf("[%s][%d]last cmd = %s; cur cmd = %s; next cmd = %s\n",
863
+ __FUNCTION__, __LINE__, cli_api->last_cmd_req,
864
+ cli_api->curr_cmd_req, cli_api->next_cmd_req);
865
+ #endif
866
+
867
+ if (cli_api->excp_cmd_resp != NULL) {
868
+ if (strcmp(cli_api->excp_cmd_resp, cli_api->rcvd_cmd_resp) == 0x00) {
869
+ if ((cli_api->next_cmd_req != NULL) &&
870
+ (strcmp(cli_api->next_cmd_req, "get-file-id-req") == 0x00)) {
871
+ cli_api->curr_cmd_req = cli_api->next_cmd_req;
872
+ cli_api->next_cmd_req = cli_api->final_cmd_req;
873
+ cli_api->final_cmd_req = NULL;
874
+ cli_api->excp_cmd_resp = "get-file-id-resp";
875
+
876
+ storj_bridge_get_file_id(cli_api->env, cli_api->bucket_id,
877
+ cli_api->file_name, cli_api, get_file_id_callback);
878
+ } else if ((cli_api->next_cmd_req != NULL) &&
879
+ (strcmp(cli_api->next_cmd_req, "list-files-req") == 0x00)) {
880
+ cli_api->curr_cmd_req = cli_api->next_cmd_req;
881
+ cli_api->next_cmd_req = cli_api->final_cmd_req;
882
+ cli_api->final_cmd_req = NULL;
883
+ cli_api->excp_cmd_resp = "list-files-resp";
884
+
885
+ storj_bridge_list_files(cli_api->env, cli_api->bucket_id,
886
+ cli_api, list_files_callback);
887
+ } else if ((cli_api->next_cmd_req != NULL) &&
888
+ (strcmp(cli_api->next_cmd_req, "remove-bucket-req") == 0x00)) {
889
+ cli_api->curr_cmd_req = cli_api->next_cmd_req;
890
+ cli_api->next_cmd_req = cli_api->final_cmd_req;
891
+ cli_api->final_cmd_req = NULL;
892
+ cli_api->excp_cmd_resp = "remove-bucket-resp";
893
+
894
+ storj_bridge_delete_bucket(cli_api->env, cli_api->bucket_id,
895
+ cli_api, delete_bucket_callback);
896
+ } else if ((cli_api->next_cmd_req != NULL) &&
897
+ (strcmp(cli_api->next_cmd_req, "remove-file-req") == 0x00)) {
898
+ printf("[%s][%d]file-name = %s; file-id = %s; bucket-name = %s \n",
899
+ __FUNCTION__, __LINE__, cli_api->file_name, cli_api->file_id,
900
+ cli_api->bucket_name);
901
+
902
+ cli_api->curr_cmd_req = cli_api->next_cmd_req;
903
+ cli_api->next_cmd_req = cli_api->final_cmd_req;
904
+ cli_api->final_cmd_req = NULL;
905
+ cli_api->excp_cmd_resp = "remove-file-resp";
906
+
907
+ storj_bridge_delete_file(cli_api->env, cli_api->bucket_id, cli_api->file_id,
908
+ cli_api, delete_file_callback);
909
+ } else if ((cli_api->next_cmd_req != NULL) &&
910
+ (strcmp(cli_api->next_cmd_req, "list-mirrors-req") == 0x00)) {
911
+ printf("[%s][%d]file-name = %s; file-id = %s; bucket-name = %s \n",
912
+ __FUNCTION__, __LINE__, cli_api->file_name, cli_api->file_id,
913
+ cli_api->bucket_name);
914
+
915
+ cli_api->curr_cmd_req = cli_api->next_cmd_req;
916
+ cli_api->next_cmd_req = cli_api->final_cmd_req;
917
+ cli_api->final_cmd_req = NULL;
918
+ cli_api->excp_cmd_resp = "list-mirrors-resp";
919
+
920
+ storj_bridge_list_mirrors(cli_api->env, cli_api->bucket_id, cli_api->file_id,
921
+ cli_api, list_mirrors_callback);
922
+ } else if ((cli_api->next_cmd_req != NULL) &&
923
+ (strcmp(cli_api->next_cmd_req, "upload-file-req") == 0x00)) {
924
+ cli_api->curr_cmd_req = cli_api->next_cmd_req;
925
+ cli_api->next_cmd_req = cli_api->final_cmd_req;
926
+ cli_api->final_cmd_req = NULL;
927
+ cli_api->excp_cmd_resp = "upload-file-resp";
928
+
929
+ upload_file(cli_api->env, cli_api->bucket_id, cli_api->file_name, cli_api);
930
+ } else if ((cli_api->next_cmd_req != NULL) &&
931
+ (strcmp(cli_api->next_cmd_req, "verify-upload-files-req") == 0x00)) {
932
+ cli_api->curr_cmd_req = cli_api->next_cmd_req;
933
+ cli_api->next_cmd_req = cli_api->final_cmd_req;
934
+ cli_api->final_cmd_req = NULL;
935
+ cli_api->excp_cmd_resp = "verify-upload-files-resp";
936
+
937
+ verify_upload_files(cli_api);
938
+ } else if ((cli_api->next_cmd_req != NULL) &&
939
+ (strcmp(cli_api->next_cmd_req, "upload-files-req") == 0x00)) {
940
+ cli_api->curr_cmd_req = cli_api->next_cmd_req;
941
+ cli_api->excp_cmd_resp = "upload-files-resp";
942
+
943
+ FILE *file = fopen(cli_api->src_list, "r");
944
+
945
+ char line[256][256];
946
+ char *temp;
947
+ int i = 0x00;
948
+ memset(line, 0x00, sizeof(line));
949
+
950
+ if (file != NULL) {
951
+ while ((fgets(line[i],sizeof(line), file)!= NULL)) {/* read a line from a file */
952
+ temp = strrchr(line[i], '\n');
953
+ if (temp) *temp = '\0';
954
+ cli_api->src_file = line[i];
955
+ i++;
956
+ if (i >= cli_api->xfer_count) {
957
+ break;
958
+ }
959
+ }
960
+ }
961
+ fclose(file);
962
+
963
+ if (cli_api->xfer_count <= cli_api->total_files) {
964
+ /* is it the last file ? */
965
+ if (cli_api->xfer_count == cli_api->total_files) {
966
+ cli_api->next_cmd_req = cli_api->final_cmd_req;
967
+ cli_api->final_cmd_req = NULL;
968
+ }
969
+
970
+ upload_files(cli_api->env, cli_api->bucket_id, cli_api->src_file, cli_api);
971
+ cli_api->xfer_count++;
972
+ } else {
973
+ printf("[%s][%d] Invalid xfer counts\n", __FUNCTION__, __LINE__);
974
+ exit(0);
975
+ }
976
+ } else if ((cli_api->next_cmd_req != NULL) &&
977
+ (strcmp(cli_api->next_cmd_req, "download-file-req") == 0x00)) {
978
+ cli_api->curr_cmd_req = cli_api->next_cmd_req;
979
+ cli_api->next_cmd_req = cli_api->final_cmd_req;
980
+ cli_api->final_cmd_req = NULL;
981
+ cli_api->excp_cmd_resp = "download-file-resp";
982
+
983
+ download_file(cli_api->env, cli_api->bucket_id, cli_api->file_id,
984
+ cli_api->dst_file, cli_api);
985
+ } else if ((cli_api->next_cmd_req != NULL) &&
986
+ (strcmp(cli_api->next_cmd_req, "download-files-req") == 0x00)) {
987
+ cli_api->curr_cmd_req = cli_api->next_cmd_req;
988
+ cli_api->excp_cmd_resp = "download-file-resp";
989
+
990
+ FILE *file = stdout;
991
+
992
+ if ((file = fopen("/tmp/dwnld_list.txt", "r")) != NULL) {
993
+ char line[256][256];
994
+ char *temp;
995
+ char temp_path[1024];
996
+ int i = 0x00;
997
+ char *token[10];
998
+ int tk_idx= 0x00;
999
+ memset(token, 0x00, sizeof(token));
1000
+ memset(temp_path, 0x00, sizeof(temp_path));
1001
+ memset(line, 0x00, sizeof(line));
1002
+ while ((fgets(line[i],sizeof(line), file)!= NULL)) {/* read a line from a file */
1003
+ temp = strrchr(line[i], '\n');
1004
+ if (temp) *temp = '\0';
1005
+ i++;
1006
+ if (i >= cli_api->xfer_count) {
1007
+ break;
1008
+ }
1009
+ }
1010
+ fclose(file);
1011
+
1012
+ /* start tokenizing */
1013
+ token[0] = strtok(line[i-1], ":");
1014
+ while (token[tk_idx] != NULL) {
1015
+ tk_idx++;
1016
+ token[tk_idx] = strtok(NULL, ":");
1017
+ }
1018
+
1019
+ if (cli_api->xfer_count <= cli_api->total_files) {
1020
+ /* is it the last file ? */
1021
+ if (cli_api->xfer_count == cli_api->total_files) {
1022
+ cli_api->next_cmd_req = cli_api->final_cmd_req;
1023
+ cli_api->final_cmd_req = NULL;
1024
+ }
1025
+
1026
+ memset(cli_api->file_id, 0x00, sizeof(cli_api->file_id));
1027
+ strcpy(cli_api->file_id, token[0]);
1028
+ strcpy(temp_path, cli_api->file_path);
1029
+ if (cli_api->file_path[(strlen(cli_api->file_path)-1)] != '/') {
1030
+ strcat(temp_path, "/");
1031
+ }
1032
+ strcat(temp_path, token[1]);
1033
+ fprintf(stdout,"*****[%d:%d] downloading file to: %s *****\n", cli_api->xfer_count, cli_api->total_files, temp_path);
1034
+ cli_api->xfer_count++;
1035
+
1036
+ download_file(cli_api->env, cli_api->bucket_id, cli_api->file_id, temp_path, cli_api);
1037
+ } else {
1038
+ printf("[%s][%d] Invalid xfer counts\n", __FUNCTION__, __LINE__);
1039
+ exit(0);
1040
+ }
1041
+ }
1042
+ } else {
1043
+ #ifdef debug_enable
1044
+ printf("[%s][%d] **** ALL CLEAN & DONE *****\n", __FUNCTION__, __LINE__);
1045
+ #endif
1046
+
1047
+ exit(0);
1048
+ }
1049
+ } else {
1050
+ printf("[%s][%d]Oops !!!! expt resp = %s; rcvd resp = %s \n",
1051
+ __FUNCTION__, __LINE__,
1052
+ cli_api->excp_cmd_resp, cli_api->rcvd_cmd_resp );
1053
+ printf("[%s][%d]last cmd = %s; cur cmd = %s; next cmd = %s\n",
1054
+ __FUNCTION__, __LINE__, cli_api->last_cmd_req,
1055
+ cli_api->curr_cmd_req, cli_api->next_cmd_req);
1056
+ }
1057
+ } else {
1058
+ /* calling straight storj calls without going thru the state machine */
1059
+ exit(0);
1060
+ }
1061
+ }
1062
+
1063
+ int cli_list_buckets(cli_api_t *cli_api)
1064
+ {
1065
+ cli_api->last_cmd_req = NULL;
1066
+ cli_api->curr_cmd_req = "get-bucket-id-req";
1067
+ cli_api->next_cmd_req = NULL;
1068
+ cli_api->final_cmd_req = NULL;
1069
+ cli_api->excp_cmd_resp = "get-bucket-id-resp";
1070
+
1071
+ /* when callback returns, we store the bucket id of bucket name else null */
1072
+ return storj_bridge_get_buckets(cli_api->env, cli_api, get_buckets_callback);
1073
+ }
1074
+
1075
+ int cli_get_bucket_id(cli_api_t *cli_api)
1076
+ {
1077
+ int ret = -1;
1078
+ cli_api->last_cmd_req = NULL;
1079
+ cli_api->curr_cmd_req = "get-bucket-id-req";
1080
+ cli_api->next_cmd_req = NULL;
1081
+ cli_api->final_cmd_req = NULL;
1082
+ cli_api->excp_cmd_resp = "get-bucket-id-resp";
1083
+
1084
+ /* when callback returns, we store the bucket id of bucket name else null */
1085
+ //return storj_bridge_get_buckets(cli_api->env, cli_api, get_bucket_id_callback);
1086
+ return storj_bridge_get_bucket_id(cli_api->env, cli_api->bucket_name, cli_api, get_bucket_id_callback);
1087
+ }
1088
+
1089
+ int cli_get_file_id(cli_api_t *cli_api)
1090
+ {
1091
+ int ret = 0x00;
1092
+ ret = cli_get_bucket_id(cli_api);
1093
+ cli_api->next_cmd_req = "get-file-id-req";
1094
+ cli_api->final_cmd_req = NULL;
1095
+
1096
+ return ret;
1097
+ }
1098
+
1099
+ int cli_list_files(cli_api_t *cli_api)
1100
+ {
1101
+ int ret = 0x00;
1102
+ ret = cli_get_bucket_id(cli_api);
1103
+ cli_api->next_cmd_req = "list-files-req";
1104
+ cli_api->final_cmd_req = NULL;
1105
+
1106
+ return ret;
1107
+ }
1108
+
1109
+ int cli_remove_bucket(cli_api_t *cli_api)
1110
+ {
1111
+ int ret = 0x00;
1112
+ ret = cli_get_bucket_id(cli_api);
1113
+ cli_api->next_cmd_req = "remove-bucket-req";
1114
+ cli_api->final_cmd_req = NULL;
1115
+
1116
+ return ret;
1117
+ }
1118
+
1119
+ int cli_remove_file(cli_api_t *cli_api)
1120
+ {
1121
+ int ret = 0x00;
1122
+ ret = cli_get_file_id(cli_api);
1123
+ cli_api->final_cmd_req = "remove-file-req";
1124
+
1125
+ return ret;
1126
+ }
1127
+
1128
+ int cli_list_mirrors(cli_api_t *cli_api)
1129
+ {
1130
+ int ret = 0x00;
1131
+ ret = cli_get_file_id(cli_api);
1132
+ cli_api->final_cmd_req = "list-mirrors-req";
1133
+
1134
+ return ret;
1135
+ }
1136
+
1137
+ int cli_upload_file(cli_api_t *cli_api)
1138
+ {
1139
+ int ret = 0x00;
1140
+ ret = cli_get_bucket_id(cli_api);
1141
+ cli_api->next_cmd_req = "upload-file-req";
1142
+ cli_api->final_cmd_req = NULL;
1143
+
1144
+ return ret;
1145
+ }
1146
+
1147
+ int cli_upload_files(cli_api_t *cli_api)
1148
+ {
1149
+ int ret = 0x00;
1150
+ ret = cli_get_bucket_id(cli_api);
1151
+ cli_api->next_cmd_req = "verify-upload-files-req";
1152
+ cli_api->final_cmd_req = "upload-files-req";
1153
+
1154
+ return ret;
1155
+ }
1156
+
1157
+ int cli_download_file(cli_api_t *cli_api)
1158
+ {
1159
+ int ret = 0x00;
1160
+ ret = cli_get_file_id(cli_api);
1161
+ cli_api->final_cmd_req = "download-file-req";
1162
+
1163
+ return ret;
1164
+ }
1165
+
1166
+ int cli_download_files(cli_api_t *cli_api)
1167
+ {
1168
+ int ret = 0x00;
1169
+ ret = cli_list_files(cli_api);
1170
+ cli_api->final_cmd_req = "download-files-req";
1171
+
1172
+ return ret;
1173
+ }