aboutsummarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api.c46
-rw-r--r--api.h5
-rw-r--r--main.c61
-rw-r--r--portfolio.c300
-rw-r--r--portfolio.h41
-rw-r--r--rc4.c72
-rw-r--r--rc4.h20
-rw-r--r--string-tick.c8
-rw-r--r--string-tick.h4
9 files changed, 252 insertions, 305 deletions
diff --git a/api.c b/api.c
index 6bc28cbc1eae..236864f149b7 100644
--- a/api.c
+++ b/api.c
@@ -38,7 +38,7 @@ size_t api_string_writefunc(void* ptr, size_t size, size_t nmemb, String* hStrin
}
String* api_curl_data(char* url, char* post_field) {
- String* pString = api_string_init();
+ String* pString = string_init();
if (pString == NULL)
return NULL;
CURL* curl = curl_easy_init();
@@ -89,7 +89,7 @@ double* iex_get_price(const char* ticker_name_string) {
sprintf(iex_api_string, "https://api.iextrading.com/1.0/stock/%s/quote", ticker_name_string);
String* pString = api_curl_data(iex_api_string, NULL);
if (strcmp(pString->data, "Unknown symbol") == 0) { //Invalid symbol
- api_string_destroy(&pString);
+ string_destroy(&pString);
return NULL;
}
Json* jobj = json_tokener_parse(pString->data);
@@ -102,7 +102,7 @@ double* iex_get_price(const char* ticker_name_string) {
const char* close_price_string = json_object_to_json_string(json_object_object_get(jobj, "previousClose"));
ret[0] = strtod(price_string, NULL); //Intraday current price
ret[1] = strtod(close_price_string, NULL); //Previous day's close price
- api_string_destroy(&pString);
+ string_destroy(&pString);
json_object_put(jobj);
return ret;
}
@@ -122,7 +122,7 @@ double* morningstar_get_price(const char* ticker_name_string) {
ticker_name_string, yesterday_char, today_char);
String* pString = api_curl_data(morningstar_api_string, NULL);
if (strcmp("null", pString->data) == 0) { //Invalid symbol
- api_string_destroy(&pString);
+ string_destroy(&pString);
return NULL;
}
Json* jobj = json_tokener_parse(pString->data);
@@ -141,7 +141,7 @@ double* morningstar_get_price(const char* ticker_name_string) {
price = json_object_to_json_string(yesterday);
ret[1] = strtod(price, NULL); //Close price before last close price
json_object_put(jobj);
- api_string_destroy(&pString);
+ string_destroy(&pString);
return ret;
}
@@ -150,7 +150,7 @@ double* coinmarketcap_get_price(const char* ticker_name_string) {
sprintf(coinmarketcap_api_string, "https://api.coinmarketcap.com/v1/ticker/%s", ticker_name_string);
String* pString = api_curl_data(coinmarketcap_api_string, NULL);
if (pString->data[0] == '{') { //Invalid symbol
- api_string_destroy(&pString);
+ string_destroy(&pString);
return NULL;
}
Json* jobj = json_tokener_parse(pString->data);
@@ -166,7 +166,7 @@ double* coinmarketcap_get_price(const char* ticker_name_string) {
}
ret[0] = strtod(price, NULL); //Current real-time price
ret[1] = ret[0] - ((strtod(change_1d, NULL) / 100) * ret[0]); //Price 24 hours earlier
- api_string_destroy(&pString);
+ string_destroy(&pString);
json_object_put(jobj);
return ret;
}
@@ -190,7 +190,7 @@ void news_print_top_three(const char* ticker_name_string) {
mktime(ts);
strftime(yearchar, 16, "%Y-%m-%d", ts);
sprintf(news_api_string,
- "https://newsapi.org/v2/everything?sortBy=relevancy&pageSize=3&language=en&apiKey=1163c352d041460381f0a8273e60a9d1&from=%s&q=%s",
+ "https://newsapi.org/v2/everything?sortBy=popularity&pageSize=3&language=en&apiKey=1163c352d041460381f0a8273e60a9d1&from=%s&q=%s",
yearchar, url_encoded_string);
free(url_encoded_string);
String* pString = api_curl_data(news_api_string, NULL);
@@ -199,7 +199,7 @@ void news_print_top_three(const char* ticker_name_string) {
10) > 0)
json_print_news(jobj);
else printf("No articles. Try a different input.\n");
- api_string_destroy(&pString);
+ string_destroy(&pString);
json_object_put(jobj);
}
@@ -269,7 +269,7 @@ Info* iex_get_info(const char* ticker_name_string) {
sprintf(iex_api_string, "https://api.iextrading.com/1.0/stock/%s/quote", ticker_name_string);
String* pString = api_curl_data(iex_api_string, NULL); // API CALL 1 -- name, symbol, price, mcap, volume
if (strcmp(pString->data, "Unknown symbol") == 0) { //Invalid symbol
- api_string_destroy(&pString);
+ string_destroy(&pString);
return NULL;
}
Info* ticker_info = api_info_init();
@@ -280,18 +280,22 @@ Info* iex_get_info(const char* ticker_name_string) {
ticker_info->marketcap = json_object_get_int64(json_object_object_get(jobj, "marketCap"));
ticker_info->volume_1d = json_object_get_int64(json_object_object_get(jobj, "latestVolume"));
json_object_put(jobj);
- api_string_destroy(&pString);
+ string_destroy(&pString);
sprintf(iex_api_string, "https://api.iextrading.com/1.0/stock/%s/stats/dividendYield", ticker_name_string);
pString = api_curl_data(iex_api_string, NULL); // API CALL 2 -- dividend
if (strcmp("0", pString->data) != 0)
ticker_info->div_yield = strtod(pString->data, NULL);
- api_string_destroy(&pString);
+ string_destroy(&pString);
sprintf(iex_api_string, "https://api.iextrading.com/1.0/stock/%s/chart", ticker_name_string);
pString = api_curl_data(iex_api_string, NULL); // API CALL 3 -- historical
jobj = json_tokener_parse(pString->data);
- Json* d_30 = json_object_array_get_idx(jobj, 0);
- Json* d_7 = json_object_array_get_idx(jobj, json_object_array_length(jobj) - 6);
- Json* d_1 = json_object_array_get_idx(jobj, json_object_array_length(jobj) - 2);
+ time_t now = time(NULL);
+ struct tm* ts = localtime(&now);
+ mktime(ts);
+ int after_close = ts->tm_hour > 16 && ts->tm_wday != 0 && ts->tm_wday != 6;
+ Json* d_30 = json_object_array_get_idx(jobj, (size_t)after_close);
+ Json* d_7 = json_object_array_get_idx(jobj, json_object_array_length(jobj) - 6 + after_close);
+ Json* d_1 = json_object_array_get_idx(jobj, json_object_array_length(jobj) - 2 + after_close);
ticker_info->change_30d = 100 / ticker_info->price *
(ticker_info->price - json_object_get_double(json_object_object_get(d_30, "close")));
ticker_info->change_7d = 100 / ticker_info->price *
@@ -299,7 +303,7 @@ Info* iex_get_info(const char* ticker_name_string) {
ticker_info->change_1d = 100 / ticker_info->price *
(ticker_info->price - json_object_get_double(json_object_object_get(d_1, "close")));
json_object_put(jobj);
- api_string_destroy(&pString);
+ string_destroy(&pString);
return ticker_info;
}
@@ -318,7 +322,7 @@ Info* morningstar_get_info(const char* ticker_name_string) {
ticker_name_string, yesterday_char, today_char);
String* pString = api_curl_data(morningstar_api_string, NULL);
if (strcmp("null", pString->data) == 0) { //Invalid symbol
- api_string_destroy(&pString);
+ string_destroy(&pString);
return NULL;
}
Info* ticker_info = api_info_init();
@@ -341,7 +345,7 @@ Info* morningstar_get_info(const char* ticker_name_string) {
ticker_info->volume_1d = (long) (1000000 * json_object_get_double( // Data listed in millions
json_object_array_get_idx(json_object_object_get(vol, "Datapoints"), days - 1)));
json_object_put(jobj);
- api_string_destroy(&pString);
+ string_destroy(&pString);
return ticker_info;
}
@@ -350,7 +354,7 @@ Info* coinmarketcap_get_info(const char* ticker_name_string) {
sprintf(coinmarketcap_api_string, "https://api.coinmarketcap.com/v1/ticker/%s", ticker_name_string);
String* pString = api_curl_data(coinmarketcap_api_string, NULL);
if (pString->data[0] == '{') { //Invalid symbol
- api_string_destroy(&pString);
+ string_destroy(&pString);
return NULL;
}
Info* ticker_info = api_info_init();
@@ -364,7 +368,7 @@ Info* coinmarketcap_get_info(const char* ticker_name_string) {
ticker_info->marketcap = strtol(json_object_get_string(json_object_object_get(data, "market_cap_usd")), NULL, 10);
ticker_info->volume_1d = strtol(json_object_get_string(json_object_object_get(data, "24h_volume_usd")), NULL, 10);
json_object_put(jobj);
- api_string_destroy(&pString);
+ string_destroy(&pString);
return ticker_info;
}
@@ -383,7 +387,7 @@ char* google_shorten_link(const char* url_string) {
strip_char(short_url, '\\');
strip_char(short_url, '\"');
json_object_put(jobj);
- api_string_destroy(&pString);
+ string_destroy(&pString);
return short_url;
}
diff --git a/api.h b/api.h
index 0d059365035a..a7f5ffc834d9 100644
--- a/api.h
+++ b/api.h
@@ -11,9 +11,6 @@
#define EMPTY (-999)
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <stddef.h>
#include <curl/curl.h>
#include <json-c/json_tokener.h>
@@ -31,8 +28,6 @@ struct info {
typedef struct info Info;
-typedef struct json_object Json;
-
/**
* Creates and returns an Info object
* @return Info object
diff --git a/main.c b/main.c
index b075b7ebefbb..174b8c19b73b 100644
--- a/main.c
+++ b/main.c
@@ -10,14 +10,8 @@ int main(int argc, char* argv[]) {
strcpy(cmd, argv[1]);
strtolower(cmd);
- // Init/open portfolio
+ // Init portfolio path
portfolio_file_init();
- FILE* fp = fopen(portfolio_file, "r+");
- if (fp == NULL) {
- printf("Could not open portfolio file\n");
- free(portfolio_file);
- return 0;
- }
// Portfolio modify operation
int modop = -1;
@@ -28,16 +22,40 @@ int main(int argc, char* argv[]) {
news_print_top_three(argv[2]);
else printf("Invalid symbol.\n");
}
- //Convert
- else if (strcmp(cmd, "convert") == 0 && argc == 2)
- portfolio_legacy_convert();
//Encrypt/decrypt
- else if (strcmp(cmd, "encrypt") == 0 && argc == 2)
- portfolio_encrypt_decrypt(ENCRYPT, fp, NULL);
- else if (strcmp(cmd, "decrypt") == 0 && argc == 2)
- portfolio_encrypt_decrypt(DECRYPT, fp, NULL);
-
+ else if (strcmp(cmd, "encrypt") == 0 && argc == 2) {
+ String* pString = portfolio_file_get_string();
+ if (pString == NULL){
+ free(portfolio_file);
+ return 0;
+ }
+ String* encrypted = rc4_get_crypted_string(pString, NULL, ENCRYPT);
+ if (encrypted == NULL){
+ string_destroy(&pString);
+ free(portfolio_file);
+ return 0;
+ }
+ string_write_portfolio(encrypted);
+ string_destroy(&pString);
+ string_destroy(&encrypted);
+ }
+ else if (strcmp(cmd, "decrypt") == 0 && argc == 2) {
+ String* pString = portfolio_file_get_string();
+ if (pString == NULL){
+ free(portfolio_file);
+ return 0;
+ }
+ String* decrypted = rc4_get_crypted_string(pString, NULL, DECRYPT);
+ if (decrypted == NULL){
+ string_destroy(&pString);
+ free(portfolio_file);
+ return 0;
+ }
+ string_write_portfolio(decrypted);
+ string_destroy(&pString);
+ string_destroy(&decrypted);
+ }
// Info
else if (strcmp(cmd, "info") == 0 && argc == 3) {
char sym[strlen(argv[2]) + 1];
@@ -49,15 +67,15 @@ int main(int argc, char* argv[]) {
// Check
else if (strcmp(cmd, "check") == 0) {
if (argc < 3) {
- portfolio_print_all(fp);
+ portfolio_print_all();
} else {
char sym[strlen(argv[2]) + 1];
strcpy(sym, argv[2]);
strtoupper(sym);
if (strcmp(sym, "ALL") == 0)
- portfolio_print_all(fp);
+ portfolio_print_all();
else {
- double* data = portfolio_print_stock(sym, fp, NULL);
+ double* data = portfolio_print_stock(sym, NULL);
if (data != NULL)
free(data);
}
@@ -108,13 +126,13 @@ int main(int argc, char* argv[]) {
switch (modop) {
case ADD:
- portfolio_modify(sym, qty, usd, fp, ADD);
+ portfolio_modify(sym, qty, usd, ADD);
break;
case REMOVE:
- portfolio_modify(sym, qty, usd, fp, REMOVE);
+ portfolio_modify(sym, qty, usd, REMOVE);
break;
case SET:
- portfolio_modify(sym, qty, usd, fp, SET);
+ portfolio_modify(sym, qty, usd, SET);
break;
default:
break;
@@ -122,6 +140,5 @@ int main(int argc, char* argv[]) {
}
}
free(portfolio_file);
- fclose(fp);
return 0;
} \ No newline at end of file
diff --git a/portfolio.c b/portfolio.c
index 4a36fc30a619..02ae948ed5d3 100644
--- a/portfolio.c
+++ b/portfolio.c
@@ -13,23 +13,30 @@ void portfolio_file_init(void) {
portfolio_file = path;
}
-char* portfolio_file_get_string(FILE* fp, size_t* len) {
- char* portfolio_string = calloc(65536, 1);
- if (portfolio_string == NULL) {
- fprintf(stderr, "calloc() failed\n");
+String* portfolio_file_get_string(void) {
+ FILE* fp = fopen(portfolio_file, "r");
+ if (fp == NULL)
+ return NULL;
+ String* pString = string_init();
+ pString->data = realloc(pString->data, 65536);
+ memset(pString->data, '\0', 65536);
+ if (pString->data == NULL) {
+ fprintf(stderr, "realloc() failed\n");
exit(EXIT_FAILURE);
}
fseek(fp, 0, SEEK_END);
- size_t portfolio_size = (size_t) ftell(fp);
- if (len != NULL)
- *len = portfolio_size;
+ pString->len = (size_t) ftell(fp);
fseek(fp, 0, SEEK_SET);
- if (fread(portfolio_string, sizeof(char), portfolio_size, fp) != portfolio_size)
+ if (fread(pString->data, sizeof(char), pString->len, fp) != pString->len) {
+ fclose(fp);
+ printf("Returning null\n");
return NULL;
- return portfolio_string;
+ }
+ fclose(fp);
+ return pString;
}
-void portfolio_modify(const char* ticker_name_string, double quantity_shares, double usd_spent, FILE* fp, int option) {
+void portfolio_modify(const char* ticker_name_string, double quantity_shares, double usd_spent, int option) {
if (quantity_shares < 0 || usd_spent < 0) { // Negative numbers
printf("You must use positive values.\n");
return;
@@ -38,24 +45,25 @@ void portfolio_modify(const char* ticker_name_string, double quantity_shares, do
printf("You cannot add or remove values of 0.\n");
return;
}
- size_t len;
- char* portfolio_string = portfolio_file_get_string(fp, &len);
+ String* pString = portfolio_file_get_string();
+ if (pString == NULL) {
+ printf("Error reading portfolio.\n");
+ return;
+ }
Json* jobj = NULL;
- if (len == 0) //new file
+ if (pString->len == 0) //new file
jobj = json_object_new_array();
- else jobj = json_tokener_parse(portfolio_string); //existing file
+ else jobj = json_tokener_parse(pString->data); //existing file
char* password = NULL;
if (jobj == NULL) { //ENCRYPTED PORTFOLIO
password = rc4_getPassword();
printf("Decrypting portfolio...\n");
- portfolio_encrypt_decrypt(DECRYPT, fp, password);
- fp = fopen(portfolio_file, "r+");
- free(portfolio_string);
- portfolio_string = portfolio_file_get_string(fp, NULL);
- json_object_put(jobj);
- jobj = json_tokener_parse(portfolio_string);
- if (jobj == NULL) {
- free(portfolio_string);
+ String* temp = rc4_get_crypted_string(pString, password, DECRYPT);
+ string_destroy(&pString);
+ pString = temp;
+ jobj = json_tokener_parse(pString->data);
+ if (pString == NULL) {
+ free(password);
return;
}
}
@@ -63,8 +71,10 @@ void portfolio_modify(const char* ticker_name_string, double quantity_shares, do
if (index == -1) { //if not already in portfolio
if (option == REMOVE) {
printf("You don't have any %s to remove.\n", ticker_name_string);
- free(portfolio_string);
json_object_put(jobj);
+ string_destroy(&pString);
+ if (password != NULL)
+ free(password);
return;
}
if (strcmp("USD$", ticker_name_string) != 0) {
@@ -72,7 +82,9 @@ void portfolio_modify(const char* ticker_name_string, double quantity_shares, do
if (data == NULL) {
printf("Invalid symbol.\n");
json_object_put(jobj);
- free(portfolio_string);
+ string_destroy(&pString);
+ if (password != NULL)
+ free(password);
return;
} else free(data);
}
@@ -104,7 +116,9 @@ void portfolio_modify(const char* ticker_name_string, double quantity_shares, do
if (current_shares < 0 || current_spent < 0) { // If you try to remove more than you have
printf("You do not have that many %s to remove.\n", ticker_name_string);
json_object_put(jobj);
- free(portfolio_string);
+ string_destroy(&pString);
+ if (password != NULL)
+ free(password);
return;
}
printf("Removed %lf %s bought for %lf to portfolio.\n", quantity_shares, ticker_name_string, usd_spent);
@@ -118,43 +132,42 @@ void portfolio_modify(const char* ticker_name_string, double quantity_shares, do
json_object_new_double(round(current_spent * 100) / 100));
}
}
- fp = fopen(portfolio_file, "w");
- fprintf(fp, "%s", json_object_to_json_string(jobj));
- if (password != NULL) { // If portfolio was decrypted, encrypt again
- fflush(fp);
- printf("Encrypting porfolio...\n");
- portfolio_encrypt_decrypt(ENCRYPT, fp, password);
+ if (password != NULL) { // If data must be re-encrypted
+ printf("Encrypting portfolio...\n");
+ strcpy(pString->data, json_object_to_json_string(jobj));
+ String* temp = rc4_get_crypted_string(pString, password, ENCRYPT);
+ string_destroy(&pString);
+ pString = temp;
free(password);
}
json_object_put(jobj);
- free(portfolio_string);
+ string_write_portfolio(pString);
+ string_destroy(&pString);
}
-void portfolio_print_all(FILE* fp) {
- char* portfolio_string = portfolio_file_get_string(fp, NULL);
+void portfolio_print_all(void) {
+ String* pString = portfolio_file_get_string();
+ if (pString == NULL)
+ return;
+ if (strcmp(pString->data, "") == 0) {
+ string_destroy(&pString);
+ return;
+ }
double* data, total_owned = 0, total_spent = 0, total_gain_1d = 0;
- Json* jobj = json_tokener_parse(portfolio_string);
+ Json* jobj = json_tokener_parse(pString->data);
char* password = NULL;
if (jobj == NULL) { //ENCRYPTED PORTFOLIO
password = rc4_getPassword();
printf("Decrypting portfolio...\n");
- portfolio_encrypt_decrypt(DECRYPT, fp, password);
- fp = fopen(portfolio_file, "r+");
- free(portfolio_string);
- portfolio_string = portfolio_file_get_string(fp, NULL);
- json_object_put(jobj);
- jobj = json_tokener_parse(portfolio_string);
- if (jobj == NULL) {
- free(portfolio_string);
- return;
- }
+ String* temp = rc4_get_crypted_string(pString, password, DECRYPT);
+ string_destroy(&pString);
+ pString = temp;
+ jobj = json_tokener_parse(pString->data);
}
- if (strcmp(portfolio_string, "") == 0)
- return;
int num_symbols = (int) json_object_array_length(jobj);
printf(" AMOUNT SYMBOL VALUE SPENT PROFIT (%%) 24H (%%)\n");
for (int i = 0; i < num_symbols; i++) {
- data = portfolio_print_stock(NULL, NULL, json_object_array_get_idx(jobj, (size_t) i));
+ data = portfolio_print_stock(NULL, json_object_array_get_idx(jobj, (size_t) i));
if (data != NULL) {
total_owned += data[0];
total_spent += data[1];
@@ -165,17 +178,13 @@ void portfolio_print_all(FILE* fp) {
printf("\n TOTALS %8.2lf %8.2lf %8.2lf (%6.2lf%%) %8.2lf (%6.2lf%%)\n",
total_owned, total_spent, total_owned - total_spent, (100 * (total_owned - total_spent)) / total_spent,
total_gain_1d, 100 * total_gain_1d / total_spent);
- if (password != NULL) { // If portfolio was decrypted, encrypt again
- fflush(fp);
- printf("Encrypting porfolio...\n");
- portfolio_encrypt_decrypt(ENCRYPT, fp, password);
+ if (password != NULL)
free(password);
- }
json_object_put(jobj);
- free(portfolio_string);
+ string_destroy(&pString);
}
-double* portfolio_print_stock(char* ticker_name_string, FILE* fp, Json* current_index) {
+double* portfolio_print_stock(char* ticker_name_string, Json* current_index) {
/**
* Values in USD
* a[0] -- current balance
@@ -184,29 +193,31 @@ double* portfolio_print_stock(char* ticker_name_string, FILE* fp, Json* current_
*/
char symbol[32];
double* data = malloc(sizeof(double) * 3);
- char* portfolio_string = NULL;
+ if (data == NULL) {
+ fprintf(stderr, "malloc() failed\n");
+ exit(EXIT_FAILURE);
+ }
+ String* pString = NULL;
char* password = NULL;
Json* jobj = NULL;
- if (fp == NULL) { //if being called from portfolio_print_all
+ if (current_index != NULL) { //if being called from portfolio_print_all
strcpy(symbol, json_object_get_string(json_object_object_get(current_index, "Symbol")));
strip_char(symbol, '\"');
data[0] = json_object_get_double(json_object_object_get(current_index, "Shares"));
data[1] = json_object_get_double(json_object_object_get(current_index, "USD_Spent"));
} else { //if being called directly from main
strcpy(symbol, ticker_name_string);
- portfolio_string = portfolio_file_get_string(fp, NULL);
- jobj = json_tokener_parse(portfolio_string);
+ pString = portfolio_file_get_string();
+ jobj = json_tokener_parse(pString->data);
if (jobj == NULL) { //ENCRYPTED PORTFOLIO
password = rc4_getPassword();
printf("Decrypting portfolio...\n");
- portfolio_encrypt_decrypt(DECRYPT, fp, password);
- fp = fopen(portfolio_file, "r+");
- free(portfolio_string);
- portfolio_string = portfolio_file_get_string(fp, NULL);
- json_object_put(jobj);
- jobj = json_tokener_parse(portfolio_string);
- if (jobj == NULL) {
- free(portfolio_string);
+ String* temp = rc4_get_crypted_string(pString, password, DECRYPT);
+ string_destroy(&pString);
+ pString = temp;
+ jobj = json_tokener_parse(pString->data);
+ if (pString == NULL) {
+ free(password);
return NULL;
}
}
@@ -216,6 +227,7 @@ double* portfolio_print_stock(char* ticker_name_string, FILE* fp, Json* current_
return data;
}
current_index = json_object_array_get_idx(jobj, (size_t) index);
+ printf(" AMOUNT SYMBOL VALUE SPENT PROFIT (%%) 24H (%%)\n");
}
data[0] = json_object_get_double(json_object_object_get(current_index, "Shares"));
data[1] = json_object_get_double(json_object_object_get(current_index, "USD_Spent"));
@@ -234,160 +246,22 @@ double* portfolio_print_stock(char* ticker_name_string, FILE* fp, Json* current_
data[0] / ticker_current_price_usd, symbol, data[0], data[1], data[0] - data[1],
(100 * (data[0] - data[1])) / data[1],
data[2], ticker_1d_percent_change);
- if (fp != NULL) {
- json_object_put(jobj);
- if (password != NULL) { // If portfolio was decrypted, encrypt again
- fflush(fp);
- printf("Encrypting porfolio...\n");
- portfolio_encrypt_decrypt(ENCRYPT, fp, password);
- free(password);
- }
- }
- free(portfolio_string);
+ if (password != NULL)
+ free(password);
+ json_object_put(jobj);
+ if (pString != NULL)
+ string_destroy(&pString);
return data;
}
int portfolio_symbol_index(const char* ticker_name_string, Json* jarray) {
char string[32];
- for (int i = 0; i < (int)json_object_array_length(jarray); i++) {
- strcpy(string, json_object_to_json_string(json_object_object_get(json_object_array_get_idx(jarray, (size_t) i), "Symbol")));
+ for (int i = 0; i < (int) json_object_array_length(jarray); i++) {
+ strcpy(string, json_object_to_json_string(
+ json_object_object_get(json_object_array_get_idx(jarray, (size_t) i), "Symbol")));
strip_char(string, '\"');
if (strcmp(string, ticker_name_string) == 0)
return i;
}
return -1;
-}
-
-char* portfolio_legacy_get_next_val(FILE* fp) {
- char* val = calloc(16, 1);
- char c;
- for (int i = 0; i < 16; i++) {
- c = (char) fgetc(fp);
- if (c == ' ' || c == '\n' || feof(fp))
- break;
- val[i] = c;
- }
- return val;
-}
-
-void portfolio_legacy_convert(void) {
- printf("Warning: this will overwrite your JSON formatted portfolio, which is stored at: \"$HOME/.tick_portfolio.json\". Continue? y/n\n");
- char c = 0;
- while (c != 'y' && c != 'n') {
- if (scanf("%c", &c) < 0)
- c = 0;
- }
- if (c == 'n') {
- printf("Aborted.\n");
- return;
- }
- FILE* fp = fopen(portfolio_file, "w");
- char* pf = portfolio_file_get_string(fp, NULL);
- if (pf == NULL) {
- fprintf(stderr, "fread() failed\n");
- exit(EXIT_FAILURE);
- }
- if (strcmp(pf, "") != 0)
- remove(portfolio_file);
- fclose(fp);
- fp = fopen(portfolio_file, "a+");
- free(pf);
- char* legacy_path = malloc(64);
- strcpy(legacy_path, portfolio_file);
- legacy_path[strlen(legacy_path) - 5] = '\0';
- FILE* fp_legacy = fopen(legacy_path, "r");
- free(legacy_path);
- if (!fp) {
- printf("Could not open legacy portfolio.\n");
- return;
- }
- char* symbol, * amount, * spent;
- while (1) {
- symbol = portfolio_legacy_get_next_val(fp_legacy);
- amount = portfolio_legacy_get_next_val(fp_legacy);
- spent = portfolio_legacy_get_next_val(fp_legacy);
- portfolio_modify(symbol, strtod(amount, NULL), strtod(spent, NULL), fp, ADD);
- free(symbol);
- free(amount);
- free(spent);
- if (feof(fp_legacy))
- break;
- }
- printf("Successfully converted portfolio!\n");
- fclose(fp_legacy);
- fclose(fp);
-}
-
-char* portfolio_get_encrypt_string(char* input, size_t input_len, char* password) {
- int keySchedule[256];
- rc4_key_exchange(keySchedule, password);
- char* output = rc4_prga(keySchedule, input_len);
- rc4_execute(output, input, input_len);
- return output;
-}
-
-void portfolio_encrypt_decrypt(int option, FILE* fp, char* password) {
- int free_pw = 0;
- if (password == NULL)
- free_pw = 1;
- fp = fopen(portfolio_file, "r+");
- size_t len;
- char* ps = portfolio_file_get_string(fp, &len);
- Json* jobj = json_tokener_parse(ps);
- if (option == ENCRYPT && jobj == NULL) // If trying to encrypt an encrypted portfolio
- printf("Your portfolio is already encrypted.\n");
- else if (option == DECRYPT && jobj != NULL) // If trying to decrypt an unencrypted portfolio
- printf("Your portfolio isn't encrypted.\n");
- else {
- if (password == NULL) {
- password = rc4_getPassword();
- if (option == ENCRYPT) { // When encrypting, ask to enter pw twice to make sure
- printf("You will be asked to enter your password again to make sure the entries match.\n");
- sleep(2);
- char* passwordCheck = rc4_getPassword();
- if (strcmp(password, passwordCheck) != 0) {
- printf("Passwords do not match!\n");
- free(password);
- free(passwordCheck);
- free(ps);
- json_object_put(jobj);
- return;
- }
- free(passwordCheck);
- }
- }
- char* encrypted = portfolio_get_encrypt_string(ps, len, password);
- if (option == DECRYPT) {
- json_object_put(jobj);
- encrypted = realloc(encrypted, len + 1);// Realloc to add null terminator for json parsing
- if (encrypted == NULL) { // Dealing with len is annoying so it's easier to just realloc
- fprintf(stderr, "malloc() failed\n");
- exit(EXIT_FAILURE);
- }
- encrypted[len] = '\0';
- jobj = json_tokener_parse(encrypted);
- if (jobj == NULL) { // If after decrypting, the portfolio is not JSON formatted,
- printf("Wrong password!\n"); // then it's the wrong password
- free(encrypted);
- free(password);
- free(ps);
- return;
- }
- }
- remove(portfolio_file); // Remove existing file and use fputc to write
- fp = fopen(portfolio_file, "w"); // fprintf %s won't work since there some chars are encoded to '\0', so it
- for (int i = 0; i < (int)len; i++) // will be null terminated several times in the middle
- fputc(encrypted[i], fp);
- fclose(fp);
- free(encrypted);
- if (free_pw) { // If being called from main
- free(password);
- if (option == ENCRYPT)
- printf("Successfully encrypted your portfolio.\n");
- else printf("Successfully decrypted your portfolio.\n");
- }
- }
- if (jobj != NULL)
- json_object_put(jobj);
- free(ps);
} \ No newline at end of file
diff --git a/portfolio.h b/portfolio.h
index 42012d57113e..fe50b16ff1c7 100644
--- a/portfolio.h
+++ b/portfolio.h
@@ -2,15 +2,12 @@
#define PORTFOLIO_H
#include <math.h>
-#include <unistd.h>
#include "api.h"
#include "rc4.h"
#define REMOVE 0
#define ADD 1
#define SET 2
-#define DECRYPT 0
-#define ENCRYPT 1
extern char* portfolio_file;
@@ -26,7 +23,7 @@ void portfolio_file_init(void);
* the returned string will be null terminated somewhere in the middle several times
* @return the string containing the file
*/
-char* portfolio_file_get_string(FILE* fp, size_t* len);
+String* portfolio_file_get_string(void);
/**
* Adds quantity_shares of given symbol at given price to portfolio
@@ -35,7 +32,7 @@ char* portfolio_file_get_string(FILE* fp, size_t* len);
* @param purchase_price quantity_shares of money spent
* @param fp portfolio file
*/
-void portfolio_modify(const char* ticker_name_string, double quantity_shares, double usd_spent, FILE* fp, int option);
+void portfolio_modify(const char* ticker_name_string, double quantity_shares, double usd_spent, int option);
/**
* Prints current holdings of all symbols
@@ -43,7 +40,7 @@ void portfolio_modify(const char* ticker_name_string, double quantity_shares, do
* @param crypto_data JSON to hold STRING data in
* @param fp portfolio file
*/
-void portfolio_print_all(FILE* fp);
+void portfolio_print_all(void);
/**
* Prints current holdings of a symbol
@@ -51,7 +48,7 @@ void portfolio_print_all(FILE* fp);
* @param fp portfolio file, NULL if printing all
* @param current_index portfolio file index, NULL if printing one
*/
-double* portfolio_print_stock(char* ticker_name_string, FILE* fp, Json* current_index);
+double* portfolio_print_stock(char* ticker_name_string, Json* current_index);
/**
* Returns the index in the Json array of the given symbol
@@ -61,34 +58,4 @@ double* portfolio_print_stock(char* ticker_name_string, FILE* fp, Json* current_
*/
int portfolio_symbol_index(const char* ticker_name_string, Json* jarray);
-/**
- * Returns a string from the current stream pointer to the next space, newline, or EOF
- * @param fp the file
- * @return the string
- */
-char* portfolio_legacy_get_next_val(FILE* fp);
-
-/**
- * Adds contents of legacy portfolio to JSON formatted portfolio
- * @param fp JSON formatted portfolio
- */
-void portfolio_legacy_convert(void);
-
-/**
- * Returns an either encrypted or decrypted string of the input
- * @param input the string to encrypt or decrypt
- * @param input_len the length of the string
- * @param password the password to encrypt or decrypt with
- * @return encrypted or decrypted string
- */
-char* portfolio_get_encrypt_string(char* input, size_t input_len, char* password);
-
-/**
- * Either encrypts or decrypts the portfolio file
- * @param option ENCRYPT or DECRYPT
- * @param fp portfolio file
- * @param password the password to encrypt/decrypt with or NULL to ask user
- */
-void portfolio_encrypt_decrypt(int option, FILE* fp, char* password);
-
#endif \ No newline at end of file
diff --git a/rc4.c b/rc4.c
index 691abf3de7f5..ab9f59d54321 100644
--- a/rc4.c
+++ b/rc4.c
@@ -51,7 +51,7 @@ char* rc4_prga(int keySchedule[KEY_SCHEDULE_LENGTH], size_t len) {
fprintf(stderr, "malloc() failed\n");
return NULL;
}
- for (int k = 0; k < (int)len; k++) {
+ for (int k = 0; k < (int) len; k++) {
i = (i + 1) % KEY_SCHEDULE_LENGTH;
j = (j + keySchedule[i]) % KEY_SCHEDULE_LENGTH;
temp = keySchedule[i];
@@ -62,7 +62,71 @@ char* rc4_prga(int keySchedule[KEY_SCHEDULE_LENGTH], size_t len) {
return output;
}
-void rc4_execute(char* output, char* message, size_t len) {
- for (int i = 0; i < (int)len; i++)
- output[i] ^= message[i];
+void rc4_execute(char* output, String* pString) {
+ for (int i = 0; i < (int) pString->len; i++)
+ output[i] ^= pString->data[i];
+}
+
+char* rc4_encode_string(String* pString, char* password){
+ int keySchedule[256];
+ rc4_key_exchange(keySchedule, password);
+ char* output = rc4_prga(keySchedule, pString->len);
+ rc4_execute(output, pString);
+ return output;
+}
+
+String* rc4_get_crypted_string(String* input_pString, char* password, int option) {
+ String* output_pString = NULL;
+ int free_pw = (password == NULL);
+ Json* jobj = json_tokener_parse(input_pString->data);
+ if (option == ENCRYPT && jobj == NULL) // If trying to encrypt an encrypted portfolio
+ printf("Your portfolio is already encrypted.\n");
+ else if (option == DECRYPT && jobj != NULL) // If trying to decrypt an unencrypted portfolio
+ printf("Your portfolio isn't encrypted.\n");
+ else {
+ if (password == NULL) { // Get password if not provided
+ password = rc4_getPassword();
+ if (option == ENCRYPT) { // When encrypting, ask to enter pw twice to make sure
+ printf("You will be asked to enter your password again to make sure the entries match.\n");
+ sleep(2);
+ char* passwordCheck = rc4_getPassword();
+ if (strcmp(password, passwordCheck) != 0) {
+ printf("Passwords do not match!\n");
+ free(password);
+ free(passwordCheck);
+ json_object_put(jobj);
+ return NULL;
+ }
+ free(passwordCheck);
+ }
+ }
+ output_pString = string_init(); // Set ouput string to en/decrypted data
+ free(output_pString->data);
+ output_pString->data = rc4_encode_string(input_pString, password);
+ output_pString->len = input_pString->len;
+ if (option == DECRYPT) {
+ json_object_put(jobj);
+ output_pString->data = realloc(output_pString->data, output_pString->len + 1);// Realloc to add null terminator for json parsing
+ if (output_pString->data == NULL) { // Dealing with len is annoying so it's easier to just realloc
+ fprintf(stderr, "realloc() failed\n");
+ exit(EXIT_FAILURE);
+ }
+ output_pString->data[output_pString->len] = '\0'; // Null terminate string for parsing
+ jobj = json_tokener_parse(output_pString->data);
+ if (jobj == NULL) { // If after decrypting, the portfolio is not JSON formatted,
+ printf("Wrong password!\n"); // then it's the wrong password
+ free(password);
+ string_destroy(&output_pString);
+ return NULL;
+ }
+ }
+ if (free_pw) { // If being called from main
+ free(password);
+ if (option == ENCRYPT)
+ printf("Successfully encrypted your portfolio.\n");
+ else printf("Successfully decrypted your portfolio.\n");
+ }
+ }
+ json_object_put(jobj);
+ return output_pString;
} \ No newline at end of file
diff --git a/rc4.h b/rc4.h
index 4634bebfadaa..5e864db0f39b 100644
--- a/rc4.h
+++ b/rc4.h
@@ -4,10 +4,13 @@
#define PASS_MAX 32
#define BACKSPACE 127
#define KEY_SCHEDULE_LENGTH 256
+#define DECRYPT 0
+#define ENCRYPT 1
-#include <stdlib.h>
-#include <string.h>
#include <ncurses.h>
+#include <json-c/json_tokener.h>
+#include <unistd.h>
+#include "string-tick.h"
/**
* Takes a password from user input and returns it (max 32 chars)
@@ -36,6 +39,17 @@ char* rc4_prga(int keySchedule[KEY_SCHEDULE_LENGTH], size_t len);
* @param message portoflio string
* @param len length of portfolio in bytes
*/
-void rc4_execute(char* output, char* message, size_t len);
+void rc4_execute(char* output, String* pString);
+
+/**
+ * Returns an either encrypted or decrypted string of the input
+ * @param input the string to encrypt or decrypt
+ * @param input_len the length of the string
+ * @param password the password to encrypt or decrypt with
+ * @return encrypted or decrypted string
+ */
+char* rc4_encode_string(String* pString, char* password);
+
+String* rc4_get_crypted_string(String* input_pString, char* password, int option);
#endif \ No newline at end of file
diff --git a/string-tick.c b/string-tick.c
index f3575d01a356..701c87463135 100644
--- a/string-tick.c
+++ b/string-tick.c
@@ -1,4 +1,5 @@
#include "string-tick.h"
+#include "portfolio.h"
String* string_init(void) {
String* pString = (String*) malloc(sizeof(String));
@@ -39,6 +40,13 @@ char* strip_char(char* string, char c) {
return string;
}
+void string_write_portfolio(String* pString){
+ FILE* fp = fopen(portfolio_file, "w"); // fprintf %s won't work since there some chars are encoded to '\0', so it
+ for (int i = 0; i < (int) pString->len; i++) // will be null terminated several times in the middle
+ fputc(pString->data[i], fp);
+ fclose(fp);
+}
+
void string_destroy(String** phString) {
String* pString = *phString;
free(pString->data);
diff --git a/string-tick.h b/string-tick.h
index 3e9575560d3a..1397ee3fb2ef 100644
--- a/string-tick.h
+++ b/string-tick.h
@@ -13,6 +13,8 @@ struct string {
typedef struct string String;
+typedef struct json_object Json;
+
/**
* Creates and returns a STRING
* object with size 1 and no data
@@ -40,6 +42,8 @@ void strtoupper(char* str);
*/
char* strip_char(char* string, char c);
+void string_write_portfolio(String* pString);
+
/**
* Destroys String object and frees memory
* @param phString the String to destroy