ruby-libstorj 0.0.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 52c2c5dd170de6905993f7a4c034102773de5cd1
4
- data.tar.gz: 599fcf11242ff3dad90f62f0771da0affa3cefc8
3
+ metadata.gz: 8de9d6c135ae3b5e58a34ce91f1ac731bc2e887a
4
+ data.tar.gz: f581db0c00bfcbbec33081df8034bcb17c8d7e18
5
5
  SHA512:
6
- metadata.gz: 60e028360df7c68c8686f2a4077f6799f1989b6049310b3a0a0e33e33c7ed29a456d95520fffdc658c5c2e3ccb5cd1bcc4caa0ea5ccd4c23f749ce80fbc6183b
7
- data.tar.gz: 0a92e395b4a2cbd29d2f53351dc7a6afe2f2bab22fd86c21adad27e57adea0fbff4cb9ceeb234642d33fad3462646e9da8c49acc9a5a6828cbe9a29474aeedce
6
+ metadata.gz: d7d9eef9134284db52495f95e1fbf73f7827380e180e6da2ffff75ae8ff6db1a204f3f3e646670ca7c664c74613dbd2e3e028ef945abf531a940c670fd842f29
7
+ data.tar.gz: 0a58c196a68386fc3ca0fc8bf3caf0156f38d2526c374a551b4a7eb194121f733e22943fbf06e171cfd2283195e6cbb2f0581cbdf4b3ea8b76a7c47dbafbc1b1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-libstorj (0.0.0)
4
+ ruby-libstorj (1.0.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -108,4 +108,4 @@ DEPENDENCIES
108
108
  simplecov!
109
109
 
110
110
  BUNDLED WITH
111
- 1.15.4
111
+ 1.16.0
data/README.md CHANGED
@@ -1,10 +1,22 @@
1
1
  ruby-libstorj: Ruby bindings for libstorj
2
2
  ===
3
+ [![Gem Version](https://badge.fury.io/rb/ruby-libstorj.svg)](https://badge.fury.io/rb/ruby-libstorj)
3
4
 
4
5
  ## Using ruby-libstorj
5
6
 
6
7
  ### Install gem:
7
- _(until initial release installing from source is necessary)_
8
+ + using bundler:
9
+ ```
10
+ # in your Gemfile
11
+ gem 'ruby-libstorj'
12
+ ```
13
+ ```bash
14
+ bundle install
15
+ ```
16
+ + using rubygems (`gem`):
17
+ ```bash
18
+ gem install ruby-libstorj
19
+ ```
8
20
  + from source:
9
21
  ```bash
10
22
  git clone https://github.com/storj/ruby-libstorj && \
@@ -76,7 +88,7 @@ rake
76
88
  #### First create spec/helpers/options.yml !
77
89
  For the moment, the test suite doesn't start it's own mock backend but it does parse whatever's in the `spec/helpsers/options.yml` file to initialize `LibStorj::Ext::Storj::Env` to connect via http/https.
78
90
 
79
- You can copy [`spec/helpers/options.yml.example`](./spec/helpers/options.yml.example) and modify it for your use:
91
+ You can copy [`spec/helpers/options.yml.example`](spec/helpers/options.example.yml) and modify it for your use:
80
92
  ```bash
81
93
  cp spec/helpers/options.yml.example spec/helpers/options.yml && \
82
94
  vim spec/helpers/options.yml # or whatever
@@ -29,6 +29,7 @@ docs
29
29
  libstorj.pc
30
30
  libtool
31
31
  src/main
32
+ src/shard_size
32
33
  src/storj
33
34
  src/storj.dSYM/
34
35
  src/storj.exe
@@ -0,0 +1,66 @@
1
+ # Contributing
2
+
3
+ ## Required Skill-set
4
+ - An understanding of the Storj network and [SIP5](https://github.com/Storj/sips/blob/master/sip-0005.md)
5
+ - Practical understanding of cryptographic concepts
6
+ - Experience with some C-like language
7
+ - Understanding of asynchronous programming and event loops
8
+ - An understanding of networking protocols, such as TCP/HTTP
9
+ - Familiarity with unit, integration and e2e testing
10
+ - Familiarity with autotools
11
+ - An understanding of `git` for version control and collaboration
12
+ - Debugging experience
13
+
14
+ ## Share Early, Share Often
15
+
16
+ It's highly recommended to announce your plans before you start work. Once started, commit your changes in small, clear and atomic commits (see commit messages below). This has several benefits:
17
+ - Avoids duplicate work
18
+ - Get feedback and help to achieve your goals
19
+ - Requires less rebasing or merging from master
20
+ - Improves ability to rebase changes
21
+
22
+ ## Compiling, Debugging and Testing
23
+
24
+ We strive to do test driven development and cover all critical sections of code.
25
+
26
+ The test suite is composed of a mix of unit and integration tests. All dependent network components are mocked with reproducible behaviors.
27
+
28
+ There should not be any known leaks when running `valgrind --leak-check=full ./test/tests`, and there shouldn't be compile warnings with either `gcc` or `clang`.
29
+
30
+ Using `gdb` is recommended to be used to help identify issues, this can become more tricky on systems such as Windows. However it's possible to compile `gdb` for Windows using Cygwin. Almost all development for Windows can be done using Mingw and Wine, with results then verified on a Windows virtual machine. Please see the [README for details on cross compilation](README.md#cross-compiling-dependencies-from-ubuntu-1604).
31
+
32
+ ## Memory Ownership & Threads
33
+
34
+ To avoid issues with multi-threaded memory conflicts, it's necessary to make it clear where memory is allocated, free'd, and if it's safe to modify in a thread. This is handled by making it unnecessary to get locks before modifying variables. For an example of this, the `state` types for uploads and downloads can be modified in the main event loop, however should not be modified in the worker pool threads. There is a specific data type for work in the thread pool, that is for the purpose of moving memory between threads.
35
+
36
+ ## Coding Style
37
+
38
+ - Naming and comments are important, think about yourself after a few months away
39
+ - 4 spaces
40
+ - Always use brackets, and keep on the same line, except for functions
41
+ - The pointer `*` goes next to the name not the type
42
+ - Types are defined with a `_t` for example `storj_download_state_t`
43
+
44
+ ## Commit Messages
45
+
46
+ It's recommended to make atomic commits for each change. This improves the ability to rebase and review changes.
47
+
48
+ An example commit message:
49
+
50
+ ```
51
+ Short description of the changes
52
+
53
+ More detailed description of changes and potentially the
54
+ rational for the changes and any other information that
55
+ would help someone looking back at the history may want
56
+ to know.
57
+ ```
58
+
59
+ ## Contributor License Agreement
60
+
61
+ By submitting pull requests, you agree that your work may be licensed under one of:
62
+
63
+ GNU Affero General Public License Version 3 (or later)
64
+ GNU Lesser General Public License Version 2.1 (or later)
65
+
66
+ You also assert that you have completed the [Contributor License Agreement](https://docs.google.com/forms/d/e/1FAIpQLSdVzD5W8rx-J_jLaPuG31nbOzS8yhNIIu4yHvzonji6NeZ4ig/viewform)
@@ -827,7 +827,7 @@ EXCLUDE_SYMLINKS = NO
827
827
  # Note that the wildcards are matched against the file with absolute path, so to
828
828
  # exclude all test directories for example use the pattern */test/*
829
829
 
830
- EXCLUDE_PATTERNS =
830
+ EXCLUDE_PATTERNS = */depends/* */release/* */test/*
831
831
 
832
832
  # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
833
833
  # (namespaces, classes, functions, etc.) that should be excluded from the
@@ -1,6 +1,7 @@
1
1
  libstorj
2
2
  =======
3
3
 
4
+ [![Storj.io](https://storj.io/img/storj-badge.svg)](https://storj.io)
4
5
  [![Build Status](https://travis-ci.org/Storj/libstorj.svg?branch=master)](https://travis-ci.org/Storj/libstorj)
5
6
 
6
7
  Asynchronous multi-platform C library and CLI for encrypted file transfer on the Storj network.
@@ -66,7 +67,11 @@ Dependencies:
66
67
  brew install curl nettle json-c libuv
67
68
  ```
68
69
 
69
- ### Cross Compiling Dependencies from Ubuntu 16.04
70
+ ------
71
+
72
+ ## Cross Compiling Dependencies from Ubuntu 16.04
73
+
74
+ These notes are for cross compiling for various systems from a Debian based linux distribution, specifically Ubuntu 16.04. The mingw toolchain is used to build for Windows and clang and cctools for macOS builds.
70
75
 
71
76
  **Windows**
72
77
 
@@ -1,4 +1,4 @@
1
- AC_INIT([libstorj],[2.0.0-beta])
1
+ AC_INIT([libstorj],[2.0.0-beta2])
2
2
  AC_CONFIG_AUX_DIR([build-aux])
3
3
  AC_CONFIG_MACRO_DIR([build-aux/m4])
4
4
  AM_INIT_AUTOMAKE([foreign])
@@ -0,0 +1,61 @@
1
+ #!/bin/bash
2
+
3
+ # This file is to automate some of the release process.
4
+ # It will package up releases built and installed into
5
+ # a prefix directory of "release". The result will be
6
+ # signed tar and zip files in "release/packages".
7
+
8
+ set -e
9
+
10
+ basename="libstorj-2.0.0-beta2"
11
+
12
+ releases=(arm-linux-gnueabihf
13
+ i686-pc-linux-gnu
14
+ i686-w64-mingw32
15
+ x86_64-apple-darwin11
16
+ x86_64-pc-linux-gnu
17
+ x86_64-w64-mingw32)
18
+
19
+ short_releases=(linux-armv7
20
+ linux32
21
+ win32
22
+ macos
23
+ linux64
24
+ win64)
25
+
26
+ for i in "${!releases[@]}"; do
27
+ release="${releases[$i]}"
28
+ short="${short_releases[$i]}"
29
+
30
+ printf "Starting %s (%s)...\n" $release $short
31
+
32
+ echo "Copying documents..."
33
+ rel_dir="release/${release}"
34
+ cp -v "README.md" "${rel_dir}/"
35
+ cp -v "LICENSE" "${rel_dir}/"
36
+
37
+ echo "Preparing directory..."
38
+ new_dir="release/${release}/${basename}"
39
+ mkdir -p "${new_dir}"
40
+ mv -v $rel_dir/[^$basename]* $new_dir/
41
+
42
+ echo "Packaging..."
43
+ mkdir -p "release/packages"
44
+ pushd $rel_dir
45
+ if [[ "$release" =~ "w64" ]]; then
46
+ zip -r $basename-$short.zip $basename
47
+ mv $basename-$short.zip ../packages/
48
+ else
49
+ tar -cvzf $basename-$short.tar.gz $basename
50
+ mv $basename-$short.tar.gz ../packages/
51
+ fi
52
+ popd
53
+
54
+ printf "\n\n"
55
+ done
56
+
57
+ echo "Hashing and signing packages..."
58
+ pushd "release/packages"
59
+ sha256sum [!SHA256SUMS]* > SHA256SUMS
60
+ gpg --clearsign SHA256SUMS
61
+ popd
@@ -1,5 +1,5 @@
1
1
  lib_LTLIBRARIES = libstorj.la
2
- libstorj_la_SOURCES = storj.c utils.c utils.h http.c http.h uploader.c uploader.h downloader.c downloader.h bip39.c bip39.h bip39_english.h crypto.c crypto.h rs.c rs.h
2
+ libstorj_la_SOURCES = storj.c utils.c utils.h http.c http.h uploader.c uploader.h downloader.c downloader.h bip39.c bip39.h bip39_english.h crypto.c crypto.h rs.c rs.h cli_callback.c cli_callback.h
3
3
  libstorj_la_LIBADD = -lcurl -lnettle -ljson-c -luv -lm
4
4
  # The rules of thumb, when dealing with these values are:
5
5
  # - Always increase the revision value.
@@ -7,7 +7,7 @@ libstorj_la_LIBADD = -lcurl -lnettle -ljson-c -luv -lm
7
7
  # - Increase the age value only if the changes made to the ABI are backward compatible.
8
8
  # https://autotools.io/libtool/version.html
9
9
  # The order for version-info is <current>:<revision>:<age>
10
- libstorj_la_LDFLAGS = -Wall -version-info 1:1:0
10
+ libstorj_la_LDFLAGS = -Wall -version-info 2:2:0
11
11
  if BUILD_STORJ_DLL
12
12
  libstorj_la_LDFLAGS += -no-undefined
13
13
  endif
@@ -190,6 +190,11 @@ bool mnemonic_check(const char *mnemonic)
190
190
  int mnemonic_to_seed(const char *mnemonic, const char *passphrase,
191
191
  char **buffer)
192
192
  {
193
+ // If mnemonic is NULL, assume empty string
194
+ if (!mnemonic) {
195
+ mnemonic = "";
196
+ }
197
+
193
198
  int passphraselen = strlen(passphrase);
194
199
 
195
200
  // We can't exceed a password of 256 bytes
@@ -15,6 +15,9 @@
15
15
  #endif
16
16
 
17
17
  #include "storj.h"
18
+ #include "cli_callback.c"
19
+
20
+ //#define debug_enable
18
21
 
19
22
  #define STORJ_THREADPOOL_SIZE "64"
20
23
 
@@ -30,45 +33,153 @@ typedef struct {
30
33
  extern int errno;
31
34
  #endif
32
35
 
33
- static inline void noop() {};
34
36
 
35
37
  #define HELP_TEXT "usage: storj [<options>] <command> [<args>]\n\n" \
36
38
  "These are common Storj commands for various situations:\n\n" \
37
- "setting up users profiles\n" \
38
- " register setup a new storj bridge user\n" \
39
- " import-keys import existing user\n" \
40
- " export-keys export bridge user, password and " \
39
+ "setting up user profiles:\n" \
40
+ " register setup a new storj bridge user\n" \
41
+ " import-keys import existing user\n" \
42
+ " export-keys export bridge user, password and " \
41
43
  "encryption keys\n\n" \
42
- "working with buckets and files\n" \
44
+ "unix style commands:\n" \
45
+ " ls lists the available buckets\n" \
46
+ " ls <bucket-name> lists the files in a bucket\n" \
47
+ " cp [-rR] <path> <uri> upload files to a bucket " \
48
+ "(e.g. storj cp -[rR] /<some-dir>/* storj://<bucket-name>/)\n" \
49
+ " cp [-rR] <uri> <path> download files from a bucket " \
50
+ "(e.g. storj cp -[rR] storj://<bucket-name>/ /<some-dir>/)\n" \
51
+ " mkbkt <bucket-name> make a bucket\n" \
52
+ " rm <bucket-name> <file-name> remove a file from a bucket\n" \
53
+ " rm <bucket-name> remove a bucket\n" \
54
+ " lm <bucket-name> <file-name> list mirrors\n\n" \
55
+ "working with buckets and files:\n" \
43
56
  " list-buckets\n" \
44
57
  " list-files <bucket-id>\n" \
45
58
  " remove-file <bucket-id> <file-id>\n" \
46
- " add-bucket <name> \n" \
47
59
  " remove-bucket <bucket-id>\n" \
48
- " list-mirrors <bucket-id> <file-id>\n\n" \
49
- "downloading and uploading files\n" \
50
- " upload-file <bucket-id> <path>\n" \
51
- " download-file <bucket-id> <file-id> <path>\n" \
52
- "bridge api information\n" \
60
+ " add-bucket <name> \n" \
61
+ " list-mirrors <bucket-id> <file-id>\n" \
62
+ " get-bucket-id <bucket-name>\n\n" \
63
+ "uploading files:\n" \
64
+ " upload-file <bucket-id> <path>\n\n" \
65
+ "downloading files:\n" \
66
+ " download-file <bucket-id> <file-id> <path>\n\n" \
67
+ "bridge api information:\n" \
53
68
  " get-info\n\n" \
54
69
  "options:\n" \
55
- " -h, --help output usage information\n" \
56
- " -v, --version output the version number\n" \
57
- " -u, --url <url> set the base url for the api\n" \
58
- " -p, --proxy <url> set the socks proxy " \
70
+ " -h, --help output usage information\n" \
71
+ " -v, --version output the version number\n" \
72
+ " -u, --url <url> set the base url for the api\n" \
73
+ " -p, --proxy <url> set the socks proxy " \
59
74
  "(e.g. <[protocol://][user:password@]proxyhost[:port]>)\n" \
60
- " -l, --log <level> set the log level (default 0)\n" \
61
- " -d, --debug set the debug log level\n\n" \
75
+ " -l, --log <level> set the log level (default 0)\n" \
76
+ " -d, --debug set the debug log level\n\n" \
62
77
  "environment variables:\n" \
63
- " STORJ_KEYPASS imported user settings passphrase\n" \
64
- " STORJ_BRIDGE the bridge host " \
78
+ " STORJ_KEYPASS imported user settings passphrase\n" \
79
+ " STORJ_BRIDGE the bridge host " \
65
80
  "(e.g. https://api.storj.io)\n" \
66
- " STORJ_BRIDGE_USER bridge username\n" \
67
- " STORJ_BRIDGE_PASS bridge password\n" \
68
- " STORJ_ENCRYPTION_KEY file encryption key\n\n"
81
+ " STORJ_BRIDGE_USER bridge username\n" \
82
+ " STORJ_BRIDGE_PASS bridge password\n" \
83
+ " STORJ_ENCRYPTION_KEY file encryption key\n\n"
84
+
85
+
86
+ #define CLI_VERSION "libstorj-2.0.0-beta2"
87
+
88
+ static int check_file_path(char *file_path)
89
+ {
90
+ struct stat sb;
91
+
92
+ if (stat(file_path, &sb) == -1) {
93
+ perror("stat");
94
+ return CLI_NO_SUCH_FILE_OR_DIR;
95
+ }
96
+
97
+ switch (sb.st_mode & S_IFMT) {
98
+ case S_IFBLK:
99
+ printf("block device\n");
100
+ break;
101
+ case S_IFCHR:
102
+ printf("character device\n");
103
+ break;
104
+ case S_IFDIR:
105
+ return CLI_VALID_DIR;
106
+ break;
107
+ case S_IFIFO:
108
+ printf("FIFO/pipe\n");
109
+ break;
110
+ case S_IFLNK:
111
+ printf("symlink\n");
112
+ break;
113
+ case S_IFREG:
114
+ return CLI_VALID_REGULAR_FILE;
115
+ break;
116
+ case S_IFSOCK:
117
+ printf("socket\n");
118
+ break;
119
+ default:
120
+ printf("unknown?\n");
121
+ break;
122
+ }
123
+
124
+ #if ENABLE_FILE_DETAILS
125
+ printf("I-node number: %ld\n", (long)sb.st_ino);
126
+
127
+ printf("Mode: %lo (octal)\n",
128
+ (unsigned long)sb.st_mode);
129
+
130
+ printf("Link count: %ld\n", (long)sb.st_nlink);
131
+ printf("Ownership: UID=%ld GID=%ld\n",
132
+ (long)sb.st_uid, (long)sb.st_gid);
133
+
134
+ printf("Preferred I/O block size: %ld bytes\n",
135
+ (long)sb.st_blksize);
136
+ printf("File size: %lld bytes\n",
137
+ (long long)sb.st_size);
138
+ printf("Blocks allocated: %lld\n",
139
+ (long long)sb.st_blocks);
140
+
141
+ printf("Last status change: %s", ctime(&sb.st_ctime));
142
+ printf("Last file access: %s", ctime(&sb.st_atime));
143
+ printf("Last file modification: %s", ctime(&sb.st_mtime));
144
+ #endif
145
+
146
+ return CLI_UNKNOWN_FILE_ATTR;
147
+ }
148
+
149
+
150
+ static int strpos(char *str, char *sub_str)
151
+ {
152
+ /* find first occurance of substring in string */
153
+ char *sub_str_pos=strstr(str,sub_str);
154
+
155
+ /* if null return -1 , otherwise return substring address - base address */
156
+ return sub_str_pos == NULL ? -1 : (sub_str_pos - str );
157
+ }
158
+
159
+ static int validate_cmd_tokenize(char *cmd_str, char *str_token[])
160
+ {
161
+ char sub_str[] = "storj://";
162
+ int i = 0x00; /* num of tokens */
163
+
164
+ int ret = strpos(cmd_str, sub_str);
165
+ if (ret == -1) {
166
+ printf("Invalid Command Entry (%d), \ntry ... storj://<bucket_name>/<file_name>\n", ret);
167
+ }
69
168
 
169
+ if (ret == 0x00) {
170
+ /* start tokenizing */
171
+ str_token[0] = strtok(cmd_str, "/");
172
+ while (str_token[i] != NULL) {
173
+ i++;
174
+ str_token[i] = strtok(NULL, "/");
175
+ }
176
+ } else {
177
+ i = ret;
178
+ }
179
+
180
+ return i;
181
+ }
70
182
 
71
- #define CLI_VERSION "libstorj-2.0.0-beta"
72
183
 
73
184
  static void json_logger(const char *message, int level, void *handle)
74
185
  {
@@ -109,37 +220,6 @@ static int make_user_directory(char *path)
109
220
  return 0;
110
221
  }
111
222
 
112
- static const char *get_filename_separator(const char *file_path)
113
- {
114
- const char *file_name = NULL;
115
- #ifdef _WIN32
116
- file_name = strrchr(file_path, '\\');
117
- if (!file_name) {
118
- file_name = strrchr(file_path, '/');
119
- }
120
- if (!file_name && file_path) {
121
- file_name = file_path;
122
- }
123
- if (!file_name) {
124
- return NULL;
125
- }
126
- if (file_name[0] == '\\' || file_name[0] == '/') {
127
- file_name++;
128
- }
129
- #else
130
- file_name = strrchr(file_path, '/');
131
- if (!file_name && file_path) {
132
- file_name = file_path;
133
- }
134
- if (!file_name) {
135
- return NULL;
136
- }
137
- if (file_name[0] == '/') {
138
- file_name++;
139
- }
140
- #endif
141
- return file_name;
142
- }
143
223
 
144
224
  static int get_user_auth_location(char *host, char **root_dir, char **user_file)
145
225
  {
@@ -170,24 +250,6 @@ static int get_user_auth_location(char *host, char **root_dir, char **user_file)
170
250
  return 0;
171
251
  }
172
252
 
173
- static void get_input(char *line)
174
- {
175
- if (fgets(line, BUFSIZ, stdin) == NULL) {
176
- line[0] = '\0';
177
- } else {
178
- int len = strlen(line);
179
- if (len > 0) {
180
- char *last = strrchr(line, '\n');
181
- if (last) {
182
- last[0] = '\0';
183
- }
184
- last = strrchr(line, '\r');
185
- if (last) {
186
- last[0] = '\0';
187
- }
188
- }
189
- }
190
- }
191
253
 
192
254
  static int generate_mnemonic(char **mnemonic)
193
255
  {
@@ -318,274 +380,6 @@ static int get_password_verify(char *prompt, char *password, int count)
318
380
  }
319
381
  }
320
382
 
321
- void close_signal(uv_handle_t *handle)
322
- {
323
- ((void)0);
324
- }
325
-
326
- static void file_progress(double progress,
327
- uint64_t downloaded_bytes,
328
- uint64_t total_bytes,
329
- void *handle)
330
- {
331
- int bar_width = 70;
332
-
333
- if (progress == 0 && downloaded_bytes == 0) {
334
- printf("Preparing File...");
335
- fflush(stdout);
336
- return;
337
- }
338
-
339
- printf("\r[");
340
- int pos = bar_width * progress;
341
- for (int i = 0; i < bar_width; ++i) {
342
- if (i < pos) {
343
- printf("=");
344
- } else if (i == pos) {
345
- printf(">");
346
- } else {
347
- printf(" ");
348
- }
349
- }
350
- printf("] %.*f%%", 2, progress * 100);
351
-
352
- fflush(stdout);
353
- }
354
-
355
- static void upload_file_complete(int status, char *file_id, void *handle)
356
- {
357
- printf("\n");
358
- if (status != 0) {
359
- printf("Upload failure: %s\n", storj_strerror(status));
360
- exit(status);
361
- }
362
-
363
- printf("Upload Success! File ID: %s\n", file_id);
364
-
365
- free(file_id);
366
-
367
- exit(0);
368
- }
369
-
370
- void upload_signal_handler(uv_signal_t *req, int signum)
371
- {
372
- storj_upload_state_t *state = req->data;
373
- storj_bridge_store_file_cancel(state);
374
- if (uv_signal_stop(req)) {
375
- printf("Unable to stop signal\n");
376
- }
377
- uv_close((uv_handle_t *)req, close_signal);
378
- }
379
-
380
- static int upload_file(storj_env_t *env, char *bucket_id, const char *file_path)
381
- {
382
- bool using_stdin = false;
383
- FILE *fd = fopen(file_path, "r");
384
-
385
- if (!fd) {
386
- printf("Invalid file path: %s\n", file_path);
387
- fd = fdopen(0, "r");
388
- using_stdin = true;
389
- }
390
-
391
- const char *file_name = get_filename_separator(file_path);
392
-
393
- if (!file_name) {
394
- file_name = file_path;
395
- }
396
-
397
- // Upload opts env variables:
398
- char *prepare_frame_limit;
399
- char *push_frame_limit;
400
- char *push_shard_limit;
401
- char *rs = getenv("STORJ_REED_SOLOMON");
402
-
403
- storj_upload_opts_t upload_opts = {
404
- .prepare_frame_limit = (prepare_frame_limit) ? atoi(prepare_frame_limit) : 1,
405
- .push_frame_limit = (push_frame_limit) ? atoi(push_frame_limit) : 64,
406
- .push_shard_limit = (push_shard_limit) ? atoi(push_shard_limit) : 64,
407
- .rs = (!rs) ? true : (strcmp(rs, "false") == 0) ? false : true,
408
- .bucket_id = bucket_id,
409
- .file_name = file_name,
410
- .fd = fd
411
- };
412
-
413
- uv_signal_t *sig = malloc(sizeof(uv_signal_t));
414
- if (!sig) {
415
- return 1;
416
- }
417
- uv_signal_init(env->loop, sig);
418
- uv_signal_start(sig, upload_signal_handler, SIGINT);
419
-
420
-
421
-
422
- storj_progress_cb progress_cb = (storj_progress_cb)noop;
423
- if (env->log_options->level == 0) {
424
- progress_cb = file_progress;
425
- }
426
-
427
- storj_upload_state_t *state = storj_bridge_store_file(env,
428
- &upload_opts,
429
- NULL,
430
- progress_cb,
431
- upload_file_complete);
432
-
433
- if (!state) {
434
- return 1;
435
- }
436
-
437
- sig->data = state;
438
-
439
- return state->error_status;
440
- }
441
-
442
- static void download_file_complete(int status, FILE *fd, void *handle)
443
- {
444
- printf("\n");
445
- fclose(fd);
446
- if (status) {
447
- // TODO send to stderr
448
- switch(status) {
449
- case STORJ_FILE_DECRYPTION_ERROR:
450
- printf("Unable to properly decrypt file, please check " \
451
- "that the correct encryption key was " \
452
- "imported correctly.\n\n");
453
- break;
454
- default:
455
- printf("Download failure: %s\n", storj_strerror(status));
456
- }
457
-
458
- exit(status);
459
- }
460
- printf("Download Success!\n");
461
- exit(0);
462
- }
463
-
464
- void download_signal_handler(uv_signal_t *req, int signum)
465
- {
466
- storj_download_state_t *state = req->data;
467
- storj_bridge_resolve_file_cancel(state);
468
- if (uv_signal_stop(req)) {
469
- printf("Unable to stop signal\n");
470
- }
471
- uv_close((uv_handle_t *)req, close_signal);
472
- }
473
-
474
- static int download_file(storj_env_t *env, char *bucket_id,
475
- char *file_id, char *path)
476
- {
477
- FILE *fd = NULL;
478
-
479
- if (path) {
480
- char user_input[BUFSIZ];
481
- memset(user_input, '\0', BUFSIZ);
482
-
483
- if(access(path, F_OK) != -1 ) {
484
- printf("Warning: File already exists at path [%s].\n", path);
485
- while (strcmp(user_input, "y") != 0 && strcmp(user_input, "n") != 0)
486
- {
487
- memset(user_input, '\0', BUFSIZ);
488
- printf("Would you like to overwrite [%s]: [y/n] ", path);
489
- get_input(user_input);
490
- }
491
-
492
- if (strcmp(user_input, "n") == 0) {
493
- printf("\nCanceled overwriting of [%s].\n", path);
494
- return 1;
495
- }
496
-
497
- unlink(path);
498
- }
499
-
500
- fd = fopen(path, "w+");
501
- } else {
502
- fd = stdout;
503
- }
504
-
505
- if (fd == NULL) {
506
- // TODO send to stderr
507
- printf("Unable to open %s: %s\n", path, strerror(errno));
508
- return 1;
509
- }
510
-
511
- uv_signal_t *sig = malloc(sizeof(uv_signal_t));
512
- uv_signal_init(env->loop, sig);
513
- uv_signal_start(sig, download_signal_handler, SIGINT);
514
-
515
- storj_progress_cb progress_cb = (storj_progress_cb)noop;
516
- if (path && env->log_options->level == 0) {
517
- progress_cb = file_progress;
518
- }
519
-
520
- storj_download_state_t *state = storj_bridge_resolve_file(env, bucket_id,
521
- file_id, fd, NULL,
522
- progress_cb,
523
- download_file_complete);
524
- if (!state) {
525
- return 1;
526
- }
527
- sig->data = state;
528
-
529
- return state->error_status;
530
- }
531
-
532
- static void list_mirrors_callback(uv_work_t *work_req, int status)
533
- {
534
- assert(status == 0);
535
- json_request_t *req = work_req->data;
536
-
537
- if (req->status_code != 200) {
538
- printf("Request failed with status code: %i\n",
539
- req->status_code);
540
- }
541
-
542
- if (req->response == NULL) {
543
- free(req);
544
- free(work_req);
545
- printf("Failed to list mirrors.\n");
546
- exit(1);
547
- }
548
-
549
- int num_mirrors = json_object_array_length(req->response);
550
-
551
- struct json_object *shard;
552
- struct json_object *established;
553
- struct json_object *available;
554
- struct json_object *item;
555
- struct json_object *hash;
556
- struct json_object *contract;
557
- struct json_object *address;
558
- struct json_object *port;
559
- struct json_object *node_id;
560
-
561
- for (int i = 0; i < num_mirrors; i++) {
562
- shard = json_object_array_get_idx(req->response, i);
563
- json_object_object_get_ex(shard, "established",
564
- &established);
565
- int num_established =
566
- json_object_array_length(established);
567
- for (int j = 0; j < num_established; j++) {
568
- item = json_object_array_get_idx(established, j);
569
- if (j == 0) {
570
- json_object_object_get_ex(item, "shardHash",
571
- &hash);
572
- printf("Shard %i: %s\n", i, json_object_get_string(hash));
573
- }
574
- json_object_object_get_ex(item, "contract", &contract);
575
- json_object_object_get_ex(contract, "farmer_id", &node_id);
576
-
577
- const char *node_id_str = json_object_get_string(node_id);
578
- printf("\tnodeID: %s\n", node_id_str);
579
- }
580
- printf("\n\n");
581
- }
582
-
583
- json_object_put(req->response);
584
- free(req->path);
585
- free(req);
586
- free(work_req);
587
- }
588
-
589
383
  static int import_keys(user_options_t *options)
590
384
  {
591
385
  int status = 0;
@@ -810,123 +604,20 @@ static void register_callback(uv_work_t *work_req, int status)
810
604
  free(work_req);
811
605
  }
812
606
 
813
- static void list_files_callback(uv_work_t *work_req, int status)
814
- {
815
- int ret_status = 0;
816
- assert(status == 0);
817
- list_files_request_t *req = work_req->data;
818
-
819
- if (req->status_code == 404) {
820
- printf("Bucket id [%s] does not exist\n", req->bucket_id);
821
- goto cleanup;
822
- } else if (req->status_code == 400) {
823
- printf("Bucket id [%s] is invalid\n", req->bucket_id);
824
- goto cleanup;
825
- } else if (req->status_code == 401) {
826
- printf("Invalid user credentials.\n");
827
- goto cleanup;
828
- } else if (req->status_code != 200) {
829
- printf("Request failed with status code: %i\n", req->status_code);
830
- }
831
-
832
- if (req->total_files == 0) {
833
- printf("No files for bucket.\n");
834
- }
835
-
836
- for (int i = 0; i < req->total_files; i++) {
837
-
838
- storj_file_meta_t *file = &req->files[i];
839
-
840
- printf("ID: %s \tSize: %" PRIu64 " bytes \tDecrypted: %s \tType: %s \tCreated: %s \tName: %s\n",
841
- file->id,
842
- file->size,
843
- file->decrypted ? "true" : "false",
844
- file->mimetype,
845
- file->created,
846
- file->filename);
847
- }
848
-
849
- cleanup:
850
- json_object_put(req->response);
851
- storj_free_list_files_request(req);
852
- free(work_req);
853
- exit(ret_status);
854
- }
855
-
856
- static void delete_file_callback(uv_work_t *work_req, int status)
857
- {
858
- assert(status == 0);
859
- json_request_t *req = work_req->data;
860
-
861
- if (req->status_code == 200 || req->status_code == 204) {
862
- printf("File was successfully removed from bucket.\n");
863
- } else if (req->status_code == 401) {
864
- printf("Invalid user credentials.\n");
865
- } else {
866
- printf("Failed to remove file from bucket. (%i)\n", req->status_code);
867
- }
868
-
869
- json_object_put(req->response);
870
- free(req->path);
871
- free(req);
872
- free(work_req);
873
- }
874
-
875
- static void delete_bucket_callback(uv_work_t *work_req, int status)
876
- {
877
- assert(status == 0);
878
- json_request_t *req = work_req->data;
879
-
880
- if (req->status_code == 200 || req->status_code == 204) {
881
- printf("Bucket was successfully removed.\n");
882
- } else if (req->status_code == 401) {
883
- printf("Invalid user credentials.\n");
884
- } else {
885
- printf("Failed to destroy bucket. (%i)\n", req->status_code);
886
- }
887
-
888
- json_object_put(req->response);
889
- free(req->path);
890
- free(req);
891
- free(work_req);
892
- }
893
-
894
- static void get_buckets_callback(uv_work_t *work_req, int status)
895
- {
896
- assert(status == 0);
897
- get_buckets_request_t *req = work_req->data;
898
-
899
- if (req->status_code == 401) {
900
- printf("Invalid user credentials.\n");
901
- } else if (req->status_code != 200 && req->status_code != 304) {
902
- printf("Request failed with status code: %i\n", req->status_code);
903
- } else if (req->total_buckets == 0) {
904
- printf("No buckets.\n");
905
- }
906
-
907
- for (int i = 0; i < req->total_buckets; i++) {
908
- storj_bucket_meta_t *bucket = &req->buckets[i];
909
- printf("ID: %s \tDecrypted: %s \tCreated: %s \tName: %s\n",
910
- bucket->id, bucket->decrypted ? "true" : "false",
911
- bucket->created, bucket->name);
912
- }
913
-
914
- json_object_put(req->response);
915
- storj_free_get_buckets_request(req);
916
- free(work_req);
917
- }
918
-
919
607
  static void create_bucket_callback(uv_work_t *work_req, int status)
920
608
  {
921
609
  assert(status == 0);
922
610
  create_bucket_request_t *req = work_req->data;
923
611
 
924
- if (req->status_code == 404) {
925
- printf("Cannot create bucket [%s]. Name already exists \n", req->bucket->name);
612
+ if (req->status_code == 409) {
613
+ printf("Cannot create bucket [%s]. Name already exists.\n", req->bucket->name);
926
614
  goto clean_variables;
927
615
  } else if (req->status_code == 401) {
928
616
  printf("Invalid user credentials.\n");
929
617
  goto clean_variables;
618
+ } else if (req->status_code == 403) {
619
+ printf("Forbidden, user not active.\n");
620
+ goto clean_variables;
930
621
  }
931
622
 
932
623
  if (req->status_code != 201) {
@@ -1047,6 +738,7 @@ clear_variables:
1047
738
  int main(int argc, char **argv)
1048
739
  {
1049
740
  int status = 0;
741
+ char temp_buff[256] = {};
1050
742
 
1051
743
  static struct option cmd_options[] = {
1052
744
  {"url", required_argument, 0, 'u'},
@@ -1055,6 +747,7 @@ int main(int argc, char **argv)
1055
747
  {"log", required_argument, 0, 'l'},
1056
748
  {"debug", no_argument, 0, 'd'},
1057
749
  {"help", no_argument, 0, 'h'},
750
+ {"recursive", required_argument, 0, 'r'},
1058
751
  {0, 0, 0, 0}
1059
752
  };
1060
753
 
@@ -1073,10 +766,11 @@ int main(int argc, char **argv)
1073
766
  char *storj_bridge = getenv("STORJ_BRIDGE");
1074
767
  int c;
1075
768
  int log_level = 0;
769
+ char *local_file_path = NULL;
1076
770
 
1077
771
  char *proxy = getenv("STORJ_PROXY");
1078
772
 
1079
- while ((c = getopt_long_only(argc, argv, "hdl:p:vVu:",
773
+ while ((c = getopt_long_only(argc, argv, "hdl:p:vVu:r:R:",
1080
774
  cmd_options, &index)) != -1) {
1081
775
  switch (c) {
1082
776
  case 'u':
@@ -1096,10 +790,18 @@ int main(int argc, char **argv)
1096
790
  printf(CLI_VERSION "\n\n");
1097
791
  exit(0);
1098
792
  break;
793
+ case 'R':
794
+ case 'r':
795
+ local_file_path = optarg;
796
+ break;
1099
797
  case 'h':
1100
798
  printf(HELP_TEXT);
1101
799
  exit(0);
1102
800
  break;
801
+ default:
802
+ exit(0);
803
+ break;
804
+
1103
805
  }
1104
806
  }
1105
807
 
@@ -1172,6 +874,7 @@ int main(int argc, char **argv)
1172
874
  char *user = NULL;
1173
875
  char *pass = NULL;
1174
876
  char *mnemonic = NULL;
877
+ cli_api_t *cli_api = NULL;
1175
878
 
1176
879
  if (strcmp(command, "get-info") == 0) {
1177
880
  printf("Storj bridge: %s\n\n", storj_bridge);
@@ -1191,7 +894,7 @@ int main(int argc, char **argv)
1191
894
 
1192
895
  storj_bridge_get_info(env, NULL, get_info_callback);
1193
896
 
1194
- } else if(strcmp(command, "register") == 0) {
897
+ } else if (strcmp(command, "register") == 0) {
1195
898
  storj_bridge_options_t options = {
1196
899
  .proto = proto,
1197
900
  .host = host,
@@ -1303,7 +1006,6 @@ int main(int argc, char **argv)
1303
1006
  } else if (file_mnemonic) {
1304
1007
  free(file_mnemonic);
1305
1008
  }
1306
-
1307
1009
  }
1308
1010
 
1309
1011
  // Third, ask for authentication
@@ -1369,6 +1071,28 @@ int main(int argc, char **argv)
1369
1071
  goto end_program;
1370
1072
  }
1371
1073
 
1074
+ cli_api = malloc(sizeof(cli_api_t));
1075
+
1076
+ if (!cli_api) {
1077
+ status = 1;
1078
+ goto end_program;
1079
+ }
1080
+ memset(cli_api, 0x00, sizeof(*cli_api));
1081
+
1082
+ cli_api->env = env;
1083
+
1084
+ #ifdef debug_enable
1085
+ printf("command = %s; command_index = %d\n", command, command_index);
1086
+ printf("local_file_path (req arg_ = %s\n", local_file_path);
1087
+ for (int i = 0x00; i < argc; i++) {
1088
+ printf("argc = %d; argv[%d] = %s\n", argc, i, argv[i]);
1089
+ }
1090
+
1091
+ for (int i = 0x00; i < (argc - command_index); i++) {
1092
+ printf("argc = %d; argv[command_index+%d] = %s\n", argc, i, argv[command_index + i]);
1093
+ }
1094
+ #endif
1095
+
1372
1096
  if (strcmp(command, "download-file") == 0) {
1373
1097
  char *bucket_id = argv[command_index + 1];
1374
1098
  char *file_id = argv[command_index + 2];
@@ -1380,7 +1104,11 @@ int main(int argc, char **argv)
1380
1104
  goto end_program;
1381
1105
  }
1382
1106
 
1383
- if (download_file(env, bucket_id, file_id, path)) {
1107
+ memcpy(cli_api->bucket_id, bucket_id, strlen(bucket_id));
1108
+ memcpy(cli_api->file_id, file_id, strlen(file_id));
1109
+ cli_api->dst_file = path;
1110
+
1111
+ if (download_file(env, bucket_id, file_id, path, cli_api)) {
1384
1112
  status = 1;
1385
1113
  goto end_program;
1386
1114
  }
@@ -1394,7 +1122,10 @@ int main(int argc, char **argv)
1394
1122
  goto end_program;
1395
1123
  }
1396
1124
 
1397
- if (upload_file(env, bucket_id, path)) {
1125
+ memcpy(cli_api->bucket_id, bucket_id, strlen(bucket_id));
1126
+ cli_api->dst_file = path;
1127
+
1128
+ if (upload_file(env, bucket_id, path, cli_api)) {
1398
1129
  status = 1;
1399
1130
  goto end_program;
1400
1131
  }
@@ -1407,8 +1138,8 @@ int main(int argc, char **argv)
1407
1138
  goto end_program;
1408
1139
  }
1409
1140
 
1410
- storj_bridge_list_files(env, bucket_id, NULL, list_files_callback);
1411
- } else if (strcmp(command, "add-bucket") == 0) {
1141
+ storj_bridge_list_files(env, bucket_id, cli_api, list_files_callback);
1142
+ } else if ((strcmp(command, "add-bucket") == 0) || (strcmp(command, "mkbkt") == 0x00)) {
1412
1143
  char *bucket_name = argv[command_index + 1];
1413
1144
 
1414
1145
  if (!bucket_name) {
@@ -1429,7 +1160,7 @@ int main(int argc, char **argv)
1429
1160
  goto end_program;
1430
1161
  }
1431
1162
 
1432
- storj_bridge_delete_bucket(env, bucket_id, NULL,
1163
+ storj_bridge_delete_bucket(env, bucket_id, cli_api,
1433
1164
  delete_bucket_callback);
1434
1165
 
1435
1166
  } else if (strcmp(command, "remove-file") == 0) {
@@ -1442,7 +1173,7 @@ int main(int argc, char **argv)
1442
1173
  goto end_program;
1443
1174
  }
1444
1175
  storj_bridge_delete_file(env, bucket_id, file_id,
1445
- NULL, delete_file_callback);
1176
+ cli_api, delete_file_callback);
1446
1177
 
1447
1178
  } else if (strcmp(command, "list-buckets") == 0) {
1448
1179
  storj_bridge_get_buckets(env, NULL, get_buckets_callback);
@@ -1456,7 +1187,355 @@ int main(int argc, char **argv)
1456
1187
  goto end_program;
1457
1188
  }
1458
1189
  storj_bridge_list_mirrors(env, bucket_id, file_id,
1459
- NULL, list_mirrors_callback);
1190
+ cli_api, list_mirrors_callback);
1191
+ } else if (strcmp(command, "cp") == 0) {
1192
+ #define UPLOAD_CMD 0x00
1193
+ #define DOWNLOAD_CMD 0x01
1194
+ #define RECURSIVE_CMD 0x02
1195
+ #define NON_RECURSIVE_CMD 0x03
1196
+
1197
+ int ret = 0x00;
1198
+ char *src_path = NULL; /* holds the local path */
1199
+ char *dst_path = NULL; /* holds the storj:// path */
1200
+ char *bucket_name = NULL;
1201
+ int cmd_type = 0x00; /* 0-> upload and 1 -> download */
1202
+ char modified_src_path[256] = {}; /* use this buffer to store the loca-file-path, if modified */
1203
+ memset(modified_src_path, 0x00, sizeof(modified_src_path));
1204
+ char *upload_file_path = modified_src_path;
1205
+
1206
+ /* cp command wrt to upload-file */
1207
+ if (local_file_path == NULL) {/* without -r[R] */
1208
+ /* hold the local path */
1209
+ src_path = argv[command_index + 0x01];
1210
+
1211
+ /* Handle the dst argument (storj://<bucket-name>/ */
1212
+ dst_path = argv[argc - 0x01];
1213
+
1214
+ cmd_type = NON_RECURSIVE_CMD;
1215
+ } else { /* with -r[R] */
1216
+ if ((strcmp(argv[1],"-r") == 0x00) || (strcmp(argv[1],"-R") == 0x00)) {
1217
+ src_path = local_file_path;
1218
+
1219
+ /* Handle the dst argument (storj://<bucket-name>/ */
1220
+ dst_path = argv[argc - 0x01];
1221
+
1222
+ cmd_type = RECURSIVE_CMD;
1223
+ } else {
1224
+ printf("[%s][%d] Invalid command option '%s'\n",
1225
+ __FUNCTION__, __LINE__, argv[1]);
1226
+ goto end_program;
1227
+ }
1228
+ }
1229
+
1230
+ if ((strcmp(src_path, argv[command_index]) == 0x00) ||
1231
+ (strcmp(dst_path, argv[command_index]) == 0x00) ||
1232
+ (strcmp(dst_path, src_path) == 0x00)) {
1233
+ printf("[%s][%d] Invalid command option '%s'\n",
1234
+ __FUNCTION__, __LINE__, argv[1]);
1235
+ goto end_program;
1236
+ }
1237
+
1238
+ /* check for upload or download command */
1239
+ char sub_str[] = "storj://";
1240
+ ret = strpos(dst_path, sub_str);
1241
+
1242
+ if (ret == 0x00) { /* Handle upload command*/
1243
+ if (cmd_type == NON_RECURSIVE_CMD) {
1244
+ if (check_file_path(src_path) != CLI_VALID_DIR) {
1245
+ local_file_path = src_path;
1246
+
1247
+ bucket_name = dst_path;
1248
+ } else {
1249
+ printf("[%s][%d] Invalid command entry\n",
1250
+ __FUNCTION__, __LINE__);
1251
+ goto end_program;
1252
+ }
1253
+ } else if (cmd_type == RECURSIVE_CMD) {
1254
+ local_file_path = src_path;
1255
+
1256
+ bucket_name = dst_path;
1257
+ } else {
1258
+ printf("[%s][%d] Invalid command entry \n", __FUNCTION__, __LINE__);
1259
+ goto end_program;
1260
+ }
1261
+
1262
+ cmd_type = UPLOAD_CMD;
1263
+ } else if (ret == -1) { /* Handle download command*/
1264
+ ret = strpos(src_path, sub_str);
1265
+
1266
+ if (ret == 0x00) {
1267
+ if ((cmd_type == NON_RECURSIVE_CMD) || (cmd_type == RECURSIVE_CMD)) {
1268
+ local_file_path = dst_path;
1269
+ bucket_name = src_path;
1270
+
1271
+ char *dst_file_name = NULL;
1272
+ dst_file_name = (char *)get_filename_separator(local_file_path);
1273
+
1274
+ /* token[0]-> storj:; token[1]->bucket_name; token[2]->upload_file_name */
1275
+ char *token[0x03];
1276
+ memset(token, 0x00, sizeof(token));
1277
+ int num_of_tokens = validate_cmd_tokenize(bucket_name, token);
1278
+
1279
+ /* set the bucket name from which file(s) to be downloaded */
1280
+ cli_api->bucket_name = token[1];
1281
+
1282
+ /* initialize the local folder to copy the downloaded file into */
1283
+ cli_api->file_path = local_file_path;
1284
+
1285
+ /* initialize the filename to be downloaded as */
1286
+ cli_api->dst_file = dst_file_name;
1287
+
1288
+ if ((argc == 0x04) || (argc == 0x05)) { /* handle non recursive operations */
1289
+ if ((token[2] == NULL) || (strcmp(token[2], "*") == 0x00)) {
1290
+ if (check_file_path(local_file_path) == CLI_VALID_DIR) {
1291
+ cli_download_files(cli_api);
1292
+ } else {
1293
+ printf("[%s][%d] Invalid '%s' dst directory !!!!!\n",
1294
+ __FUNCTION__, __LINE__, local_file_path);
1295
+ goto end_program;
1296
+ }
1297
+ } else if (token[2] != NULL) {
1298
+ /* set the file to be downloaded */
1299
+ cli_api->file_name = token[2];
1300
+
1301
+ if ((check_file_path(local_file_path) == CLI_VALID_DIR) || (strcmp(dst_file_name, ".") == 0x00)) {
1302
+ memset(temp_buff, 0x00, sizeof(temp_buff));
1303
+ strcat(temp_buff, local_file_path);
1304
+ strcat(temp_buff, "/");
1305
+ strcat(temp_buff, token[2]);
1306
+ cli_api->dst_file = temp_buff;
1307
+ } else if (strlen(dst_file_name) > 0x00) {
1308
+ cli_api->dst_file = local_file_path;
1309
+ } else {
1310
+ printf("[%s][%d] Invalid '%s' dst directory !!!!!\n",
1311
+ __FUNCTION__, __LINE__, local_file_path);
1312
+ goto end_program;
1313
+ }
1314
+ printf("[%s][%d]file %s downloaded from bucketname = %s as file %s\n",
1315
+ __FUNCTION__, __LINE__, cli_api->file_name, cli_api->bucket_name, cli_api->dst_file);
1316
+ cli_download_file(cli_api);
1317
+ } else {
1318
+ printf("[%s][%d] Invalid '%s' dst directory !!!!!\n",
1319
+ __FUNCTION__, __LINE__, local_file_path);
1320
+ goto end_program;
1321
+ }
1322
+ } else {
1323
+ /* more args then needed wrong command */
1324
+ printf("[%s][%d] Valid dst filename missing !!!!!\n", __FUNCTION__, __LINE__);
1325
+ goto end_program;
1326
+ }
1327
+ } else {
1328
+ printf("[%s][%d] Invalid command entry \n", __FUNCTION__, __LINE__);
1329
+ goto end_program;
1330
+ }
1331
+ } else {
1332
+ printf("[%s][%d]Invalid Command Entry (%d) \n",
1333
+ __FUNCTION__, __LINE__, ret);
1334
+ goto end_program;
1335
+ }
1336
+ } else {
1337
+ printf("[%s][%d]Invalid Command Entry (%d) \n",
1338
+ __FUNCTION__, __LINE__, ret);
1339
+ goto end_program;
1340
+ }
1341
+
1342
+ if (cmd_type == UPLOAD_CMD) {
1343
+ /* handling single file copy with -r[R]: ./storj cp -r /home/kishore/libstorj/src/xxx.y storj://testbucket/yyy.x */
1344
+ /* Handle the src argument */
1345
+ /* single file to copy, make sure the files exits */
1346
+ if ((argc == 0x05) && (check_file_path(local_file_path) == CLI_VALID_REGULAR_FILE)) {
1347
+ cli_api->file_name = local_file_path;
1348
+
1349
+ /* Handle the dst argument (storj://<bucket-name>/<file-name> */
1350
+ /* token[0]-> storj:; token[1]->bucket_name; token[2]->upload_file_name */
1351
+ char *token[0x03];
1352
+ memset(token,0x00, sizeof(token));
1353
+ int num_of_tokens = validate_cmd_tokenize(bucket_name, token);
1354
+
1355
+ if ((num_of_tokens == 0x02) || (num_of_tokens == 0x03)) {
1356
+ char *dst_file_name = NULL;
1357
+
1358
+ cli_api->bucket_name = token[1];
1359
+ dst_file_name = (char *)get_filename_separator(local_file_path);
1360
+
1361
+ if ((token[2] == NULL) || (strcmp(dst_file_name, token[2]) == 0x00) ||
1362
+ (strcmp(token[2], ".") == 0x00)) {
1363
+ /* use the src list buff as temp memory to hold the dst filename */
1364
+ memset(cli_api->src_list, 0x00, sizeof(cli_api->src_list));
1365
+ strcpy(cli_api->src_list, dst_file_name);
1366
+ cli_api->dst_file = cli_api->src_list;
1367
+ } else {
1368
+ cli_api->dst_file = token[2];
1369
+ }
1370
+ cli_upload_file(cli_api);
1371
+ } else {
1372
+ printf("[%s][%d] Valid dst filename missing !!!!!\n", __FUNCTION__, __LINE__);
1373
+ goto end_program;
1374
+ }
1375
+ }
1376
+ else {
1377
+ /* directory is being used, store it in file_path */
1378
+ cli_api->file_path = local_file_path;
1379
+
1380
+ /* Handle wild character options for files selection */
1381
+ if (check_file_path(local_file_path) != CLI_VALID_DIR) {
1382
+ char pwd_path[256] = { };
1383
+ memset(pwd_path, 0x00, sizeof(pwd_path));
1384
+ char *upload_list_file = pwd_path;
1385
+
1386
+ /* create "/tmp/STORJ_upload_list_file.txt" upload files list based on the file path */
1387
+ if ((upload_list_file = getenv("TMPDIR")) != NULL) {
1388
+ if (upload_list_file[(strlen(upload_list_file) - 1)] == '/') {
1389
+ strcat(upload_list_file, "STORJ_output_list.txt");
1390
+ } else {
1391
+ strcat(upload_list_file, "/STORJ_output_list.txt");
1392
+ }
1393
+
1394
+ /* check the directory and create the path to upload list file */
1395
+ memset(cli_api->src_list, 0x00, sizeof(cli_api->src_list));
1396
+ memcpy(cli_api->src_list, upload_list_file, sizeof(pwd_path));
1397
+ cli_api->dst_file = cli_api->src_list;
1398
+ } else {
1399
+ printf("[%s][%d] Upload list file generation error!!! \n",
1400
+ __FUNCTION__, __LINE__);
1401
+ goto end_program;
1402
+ }
1403
+
1404
+ /* if local file path is a file, then just get the directory
1405
+ from that */
1406
+ char *ret = NULL;
1407
+ ret = strrchr(local_file_path, '/');
1408
+ memset(temp_buff, 0x00, sizeof(temp_buff));
1409
+ memcpy(temp_buff, local_file_path, ((ret - local_file_path)+1));
1410
+
1411
+ FILE *file = NULL;
1412
+ /* create the file and add the list of files to be uploaded */
1413
+ if ((file = fopen(cli_api->src_list, "w")) != NULL) {
1414
+ if ((strcmp(argv[1],"-r") == 0x00) || (strcmp(argv[1],"-R") == 0x00)) {
1415
+ fprintf(file, "%s\n", local_file_path);
1416
+ }
1417
+
1418
+ for (int i = 0x01; i < ((argc - command_index) - 1); i++) {
1419
+ fprintf(file, "%s\n", argv[command_index + i]);
1420
+ }
1421
+ } else {
1422
+ printf("[%s][%d] Invalid upload src path entered\n", __FUNCTION__, __LINE__);
1423
+ goto end_program;
1424
+ }
1425
+ fclose(file);
1426
+
1427
+ cli_api->file_path = temp_buff;
1428
+ } else {
1429
+ /* its a valid directory so let the list of files to be uploaded be handled in
1430
+ verify upload file () */
1431
+ cli_api->dst_file = NULL;
1432
+
1433
+ memcpy(upload_file_path, cli_api->file_path, strlen(cli_api->file_path));
1434
+ if (upload_file_path[(strlen(upload_file_path) - 1)] != '/') {
1435
+ strcat(upload_file_path, "/");
1436
+ cli_api->file_path = upload_file_path;
1437
+ }
1438
+ }
1439
+
1440
+ /* token[0]-> storj:; token[1]->bucket_name; token[2]->upload_file_name */
1441
+ char *token[0x03];
1442
+ memset(token, 0x00, sizeof(token));
1443
+ int num_of_tokens = validate_cmd_tokenize(bucket_name, token);
1444
+
1445
+ if ((num_of_tokens > 0x00) && ((num_of_tokens >= 0x02) || (num_of_tokens <= 0x03))) {
1446
+ char *dst_file_name = NULL;
1447
+
1448
+ cli_api->bucket_name = token[1];
1449
+
1450
+ if ((token[2] == NULL) ||
1451
+ (strcmp(token[2], ".") == 0x00)) {
1452
+ cli_upload_files(cli_api);
1453
+ } else {
1454
+ printf("[%s][%d] storj://<bucket-name>; storj://<bucket-name>/ storj://<bucket-name>/. !!!!!\n", __FUNCTION__, __LINE__);
1455
+ goto end_program;
1456
+ }
1457
+ } else {
1458
+ printf("[%s][%d] Valid dst filename missing !!!!!\n", __FUNCTION__, __LINE__);
1459
+ goto end_program;
1460
+ }
1461
+ }
1462
+ }
1463
+ } else if (strcmp(command, "upload-files") == 0) {
1464
+ /* get the corresponding bucket id from the bucket name */
1465
+ cli_api->bucket_name = argv[command_index + 1];
1466
+ cli_api->file_path = argv[command_index + 2];
1467
+ cli_api->dst_file = NULL;
1468
+
1469
+ if (!cli_api->bucket_name || !cli_api->file_name) {
1470
+ printf("Missing arguments: <bucket-name> <path>\n");
1471
+ status = 1;
1472
+ goto end_program;
1473
+ }
1474
+
1475
+ cli_upload_files(cli_api);
1476
+ } else if (strcmp(command, "download-files") == 0) {
1477
+ /* get the corresponding bucket id from the bucket name */
1478
+ cli_api->bucket_name = argv[command_index + 1];
1479
+ cli_api->file_path = argv[command_index + 2];
1480
+
1481
+ if (!cli_api->bucket_name || !cli_api->file_path) {
1482
+ printf("Missing arguments: <bucket-name> <path>\n");
1483
+ status = 1;
1484
+ goto end_program;
1485
+ }
1486
+
1487
+ cli_download_files(cli_api);
1488
+ } else if (strcmp(command, "mkbkt") == 0x00) {
1489
+ char *bucket_name = argv[command_index + 1];
1490
+
1491
+ if (!bucket_name) {
1492
+ printf("Missing first argument: <bucket-name>\n");
1493
+ status = 1;
1494
+ goto end_program;
1495
+ }
1496
+
1497
+ storj_bridge_create_bucket(env, bucket_name,
1498
+ NULL, create_bucket_callback);
1499
+ } else if (strcmp(command, "rm") == 0) {
1500
+ cli_api->bucket_name = argv[command_index + 1];
1501
+ cli_api->file_name = argv[command_index + 2];
1502
+
1503
+ if (cli_api->file_name != NULL) {
1504
+ if (!cli_api->bucket_name|| !cli_api->file_name) {
1505
+ printf("Missing arguments, expected: <bucket-name> <file-name>\n");
1506
+ status = 1;
1507
+ goto end_program;
1508
+ }
1509
+
1510
+ cli_remove_file(cli_api);
1511
+ }
1512
+ else {
1513
+ cli_remove_bucket(cli_api);
1514
+ }
1515
+ } else if (strcmp(command, "ls") == 0x00) {
1516
+ if (argv[command_index + 1] != NULL) {
1517
+ /* bucket-name , used to list files */
1518
+ cli_api->bucket_name = argv[command_index + 1];
1519
+
1520
+ cli_list_files(cli_api);
1521
+ }
1522
+ else {
1523
+ cli_list_buckets(cli_api);
1524
+ }
1525
+ } else if (strcmp(command, "get-bucket-id") == 0) {
1526
+ cli_api->bucket_name = argv[command_index + 1];
1527
+ cli_get_bucket_id(cli_api);
1528
+ } else if (strcmp(command, "lm") == 0) {
1529
+ cli_api->bucket_name = argv[command_index + 1];
1530
+ cli_api->file_name = argv[command_index + 2];
1531
+
1532
+ if (!cli_api->bucket_name|| !cli_api->file_name) {
1533
+ printf("Missing arguments, expected: <bucket-name> <file-name>\n");
1534
+ status = 1;
1535
+ goto end_program;
1536
+ }
1537
+
1538
+ cli_list_mirrors(cli_api);
1460
1539
  } else {
1461
1540
  printf("'%s' is not a storj command. See 'storj --help'\n\n",
1462
1541
  command);
@@ -1490,5 +1569,9 @@ end_program:
1490
1569
  if (mnemonic) {
1491
1570
  free(mnemonic);
1492
1571
  }
1572
+ if (cli_api){
1573
+ free(cli_api);
1574
+ }
1575
+
1493
1576
  return status;
1494
1577
  }