diff --git a/src/bcrypt.c b/src/bcrypt.c index 216d9e34..f3397070 100644 --- a/src/bcrypt.c +++ b/src/bcrypt.c @@ -7,7 +7,8 @@ JSValue _crypt_hashpw(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); JSValue _crypt_gensalt(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); -void tf_bcrypt_init(JSContext* context) { +void tf_bcrypt_init(JSContext* context) +{ JSValue global = JS_GetGlobalObject(context); JSValue bcrypt = JS_NewObject(context); JS_SetPropertyStr(context, global, "bCrypt", bcrypt); @@ -16,7 +17,8 @@ void tf_bcrypt_init(JSContext* context) { JS_FreeValue(context, global); } -JSValue _crypt_hashpw(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _crypt_hashpw(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ const char* key = JS_ToCString(context, argv[0]); const char* salt = JS_ToCString(context, argv[1]); char output[7 + 22 + 31 + 1]; @@ -27,7 +29,8 @@ JSValue _crypt_hashpw(JSContext* context, JSValueConst this_val, int argc, JSVal return result; } -JSValue _crypt_gensalt(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _crypt_gensalt(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ int length; JS_ToInt32(context, &length, argv[0]); char buffer[16]; diff --git a/src/database.c b/src/database.c index 51a11312..f4d73d65 100644 --- a/src/database.c +++ b/src/database.c @@ -9,7 +9,8 @@ static JSClassID _database_class_id; static int _database_count; -typedef struct _database_t { +typedef struct _database_t +{ JSContext* context; JSValue object; void* task; @@ -26,13 +27,15 @@ static JSValue _database_remove(JSContext* context, JSValueConst this_val, int a static JSValue _database_get_all(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _database_get_like(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); -void tf_database_init(JSContext* context, sqlite3* sqlite) { +void tf_database_init(JSContext* context, sqlite3* sqlite) +{ JS_NewClassID(&_database_class_id); JSClassDef def = { .class_name = "Database", .finalizer = &_database_finalizer, }; - if (JS_NewClass(JS_GetRuntime(context), _database_class_id, &def) != 0) { + if (JS_NewClass(JS_GetRuntime(context), _database_class_id, &def) != 0) + { printf("Failed to register database.\n"); } @@ -44,14 +47,16 @@ void tf_database_init(JSContext* context, sqlite3* sqlite) { JS_FreeValue(context, global); } -static JSValue _database_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* data) { +static JSValue _database_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* data) +{ ++_database_count; JSValue object = JS_NewObjectClass(context, _database_class_id); sqlite3* db = NULL; JS_ToInt64(context, (int64_t*)&db, data[0]); database_t* database = malloc(sizeof(database_t)); - *database = (database_t) { + *database = (database_t) + { .task = JS_GetContextOpaque(context), .context = context, .object = object, @@ -71,26 +76,32 @@ static JSValue _database_create(JSContext* context, JSValueConst this_val, int a return object; } -static void _database_finalizer(JSRuntime *runtime, JSValue value) { +static void _database_finalizer(JSRuntime *runtime, JSValue value) +{ database_t* database = JS_GetOpaque(value, _database_class_id); - if (database) { + if (database) + { free((void*)database->id); free(database); } --_database_count; } -static JSValue _database_get(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _database_get(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ JSValue entry = JS_UNDEFINED; database_t* database = JS_GetOpaque(this_val, _database_class_id); - if (database) { + if (database) + { sqlite3_stmt* statement; - if (sqlite3_prepare(database->db, "SELECT value FROM properties WHERE id = $1 AND key = $2", -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(database->db, "SELECT value FROM properties WHERE id = $1 AND key = $2", -1, &statement, NULL) == SQLITE_OK) + { size_t length; const char* keyString = JS_ToCStringLen(context, &length, argv[0]); if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, keyString, length, NULL) == SQLITE_OK && - sqlite3_step(statement) == SQLITE_ROW) { + sqlite3_step(statement) == SQLITE_ROW) + { entry = JS_NewStringLen(context, (const char*)sqlite3_column_text(statement, 0), sqlite3_column_bytes(statement, 0)); } JS_FreeCString(context, keyString); @@ -100,11 +111,14 @@ static JSValue _database_get(JSContext* context, JSValueConst this_val, int argc return entry; } -JSValue _database_set(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _database_set(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ database_t* database = JS_GetOpaque(this_val, _database_class_id); - if (database) { + if (database) + { sqlite3_stmt* statement; - if (sqlite3_prepare(database->db, "INSERT OR REPLACE INTO properties (id, key, value) VALUES ($1, $2, $3)", -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(database->db, "INSERT OR REPLACE INTO properties (id, key, value) VALUES ($1, $2, $3)", -1, &statement, NULL) == SQLITE_OK) + { size_t keyLength; const char* keyString = JS_ToCStringLen(context, &keyLength, argv[0]); size_t valueLength; @@ -112,7 +126,8 @@ JSValue _database_set(JSContext* context, JSValueConst this_val, int argc, JSVal if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, keyString, keyLength, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 3, valueString, valueLength, NULL) == SQLITE_OK && - sqlite3_step(statement) == SQLITE_OK) { + sqlite3_step(statement) == SQLITE_OK) + { } JS_FreeCString(context, keyString); JS_FreeCString(context, valueString); @@ -122,16 +137,20 @@ JSValue _database_set(JSContext* context, JSValueConst this_val, int argc, JSVal return JS_UNDEFINED; } -JSValue _database_remove(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _database_remove(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ database_t* database = JS_GetOpaque(this_val, _database_class_id); - if (database) { + if (database) + { sqlite3_stmt* statement; - if (sqlite3_prepare(database->db, "DELETE FROM properties WHERE id = $1 AND key = $2", -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(database->db, "DELETE FROM properties WHERE id = $1 AND key = $2", -1, &statement, NULL) == SQLITE_OK) + { size_t keyLength; const char* keyString = JS_ToCStringLen(context, &keyLength, argv[0]); if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, keyString, keyLength, NULL) == SQLITE_OK && - sqlite3_step(statement) == SQLITE_OK) { + sqlite3_step(statement) == SQLITE_OK) + { } JS_FreeCString(context, keyString); sqlite3_finalize(statement); @@ -140,16 +159,21 @@ JSValue _database_remove(JSContext* context, JSValueConst this_val, int argc, JS return JS_UNDEFINED; } -JSValue _database_get_all(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _database_get_all(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ JSValue array = JS_UNDEFINED; database_t* database = JS_GetOpaque(this_val, _database_class_id); - if (database) { + if (database) + { sqlite3_stmt* statement; - if (sqlite3_prepare(database->db, "SELECT key, value FROM properties WHERE id = $1", -1, &statement, NULL) == SQLITE_OK) { - if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK) { + if (sqlite3_prepare(database->db, "SELECT key, value FROM properties WHERE id = $1", -1, &statement, NULL) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK) + { array = JS_NewArray(context); uint32_t index = 0; - while (sqlite3_step(statement) == SQLITE_ROW) { + while (sqlite3_step(statement) == SQLITE_ROW) + { JS_SetPropertyUint32(context, array, index++, JS_NewStringLen(context, (const char*)sqlite3_column_text(statement, 0), sqlite3_column_bytes(statement, 0))); } } @@ -159,17 +183,22 @@ JSValue _database_get_all(JSContext* context, JSValueConst this_val, int argc, J return array; } -JSValue _database_get_like(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _database_get_like(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ JSValue result = JS_UNDEFINED; database_t* database = JS_GetOpaque(this_val, _database_class_id); - if (database) { + if (database) + { sqlite3_stmt* statement; - if (sqlite3_prepare(database->db, "SELECT key, value FROM properties WHERE id = ? AND KEY LIKE ?", -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(database->db, "SELECT key, value FROM properties WHERE id = ? AND KEY LIKE ?", -1, &statement, NULL) == SQLITE_OK) + { const char* pattern = JS_ToCString(context, argv[0]); if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK && - sqlite3_bind_text(statement, 2, pattern, -1, NULL) == SQLITE_OK) { + sqlite3_bind_text(statement, 2, pattern, -1, NULL) == SQLITE_OK) + { result = JS_NewObject(context); - while (sqlite3_step(statement) == SQLITE_ROW) { + while (sqlite3_step(statement) == SQLITE_ROW) + { JS_SetPropertyStr( context, result, diff --git a/src/file.c b/src/file.c index 50f603de..63463ec0 100644 --- a/src/file.c +++ b/src/file.c @@ -31,7 +31,8 @@ typedef struct file_stat_t { uv_fs_t _request; } file_stat_t; -void tf_file_init(JSContext* context) { +void tf_file_init(JSContext* context) +{ JSValue global = JS_GetGlobalObject(context); JSValue file = JS_NewObject(context); JS_SetPropertyStr(context, global, "File", file); @@ -106,7 +107,8 @@ static void _file_read_open_callback(uv_fs_t* req) } } -static JSValue _file_read_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _file_read_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ void* task = JS_GetContextOpaque(context); const char* file_name = JS_ToCString(context, argv[0]); @@ -125,19 +127,24 @@ static JSValue _file_read_file(JSContext* context, JSValueConst this_val, int ar return tf_task_get_promise(task, promise); } -static JSValue _file_write_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _file_write_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ JSValue result = JS_NULL; const char* fileName = JS_ToCString(context, argv[0]); FILE* file = fopen(fileName, "wb"); JS_FreeCString(context, fileName); - if (file) { + if (file) + { size_t size; uint8_t* buffer = tf_try_get_array_buffer(context, &size, argv[1]); - if (buffer) { + if (buffer) + { int written = fwrite((const char*)buffer, 1, size, file); result = JS_NewInt32(context, (size_t)written == size ? 0 : written); - } else { + } + else + { const char* data = JS_ToCStringLen(context, &size, argv[1]); int written = fwrite((const char*)data, 1, size, file); result = JS_NewInt32(context, (size_t)written == size ? 0 : written); @@ -148,7 +155,8 @@ static JSValue _file_write_file(JSContext* context, JSValueConst this_val, int a return result; } -static JSValue _file_rename_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _file_rename_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ void* task = JS_GetContextOpaque(context); const char* oldName = JS_ToCString(context, argv[0]); const char* newName = JS_ToCString(context, argv[1]); @@ -159,7 +167,8 @@ static JSValue _file_rename_file(JSContext* context, JSValueConst this_val, int return JS_NewInt32(context, result); } -static JSValue _file_unlink_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _file_unlink_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ void* task = JS_GetContextOpaque(context); const char* fileName = JS_ToCString(context, argv[0]); uv_fs_t req; @@ -168,7 +177,8 @@ static JSValue _file_unlink_file(JSContext* context, JSValueConst this_val, int return JS_NewInt32(context, result); } -static JSValue _file_read_directory(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _file_read_directory(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ const char* directory = JS_ToCString(context, argv[0]); JSValue array = JS_NewArray(context); @@ -177,7 +187,8 @@ static JSValue _file_read_directory(JSContext* context, JSValueConst this_val, i std::string pattern = directory; pattern += "\\*"; HANDLE handle = FindFirstFile(pattern.c_str(), &find); - if (handle != INVALID_HANDLE_VALUE) { + if (handle != INVALID_HANDLE_VALUE) + { int index = 0; do { JS_SetPropertyUint32(context, array, index++, JS_NewString(context, find.cFileName)); @@ -186,10 +197,12 @@ static JSValue _file_read_directory(JSContext* context, JSValueConst this_val, i } #else DIR* dir = opendir(directory); - if (dir) { + if (dir) + { uint32_t index = 0; struct dirent* entry = readdir(dir); - while (entry) { + while (entry) + { JS_SetPropertyUint32(context, array, index++, JS_NewString(context, entry->d_name)); entry = readdir(dir); } @@ -201,7 +214,8 @@ static JSValue _file_read_directory(JSContext* context, JSValueConst this_val, i return array; } -JSValue _file_make_directory(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _file_make_directory(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ void* task = JS_GetContextOpaque(context); const char* directory = JS_ToCString(context, argv[0]); @@ -211,7 +225,8 @@ JSValue _file_make_directory(JSContext* context, JSValueConst this_val, int argc return JS_NewInt32(context, result); } -JSValue _file_stat(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _file_stat(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ void* task = JS_GetContextOpaque(context); const char* path = JS_ToCString(context, argv[0]); promiseid_t promise = tf_task_allocate_promise(task); @@ -223,7 +238,8 @@ JSValue _file_stat(JSContext* context, JSValueConst this_val, int argc, JSValueC data->_context = context; int result = uv_fs_stat(tf_task_get_loop(task), &data->_request, path, _file_on_stat_complete); - if (result) { + if (result) + { tf_task_reject_promise(task, promise, JS_NewInt32(context, result)); free(data); } @@ -231,17 +247,22 @@ JSValue _file_stat(JSContext* context, JSValueConst this_val, int argc, JSValueC return tf_task_get_promise(task, promise); } -static double _time_spec_to_double(const uv_timespec_t* time_spec) { +static double _time_spec_to_double(const uv_timespec_t* time_spec) +{ return time_spec->tv_sec + (double)(time_spec->tv_nsec) / 1e9; } -static void _file_on_stat_complete(uv_fs_t* request) { +static void _file_on_stat_complete(uv_fs_t* request) +{ file_stat_t* data = (file_stat_t*)(request->data); JSContext* context = data->_context; - if (request->result) { + if (request->result) + { tf_task_reject_promise(data->_task, data->_promise, JS_NewInt32(context, request->result)); - } else { + } + else + { JSValue result = JS_NewObject(context); JS_SetPropertyStr(context, result, "mtime", JS_NewFloat64(context, _time_spec_to_double(&request->statbuf.st_mtim))); JS_SetPropertyStr(context, result, "ctime", JS_NewFloat64(context, _time_spec_to_double(&request->statbuf.st_ctim))); diff --git a/src/main.c b/src/main.c index 589c12f9..543e1373 100644 --- a/src/main.c +++ b/src/main.c @@ -29,7 +29,8 @@ _xopt_ctx = xopt_context((name), (options), ((flags) ^ XOPT_CTX_POSIXMEHARDER), (err_ptr)); \ if (*(err_ptr)) break; \ *extrac_ptr = xopt_parse(_xopt_ctx, (argc), (argv), (config_ptr), (extrav_ptr), (err_ptr)); \ - if ((config_ptr)->help) { \ + if ((config_ptr)->help) \ + { \ xoptAutohelpOptions __xopt_autohelp_opts; \ __xopt_autohelp_opts.usage = (autohelp_usage); \ __xopt_autohelp_opts.prefix = (autohelp_prefix); \ @@ -91,24 +92,29 @@ void shedPrivileges() // RLIMIT_SIGPENDING // RLIMIT_STACK - if (setrlimit(RLIMIT_FSIZE, &zeroLimit) != 0) { + if (setrlimit(RLIMIT_FSIZE, &zeroLimit) != 0) + { perror("setrlimit(RLIMIT_FSIZE, {0, 0})"); exit(-1); } - if (setrlimit(RLIMIT_NOFILE, &zeroLimit) != 0) { + if (setrlimit(RLIMIT_NOFILE, &zeroLimit) != 0) + { perror("setrlimit(RLIMIT_NOFILE, {0, 0})"); exit(-1); } - if (setrlimit(RLIMIT_NPROC, &zeroLimit) != 0) { + if (setrlimit(RLIMIT_NPROC, &zeroLimit) != 0) + { perror("setrlimit(RLIMIT_NPROC, {0, 0})"); exit(-1); } #if !defined (__MACH__) - if (setrlimit(RLIMIT_LOCKS, &zeroLimit) != 0) { + if (setrlimit(RLIMIT_LOCKS, &zeroLimit) != 0) + { perror("setrlimit(RLIMIT_LOCKS, {0, 0})"); exit(-1); } - if (setrlimit(RLIMIT_MSGQUEUE, &zeroLimit) != 0) { + if (setrlimit(RLIMIT_MSGQUEUE, &zeroLimit) != 0) + { perror("setrlimit(RLIMIT_MSGQUEUE, {0, 0})"); exit(-1); } @@ -134,10 +140,12 @@ static int _tf_command_test(const char* file, int argc, char* argv[]) int extra_count = 0; const char *err = NULL; XOPT_PARSE(file, XOPT_CTX_KEEPFIRST, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "test [options]", "options:", NULL, 15); - if (extras) { + if (extras) + { free((void*)extras); } - if (err) { + if (err) + { fprintf(stderr, "Error: %s\n", err); return 2; } @@ -150,7 +158,8 @@ static int _tf_command_test(const char* file, int argc, char* argv[]) tf_tests(&test_options); return 0; xopt_help: - if (extras) { + if (extras) + { free((void*)extras); } return 1; @@ -177,40 +186,50 @@ static int _tf_command_import(const char* file, int argc, char* argv[]) const char *err = NULL; XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "import [options] [paths] ...", "options:", NULL, 15); - if (err) { + if (err) + { fprintf(stderr, "Error: %s\n", err); - if (extras) { + if (extras) + { free((void*)extras); } return 2; } sqlite3* db = NULL; - if (args.db_path) { + if (args.db_path) + { sqlite3_open(args.db_path, &db); } tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db, NULL); - if (extra_count) { - for (int i = 0; i < extra_count; i++) { + if (extra_count) + { + for (int i = 0; i < extra_count; i++) + { printf("Importing %s...\n", extras[i]); tf_ssb_import(ssb, args.user, extras[i]); } - } else { + } + else + { printf("Importing %s...\n", "apps"); tf_ssb_import(ssb, args.user, "apps"); } tf_ssb_destroy(ssb); - if (db) { + if (db) + { sqlite3_close(db); } - if (extras) { + if (extras) + { free((void*)extras); } return 0; xopt_help: - if (extras) { + if (extras) + { free((void*)extras); } return 1; @@ -233,38 +252,47 @@ static int _tf_command_export(const char* file, int argc, char* argv[]) const char *err = NULL; XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "export [options] [paths] ...", "options:", NULL, 15); - if (err) { + if (err) + { fprintf(stderr, "Error: %s\n", err); - if (extras) { + if (extras) + { free((void*)extras); } return 2; } tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, NULL, NULL); - if (extra_count) { - for (int i = 0; i < extra_count; i++) { + if (extra_count) + { + for (int i = 0; i < extra_count; i++) + { printf("Exporting %s...\n", extras[i]); tf_ssb_export(ssb, extras[i]); } - } else { + } + else + { const char* k_export[] = { "/~cory/index", "/~cory/docs", }; - for (int i = 0; i < _countof(k_export); i++) { + for (int i = 0; i < _countof(k_export); i++) + { printf("Exporting %s...\n", k_export[i]); tf_ssb_export(ssb, k_export[i]); } } tf_ssb_destroy(ssb); - if (extras) { + if (extras) + { free((void*)extras); } return 0; xopt_help: - if (extras) { + if (extras) + { free((void*)extras); } return 1; @@ -304,14 +332,17 @@ static int _tf_command_run(const char* file, int argc, char* argv[]) const char *err = NULL; XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "run [options] [paths] ...", "options:", NULL, 15); - if (err) { + if (err) + { fprintf(stderr, "Error: %s\n", err); - if (extras) { + if (extras) + { free((void*)extras); } return 2; } - if (extras) { + if (extras) + { free((void*)extras); } @@ -340,7 +371,8 @@ static int _tf_command_run(const char* file, int argc, char* argv[]) return result; xopt_help: - if (extras) { + if (extras) + { free((void*)extras); } return 1; @@ -364,14 +396,17 @@ static int _tf_command_sandbox(const char* file, int argc, char* argv[]) const char *err = NULL; XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "sandbox [options]", "options:", NULL, 15); - if (err) { + if (err) + { fprintf(stderr, "Error: %s\n", err); - if (extras) { + if (extras) + { free((void*)extras); } return 2; } - if (extras) { + if (extras) + { free((void*)extras); } @@ -387,7 +422,8 @@ static int _tf_command_sandbox(const char* file, int argc, char* argv[]) return 0; xopt_help: - if (extras) { + if (extras) + { free((void*)extras); } return 1; @@ -411,10 +447,12 @@ static int _tf_command_post(const char* file, int argc, char* argv[]) int extra_count = 0; const char *err = NULL; XOPT_PARSE(file, XOPT_CTX_KEEPFIRST, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "post [options]", "options:", NULL, 15); - if (extras) { + if (extras) + { free((void*)extras); } - if (err) { + if (err) + { fprintf(stderr, "Error: %s\n", err); return 2; } @@ -426,7 +464,8 @@ static int _tf_command_post(const char* file, int argc, char* argv[]) return 0; xopt_help: - if (extras) { + if (extras) + { free((void*)extras); } return 1; @@ -436,7 +475,8 @@ static int _tf_command_usage(const char* file, int argc, char* argv[]) { printf("Usage: %s command [command-options]\n", file); printf("commands:\n"); - for (int i = 0; i < _countof(k_commands); i++) { + for (int i = 0; i < _countof(k_commands); i++) + { printf(" %s - %s\n", k_commands[i].name, k_commands[i].description); } return 0; @@ -449,15 +489,19 @@ int main(int argc, char* argv[]) tf_taskstub_startup(); #if !defined (_WIN32) - if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) + { perror("signal"); } #endif - if (argc >= 2) { - for (int i = 0; i < _countof(k_commands); i++) { + if (argc >= 2) + { + for (int i = 0; i < _countof(k_commands); i++) + { const command_t* command = &k_commands[i]; - if (strcmp(argv[1], command->name) == 0) { + if (strcmp(argv[1], command->name) == 0) + { return command->callback(argv[0], argc - 2, argv + 2); } } diff --git a/src/packetstream.c b/src/packetstream.c index 64c1258b..1004f8d1 100644 --- a/src/packetstream.c +++ b/src/packetstream.c @@ -15,84 +15,106 @@ typedef struct _tf_packetstream_t { bool destroyed; } tf_packetstream_t; -tf_packetstream_t* tf_packetstream_create() { +tf_packetstream_t* tf_packetstream_create() +{ tf_packetstream_t* impl = malloc(sizeof(tf_packetstream_t)); *impl = (tf_packetstream_t) { 0 }; return impl; } -void tf_packetstream_destroy(tf_packetstream_t* stream) { +void tf_packetstream_destroy(tf_packetstream_t* stream) +{ stream->onreceive = NULL; stream->onreceive_user_data = NULL; stream->destroyed = true; - if (stream->stream.data) { + if (stream->stream.data) + { tf_packetstream_close(stream); - } else { + } + else + { free(stream); } } -static void _packetstream_allocate(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buffer) { +static void _packetstream_allocate(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buffer) +{ buffer->base = malloc(suggested_size); buffer->len = suggested_size; } -static void _packetstream_process_messages(tf_packetstream_t* stream) { +static void _packetstream_process_messages(tf_packetstream_t* stream) +{ int packet_type = 0; size_t length = 0; - while (stream->buffer_size >= sizeof(packet_type) + sizeof(length)) { + while (stream->buffer_size >= sizeof(packet_type) + sizeof(length)) + { memcpy(&packet_type, stream->buffer, sizeof(packet_type)); memcpy(&length, stream->buffer + sizeof(packet_type), sizeof(length)); - if (stream->buffer_size >= sizeof(packet_type) + sizeof(length) + length) { - if (stream->onreceive) { + if (stream->buffer_size >= sizeof(packet_type) + sizeof(length) + length) + { + if (stream->onreceive) + { stream->onreceive(packet_type, stream->buffer + sizeof(length) + sizeof(packet_type), length, stream->onreceive_user_data); } size_t consumed = sizeof(length) + sizeof(packet_type) + length; memmove(stream->buffer, stream->buffer + consumed, stream->buffer_size - consumed); stream->buffer_size -= consumed; stream->buffer = realloc(stream->buffer, stream->buffer_size); - } else { + } + else + { break; } } } -static void _packetstream_on_read(uv_stream_t* handle, ssize_t count, const uv_buf_t* buffer) { +static void _packetstream_on_read(uv_stream_t* handle, ssize_t count, const uv_buf_t* buffer) +{ tf_packetstream_t* stream = handle->data; - if (count >= 0) { - if (count > 0) { + if (count >= 0) + { + if (count > 0) + { char* new_buffer = realloc(stream->buffer, stream->buffer_size + count); - if (new_buffer) { + if (new_buffer) + { memcpy(new_buffer + stream->buffer_size, buffer->base, count); stream->buffer = new_buffer; stream->buffer_size += count; } _packetstream_process_messages(stream); } - } else { + } + else + { tf_packetstream_close(stream); } free(buffer->base); } -void tf_packetstream_start(tf_packetstream_t* stream) { +void tf_packetstream_start(tf_packetstream_t* stream) +{ stream->stream.data = stream; uv_read_start((uv_stream_t*)&stream->stream, _packetstream_allocate, _packetstream_on_read); } -static void _packetstream_on_write(uv_write_t* request, int status) { +static void _packetstream_on_write(uv_write_t* request, int status) +{ free(request); } -void tf_packetstream_send(tf_packetstream_t* stream, int packet_type, char* begin, size_t length) { +void tf_packetstream_send(tf_packetstream_t* stream, int packet_type, char* begin, size_t length) +{ size_t buffer_length = sizeof(uv_write_t) + sizeof(packet_type) + sizeof(length) + length; uv_write_t* request = malloc(buffer_length); memset(request, 0, sizeof(uv_write_t)); char* buffer = (char*)(request + 1); memcpy(buffer, &packet_type, sizeof(packet_type)); memcpy(buffer + sizeof(packet_type), &length, sizeof(length)); - if (length) { + if (length) + { memcpy(buffer + sizeof(packet_type) + sizeof(length), begin, length); } uv_buf_t write_buffer; @@ -101,7 +123,8 @@ void tf_packetstream_send(tf_packetstream_t* stream, int packet_type, char* begi uv_write(request, (uv_stream_t*)&stream->stream, &write_buffer, 1, _packetstream_on_write); } -void tf_packetstream_set_on_receive(tf_packetstream_t* stream, tf_packetstream_onreceive_t* callback, void* user_data) { +void tf_packetstream_set_on_receive(tf_packetstream_t* stream, tf_packetstream_onreceive_t* callback, void* user_data) +{ stream->onreceive = callback; stream->onreceive_user_data = user_data; } @@ -110,17 +133,21 @@ static void _tf_packetstream_handle_closed(uv_handle_t* handle) { tf_packetstream_t* packetstream = handle->data; handle->data = NULL; - if (packetstream->destroyed) { + if (packetstream->destroyed) + { free(packetstream); } } -void tf_packetstream_close(tf_packetstream_t* stream) { - if (stream->stream.data && !uv_is_closing((uv_handle_t*)&stream->stream)) { +void tf_packetstream_close(tf_packetstream_t* stream) +{ + if (stream->stream.data && !uv_is_closing((uv_handle_t*)&stream->stream)) + { uv_close((uv_handle_t*)&stream->stream, _tf_packetstream_handle_closed); } } -uv_pipe_t* tf_packetstream_get_pipe(tf_packetstream_t* stream) { +uv_pipe_t* tf_packetstream_get_pipe(tf_packetstream_t* stream) +{ return &stream->stream; } diff --git a/src/serialize.c b/src/serialize.c index e7d4bc27..41e5b839 100644 --- a/src/serialize.c +++ b/src/serialize.c @@ -48,7 +48,8 @@ static int32_t _serialize_readInt32(const char** buffer, size_t* size); static int64_t _serialize_readInt64(const char** buffer, size_t* size); static double _serialize_readDouble(const char** buffer, size_t* size); -void tf_serialize_store(tf_task_t* task, tf_taskstub_t* to, void** out_buffer, size_t* out_size, JSValue value) { +void tf_serialize_store(tf_task_t* task, tf_taskstub_t* to, void** out_buffer, size_t* out_size, JSValue value) +{ buffer_t tmp = { 0 }; _serialize_store(task, to, &tmp, value); tmp.data = realloc(tmp.data, tmp.size); @@ -56,12 +57,15 @@ void tf_serialize_store(tf_task_t* task, tf_taskstub_t* to, void** out_buffer, s *out_size = tmp.size; } -JSValue tf_serialize_load(tf_task_t* task, tf_taskstub_t* from, const char* buffer, size_t size) { +JSValue tf_serialize_load(tf_task_t* task, tf_taskstub_t* from, const char* buffer, size_t size) +{ return _serialize_load(task, from, buffer, size); } -static void _buffer_append(buffer_t* buffer, const void* data, size_t size) { - if (buffer->capacity < buffer->size + size) { +static void _buffer_append(buffer_t* buffer, const void* data, size_t size) +{ + if (buffer->capacity < buffer->size + size) + { size_t new_capacity = (size + buffer->capacity) * 2; buffer->data = realloc(buffer->data, new_capacity); buffer->capacity = new_capacity; @@ -70,54 +74,64 @@ static void _buffer_append(buffer_t* buffer, const void* data, size_t size) { buffer->size += size; } -void _serialize_writeInt8(buffer_t* buffer, int8_t value) { +void _serialize_writeInt8(buffer_t* buffer, int8_t value) +{ _buffer_append(buffer, &value, sizeof(value)); } -void _serialize_writeInt32(buffer_t* buffer, int32_t value) { +void _serialize_writeInt32(buffer_t* buffer, int32_t value) +{ _buffer_append(buffer, &value, sizeof(value)); } -void _serialize_writeInt64(buffer_t* buffer, int64_t value) { +void _serialize_writeInt64(buffer_t* buffer, int64_t value) +{ _buffer_append(buffer, &value, sizeof(value)); } -void _serialize_writeDouble(buffer_t* buffer, double value) { +void _serialize_writeDouble(buffer_t* buffer, double value) +{ _buffer_append(buffer, &value, sizeof(value)); } -static void _serialize_read(const char** buffer, size_t* size, void* target, size_t target_size) { +static void _serialize_read(const char** buffer, size_t* size, void* target, size_t target_size) +{ assert(*size >= target_size); memcpy(target, *buffer, target_size); *buffer += target_size; *size -= target_size; } -static int8_t _serialize_readInt8(const char** buffer, size_t* size) { +static int8_t _serialize_readInt8(const char** buffer, size_t* size) +{ int8_t result; _serialize_read(buffer, size, &result, sizeof(result)); return result; } -int32_t _serialize_readInt32(const char** buffer, size_t* size) { +int32_t _serialize_readInt32(const char** buffer, size_t* size) +{ int32_t result; _serialize_read(buffer, size, &result, sizeof(result)); return result; } -int64_t _serialize_readInt64(const char** buffer, size_t* size) { +int64_t _serialize_readInt64(const char** buffer, size_t* size) +{ int64_t result; _serialize_read(buffer, size, &result, sizeof(result)); return result; } -double _serialize_readDouble(const char** buffer, size_t* size) { +double _serialize_readDouble(const char** buffer, size_t* size) +{ double result; _serialize_read(buffer, size, &result, sizeof(result)); return result; } -static bool _serialize_store(tf_task_t* task, tf_taskstub_t* to, buffer_t* buffer, JSValue value) { +static bool _serialize_store(tf_task_t* task, tf_taskstub_t* to, buffer_t* buffer, JSValue value) +{ return _serialize_storeInternal(task, to, buffer, value, 0); } @@ -129,16 +143,25 @@ static bool _serialize_storeInternal(tf_task_t* task, tf_taskstub_t* to, buffer_ size_t element_size; JSValue typed; uint8_t* bytes; - if (JS_IsUndefined(value)) { + if (JS_IsUndefined(value)) + { _serialize_writeInt32(buffer, kUndefined); - } else if (JS_IsUninitialized(value)) { + } + else if (JS_IsUninitialized(value)) + { _serialize_writeInt32(buffer, kUninitialized); - } else if (JS_IsNull(value)) { + } + else if (JS_IsNull(value)) + { _serialize_writeInt32(buffer, kNull); - } else if (JS_IsBool(value)) { + } + else if (JS_IsBool(value)) + { _serialize_writeInt32(buffer, kBoolean); _serialize_writeInt8(buffer, JS_ToBool(tf_task_get_context(task), value) ? 1 : 0); - } else if (JS_IsNumber(value)) { + } + else if (JS_IsNumber(value)) + { int64_t result = 0; if (JS_ToInt64(tf_task_get_context(task), &result, value) == 0) { @@ -149,7 +172,9 @@ static bool _serialize_storeInternal(tf_task_t* task, tf_taskstub_t* to, buffer_ { fprintf(stderr, "Unable to store integer.\n"); } - } else if (JS_IsNumber(value)) { + } + else if (JS_IsNumber(value)) + { double result = 0.0; if (JS_ToFloat64(tf_task_get_context(task), &result, value) == 0) { @@ -160,68 +185,93 @@ static bool _serialize_storeInternal(tf_task_t* task, tf_taskstub_t* to, buffer_ { fprintf(stderr, "Unable to store number.\n"); } - } else if (JS_IsString(value)) { + } + else if (JS_IsString(value)) + { size_t len = 0; const char* result = JS_ToCStringLen(tf_task_get_context(task), &len, value); _serialize_writeInt32(buffer, kString); _serialize_writeInt32(buffer, (int32_t)len); _buffer_append(buffer, result, len); JS_FreeCString(tf_task_get_context(task), result); - } else if ((bytes = tf_try_get_array_buffer(tf_task_get_context(task), &size, value)) != 0) { + } + else if ((bytes = tf_try_get_array_buffer(tf_task_get_context(task), &size, value)) != 0) + { _serialize_writeInt32(buffer, kArrayBuffer); _serialize_writeInt32(buffer, (int32_t)size); _buffer_append(buffer, bytes, size); - } else if (!JS_IsException((typed = tf_try_get_typed_array_buffer(tf_task_get_context(task), value, &offset, &size, &element_size)))) { + } + else if (!JS_IsException((typed = tf_try_get_typed_array_buffer(tf_task_get_context(task), value, &offset, &size, &element_size)))) + { size_t total_size; uint8_t* bytes = tf_try_get_array_buffer(tf_task_get_context(task), &total_size, typed); _serialize_writeInt32(buffer, kArrayBuffer); _serialize_writeInt32(buffer, (int32_t)size); _buffer_append(buffer, bytes, size); - } else if (JS_IsArray(tf_task_get_context(task), value)) { + } + else if (JS_IsArray(tf_task_get_context(task), value)) + { _serialize_writeInt32(buffer, kArray); JSValue length_val = JS_GetPropertyStr(tf_task_get_context(task), value, "length"); int length; - if (JS_ToInt32(tf_task_get_context(task), &length, length_val) == 0) { + if (JS_ToInt32(tf_task_get_context(task), &length, length_val) == 0) + { _serialize_writeInt32(buffer, length); - for (int i = 0; i < length; ++i) { + for (int i = 0; i < length; ++i) + { _serialize_storeInternal(task, to, buffer, JS_GetPropertyUint32(tf_task_get_context(task), value, i), depth + 1); } - } else { + } + else + { _serialize_writeInt32(buffer, 0); } - } else if (JS_IsFunction(tf_task_get_context(task), value)) { + } + else if (JS_IsFunction(tf_task_get_context(task), value)) + { _serialize_writeInt32(buffer, kFunction); exportid_t exportId = tf_task_export_function(task, to, value); _serialize_writeInt32(buffer, exportId); - } else if (JS_IsException(value)) { + } + else if (JS_IsException(value)) + { JSValue exception = JS_GetException(context); JSValue error = JS_NewObject(context); JSValue message = JS_GetPropertyStr(context, exception, "message"); - if (!JS_IsException(message)) { + if (!JS_IsException(message)) + { JS_SetPropertyStr(context, error, "message", message); - } else { + } + else + { JS_FreeValue(context, message); } - if (JS_IsError(context, exception)) { + if (JS_IsError(context, exception)) + { JSValue stack = JS_GetPropertyStr(context, exception, "stack"); - if (!JS_IsUndefined(stack)) { + if (!JS_IsUndefined(stack)) + { JS_SetPropertyStr(context, error, "stack", JS_DupValue(context, stack)); } } _serialize_writeInt32(buffer, kException); _serialize_storeInternal(task, to, buffer, error, depth + 1); JS_FreeValue(context, error); - } else if (JS_IsError(tf_task_get_context(task), value)) { + } + else if (JS_IsError(tf_task_get_context(task), value)) + { _serialize_writeInt32(buffer, kError); JSPropertyEnum* ptab; uint32_t plen; JS_GetOwnPropertyNames(tf_task_get_context(task), &ptab, &plen, value, JS_GPN_STRING_MASK); _serialize_writeInt32(buffer, plen); - for (uint32_t i = 0; i < plen; ++i) { + for (uint32_t i = 0; i < plen; ++i) + { JSValue key = JS_AtomToString(tf_task_get_context(task), ptab[i].atom); JSPropertyDescriptor desc; JSValue key_value = JS_NULL; - if (JS_GetOwnProperty(tf_task_get_context(task), &desc, value, ptab[i].atom) == 1) { + if (JS_GetOwnProperty(tf_task_get_context(task), &desc, value, ptab[i].atom) == 1) + { key_value = desc.value; } _serialize_storeInternal(task, to, buffer, key, depth + 1); @@ -229,21 +279,26 @@ static bool _serialize_storeInternal(tf_task_t* task, tf_taskstub_t* to, buffer_ JS_FreeValue(tf_task_get_context(task), key); JS_FreeValue(tf_task_get_context(task), key_value); } - for (uint32_t i = 0; i < plen; ++i) { + for (uint32_t i = 0; i < plen; ++i) + { JS_FreeAtom(tf_task_get_context(task), ptab[i].atom); } js_free(tf_task_get_context(task), ptab); - } else if (JS_IsObject(value)) { + } + else if (JS_IsObject(value)) + { _serialize_writeInt32(buffer, kObject); JSPropertyEnum* ptab; uint32_t plen; JS_GetOwnPropertyNames(tf_task_get_context(task), &ptab, &plen, value, JS_GPN_STRING_MASK); _serialize_writeInt32(buffer, plen); - for (uint32_t i = 0; i < plen; ++i) { + for (uint32_t i = 0; i < plen; ++i) + { JSValue key = JS_AtomToString(tf_task_get_context(task), ptab[i].atom); JSPropertyDescriptor desc; JSValue key_value = JS_NULL; - if (JS_GetOwnProperty(tf_task_get_context(task), &desc, value, ptab[i].atom) == 1) { + if (JS_GetOwnProperty(tf_task_get_context(task), &desc, value, ptab[i].atom) == 1) + { key_value = desc.value; } _serialize_storeInternal(task, to, buffer, key, depth + 1); @@ -251,11 +306,14 @@ static bool _serialize_storeInternal(tf_task_t* task, tf_taskstub_t* to, buffer_ JS_FreeValue(tf_task_get_context(task), key); JS_FreeValue(tf_task_get_context(task), key_value); } - for (uint32_t i = 0; i < plen; ++i) { + for (uint32_t i = 0; i < plen; ++i) + { JS_FreeAtom(tf_task_get_context(task), ptab[i].atom); } js_free(tf_task_get_context(task), ptab); - } else { + } + else + { fprintf(stderr, "Unknown JSValue type: %d.\n", JS_VALUE_GET_TAG(value)); abort(); } @@ -263,18 +321,24 @@ static bool _serialize_storeInternal(tf_task_t* task, tf_taskstub_t* to, buffer_ return true; } -static JSValue _serialize_load(tf_task_t* task, tf_taskstub_t* from, const char* buffer, size_t size) { +static JSValue _serialize_load(tf_task_t* task, tf_taskstub_t* from, const char* buffer, size_t size) +{ return _serialize_loadInternal(task, from, &buffer, &size, 0); } -static JSValue _serialize_loadInternal(tf_task_t* task, tf_taskstub_t* from, const char** buffer, size_t* size, int depth) { - if (*size < sizeof(size)) { +static JSValue _serialize_loadInternal(tf_task_t* task, tf_taskstub_t* from, const char** buffer, size_t* size, int depth) +{ + if (*size < sizeof(size)) + { return JS_UNDEFINED; - } else { + } + else + { int32_t type = _serialize_readInt32(buffer, size); JSValue result = JS_UNDEFINED; - switch (type) { + switch (type) + { case kUndefined: result = JS_UNDEFINED; break; @@ -316,7 +380,8 @@ static JSValue _serialize_loadInternal(tf_task_t* task, tf_taskstub_t* from, con { int32_t length = _serialize_readInt32(buffer, size); result = JS_NewArray(tf_task_get_context(task)); - for (int i = 0; i < length; ++i) { + for (int i = 0; i < length; ++i) + { JS_SetPropertyUint32(tf_task_get_context(task), result, i, _serialize_loadInternal(task, from, buffer, size, depth + 1)); } } @@ -332,7 +397,8 @@ static JSValue _serialize_loadInternal(tf_task_t* task, tf_taskstub_t* from, con _serialize_readInt32(buffer, size); JSValue error = JS_NewError(tf_task_get_context(task)); int32_t length = _serialize_readInt32(buffer, size); - for (int i = 0; i < length; ++i) { + for (int i = 0; i < length; ++i) + { JSValue key = _serialize_loadInternal(task, from, buffer, size, depth + 1); JSValue value = _serialize_loadInternal(task, from, buffer, size, depth + 1); const char* key_str = JS_ToCString(tf_task_get_context(task), key); @@ -348,7 +414,8 @@ static JSValue _serialize_loadInternal(tf_task_t* task, tf_taskstub_t* from, con { int32_t length = _serialize_readInt32(buffer, size); result = JS_NewObject(tf_task_get_context(task)); - for (int i = 0; i < length; ++i) { + for (int i = 0; i < length; ++i) + { JSValue key = _serialize_loadInternal(task, from, buffer, size, depth + 1); JSValue value = _serialize_loadInternal(task, from, buffer, size, depth + 1); const char* key_str = JS_ToCString(tf_task_get_context(task), key); diff --git a/src/socket.c b/src/socket.c index a44936fc..73819d69 100644 --- a/src/socket.c +++ b/src/socket.c @@ -86,23 +86,27 @@ private: }; */ -JSValue tf_socket_init(JSContext* context) { +JSValue tf_socket_init(JSContext* context) +{ JS_NewClassID(&_classId); JSClassDef def = { .class_name = "Socket", .finalizer = &_socket_finalizer, }; - if (JS_NewClass(JS_GetRuntime(context), _classId, &def) != 0) { + if (JS_NewClass(JS_GetRuntime(context), _classId, &def) != 0) + { fprintf(stderr, "Failed to register Socket.\n"); } return JS_NewCFunction2(context, _socket_create, "Socket", 0, JS_CFUNC_constructor, 0); } -int tf_socket_get_count() { +int tf_socket_get_count() +{ return _count; } -int tf_socket_get_open_count() { +int tf_socket_get_open_count() +{ return _open_count; } @@ -112,7 +116,8 @@ typedef struct _socket_resolve_data_t { promiseid_t promise; } socket_resolve_data_t; -socket_t* _socket_create_internal(JSContext* context) { +socket_t* _socket_create_internal(JSContext* context) +{ socket_t* socket = malloc(sizeof(socket_t)); memset(socket, 0, sizeof(*socket)); @@ -165,23 +170,28 @@ socket_t* _socket_create_internal(JSContext* context) { return socket; } -JSValue _socket_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ return _socket_create_internal(context)->_object; } -void _socket_finalizer(JSRuntime *runtime, JSValue value) { +void _socket_finalizer(JSRuntime *runtime, JSValue value) +{ socket_t* socket = JS_GetOpaque(value, _classId); --_count; free(socket); } -void _socket_close_internal(socket_t* socket) { - if (!uv_is_closing((uv_handle_t*)&socket->_socket)) { +void _socket_close_internal(socket_t* socket) +{ + if (!uv_is_closing((uv_handle_t*)&socket->_socket)) + { JS_FreeValue(tf_task_get_context(socket->_task), socket->_onRead); socket->_onRead = JS_UNDEFINED; JS_FreeValue(tf_task_get_context(socket->_task), socket->_onError); socket->_onError = JS_UNDEFINED; - if (socket->_tls) { + if (socket->_tls) + { tf_tls_session_destroy(socket->_tls); socket->_tls = NULL; } @@ -189,82 +199,110 @@ void _socket_close_internal(socket_t* socket) { } } -void _socket_reportError(socket_t* socket, const char* error) { - if (JS_IsFunction(tf_task_get_context(socket->_task),socket-> _onError)) { +void _socket_reportError(socket_t* socket, const char* error) +{ + if (JS_IsFunction(tf_task_get_context(socket->_task),socket-> _onError)) + { JSValue exception = JS_ThrowInternalError(tf_task_get_context(socket->_task), "%s", error); JSValue result = JS_Call(tf_task_get_context(socket->_task), socket->_onError, socket->_object, 1, &exception); - if (JS_IsException(result)) { + if (JS_IsException(result)) + { printf("Socket error.\n"); js_std_dump_error(tf_task_get_context(socket->_task)); } tf_task_run_jobs(socket->_task); JS_FreeValue(tf_task_get_context(socket->_task), exception); JS_FreeValue(tf_task_get_context(socket->_task), result); - } else { + } + else + { fprintf(stderr, "Socket::reportError: %s\n", error); } } -void _socket_reportTlsErrors(socket_t* socket) { +void _socket_reportTlsErrors(socket_t* socket) +{ char buffer[4096]; - while (socket->_tls && tf_tls_session_get_error(socket->_tls, buffer, sizeof(buffer))) { + while (socket->_tls && tf_tls_session_get_error(socket->_tls, buffer, sizeof(buffer))) + { _socket_reportError(socket, buffer); } } -JSValue _socket_startTls(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_startTls(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); - if (!socket->_tls) { + if (!socket->_tls) + { tf_tls_context_t* context = 0; - if (argc > 0 && JS_IsObject(argv[0])) { + if (argc > 0 && JS_IsObject(argv[0])) + { context = tf_tls_context_wrapper_get(argv[0]); - } else { - if (!_defaultTlsContext) { + } + else + { + if (!_defaultTlsContext) + { _defaultTlsContext = tf_tls_context_create(); } context = _defaultTlsContext; } - if (context) { + if (context) + { socket->_tls = tf_tls_context_create_session(context); } - if (socket->_tls) { + if (socket->_tls) + { tf_tls_session_set_hostname(socket->_tls, socket->_peerName); - if (socket->_direction == kAccept) { + if (socket->_direction == kAccept) + { tf_tls_session_start_accept(socket->_tls); - } else if (socket->_direction == kConnect) { + } + else if (socket->_direction == kConnect) + { tf_tls_session_start_connect(socket->_tls); } socket->_startTlsPromise = tf_task_allocate_promise(socket->_task); JSValue result = tf_task_get_promise(socket->_task, socket->_startTlsPromise); _socket_processOutgoingTls(socket); return result; - } else { + } + else + { return JS_ThrowInternalError(tf_task_get_context(socket->_task), "Failed to get TLS context"); } - } else { + } + else + { return JS_ThrowInternalError(tf_task_get_context(socket->_task), "startTls with TLS already started"); } } -JSValue _socket_stopTls(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_stopTls(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); - if (socket->_tls) { + if (socket->_tls) + { _socket_processOutgoingTls(socket); tf_tls_session_destroy(socket->_tls); socket->_tls = NULL; - } else { + } + else + { JS_ThrowInternalError(tf_task_get_context(socket->_task), "stopTls with TLS already stopped"); } return JS_NULL; } -bool _socket_processSomeOutgoingTls(socket_t* socket, promiseid_t promise, uv_write_cb callback) { +bool _socket_processSomeOutgoingTls(socket_t* socket, promiseid_t promise, uv_write_cb callback) +{ char buffer[65536]; int result = tf_tls_session_read_encrypted(socket->_tls, buffer, sizeof(buffer)); - if (result > 0) { + if (result > 0) + { char* request_buffer = malloc(sizeof(uv_write_t) + result); uv_write_t* request = (uv_write_t*)request_buffer; memset(request, 0, sizeof(*request)); @@ -279,23 +317,30 @@ bool _socket_processSomeOutgoingTls(socket_t* socket, promiseid_t promise, uv_wr }; int writeResult = uv_write(request, (uv_stream_t*)&socket->_socket, &writeBuffer, 1, callback); - if (writeResult != 0) { + if (writeResult != 0) + { free(request_buffer); char error[256]; snprintf(error, sizeof(error), "uv_write: %s", uv_strerror(writeResult)); _socket_reportError(socket, error); } - } else { + } + else + { _socket_reportTlsErrors(socket); } return result > 0; } -void _socket_processOutgoingTls(socket_t* socket) { - while (_socket_processSomeOutgoingTls(socket, -1, _socket_onWrite)) {} +void _socket_processOutgoingTls(socket_t* socket) +{ + while (_socket_processSomeOutgoingTls(socket, -1, _socket_onWrite)) + { + } } -JSValue _socket_bind(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_bind(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); const char* node = JS_ToCString(tf_task_get_context(socket->_task), argv[0]); const char* port = JS_ToCString(tf_task_get_context(socket->_task), argv[1]); @@ -313,7 +358,8 @@ JSValue _socket_bind(JSContext* context, JSValueConst this_val, int argc, JSValu data->promise = tf_task_allocate_promise(socket->_task); int result = uv_getaddrinfo(tf_task_get_loop(socket->_task), &data->resolver, _socket_onResolvedForBind, node, port, &hints); - if (result != 0) { + if (result != 0) + { char error[256]; snprintf(error, sizeof(error), "uv_getaddrinfo: %s", uv_strerror(result)); tf_task_reject_promise(socket->_task, data->promise, JS_ThrowInternalError(tf_task_get_context(socket->_task), error)); @@ -322,26 +368,34 @@ JSValue _socket_bind(JSContext* context, JSValueConst this_val, int argc, JSValu return tf_task_get_promise(socket->_task, data->promise); } -void _socket_onResolvedForBind(uv_getaddrinfo_t* resolver, int status, struct addrinfo* result) { +void _socket_onResolvedForBind(uv_getaddrinfo_t* resolver, int status, struct addrinfo* result) +{ socket_resolve_data_t* data = (socket_resolve_data_t*)resolver->data; - if (status != 0) { + if (status != 0) + { char error[256]; snprintf(error, sizeof(error), "uv_getaddrinfo: %s", uv_strerror(status)); tf_task_reject_promise(data->socket->_task, data->promise, JS_ThrowInternalError(tf_task_get_context(data->socket->_task), error)); - } else { + } + else + { int bindResult = uv_tcp_bind(&data->socket->_socket, result->ai_addr, 0); - if (bindResult != 0) { + if (bindResult != 0) + { char error[256]; snprintf(error, sizeof(error), "uv_tcp_bind: %s", uv_strerror(bindResult)); tf_task_reject_promise(data->socket->_task, data->promise, JS_ThrowInternalError(tf_task_get_context(data->socket->_task), error)); - } else { + } + else + { tf_task_resolve_promise(data->socket->_task, data->promise, JS_UNDEFINED); } } free(data); } -JSValue _socket_connect(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_connect(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); socket->_direction = kConnect; const char* node = JS_ToCString(context, argv[0]); @@ -363,7 +417,8 @@ JSValue _socket_connect(JSContext* context, JSValueConst this_val, int argc, JSV data->promise = promise; int result = uv_getaddrinfo(tf_task_get_loop(socket->_task), &data->resolver, _socket_onResolvedForConnect, node, port, &hints); - if (result != 0) { + if (result != 0) + { char error[256]; snprintf(error, sizeof(error), "uv_getaddrinfo: %s", uv_strerror(result)); tf_task_reject_promise(socket->_task, promise, JS_ThrowInternalError(context, "%s", error)); @@ -375,18 +430,23 @@ JSValue _socket_connect(JSContext* context, JSValueConst this_val, int argc, JSV return tf_task_get_promise(socket->_task, promise); } -void _socket_onResolvedForConnect(uv_getaddrinfo_t* resolver, int status, struct addrinfo* result) { +void _socket_onResolvedForConnect(uv_getaddrinfo_t* resolver, int status, struct addrinfo* result) +{ socket_resolve_data_t* data = resolver->data; - if (status != 0) { + if (status != 0) + { char error[256]; snprintf(error, sizeof(error), "uv_getaddrinfo: %s", uv_strerror(status)); tf_task_reject_promise(data->socket->_task, data->promise, JS_ThrowInternalError(tf_task_get_context(data->socket->_task), "%s", error)); - } else { + } + else + { uv_connect_t* request = malloc(sizeof(uv_connect_t)); memset(request, 0, sizeof(*request)); request->data = (void*)(intptr_t)data->promise; int connectResult = uv_tcp_connect(request, &data->socket->_socket, result->ai_addr, _socket_onConnect); - if (connectResult != 0) { + if (connectResult != 0) + { char error[256]; snprintf(error, sizeof(error), "uv_tcp_connect: %s", uv_strerror(connectResult)); tf_task_reject_promise(data->socket->_task, data->promise, JS_ThrowInternalError(tf_task_get_context(data->socket->_task), "%s", error)); @@ -396,14 +456,19 @@ void _socket_onResolvedForConnect(uv_getaddrinfo_t* resolver, int status, struct free(data); } -void _socket_onConnect(uv_connect_t* request, int status) { +void _socket_onConnect(uv_connect_t* request, int status) +{ promiseid_t promise = (intptr_t)request->data; - if (promise != -1) { + if (promise != -1) + { socket_t* socket = request->handle->data; - if (status == 0) { + if (status == 0) + { socket->_connected = true; tf_task_resolve_promise(socket->_task, promise, JS_NewInt32(tf_task_get_context(socket->_task), status)); - } else { + } + else + { char error[256]; snprintf(error, sizeof(error), "uv_tcp_connect: %s", uv_strerror(status)); tf_task_reject_promise(socket->_task, promise, JS_ThrowInternalError(tf_task_get_context(socket->_task), "%s", error)); @@ -412,29 +477,37 @@ void _socket_onConnect(uv_connect_t* request, int status) { free(request); } -JSValue _socket_listen(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_listen(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); int backlog = 1; JS_ToInt32(context, &backlog, argv[0]); - if (JS_IsUndefined(socket->_onConnect)) { + if (JS_IsUndefined(socket->_onConnect)) + { socket->_onConnect = JS_DupValue(context, argv[1]); int result = uv_listen((uv_stream_t*)&socket->_socket, backlog, _socket_onNewConnection); - if (result != 0) { + if (result != 0) + { char error[256]; snprintf(error, sizeof(error), "uv_listen: %s", uv_strerror(result)); return JS_ThrowInternalError(context, error); } return JS_NewInt32(context, result); - } else { + } + else + { return JS_ThrowInternalError(context, "listen: Already listening."); } } -void _socket_onNewConnection(uv_stream_t* server, int status) { +void _socket_onNewConnection(uv_stream_t* server, int status) +{ socket_t* socket = server->data; - if (!JS_IsUndefined(socket->_onConnect)) { + if (!JS_IsUndefined(socket->_onConnect)) + { JSValue result = JS_Call(tf_task_get_context(socket->_task), socket->_onConnect, socket->_object, 0, NULL); - if (JS_IsException(result)) { + if (JS_IsException(result)) + { printf("Socket error on connection.\n"); js_std_dump_error(tf_task_get_context(socket->_task)); } @@ -442,7 +515,8 @@ void _socket_onNewConnection(uv_stream_t* server, int status) { } } -JSValue _socket_accept(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_accept(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); socket_t* client = _socket_create_internal(context); @@ -450,10 +524,13 @@ JSValue _socket_accept(JSContext* context, JSValueConst this_val, int argc, JSVa promiseid_t promise = tf_task_allocate_promise(socket->_task); JSValue result = tf_task_get_promise(socket->_task, promise); int status = uv_accept((uv_stream_t*)&socket->_socket, (uv_stream_t*)&client->_socket); - if (status == 0) { + if (status == 0) + { client->_connected = true; tf_task_resolve_promise(socket->_task, promise, client->_object); - } else { + } + else + { char error[256]; snprintf(error, sizeof(error), "uv_accept: %s", uv_strerror(status)); tf_task_reject_promise(socket->_task, promise, JS_ThrowInternalError(context, error)); @@ -461,9 +538,11 @@ JSValue _socket_accept(JSContext* context, JSValueConst this_val, int argc, JSVa return result; } -JSValue _socket_close(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_close(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); - if (socket->_closePromise == -1) { + if (socket->_closePromise == -1) + { socket->_closePromise = tf_task_allocate_promise(socket->_task); JSValue result = tf_task_get_promise(socket->_task, socket->_closePromise); _socket_close_internal(socket); @@ -472,24 +551,30 @@ JSValue _socket_close(JSContext* context, JSValueConst this_val, int argc, JSVal return JS_UNDEFINED; } -JSValue _socket_shutdown(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_shutdown(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); promiseid_t promise = tf_task_allocate_promise(socket->_task); JSValue result = tf_task_get_promise(socket->_task, promise); - if (socket->_tls) { + if (socket->_tls) + { _socket_processTlsShutdown(socket, promise); - } else { + } + else + { _socket_shutdownInternal(socket, promise); } return result; } -void _socket_shutdownInternal(socket_t* socket, promiseid_t promise) { +void _socket_shutdownInternal(socket_t* socket, promiseid_t promise) +{ uv_shutdown_t* request = malloc(sizeof(uv_shutdown_t)); memset(request, 0, sizeof(*request)); request->data = (void*)(intptr_t)promise; int result = uv_shutdown(request, (uv_stream_t*)&socket->_socket, _socket_onShutdown); - if (result != 0) { + if (result != 0) + { char error[256]; snprintf(error, sizeof(error), "uv_shutdown: %s", uv_strerror(result)); tf_task_reject_promise(socket->_task, promise, JS_ThrowInternalError(tf_task_get_context(socket->_task), "%s", error)); @@ -497,23 +582,28 @@ void _socket_shutdownInternal(socket_t* socket, promiseid_t promise) { } } -void _socket_processTlsShutdown(socket_t* socket, promiseid_t promise) { +void _socket_processTlsShutdown(socket_t* socket, promiseid_t promise) +{ tf_tls_session_shutdown(socket->_tls); - if (!_socket_processSomeOutgoingTls(socket, promise, _socket_onTlsShutdown)) { + if (!_socket_processSomeOutgoingTls(socket, promise, _socket_onTlsShutdown)) + { _socket_shutdownInternal(socket, promise); } } -void _socket_onTlsShutdown(uv_write_t* request, int status) { +void _socket_onTlsShutdown(uv_write_t* request, int status) +{ socket_t* socket = request->handle->data; promiseid_t promise = (intptr_t)request->data; _socket_processTlsShutdown(socket, promise); free(request); } -JSValue _socket_onError(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_onError(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); - if (!JS_IsUndefined(socket->_onError)) { + if (!JS_IsUndefined(socket->_onError)) + { JS_FreeValue(context, socket->_onError); socket->_onError = JS_UNDEFINED; } @@ -521,34 +611,43 @@ JSValue _socket_onError(JSContext* context, JSValueConst this_val, int argc, JSV return JS_NULL; } -JSValue _socket_read(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_read(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); socket->_onRead = JS_DupValue(context, argv[0]); int result = uv_read_start((uv_stream_t*)&socket->_socket, _socket_allocateBuffer, _socket_onRead); promiseid_t promise = tf_task_allocate_promise(socket->_task); JSValue read_result = tf_task_get_promise(socket->_task, promise); - if (result != 0) { + if (result != 0) + { char error[256]; snprintf(error, sizeof(error), "uv_read_start: %s", uv_strerror(result)); tf_task_reject_promise(socket->_task, promise, JS_ThrowInternalError(context, error)); - } else { + } + else + { tf_task_resolve_promise(socket->_task, promise, JS_UNDEFINED); } return read_result; } -void _socket_allocateBuffer(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf) { +void _socket_allocateBuffer(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf) +{ *buf = uv_buf_init(malloc(suggestedSize), suggestedSize); } -void _socket_onRead(uv_stream_t* stream, ssize_t readSize, const uv_buf_t* buffer) { +void _socket_onRead(uv_stream_t* stream, ssize_t readSize, const uv_buf_t* buffer) +{ socket_t* socket = stream->data; - if (readSize <= 0) { + if (readSize <= 0) + { socket->_connected = false; - if (!JS_IsUndefined(socket->_onRead)) { + if (!JS_IsUndefined(socket->_onRead)) + { JSValue args[] = { JS_UNDEFINED }; JSValue result = JS_Call(tf_task_get_context(socket->_task), socket->_onRead, socket->_object, 1, args); - if (JS_IsException(result)) { + if (JS_IsException(result)) + { printf("Socket error on read.\n"); js_std_dump_error(tf_task_get_context(socket->_task)); } @@ -556,42 +655,60 @@ void _socket_onRead(uv_stream_t* stream, ssize_t readSize, const uv_buf_t* buffe tf_task_run_jobs(socket->_task); } _socket_close_internal(socket); - } else { - if (socket->_tls) { + } + else + { + if (socket->_tls) + { _socket_reportTlsErrors(socket); tf_tls_session_write_encrypted(socket->_tls, buffer->base, readSize); - if (socket->_startTlsPromise != -1) { + if (socket->_startTlsPromise != -1) + { tf_tls_handshake_t result = tf_tls_session_handshake(socket->_tls); - if (result == k_tls_handshake_done) { + if (result == k_tls_handshake_done) + { promiseid_t promise = socket->_startTlsPromise; socket->_startTlsPromise = -1; tf_task_resolve_promise(socket->_task, promise, JS_UNDEFINED); - } else if (result == k_tls_handshake_failed) { + } + else if (result == k_tls_handshake_failed) + { promiseid_t promise = socket->_startTlsPromise; socket->_startTlsPromise = -1; char buffer[8192]; - if (tf_tls_session_get_error(socket->_tls, buffer, sizeof(buffer))) { + if (tf_tls_session_get_error(socket->_tls, buffer, sizeof(buffer))) + { tf_task_reject_promise(socket->_task, promise, JS_ThrowInternalError(tf_task_get_context(socket->_task), buffer)); - } else { + } + else + { tf_task_reject_promise(socket->_task, promise, JS_UNDEFINED); } } } - while (true) { + while (true) + { char plain[8192]; int result = tf_tls_session_read_plain(socket->_tls, plain, sizeof(plain)); - if (result > 0) { + if (result > 0) + { _socket_notifyDataRead(socket, plain, result); - } else if (result == k_tls_read_failed) { + } + else if (result == k_tls_read_failed) + { _socket_reportTlsErrors(socket); _socket_close_internal(socket); break; - } else if (result == k_tls_read_zero) { - if (!JS_IsUndefined(socket->_onRead)) { + } + else if (result == k_tls_read_zero) + { + if (!JS_IsUndefined(socket->_onRead)) + { JSValue args[] = { JS_UNDEFINED }; JSValue result = JS_Call(tf_task_get_context(socket->_task), socket->_onRead, socket->_object, 1, args); - if (JS_IsException(result)) { + if (JS_IsException(result)) + { printf("Socket error on read plain.\n"); js_std_dump_error(tf_task_get_context(socket->_task)); } @@ -599,21 +716,27 @@ void _socket_onRead(uv_stream_t* stream, ssize_t readSize, const uv_buf_t* buffe tf_task_run_jobs(socket->_task); } break; - } else { + } + else + { break; } } - if (socket->_tls) { + if (socket->_tls) + { _socket_processOutgoingTls(socket); } - } else { + } + else + { _socket_notifyDataRead(socket, buffer->base, readSize); } } free(buffer->base); } -static JSValue _newUint8Array(JSContext* context, const void* data, size_t length) { +static JSValue _newUint8Array(JSContext* context, const void* data, size_t length) +{ JSValue arrayBuffer = JS_NewArrayBufferCopy(context, (const uint8_t*)data, length); JSValue global = JS_GetGlobalObject(context); JSValue constructor = JS_GetPropertyStr(context, global, "Uint8Array"); @@ -624,13 +747,17 @@ static JSValue _newUint8Array(JSContext* context, const void* data, size_t lengt return typedArray; } -void _socket_notifyDataRead(socket_t* socket, const char* data, size_t length) { - if (!JS_IsUndefined(socket->_onRead)) { - if (data && length > 0) { +void _socket_notifyDataRead(socket_t* socket, const char* data, size_t length) +{ + if (!JS_IsUndefined(socket->_onRead)) + { + if (data && length > 0) + { JSValue typedArray = _newUint8Array(tf_task_get_context(socket->_task), data, length); JSValue args[] = { typedArray }; JSValue result = JS_Call(tf_task_get_context(socket->_task), socket->_onRead, socket->_object, 1, args); - if (JS_IsException(result)) { + if (JS_IsException(result)) + { printf("Socket error on data read.\n"); js_std_dump_error(tf_task_get_context(socket->_task)); } @@ -641,36 +768,45 @@ void _socket_notifyDataRead(socket_t* socket, const char* data, size_t length) { } } -int _socket_writeBytes(socket_t* socket, promiseid_t promise, int (*callback)(socket_t* socket, promiseid_t promise, const char*, size_t), JSValue value, int* outLength) { +int _socket_writeBytes(socket_t* socket, promiseid_t promise, int (*callback)(socket_t* socket, promiseid_t promise, const char*, size_t), JSValue value, int* outLength) +{ int result = -1; size_t length; uint8_t* array = NULL; JSContext* context = tf_task_get_context(socket->_task); - if (JS_IsString(value)) { + if (JS_IsString(value)) + { const char* stringValue = JS_ToCStringLen(context, &length, value); result = callback(socket, promise, stringValue, length); JS_FreeCString(context, stringValue); - } else if ((array = tf_try_get_array_buffer(context, &length, value)) != 0) { + } + else if ((array = tf_try_get_array_buffer(context, &length, value)) != 0) + { result = callback(socket, promise, (const char*)array, length); - } else { + } + else + { size_t offset; size_t element_size; JSValue buffer = tf_try_get_typed_array_buffer(context, value, &offset, &length, &element_size); size_t size; - if ((array = tf_try_get_array_buffer(context, &size, buffer)) != 0) { + if ((array = tf_try_get_array_buffer(context, &size, buffer)) != 0) + { result = callback(socket, promise, (const char*)array, length); } JS_FreeValue(context, buffer); } - if (outLength) { + if (outLength) + { *outLength = (int)length; } return result; } -int _socket_writeInternal(socket_t* socket, promiseid_t promise, const char* data, size_t length) { +int _socket_writeInternal(socket_t* socket, promiseid_t promise, const char* data, size_t length) +{ char* rawBuffer = malloc(sizeof(uv_write_t) + length); uv_write_t* request = (uv_write_t*)rawBuffer; memcpy(rawBuffer + sizeof(uv_write_t), data, length); @@ -684,51 +820,70 @@ int _socket_writeInternal(socket_t* socket, promiseid_t promise, const char* dat return uv_write(request, (uv_stream_t*)&socket->_socket, &buffer, 1, _socket_onWrite); } -static int _socket_write_tls(socket_t* socket, promiseid_t promise, const char* data, size_t size) { +static int _socket_write_tls(socket_t* socket, promiseid_t promise, const char* data, size_t size) +{ return tf_tls_session_write_plain(socket->_tls, data, size); } -JSValue _socket_write(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_write(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); promiseid_t promise = tf_task_allocate_promise(socket->_task); JSValue write_result = tf_task_get_promise(socket->_task, promise); - if (!JS_IsUndefined(argv[0])) { - if (socket->_tls) { + if (!JS_IsUndefined(argv[0])) + { + if (socket->_tls) + { _socket_reportTlsErrors(socket); int length = 0; int result = _socket_writeBytes(socket, -1, _socket_write_tls, argv[0], &length); char buffer[8192]; - if (result <= 0 && tf_tls_session_get_error(socket->_tls, buffer, sizeof(buffer))) { + if (result <= 0 && tf_tls_session_get_error(socket->_tls, buffer, sizeof(buffer))) + { tf_task_reject_promise(socket->_task, promise, JS_ThrowInternalError(context, buffer)); - } else if (result < length) { + } + else if (result < length) + { tf_task_reject_promise(socket->_task, promise, JS_NewInt32(context, result)); - } else { + } + else + { tf_task_resolve_promise(socket->_task, promise, JS_NewInt32(context, result)); } _socket_processOutgoingTls(socket); - } else { + } + else + { int length; int result = _socket_writeBytes(socket, promise, _socket_writeInternal, argv[0], &length); - if (result != 0) { + if (result != 0) + { char error[256]; snprintf(error, sizeof(error), "uv_write: %s", uv_strerror(result)); tf_task_reject_promise(socket->_task, promise, JS_ThrowInternalError(context, error)); } } - } else { + } + else + { tf_task_reject_promise(socket->_task, promise, JS_NewInt32(context, -2)); } return write_result; } -void _socket_onWrite(uv_write_t* request, int status) { +void _socket_onWrite(uv_write_t* request, int status) +{ socket_t* socket = request->handle->data; promiseid_t promise = (intptr_t)request->data; - if (promise != -1) { - if (status == 0) { + if (promise != -1) + { + if (status == 0) + { tf_task_resolve_promise(socket->_task, promise, JS_NewInt32(tf_task_get_context(socket->_task), status)); - } else { + } + else + { char error[256]; snprintf(error, sizeof(error), "uv_write: %s", uv_strerror(status)); tf_task_reject_promise(socket->_task, promise, JS_ThrowInternalError(tf_task_get_context(socket->_task), error)); @@ -737,15 +892,18 @@ void _socket_onWrite(uv_write_t* request, int status) { free(request); } -JSValue _socket_isConnected(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_isConnected(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); return socket->_connected ? JS_TRUE : JS_FALSE; } -void _socket_onClose(uv_handle_t* handle) { +void _socket_onClose(uv_handle_t* handle) +{ --_open_count; socket_t* socket = handle->data; - if (socket->_closePromise != -1) { + if (socket->_closePromise != -1) + { promiseid_t promise = socket->_closePromise; socket->_closePromise = -1; socket->_connected = false; @@ -753,12 +911,16 @@ void _socket_onClose(uv_handle_t* handle) { } } -void _socket_onShutdown(uv_shutdown_t* request, int status) { +void _socket_onShutdown(uv_shutdown_t* request, int status) +{ socket_t* socket = request->handle->data; promiseid_t promise = (intptr_t)request->data; - if (status == 0) { + if (status == 0) + { tf_task_resolve_promise(socket->_task, promise, JS_UNDEFINED); - } else { + } + else + { char error[256]; snprintf(error, sizeof(error), "uv_shutdown: %s", uv_strerror(status)); tf_task_reject_promise(socket->_task, promise, JS_ThrowInternalError(tf_task_get_context(socket->_task), "%s", error)); @@ -766,18 +928,25 @@ void _socket_onShutdown(uv_shutdown_t* request, int status) { free(request); } -JSValue _socket_getPeerName(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_getPeerName(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); struct sockaddr_in6 addr; int nameLength = sizeof(addr); - if (uv_tcp_getpeername(&socket->_socket, (struct sockaddr*)&addr, &nameLength) == 0) { + if (uv_tcp_getpeername(&socket->_socket, (struct sockaddr*)&addr, &nameLength) == 0) + { char name[1024]; - if ((size_t)nameLength > sizeof(struct sockaddr_in)) { - if (uv_ip6_name(&addr, name, sizeof(name)) == 0) { + if ((size_t)nameLength > sizeof(struct sockaddr_in)) + { + if (uv_ip6_name(&addr, name, sizeof(name)) == 0) + { return JS_NewString(context, name); } - } else { - if (uv_ip4_name((struct sockaddr_in*)&addr, name, sizeof(name)) == 0) { + } + else + { + if (uv_ip4_name((struct sockaddr_in*)&addr, name, sizeof(name)) == 0) + { return JS_NewString(context, name); } } @@ -785,24 +954,29 @@ JSValue _socket_getPeerName(JSContext* context, JSValueConst this_val, int argc, return JS_UNDEFINED; } -JSValue _socket_getPeerCertificate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_getPeerCertificate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); - if (socket->_tls) { + if (socket->_tls) + { char buffer[128 * 1024]; int result = tf_tls_session_get_peer_certificate(socket->_tls, buffer, sizeof(buffer)); - if (result > 0) { + if (result > 0) + { return _newUint8Array(tf_task_get_context(socket->_task), buffer, sizeof(buffer)); } } return JS_UNDEFINED; } -JSValue _socket_getNoDelay(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_getNoDelay(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); return JS_NewBool(context, socket->_noDelay); } -JSValue _socket_setNoDelay(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _socket_setNoDelay(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ socket_t* socket = JS_GetOpaque(this_val, _classId); int result = JS_ToBool(context, argv[0]); socket->_noDelay = result > 0; diff --git a/src/ssb.c b/src/ssb.c index e13956e2..3d1308c7 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -194,23 +194,31 @@ static void _tf_ssb_connection_send_close(tf_ssb_connection_t* connection) _tf_ssb_nonce_inc(connection->send_nonce); uint8_t header[18] = { 0 }; - if (crypto_secretbox_easy(message_enc, header, sizeof(header), nonce1, connection->c_to_s_box_key) == 0) { + if (crypto_secretbox_easy(message_enc, header, sizeof(header), nonce1, connection->c_to_s_box_key) == 0) + { _tf_ssb_write(connection, message_enc, sizeof(message_enc)); - } else { + } + else + { _tf_ssb_connection_close(connection, "crypto_secretbox_easy close message"); } } static void _tf_ssb_connection_close(tf_ssb_connection_t* connection, const char* reason) { - if (connection->state == k_tf_ssb_state_closing) { + if (connection->state == k_tf_ssb_state_closing) + { return; - } else if (connection->state == k_tf_ssb_state_verified || - connection->state == k_tf_ssb_state_server_verified) { + } + else if (connection->state == k_tf_ssb_state_verified || + connection->state == k_tf_ssb_state_server_verified) + { printf("Connection %p is closing: %s.\n", connection, reason); connection->state = k_tf_ssb_state_closing; _tf_ssb_connection_send_close(connection); - } else { + } + else + { printf("closing: %s\n", reason); uv_close((uv_handle_t*)&connection->tcp, _tf_ssb_connection_on_close); } @@ -240,25 +248,29 @@ static void _tf_ssb_write(tf_ssb_connection_t* connection, void* data, size_t si static void _tf_ssb_connection_send_identity(tf_ssb_connection_t* connection, uint8_t* hmac, uint8_t* pubkey) { memcpy(connection->serverepub, pubkey, sizeof(connection->serverepub)); - if (crypto_auth_hmacsha512256_verify(hmac, connection->serverepub, 32, k_ssb_network) != 0) { + if (crypto_auth_hmacsha512256_verify(hmac, connection->serverepub, 32, k_ssb_network) != 0) + { _tf_ssb_connection_close(connection, "invalid server hello"); return; } uint8_t shared_secret_ab[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0) { + if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0) + { _tf_ssb_connection_close(connection, "unable to compute shared_secret_ab as client"); return; } uint8_t servercurvepub[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_sign_ed25519_pk_to_curve25519(servercurvepub, connection->serverpub) != 0) { + if (crypto_sign_ed25519_pk_to_curve25519(servercurvepub, connection->serverpub) != 0) + { _tf_ssb_connection_close(connection, "unable to compute key to curve25519 as client"); return; } uint8_t shared_secret_aB[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_scalarmult_curve25519(shared_secret_aB, connection->epriv, servercurvepub) != 0) { + if (crypto_scalarmult_curve25519(shared_secret_aB, connection->epriv, servercurvepub) != 0) + { _tf_ssb_connection_close(connection, "unable to compute shared_secret_aB as client"); return; } @@ -272,7 +284,8 @@ static void _tf_ssb_connection_send_identity(tf_ssb_connection_t* connection, ui memcpy(msg + sizeof(k_ssb_network) + sizeof(connection->serverpub), hash, sizeof(hash)); unsigned long long siglen; - if (crypto_sign_detached(connection->detached_signature_A, &siglen, msg, sizeof(msg), connection->ssb->priv) != 0) { + if (crypto_sign_detached(connection->detached_signature_A, &siglen, msg, sizeof(msg), connection->ssb->priv) != 0) + { _tf_ssb_connection_close(connection, "unable to compute detached_signature_A as client"); return; } @@ -290,7 +303,8 @@ static void _tf_ssb_connection_send_identity(tf_ssb_connection_t* connection, ui crypto_hash_sha256(hash2, tohash, sizeof(tohash)); uint8_t c[crypto_secretbox_MACBYTES + sizeof(tosend)]; - if (crypto_secretbox_easy(c, tosend, sizeof(tosend), nonce, hash2) != 0) { + if (crypto_secretbox_easy(c, tosend, sizeof(tosend), nonce, hash2) != 0) + { _tf_ssb_connection_close(connection, "unable to create initial secretbox as client"); return; } @@ -304,7 +318,8 @@ static void _tf_ssb_connection_send_identity(tf_ssb_connection_t* connection, ui static void _tf_ssb_nonce_inc(uint8_t* nonce) { int i = 23; - while (++nonce[i] == 0 && i > 0) { + while (++nonce[i] == 0 && i > 0) + { i--; } } @@ -320,7 +335,8 @@ static void _tf_ssb_connection_box_stream_send(tf_ssb_connection_t* connection, memcpy(nonce2, connection->send_nonce, sizeof(nonce2)); _tf_ssb_nonce_inc(connection->send_nonce); - if (crypto_secretbox_easy(message_enc + 34 - 16, message, size, nonce2, connection->c_to_s_box_key) != 0) { + if (crypto_secretbox_easy(message_enc + 34 - 16, message, size, nonce2, connection->c_to_s_box_key) != 0) + { _tf_ssb_connection_close(connection, "unable to secretbox message"); free(message_enc); return; @@ -329,7 +345,8 @@ static void _tf_ssb_connection_box_stream_send(tf_ssb_connection_t* connection, uint8_t header[18]; *(uint16_t*)header = htons((uint16_t)size); memcpy(header + sizeof(uint16_t), message_enc + 34 - 16, 16); - if (crypto_secretbox_easy(message_enc, header, sizeof(header), nonce1, connection->c_to_s_box_key) != 0) { + if (crypto_secretbox_easy(message_enc, header, sizeof(header), nonce1, connection->c_to_s_box_key) != 0) + { _tf_ssb_connection_close(connection, "unable to secretbox header"); free(message_enc); return; @@ -342,12 +359,16 @@ static void _tf_ssb_connection_box_stream_send(tf_ssb_connection_t* connection, static bool _tf_ssb_connection_get_request_callback(tf_ssb_connection_t* connection, int32_t request_number, tf_ssb_rpc_callback_t** out_callback, void** out_user_data) { bool found = false; - for (tf_ssb_request_t* it = connection->requests; it; it = it->next) { - if (it->request_number == request_number) { - if (out_callback) { + for (tf_ssb_request_t* it = connection->requests; it; it = it->next) + { + if (it->request_number == request_number) + { + if (out_callback) + { *out_callback = it->callback; } - if (out_user_data) { + if (out_user_data) + { *out_user_data = it->user_data; } found = true; @@ -359,11 +380,13 @@ static bool _tf_ssb_connection_get_request_callback(tf_ssb_connection_t* connect void tf_ssb_connection_add_request(tf_ssb_connection_t* connection, int32_t request_number, tf_ssb_rpc_callback_t* callback, void* user_data) { - if (_tf_ssb_connection_get_request_callback(connection, request_number, NULL, NULL)) { + if (_tf_ssb_connection_get_request_callback(connection, request_number, NULL, NULL)) + { return; } tf_ssb_request_t* request = malloc(sizeof(tf_ssb_request_t)); - *request = (tf_ssb_request_t) { + *request = (tf_ssb_request_t) + { .next = connection->requests, .request_number = request_number, .callback = callback, @@ -374,10 +397,13 @@ void tf_ssb_connection_add_request(tf_ssb_connection_t* connection, int32_t requ void tf_ssb_connection_remove_request(tf_ssb_connection_t* connection, int32_t request_number) { - for (tf_ssb_request_t** it = &connection->requests; *it; it = &(*it)->next) { - if ((*it)->request_number == request_number) { + for (tf_ssb_request_t** it = &connection->requests; *it; it = &(*it)->next) + { + if ((*it)->request_number == request_number) + { tf_ssb_request_t* found = *it; - if (found->user_data) { + if (found->user_data) + { JS_FreeValue(tf_ssb_connection_get_context(connection), JS_MKPTR(JS_TAG_OBJECT, found->user_data)); } *it = found->next; @@ -389,7 +415,8 @@ void tf_ssb_connection_remove_request(tf_ssb_connection_t* connection, int32_t r void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const uint8_t* message, size_t size, tf_ssb_rpc_callback_t* callback, void* user_data) { - if (request_number > 0) { + if (request_number > 0) + { tf_ssb_connection_add_request(connection, request_number, callback, user_data); } uint8_t* combined = malloc(9 + size); @@ -430,7 +457,8 @@ bool tf_ssb_verify_and_strip_signature(JSContext* context, JSValue val, char* ou JS_DeleteProperty(context, val, sigatom, 0); JS_FreeAtom(context, sigatom); - if (out_signature) { + if (out_signature) + { memset(out_signature, 0, out_signature_size); strncpy(out_signature, str, out_signature_size - 1); } @@ -446,19 +474,26 @@ bool tf_ssb_verify_and_strip_signature(JSContext* context, JSValue val, char* ou uint8_t publickey[crypto_box_PUBLICKEYBYTES]; int r = base64c_decode((const uint8_t*)author_id, type - author_id, publickey, sizeof(publickey)); - if (r != -1) { + if (r != -1) + { uint8_t binsig[crypto_sign_BYTES]; r = base64c_decode((const uint8_t*)str, sigkind - str, binsig, sizeof(binsig)); - if (r != -1) { + if (r != -1) + { r = crypto_sign_verify_detached(binsig, (const uint8_t*)sigstr, strlen(sigstr), publickey); verified = r == 0; - if (!verified) { + if (!verified) + { printf("crypto_sign_verify_detached fail\n"); } - } else { + } + else + { printf("base64 decode sig fail\n"); } - } else { + } + else + { printf("base64 decode author fail\n"); } @@ -473,7 +508,8 @@ bool tf_ssb_verify_and_strip_signature(JSContext* context, JSValue val, char* ou void tf_ssb_send_close(tf_ssb_t* ssb) { - for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next) { + for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next) + { _tf_ssb_connection_send_close(connection); } } @@ -497,31 +533,36 @@ static void _tf_ssb_connection_verify_identity(tf_ssb_connection_t* connection, uint8_t nonce[crypto_secretbox_NONCEBYTES] = { 0 }; uint8_t shared_secret_ab[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0) { + if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0) + { _tf_ssb_connection_close(connection, "unable to compute shared_secret_ab"); return; } uint8_t servercurvepub[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_sign_ed25519_pk_to_curve25519(servercurvepub, connection->serverpub) != 0) { + if (crypto_sign_ed25519_pk_to_curve25519(servercurvepub, connection->serverpub) != 0) + { _tf_ssb_connection_close(connection, "unable to convert key to curve25519"); return; } uint8_t shared_secret_aB[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_scalarmult_curve25519(shared_secret_aB, connection->epriv, servercurvepub) != 0) { + if (crypto_scalarmult_curve25519(shared_secret_aB, connection->epriv, servercurvepub) != 0) + { _tf_ssb_connection_close(connection, "unable to compute shared_secret_aB"); return; } uint8_t clientcurvepriv[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_sign_ed25519_sk_to_curve25519(clientcurvepriv, connection->ssb->priv) != 0) { + if (crypto_sign_ed25519_sk_to_curve25519(clientcurvepriv, connection->ssb->priv) != 0) + { _tf_ssb_connection_close(connection, "unable to convert key to curve25519"); return; } uint8_t shared_secret_Ab[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_scalarmult_curve25519(shared_secret_Ab, clientcurvepriv, connection->serverepub) != 0) { + if (crypto_scalarmult_curve25519(shared_secret_Ab, clientcurvepriv, connection->serverepub) != 0) + { _tf_ssb_connection_close(connection, "unable to compute shared_secret_Ab"); return; } @@ -545,7 +586,8 @@ static void _tf_ssb_connection_verify_identity(tf_ssb_connection_t* connection, crypto_hash_sha256(connection->c_to_s_box_key, hash3b, sizeof(hash3b)); uint8_t m[80]; - if (crypto_secretbox_open_easy(m, message, len, nonce, hash2) != 0) { + if (crypto_secretbox_open_easy(m, message, len, nonce, hash2) != 0) + { _tf_ssb_connection_close(connection, "unable to open initial secret box as client"); return; } @@ -558,20 +600,23 @@ static void _tf_ssb_connection_verify_identity(tf_ssb_connection_t* connection, memcpy(msg + sizeof(k_ssb_network), connection->detached_signature_A, sizeof(connection->detached_signature_A)); memcpy(msg + sizeof(k_ssb_network) + sizeof(connection->detached_signature_A), connection->ssb->pub, sizeof(connection->ssb->pub)); memcpy(msg + sizeof(k_ssb_network) + sizeof(connection->detached_signature_A) + sizeof(connection->ssb->pub), hash3, sizeof(hash3)); - if (crypto_sign_verify_detached(m, msg, sizeof(msg), connection->serverpub) != 0) { + if (crypto_sign_verify_detached(m, msg, sizeof(msg), connection->serverpub) != 0) + { _tf_ssb_connection_close(connection, "unable to verify server identity"); return; } uint8_t nonce2[crypto_auth_hmacsha512256_BYTES]; - if (crypto_auth_hmacsha512256(nonce2, connection->epub, sizeof(connection->epub), k_ssb_network) != 0) { + if (crypto_auth_hmacsha512256(nonce2, connection->epub, sizeof(connection->epub), k_ssb_network) != 0) + { _tf_ssb_connection_close(connection, "unable to compute client recv nonce"); return; } memcpy(connection->nonce, nonce2, sizeof(connection->nonce)); uint8_t nonce3[crypto_auth_hmacsha512256_BYTES]; - if (crypto_auth_hmacsha512256(nonce3, connection->serverepub, sizeof(connection->serverepub), k_ssb_network) != 0) { + if (crypto_auth_hmacsha512256(nonce3, connection->serverepub, sizeof(connection->serverepub), k_ssb_network) != 0) + { _tf_ssb_connection_close(connection, "unable to compute client send nonce"); return; } @@ -584,7 +629,8 @@ static void _tf_ssb_connection_verify_identity(tf_ssb_connection_t* connection, JS_SetPropertyStr(context, connection->object, "id", JS_NewString(context, fullid)); connection->state = k_tf_ssb_state_verified; - for (int i = 0; i < connection->ssb->connections_changed_count; i++) { + for (int i = 0; i < connection->ssb->connections_changed_count; i++) + { connection->ssb->connections_changed[i](connection->ssb, k_tf_ssb_change_connect, connection, connection->ssb->connections_changed_user_data[i]); } } @@ -606,10 +652,14 @@ bool tf_ssb_connection_get_id(tf_ssb_connection_t* connection, char* out_id, siz static bool _tf_ssb_is_already_connected(tf_ssb_t* ssb, uint8_t* id) { - for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next) { - if (memcmp(connection->serverpub, id, k_id_bin_len) == 0) { + for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next) + { + if (memcmp(connection->serverpub, id, k_id_bin_len) == 0) + { return true; - } else if (memcmp(ssb->pub, id, k_id_bin_len) == 0) { + } + else if (memcmp(ssb->pub, id, k_id_bin_len) == 0) + { return true; } } @@ -627,7 +677,8 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne ** ) */ uint8_t shared_secret_ab[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0) { + if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0) + { _tf_ssb_connection_close(connection, "unable to compute shared_secret_ab"); return; } @@ -639,7 +690,8 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne ** ) */ uint8_t curvepriv[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_sign_ed25519_sk_to_curve25519(curvepriv, connection->ssb->priv) != 0) { + if (crypto_sign_ed25519_sk_to_curve25519(curvepriv, connection->ssb->priv) != 0) + { _tf_ssb_connection_close(connection, "unable to convert key to curve25519"); return; } @@ -647,7 +699,8 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne static_assert(sizeof(connection->ssb->priv) == crypto_sign_ed25519_SECRETKEYBYTES, "size"); uint8_t shared_secret_aB[crypto_scalarmult_curve25519_SCALARBYTES] = { 0 }; - if (crypto_scalarmult(shared_secret_aB, curvepriv, connection->serverepub) != 0) { + if (crypto_scalarmult(shared_secret_aB, curvepriv, connection->serverepub) != 0) + { _tf_ssb_connection_close(connection, "unable to compute shared_secret_aB"); return; } @@ -675,13 +728,15 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne */ uint8_t m[96]; - if (crypto_secretbox_open_easy(m, message, len, nonce, hash2) != 0) { + if (crypto_secretbox_open_easy(m, message, len, nonce, hash2) != 0) + { _tf_ssb_connection_close(connection, "unable to open initial secret box as server"); return; } uint8_t* detached_signature_A = m; - if (_tf_ssb_is_already_connected(connection->ssb, m + 64)) { + if (_tf_ssb_is_already_connected(connection->ssb, m + 64)) + { _tf_ssb_connection_close(connection, "already connected"); return; } @@ -695,20 +750,23 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne memcpy(msg, k_ssb_network, sizeof(k_ssb_network)); memcpy(msg + sizeof(k_ssb_network), connection->ssb->pub, sizeof(connection->ssb->pub)); memcpy(msg + sizeof(k_ssb_network) + sizeof(connection->ssb->pub), hash3, sizeof(hash3)); - if (crypto_sign_verify_detached(detached_signature_A, msg, sizeof(msg), connection->serverpub) != 0) { + if (crypto_sign_verify_detached(detached_signature_A, msg, sizeof(msg), connection->serverpub) != 0) + { _tf_ssb_connection_close(connection, "unable to verify client identity"); return; } uint8_t nonce2[crypto_auth_hmacsha512256_BYTES]; - if (crypto_auth_hmacsha512256(nonce2, connection->epub, sizeof(connection->epub), k_ssb_network) != 0) { + if (crypto_auth_hmacsha512256(nonce2, connection->epub, sizeof(connection->epub), k_ssb_network) != 0) + { _tf_ssb_connection_close(connection, "unable to compute initial recv nonce as server"); return; } memcpy(connection->nonce, nonce2, sizeof(connection->nonce)); uint8_t nonce3[crypto_auth_hmacsha512256_BYTES]; - if (crypto_auth_hmacsha512256(nonce3, connection->serverepub, sizeof(connection->serverepub), k_ssb_network) != 0) { + if (crypto_auth_hmacsha512256(nonce3, connection->serverepub, sizeof(connection->serverepub), k_ssb_network) != 0) + { _tf_ssb_connection_close(connection, "unable to compute initial send nonce as server"); return; } @@ -723,19 +781,22 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne uint8_t detached_signature_B[crypto_sign_BYTES]; unsigned long long siglen; - if (crypto_sign_detached(detached_signature_B, &siglen, sign_b, sizeof(sign_b), connection->ssb->priv) != 0) { + if (crypto_sign_detached(detached_signature_B, &siglen, sign_b, sizeof(sign_b), connection->ssb->priv) != 0) + { _tf_ssb_connection_close(connection, "unable to compute detached_signature_B as server"); return; } uint8_t clientcurvepub[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_sign_ed25519_pk_to_curve25519(clientcurvepub, connection->serverpub) != 0) { + if (crypto_sign_ed25519_pk_to_curve25519(clientcurvepub, connection->serverpub) != 0) + { _tf_ssb_connection_close(connection, "unable to convert key to curve25519"); return; } uint8_t shared_secret_Ab[crypto_scalarmult_curve25519_SCALARBYTES]; - if (crypto_scalarmult_curve25519(shared_secret_Ab, connection->epriv, clientcurvepub) != 0) { + if (crypto_scalarmult_curve25519(shared_secret_Ab, connection->epriv, clientcurvepub) != 0) + { _tf_ssb_connection_close(connection, "unable to compute shared_secret_Ab as server"); return; } @@ -760,7 +821,8 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne crypto_hash_sha256(connection->c_to_s_box_key, hash3b, sizeof(hash3b)); uint8_t c[crypto_secretbox_MACBYTES + sizeof(detached_signature_B)]; - if (crypto_secretbox_easy(c, detached_signature_B, sizeof(detached_signature_B), nonce, key_hash) != 0) { + if (crypto_secretbox_easy(c, detached_signature_B, sizeof(detached_signature_B), nonce, key_hash) != 0) + { _tf_ssb_connection_close(connection, "unable to create initial secret box as server"); return; } @@ -775,19 +837,22 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne JS_SetPropertyStr(context, connection->object, "id", JS_NewString(context, fullid)); connection->state = k_tf_ssb_state_server_verified; - for (int i = 0; i < connection->ssb->connections_changed_count; i++) { + for (int i = 0; i < connection->ssb->connections_changed_count; i++) + { connection->ssb->connections_changed[i](connection->ssb, k_tf_ssb_change_connect, connection, connection->ssb->connections_changed_user_data[i]); } } static bool _tf_ssb_connection_recv_pop(tf_ssb_connection_t* connection, uint8_t* buffer, size_t size) { - if (connection->recv_size < size) { + if (connection->recv_size < size) + { return false; } memcpy(buffer, connection->recv_buffer, size); - if (connection->recv_size - size) { + if (connection->recv_size - size) + { memmove(connection->recv_buffer, connection->recv_buffer + size, connection->recv_size - size); } connection->recv_size -= size; @@ -799,30 +864,38 @@ static bool _tf_ssb_name_equals(JSContext* context, JSValue object, const char** bool result = true; JSValue name = JS_GetPropertyStr(context, object, "name"); - if (JS_IsArray(context, name)) { + if (JS_IsArray(context, name)) + { int length; JSValue lengthval = JS_GetPropertyStr(context, name, "length"); - if (JS_ToInt32(context, &length, lengthval) == 0) { - for (int i = 0; i < length; i++) { - if (!match[i]) { + if (JS_ToInt32(context, &length, lengthval) == 0) + { + for (int i = 0; i < length; i++) + { + if (!match[i]) + { result = false; break; } JSValue element = JS_GetPropertyUint32(context, name, i); const char* str = JS_ToCString(context, element); - if (!str || strcmp(str, match[i]) != 0) { + if (!str || strcmp(str, match[i]) != 0) + { result = false; } JS_FreeCString(context, str); JS_FreeValue(context, element); } - if (result && match[length]) { + if (result && match[length]) + { result = false; } } JS_FreeValue(context, lengthval); - } else { + } + else + { result = false; } @@ -832,28 +905,37 @@ static bool _tf_ssb_name_equals(JSContext* context, JSValue object, const char** static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const uint8_t* message, size_t size) { - if (flags & k_ssb_rpc_flag_json) { + if (flags & k_ssb_rpc_flag_json) + { printf("RPC RECV flags=%x RN=%d: %.*s\n", flags, request_number, (int)size, message); JSContext* context = connection->ssb->context; JSValue val = JS_ParseJSON(context, (const char*)message, size, NULL); - if (JS_IsObject(val)) { + if (JS_IsObject(val)) + { bool found = false; - for (tf_ssb_rpc_callback_node_t* it = connection->ssb->rpc; it; it = it->next) { - if (_tf_ssb_name_equals(context, val, it->name)) { + for (tf_ssb_rpc_callback_node_t* it = connection->ssb->rpc; it; it = it->next) + { + if (_tf_ssb_name_equals(context, val, it->name)) + { it->callback(connection, flags, request_number, JS_DupValue(context, val), NULL, 0, it->user_data); found = true; break; } } - if (!found) { + if (!found) + { tf_ssb_rpc_callback_t* callback = NULL; void* user_data = NULL; - if (_tf_ssb_connection_get_request_callback(connection, -request_number, &callback, &user_data)) { - if (callback) { + if (_tf_ssb_connection_get_request_callback(connection, -request_number, &callback, &user_data)) + { + if (callback) + { callback(connection, flags, request_number, JS_DupValue(context, val), NULL, 0, user_data); } - } else { + } + else + { const char* k_unsupported = "{\"message\": \"unsupported message\", \"name\": \"Error\", \"stack\": \"none\", \"args\": []}"; tf_ssb_connection_rpc_send(connection, k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error, -request_number, (const uint8_t*)k_unsupported, strlen(k_unsupported), NULL, NULL); @@ -862,26 +944,32 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t } JS_FreeValue(context, val); - } else if ((flags & k_ssb_rpc_mask_type) == k_ssb_rpc_flag_binary) { + } + else if ((flags & k_ssb_rpc_mask_type) == k_ssb_rpc_flag_binary) + { printf("RPC RECV flags=%x RN=%d: %zd bytes\n", flags, request_number, size); tf_ssb_rpc_callback_t* callback = NULL; void* user_data = NULL; - if (_tf_ssb_connection_get_request_callback(connection, -request_number, &callback, &user_data)) { - if (callback) { + if (_tf_ssb_connection_get_request_callback(connection, -request_number, &callback, &user_data)) + { + if (callback) + { callback(connection, flags, request_number, JS_UNDEFINED, message, size, user_data); } } } if (request_number < 0 && - (flags & k_ssb_rpc_flag_end_error)) { + (flags & k_ssb_rpc_flag_end_error)) + { tf_ssb_connection_remove_request(connection, -request_number); } } static void _tf_ssb_connection_rpc_recv_push(tf_ssb_connection_t* connection, const uint8_t* data, size_t size) { - if (connection->rpc_recv_size + size > sizeof(connection->rpc_recv_buffer)) { + if (connection->rpc_recv_size + size > sizeof(connection->rpc_recv_buffer)) + { _tf_ssb_connection_close(connection, "recv buffer overflow"); return; } @@ -889,7 +977,8 @@ static void _tf_ssb_connection_rpc_recv_push(tf_ssb_connection_t* connection, co memcpy(connection->rpc_recv_buffer + connection->rpc_recv_size, data, size); connection->rpc_recv_size += size; - while (connection->rpc_recv_size >= 9) { + while (connection->rpc_recv_size >= 9) + { uint8_t flags = *connection->rpc_recv_buffer; uint32_t body_len; int32_t request_number; @@ -899,7 +988,8 @@ static void _tf_ssb_connection_rpc_recv_push(tf_ssb_connection_t* connection, co request_number = htonl(request_number); size_t rpc_size = 9 + body_len; - if (connection->rpc_recv_size >= rpc_size) { + if (connection->rpc_recv_size >= rpc_size) + { uint8_t* end = &connection->rpc_recv_buffer[9 + body_len]; uint8_t tmp = *end; *end = '\0'; @@ -907,7 +997,9 @@ static void _tf_ssb_connection_rpc_recv_push(tf_ssb_connection_t* connection, co *end = tmp; memmove(connection->rpc_recv_buffer, connection->rpc_recv_buffer + rpc_size, connection->rpc_recv_size - rpc_size); connection->rpc_recv_size -= rpc_size; - } else { + } + else + { /* Wait for more body. */ break; } @@ -916,42 +1008,54 @@ static void _tf_ssb_connection_rpc_recv_push(tf_ssb_connection_t* connection, co static bool _tf_ssb_connection_box_stream_recv(tf_ssb_connection_t* connection) { - if (!connection->body_len) { + if (!connection->body_len) + { uint8_t header_enc[34]; - if (_tf_ssb_connection_recv_pop(connection, header_enc, sizeof(header_enc))) { + if (_tf_ssb_connection_recv_pop(connection, header_enc, sizeof(header_enc))) + { uint8_t header[18]; - if (crypto_secretbox_open_easy(header, header_enc, sizeof(header_enc), connection->nonce, connection->s_to_c_box_key) != 0) { + if (crypto_secretbox_open_easy(header, header_enc, sizeof(header_enc), connection->nonce, connection->s_to_c_box_key) != 0) + { _tf_ssb_connection_close(connection, "failed to open header secret box"); return false; } _tf_ssb_nonce_inc(connection->nonce); connection->body_len = htons(*(uint16_t*)header); - if (connection->body_len > k_tf_ssb_rpc_message_body_length_max) { + if (connection->body_len > k_tf_ssb_rpc_message_body_length_max) + { _tf_ssb_connection_close(connection, "body length is too large"); return false; } memcpy(connection->body_auth_tag, header + sizeof(uint16_t), sizeof(connection->body_auth_tag)); - if (!connection->body_len) { + if (!connection->body_len) + { uv_close((uv_handle_t*)&connection->tcp, _tf_ssb_connection_on_close); } - } else { + } + else + { return false; } } - if (connection->body_len) { + if (connection->body_len) + { uint8_t buf[16 + k_tf_ssb_rpc_message_body_length_max]; memcpy(buf, connection->body_auth_tag, sizeof(connection->body_auth_tag)); - if (_tf_ssb_connection_recv_pop(connection, buf + 16, connection->body_len)) { + if (_tf_ssb_connection_recv_pop(connection, buf + 16, connection->body_len)) + { uint8_t body[k_tf_ssb_rpc_message_body_length_max]; - if (crypto_secretbox_open_easy(body, buf, 16 + connection->body_len, connection->nonce, connection->s_to_c_box_key) != 0) { + if (crypto_secretbox_open_easy(body, buf, 16 + connection->body_len, connection->nonce, connection->s_to_c_box_key) != 0) + { _tf_ssb_connection_close(connection, "failed to open secret box"); return false; } _tf_ssb_nonce_inc(connection->nonce); _tf_ssb_connection_rpc_recv_push(connection, body, connection->body_len); connection->body_len = 0; - } else { + } + else + { return false; } } @@ -971,9 +1075,12 @@ void tf_ssb_append_message(tf_ssb_t* ssb, JSValue message) JSContext* context = ssb->context; JSValue root = JS_NewObject(context); - if (have_previous) { + if (have_previous) + { JS_SetPropertyStr(context, root, "previous", JS_NewString(context, previous_id)); - } else { + } + else + { JS_SetPropertyStr(context, root, "previous", JS_NULL); } JSValue authorstr = JS_NewString(context, author); @@ -1016,11 +1123,13 @@ void tf_ssb_append_message(tf_ssb_t* ssb, JSValue message) char id[sodium_base64_ENCODED_LEN(crypto_hash_sha256_BYTES, sodium_base64_VARIANT_ORIGINAL) + 1]; tf_ssb_calculate_message_id(ssb->context, root, id, sizeof(id)); if (valid && - !tf_ssb_db_store_message(ssb, ssb->context, id, root, signature_base64)) { + !tf_ssb_db_store_message(ssb, ssb->context, id, root, signature_base64)) + { printf("message not stored.\n"); } - if (!tf_ssb_verify_and_strip_signature(ssb->context, root, NULL, 0)) { + if (!tf_ssb_verify_and_strip_signature(ssb->context, root, NULL, 0)) + { printf("Failed to verify message signature.\n"); } @@ -1038,17 +1147,21 @@ static void _tf_ssb_connection_on_close(uv_handle_t* handle) handle->data = NULL; tf_ssb_t* ssb = connection->ssb; - for (tf_ssb_connection_t** it = &connection->ssb->connections; *it; it = &(*it)->next) { - if (*it == connection) { + for (tf_ssb_connection_t** it = &connection->ssb->connections; *it; it = &(*it)->next) + { + if (*it == connection) + { *it = connection->next; connection->next = NULL; break; } } - while (connection->requests) { + while (connection->requests) + { tf_ssb_connection_remove_request(connection, connection->requests->request_number); } - for (int i = 0; i < ssb->connections_changed_count; i++) { + for (int i = 0; i < ssb->connections_changed_count; i++) + { ssb->connections_changed[i](ssb, k_tf_ssb_change_remove, connection, ssb->connections_changed_user_data[i]); } JS_FreeValue(connection->ssb->context, connection->object); @@ -1057,8 +1170,10 @@ static void _tf_ssb_connection_on_close(uv_handle_t* handle) static void _tf_ssb_connection_on_tcp_recv(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { tf_ssb_connection_t* connection = stream->data; - if (nread >= 0) { - if (connection->recv_size + nread > sizeof(connection->recv_buffer)) { + if (nread >= 0) + { + if (connection->recv_size + nread > sizeof(connection->recv_buffer)) + { _tf_ssb_connection_close(connection, "recv buffer overflow"); free(buf->base); return; @@ -1066,7 +1181,8 @@ static void _tf_ssb_connection_on_tcp_recv(uv_stream_t* stream, ssize_t nread, c memcpy(connection->recv_buffer + connection->recv_size, buf->base, nread); connection->recv_size += nread; - switch (connection->state) { + switch (connection->state) + { case k_tf_ssb_state_invalid: _tf_ssb_connection_close(connection, "received a message in invalid state"); break; @@ -1076,7 +1192,8 @@ static void _tf_ssb_connection_on_tcp_recv(uv_stream_t* stream, ssize_t nread, c case k_tf_ssb_state_sent_hello: { uint8_t hello[64]; - if (_tf_ssb_connection_recv_pop(connection, hello, sizeof(hello))) { + if (_tf_ssb_connection_recv_pop(connection, hello, sizeof(hello))) + { _tf_ssb_connection_send_identity(connection, hello, hello + 32); } } @@ -1084,25 +1201,32 @@ static void _tf_ssb_connection_on_tcp_recv(uv_stream_t* stream, ssize_t nread, c case k_tf_ssb_state_sent_identity: { uint8_t identity[80]; - if (_tf_ssb_connection_recv_pop(connection, identity, sizeof(identity))) { + if (_tf_ssb_connection_recv_pop(connection, identity, sizeof(identity))) + { _tf_ssb_connection_verify_identity(connection, identity, sizeof(identity)); } } break; case k_tf_ssb_state_verified: - while (_tf_ssb_connection_box_stream_recv(connection)) {} + while (_tf_ssb_connection_box_stream_recv(connection)) + { + } break; case k_tf_ssb_state_server_wait_hello: { uint8_t hello[64]; - if (_tf_ssb_connection_recv_pop(connection, hello, sizeof(hello))) { + if (_tf_ssb_connection_recv_pop(connection, hello, sizeof(hello))) + { uint8_t* hmac = hello; memcpy(connection->serverepub, hello + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); static_assert(sizeof(connection->serverepub) == crypto_box_PUBLICKEYBYTES, "serverepub size"); - if (crypto_auth_hmacsha512256_verify(hmac, connection->serverepub, 32, k_ssb_network) != 0) { + if (crypto_auth_hmacsha512256_verify(hmac, connection->serverepub, 32, k_ssb_network) != 0) + { printf("crypto_auth_hmacsha512256_verify failed\n"); uv_close((uv_handle_t*)stream, _tf_ssb_connection_on_close); - } else { + } + else + { _tf_ssb_connection_client_send_hello((uv_stream_t*)&connection->tcp); connection->state = k_tf_ssb_state_server_wait_client_identity; } @@ -1112,18 +1236,23 @@ static void _tf_ssb_connection_on_tcp_recv(uv_stream_t* stream, ssize_t nread, c case k_tf_ssb_state_server_wait_client_identity: { uint8_t identity[112]; - if (_tf_ssb_connection_recv_pop(connection, identity, sizeof(identity))) { + if (_tf_ssb_connection_recv_pop(connection, identity, sizeof(identity))) + { _tf_ssb_connection_verify_client_identity(connection, identity, sizeof(identity)); } } break; case k_tf_ssb_state_server_verified: - while (_tf_ssb_connection_box_stream_recv(connection)) {} + while (_tf_ssb_connection_box_stream_recv(connection)) + { + } break; case k_tf_ssb_state_closing: break; } - } else { + } + else + { uv_close((uv_handle_t*)stream, _tf_ssb_connection_on_close); } free(buf->base); @@ -1134,13 +1263,15 @@ static void _tf_ssb_connection_client_send_hello(uv_stream_t* stream) tf_ssb_connection_t* connection = stream->data; char write[crypto_auth_BYTES + crypto_box_PUBLICKEYBYTES]; - if (crypto_box_keypair(connection->epub, connection->epriv) != 0) { + if (crypto_box_keypair(connection->epub, connection->epriv) != 0) + { _tf_ssb_connection_close(connection, "failed to generate ephemeral keypair"); return; } uint8_t a[crypto_auth_hmacsha512256_BYTES]; - if (crypto_auth_hmacsha512256(a, connection->epub, sizeof(connection->epub), k_ssb_network) != 0) { + if (crypto_auth_hmacsha512256(a, connection->epub, sizeof(connection->epub), k_ssb_network) != 0) + { _tf_ssb_connection_close(connection, "failed to create hello message"); return; } @@ -1157,12 +1288,15 @@ static void _tf_ssb_connection_on_connect(uv_connect_t* connect, int status) { tf_ssb_connection_t* connection = connect->data; connect->data = NULL; - if (status == 0) { + if (status == 0) + { printf("on connect\n"); connection->state = k_tf_ssb_state_connected; uv_read_start(connect->handle, _tf_ssb_connection_on_tcp_alloc, _tf_ssb_connection_on_tcp_recv); _tf_ssb_connection_client_send_hello(connect->handle); - } else { + } + else + { printf("connect => %s\n", uv_strerror(status)); uv_close((uv_handle_t*)&connection->tcp, _tf_ssb_connection_on_close); } @@ -1171,7 +1305,8 @@ static void _tf_ssb_connection_on_connect(uv_connect_t* connect, int status) static bool _tf_ssb_load_keys(tf_ssb_t* ssb) { const char* home = getenv("HOME"); - if (!home) { + if (!home) + { return false; } @@ -1180,7 +1315,8 @@ static bool _tf_ssb_load_keys(tf_ssb_t* ssb) snprintf(path, path_size, "%s%s", home, ssb->secrets_path); FILE* file = fopen(path, "rb"); - if (!file) { + if (!file) + { printf("Failed to open %s: %s.\n", path, strerror(errno)); return false; } @@ -1188,19 +1324,22 @@ static bool _tf_ssb_load_keys(tf_ssb_t* ssb) char* json = NULL; bool result = false; - if (fseek(file, 0, SEEK_END) != 0) { + if (fseek(file, 0, SEEK_END) != 0) + { printf("Failed to seek %s: %s\n.", path, strerror(errno)); goto failed; } long len = ftell(file); if (len < 0 || - fseek(file, 0, SEEK_SET) != 0) { + fseek(file, 0, SEEK_SET) != 0) + { printf("Failed to seek %s: %s\n.", path, strerror(errno)); goto failed; } json = malloc(len + 1); - if (fread(json, 1, len, file) != (size_t)len) { + if (fread(json, 1, len, file) != (size_t)len) + { printf("Failed to read %s: %s\n.", path, strerror(errno)); goto failed; } @@ -1217,7 +1356,8 @@ static bool _tf_ssb_load_keys(tf_ssb_t* ssb) JSValue privvalue = JS_GetPropertyStr(context, root, "private"); const char* privstr = JS_ToCStringLen(context, &privstrlen, privvalue); - if (pubstr && privstr) { + if (pubstr && privstr) + { result = base64c_decode((const uint8_t*)pubstr, pubstrlen - strlen(".ed25519"), ssb->pub, sizeof(ssb->pub)) != 0 && base64c_decode((const uint8_t*)privstr, privstrlen - strlen(".ed25519"), ssb->priv, sizeof(ssb->priv)) != 0; @@ -1232,11 +1372,13 @@ static bool _tf_ssb_load_keys(tf_ssb_t* ssb) JS_FreeValue(context, root); failed: - if (json) { + if (json) + { free(json); } fclose(file); - if (path) { + if (path) + { free(path); } return result; @@ -1258,7 +1400,8 @@ static bool _tf_ssb_save_keys(tf_ssb_t* ssb) snprintf(id, sizeof(id), "@%s.ed25519", public_base64); const char* home = getenv("HOME"); - if (!home) { + if (!home) + { return false; } @@ -1278,7 +1421,8 @@ static bool _tf_ssb_save_keys(tf_ssb_t* ssb) const char* json = JS_ToCStringLen(context, &len, jsonval); FILE* file = fopen(path, "wb"); - if (file) { + if (file) + { result = fwrite(json, 1, len, file) == len; fclose(file); } @@ -1296,9 +1440,12 @@ tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, sqlite3* db, const tf_ssb_t* ssb = malloc(sizeof(tf_ssb_t)); memset(ssb, 0, sizeof(*ssb)); ssb->secrets_path = secrets_path ? secrets_path : k_secrets_path; - if (context) { + if (context) + { ssb->context = context; - } else { + } + else + { ssb->own_context = true; ssb->runtime = JS_NewRuntime(); ssb->context = JS_NewContext(ssb->runtime); @@ -1312,17 +1459,23 @@ tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, sqlite3* db, const }; JS_NewClass(JS_GetRuntime(ssb->context), _connection_class_id, &def); - if (db) { + if (db) + { ssb->db = db; - } else { + } + else + { sqlite3_open("db.sqlite", &ssb->db); ssb->owns_db = true; } tf_ssb_db_init(ssb); - if (loop) { + if (loop) + { ssb->loop = loop; - } else { + } + else + { uv_loop_init(&ssb->own_loop); ssb->loop = &ssb->own_loop; } @@ -1339,7 +1492,8 @@ tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, sqlite3* db, const uv_udp_bind(&ssb->broadcast_sender, (struct sockaddr*)&broadcast_from, 0); uv_udp_set_broadcast(&ssb->broadcast_sender, 1); - if (!_tf_ssb_load_keys(ssb)) { + if (!_tf_ssb_load_keys(ssb)) + { printf("Generating a new keypair.\n"); tf_ssb_generate_keys(ssb); _tf_ssb_save_keys(ssb); @@ -1368,7 +1522,8 @@ void tf_ssb_generate_keys(tf_ssb_t* ssb) void tf_ssb_set_trace(tf_ssb_t* ssb, tf_trace_t* trace) { ssb->trace = trace; - if (trace && ssb->db) { + if (trace && ssb->db) + { tf_trace_sqlite(trace, ssb->db); } } @@ -1393,63 +1548,78 @@ void tf_ssb_destroy(tf_ssb_t* ssb) tf_ssb_connections_destroy(ssb->connections_tracker); ssb->connections_tracker = NULL; - for (int i = 0; i < ssb->connections_changed_count; i++) { - if (ssb->connections_changed_cleanup[i]) { + for (int i = 0; i < ssb->connections_changed_count; i++) + { + if (ssb->connections_changed_cleanup[i]) + { ssb->connections_changed_cleanup[i](ssb, ssb->connections_changed_user_data[i]); } } - if (ssb->broadcast_listener.data && !uv_is_closing((uv_handle_t*)&ssb->broadcast_listener)) { + if (ssb->broadcast_listener.data && !uv_is_closing((uv_handle_t*)&ssb->broadcast_listener)) + { uv_close((uv_handle_t*)&ssb->broadcast_listener, _tf_ssb_on_handle_close); } - if (ssb->broadcast_sender.data && !uv_is_closing((uv_handle_t*)&ssb->broadcast_sender)) { + if (ssb->broadcast_sender.data && !uv_is_closing((uv_handle_t*)&ssb->broadcast_sender)) + { uv_close((uv_handle_t*)&ssb->broadcast_sender, _tf_ssb_on_handle_close); } - if (ssb->broadcast_timer.data && !uv_is_closing((uv_handle_t*)&ssb->broadcast_timer)) { + if (ssb->broadcast_timer.data && !uv_is_closing((uv_handle_t*)&ssb->broadcast_timer)) + { uv_close((uv_handle_t*)&ssb->broadcast_timer, _tf_ssb_on_handle_close); } - if (ssb->server.data && !uv_is_closing((uv_handle_t*)&ssb->server)) { + if (ssb->server.data && !uv_is_closing((uv_handle_t*)&ssb->server)) + { uv_close((uv_handle_t*)&ssb->server, _tf_ssb_on_handle_close); } while (ssb->broadcast_listener.data || ssb->broadcast_sender.data || ssb->broadcast_timer.data || - ssb->server.data) { + ssb->server.data) + { uv_run(ssb->loop, UV_RUN_ONCE); } - if (ssb->loop == &ssb->own_loop) { + if (ssb->loop == &ssb->own_loop) + { uv_loop_close(ssb->loop); } - while (ssb->rpc) { + while (ssb->rpc) + { tf_ssb_rpc_callback_node_t* node = ssb->rpc; ssb->rpc = node->next; - if (node->cleanup) { + if (node->cleanup) + { node->cleanup(ssb, node->user_data); node->cleanup = NULL; } free(node); } - while (ssb->blob_want_added) { + while (ssb->blob_want_added) + { tf_ssb_blob_want_added_callback_node_t* node = ssb->blob_want_added; ssb->blob_want_added = node->next; - if (node->cleanup) { + if (node->cleanup) + { node->cleanup(ssb, node->user_data); } free(node); } - if (ssb->own_context) { + if (ssb->own_context) + { JS_FreeContext(ssb->context); JS_FreeRuntime(ssb->runtime); } - if (ssb->owns_db) { + if (ssb->owns_db) + { sqlite3_close(ssb->db); } - while (ssb->broadcasts) { + while (ssb->broadcasts) + { tf_ssb_broadcast_t* broadcast = ssb->broadcasts; ssb->broadcasts = broadcast->next; free(broadcast); @@ -1470,7 +1640,8 @@ static void _tf_ssb_connection_finalizer(JSRuntime* runtime, JSValue value) static void _tf_ssb_connection_send_json_response(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data) { - if (!user_data) { + if (!user_data) + { return; } @@ -1481,7 +1652,8 @@ static void _tf_ssb_connection_send_json_response(tf_ssb_connection_t* connectio static JSValue _tf_ssb_connection_send_json(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_ssb_connection_t* connection = JS_GetOpaque(this_val, _connection_class_id); - if (!connection) { + if (!connection) + { return JS_UNDEFINED; } @@ -1532,7 +1704,8 @@ tf_ssb_connection_t* tf_ssb_connection_create(tf_ssb_t* ssb, const char* host, c connection->next = ssb->connections; ssb->connections = connection; - for (int i = 0; i < ssb->connections_changed_count; i++) { + for (int i = 0; i < ssb->connections_changed_count; i++) + { ssb->connections_changed[i](ssb, k_tf_ssb_change_create, connection, ssb->connections_changed_user_data[i]); } return connection; @@ -1549,7 +1722,8 @@ typedef struct _connect_t { static void _tf_on_connect_getaddrinfo(uv_getaddrinfo_t* addrinfo, int result, struct addrinfo* info) { connect_t* connect = addrinfo->data; - if (result == 0 && info) { + if (result == 0 && info) + { struct sockaddr_in addr = *(struct sockaddr_in*)info->ai_addr; addr.sin_port = htons(connect->port); tf_ssb_connection_create(connect->ssb, connect->host, &addr, connect->key); @@ -1560,13 +1734,17 @@ static void _tf_on_connect_getaddrinfo(uv_getaddrinfo_t* addrinfo, int result, s void tf_ssb_connect(tf_ssb_t* ssb, const char* host, int port, const uint8_t* key) { - for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next) { - if (memcmp(connection->serverpub, key, k_id_bin_len) == 0) { + for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next) + { + if (memcmp(connection->serverpub, key, k_id_bin_len) == 0) + { char id[k_id_base64_len]; tf_ssb_id_bin_to_str(id, sizeof(id), key); printf("Not connecting to %s:%d, because we are already connected to %s.\n", host, port, id); return; - } else if (memcmp(key, ssb->pub, k_id_bin_len) == 0) { + } + else if (memcmp(key, ssb->pub, k_id_bin_len) == 0) + { char id[k_id_base64_len]; tf_ssb_id_bin_to_str(id, sizeof(id), key); printf("Not connecting to %s:%d, because they appear to be ourselves %s.\n", host, port, id); @@ -1575,7 +1753,8 @@ void tf_ssb_connect(tf_ssb_t* ssb, const char* host, int port, const uint8_t* ke } connect_t* connect = malloc(sizeof(connect_t)); - *connect = (connect_t) { + *connect = (connect_t) + { .ssb = ssb, .port = port, .req.data = connect, @@ -1583,14 +1762,17 @@ void tf_ssb_connect(tf_ssb_t* ssb, const char* host, int port, const uint8_t* ke snprintf(connect->host, sizeof(connect->host), "%s", host); memcpy(connect->key, key, k_id_bin_len); int r = uv_getaddrinfo(ssb->loop, &connect->req, _tf_on_connect_getaddrinfo, host, NULL, &(struct addrinfo) { .ai_family = AF_INET }); - if (r < 0) { + if (r < 0) + { printf("uv_getaddrinfo: %s\n", uv_strerror(r)); } } -static void _tf_ssb_on_connection(uv_stream_t* stream, int status) { +static void _tf_ssb_on_connection(uv_stream_t* stream, int status) +{ tf_ssb_t* ssb = stream->data; - if (status < 0) { + if (status < 0) + { printf("uv_listen failed: %s\n", uv_strerror(status)); return; } @@ -1605,20 +1787,23 @@ static void _tf_ssb_on_connection(uv_stream_t* stream, int status) { JS_SetPropertyStr(ssb->context, connection->object, "send_json", JS_NewCFunction(ssb->context, _tf_ssb_connection_send_json, "send_json", 2)); JS_SetOpaque(connection->object, connection); - if (uv_tcp_init(ssb->loop, &connection->tcp) != 0) { + if (uv_tcp_init(ssb->loop, &connection->tcp) != 0) + { printf("uv_tcp_init failed\n"); free(connection); return; } - if (uv_accept(stream, (uv_stream_t*)&connection->tcp) != 0) { + if (uv_accept(stream, (uv_stream_t*)&connection->tcp) != 0) + { printf("uv_accept failed\n"); return; } connection->next = ssb->connections; ssb->connections = connection; - for (int i = 0; i < ssb->connections_changed_count; i++) { + for (int i = 0; i < ssb->connections_changed_count; i++) + { ssb->connections_changed[i](ssb, k_tf_ssb_change_create, connection, ssb->connections_changed_user_data[i]); } @@ -1631,12 +1816,14 @@ static void _tf_ssb_send_broadcast(tf_ssb_t* ssb, struct sockaddr_in* address) struct sockaddr server_addr; int len = (int)sizeof(server_addr); if (uv_tcp_getsockname(&ssb->server, &server_addr, &len) != 0 || - server_addr.sa_family != AF_INET) { + server_addr.sa_family != AF_INET) + { printf("Unable to get server's address.\n"); } char address_str[256]; - if (uv_ip4_name(address, address_str, sizeof(address_str)) != 0) { + if (uv_ip4_name(address, address_str, sizeof(address_str)) != 0) + { printf("Unable to convert address to string.\n"); } @@ -1654,7 +1841,8 @@ static void _tf_ssb_send_broadcast(tf_ssb_t* ssb, struct sockaddr_in* address) broadcast_addr.sin_port = htons(8008); broadcast_addr.sin_addr.s_addr = INADDR_BROADCAST; int r = uv_udp_try_send(&ssb->broadcast_sender, &buf, 1, (struct sockaddr*)&broadcast_addr); - if (r < 0) { + if (r < 0) + { printf("failed to send broadcast %d: %s\n", r, uv_strerror(r)); } } @@ -1664,10 +1852,13 @@ static void _tf_ssb_broadcast_timer(uv_timer_t* timer) tf_ssb_t* ssb = timer->data; uv_interface_address_t* info = NULL; int count = 0; - if (uv_interface_addresses(&info, &count) == 0) { - for (int i = 0; i < count; i++) { + if (uv_interface_addresses(&info, &count) == 0) + { + for (int i = 0; i < count; i++) + { if (!info[i].is_internal && - info[i].address.address4.sin_family == AF_INET) { + info[i].address.address4.sin_family == AF_INET) + { _tf_ssb_send_broadcast(ssb, &info[i].address.address4); } } @@ -1677,13 +1868,15 @@ static void _tf_ssb_broadcast_timer(uv_timer_t* timer) void tf_ssb_server_open(tf_ssb_t* ssb, int port) { - if (ssb->server.data) { + if (ssb->server.data) + { printf("Already listening.\n"); return; } ssb->server.data = ssb; - if (uv_tcp_init(ssb->loop, &ssb->server) != 0) { + if (uv_tcp_init(ssb->loop, &ssb->server) != 0) + { printf("uv_tcp_init failed\n"); return; } @@ -1692,13 +1885,15 @@ void tf_ssb_server_open(tf_ssb_t* ssb, int port) addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; - if (uv_tcp_bind(&ssb->server, (struct sockaddr*)&addr, 0) != 0) { + if (uv_tcp_bind(&ssb->server, (struct sockaddr*)&addr, 0) != 0) + { printf("uv_tcp_bind failed\n"); return; } int status = uv_listen((uv_stream_t*)&ssb->server, SOMAXCONN, _tf_ssb_on_connection); - if (status != 0) { + if (status != 0) + { printf("uv_listen failed: %s\n", uv_strerror(status)); /* TODO: cleanup */ return; @@ -1709,7 +1904,8 @@ void tf_ssb_server_open(tf_ssb_t* ssb, int port) void tf_ssb_server_close(tf_ssb_t* ssb) { - if (ssb->server.data && !uv_is_closing((uv_handle_t*)&ssb->server)) { + if (ssb->server.data && !uv_is_closing((uv_handle_t*)&ssb->server)) + { uv_close((uv_handle_t*)&ssb->server, _tf_ssb_on_handle_close); } @@ -1726,16 +1922,22 @@ static bool _tf_ssb_parse_broadcast(const char* in_broadcast, tf_ssb_broadcast_t char public_key_str[45] = { 0 }; int port = 0; static_assert(sizeof(out_broadcast->host) == 256, "host field size"); - if (sscanf(in_broadcast, "net:%255[0-9.]:%d~shs:%44s", out_broadcast->host, &port, public_key_str) == 3) { - if (uv_inet_pton(AF_INET, out_broadcast->host, &out_broadcast->addr.sin_addr) == 0) { + if (sscanf(in_broadcast, "net:%255[0-9.]:%d~shs:%44s", out_broadcast->host, &port, public_key_str) == 3) + { + if (uv_inet_pton(AF_INET, out_broadcast->host, &out_broadcast->addr.sin_addr) == 0) + { out_broadcast->addr.sin_family = AF_INET; out_broadcast->addr.sin_port = htons((uint16_t)port); int r = base64c_decode((const uint8_t*)public_key_str, strlen(public_key_str), out_broadcast->pub, crypto_sign_PUBLICKEYBYTES); return r != -1; - } else { + } + else + { printf("pton failed\n"); } - } else { + } + else + { printf("Unsupported broadcast: %s\n", in_broadcast); } return false; @@ -1744,9 +1946,12 @@ static bool _tf_ssb_parse_broadcast(const char* in_broadcast, tf_ssb_broadcast_t void tf_ssb_connect_str(tf_ssb_t* ssb, const char* address) { tf_ssb_broadcast_t broadcast = { 0 }; - if (_tf_ssb_parse_broadcast(address, &broadcast)) { + if (_tf_ssb_parse_broadcast(address, &broadcast)) + { tf_ssb_connection_create(ssb, broadcast.host, &broadcast.addr, broadcast.pub); - } else { + } + else + { printf("Unable to parse: %s\n", address); } } @@ -1759,22 +1964,26 @@ static void _tf_ssb_on_broadcast_listener_alloc(uv_handle_t* handle, size_t sugg static void _tf_ssb_add_broadcast(tf_ssb_t* ssb, const tf_ssb_broadcast_t* broadcast) { - if (memcmp(broadcast->pub, ssb->pub, sizeof(ssb->pub)) == 0) { + if (memcmp(broadcast->pub, ssb->pub, sizeof(ssb->pub)) == 0) + { return; } - for (tf_ssb_broadcast_t* node = ssb->broadcasts; node; node = node->next) { + for (tf_ssb_broadcast_t* node = ssb->broadcasts; node; node = node->next) + { if (node->addr.sin_family == broadcast->addr.sin_family && node->addr.sin_port == broadcast->addr.sin_port && node->addr.sin_addr.s_addr == broadcast->addr.sin_addr.s_addr && - memcmp(node->pub, broadcast->pub, sizeof(node->pub)) == 0) { + memcmp(node->pub, broadcast->pub, sizeof(node->pub)) == 0) + { node->mtime = time(NULL); return; } } char key[ID_BASE64_LEN]; - if (tf_ssb_id_bin_to_str(key, sizeof(key), broadcast->pub)) { + if (tf_ssb_id_bin_to_str(key, sizeof(key), broadcast->pub)) + { tf_ssb_connections_store(ssb->connections_tracker, broadcast->host, ntohs(broadcast->addr.sin_port), key); } @@ -1785,14 +1994,16 @@ static void _tf_ssb_add_broadcast(tf_ssb_t* ssb, const tf_ssb_broadcast_t* broad node->mtime = node->ctime; ssb->broadcasts = node; - if (ssb->broadcasts_changed) { + if (ssb->broadcasts_changed) + { ssb->broadcasts_changed(ssb, ssb->broadcasts_changed_user_data); } } static void _tf_ssb_on_broadcast_listener_recv(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) { - if (nread <= 0) { + if (nread <= 0) + { free(buf->base); return; } @@ -1804,9 +2015,11 @@ static void _tf_ssb_on_broadcast_listener_recv(uv_udp_t* handle, ssize_t nread, const char* k_delim = ";"; char* state = NULL; char* entry = strtok_r(buf->base, k_delim, &state); - while (entry) { + while (entry) + { tf_ssb_broadcast_t broadcast = { 0 }; - if (_tf_ssb_parse_broadcast(entry, &broadcast)) { + if (_tf_ssb_parse_broadcast(entry, &broadcast)) + { _tf_ssb_add_broadcast(ssb, &broadcast); } entry = strtok_r(NULL, k_delim, &state); @@ -1817,8 +2030,10 @@ static void _tf_ssb_on_broadcast_listener_recv(uv_udp_t* handle, ssize_t nread, void tf_ssb_visit_broadcasts(tf_ssb_t* ssb, void (*callback)(const struct sockaddr_in* addr, const uint8_t* pub, void* user_data), void* user_data) { time_t now = time(NULL); - for (tf_ssb_broadcast_t* node = ssb->broadcasts; node; node = node->next) { - if (node->mtime - now < 60) { + for (tf_ssb_broadcast_t* node = ssb->broadcasts; node; node = node->next) + { + if (node->mtime - now < 60) + { callback(&node->addr, node->pub, user_data); } } @@ -1826,7 +2041,8 @@ void tf_ssb_visit_broadcasts(tf_ssb_t* ssb, void (*callback)(const struct sockad void tf_ssb_broadcast_listener_start(tf_ssb_t* ssb, bool linger) { - if (ssb->broadcast_listener.data) { + if (ssb->broadcast_listener.data) + { return; } @@ -1838,16 +2054,19 @@ void tf_ssb_broadcast_listener_start(tf_ssb_t* ssb, bool linger) addr.sin_port = htons(8008); addr.sin_addr.s_addr = INADDR_ANY; int result = uv_udp_bind(&ssb->broadcast_listener, (const struct sockaddr*)&addr, UV_UDP_REUSEADDR); - if (result != 0) { + if (result != 0) + { printf("bind: %s\n", uv_strerror(result)); } result = uv_udp_recv_start(&ssb->broadcast_listener, _tf_ssb_on_broadcast_listener_alloc, _tf_ssb_on_broadcast_listener_recv); - if (result != 0) { + if (result != 0) + { printf("uv_udp_recv_start: %s\n", uv_strerror(result)); } - if (!linger) { + if (!linger) + { uv_unref((uv_handle_t*)&ssb->broadcast_listener); } } @@ -1864,8 +2083,10 @@ void tf_ssb_append_post(tf_ssb_t* ssb, const char* text) const char** tf_ssb_get_connection_ids(tf_ssb_t* ssb) { int count = 0; - for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next) { - if (connection->state == k_tf_ssb_state_verified || connection->state == k_tf_ssb_state_server_verified) { + for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next) + { + if (connection->state == k_tf_ssb_state_verified || connection->state == k_tf_ssb_state_server_verified) + { count++; } } @@ -1874,8 +2095,10 @@ const char** tf_ssb_get_connection_ids(tf_ssb_t* ssb) char** array = (char**)buffer; char* strings = buffer + sizeof(char*) * (count + 1); int i = 0; - for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next) { - if (connection->state == k_tf_ssb_state_verified || connection->state == k_tf_ssb_state_server_verified) { + for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next) + { + if (connection->state == k_tf_ssb_state_verified || connection->state == k_tf_ssb_state_server_verified) + { char* write_pos = strings + k_id_base64_len * i; tf_ssb_id_bin_to_str(write_pos, k_id_base64_len, connection->serverpub); array[i++] = write_pos; @@ -1890,7 +2113,8 @@ int tf_ssb_get_connections(tf_ssb_t* ssb, tf_ssb_connection_t** out_connections, int i = 0; for (tf_ssb_connection_t* connection = ssb->connections; connection && i < out_connections_count; - connection = connection->next) { + connection = connection->next) + { out_connections[i++] = connection; } return i; @@ -1915,12 +2139,14 @@ void tf_ssb_register_rpc(tf_ssb_t* ssb, const char** name, tf_ssb_rpc_callback_t { size_t name_len = 0; int name_count = 0; - for (int i = 0; name[i]; i++) { + for (int i = 0; name[i]; i++) + { name_count++; name_len += strlen(name[i]) + 1; } tf_ssb_rpc_callback_node_t* node = malloc(sizeof(tf_ssb_rpc_callback_node_t) + (name_count + 1) * sizeof(const char*) + name_len); - *node = (tf_ssb_rpc_callback_node_t) { + *node = (tf_ssb_rpc_callback_node_t) + { .name = (const char**)(node + 1), .callback = callback, .cleanup = cleanup, @@ -1928,7 +2154,8 @@ void tf_ssb_register_rpc(tf_ssb_t* ssb, const char** name, tf_ssb_rpc_callback_t .next = ssb->rpc, }; char* p = (char*)(node + 1) + (name_count + 1) * sizeof(const char*); - for (int i = 0; i < name_count; i++) { + for (int i = 0; i < name_count; i++) + { size_t len = strlen(name[i]); memcpy(p, name[i], len + 1); node->name[i] = p; @@ -1938,11 +2165,6 @@ void tf_ssb_register_rpc(tf_ssb_t* ssb, const char** name, tf_ssb_rpc_callback_t ssb->rpc = node; } -sqlite3* tf_ssb_connection_get_db(tf_ssb_connection_t* connection) -{ - return connection->ssb->db; -} - JSContext* tf_ssb_connection_get_context(tf_ssb_connection_t* connection) { return connection->ssb->context; diff --git a/src/ssb.connections.c b/src/ssb.connections.c index f025265e..5b6c42fa 100644 --- a/src/ssb.connections.c +++ b/src/ssb.connections.c @@ -22,14 +22,16 @@ typedef struct _tf_ssb_connections_t static void _tf_ssb_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_change_t change, tf_ssb_connection_t* connection, void* user_data) { tf_ssb_connections_t* connections = user_data; - switch (change) { + switch (change) + { case k_tf_ssb_change_create: { char key[ID_BASE64_LEN]; if (tf_ssb_connection_get_host(connection) && *tf_ssb_connection_get_host(connection) && tf_ssb_connection_get_port(connection) && - tf_ssb_connection_get_id(connection, key, sizeof(key))) { + tf_ssb_connection_get_id(connection, key, sizeof(key))) + { tf_ssb_connections_store(connections, tf_ssb_connection_get_host(connection), tf_ssb_connection_get_port(connection), key); tf_ssb_connections_set_attempted(connections, tf_ssb_connection_get_host(connection), tf_ssb_connection_get_port(connection), key); } @@ -38,7 +40,8 @@ static void _tf_ssb_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_change_t case k_tf_ssb_change_connect: { char key[ID_BASE64_LEN]; - if (tf_ssb_connection_get_id(connection, key, sizeof(key))) { + if (tf_ssb_connection_get_id(connection, key, sizeof(key))) + { tf_ssb_connections_set_succeeded(connections, tf_ssb_connection_get_host(connection), tf_ssb_connection_get_port(connection), key); } } @@ -52,16 +55,20 @@ static bool _tf_ssb_connections_get_next_connection(tf_ssb_connections_t* connec { bool result = false; sqlite3_stmt* statement; - if (sqlite3_prepare(connections->db, "SELECT host, port, key FROM connections WHERE last_attempt IS NULL OR (strftime('%s', 'now') - last_attempt > $1) ORDER BY last_attempt LIMIT 1", -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(connections->db, "SELECT host, port, key FROM connections WHERE last_attempt IS NULL OR (strftime('%s', 'now') - last_attempt > $1) ORDER BY last_attempt LIMIT 1", -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_int(statement, 1, 60000) == SQLITE_OK && - sqlite3_step(statement) == SQLITE_ROW) { + sqlite3_step(statement) == SQLITE_ROW) + { snprintf(host, host_size, "%s", sqlite3_column_text(statement, 0)); *port = sqlite3_column_int(statement, 1); snprintf(key, key_size, "%s", sqlite3_column_text(statement, 2)); result = true; } sqlite3_finalize(statement); - } else { + } + else + { printf("prepare: %s\n", sqlite3_errmsg(connections->db)); } return result; @@ -72,13 +79,16 @@ static void _tf_ssb_connections_timer(uv_timer_t* timer) tf_ssb_connections_t* connections = timer->data; tf_ssb_connection_t* active[4]; int count = tf_ssb_get_connections(connections->ssb, active, _countof(active)); - if (count < _countof(active)) { + if (count < _countof(active)) + { char host[256]; int port; char key[ID_BASE64_LEN]; - if (_tf_ssb_connections_get_next_connection(connections, host, sizeof(host), &port, key, sizeof(key))) { + if (_tf_ssb_connections_get_next_connection(connections, host, sizeof(host), &port, key, sizeof(key))) + { uint8_t key_bin[ID_BIN_LEN]; - if (tf_ssb_id_str_to_bin(key_bin, key)) { + if (tf_ssb_id_str_to_bin(key_bin, key)) + { tf_ssb_connect(connections->ssb, host, port, key_bin); } } @@ -118,12 +128,15 @@ void tf_ssb_connections_destroy(tf_ssb_connections_t* connections) void tf_ssb_connections_store(tf_ssb_connections_t* connections, const char* host, int port, const char* key) { sqlite3_stmt* statement; - if (sqlite3_prepare(connections->db, "INSERT INTO connections (host, port, key) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING", -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(connections->db, "INSERT INTO connections (host, port, key) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING", -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_text(statement, 1, host, -1, NULL) == SQLITE_OK && sqlite3_bind_int(statement, 2, port) == SQLITE_OK && - sqlite3_bind_text(statement, 3, key, -1, NULL) == SQLITE_OK) { + sqlite3_bind_text(statement, 3, key, -1, NULL) == SQLITE_OK) + { int r = sqlite3_step(statement); - if (r != SQLITE_DONE) { + if (r != SQLITE_DONE) + { printf("tf_ssb_connections_store: %d, %s.\n", r, sqlite3_errmsg(connections->db)); } } @@ -134,11 +147,14 @@ void tf_ssb_connections_store(tf_ssb_connections_t* connections, const char* hos void tf_ssb_connections_set_attempted(tf_ssb_connections_t* connections, const char* host, int port, const char* key) { sqlite3_stmt* statement; - if (sqlite3_prepare(connections->db, "UPDATE connections SET last_attempt = strftime('%s', 'now') WHERE host = $1 AND port = $2 AND key = $3", -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(connections->db, "UPDATE connections SET last_attempt = strftime('%s', 'now') WHERE host = $1 AND port = $2 AND key = $3", -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_text(statement, 1, host, -1, NULL) == SQLITE_OK && sqlite3_bind_int(statement, 2, port) == SQLITE_OK && - sqlite3_bind_text(statement, 3, key, -1, NULL) == SQLITE_OK) { - if (sqlite3_step(statement) != SQLITE_DONE) { + sqlite3_bind_text(statement, 3, key, -1, NULL) == SQLITE_OK) + { + if (sqlite3_step(statement) != SQLITE_DONE) + { printf("tf_ssb_connections_set_attempted: %s.\n", sqlite3_errmsg(connections->db)); } } @@ -149,11 +165,14 @@ void tf_ssb_connections_set_attempted(tf_ssb_connections_t* connections, const c void tf_ssb_connections_set_succeeded(tf_ssb_connections_t* connections, const char* host, int port, const char* key) { sqlite3_stmt* statement; - if (sqlite3_prepare(connections->db, "UPDATE connections SET last_success = strftime('%s', 'now') WHERE host = $1 AND port = $2 AND key = $3", -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(connections->db, "UPDATE connections SET last_success = strftime('%s', 'now') WHERE host = $1 AND port = $2 AND key = $3", -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_text(statement, 1, host, -1, NULL) == SQLITE_OK && sqlite3_bind_int(statement, 2, port) == SQLITE_OK && - sqlite3_bind_text(statement, 3, key, -1, NULL) == SQLITE_OK) { - if (sqlite3_step(statement) != SQLITE_DONE) { + sqlite3_bind_text(statement, 3, key, -1, NULL) == SQLITE_OK) + { + if (sqlite3_step(statement) != SQLITE_DONE) + { printf("tf_ssb_connections_set_succeeded: %s.\n", sqlite3_errmsg(connections->db)); } } diff --git a/src/ssb.db.c b/src/ssb.db.c index 4410fc76..edb689a5 100644 --- a/src/ssb.db.c +++ b/src/ssb.db.c @@ -82,7 +82,8 @@ bool tf_ssb_db_store_message(tf_ssb_t* ssb, JSContext* context, const char* id, sqlite3_stmt* statement; int64_t last_row_id = -1; const char* query = "INSERT INTO messages (id, previous, author, sequence, timestamp, content, hash, signature) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING"; - if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && (previous ? sqlite3_bind_text(statement, 2, previous, -1, NULL) : sqlite3_bind_null(statement, 2)) == SQLITE_OK && sqlite3_bind_text(statement, 3, author, -1, NULL) == SQLITE_OK && @@ -90,9 +91,11 @@ bool tf_ssb_db_store_message(tf_ssb_t* ssb, JSContext* context, const char* id, sqlite3_bind_int64(statement, 5, timestamp) == SQLITE_OK && sqlite3_bind_text(statement, 6, contentstr, content_len, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 7, "sha256", 6, NULL) == SQLITE_OK && - sqlite3_bind_text(statement, 8, signature, -1, NULL) == SQLITE_OK) { + sqlite3_bind_text(statement, 8, signature, -1, NULL) == SQLITE_OK) + { int r = sqlite3_step(statement); - if (r != SQLITE_DONE) { + if (r != SQLITE_DONE) + { printf("%s\n", sqlite3_errmsg(db)); } stored = r == SQLITE_DONE && sqlite3_changes(db) != 0; @@ -102,27 +105,34 @@ bool tf_ssb_db_store_message(tf_ssb_t* ssb, JSContext* context, const char* id, } } sqlite3_finalize(statement); - } else { + } + else + { printf("prepare failed: %s\n", sqlite3_errmsg(db)); } if (last_row_id != -1) { query = "INSERT INTO blob_wants (id) SELECT DISTINCT json.value FROM messages, json_tree(messages.content) AS json LEFT OUTER JOIN blobs ON json.value = blobs.id WHERE messages.rowid = ?1 AND json.value LIKE '&%%.sha256' AND length(json.value) = ?2 AND blobs.content IS NULL ON CONFLICT DO NOTHING RETURNING id"; - if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_int64(statement, 1, last_row_id) == SQLITE_OK && - sqlite3_bind_int(statement, 2, BLOB_ID_LEN - 1) == SQLITE_OK) { + sqlite3_bind_int(statement, 2, BLOB_ID_LEN - 1) == SQLITE_OK) + { int r = SQLITE_OK; while ((r = sqlite3_step(statement)) == SQLITE_ROW) { tf_ssb_notify_blob_want_added(ssb, (const char*)sqlite3_column_text(statement, 0)); } - if (r != SQLITE_DONE) { + if (r != SQLITE_DONE) + { printf("%s\n", sqlite3_errmsg(db)); } } sqlite3_finalize(statement); - } else { + } + else + { printf("prepare failed: %s\n", sqlite3_errmsg(db)); } } @@ -141,17 +151,21 @@ bool tf_ssb_db_message_content_get(tf_ssb_t* ssb, const char* id, uint8_t** out_ bool result = false; sqlite3_stmt* statement; const char* query = "SELECT content FROM messages WHERE id = ?"; - if (sqlite3_prepare(tf_ssb_get_db(ssb), query, -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(tf_ssb_get_db(ssb), query, -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && - sqlite3_step(statement) == SQLITE_ROW) { + sqlite3_step(statement) == SQLITE_ROW) + { const uint8_t* blob = sqlite3_column_blob(statement, 0); int size = sqlite3_column_bytes(statement, 0); - if (out_blob) { + if (out_blob) + { *out_blob = malloc(size + 1); memcpy(*out_blob, blob, size); (*out_blob)[size] = '\0'; } - if (out_size) { + if (out_size) + { *out_size = size; } result = true; @@ -166,17 +180,21 @@ bool tf_ssb_db_blob_get(tf_ssb_t* ssb, const char* id, uint8_t** out_blob, size_ bool result = false; sqlite3_stmt* statement; const char* query = "SELECT content FROM blobs WHERE id = $1"; - if (sqlite3_prepare(tf_ssb_get_db(ssb), query, -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(tf_ssb_get_db(ssb), query, -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && - sqlite3_step(statement) == SQLITE_ROW) { + sqlite3_step(statement) == SQLITE_ROW) + { const uint8_t* blob = sqlite3_column_blob(statement, 0); int size = sqlite3_column_bytes(statement, 0); - if (out_blob) { + if (out_blob) + { *out_blob = malloc(size + 1); memcpy(*out_blob, blob, size); (*out_blob)[size] = '\0'; } - if (out_size) { + if (out_size) + { *out_size = size; } result = true; @@ -203,19 +221,26 @@ bool tf_ssb_db_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char* printf("blob store %s\n", id); const char* query = "INSERT INTO blobs (id, content, created) VALUES ($1, $2, CAST(strftime('%s') AS INTEGER)) ON CONFLICT DO NOTHING"; - if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && - sqlite3_bind_blob(statement, 2, blob, size, NULL) == SQLITE_OK) { + sqlite3_bind_blob(statement, 2, blob, size, NULL) == SQLITE_OK) + { result = sqlite3_step(statement) == SQLITE_DONE; - } else { + } + else + { printf("bind failed: %s\n", sqlite3_errmsg(db)); } sqlite3_finalize(statement); - } else { + } + else + { printf("prepare failed: %s\n", sqlite3_errmsg(db)); } - if (result && out_id) { + if (result && out_id) + { snprintf(out_id, out_id_size, "%s", id); } return result; @@ -226,23 +251,30 @@ bool tf_ssb_db_get_message_by_author_and_sequence(tf_ssb_t* ssb, const char* aut bool found = false; sqlite3_stmt* statement; const char* query = "SELECT id, timestamp, content FROM messages WHERE author = $1 AND sequence = $2"; - if (sqlite3_prepare(tf_ssb_get_db(ssb), query, -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(tf_ssb_get_db(ssb), query, -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_text(statement, 1, author, -1, NULL) == SQLITE_OK && sqlite3_bind_int64(statement, 2, sequence) == SQLITE_OK && - sqlite3_step(statement) == SQLITE_ROW) { - if (out_message_id) { + sqlite3_step(statement) == SQLITE_ROW) + { + if (out_message_id) + { strncpy(out_message_id, (const char*)sqlite3_column_text(statement, 0), out_message_id_size - 1); } - if (out_timestamp) { + if (out_timestamp) + { *out_timestamp = sqlite3_column_int64(statement, 1); } - if (out_content) { + if (out_content) + { *out_content = strdup((const char*)sqlite3_column_text(statement, 2)); } found = true; } sqlite3_finalize(statement); - } else { + } + else + { printf("prepare failed: %s\n", sqlite3_errmsg(tf_ssb_get_db(ssb))); } return found; @@ -253,77 +285,105 @@ bool tf_ssb_db_get_latest_message_by_author(tf_ssb_t* ssb, const char* author, i bool found = false; sqlite3_stmt* statement; const char* query = "SELECT id, sequence FROM messages WHERE author = $1 AND sequence = (SELECT MAX(sequence) FROM messages WHERE author = $1)"; - if (sqlite3_prepare(tf_ssb_get_db(ssb), query, -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(tf_ssb_get_db(ssb), query, -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_text(statement, 1, author, -1, NULL) == SQLITE_OK && - sqlite3_step(statement) == SQLITE_ROW) { - if (out_sequence) { + sqlite3_step(statement) == SQLITE_ROW) + { + if (out_sequence) + { *out_sequence = sqlite3_column_int64(statement, 1); } - if (out_message_id) { + if (out_message_id) + { strncpy(out_message_id, (const char*)sqlite3_column_text(statement, 0), out_message_id_size - 1); } found = true; } sqlite3_finalize(statement); - } else { + } + else + { printf("prepare failed: %s\n", sqlite3_errmsg(tf_ssb_get_db(ssb))); } return found; } -static bool _tf_ssb_sqlite_bind_json(JSContext* context, sqlite3* db, sqlite3_stmt* statement, JSValue binds) { +static bool _tf_ssb_sqlite_bind_json(JSContext* context, sqlite3* db, sqlite3_stmt* statement, JSValue binds) +{ bool all_bound = true; int32_t length = 0; - if (JS_IsUndefined(binds)) { + if (JS_IsUndefined(binds)) + { return true; } JSValue lengthval = JS_GetPropertyStr(context, binds, "length"); - if (JS_ToInt32(context, &length, lengthval) == 0) { - for (int i = 0; i < length; i++) { + if (JS_ToInt32(context, &length, lengthval) == 0) + { + for (int i = 0; i < length; i++) + { JSValue value = JS_GetPropertyUint32(context, binds, i); - if (JS_IsString(value)) { + if (JS_IsString(value)) + { size_t str_len = 0; const char* str = JS_ToCStringLen(context, &str_len, value); - if (str) { - if (sqlite3_bind_text(statement, i + 1, str, str_len, SQLITE_TRANSIENT) != SQLITE_OK) { + if (str) + { + if (sqlite3_bind_text(statement, i + 1, str, str_len, SQLITE_TRANSIENT) != SQLITE_OK) + { printf("failed to bind: %s\n", sqlite3_errmsg(db)); all_bound = false; } JS_FreeCString(context, str); - } else { + } + else + { printf("expected cstring\n"); } - } else if (JS_IsNumber(value)) { + } + else if (JS_IsNumber(value)) + { int64_t number = 0; JS_ToInt64(context, &number, value); - if (sqlite3_bind_int64(statement, i + 1, number) != SQLITE_OK) { + if (sqlite3_bind_int64(statement, i + 1, number) != SQLITE_OK) + { printf("failed to bind: %s\n", sqlite3_errmsg(db)); all_bound = false; } - } else if (JS_IsNull(value)) { - if (sqlite3_bind_null(statement, i + 1) != SQLITE_OK) { + } + else if (JS_IsNull(value)) + { + if (sqlite3_bind_null(statement, i + 1) != SQLITE_OK) + { printf("failed to bind: %s\n", sqlite3_errmsg(db)); all_bound = false; } - } else { + } + else + { const char* str = JS_ToCString(context, value); printf("expected string: %s\n", str); JS_FreeCString(context, str); } JS_FreeValue(context, value); } - } else { + } + else + { printf("expected array\n"); } JS_FreeValue(context, lengthval); return all_bound; } -static JSValue _tf_ssb_sqlite_row_to_json(JSContext* context, sqlite3_stmt* row) { +static JSValue _tf_ssb_sqlite_row_to_json(JSContext* context, sqlite3_stmt* row) +{ JSValue result = JS_NewObject(context); - for (int i = 0; i < sqlite3_column_count(row); i++) { + for (int i = 0; i < sqlite3_column_count(row); i++) + { const char* name = sqlite3_column_name(row, i); - switch (sqlite3_column_type(row, i)) { + switch (sqlite3_column_type(row, i)) + { case SQLITE_INTEGER: JS_SetPropertyStr(context, result, name, JS_NewInt64(context, sqlite3_column_int64(row, i))); break; @@ -346,7 +406,8 @@ static JSValue _tf_ssb_sqlite_row_to_json(JSContext* context, sqlite3_stmt* row) static int _tf_ssb_sqlite_authorizer(void* user_data, int action_code, const char* arg0, const char* arg1, const char* arg2, const char* arg3) { - switch (action_code) { + switch (action_code) + { case SQLITE_SELECT: case SQLITE_FUNCTION: return SQLITE_OK; @@ -365,10 +426,13 @@ void tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue binds sqlite3* db = tf_ssb_get_db(ssb); sqlite3_stmt* statement; sqlite3_set_authorizer(db, _tf_ssb_sqlite_authorizer, ssb); - if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) + { JSContext* context = tf_ssb_get_context(ssb); - if (_tf_ssb_sqlite_bind_json(context, db, statement, binds)) { - while (sqlite3_step(statement) == SQLITE_ROW) { + if (_tf_ssb_sqlite_bind_json(context, db, statement, binds)) + { + while (sqlite3_step(statement) == SQLITE_ROW) + { JSValue row = _tf_ssb_sqlite_row_to_json(context, statement); tf_trace_t* trace = tf_ssb_get_trace(ssb); tf_trace_begin(trace, "callback"); @@ -378,7 +442,9 @@ void tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue binds } } sqlite3_finalize(statement); - } else { + } + else + { printf("prepare failed: %s\n", sqlite3_errmsg(db)); } sqlite3_set_authorizer(db, NULL, NULL); diff --git a/src/ssb.export.c b/src/ssb.export.c index dfcb8fe5..b241b7d1 100644 --- a/src/ssb.export.c +++ b/src/ssb.export.c @@ -11,10 +11,13 @@ static void _write_file(const char* path, void* blob, size_t size) { FILE* file = fopen(path, "wb"); - if (file) { + if (file) + { fwrite(blob, 1, size, file); fclose(file); - } else { + } + else + { printf("Failed to open %s for write: %s.\n", path, strerror(errno)); } } @@ -23,7 +26,8 @@ void tf_ssb_export(tf_ssb_t* ssb, const char* key) { char user[256] = { 0 }; char path[256] = { 0 }; - if (sscanf(key, "/~%255[^/]/%255s", user, path) != 2) { + if (sscanf(key, "/~%255[^/]/%255s", user, path) != 2) + { printf("Unable to export %s.\n", key); return; } @@ -31,12 +35,15 @@ void tf_ssb_export(tf_ssb_t* ssb, const char* key) char app_blob_id[64] = { 0 }; sqlite3_stmt* statement; - if (sqlite3_prepare(tf_ssb_get_db(ssb), "SELECT value FROM properties WHERE id = $1 AND key = 'path:' || $2", -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(tf_ssb_get_db(ssb), "SELECT value FROM properties WHERE id = $1 AND key = 'path:' || $2", -1, &statement, NULL) == SQLITE_OK) + { if (sqlite3_bind_text(statement, 1, user, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, path, -1, NULL) == SQLITE_OK && - sqlite3_step(statement) == SQLITE_ROW) { + sqlite3_step(statement) == SQLITE_ROW) + { int len = sqlite3_column_bytes(statement, 0); - if (len >= (int)sizeof(app_blob_id)) { + if (len >= (int)sizeof(app_blob_id)) + { len = sizeof(app_blob_id) - 1; } memcpy(app_blob_id, sqlite3_column_text(statement, 0), len); @@ -45,14 +52,16 @@ void tf_ssb_export(tf_ssb_t* ssb, const char* key) sqlite3_finalize(statement); } - if (!*app_blob_id) { + if (!*app_blob_id) + { printf("Did not find app blob ID for %s.\n", key); return; } uint8_t* blob = NULL; size_t size = 0; - if (!tf_ssb_db_blob_get(ssb, app_blob_id, &blob, &size)) { + if (!tf_ssb_db_blob_get(ssb, app_blob_id, &blob, &size)) + { printf("Did not find blob for %s: %s.\n", key, app_blob_id); return; } @@ -66,17 +75,21 @@ void tf_ssb_export(tf_ssb_t* ssb, const char* key) JSValue files = JS_GetPropertyStr(context, app, "files"); JSPropertyEnum* ptab = NULL; uint32_t plen = 0; - if (JS_GetOwnPropertyNames(context, &ptab, &plen, files, JS_GPN_STRING_MASK) == 0) { - for (uint32_t i = 0; i < plen; ++i) { + if (JS_GetOwnPropertyNames(context, &ptab, &plen, files, JS_GPN_STRING_MASK) == 0) + { + for (uint32_t i = 0; i < plen; ++i) + { JSPropertyDescriptor desc; - if (JS_GetOwnProperty(context, &desc, files, ptab[i].atom) == 1) { + if (JS_GetOwnProperty(context, &desc, files, ptab[i].atom) == 1) + { JSValue key = JS_AtomToString(context, ptab[i].atom); const char* file_name = JS_ToCString(context, key); const char* blob_id = JS_ToCString(context, desc.value); uint8_t* file_blob = NULL; size_t file_size = 0; - if (tf_ssb_db_blob_get(ssb, blob_id, &file_blob, &file_size)) { + if (tf_ssb_db_blob_get(ssb, blob_id, &file_blob, &file_size)) + { snprintf(file_path, sizeof(file_path), "apps/%s/%s/%s", user, path, file_name); _write_file(file_path, file_blob, file_size); free(file_blob); @@ -90,7 +103,8 @@ void tf_ssb_export(tf_ssb_t* ssb, const char* key) } } - for (uint32_t i = 0; i < plen; ++i) { + for (uint32_t i = 0; i < plen; ++i) + { JS_FreeAtom(context, ptab[i].atom); } js_free(context, ptab); diff --git a/src/ssb.import.c b/src/ssb.import.c index 1e34f617..2aafc58c 100644 --- a/src/ssb.import.c +++ b/src/ssb.import.c @@ -33,17 +33,22 @@ static void _tf_ssb_import_file_read(uv_fs_t* req) { tf_import_file_t* file = req->data; char id[k_id_base64_len]; - if (req->result >= 0) { - if (tf_ssb_db_blob_store(file->ssb, (const uint8_t*)file->data, req->result, id, sizeof(id))) { + if (req->result >= 0) + { + if (tf_ssb_db_blob_store(file->ssb, (const uint8_t*)file->data, req->result, id, sizeof(id))) + { printf("Stored %s/%s as %s.\n", file->parent, file->name, id); - if (strcasecmp(file->name + strlen(file->name) - strlen(".json"), ".json") == 0) { + if (strcasecmp(file->name + strlen(file->name) - strlen(".json"), ".json") == 0) + { sqlite3_stmt* statement; - if (sqlite3_prepare(tf_ssb_get_db(file->ssb), "INSERT OR REPLACE INTO properties (id, key, value) VALUES ($1, 'path:' || $2, $3)", -1, &statement, NULL) == SQLITE_OK) { + if (sqlite3_prepare(tf_ssb_get_db(file->ssb), "INSERT OR REPLACE INTO properties (id, key, value) VALUES ($1, 'path:' || $2, $3)", -1, &statement, NULL) == SQLITE_OK) + { ((char*)file->name)[strlen(file->name) - strlen(".json")] = '\0'; if (sqlite3_bind_text(statement, 1, file->user, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, file->name, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 3, id, -1, NULL) == SQLITE_OK && - sqlite3_step(statement) == SQLITE_DONE) { + sqlite3_step(statement) == SQLITE_DONE) + { printf("Registered %s path:%s as %s.\n", file->user, file->name, id); } sqlite3_finalize(statement); @@ -75,13 +80,17 @@ static void _tf_ssb_import_scandir(uv_fs_t* req) { tf_import_t* import = req->data; uv_dirent_t ent; - while (uv_fs_scandir_next(req, &ent) == 0) { + while (uv_fs_scandir_next(req, &ent) == 0) + { size_t len = strlen(import->parent) + strlen(ent.name) + 2; char* path = malloc(len); snprintf(path, len, "%s/%s", import->parent, ent.name); - if (ent.type == UV_DIRENT_DIR) { + if (ent.type == UV_DIRENT_DIR) + { tf_ssb_import(import->ssb, import->user, path); - } else { + } + else + { size_t size = sizeof(tf_import_file_t) + strlen(import->parent) +1 + strlen(ent.name) + 1; tf_import_file_t* file = malloc(size); memset(file, 0, size); @@ -96,7 +105,8 @@ static void _tf_ssb_import_scandir(uv_fs_t* req) import->work_left++; int r = uv_fs_open(tf_ssb_get_loop(import->ssb), &file->req, path, 0, 0, _tf_ssb_import_file_open); - if (r < 0) { + if (r < 0) + { printf("Failed to open %s: %s.\n", path, uv_strerror(r)); free(file); import->work_left--; @@ -117,11 +127,13 @@ void tf_ssb_import(tf_ssb_t* ssb, const char* user, const char* path) }; import.req.data = &import; int r = uv_fs_scandir(tf_ssb_get_loop(ssb), &import.req, path, 0, _tf_ssb_import_scandir); - if (r) { + if (r) + { printf("Failed to scan directory %s: %s.", path, uv_strerror(r)); } - while (import.work_left > 0) { + while (import.work_left > 0) + { uv_run(tf_ssb_get_loop(ssb), UV_RUN_ONCE); } uv_fs_req_cleanup(&import.req); diff --git a/src/ssb.qjs.c b/src/ssb.qjs.c index e2fcc157..d5be2529 100644 --- a/src/ssb.qjs.c +++ b/src/ssb.qjs.c @@ -19,9 +19,11 @@ static JSValue _tf_ssb_whoami(JSContext* context, JSValueConst this_val, int arg { tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); printf("WHOAMI on %p\n", ssb); - if (ssb) { + if (ssb) + { char id[512]; - if (tf_ssb_whoami(ssb, id, sizeof(id))) { + if (tf_ssb_whoami(ssb, id, sizeof(id))) + { return JS_NewString(context, id); } } @@ -32,13 +34,15 @@ static JSValue _tf_ssb_getMessage(JSContext* context, JSValueConst this_val, int { JSValue result = JS_NULL; tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) { + if (ssb) + { const char* id = JS_ToCString(context, argv[0]); int64_t sequence = 0; JS_ToInt64(context, &sequence, argv[1]); int64_t timestamp = -1; char* contents = NULL; - if (tf_ssb_db_get_message_by_author_and_sequence(ssb, id, sequence, NULL, 0, ×tamp, &contents)) { + if (tf_ssb_db_get_message_by_author_and_sequence(ssb, id, sequence, NULL, 0, ×tamp, &contents)) + { result = JS_NewObject(context); JS_SetPropertyStr(context, result, "timestamp", JS_NewInt64(context, timestamp)); JS_SetPropertyStr(context, result, "content", JS_NewString(context, contents)); @@ -53,11 +57,13 @@ static JSValue _tf_ssb_blobGet(JSContext* context, JSValueConst this_val, int ar { JSValue result = JS_NULL; tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) { + if (ssb) + { const char* id = JS_ToCString(context, argv[0]); uint8_t* blob = NULL; size_t size = 0; - if (tf_ssb_db_blob_get(ssb, id, &blob, &size)) { + if (tf_ssb_db_blob_get(ssb, id, &blob, &size)) + { result = JS_NewArrayBufferCopy(context, blob, size); free(blob); } @@ -70,18 +76,24 @@ static JSValue _tf_ssb_blobStore(JSContext* context, JSValueConst this_val, int { JSValue result = JS_NULL; tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) { + if (ssb) + { uint8_t* blob = NULL; size_t size = 0; char id[512]; - if (JS_IsString(argv[0])) { + if (JS_IsString(argv[0])) + { const char* text = JS_ToCStringLen(context, &size, argv[0]); - if (tf_ssb_db_blob_store(ssb, (const uint8_t*)text, size, id, sizeof(id))) { + if (tf_ssb_db_blob_store(ssb, (const uint8_t*)text, size, id, sizeof(id))) + { result = JS_NewString(context, id); } JS_FreeCString(context, text); - } else if ((blob = tf_try_get_array_buffer(context, &size, argv[0])) != 0) { - if (tf_ssb_db_blob_store(ssb, blob, size, id, sizeof(id))) { + } + else if ((blob = tf_try_get_array_buffer(context, &size, argv[0])) != 0) + { + if (tf_ssb_db_blob_store(ssb, blob, size, id, sizeof(id))) + { result = JS_NewString(context, id); } } @@ -93,11 +105,13 @@ static JSValue _tf_ssb_messageContentGet(JSContext* context, JSValueConst this_v { JSValue result = JS_NULL; tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) { + if (ssb) + { const char* id = JS_ToCString(context, argv[0]); uint8_t* blob = NULL; size_t size = 0; - if (tf_ssb_db_message_content_get(ssb, id, &blob, &size)) { + if (tf_ssb_db_message_content_get(ssb, id, &blob, &size)) + { result = JS_NewArrayBufferCopy(context, blob, size); free(blob); } @@ -110,12 +124,15 @@ static JSValue _tf_ssb_connections(JSContext* context, JSValueConst this_val, in { JSValue result = JS_NULL; tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) { + if (ssb) + { const char** connections = tf_ssb_get_connection_ids(ssb); - if (connections) { + if (connections) + { result = JS_NewArray(context); uint32_t i = 0; - for (const char** p = connections; *p; p++, i++) { + for (const char** p = connections; *p; p++, i++) + { JS_SetPropertyUint32(context, result, i, JS_NewString(context, *p)); } free(connections); @@ -132,7 +149,8 @@ static void _check_call(JSContext* context, JSValue result) printf("ERROR: %s\n", value); JS_FreeCString(context, value); JSValue stack = JS_GetPropertyStr(context, result, "stack"); - if (!JS_IsUndefined(stack)) { + if (!JS_IsUndefined(stack)) + { const char* stack_str = JS_ToCString(context, stack); printf("%s\n", stack_str); JS_FreeCString(context, stack_str); @@ -157,7 +175,8 @@ typedef struct _sqlStream_callback_t JSValue callback; } sqlStream_callback_t; -static void _tf_ssb_sqlStream_callback(JSValue row, void* user_data) { +static void _tf_ssb_sqlStream_callback(JSValue row, void* user_data) +{ sqlStream_callback_t* info = user_data; JSValue response = JS_Call(info->context, info->callback, JS_UNDEFINED, 1, &row); _check_call(info->context, response); @@ -171,9 +190,11 @@ static void _tf_ssb_sqlStream_callback(JSValue row, void* user_data) { static JSValue _tf_ssb_sqlStream(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) { + if (ssb) + { const char* query = JS_ToCString(context, argv[0]); - if (query) { + if (query) + { sqlStream_callback_t info = { .context = context, .callback = argv[2], @@ -188,9 +209,11 @@ static JSValue _tf_ssb_sqlStream(JSContext* context, JSValueConst this_val, int static JSValue _tf_ssb_post(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) { + if (ssb) + { const char* post_text = JS_ToCString(context, argv[0]); - if (post_text) { + if (post_text) + { tf_ssb_append_post(ssb, post_text); JS_FreeCString(context, post_text); } @@ -201,7 +224,8 @@ static JSValue _tf_ssb_post(JSContext* context, JSValueConst this_val, int argc, static JSValue _tf_ssb_appendMessage(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) { + if (ssb) + { tf_ssb_append_message(ssb, argv[0]); } return JS_NULL; @@ -213,9 +237,12 @@ static JSValue _tf_ssb_storeMessage(JSContext* context, JSValueConst this_val, i char signature[crypto_sign_BYTES + 128]; char id[crypto_hash_sha256_BYTES * 2 + 1]; tf_ssb_calculate_message_id(context, argv[0], id, sizeof(id)); - if (tf_ssb_verify_and_strip_signature(context, argv[0], signature, sizeof(signature))) { + if (tf_ssb_verify_and_strip_signature(context, argv[0], signature, sizeof(signature))) + { tf_ssb_db_store_message(ssb, context, id, argv[0], signature); - } else { + } + else + { printf("failed to verify message\n"); } return JS_UNDEFINED; @@ -246,7 +273,8 @@ static JSValue _tf_ssb_getBroadcasts(JSContext* context, JSValueConst this_val, { JSValue result = JS_UNDEFINED; tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) { + if (ssb) + { result = JS_NewArray(context); broadcasts_t broadcasts = { .context = context, @@ -262,13 +290,17 @@ static JSValue _tf_ssb_connect(JSContext* context, JSValueConst this_val, int ar { JSValue args = argv[0]; tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) { - if (JS_IsString(args)) { + if (ssb) + { + if (JS_IsString(args)) + { const char* address_str = JS_ToCString(context, args); printf("Connecting to %s\n", address_str); tf_ssb_connect_str(ssb, address_str); JS_FreeCString(context, address_str); - } else { + } + else + { JSValue address = JS_GetPropertyStr(context, args, "address"); JSValue port = JS_GetPropertyStr(context, args, "port"); JSValue pubkey = JS_GetPropertyStr(context, args, "pubkey"); @@ -296,7 +328,8 @@ static void _tf_ssb_call_callback(tf_ssb_t* ssb, const char* name, void* user_da JSValue global = JS_GetGlobalObject(context); JSValue ssbo = JS_GetPropertyStr(context, global, "ssb"); JSValue callback = JS_GetPropertyStr(context, ssbo, name); - if (JS_IsFunction(context, callback)) { + if (JS_IsFunction(context, callback)) + { JSValue args = JS_UNDEFINED; JSValue response = JS_Call(context, callback, JS_UNDEFINED, 0, &args); _check_call(context, response); @@ -358,7 +391,8 @@ static JSValue _tf_ssb_rpc_send_binary(JSContext* context, JSValueConst this_val size_t size; uint8_t* message = tf_try_get_array_buffer(context, &size, argv[0]); - if (message) { + if (message) + { tf_ssb_connection_rpc_send( connection, k_ssb_rpc_flag_binary | k_ssb_rpc_flag_stream, @@ -550,7 +584,8 @@ void tf_ssb_run_file(JSContext* context, const char* file_name) printf("ERROR: %s\n", value); JS_FreeCString(context, value); JSValue stack = JS_GetPropertyStr(context, result, "stack"); - if (!JS_IsUndefined(stack)) { + if (!JS_IsUndefined(stack)) + { const char* stack_str = JS_ToCString(context, stack); printf("%s\n", stack_str); JS_FreeCString(context, stack_str); @@ -568,12 +603,14 @@ void tf_ssb_run_file(JSContext* context, const char* file_name) } JSRuntime* runtime = JS_GetRuntime(context); - while (JS_IsJobPending(runtime)) { + while (JS_IsJobPending(runtime)) + { JSContext* context2 = NULL; int r = JS_ExecutePendingJob(runtime, &context2); JSValue result = JS_GetException(context2); _check_call(context, result); - if (r == 0) { + if (r == 0) + { break; } } @@ -582,11 +619,16 @@ void tf_ssb_run_file(JSContext* context, const char* file_name) free(source); } -JSValue _print(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { - for (int i = 0; i < argc; ++i) { - if (JS_IsNull(argv[i])) { +JSValue _print(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ + for (int i = 0; i < argc; ++i) + { + if (JS_IsNull(argv[i])) + { printf(" null"); - } else { + } + else + { const char* value = JS_ToCString(context, argv[i]); printf(" %s", value); JS_FreeCString(context, value); @@ -596,27 +638,37 @@ JSValue _print(JSContext* context, JSValueConst this_val, int argc, JSValueConst return JS_NULL; } -static JSValue _utf8Decode(JSContext* context, uint8_t* data, size_t length) { +static JSValue _utf8Decode(JSContext* context, uint8_t* data, size_t length) +{ return JS_NewStringLen(context, (const char*)data, length); } -static JSValue _utf8_decode(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _utf8_decode(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ JSValue result = JS_NULL; size_t length; - if (JS_IsString(argv[0])) { + if (JS_IsString(argv[0])) + { result = JS_DupValue(context, argv[0]); - } else { + } + else + { uint8_t* array = tf_try_get_array_buffer(context, &length, argv[0]); - if (array) { + if (array) + { result = _utf8Decode(context, array, length); - } else { + } + else + { size_t offset; size_t element_size; JSValue buffer = tf_try_get_typed_array_buffer(context, argv[0], &offset, &length, &element_size); size_t size; - if (!JS_IsException(buffer)) { + if (!JS_IsException(buffer)) + { array = tf_try_get_array_buffer(context, &size, buffer); - if (array) { + if (array) + { result = _utf8Decode(context, array, size); } } @@ -629,10 +681,12 @@ static JSValue _utf8_decode(JSContext* context, JSValueConst this_val, int argc, void tf_ssb_init(JSContext* context, tf_ssb_t* ssb) { JS_NewClassID(&_tf_ssb_classId); - JSClassDef def = { + JSClassDef def = + { .class_name = "ssb", }; - if (JS_NewClass(JS_GetRuntime(context), _tf_ssb_classId, &def) != 0) { + if (JS_NewClass(JS_GetRuntime(context), _tf_ssb_classId, &def) != 0) + { fprintf(stderr, "Failed to register ssb.\n"); } diff --git a/src/ssb.tests.c b/src/ssb.tests.c index 90eac2a9..3fae8506 100644 --- a/src/ssb.tests.c +++ b/src/ssb.tests.c @@ -37,15 +37,19 @@ static void _ssb_test_connections_changed(tf_ssb_t* ssb, tf_ssb_change_t change, int count = 0; const char** c = tf_ssb_get_connection_ids(ssb); - for (const char** p = c; *p; p++) { + for (const char** p = c; *p; p++) + { count++; } free(c); - if (ssb == test->ssb0) { + if (ssb == test->ssb0) + { printf("callback0 change=%d connection=%p\n", change, connection); test->connection_count0 = count; - } else if (ssb == test->ssb1) { + } + else if (ssb == test->ssb1) + { printf("callback1 change=%d connection=%p\n", change, connection); test->connection_count1 = count; } @@ -131,17 +135,20 @@ void tf_ssb_test_ssb(const tf_test_options_t* options) tf_ssb_connect(ssb1, "127.0.0.1", 12347, id0bin); while (test.connection_count0 != 1 || - test.connection_count1 != 1) { + test.connection_count1 != 1) + { uv_run(&loop, UV_RUN_ONCE); } tf_ssb_server_close(ssb0); - while (_ssb_test_count_messages(ssb1) < 3) { + while (_ssb_test_count_messages(ssb1) < 3) + { uv_run(&loop, UV_RUN_ONCE); } printf("waiting for blob\n"); - while (!tf_ssb_db_blob_get(ssb1, blob_id, NULL, NULL)) { + while (!tf_ssb_db_blob_get(ssb1, blob_id, NULL, NULL)) + { uv_run(&loop, UV_RUN_ONCE); } printf("done\n"); @@ -202,16 +209,19 @@ void tf_ssb_test_following(const tf_test_options_t* options) #define DUMP(id, depth) #else #define DUMP(id, depth) \ - do { \ + do \ + { \ printf("following %d:\n", depth); \ const char** tf_ssb_get_following_deep(tf_ssb_t* ssb_param, const char** ids, int depth_param); \ const char** f = tf_ssb_get_following_deep(ssb0, (const char*[]) { id, NULL }, depth); \ - for (const char** p = f; p && *p; p++) { \ + for (const char** p = f; p && *p; p++) \ + { \ printf("* %s\n", *p); \ } \ printf("\n"); \ free(f); \ - } while (0) + } \ + while (0) #endif FOLLOW(ssb0, id1, true); diff --git a/src/task.c b/src/task.c index b5f04909..36b24bd0 100644 --- a/src/task.c +++ b/src/task.c @@ -116,11 +116,13 @@ typedef struct _export_record_t { export_record_t* _next; } export_record_t; -static void _export_record_ref(export_record_t* export) { +static void _export_record_ref(export_record_t* export) +{ export->_useCount++; } -static bool _export_record_release(export_record_t* export) { +static bool _export_record_release(export_record_t* export) +{ return --export->_useCount == 0; } @@ -156,9 +158,11 @@ static void _tf_task_trace_imports(tf_task_t* task) tf_trace_counter(task->_trace, "imports", 1, (const char*[]) { "count" }, (int64_t[]) { task->_import_count }); } -static void _import_record_release(import_record_t* import) { +static void _import_record_release(import_record_t* import) +{ JSContext* context = import->_owner->_context; - if (--import->_useCount > 0) { + if (--import->_useCount > 0) + { return; } @@ -169,8 +173,10 @@ static void _import_record_release(import_record_t* import) { for (import_record_t** it = &import->_owner->_imports; *it; - it = &(*it)->_next) { - if (*it == import) { + it = &(*it)->_next) + { + if (*it == import) + { *it = import->_next; import->_owner->_import_count--; _tf_task_trace_imports(import->_owner); @@ -188,9 +194,11 @@ static void _import_record_release_for_task(tf_task_t* task, taskid_t task_id) import_record_t** next = NULL; for (import_record_t** it = &task->_imports; *it; - it = next) { + it = next) + { next = &(*it)->_next; - if ((*it)->_task == task_id) { + if ((*it)->_task == task_id) + { import_record_t* import = *it; _import_record_release(import); next = it; @@ -198,7 +206,8 @@ static void _import_record_release_for_task(tf_task_t* task, taskid_t task_id) } } - if (any) { + if (any) + { _tf_task_trace_imports(task); } } @@ -214,11 +223,14 @@ static void _export_record_release_for_task(tf_task_t* task, taskid_t task_id) export_record_t** next = NULL; for (export_record_t** it = &task->_exports; *it; - it = next) { + it = next) + { next = &(*it)->_next; - if ((*it)->_taskid == task_id) { + if ((*it)->_taskid == task_id) + { export_record_t* export = *it; - if (_export_record_release(export)) { + if (_export_record_release(export)) + { *it = export->_next; JS_FreeValue(task->_context, export->_function); free(export); @@ -230,13 +242,16 @@ static void _export_record_release_for_task(tf_task_t* task, taskid_t task_id) } } - if (any) { + if (any) + { _tf_task_trace_exports(task); } } -static void _tf_task_send_error_to_parent(tf_task_t* task, JSValue error) { - if (task->_parent) { +static void _tf_task_send_error_to_parent(tf_task_t* task, JSValue error) +{ + if (task->_parent) + { void* buffer = NULL; size_t size = 0; tf_serialize_store(task, task->_parent, &buffer, &size, error); @@ -245,15 +260,18 @@ static void _tf_task_send_error_to_parent(tf_task_t* task, JSValue error) { } } -void tf_task_report_error(tf_task_t* task, JSValue error) { +void tf_task_report_error(tf_task_t* task, JSValue error) +{ JSContext* context = task->_context; - if (JS_IsError(context, error)) { + if (JS_IsError(context, error)) + { const char* value = JS_ToCString(context, error); printf("ERROR: %s\n", value); JS_FreeCString(context, value); JSValue stack = JS_GetPropertyStr(context, error, "stack"); - if (!JS_IsUndefined(stack)) { + if (!JS_IsUndefined(stack)) + { const char* stack_str = JS_ToCString(context, stack); printf("%s\n", stack_str); JS_FreeCString(context, stack_str); @@ -261,7 +279,9 @@ void tf_task_report_error(tf_task_t* task, JSValue error) { JS_FreeValue(context, stack); _tf_task_send_error_to_parent(task, error); - } else if (JS_IsException(error)) { + } + else if (JS_IsException(error)) + { error = JS_GetException(context); const char* value = JS_ToCString(context, error); printf("Exception: %s\n", value); @@ -270,10 +290,12 @@ void tf_task_report_error(tf_task_t* task, JSValue error) { } } -static const char* _task_loadFile(const char* fileName) { +static const char* _task_loadFile(const char* fileName) +{ char* result = NULL; FILE* file = fopen(fileName, "rb"); - if (file) { + if (file) + { fseek(file, 0, SEEK_END); long fileSize = ftell(file); fseek(file, 0, SEEK_SET); @@ -285,13 +307,18 @@ static const char* _task_loadFile(const char* fileName) { return result; } -JSValue _tf_task_print(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _tf_task_print(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_task_t* task = JS_GetContextOpaque(context); printf("Task[%p:%s]>", task, task->_scriptName); - for (int i = 0; i < argc; ++i) { - if (JS_IsNull(argv[i])) { + for (int i = 0; i < argc; ++i) + { + if (JS_IsNull(argv[i])) + { printf(" null"); - } else { + } + else + { const char* value = JS_ToCString(task->_context, argv[i]); printf(" %s", value); JS_FreeCString(task->_context, value); @@ -306,11 +333,13 @@ typedef struct _timeout_t { JSValue _callback; } timeout_t; -static JSValue _task_setTimeout(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _task_setTimeout(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_task_t* task = JS_GetContextOpaque(context); timeout_t* timeout = malloc(sizeof(timeout_t)); - *timeout = (timeout_t) { + *timeout = (timeout_t) + { ._task = task, ._callback = JS_DupValue(context, argv[0]), }; @@ -331,7 +360,8 @@ static void _handle_closed(uv_handle_t* handle) free(handle); } -static void _task_timeoutCallback(uv_timer_t* handle) { +static void _task_timeoutCallback(uv_timer_t* handle) +{ timeout_t* timeout = handle->data; tf_trace_begin(timeout->_task->_trace, "_task_timeoutCallback"); JSValue result = JS_Call( @@ -348,7 +378,8 @@ static void _task_timeoutCallback(uv_timer_t* handle) { uv_close((uv_handle_t*)handle, _handle_closed); } -JSValue _tf_task_exit(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _tf_task_exit(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_task_t* task = JS_GetContextOpaque(context); int exitCode = 0; JS_ToInt32(task->_context, &exitCode, argv[0]); @@ -356,49 +387,63 @@ JSValue _tf_task_exit(JSContext* context, JSValueConst this_val, int argc, JSVal return JS_UNDEFINED; } -int tf_task_execute(tf_task_t* task, const char* fileName) { +int tf_task_execute(tf_task_t* task, const char* fileName) +{ bool executed = false; tf_trace_begin(task->_trace, "tf_task_execute"); const char* source = _task_loadFile(fileName); printf("Running script %s\n", fileName); - if (!*task->_scriptName) { + if (!*task->_scriptName) + { strncpy(task->_scriptName, fileName, sizeof(task->_scriptName) - 1); } - if (!task->_path) { + if (!task->_path) + { char* path = strdup(fileName); char* slash = strrchr(path, '/'); - if (slash) { + if (slash) + { *slash = '\0'; task->_path = strdup(path); - } else { + } + else + { task->_path = strdup("./"); } free(path); } - if (source) { + if (source) + { JSValue result = JS_Eval(task->_context, source, strlen(source), fileName, 0); tf_task_report_error(task, result); - if (!JS_IsError(task->_context, result) && !JS_IsException(result)) { + if (!JS_IsError(task->_context, result) && !JS_IsException(result)) + { executed = true; } JS_FreeValue(task->_context, result); tf_task_run_jobs(task); free((void*)source); - } else { + } + else + { printf("Failed to load file: %s.\n", fileName); } tf_trace_end(task->_trace); return executed; } -static tf_taskstub_t* _tf_task_get_stub(tf_task_t* task, taskid_t id) { - if (id == k_task_parent_id) { +static tf_taskstub_t* _tf_task_get_stub(tf_task_t* task, taskid_t id) +{ + if (id == k_task_parent_id) + { return task->_parent; } - for (task_child_node_t* node = task->_children; node; node = node->next) { - if (node->id == id) { + for (task_child_node_t* node = task->_children; node; node = node->next) + { + if (node->id == id) + { return node->stub; } } @@ -409,55 +454,68 @@ static tf_taskstub_t* _tf_task_get_stub(tf_task_t* task, taskid_t id) { static JSValue _import_call(JSContext* context, JSValueConst func_obj, JSValueConst this_val, int argc, JSValueConst *argv, int flags) { import_record_t* import = JS_GetOpaque(func_obj, _import_class_id); - if (!import) { + if (!import) + { return JS_ThrowInternalError(context, "Invoking a function that has been released."); } import->_useCount++; JSValue array = JS_NewArray(context); JS_SetPropertyUint32(context, array, 0, JS_DupValue(context, this_val)); - for (int i = 0; i < argc; ++i) { + for (int i = 0; i < argc; ++i) + { JS_SetPropertyUint32(context, array, i + 1, JS_DupValue(context, argv[i])); } tf_task_t* sender = JS_GetContextOpaque(context); JSValue result; tf_taskstub_t* recipient = _tf_task_get_stub(sender, import->_task); - if (recipient) { + if (recipient) + { promiseid_t promise = tf_task_allocate_promise(sender); _tf_task_sendPromiseExportMessage(sender, recipient, kInvokeExport, promise, import->_export, array); result = tf_task_get_promise(sender, promise); - } else { + } + else + { result = JS_ThrowInternalError(context, "Invoking a function on a nonexistent task."); } JS_FreeValue(context, array); return result; } -static export_record_t* _task_get_export(tf_task_t* task, exportid_t export_id) { - for (export_record_t* it = task->_exports; it; it = it->_next) { - if (it->_export_id == export_id) { +static export_record_t* _task_get_export(tf_task_t* task, exportid_t export_id) +{ + for (export_record_t* it = task->_exports; it; it = it->_next) + { + if (it->_export_id == export_id) + { return it; } } return NULL; } -JSValue _task_invokeExport_internal(tf_taskstub_t* from, tf_task_t* to, exportid_t exportId, const char* buffer, size_t size) { +JSValue _task_invokeExport_internal(tf_taskstub_t* from, tf_task_t* to, exportid_t exportId, const char* buffer, size_t size) +{ JSValue result = JS_NULL; export_record_t* export = _task_get_export(to, exportId); - if (export) { + if (export) + { JSValue arguments = tf_serialize_load((tf_task_t*)to, from, buffer, size); JSValue* argument_array = NULL; JSValue length_val = JS_GetPropertyStr(to->_context, arguments, "length"); int length; JSValue this_val = JS_NULL; - if (JS_ToInt32(to->_context, &length, length_val) == 0) { - if (length > 0) { + if (JS_ToInt32(to->_context, &length, length_val) == 0) + { + if (length > 0) + { this_val = JS_GetPropertyUint32(to->_context, arguments, 0); argument_array = alloca(sizeof(JSValue) * (length - 1)); } - for (int i = 1; i < length; ++i) { + for (int i = 1; i < length; ++i) + { argument_array[i - 1] = JS_GetPropertyUint32(to->_context, arguments, i); } } @@ -465,27 +523,32 @@ JSValue _task_invokeExport_internal(tf_taskstub_t* from, tf_task_t* to, exportid JSPropertyDescriptor desc; const char* name = NULL; JSAtom atom = JS_NewAtom(to->_context, "name"); - if (JS_GetOwnProperty(to->_context, &desc, function, atom) == 1) { + if (JS_GetOwnProperty(to->_context, &desc, function, atom) == 1) + { name = JS_ToCString(to->_context, desc.value); JS_FreeValue(to->_context, desc.value); } JS_FreeAtom(to->_context, atom); tf_trace_begin(to->_trace, name ? name : "_task_invokeExport_internal"); - if (name) { + if (name) + { JS_FreeCString(to->_context, name); } result = JS_Call(to->_context, function, this_val, length - 1, argument_array); tf_trace_end(to->_trace); tf_task_report_error(to, result); tf_task_run_jobs(to); - } else { + } + else + { printf("%s: That's not an export we have (exportId=%d, exports=%d)\n", to->_scriptName, exportId, to->_export_count); } tf_packetstream_send(tf_taskstub_get_stream(from), kReleaseImport, (void*)&exportId, sizeof(exportId)); return result; } -static JSValue _invokeThen(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* func_data) { +static JSValue _invokeThen(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* func_data) +{ taskid_t taskid = 0; JS_ToInt32(context, &taskid, func_data[0]); tf_task_t* from = JS_GetContextOpaque(context); @@ -496,7 +559,8 @@ static JSValue _invokeThen(JSContext* context, JSValueConst this_val, int argc, return JS_DupValue(context, this_val); } -static JSValue _invokeCatch(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* func_data) { +static JSValue _invokeCatch(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* func_data) +{ taskid_t taskid = 0; JS_ToInt32(context, &taskid, func_data[0]); tf_task_t* from = JS_GetContextOpaque(context); @@ -507,7 +571,8 @@ static JSValue _invokeCatch(JSContext* context, JSValueConst this_val, int argc, return JS_DupValue(context, this_val); } -static void _forward_promise(tf_task_t* from, tf_taskstub_t* to, promiseid_t promise, JSValue result) { +static void _forward_promise(tf_task_t* from, tf_taskstub_t* to, promiseid_t promise, JSValue result) +{ // We're not going to serialize/deserialize a promise... JSValue data[] = { JS_NewInt32(from->_context, tf_taskstub_get_id(to)), @@ -529,30 +594,40 @@ static void _forward_promise(tf_task_t* from, tf_taskstub_t* to, promiseid_t pro tf_task_run_jobs(from); } -static void _tf_task_sendPromiseResolve(tf_task_t* from, tf_taskstub_t* to, promiseid_t promise, JSValue result) { +static void _tf_task_sendPromiseResolve(tf_task_t* from, tf_taskstub_t* to, promiseid_t promise, JSValue result) +{ JSValue global = JS_GetGlobalObject(from->_context); JSValue promiseType = JS_GetPropertyStr(from->_context, global, "Promise"); JS_FreeValue(from->_context, global); - if (JS_IsInstanceOf(from->_context, result, promiseType)) { + if (JS_IsInstanceOf(from->_context, result, promiseType)) + { _forward_promise(from, to, promise, result); - } else { + } + else + { _tf_task_sendPromiseMessage(from, to, kResolvePromise, promise, result); } } -static void _tf_task_sendPromiseReject(tf_task_t* from, tf_taskstub_t* to, promiseid_t promise, JSValue result) { +static void _tf_task_sendPromiseReject(tf_task_t* from, tf_taskstub_t* to, promiseid_t promise, JSValue result) +{ JSValue global = JS_GetGlobalObject(from->_context); JSValue promiseType = JS_GetPropertyStr(from->_context, global, "Promise"); JS_FreeValue(from->_context, global); - if (JS_IsInstanceOf(from->_context, result, promiseType)) { + if (JS_IsInstanceOf(from->_context, result, promiseType)) + { _forward_promise(from, to, promise, result); - } else { + } + else + { _tf_task_sendPromiseMessage(from, to, kRejectPromise, promise, result); } } -static void _tf_task_sendPromiseMessage(tf_task_t* from, tf_taskstub_t* to, tf_task_message_t messageType, promiseid_t promise, JSValue result) { - if (to) { +static void _tf_task_sendPromiseMessage(tf_task_t* from, tf_taskstub_t* to, tf_task_message_t messageType, promiseid_t promise, JSValue result) +{ + if (to) + { void* buffer; size_t size; tf_serialize_store(from, to, &buffer, &size, result); @@ -563,12 +638,15 @@ static void _tf_task_sendPromiseMessage(tf_task_t* from, tf_taskstub_t* to, tf_t tf_packetstream_send(tf_taskstub_get_stream(to), messageType, copy, size + sizeof(promise)); free(buffer); free(copy); - } else { + } + else + { printf("Sending to a NULL task.\n"); } } -static void _tf_task_sendPromiseExportMessage(tf_task_t* from, tf_taskstub_t* to, tf_task_message_t messageType, promiseid_t promise, exportid_t exportId, JSValue result) { +static void _tf_task_sendPromiseExportMessage(tf_task_t* from, tf_taskstub_t* to, tf_task_message_t messageType, promiseid_t promise, exportid_t exportId, JSValue result) +{ void* buffer; size_t size; tf_serialize_store(from, to, &buffer, &size, result); @@ -581,12 +659,14 @@ static void _tf_task_sendPromiseExportMessage(tf_task_t* from, tf_taskstub_t* to free(copy); } -JSValue _tf_task_get_parent(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _tf_task_get_parent(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_task_t* task = JS_GetContextOpaque(context); return task->_parent ? tf_taskstub_get_task_object(task->_parent) : JS_UNDEFINED; } -static JSValue _tf_task_version(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _tf_task_version(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_task_t* task = JS_GetContextOpaque(context); return JS_NewString(task->_context, k_version); } @@ -595,22 +675,26 @@ exportid_t tf_task_export_function(tf_task_t* task, tf_taskstub_t* to, JSValue f { export_record_t* export = NULL; - for (export_record_t* it = task->_exports; it; it = it->_next) { + for (export_record_t* it = task->_exports; it; it = it->_next) + { if (JS_VALUE_GET_PTR(it->_function) == JS_VALUE_GET_PTR(function) && - it->_taskid == tf_taskstub_get_id(to)) { + it->_taskid == tf_taskstub_get_id(to)) + { export = it; break; } } - if (!export) { + if (!export) + { int id = -1; do { id = task->_nextExport++; } while (_task_get_export(task, id)); export = malloc(sizeof(export_record_t)); - *export = (export_record_t) { + *export = (export_record_t) + { ._export_id = id, ._taskid = tf_taskstub_get_id(to), ._function = JS_DupValue(task->_context, function), @@ -621,7 +705,8 @@ exportid_t tf_task_export_function(tf_task_t* task, tf_taskstub_t* to, JSValue f _tf_task_trace_exports(task); } - if (export) { + if (export) + { _export_record_ref(export); } @@ -630,9 +715,11 @@ exportid_t tf_task_export_function(tf_task_t* task, tf_taskstub_t* to, JSValue f static void _tf_task_release_export(tf_taskstub_t* stub, exportid_t exportId) { - if (stub) { + if (stub) + { tf_packetstream_t* stream = tf_taskstub_get_stream(stub); - if (stream) { + if (stream) + { tf_packetstream_send(stream, kReleaseExport, (void*)&exportId, sizeof(exportId)); } } @@ -640,7 +727,8 @@ static void _tf_task_release_export(tf_taskstub_t* stub, exportid_t exportId) static JSValue _tf_task_trace(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv){ tf_task_t* task = JS_GetContextOpaque(context); - if (!task->_trace) { + if (!task->_trace) + { return JS_UNDEFINED; } @@ -666,7 +754,8 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, tf_task_t* to = tf_taskstub_get_owner(stub); tf_trace_begin(to->_trace, "tf_task_on_receive_packet"); - switch (packetType) { + switch (packetType) + { case kInvokeExport: { promiseid_t promise; @@ -675,9 +764,12 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, memcpy(&exportId, begin + sizeof(promise), sizeof(exportId)); JSValue result = _task_invokeExport_internal(from, to, exportId, begin + sizeof(promiseid_t) + sizeof(exportid_t), length); - if (JS_IsException(result)) { + if (JS_IsException(result)) + { _tf_task_sendPromiseReject(to, from, promise, result); - } else { + } + else + { _tf_task_sendPromiseResolve(to, from, promise, result); } } @@ -688,12 +780,16 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, JSValue arg = JS_UNDEFINED; promiseid_t promise; memcpy(&promise, begin, sizeof(promiseid_t)); - if (length > sizeof(promiseid_t)) { + if (length > sizeof(promiseid_t)) + { arg = tf_serialize_load((tf_task_t*)to, from, begin + sizeof(promiseid_t), length - sizeof(promiseid_t)); } - if (packetType == kResolvePromise) { + if (packetType == kResolvePromise) + { tf_task_resolve_promise(to, promise, arg); - } else { + } + else + { tf_task_reject_promise(to, promise, arg); } JS_FreeValue(to->_context, arg); @@ -704,11 +800,14 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, assert(length == sizeof(exportid_t)); exportid_t exportId; memcpy(&exportId, begin, sizeof(exportId)); - for (export_record_t** it = &to->_exports; *it; it = &(*it)->_next) { + for (export_record_t** it = &to->_exports; *it; it = &(*it)->_next) + { export_record_t* export = *it; if (export->_export_id == exportId && - export->_taskid == tf_taskstub_get_id(from)) { - if (_export_record_release(export)) { + export->_taskid == tf_taskstub_get_id(from)) + { + if (_export_record_release(export)) + { *it = export->_next; JS_FreeValue(to->_context, export->_function); free(export); @@ -725,8 +824,10 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, assert(length == sizeof(exportid_t)); exportid_t exportId; memcpy(&exportId, begin, sizeof(exportId)); - for (import_record_t* it = to->_imports; it; it = it->_next) { - if (it->_task == tf_taskstub_get_id(from) && it->_export == exportId) { + for (import_record_t* it = to->_imports; it; it = it->_next) + { + if (it->_task == tf_taskstub_get_id(from) && it->_export == exportId) + { _import_record_release(it); break; } @@ -784,9 +885,11 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, JSPropertyEnum* ptab; uint32_t plen; JS_GetOwnPropertyNames(to->_context, &ptab, &plen, imports, JS_GPN_STRING_MASK); - for (uint32_t i = 0; i < plen; ++i) { + for (uint32_t i = 0; i < plen; ++i) + { JSPropertyDescriptor desc; - if (JS_GetOwnProperty(to->_context, &desc, imports, ptab[i].atom) == 1) { + if (JS_GetOwnProperty(to->_context, &desc, imports, ptab[i].atom) == 1) + { JS_SetProperty(to->_context, global, ptab[i].atom, desc.value); } JS_FreeAtom(to->_context, ptab[i].atom); @@ -820,48 +923,63 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, tf_trace_end(to->_trace); } -static const char* _tf_task_resolveRequire(tf_task_t* task, const char* require) { +static const char* _tf_task_resolveRequire(tf_task_t* task, const char* require) +{ printf("Looking in %s for %s\n", task->_path, require); - if (strstr(require, "..") || strstr(require, "/") || strstr(require, "\\")) { + if (strstr(require, "..") || strstr(require, "/") || strstr(require, "\\")) + { return NULL; } char test[1024]; snprintf(test, sizeof(test), "%s/%s%s", task->_path, require, strstr(require, ".js") ? "" : ".js"); printf("Testing %s\n", test); uv_fs_t request; - if (uv_fs_access(task->_loop, &request, test, R_OK, 0) == 0) { + if (uv_fs_access(task->_loop, &request, test, R_OK, 0) == 0) + { return strdup(test); } return NULL; } -static script_export_t* _task_find_script_export(tf_task_t* task, const char* path) { - for (script_export_t* it = task->_scriptExports; it; it = it->next) { - if (strcmp(it->name, path) == 0) { +static script_export_t* _task_find_script_export(tf_task_t* task, const char* path) +{ + for (script_export_t* it = task->_scriptExports; it; it = it->next) + { + if (strcmp(it->name, path) == 0) + { return it; } } return NULL; } -JSValue _tf_task_require(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _tf_task_require(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ JSValue result = JS_NULL; tf_task_t* task = JS_GetContextOpaque(context); tf_trace_begin(task->_trace, "_tf_task_require"); const char* in_path = JS_ToCString(context, argv[0]); - if (in_path) { + if (in_path) + { const char* path = _tf_task_resolveRequire(task, in_path); - if (!path) { + if (!path) + { result = JS_ThrowReferenceError(task->_context, "require(): Unable to resolve module: %s.", in_path); - } else { + } + else + { script_export_t* it = _task_find_script_export(task, path); - if (it) { + if (it) + { result = JS_DupValue(task->_context, it->value); free((void*)path); - } else { + } + else + { JSValue exports = JS_NewObject(task->_context); script_export_t* export = malloc(sizeof(script_export_t)); - *export = (script_export_t) { + *export = (script_export_t) + { .name = path, .value = JS_DupValue(task->_context, exports), .next = task->_scriptExports, @@ -869,7 +987,8 @@ JSValue _tf_task_require(JSContext* context, JSValueConst this_val, int argc, JS task->_scriptExports = export; const char* source = _task_loadFile(path); printf("Requiring script %s\n", path); - if (source) { + if (source) + { JSValue global = JS_GetGlobalObject(task->_context); JSValue oldExports = JS_GetPropertyStr(task->_context, global, "exports"); JS_SetPropertyStr(task->_context, global, "exports", JS_DupValue(task->_context, exports)); @@ -877,22 +996,29 @@ JSValue _tf_task_require(JSContext* context, JSValueConst this_val, int argc, JS tf_task_report_error(task, eval); tf_task_run_jobs(task); if (JS_IsError(task->_context, eval) || - JS_IsException(eval)) { + JS_IsException(eval)) + { result = JS_DupValue(task->_context, eval); - } else { + } + else + { result = JS_DupValue(task->_context, exports); } JS_FreeValue(task->_context, eval); JS_SetPropertyStr(task->_context, global, "exports", oldExports); JS_FreeValue(task->_context, global); free((void*)source); - } else { + } + else + { printf("Failed to load %s.\n", path); } JS_FreeValue(task->_context, exports); } } - } else { + } + else + { result = JS_ThrowReferenceError(task->_context, "require(): No module specified."); } JS_FreeCString(context, in_path); @@ -900,11 +1026,13 @@ JSValue _tf_task_require(JSContext* context, JSValueConst this_val, int argc, JS return result; } -static JSValue _tf_task_executeSource(tf_task_t* task, const char* source, const char* name) { +static JSValue _tf_task_executeSource(tf_task_t* task, const char* source, const char* name) +{ tf_trace_begin(task->_trace, "_tf_task_executeSource"); JSValue result = JS_Eval(task->_context, source, strlen(source), name, 0); tf_task_report_error(task, result); - if (!*task->_scriptName) { + if (!*task->_scriptName) + { snprintf(task->_scriptName, sizeof(task->_scriptName), "%s", name); } tf_task_run_jobs(task); @@ -912,21 +1040,27 @@ static JSValue _tf_task_executeSource(tf_task_t* task, const char* source, const return result; } -JSValue _tf_task_sandbox_require(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _tf_task_sandbox_require(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_task_t* task = JS_GetContextOpaque(context); - if (JS_IsObject(task->_loadedFiles)) { + if (JS_IsObject(task->_loadedFiles)) + { const char* name = JS_ToCString(context, argv[0]); script_export_t* it = _task_find_script_export(task, name); - if (it) { + if (it) + { return it->value; - } else { + } + else + { JSValue exports = JS_NewObject(context); const char* name = JS_ToCString(context, argv[0]); JSValue value = JS_GetPropertyStr(context, task->_loadedFiles, name); size_t length; uint8_t* array = tf_try_get_array_buffer(context, &length, value); - if (array) { + if (array) + { char* source = malloc(length + 1); memcpy(source, array, length); source[length] = '\0'; @@ -940,7 +1074,9 @@ JSValue _tf_task_sandbox_require(JSContext* context, JSValueConst this_val, int tf_task_run_jobs(task); free(source); return exports; - } else if (JS_IsString(value)) { + } + else if (JS_IsString(value)) + { size_t length; const char* source = JS_ToCStringLen(context, &length, value); JSValue global = JS_GetGlobalObject(context); @@ -952,7 +1088,9 @@ JSValue _tf_task_sandbox_require(JSContext* context, JSValueConst this_val, int JS_FreeValue(context, global); tf_task_run_jobs(task); return exports; - } else { + } + else + { return JS_ThrowInternalError(context, "Failed to load %s %d %d %d.", name, JS_IsNull(value), JS_IsUndefined(value), JS_IsException(value)); } } @@ -961,27 +1099,37 @@ JSValue _tf_task_sandbox_require(JSContext* context, JSValueConst this_val, int return JS_UNDEFINED; } -static JSValue _utf8Decode(JSContext* context, uint8_t* data, size_t length) { +static JSValue _utf8Decode(JSContext* context, uint8_t* data, size_t length) +{ return JS_NewStringLen(context, (const char*)data, length); } -static JSValue _tf_task_utf8Decode(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _tf_task_utf8Decode(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ JSValue result = JS_NULL; size_t length; - if (JS_IsString(argv[0])) { + if (JS_IsString(argv[0])) + { result = JS_DupValue(context, argv[0]); - } else { + } + else + { uint8_t* array = tf_try_get_array_buffer(context, &length, argv[0]); - if (array) { + if (array) + { result = _utf8Decode(context, array, length); - } else { + } + else + { size_t offset; size_t element_size; JSValue buffer = tf_try_get_typed_array_buffer(context, argv[0], &offset, &length, &element_size); size_t size; - if (!JS_IsException(buffer)) { + if (!JS_IsException(buffer)) + { array = tf_try_get_array_buffer(context, &size, buffer); - if (array) { + if (array) + { result = _utf8Decode(context, array, size); } } @@ -991,13 +1139,17 @@ static JSValue _tf_task_utf8Decode(JSContext* context, JSValueConst this_val, in return result; } -uv_loop_t* tf_task_get_loop(tf_task_t* task) { +uv_loop_t* tf_task_get_loop(tf_task_t* task) +{ return task->_loop; } -static promise_t* _tf_task_find_promise(tf_task_t* task, promiseid_t id) { - for (promise_t* it = task->_promises; it; it = it->next) { - if (it->id == id) { +static promise_t* _tf_task_find_promise(tf_task_t* task, promiseid_t id) +{ + for (promise_t* it = task->_promises; it; it = it->next) + { + if (it->id == id) + { return it; } } @@ -1009,9 +1161,12 @@ static void _tf_task_trace_promises(tf_task_t* task) tf_trace_counter(task->_trace, "promises", 1, (const char*[]) { "count" }, (int64_t[]) { task->_promise_count }); } -static void _tf_task_free_promise(tf_task_t* task, promiseid_t id) { - for (promise_t** it = &task->_promises; *it; it = &(*it)->next) { - if ((*it)->id == id) { +static void _tf_task_free_promise(tf_task_t* task, promiseid_t id) +{ + for (promise_t** it = &task->_promises; *it; it = &(*it)->next) + { + if ((*it)->id == id) + { promise_t* promise = *it; *it = (*it)->next; free(promise); @@ -1022,14 +1177,16 @@ static void _tf_task_free_promise(tf_task_t* task, promiseid_t id) { } } -promiseid_t tf_task_allocate_promise(tf_task_t* task) { +promiseid_t tf_task_allocate_promise(tf_task_t* task) +{ promiseid_t promiseId; do { promiseId = task->_nextPromise++; } while (_tf_task_find_promise(task, promiseId)); promise_t* promise = malloc(sizeof(promise_t)); - *promise = (promise_t) { + *promise = (promise_t) + { .id = promiseId, .next = task->_promises, .values = { JS_NULL, JS_NULL, JS_NULL }, @@ -1041,9 +1198,11 @@ promiseid_t tf_task_allocate_promise(tf_task_t* task) { return promiseId; } -void tf_task_resolve_promise(tf_task_t* task, promiseid_t promise, JSValue value) { +void tf_task_resolve_promise(tf_task_t* task, promiseid_t promise, JSValue value) +{ promise_t* it = _tf_task_find_promise(task, promise); - if (it) { + if (it) + { JSValue result = JS_Call(task->_context, it->values[1], JS_UNDEFINED, 1, &value); tf_task_report_error(task, result); JS_FreeValue(task->_context, it->values[1]); @@ -1051,15 +1210,19 @@ void tf_task_resolve_promise(tf_task_t* task, promiseid_t promise, JSValue value JS_FreeValue(task->_context, result); _tf_task_free_promise(task, promise); tf_task_run_jobs(task); - } else { + } + else + { printf("Didn't find promise %d to resolve.\n", promise); abort(); } } -void tf_task_reject_promise(tf_task_t* task, promiseid_t promise, JSValue value) { +void tf_task_reject_promise(tf_task_t* task, promiseid_t promise, JSValue value) +{ promise_t* it = _tf_task_find_promise(task, promise); - if (it) { + if (it) + { JSValue result = JS_Call(task->_context, it->values[2], JS_UNDEFINED, 1, &value); tf_task_report_error(task, result); JS_FreeValue(task->_context, it->values[1]); @@ -1070,7 +1233,8 @@ void tf_task_reject_promise(tf_task_t* task, promiseid_t promise, JSValue value) } } -JSValue tf_task_get_promise(tf_task_t* task, promiseid_t promise) { +JSValue tf_task_get_promise(tf_task_t* task, promiseid_t promise) +{ promise_t* it = _tf_task_find_promise(task, promise); return it ? it->values[0] : JS_NULL; } @@ -1080,14 +1244,16 @@ static void _tf_task_trace_children(tf_task_t* task) tf_trace_counter(task->_trace, "child_tasks", 1, (const char*[]) { "count" }, (int64_t[]) { task->_child_count }); } -taskid_t tf_task_allocate_task_id(tf_task_t* task, tf_taskstub_t* stub) { +taskid_t tf_task_allocate_task_id(tf_task_t* task, tf_taskstub_t* stub) +{ taskid_t id = 0; do { id = task->_nextTask++; } while (id == k_task_parent_id || _tf_task_get_stub(task, id)); task_child_node_t* node = malloc(sizeof(task_child_node_t)); - *node = (task_child_node_t) { + *node = (task_child_node_t) + { .id = id, .stub = stub, .next = task->_children, @@ -1104,8 +1270,10 @@ void tf_task_remove_child(tf_task_t* task, tf_taskstub_t* child) _export_record_release_for_task(task, tf_taskstub_get_id(child)); for (task_child_node_t** it = &task->_children; *it; - it = &(*it)->next) { - if ((*it)->stub == child) { + it = &(*it)->next) + { + if ((*it)->stub == child) + { task_child_node_t* node = *it; *it = node->next; free(node); @@ -1125,7 +1293,8 @@ static void _import_finalizer(JSRuntime* runtime, JSValue value) static void _import_mark_func(JSRuntime* runtime, JSValueConst value, JS_MarkFunc mark_func) { import_record_t* import = JS_GetOpaque(value, _import_class_id); - if (import && import->_useCount > 0) { + if (import && import->_useCount > 0) + { JS_MarkValue(runtime, import->_function, mark_func); } } @@ -1133,12 +1302,14 @@ static void _import_mark_func(JSRuntime* runtime, JSValueConst value, JS_MarkFun static void _tf_task_promise_rejection_tracker(JSContext* context, JSValueConst promise, JSValueConst reason, JS_BOOL is_handled, void* user_data) { tf_task_t* task = user_data; - if (!is_handled) { + if (!is_handled) + { tf_task_report_error(task, reason); } } -tf_task_t* tf_task_create() { +tf_task_t* tf_task_create() +{ tf_task_t* task = malloc(sizeof(tf_task_t)); *task = (tf_task_t) { 0 }; task->_loop = uv_loop_new(); @@ -1162,7 +1333,8 @@ tf_task_t* tf_task_create() { return task; } -void tf_task_configure_from_stdin(tf_task_t* task) { +void tf_task_configure_from_stdin(tf_task_t* task) +{ task->_parent = tf_taskstub_create_parent(task, STDIN_FILENO); } @@ -1182,7 +1354,8 @@ void tf_task_activate(tf_task_t* task) JS_SetPropertyStr(context, tildefriends, "https_port", JS_NewInt32(context, task->_https_port)); JS_SetPropertyStr(context, global, "tildefriends", tildefriends); - if (task->_trusted) { + if (task->_trusted) + { sqlite3_open(task->_db_path ? task->_db_path : "db.sqlite", &task->_db); JS_SetPropertyStr(context, global, "require", JS_NewCFunction(context, _tf_task_require, "require", 1)); @@ -1198,12 +1371,15 @@ void tf_task_activate(tf_task_t* task) tf_ssb_set_trace(task->_ssb, task->_trace); tf_ssb_broadcast_listener_start(task->_ssb, false); tf_ssb_init(context, task->_ssb); - if (task->_ssb_port) { + if (task->_ssb_port) + { tf_ssb_server_open(task->_ssb, task->_ssb_port); } JS_SetPropertyStr(context, global, "trace", JS_NewCFunction(context, _tf_task_trace, "trace", 1)); - } else { + } + else + { JS_SetPropertyStr(context, global, "require", JS_NewCFunction(context, _tf_task_sandbox_require, "sandboxRequire", 0)); } @@ -1217,21 +1393,26 @@ void tf_task_activate(tf_task_t* task) JS_FreeValue(context, global); } -void tf_task_run(tf_task_t* task) { +void tf_task_run(tf_task_t* task) +{ uv_run(task->_loop, UV_RUN_DEFAULT); } -void tf_task_set_trusted(tf_task_t* task, bool trusted) { +void tf_task_set_trusted(tf_task_t* task, bool trusted) +{ task->_trusted = trusted; } -JSContext* tf_task_get_context(tf_task_t* task) { +JSContext* tf_task_get_context(tf_task_t* task) +{ return task->_context; } -void tf_task_destroy(tf_task_t* task) { +void tf_task_destroy(tf_task_t* task) +{ import_record_t* it = task->_imports; - while (it) { + while (it) + { import_record_t* next = it->_next; JS_FreeValue(task->_context, it->_function); free(it); @@ -1239,27 +1420,32 @@ void tf_task_destroy(tf_task_t* task) { } task->_imports = NULL; - while (task->_exports) { + while (task->_exports) + { export_record_t* export = task->_exports; JS_FreeValue(task->_context, export->_function); task->_exports = export->_next; free(export); } - while (task->_children) { + while (task->_children) + { task_child_node_t* node = task->_children; tf_taskstub_destroy(node->stub); task->_children = node->next; free(node); } - if (task->_parent) { + if (task->_parent) + { JS_FreeValue(task->_context, tf_taskstub_get_task_object(task->_parent)); } - while (task->_promises) { + while (task->_promises) + { tf_task_reject_promise(task, task->_promises->id, JS_NULL); } JS_FreeValue(task->_context, task->_requires); JS_FreeValue(task->_context, task->_loadedFiles); - while (task->_scriptExports) { + while (task->_scriptExports) + { script_export_t* export = task->_scriptExports; JS_FreeValue(task->_context, export->value); task->_scriptExports = export->next; @@ -1267,17 +1453,20 @@ void tf_task_destroy(tf_task_t* task) { free(export); } - if (task->_trace) { + if (task->_trace) + { tf_trace_destroy(task->_trace); } - if (task->_ssb) { + if (task->_ssb) + { tf_ssb_destroy(task->_ssb); } JS_FreeContext(task->_context); JS_FreeRuntime(task->_runtime); - if (task->_db) { + if (task->_db) + { sqlite3_close(task->_db); } @@ -1293,7 +1482,8 @@ JSValue tf_task_add_import(tf_task_t* task, taskid_t stub_id, exportid_t export_ JSValue function = JS_NewObjectClass(task->_context, _import_class_id); import_record_t* import = malloc(sizeof(import_record_t)); JS_SetOpaque(function, import); - *import = (import_record_t) { + *import = (import_record_t) + { ._function = JS_DupValue(task->_context, function), ._export = export_id, ._owner = task, @@ -1308,19 +1498,25 @@ JSValue tf_task_add_import(tf_task_t* task, taskid_t stub_id, exportid_t export_ return function; } -tf_task_t* tf_task_get(JSContext* context) { +tf_task_t* tf_task_get(JSContext* context) +{ return JS_GetContextOpaque(context); } -void tf_task_run_jobs(tf_task_t* task) { - while (JS_IsJobPending(task->_runtime)) { +void tf_task_run_jobs(tf_task_t* task) +{ + while (JS_IsJobPending(task->_runtime)) + { JSContext* context = NULL; int r = JS_ExecutePendingJob(task->_runtime, &context); JSValue result = JS_GetException(context); tf_task_report_error(task, result); - if (r < 0) { + if (r < 0) + { js_std_dump_error(context); - } else if (r == 0) { + } + else if (r == 0) + { break; } } diff --git a/src/taskstub.c b/src/taskstub.c index de120cdc..0b0b3d4f 100644 --- a/src/taskstub.c +++ b/src/taskstub.c @@ -38,9 +38,11 @@ typedef struct _tf_taskstub_t { bool _finalized; } tf_taskstub_t; -void tf_taskstub_startup() { +void tf_taskstub_startup() +{ static bool initialized; - if (!initialized) { + if (!initialized) + { JS_NewClassID(&_classId); size_t size = sizeof(_executable); uv_exepath(_executable, &size); @@ -62,7 +64,8 @@ static JSValue _taskstub_loadFile(JSContext* context, JSValueConst this_val, int static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int terminationSignal); static void _taskstub_finalizer(JSRuntime *runtime, JSValue value); -static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_task_t* parent = tf_task_get(context); tf_taskstub_t* stub = malloc(sizeof(tf_taskstub_t)); memset(stub, 0, sizeof(*stub)); @@ -106,7 +109,8 @@ static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int a JS_SetPropertyStr(context, taskObject, "loadFile", JS_NewCFunction(context, _taskstub_loadFile, "loadFile", 1)); taskid_t id = k_task_parent_id; - if (parent) { + if (parent) + { id = tf_task_allocate_task_id(parent, (tf_taskstub_t*)stub); } stub->_id = id; @@ -116,7 +120,8 @@ static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int a uv_pipe_t* pipe = tf_packetstream_get_pipe(stub->_stream); memset(pipe, 0, sizeof(*pipe)); - if (uv_pipe_init(tf_task_get_loop(parent), pipe, 1) != 0) { + if (uv_pipe_init(tf_task_get_loop(parent), pipe, 1) != 0) + { fprintf(stderr, "uv_pipe_init failed\n"); } @@ -138,55 +143,67 @@ static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int a JSValue result = JS_NULL; stub->_process.data = stub; int spawn_result = uv_spawn(tf_task_get_loop(parent), &stub->_process, &options); - if (spawn_result == 0) { + if (spawn_result == 0) + { tf_packetstream_set_on_receive(stub->_stream, tf_task_on_receive_packet, stub); tf_packetstream_start(stub->_stream); result = taskObject; - } else { + } + else + { fprintf(stderr, "uv_spawn failed: %s\n", uv_strerror(spawn_result)); JS_FreeValue(context, taskObject); } return result; } -void _taskstub_gc_mark(JSRuntime* rt, JSValueConst value, JS_MarkFunc mark_func) { +void _taskstub_gc_mark(JSRuntime* rt, JSValueConst value, JS_MarkFunc mark_func) +{ tf_taskstub_t* stub = JS_GetOpaque(value, _classId); - if (stub) { + if (stub) + { JS_MarkValue(rt, stub->_on_exit, mark_func); JS_MarkValue(rt, stub->_on_error, mark_func); } } -JSValue tf_taskstub_init(JSContext* context) { +JSValue tf_taskstub_init(JSContext* context) +{ JSClassDef def = { .class_name = "TaskStub", .finalizer = &_taskstub_finalizer, .gc_mark = _taskstub_gc_mark, }; - if (JS_NewClass(JS_GetRuntime(context), _classId, &def) != 0) { + if (JS_NewClass(JS_GetRuntime(context), _classId, &def) != 0) + { fprintf(stderr, "Failed to register TaskStub class.\n"); } return JS_NewCFunction2(context, _taskstub_create, "TaskStub", 0, JS_CFUNC_constructor, 0); } -taskid_t tf_taskstub_get_id(const tf_taskstub_t* stub) { +taskid_t tf_taskstub_get_id(const tf_taskstub_t* stub) +{ return stub->_id; } -JSValue tf_taskstub_get_task_object(const tf_taskstub_t* stub) { +JSValue tf_taskstub_get_task_object(const tf_taskstub_t* stub) +{ return stub->_taskObject; } -tf_packetstream_t* tf_taskstub_get_stream(const tf_taskstub_t* stub) { +tf_packetstream_t* tf_taskstub_get_stream(const tf_taskstub_t* stub) +{ return stub->_stream; } -tf_task_t* tf_taskstub_get_owner(const tf_taskstub_t* stub) { +tf_task_t* tf_taskstub_get_owner(const tf_taskstub_t* stub) +{ return stub->_owner; } -tf_taskstub_t* tf_taskstub_create_parent(tf_task_t* task, uv_file file) { +tf_taskstub_t* tf_taskstub_create_parent(tf_task_t* task, uv_file file) +{ JSValue parentObject = JS_NewObject(tf_task_get_context(task)); tf_taskstub_t* parentStub = malloc(sizeof(tf_taskstub_t)); memset(parentStub, 0, sizeof(tf_taskstub_t)); @@ -200,11 +217,13 @@ tf_taskstub_t* tf_taskstub_create_parent(tf_task_t* task, uv_file file) { parentStub->_id = k_task_parent_id; parentStub->_object = JS_DupValue(tf_task_get_context(task), parentObject); - if (uv_pipe_init(tf_task_get_loop(task), tf_packetstream_get_pipe(parentStub->_stream), 1) != 0) { + if (uv_pipe_init(tf_task_get_loop(task), tf_packetstream_get_pipe(parentStub->_stream), 1) != 0) + { fprintf(stderr, "uv_pipe_init failed\n"); } tf_packetstream_set_on_receive(parentStub->_stream, tf_task_on_receive_packet, parentStub); - if (uv_pipe_open(tf_packetstream_get_pipe(parentStub->_stream), file) != 0) { + if (uv_pipe_open(tf_packetstream_get_pipe(parentStub->_stream), file) != 0) + { fprintf(stderr, "uv_pipe_open failed\n"); } tf_packetstream_start(parentStub->_stream); @@ -216,12 +235,14 @@ static void _taskstub_cleanup(tf_taskstub_t* stub) { if (!stub->_process.data && JS_IsUndefined(stub->_object) && - stub->_finalized) { + stub->_finalized) + { free(stub); } } -static void _taskstub_finalizer(JSRuntime* runtime, JSValue value) { +static void _taskstub_finalizer(JSRuntime* runtime, JSValue value) +{ tf_taskstub_t* stub = JS_GetOpaque(value, _classId); stub->_on_exit = JS_UNDEFINED; stub->_on_error = JS_UNDEFINED; @@ -240,10 +261,12 @@ static void _taskstub_on_handle_close(uv_handle_t* handle) _taskstub_cleanup(stub); } -static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int terminationSignal) { +static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int terminationSignal) +{ tf_taskstub_t* stub = process->data; JSContext* context = tf_task_get_context(stub->_owner); - if (!JS_IsUndefined(stub->_on_exit)) { + if (!JS_IsUndefined(stub->_on_exit)) + { JSValue argv[] = { JS_NewInt32(context, status), JS_NewInt32(context, terminationSignal) }; JSValue result = JS_Call(context, stub->_on_exit, JS_NULL, 2, argv); tf_task_report_error(stub->_owner, result); @@ -257,14 +280,16 @@ static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int tf_taskstub_destroy(stub); } -static JSValue _taskstub_getExports(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_getExports(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); promiseid_t promise = tf_task_allocate_promise(stub->_owner); tf_task_send_promise_message(stub->_owner, (tf_taskstub_t*)stub, kGetExports, promise, JS_UNDEFINED); return tf_task_get_promise(stub->_owner, promise); } -static JSValue _taskstub_setImports(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_setImports(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); void* buffer; size_t size; @@ -273,7 +298,8 @@ static JSValue _taskstub_setImports(JSContext* context, JSValueConst this_val, i return JS_UNDEFINED; } -static JSValue _taskstub_setRequires(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_setRequires(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); void* buffer; size_t size; @@ -282,7 +308,8 @@ static JSValue _taskstub_setRequires(JSContext* context, JSValueConst this_val, return JS_UNDEFINED; } -static JSValue _taskstub_loadFile(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_loadFile(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); void* buffer; size_t size; @@ -291,57 +318,69 @@ static JSValue _taskstub_loadFile(JSContext* context, JSValueConst this_val, int return JS_UNDEFINED; } -static JSValue _taskstub_get_on_exit(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_get_on_exit(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); return JS_DupValue(context, stub->_on_exit); } -static JSValue _taskstub_set_on_exit(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_set_on_exit(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); - if (!JS_IsUndefined(stub->_on_exit)) { + if (!JS_IsUndefined(stub->_on_exit)) + { JS_FreeValue(context, stub->_on_exit); } stub->_on_exit = JS_DupValue(context, argv[0]); return JS_UNDEFINED; } -static JSValue _taskstub_get_on_error(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_get_on_error(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); return JS_DupValue(context, stub->_on_error); } -static JSValue _taskstub_set_on_error(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_set_on_error(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); - if (!JS_IsUndefined(stub->_on_error)) { + if (!JS_IsUndefined(stub->_on_error)) + { JS_FreeValue(context, stub->_on_error); } stub->_on_error = JS_DupValue(context, argv[0]); return JS_UNDEFINED; } -static JSValue _taskstub_activate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_activate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); - if (stub) { + if (stub) + { tf_packetstream_send(stub->_stream, kActivate, 0, 0); } return JS_NULL; } -static JSValue _taskstub_execute(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_execute(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); promiseid_t promise = tf_task_allocate_promise(stub->_owner); tf_task_send_promise_message(stub->_owner, (tf_taskstub_t*)stub, kExecute, promise, argv[0]); return tf_task_get_promise(stub->_owner, promise); } -static JSValue _taskstub_kill(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +static JSValue _taskstub_kill(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); uv_process_kill(&stub->_process, SIGTERM); return JS_UNDEFINED; } -void tf_taskstub_destroy(tf_taskstub_t* stub) { - if (!JS_IsUndefined(stub->_object)) { +void tf_taskstub_destroy(tf_taskstub_t* stub) +{ + if (!JS_IsUndefined(stub->_object)) + { JSValue object = stub->_object; stub->_object = JS_UNDEFINED; JS_FreeValue(tf_task_get_context(stub->_owner), object); @@ -351,7 +390,8 @@ void tf_taskstub_destroy(tf_taskstub_t* stub) { void tf_taskstub_on_error(tf_taskstub_t* stub, JSValue error) { JSContext* context = tf_task_get_context(stub->_owner); - if (!JS_IsUndefined(stub->_on_error)) { + if (!JS_IsUndefined(stub->_on_error)) + { JSValue result = JS_Call(context, stub->_on_error, JS_NULL, 1, &error); tf_task_report_error(stub->_owner, result); JS_FreeValue(context, result); diff --git a/src/tests.c b/src/tests.c index 9f67cdc8..a7a37e1a 100644 --- a/src/tests.c +++ b/src/tests.c @@ -513,12 +513,15 @@ static void _test_file(const tf_test_options_t* options) static void _tf_test_run(const tf_test_options_t* options, const char* name, void (*test)(const tf_test_options_t* options)) { bool specified = false; - if (options->tests) { + if (options->tests) + { char* dup = strdup(options->tests); char* state = NULL; const char* t = NULL; - while ((t = strtok_r(t ? NULL : dup, ",", &state)) != NULL) { - if (strcmp(t, name) == 0) { + while ((t = strtok_r(t ? NULL : dup, ",", &state)) != NULL) + { + if (strcmp(t, name) == 0) + { specified = true; break; } @@ -526,7 +529,8 @@ static void _tf_test_run(const tf_test_options_t* options, const char* name, voi free(dup); } - if (!options->tests || specified) { + if (!options->tests || specified) + { printf("Running test %s.\n", name); test(options); printf("[\e[1;32mpass\e[0m] %s\n", name); diff --git a/src/tls.c b/src/tls.c index 0ca2c1ca..d94a2ed3 100644 --- a/src/tls.c +++ b/src/tls.c @@ -68,9 +68,18 @@ public: bool setPrivateKey(const char* privateKey) override; bool addTrustedCertificate(const char* certificate) override; - SecKeyRef& getPrivateKey() { return _privateKey; } - SecCertificateRef& getCertificate() { return _certificate; } - CFArrayRef getTrustedCertificates() { return _trustedCertificates; } + SecKeyRef& getPrivateKey() + { + return _privateKey; + } + SecCertificateRef& getCertificate() + { + return _certificate; + + CFArrayRef getTrustedCertificates() + { + return _trustedCertificates; + } private: SecKeyRef _privateKey = 0; @@ -109,27 +118,34 @@ private: bool _shutdown = false; }; -TlsContext_osx::~TlsContext_osx() { - if (_privateKey) { +TlsContext_osx::~TlsContext_osx() +{ + if (_privateKey) + { CFRelease(_privateKey); _privateKey = 0; } - if (_certificate) { + if (_certificate) + { CFRelease(_certificate); _certificate = 0; } - if (_trustedCertificates) { + if (_trustedCertificates) + { CFRelease(_trustedCertificates); _trustedCertificates = 0; } } -TlsSession* TlsContext_osx::createSession() { +TlsSession* TlsContext_osx::createSession() +{ return new TlsSession_osx(this); } -bool TlsContext_osx::setCertificate(const char* certificate) { - if (_certificate) { +bool TlsContext_osx::setCertificate(const char* certificate) +{ + if (_certificate) + { CFRelease(_certificate); _certificate = 0; } @@ -138,14 +154,17 @@ bool TlsContext_osx::setCertificate(const char* certificate) { SecExternalFormat format = kSecFormatPEMSequence; SecExternalItemType itemType = kSecItemTypeCertificate; OSStatus status = SecItemImport(data, 0, &format, &itemType, 0, 0, 0, &items); - if (status == noErr && CFArrayGetCount(items) > 0) { + if (status == noErr && CFArrayGetCount(items) > 0) + { _certificate = (SecCertificateRef)CFArrayGetValueAtIndex(items, 0); } return _certificate != 0; } -bool TlsContext_osx::setPrivateKey(const char* privateKey) { - if (_privateKey) { +bool TlsContext_osx::setPrivateKey(const char* privateKey) +{ + if (_privateKey) + { CFRelease(_privateKey); _privateKey = 0; } @@ -155,14 +174,17 @@ bool TlsContext_osx::setPrivateKey(const char* privateKey) { SecExternalFormat format = kSecFormatPEMSequence; SecExternalItemType itemType = kSecItemTypePrivateKey; OSStatus status = SecItemImport(data, 0, &format, &itemType, 0, 0, 0, &items); - if (status == noErr && CFArrayGetCount(items) > 0) { + if (status == noErr && CFArrayGetCount(items) > 0) + { _privateKey = (SecKeyRef)CFArrayGetValueAtIndex(items, 0); } return _privateKey != 0; } -bool TlsContext_osx::addTrustedCertificate(const char* certificate) { - if (!_trustedCertificates) { +bool TlsContext_osx::addTrustedCertificate(const char* certificate) +{ + if (!_trustedCertificates) + { _trustedCertificates = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); } SecCertificateRef certificateItem = 0; @@ -171,29 +193,36 @@ bool TlsContext_osx::addTrustedCertificate(const char* certificate) { SecExternalFormat format = kSecFormatPEMSequence; SecExternalItemType itemType = kSecItemTypeCertificate; OSStatus status = SecItemImport(data, 0, &format, &itemType, 0, 0, 0, &items); - if (status == noErr && CFArrayGetCount(items) > 0) { + if (status == noErr && CFArrayGetCount(items) > 0) + { certificateItem = (SecCertificateRef)CFArrayGetValueAtIndex(items, 0); } - if (certificateItem) { + if (certificateItem) + { CFArrayAppendValue(_trustedCertificates, certificateItem); } return certificateItem != 0; } -TlsSession_osx::TlsSession_osx(TlsContext_osx* context) { +TlsSession_osx::TlsSession_osx(TlsContext_osx* context) +{ _context = context; } -TlsSession_osx::~TlsSession_osx() { - if (_session) { +TlsSession_osx::~TlsSession_osx() +{ + if (_session) + { CFRelease(_session); _session = 0; } } -void TlsSession_osx::startAccept() { +void TlsSession_osx::startAccept() +{ _session = SSLCreateContext(0, kSSLServerSide, kSSLStreamType); - if (_context->getCertificate() && _context->getPrivateKey()) { + if (_context->getCertificate() && _context->getPrivateKey()) + { SecIdentityRef identity = SecIdentityCreate(kCFAllocatorDefault, _context->getCertificate(), _context->getPrivateKey()); CFArrayRef array = CFArrayCreate(kCFAllocatorDefault, (const void**)&identity, 1, &kCFTypeArrayCallBacks); SSLSetCertificate(_session, array); @@ -203,9 +232,11 @@ void TlsSession_osx::startAccept() { handshake(); } -void TlsSession_osx::startConnect() { +void TlsSession_osx::startConnect() +{ _session = SSLCreateContext(0, kSSLClientSide, kSSLStreamType); - if (_context->getTrustedCertificates()) { + if (_context->getTrustedCertificates()) + { // XXX: SSLSetTrustedRoots(_session, _context->getTrustedCertificates(), false); } SSLSetIOFuncs(_session, readCallback, writeCallback); @@ -214,19 +245,25 @@ void TlsSession_osx::startConnect() { handshake(); } -void TlsSession_osx::shutdown() { - if (!_outBuffer.size()) { +void TlsSession_osx::shutdown() +{ + if (!_outBuffer.size()) + { SSLClose(_session); _shutdown = false; - } else { + } + else + { _shutdown = true; } } -TlsSession::HandshakeResult TlsSession_osx::handshake() { +TlsSession::HandshakeResult TlsSession_osx::handshake() +{ TlsSession::HandshakeResult result = TlsSession::kFailed; OSStatus status = SSLHandshake(_session); - switch (status) { + switch (status) + { case noErr: result = TlsSession::kDone; break; @@ -240,83 +277,108 @@ TlsSession::HandshakeResult TlsSession_osx::handshake() { return result; } -int TlsSession_osx::readPlain(char* buffer, size_t bytes) { +int TlsSession_osx::readPlain(char* buffer, size_t bytes) +{ int result = 0; size_t processed = bytes; OSStatus status = SSLRead(_session, buffer, bytes, &processed); - if (status == noErr) { + if (status == noErr) + { result = processed; - } else if (status == errSSLWouldBlock) { + } + else if (status == errSSLWouldBlock) + { result = processed; - } else if (status == errSSLClosedGraceful) { + } + else if (status == errSSLClosedGraceful) + { result = kReadZero; - } else { + } + else + { result = kReadFailed; } return result; } -int TlsSession_osx::writePlain(const char* buffer, size_t bytes) { +int TlsSession_osx::writePlain(const char* buffer, size_t bytes) +{ int result = 0; size_t processed; OSStatus status = SSLWrite(_session, buffer, bytes, &processed); - if (status == noErr) { + if (status == noErr) + { result = processed; - } else { + } + else + { result = -1; } return result; } -OSStatus TlsSession_osx::writeCallback(SSLConnectionRef connection, const void* data, size_t* dataLength) { +OSStatus TlsSession_osx::writeCallback(SSLConnectionRef connection, const void* data, size_t* dataLength) +{ TlsSession_osx* tls = reinterpret_cast(const_cast(connection)); tls->_outBuffer.insert(tls->_outBuffer.end(), reinterpret_cast(data), reinterpret_cast(data) + *dataLength); - if (tls->_shutdown && !tls->_outBuffer.size()) { + if (tls->_shutdown && !tls->_outBuffer.size()) + { SSLClose(tls->_session); tls->_shutdown = false; } return noErr; } -OSStatus TlsSession_osx::readCallback(SSLConnectionRef connection, void* data, size_t* dataLength) { +OSStatus TlsSession_osx::readCallback(SSLConnectionRef connection, void* data, size_t* dataLength) +{ TlsSession_osx* tls = reinterpret_cast(const_cast(connection)); OSStatus result = noErr; size_t bytes = std::min(tls->_inBuffer.size(), *dataLength); - if (bytes > 0) { + if (bytes > 0) + { std::memcpy(data, tls->_inBuffer.data(), bytes); tls->_inBuffer.erase(tls->_inBuffer.begin(), tls->_inBuffer.begin() + bytes); } - if (bytes < *dataLength) { + if (bytes < *dataLength) + { result = errSSLWouldBlock; } *dataLength = bytes; return result; } -int TlsSession_osx::readEncrypted(char* buffer, size_t bytes) { +int TlsSession_osx::readEncrypted(char* buffer, size_t bytes) +{ size_t size = std::min(bytes, _outBuffer.size()); - if (size > 0) { + if (size > 0) + { std::memcpy(buffer, _outBuffer.data(), size); _outBuffer.erase(_outBuffer.begin(), _outBuffer.begin() + size); } return size; } -int TlsSession_osx::writeEncrypted(const char* buffer, size_t bytes) { +int TlsSession_osx::writeEncrypted(const char* buffer, size_t bytes) +{ _inBuffer.insert(_inBuffer.end(), buffer, buffer + bytes); return bytes; } -int TlsSession_osx::getPeerCertificate(char* buffer, size_t size) { +int TlsSession_osx::getPeerCertificate(char* buffer, size_t size) +{ int result = -1; SecTrustRef trust = 0; - if (SSLCopyPeerTrust(_session, &trust) == noErr) { - if (SecTrustGetCertificateCount(trust) > 0) { + if (SSLCopyPeerTrust(_session, &trust) == noErr) + { + if (SecTrustGetCertificateCount(trust) > 0) + { SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, 0); CFDataRef data = 0; - if (SecItemExport(certificate, kSecFormatX509Cert, kSecItemPemArmour, nil, &data) == noErr) { + if (SecItemExport(certificate, kSecFormatX509Cert, kSecItemPemArmour, nil, &data) == noErr) + { size_t actualSize = CFDataGetLength(data); - if (actualSize <= size) { + if (actualSize <= size) + { CFDataGetBytes(data, CFRangeMake(0, actualSize), reinterpret_cast(buffer)); result = actualSize; } @@ -327,7 +389,8 @@ int TlsSession_osx::getPeerCertificate(char* buffer, size_t size) { return result; } -TlsContext* TlsContext::create() { +TlsContext* TlsContext::create() +{ return new TlsContext_osx(); } #elif defined (_WIN32) @@ -355,9 +418,15 @@ public: TlsSession* createSession() override; bool setCertificate(const char* certificate) override; bool setPrivateKey(const char* privateKey) override; - bool addTrustedCertificate(const char* certificate) { return false; } + bool addTrustedCertificate(const char* certificate) + { + return false; + } - PCCERT_CONTEXT& getCertificate() { return _certificate; } + PCCERT_CONTEXT& getCertificate() + { + return _certificate; + } private: static const char* kContainerName; @@ -388,7 +457,10 @@ public: int readEncrypted(char* buffer, size_t bytes) override; int writeEncrypted(const char* buffer, size_t bytes) override; - void setHostname(const char* hostname) { _hostname = hostname; } + void setHostname(const char* hostname) + { + _hostname = hostname; + } static void setError(HRESULT error); bool getError(char* buffer, size_t bytes) override; @@ -412,11 +484,13 @@ private: HRESULT TlsSession_sspi::_lastError = S_OK; -PSecurityFunctionTable getSecurityLibrary() { +PSecurityFunctionTable getSecurityLibrary() +{ PSecurityFunctionTable (*table)(); static PSecurityFunctionTable security; static bool loaded; - if (!loaded) { + if (!loaded) + { HMODULE module = LoadLibrary("security.dll"); table = (PSecurityFunctionTable(*)())GetProcAddress(module, "InitSecurityInterfaceA"); assert(table && "failed to load security.dll"); @@ -427,9 +501,12 @@ PSecurityFunctionTable getSecurityLibrary() { return security; } -TlsContext_sspi::TlsContext_sspi() { - if (!CryptAcquireContext(&_provider, kContainerName, MS_DEF_RSA_SCHANNEL_PROV, PROV_RSA_SCHANNEL, CRYPT_NEWKEYSET)) { - if (GetLastError() != NTE_EXISTS || !CryptAcquireContext(&_provider, kContainerName, MS_DEF_RSA_SCHANNEL_PROV, PROV_RSA_SCHANNEL, 0)) { +TlsContext_sspi::TlsContext_sspi() +{ + if (!CryptAcquireContext(&_provider, kContainerName, MS_DEF_RSA_SCHANNEL_PROV, PROV_RSA_SCHANNEL, CRYPT_NEWKEYSET)) + { + if (GetLastError() != NTE_EXISTS || !CryptAcquireContext(&_provider, kContainerName, MS_DEF_RSA_SCHANNEL_PROV, PROV_RSA_SCHANNEL, 0)) + { TlsSession_sspi::setError(GetLastError()); } } @@ -441,41 +518,51 @@ TlsContext_sspi::TlsContext_sspi() { L"MY"); } -TlsContext_sspi::~TlsContext_sspi() { - if (_store) { +TlsContext_sspi::~TlsContext_sspi() +{ + if (_store) + { CertCloseStore(_store, 0); _store = INVALID_HANDLE_VALUE; } - if (_provider) { + if (_provider) + { CryptReleaseContext(_provider, 0); _provider = 0; } - if (_certificate) { + if (_certificate) + { CertFreeCertificateContext(_certificate); _certificate = 0; } } -bool TlsContext_sspi::setCertificate(const char* certificate) { - if (_certificate) { +bool TlsContext_sspi::setCertificate(const char* certificate) +{ + if (_certificate) + { CertFreeCertificateContext(_certificate); _certificate = 0; } std::vector certificateBuffer; DWORD size = 0; - if (CryptStringToBinary(certificate, 0, CRYPT_STRING_BASE64HEADER, 0, &size, 0, 0)) { + if (CryptStringToBinary(certificate, 0, CRYPT_STRING_BASE64HEADER, 0, &size, 0, 0)) + { certificateBuffer.resize(size); - if (!CryptStringToBinary(certificate, 0, CRYPT_STRING_BASE64HEADER, certificateBuffer.data(), &size, 0, 0)) { + if (!CryptStringToBinary(certificate, 0, CRYPT_STRING_BASE64HEADER, certificateBuffer.data(), &size, 0, 0)) + { certificateBuffer.resize(0); } } - if (certificateBuffer.size()) { + if (certificateBuffer.size()) + { _certificate = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, certificateBuffer.data(), certificateBuffer.size()); } - if (!CertAddCertificateContextToStore(_store, _certificate, CERT_STORE_ADD_REPLACE_EXISTING, 0)) { + if (!CertAddCertificateContextToStore(_store, _certificate, CERT_STORE_ADD_REPLACE_EXISTING, 0)) + { TlsSession_sspi::setError(GetLastError()); } @@ -484,35 +571,43 @@ bool TlsContext_sspi::setCertificate(const char* certificate) { return _certificate != 0; } -bool TlsContext_sspi::setPrivateKey(const char* privateKey) { +bool TlsContext_sspi::setPrivateKey(const char* privateKey) +{ bool result = false; std::vector keyBuffer; std::vector keyBlob; DWORD size = 0; - if (CryptStringToBinary(privateKey, 0, CRYPT_STRING_BASE64HEADER, 0, &size, 0, 0)) { + if (CryptStringToBinary(privateKey, 0, CRYPT_STRING_BASE64HEADER, 0, &size, 0, 0)) + { keyBuffer.resize(size); - if (!CryptStringToBinary(privateKey, 0, CRYPT_STRING_BASE64HEADER, keyBuffer.data(), &size, 0, 0)) { + if (!CryptStringToBinary(privateKey, 0, CRYPT_STRING_BASE64HEADER, keyBuffer.data(), &size, 0, 0)) + { TlsSession_sspi::setError(GetLastError()); keyBuffer.resize(0); } } size = 0; - if (CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, keyBuffer.data(), keyBuffer.size(), 0, 0, 0, &size)) { + if (CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, keyBuffer.data(), keyBuffer.size(), 0, 0, 0, &size)) + { keyBlob.resize(size); - if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, keyBuffer.data(), keyBuffer.size(), 0, 0, keyBlob.data(), &size)) { + if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, keyBuffer.data(), keyBuffer.size(), 0, 0, keyBlob.data(), &size)) + { TlsSession_sspi::setError(GetLastError()); keyBlob.resize(0); } } HCRYPTKEY cryptKey = 0; - if (CryptImportKey(_provider, keyBlob.data(), keyBlob.size(), 0, 0, &cryptKey)) { + if (CryptImportKey(_provider, keyBlob.data(), keyBlob.size(), 0, 0, &cryptKey)) + { CryptDestroyKey(cryptKey); cryptKey = 0; result = true; - } else { + } + else + { TlsSession_sspi::setError(GetLastError()); } @@ -521,8 +616,10 @@ bool TlsContext_sspi::setPrivateKey(const char* privateKey) { return result; } -void TlsContext_sspi::importKeyAndCertificate() { - if (_certificate) { +void TlsContext_sspi::importKeyAndCertificate() +{ + if (_certificate) + { WCHAR wname[32]; mbstowcs(wname, kContainerName, sizeof(kContainerName) + 1); @@ -533,33 +630,39 @@ void TlsContext_sspi::importKeyAndCertificate() { info.dwProvType = PROV_RSA_SCHANNEL; info.dwKeySpec = AT_KEYEXCHANGE; - if (!CertSetCertificateContextProperty(_certificate, CERT_KEY_PROV_INFO_PROP_ID, 0, reinterpret_cast(&info))) { + if (!CertSetCertificateContextProperty(_certificate, CERT_KEY_PROV_INFO_PROP_ID, 0, reinterpret_cast(&info))) + { TlsSession_sspi::setError(GetLastError()); } } _dirty = false; } -TlsSession* TlsContext_sspi::createSession() { - if (_dirty) { +TlsSession* TlsContext_sspi::createSession() +{ + if (_dirty) + { importKeyAndCertificate(); } return new TlsSession_sspi(this); } -TlsSession_sspi::TlsSession_sspi(TlsContext_sspi* context) { +TlsSession_sspi::TlsSession_sspi(TlsContext_sspi* context) +{ _context = context; ZeroMemory(&_credentialsHandle, sizeof(_credentialsHandle)); ZeroMemory(&_securityContext, sizeof(_securityContext)); ZeroMemory(&_sizes, sizeof(_sizes)); } -TlsSession_sspi::~TlsSession_sspi() { +TlsSession_sspi::~TlsSession_sspi() +{ getSecurityLibrary()->FreeCredentialsHandle(&_credentialsHandle); getSecurityLibrary()->DeleteSecurityContext(&_securityContext); } -void TlsSession_sspi::startAccept() { +void TlsSession_sspi::startAccept() +{ _direction = k_direction_accept; _initial = true; SCHANNEL_CRED credentials; @@ -568,12 +671,14 @@ void TlsSession_sspi::startAccept() { credentials.cCreds = 1; credentials.paCred = &_context->getCertificate(); _lastError = getSecurityLibrary()->AcquireCredentialsHandleA(0, UNISP_NAME_A, SECPKG_CRED_INBOUND, 0, &credentials, 0, 0, &_credentialsHandle, 0); - if (_lastError == S_OK) { + if (_lastError == S_OK) + { handshakeInternal(true); } } -void TlsSession_sspi::startConnect() { +void TlsSession_sspi::startConnect() +{ _direction = k_direction_connect; _initial = true; SCHANNEL_CRED credentials; @@ -581,27 +686,34 @@ void TlsSession_sspi::startConnect() { credentials.dwVersion = SCHANNEL_CRED_VERSION; credentials.dwFlags = SCH_CRED_NO_DEFAULT_CREDS; _lastError = getSecurityLibrary()->AcquireCredentialsHandleA(0, UNISP_NAME_A, SECPKG_CRED_OUTBOUND, 0, &credentials, 0, 0, &_credentialsHandle, 0); - if (_lastError == S_OK) { + if (_lastError == S_OK) + { handshakeInternal(true); } } -int TlsSession_sspi::getPeerCertificate(char* buffer, size_t size) { +int TlsSession_sspi::getPeerCertificate(char* buffer, size_t size) +{ int result = -1; PCCERT_CONTEXT certificate; HRESULT status = getSecurityLibrary()->QueryContextAttributesA(&_securityContext, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &certificate); - if (FAILED(status)) { + if (FAILED(status)) + { _lastError = status; - } else { + } + else + { DWORD bufferSize = size; - if (CryptBinaryToString(certificate->pbCertEncoded, certificate->cbCertEncoded, CRYPT_STRING_BASE64HEADER, buffer, &bufferSize)) { + if (CryptBinaryToString(certificate->pbCertEncoded, certificate->cbCertEncoded, CRYPT_STRING_BASE64HEADER, buffer, &bufferSize)) + { return bufferSize; } } return result; } -void TlsSession_sspi::shutdown() { +void TlsSession_sspi::shutdown() +{ DWORD type = SCHANNEL_SHUTDOWN; SecBufferDesc bufferDesc; SecBuffer buffers[1]; @@ -613,7 +725,8 @@ void TlsSession_sspi::shutdown() { bufferDesc.ulVersion = SECBUFFER_TOKEN; SECURITY_STATUS status = getSecurityLibrary()->ApplyControlToken(&_securityContext, &bufferDesc); - if (!FAILED(status)) { + if (!FAILED(status)) + { buffers[0].pvBuffer = 0; buffers[0].BufferType = SECBUFFER_TOKEN; buffers[0].cbBuffer = 0; @@ -637,18 +750,21 @@ void TlsSession_sspi::shutdown() { &outFlags, 0); - if (!FAILED(status) && buffers[0].pvBuffer && buffers[0].cbBuffer) { + if (!FAILED(status) && buffers[0].pvBuffer && buffers[0].cbBuffer) + { const char* data = reinterpret_cast(buffers[0].pvBuffer); _outBuffer.insert(_outBuffer.end(), data, data + buffers[0].cbBuffer); } } } -TlsSession::HandshakeResult TlsSession_sspi::handshake() { +TlsSession::HandshakeResult TlsSession_sspi::handshake() +{ return handshakeInternal(_initial); } -TlsSession::HandshakeResult TlsSession_sspi::handshakeInternal(bool initial) { +TlsSession::HandshakeResult TlsSession_sspi::handshakeInternal(bool initial) +{ SecBufferDesc outBuffer; SecBuffer outBuffers[1]; SecBufferDesc inBuffer; @@ -673,7 +789,8 @@ TlsSession::HandshakeResult TlsSession_sspi::handshakeInternal(bool initial) { SECURITY_STATUS status = SEC_E_OK; - if (_direction == k_direction_connect) { + if (_direction == k_direction_connect) + { status = getSecurityLibrary()->InitializeSecurityContextA( &_credentialsHandle, initial ? 0 : &_securityContext, @@ -687,7 +804,9 @@ TlsSession::HandshakeResult TlsSession_sspi::handshakeInternal(bool initial) { &outBuffer, &outFlags, 0); - } else if (_direction = k_direction_accept) { + } + else if (_direction = k_direction_accept) + { status = getSecurityLibrary()->AcceptSecurityContext( &_credentialsHandle, initial ? 0 : &_securityContext, @@ -700,45 +819,58 @@ TlsSession::HandshakeResult TlsSession_sspi::handshakeInternal(bool initial) { 0); } - if (!FAILED(status)) { + if (!FAILED(status)) + { _initial = false; } TlsSession::HandshakeResult result = TlsSession::kFailed; size_t extra = 0; - for (int i = 0; i < inBuffer.cBuffers; ++i) { - if (inBuffers[i].BufferType == SECBUFFER_EXTRA && inBuffers[i].cbBuffer) { + for (int i = 0; i < inBuffer.cBuffers; ++i) + { + if (inBuffers[i].BufferType == SECBUFFER_EXTRA && inBuffers[i].cbBuffer) + { extra += inBuffers[i].cbBuffer; } } size_t missing = 0; - for (int i = 0; i < inBuffer.cBuffers; ++i) { - if (inBuffers[i].BufferType == SECBUFFER_MISSING && inBuffers[i].cbBuffer) { + for (int i = 0; i < inBuffer.cBuffers; ++i) + { + if (inBuffers[i].BufferType == SECBUFFER_MISSING && inBuffers[i].cbBuffer) + { missing += inBuffers[i].cbBuffer; } } - if (outBuffers[0].cbBuffer && outBuffers[0].pvBuffer) { + if (outBuffers[0].cbBuffer && outBuffers[0].pvBuffer) + { const char* data = reinterpret_cast(outBuffers[0].pvBuffer); _outBuffer.insert(_outBuffer.end(), data, data + outBuffers[0].cbBuffer); getSecurityLibrary()->FreeContextBuffer(outBuffers[0].pvBuffer); } - if (status == SEC_E_OK) { + if (status == SEC_E_OK) + { result = TlsSession::kDone; - } else if (status == SEC_E_INCOMPLETE_MESSAGE - || status == SEC_I_CONTINUE_NEEDED) { + } + else if (status == SEC_E_INCOMPLETE_MESSAGE + || status == SEC_I_CONTINUE_NEEDED) + { result = TlsSession::kMore; - } else if (FAILED(status)) { + } + else if (FAILED(status)) + { result = TlsSession::kFailed; } _inBuffer.erase(_inBuffer.begin(), _inBuffer.end() - extra); - if (result == TlsSession::kDone) { + if (result == TlsSession::kDone) + { status = getSecurityLibrary()->QueryContextAttributesA(&_securityContext, SECPKG_ATTR_STREAM_SIZES, &_sizes); - if (FAILED(status)) { + if (FAILED(status)) + { result = TlsSession::kFailed; } } @@ -746,13 +878,17 @@ TlsSession::HandshakeResult TlsSession_sspi::handshakeInternal(bool initial) { return result; } -int TlsSession_sspi::readPlain(char* buffer, size_t bytes) { +int TlsSession_sspi::readPlain(char* buffer, size_t bytes) +{ int result = TlsSession::kReadFailed; - if (bytes <= _decryptedBuffer.size()) { + if (bytes <= _decryptedBuffer.size()) + { std::memcpy(buffer, _decryptedBuffer.data(), bytes); _decryptedBuffer.erase(_decryptedBuffer.begin(), _decryptedBuffer.begin() + bytes); result = bytes; - } else if (_inBuffer.size()) { + } + else if (_inBuffer.size()) + { SecBufferDesc bufferDesc; SecBuffer buffers[4]; std::vector data(_inBuffer); @@ -767,48 +903,66 @@ int TlsSession_sspi::readPlain(char* buffer, size_t bytes) { bufferDesc.pBuffers = buffers; SECURITY_STATUS status = getSecurityLibrary()->DecryptMessage(&_securityContext, &bufferDesc, 0, 0); - if (status == SEC_I_CONTEXT_EXPIRED) { + if (status == SEC_I_CONTEXT_EXPIRED) + { _inBuffer.clear(); result = TlsSession::kReadZero; - } else if (status == SEC_E_INCOMPLETE_MESSAGE) { + } + else if (status == SEC_E_INCOMPLETE_MESSAGE) + { result = 0; - } else if (status == SEC_E_OK) { + } + else if (status == SEC_E_OK) + { result = 0; size_t extra = 0; - for (int i = 0; i < bufferDesc.cBuffers; ++i) { - if (buffers[i].BufferType == SECBUFFER_DATA) { + for (int i = 0; i < bufferDesc.cBuffers; ++i) + { + if (buffers[i].BufferType == SECBUFFER_DATA) + { const char* decrypted = reinterpret_cast(buffers[i].pvBuffer); _decryptedBuffer.insert(_decryptedBuffer.end(), decrypted, decrypted + buffers[i].cbBuffer); - } else if (buffers[i].BufferType == SECBUFFER_EXTRA) { + } + else if (buffers[i].BufferType == SECBUFFER_EXTRA) + { extra += buffers[i].cbBuffer; } } _inBuffer.erase(_inBuffer.begin(), _inBuffer.end() - extra); size_t actual = std::min(_decryptedBuffer.size(), bytes); - if (actual > 0) { + if (actual > 0) + { std::memcpy(buffer, _decryptedBuffer.data(), actual); _decryptedBuffer.erase(_decryptedBuffer.begin(), _decryptedBuffer.begin() + actual); result = actual; } - } else { + } + else + { _inBuffer.clear(); result = TlsSession::kReadFailed; } - } else { + } + else + { size_t actual = std::min(_decryptedBuffer.size(), bytes); - if (actual > 0) { + if (actual > 0) + { std::memcpy(buffer, _decryptedBuffer.data(), actual); _decryptedBuffer.erase(_decryptedBuffer.begin(), _decryptedBuffer.begin() + actual); result = actual; - } else { + } + else + { result = 0; } } return result; } -int TlsSession_sspi::writePlain(const char* buffer, size_t bytes) { +int TlsSession_sspi::writePlain(const char* buffer, size_t bytes) +{ SecBufferDesc bufferDesc; SecBuffer buffers[4]; std::vector data(_sizes.cbHeader + _sizes.cbTrailer + bytes); @@ -832,8 +986,10 @@ int TlsSession_sspi::writePlain(const char* buffer, size_t bytes) { bufferDesc.cBuffers = 4; bufferDesc.pBuffers = buffers; SECURITY_STATUS status = getSecurityLibrary()->EncryptMessage(&_securityContext, 0, &bufferDesc, 0); - for (int i = 0; i < bufferDesc.cBuffers; ++i) { - if (buffers[i].BufferType != SECBUFFER_EMPTY && buffers[i].pvBuffer && buffers[i].cbBuffer) { + for (int i = 0; i < bufferDesc.cBuffers; ++i) + { + if (buffers[i].BufferType != SECBUFFER_EMPTY && buffers[i].pvBuffer && buffers[i].cbBuffer) + { const char* bufferData = reinterpret_cast(buffers[i].pvBuffer); _outBuffer.insert(_outBuffer.end(), bufferData, bufferData + buffers[i].cbBuffer); } @@ -841,46 +997,56 @@ int TlsSession_sspi::writePlain(const char* buffer, size_t bytes) { return 0; } -int TlsSession_sspi::readEncrypted(char* buffer, size_t bytes) { +int TlsSession_sspi::readEncrypted(char* buffer, size_t bytes) +{ size_t size = std::min(bytes, _outBuffer.size()); - if (size > 0) { + if (size > 0) + { std::memcpy(buffer, _outBuffer.data(), size); _outBuffer.erase(_outBuffer.begin(), _outBuffer.begin() + size); } return size; } -int TlsSession_sspi::writeEncrypted(const char* buffer, size_t bytes) { +int TlsSession_sspi::writeEncrypted(const char* buffer, size_t bytes) +{ _inBuffer.insert(_inBuffer.end(), buffer, buffer + bytes); return bytes; } -void TlsSession_sspi::setError(HRESULT error) { +void TlsSession_sspi::setError(HRESULT error) +{ _lastError = error; } -bool TlsSession_sspi::getError(char* buffer, size_t bytes) { +bool TlsSession_sspi::getError(char* buffer, size_t bytes) +{ bool result = false; - if (_lastError != S_OK) { + if (_lastError != S_OK) + { DWORD length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, _lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)buffer, bytes, 0); _lastError = S_OK; - if (length > 0) { + if (length > 0) + { result = true; } } return result; } -TlsContext* TlsContext::create() { +TlsContext* TlsContext::create() +{ return new TlsContext_sspi(); } #else -TlsContext* TlsContext::create() { +TlsContext* TlsContext::create() +{ return 0; } #endif -tf_tls_context_t* tf_tls_context_create() { +tf_tls_context_t* tf_tls_context_create() +{ tf_tls_context_t* context = malloc(sizeof(tf_tls_context_t)); memset(context, 0, sizeof(*context)); #if defined(TF_TLS_OPENSSL) @@ -894,18 +1060,23 @@ tf_tls_context_t* tf_tls_context_create() { return context; } -bool tf_tls_context_set_certificate(tf_tls_context_t* context, const char* certificate) { +bool tf_tls_context_set_certificate(tf_tls_context_t* context, const char* certificate) +{ #if defined(TF_TLS_OPENSSL) int result = 0; BIO* bio = BIO_new(BIO_s_mem()); BIO_puts(bio, certificate); X509* x509 = PEM_read_bio_X509(bio, 0, 0, 0); result = SSL_CTX_use_certificate(context->context, x509); - while (true) { + while (true) + { x509 = PEM_read_bio_X509(bio, 0, 0, 0); - if (x509) { + if (x509) + { SSL_CTX_add_extra_chain_cert(context->context, x509); - } else { + } + else + { break; } } @@ -916,7 +1087,8 @@ bool tf_tls_context_set_certificate(tf_tls_context_t* context, const char* certi #endif } -bool tf_tls_context_set_private_key(tf_tls_context_t* context, const char* private_key) { +bool tf_tls_context_set_private_key(tf_tls_context_t* context, const char* private_key) +{ #if defined(TF_TLS_OPENSSL) int result = 0; BIO* bio = BIO_new(BIO_s_mem()); @@ -930,16 +1102,19 @@ bool tf_tls_context_set_private_key(tf_tls_context_t* context, const char* priva #endif } -bool tf_tls_context_add_trusted_certificate(tf_tls_context_t* context, const char* certificate) { +bool tf_tls_context_add_trusted_certificate(tf_tls_context_t* context, const char* certificate) +{ #if defined(TF_TLS_OPENSSL) bool result = false; BIO* bio = BIO_new_mem_buf(certificate, -1); X509* x509 = PEM_read_bio_X509(bio, 0, 0, 0); BIO_free(bio); - if (x509) { + if (x509) + { X509_STORE* store = SSL_CTX_get_cert_store(context->context); - if (store && X509_STORE_add_cert(store, x509) == 1) { + if (store && X509_STORE_add_cert(store, x509) == 1) + { result = true; } X509_free(x509); @@ -951,7 +1126,8 @@ bool tf_tls_context_add_trusted_certificate(tf_tls_context_t* context, const cha #endif } -tf_tls_session_t* tf_tls_context_create_session(tf_tls_context_t* context) { +tf_tls_session_t* tf_tls_context_create_session(tf_tls_context_t* context) +{ #if defined(TF_TLS_OPENSSL) tf_tls_session_t* session = malloc(sizeof(tf_tls_session_t)); memset(session, 0, sizeof(*session)); @@ -964,7 +1140,8 @@ tf_tls_session_t* tf_tls_context_create_session(tf_tls_context_t* context) { #endif } -void tf_tls_context_destroy(tf_tls_context_t* context) { +void tf_tls_context_destroy(tf_tls_context_t* context) +{ #if defined(TF_TLS_OPENSSL) SSL_CTX_free(context->context); free(context); @@ -973,12 +1150,15 @@ void tf_tls_context_destroy(tf_tls_context_t* context) { #endif } -void tf_tls_session_destroy(tf_tls_session_t* session) { +void tf_tls_session_destroy(tf_tls_session_t* session) +{ #if defined(TF_TLS_OPENSSL) - if (session->ssl) { + if (session->ssl) + { SSL_free(session->ssl); } - if (session->hostname) { + if (session->hostname) + { free((void*)session->hostname); } free(session); @@ -987,13 +1167,16 @@ void tf_tls_session_destroy(tf_tls_session_t* session) { #endif } -void tf_tls_session_set_hostname(tf_tls_session_t* session, const char* hostname) { +void tf_tls_session_set_hostname(tf_tls_session_t* session, const char* hostname) +{ #if defined(TF_TLS_OPENSSL) - if (session->hostname) { + if (session->hostname) + { free((void*)session->hostname); session->hostname = NULL; } - if (hostname) { + if (hostname) + { session->hostname = strdup(hostname); } #elif defined(TF_TLS_APPLE) @@ -1001,7 +1184,8 @@ void tf_tls_session_set_hostname(tf_tls_session_t* session, const char* hostname #endif } -void tf_tls_session_start_accept(tf_tls_session_t* session) { +void tf_tls_session_start_accept(tf_tls_session_t* session) +{ #if defined(TF_TLS_OPENSSL) session->direction = k_direction_accept; session->ssl = SSL_new(session->context->context); @@ -1013,7 +1197,8 @@ void tf_tls_session_start_accept(tf_tls_session_t* session) { #endif } -void tf_tls_session_start_connect(tf_tls_session_t* session) { +void tf_tls_session_start_connect(tf_tls_session_t* session) +{ #if defined(TF_TLS_OPENSSL) session->direction = k_direction_connect; session->ssl = SSL_new(session->context->context); @@ -1028,7 +1213,8 @@ void tf_tls_session_start_connect(tf_tls_session_t* session) { #endif } -void tf_tls_session_shutdown(tf_tls_session_t* session) { +void tf_tls_session_shutdown(tf_tls_session_t* session) +{ #if defined(TF_TLS_OPENSSL) SSL_shutdown(session->ssl); #elif defined(TF_TLS_APPLE) @@ -1036,7 +1222,8 @@ void tf_tls_session_shutdown(tf_tls_session_t* session) { #endif } -int tf_tls_session_get_peer_certificate(tf_tls_session_t* session, char* buffer, size_t bytes) { +int tf_tls_session_get_peer_certificate(tf_tls_session_t* session, char* buffer, size_t bytes) +{ #if defined(TF_TLS_OPENSSL) int result = -1; X509* certificate = SSL_get_peer_certificate(session->ssl); @@ -1044,7 +1231,8 @@ int tf_tls_session_get_peer_certificate(tf_tls_session_t* session, char* buffer, PEM_write_bio_X509(bio, certificate); BUF_MEM* mem; BIO_get_mem_ptr(bio, &mem); - if (mem->length <= bytes) { + if (mem->length <= bytes) + { memcpy(buffer, mem->data, mem->length); result = mem->length; } @@ -1057,41 +1245,55 @@ int tf_tls_session_get_peer_certificate(tf_tls_session_t* session, char* buffer, #if defined(TF_TLS_OPENSSL) #if OPENSSL_VERSION_NUMBER < 0x10100000L -bool _tls_session_wildcard_match(const char* pattern, size_t pattern_length, const char* name) { +bool _tls_session_wildcard_match(const char* pattern, size_t pattern_length, const char* name) +{ const char* it = pattern; - while (it - pattern < pattern_length && *name) { - if (*it == '*') { - for (const char* p = name; *p; ++p) { - if (_tls_session_wildcard_match(it + 1, pattern_length - 1, p)) { + while (it - pattern < pattern_length && *name) + { + if (*it == '*') + { + for (const char* p = name; *p; ++p) + { + if (_tls_session_wildcard_match(it + 1, pattern_length - 1, p)) + { return true; } } return false; - } else if (tolower(*it) == tolower(*name)) { + } + else if (tolower(*it) == tolower(*name)) + { ++it; ++name; - } else { + } + else + { break; } } return it - pattern <= pattern_length && *name == 0; } -static bool _tls_session_verify_hostname(X509* certificate, const char* hostname) { +static bool _tls_session_verify_hostname(X509* certificate, const char* hostname) +{ bool verified = false; void* names = X509_get_ext_d2i(certificate, NID_subject_alt_name, 0, 0); - if (names) { + if (names) + { int count = sk_GENERAL_NAME_num(names); - for (int i = 0; i < count; ++i) { + for (int i = 0; i < count; ++i) + { const GENERAL_NAME* check = sk_GENERAL_NAME_value(names, i); - if (!verified) { + if (!verified) + { #if OPENSSL_VERSION_NUMBER <= 0x1000211fL const unsigned char* name = ASN1_STRING_data(check->d.ia5); #else const char* name = ASN1_STRING_get0_data(check->d.ia5); #endif size_t length = ASN1_STRING_length(check->d.ia5); - if (_tls_session_wildcard_match((const char*)name, length, hostname)) { + if (_tls_session_wildcard_match((const char*)name, length, hostname)) + { verified = true; } } @@ -1099,19 +1301,24 @@ static bool _tls_session_verify_hostname(X509* certificate, const char* hostname sk_GENERAL_NAMES_free(names); } - if (!verified) { + if (!verified) + { int index = X509_NAME_get_index_by_NID(X509_get_subject_name(certificate), NID_commonName, -1); - if (index >= 0) { + if (index >= 0) + { X509_NAME_ENTRY* entry = X509_NAME_get_entry(X509_get_subject_name(certificate), index); - if (entry) { + if (entry) + { ASN1_STRING* asn1 = X509_NAME_ENTRY_get_data(entry); - if (asn1) { + if (asn1) + { #if OPENSSL_VERSION_NUMBER <= 0x1000211fL const unsigned char* commonName = ASN1_STRING_data(asn1); #else const char* commonName = ASN1_STRING_get0_data(asn1); #endif - if ((size_t)(ASN1_STRING_length(asn1)) == strlen((const char*)commonName)) { + if ((size_t)(ASN1_STRING_length(asn1)) == strlen((const char*)commonName)) + { verified = _tls_session_wildcard_match((const char*)commonName, ASN1_STRING_length(asn1), hostname); } } @@ -1123,13 +1330,17 @@ static bool _tls_session_verify_hostname(X509* certificate, const char* hostname } #endif -static bool _tls_session_verify_peer_certificate(tf_tls_session_t* session) { +static bool _tls_session_verify_peer_certificate(tf_tls_session_t* session) +{ bool verified = false; X509* certificate = SSL_get_peer_certificate(session->ssl); - if (certificate) { - if (SSL_get_verify_result(session->ssl) == X509_V_OK) { + if (certificate) + { + if (SSL_get_verify_result(session->ssl) == X509_V_OK) + { #if OPENSSL_VERSION_NUMBER < 0x10100000L - if (_tls_session_verify_hostname(certificate, session->hostname)) { + if (_tls_session_verify_hostname(certificate, session->hostname)) + { verified = true; } #else @@ -1142,21 +1353,28 @@ static bool _tls_session_verify_peer_certificate(tf_tls_session_t* session) { } #endif -tf_tls_handshake_t tf_tls_session_handshake(tf_tls_session_t* session) { +tf_tls_handshake_t tf_tls_session_handshake(tf_tls_session_t* session) +{ #if defined(TF_TLS_OPENSSL) tf_tls_handshake_t result = k_tls_handshake_done; - if (!SSL_is_init_finished(session->ssl)) { + if (!SSL_is_init_finished(session->ssl)) + { int value = SSL_do_handshake(session->ssl); - if (value <= 0) { + if (value <= 0) + { int error = SSL_get_error(session->ssl, value); - if (error != SSL_ERROR_WANT_READ && error != SSL_ERROR_WANT_WRITE) { + if (error != SSL_ERROR_WANT_READ && error != SSL_ERROR_WANT_WRITE) + { result = k_tls_handshake_failed; - } else { + } + else + { result = k_tls_handshake_more; } } } - if (result == k_tls_handshake_done && session->direction == k_direction_connect && !_tls_session_verify_peer_certificate(session)) { + if (result == k_tls_handshake_done && session->direction == k_direction_connect && !_tls_session_verify_peer_certificate(session)) + { result = k_tls_handshake_failed; } return result; @@ -1165,20 +1383,30 @@ tf_tls_handshake_t tf_tls_session_handshake(tf_tls_session_t* session) { #endif } -int tf_tls_session_read_plain(tf_tls_session_t* session, char* buffer, size_t bytes) { +int tf_tls_session_read_plain(tf_tls_session_t* session, char* buffer, size_t bytes) +{ #if defined(TF_TLS_OPENSSL) int result = SSL_read(session->ssl, buffer, bytes); - if (result <= 0) { + if (result <= 0) + { int error = SSL_get_error(session->ssl, result); - if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) { + if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) + { result = 0; - } else if (error == SSL_ERROR_ZERO_RETURN) { - if ((SSL_get_shutdown(session->ssl) & SSL_RECEIVED_SHUTDOWN) != 0) { + } + else if (error == SSL_ERROR_ZERO_RETURN) + { + if ((SSL_get_shutdown(session->ssl) & SSL_RECEIVED_SHUTDOWN) != 0) + { result = k_tls_read_zero; - } else { + } + else + { result = 0; } - } else { + } + else + { result = k_tls_read_failed; } } @@ -1188,7 +1416,8 @@ int tf_tls_session_read_plain(tf_tls_session_t* session, char* buffer, size_t by #endif } -int tf_tls_session_write_plain(tf_tls_session_t* session, const char* buffer, size_t bytes) { +int tf_tls_session_write_plain(tf_tls_session_t* session, const char* buffer, size_t bytes) +{ #if defined(TF_TLS_OPENSSL) return SSL_write(session->ssl, buffer, bytes); #elif defined(TF_TLS_APPLE) @@ -1196,7 +1425,8 @@ int tf_tls_session_write_plain(tf_tls_session_t* session, const char* buffer, si #endif } -int tf_tls_session_read_encrypted(tf_tls_session_t* session, char* buffer, size_t bytes) { +int tf_tls_session_read_encrypted(tf_tls_session_t* session, char* buffer, size_t bytes) +{ #if defined(TF_TLS_OPENSSL) return BIO_read(session->bio_out, buffer, bytes); #elif defined(TF_TLS_APPLE) @@ -1204,7 +1434,8 @@ int tf_tls_session_read_encrypted(tf_tls_session_t* session, char* buffer, size_ #endif } -int tf_tls_session_write_encrypted(tf_tls_session_t* session, const char* buffer, size_t bytes) { +int tf_tls_session_write_encrypted(tf_tls_session_t* session, const char* buffer, size_t bytes) +{ #if defined(TF_TLS_OPENSSL) return BIO_write(session->bio_in, buffer, bytes); #elif defined(TF_TLS_APPLE) @@ -1212,10 +1443,12 @@ int tf_tls_session_write_encrypted(tf_tls_session_t* session, const char* buffer #endif } -bool tf_tls_session_get_error(tf_tls_session_t* session, char* buffer, size_t bytes) { +bool tf_tls_session_get_error(tf_tls_session_t* session, char* buffer, size_t bytes) +{ #if defined(TF_TLS_OPENSSL) unsigned long error = ERR_get_error(); - if (error != 0) { + if (error != 0) + { ERR_error_string_n(error, buffer, bytes); } return error != 0; diff --git a/src/tlscontextwrapper.c b/src/tlscontextwrapper.c index 31f0321b..6df0d9f1 100644 --- a/src/tlscontextwrapper.c +++ b/src/tlscontextwrapper.c @@ -23,7 +23,8 @@ static JSValue _tls_context_wrapper_add_trusted_certificate(JSContext* context, static JSValue _tls_context_wrapper_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static void _tls_context_wrapper_finalizer(JSRuntime *runtime, JSValue value); -JSValue _tls_context_wrapper_set_certificate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _tls_context_wrapper_set_certificate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_tls_context_wrapper_t* wrapper = JS_GetOpaque(this_val, _classId); const char* value = JS_ToCString(context, argv[0]); tf_tls_context_set_certificate(wrapper->context, value); @@ -31,7 +32,8 @@ JSValue _tls_context_wrapper_set_certificate(JSContext* context, JSValueConst th return JS_UNDEFINED; } -JSValue _tls_context_wrapper_set_private_key(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _tls_context_wrapper_set_private_key(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_tls_context_wrapper_t* wrapper = JS_GetOpaque(this_val, _classId); const char* value = JS_ToCString(context, argv[0]); tf_tls_context_set_private_key(wrapper->context, value); @@ -39,7 +41,8 @@ JSValue _tls_context_wrapper_set_private_key(JSContext* context, JSValueConst th return JS_UNDEFINED; } -JSValue _tls_context_wrapper_add_trusted_certificate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _tls_context_wrapper_add_trusted_certificate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_tls_context_wrapper_t* wrapper = JS_GetOpaque(this_val, _classId); const char* value = JS_ToCString(context, argv[0]); tf_tls_context_add_trusted_certificate(wrapper->context, value); @@ -47,28 +50,34 @@ JSValue _tls_context_wrapper_add_trusted_certificate(JSContext* context, JSValue return JS_UNDEFINED; } -JSValue tf_tls_context_wrapper_init(JSContext* context) { +JSValue tf_tls_context_wrapper_init(JSContext* context) +{ JS_NewClassID(&_classId); - JSClassDef def = { + JSClassDef def = + { .class_name = "TlsContext", .finalizer = _tls_context_wrapper_finalizer, }; - if (JS_NewClass(JS_GetRuntime(context), _classId, &def) != 0) { + if (JS_NewClass(JS_GetRuntime(context), _classId, &def) != 0) + { fprintf(stderr, "Failed to register TlsContext.\n"); } return JS_NewCFunction2(context, _tls_context_wrapper_create, "TlsContext", 0, JS_CFUNC_constructor, 0); } -tf_tls_context_t* tf_tls_context_wrapper_get(JSValue value) { +tf_tls_context_t* tf_tls_context_wrapper_get(JSValue value) +{ tf_tls_context_wrapper_t* wrapper = JS_GetOpaque(value, _classId); return wrapper ? wrapper->context : NULL; } -int tf_tls_context_wrapper_get_count() { +int tf_tls_context_wrapper_get_count() +{ return _count; } -JSValue _tls_context_wrapper_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { +JSValue _tls_context_wrapper_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ tf_tls_context_wrapper_t* wrapper = malloc(sizeof(tf_tls_context_wrapper_t)); memset(wrapper, 0, sizeof(*wrapper)); @@ -86,9 +95,11 @@ JSValue _tls_context_wrapper_create(JSContext* context, JSValueConst this_val, i return wrapper->object; } -void _tls_context_wrapper_finalizer(JSRuntime *runtime, JSValue value) { +void _tls_context_wrapper_finalizer(JSRuntime *runtime, JSValue value) +{ tf_tls_context_wrapper_t* wrapper = JS_GetOpaque(value, _classId); - if (wrapper->context) { + if (wrapper->context) + { tf_tls_context_destroy(wrapper->context); wrapper->context = NULL; } diff --git a/src/trace.c b/src/trace.c index dd9b74ad..217136f6 100644 --- a/src/trace.c +++ b/src/trace.c @@ -34,7 +34,8 @@ static int64_t _trace_ts() { int64_t result = 0; struct timespec ts; - if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) + { result = (ts.tv_sec * 1e9 + ts.tv_nsec) / 1e3; } return result; @@ -42,12 +43,14 @@ static int64_t _trace_ts() static void _trace_append(tf_trace_t* trace, const char* buffer, size_t size) { - if (trace->write_offset + size >= k_buffer_size) { + if (trace->write_offset + size >= k_buffer_size) + { trace->buffer[trace->write_offset] = '\0'; trace->write_offset = 0; } - if (trace->write_offset + size < k_buffer_size) { + if (trace->write_offset + size < k_buffer_size) + { memcpy(trace->buffer + trace->write_offset, buffer, size); trace->write_offset += size; trace->buffer[trace->write_offset++] = '\n'; @@ -56,7 +59,8 @@ static void _trace_append(tf_trace_t* trace, const char* buffer, size_t size) void tf_trace_counter(tf_trace_t* trace, const char* name, int argc, const char** arg_names, const int64_t* arg_values) { - if (!trace) { + if (!trace) + { return; } @@ -73,18 +77,22 @@ void tf_trace_counter(tf_trace_t* trace, const char* name, int argc, const char* void tf_trace_begin(tf_trace_t* trace, const char* name) { - if (!trace) { + if (!trace) + { return; } char line[1024]; int p = snprintf(line, sizeof(line), "{\"ph\": \"B\", \"pid\": %d, \"ts\": %" PRId64 ", \"name\": \"", getpid(), _trace_ts()); - for (const char* c = name; *c && p < (int)sizeof(line); c++) { - switch (*c) { + for (const char* c = name; *c && p < (int)sizeof(line); c++) + { + switch (*c) + { case '"': case '\\': line[p++] = '\\'; - if (p < (int)sizeof(line)) { + if (p < (int)sizeof(line)) + { line[p++] = *c; } break; @@ -99,7 +107,8 @@ void tf_trace_begin(tf_trace_t* trace, const char* name) void tf_trace_end(tf_trace_t* trace) { - if (!trace) { + if (!trace) + { return; } @@ -110,7 +119,8 @@ void tf_trace_end(tf_trace_t* trace) char* tf_trace_export(tf_trace_t* trace) { - if (!trace) { + if (!trace) + { return NULL; } @@ -120,14 +130,16 @@ char* tf_trace_export(tf_trace_t* trace) int begin = newline ? newline - trace->buffer : 0; size_t size = 0; size += snprintf(buffer, k_buffer_size, "{\"displayTimeUnit\": \"ns\",\n\"traceEvents\": [\n"); - if (begin) { + if (begin) + { size_t this_size = strlen(trace->buffer + begin); memcpy(buffer + size, trace->buffer + begin, this_size); size += this_size; } memcpy(buffer + size, trace->buffer, trace->write_offset); size += trace->write_offset; - if (size > 2 && buffer[size - 1] == '\n' && buffer[size - 2] == ',') { + if (size > 2 && buffer[size - 1] == '\n' && buffer[size - 2] == ',') + { buffer[size - 2] = '\n'; size--; } @@ -140,11 +152,13 @@ char* tf_trace_export(tf_trace_t* trace) static int _tf_trace_sqlite_callback(unsigned int t, void* c, void* p, void* x) { tf_trace_t* trace = c; - switch (t) { + switch (t) + { case SQLITE_TRACE_STMT: { const char* statement = x; - if (statement[0] != '-' || statement[1] != '-') { + if (statement[0] != '-' || statement[1] != '-') + { tf_trace_begin(trace, statement); } } @@ -158,9 +172,12 @@ static int _tf_trace_sqlite_callback(unsigned int t, void* c, void* p, void* x) void tf_trace_sqlite(tf_trace_t* trace, sqlite3* sqlite) { - if (sqlite) { + if (sqlite) + { sqlite3_trace_v2(sqlite, SQLITE_TRACE_STMT | SQLITE_TRACE_PROFILE, _tf_trace_sqlite_callback, trace); - } else { + } + else + { sqlite3_trace_v2(sqlite, 0, NULL, NULL); } }