forked from cory/tildefriends
		
	ssb: Add a command-line action to generate an invite, and verified that Patchwork can accept it.
This commit is contained in:
		
							
								
								
									
										90
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								src/main.c
									
									
									
									
									
								
							@@ -149,6 +149,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[]);
 | 
				
			|||||||
static int _tf_command_sandbox(const char* file, int argc, char* argv[]);
 | 
					static int _tf_command_sandbox(const char* file, int argc, char* argv[]);
 | 
				
			||||||
static int _tf_command_has_blob(const char* file, int argc, char* argv[]);
 | 
					static int _tf_command_has_blob(const char* file, int argc, char* argv[]);
 | 
				
			||||||
static int _tf_command_store_blob(const char* file, int argc, char* argv[]);
 | 
					static int _tf_command_store_blob(const char* file, int argc, char* argv[]);
 | 
				
			||||||
 | 
					static int _tf_command_create_invite(const char* file, int argc, char* argv[]);
 | 
				
			||||||
static int _tf_command_get_sequence(const char* file, int argc, char* argv[]);
 | 
					static int _tf_command_get_sequence(const char* file, int argc, char* argv[]);
 | 
				
			||||||
static int _tf_command_get_identity(const char* file, int argc, char* argv[]);
 | 
					static int _tf_command_get_identity(const char* file, int argc, char* argv[]);
 | 
				
			||||||
static int _tf_command_get_profile(const char* file, int argc, char* argv[]);
 | 
					static int _tf_command_get_profile(const char* file, int argc, char* argv[]);
 | 
				
			||||||
@@ -171,6 +172,7 @@ const command_t k_commands[] = {
 | 
				
			|||||||
	{ "export", _tf_command_export, "Export apps from SSB." },
 | 
						{ "export", _tf_command_export, "Export apps from SSB." },
 | 
				
			||||||
	{ "publish", _tf_command_publish, "Append a message to a feed." },
 | 
						{ "publish", _tf_command_publish, "Append a message to a feed." },
 | 
				
			||||||
	{ "private", _tf_command_private, "Append a private post message to a feed." },
 | 
						{ "private", _tf_command_private, "Append a private post message to a feed." },
 | 
				
			||||||
 | 
						{ "create_invite", _tf_command_create_invite, "Create an invite." },
 | 
				
			||||||
	{ "get_sequence", _tf_command_get_sequence, "Get the last sequence number for a feed." },
 | 
						{ "get_sequence", _tf_command_get_sequence, "Get the last sequence number for a feed." },
 | 
				
			||||||
	{ "get_identity", _tf_command_get_identity, "Get the server account identity." },
 | 
						{ "get_identity", _tf_command_get_identity, "Get the server account identity." },
 | 
				
			||||||
	{ "get_profile", _tf_command_get_profile, "Get profile information for the given identity." },
 | 
						{ "get_profile", _tf_command_get_profile, "Get profile information for the given identity." },
 | 
				
			||||||
@@ -801,6 +803,94 @@ static int _tf_command_has_blob(const char* file, int argc, char* argv[])
 | 
				
			|||||||
	return has ? EXIT_SUCCESS : EXIT_FAILURE;
 | 
						return has ? EXIT_SUCCESS : EXIT_FAILURE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int _tf_command_create_invite(const char* file, int argc, char* argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char* default_db_path = _get_db_path();
 | 
				
			||||||
 | 
						const char* db_path = default_db_path;
 | 
				
			||||||
 | 
						const char* identity = NULL;
 | 
				
			||||||
 | 
						int use_count = 0;
 | 
				
			||||||
 | 
						int expires = 0;
 | 
				
			||||||
 | 
						bool show_usage = false;
 | 
				
			||||||
 | 
						const char* host = NULL;
 | 
				
			||||||
 | 
						int port = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (!show_usage)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							static const struct option k_options[] = {
 | 
				
			||||||
 | 
								{ "db-path", required_argument, NULL, 'd' },
 | 
				
			||||||
 | 
								{ "identity", required_argument, NULL, 'i' },
 | 
				
			||||||
 | 
								{ "address", required_argument, NULL, 'a' },
 | 
				
			||||||
 | 
								{ "port", required_argument, NULL, 'p' },
 | 
				
			||||||
 | 
								{ "use_count", required_argument, NULL, 'u' },
 | 
				
			||||||
 | 
								{ "expires", required_argument, NULL, 'e' },
 | 
				
			||||||
 | 
								{ "help", no_argument, NULL, 'h' },
 | 
				
			||||||
 | 
								{ 0 },
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							int c = getopt_long(argc, argv, "d:i:a:p:u:e:h", k_options, NULL);
 | 
				
			||||||
 | 
							if (c == -1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (c)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							case '?':
 | 
				
			||||||
 | 
							case 'h':
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								show_usage = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'd':
 | 
				
			||||||
 | 
								db_path = optarg;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'i':
 | 
				
			||||||
 | 
								identity = optarg;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'a':
 | 
				
			||||||
 | 
								host = optarg;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'p':
 | 
				
			||||||
 | 
								port = atoi(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'u':
 | 
				
			||||||
 | 
								use_count = atoi(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'e':
 | 
				
			||||||
 | 
								expires = atoi(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (show_usage || !identity || !use_count || !expires || !host || !port)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							tf_printf("\n%s get_sequence [options]\n\n", file);
 | 
				
			||||||
 | 
							tf_printf("options:\n");
 | 
				
			||||||
 | 
							tf_printf("  -d, --db-path db_path    SQLite database path (default: %s).\n", default_db_path);
 | 
				
			||||||
 | 
							tf_printf("  -i, --identity identity  Account from which to get latest sequence number.\n");
 | 
				
			||||||
 | 
							tf_printf("  -a, --address address    Address to which the recipient will connect.\n");
 | 
				
			||||||
 | 
							tf_printf("  -p, --port port          Port to which the recipient will connect.\n");
 | 
				
			||||||
 | 
							tf_printf("  -u, --use_count count    Number of times this invite may be used.\n");
 | 
				
			||||||
 | 
							tf_printf("  -e, --expires seconds    How long this invite is valid in seconds (-1 for indefinitely).\n");
 | 
				
			||||||
 | 
							tf_printf("  -h, --help               Show this usage information.\n");
 | 
				
			||||||
 | 
							tf_free((void*)default_db_path);
 | 
				
			||||||
 | 
							return EXIT_FAILURE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int result = EXIT_FAILURE;
 | 
				
			||||||
 | 
						tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
 | 
				
			||||||
 | 
						tf_ssb_set_quiet(ssb, true);
 | 
				
			||||||
 | 
						char invite[1024] = "";
 | 
				
			||||||
 | 
						sqlite3* db = tf_ssb_acquire_db_writer(ssb);
 | 
				
			||||||
 | 
						if (tf_ssb_db_generate_invite(db, identity, host, port, use_count, expires, invite, sizeof(invite)))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							tf_printf("%s\n", invite);
 | 
				
			||||||
 | 
							result = EXIT_SUCCESS;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tf_ssb_release_db_writer(ssb, db);
 | 
				
			||||||
 | 
						tf_ssb_destroy(ssb);
 | 
				
			||||||
 | 
						tf_free((void*)default_db_path);
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int _tf_command_get_sequence(const char* file, int argc, char* argv[])
 | 
					static int _tf_command_get_sequence(const char* file, int argc, char* argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char* default_db_path = _get_db_path();
 | 
						const char* default_db_path = _get_db_path();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								src/ssb.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/ssb.c
									
									
									
									
									
								
							@@ -2612,18 +2612,13 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
 | 
				
			|||||||
	while (ssb->broadcast_listener.data || ssb->broadcast_sender.data || ssb->broadcast_timer.data || ssb->broadcast_cleanup_timer.data || ssb->trace_timer.data ||
 | 
						while (ssb->broadcast_listener.data || ssb->broadcast_sender.data || ssb->broadcast_timer.data || ssb->broadcast_cleanup_timer.data || ssb->trace_timer.data ||
 | 
				
			||||||
		ssb->server.data || ssb->ref_count || ssb->request_activity_timer.data || ssb->timers_count)
 | 
							ssb->server.data || ssb->ref_count || ssb->request_activity_timer.data || ssb->timers_count)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		tf_printf("bl=%p bs=%p bt=%p bc=%p tt=%p s=%p rc=%d rat=%p tc=%d\n",
 | 
							if (!ssb->quiet)
 | 
				
			||||||
			ssb->broadcast_listener.data,
 | 
							{
 | 
				
			||||||
			ssb->broadcast_sender.data,
 | 
								tf_printf("bl=%p bs=%p bt=%p bc=%p tt=%p s=%p rc=%d rat=%p tc=%d\n", ssb->broadcast_listener.data, ssb->broadcast_sender.data, ssb->broadcast_timer.data,
 | 
				
			||||||
			ssb->broadcast_timer.data,
 | 
									ssb->broadcast_cleanup_timer.data, ssb->trace_timer.data, ssb->server.data, ssb->ref_count, ssb->request_activity_timer.data, ssb->timers_count);
 | 
				
			||||||
			ssb->broadcast_cleanup_timer.data,
 | 
					 | 
				
			||||||
			ssb->trace_timer.data,
 | 
					 | 
				
			||||||
			ssb->server.data,
 | 
					 | 
				
			||||||
			ssb->ref_count,
 | 
					 | 
				
			||||||
			ssb->request_activity_timer.data,
 | 
					 | 
				
			||||||
			ssb->timers_count);
 | 
					 | 
				
			||||||
			tf_printf("--\n");
 | 
								tf_printf("--\n");
 | 
				
			||||||
			uv_print_all_handles(ssb->loop, stdout);
 | 
								uv_print_all_handles(ssb->loop, stdout);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		uv_run(ssb->loop, UV_RUN_ONCE);
 | 
							uv_run(ssb->loop, UV_RUN_ONCE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -3080,7 +3075,8 @@ void tf_ssb_connect(tf_ssb_t* ssb, const char* host, int port, const uint8_t* ke
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void _tf_ssb_connect_with_invite(tf_ssb_t* ssb, const char* host, int port, const uint8_t* key, const uint8_t* invite, int connect_flags, tf_ssb_connect_callback_t* callback, void* user_data)
 | 
					static void _tf_ssb_connect_with_invite(
 | 
				
			||||||
 | 
						tf_ssb_t* ssb, const char* host, int port, const uint8_t* key, const uint8_t* invite, int connect_flags, tf_ssb_connect_callback_t* callback, void* user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (ssb->shutting_down)
 | 
						if (ssb->shutting_down)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -3388,8 +3384,7 @@ static bool _tf_ssb_parse_connect_string(const char* in_broadcast, tf_ssb_broadc
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		out_broadcast->addr.sin_family = AF_INET;
 | 
							out_broadcast->addr.sin_family = AF_INET;
 | 
				
			||||||
		out_broadcast->addr.sin_port = htons((uint16_t)port);
 | 
							out_broadcast->addr.sin_port = htons((uint16_t)port);
 | 
				
			||||||
		return
 | 
							return tf_ssb_id_str_to_bin(out_broadcast->pub, public_key_str) &&
 | 
				
			||||||
			tf_ssb_id_str_to_bin(out_broadcast->pub, public_key_str) &&
 | 
					 | 
				
			||||||
			tf_base64_decode(secret_key_str, strlen(secret_key_str), out_broadcast->invite, sizeof(out_broadcast->invite));
 | 
								tf_base64_decode(secret_key_str, strlen(secret_key_str), out_broadcast->invite, sizeof(out_broadcast->invite));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (strncmp(in_broadcast, "ws:", 3) == 0)
 | 
						else if (strncmp(in_broadcast, "ws:", 3) == 0)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								src/ssb.db.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/ssb.db.c
									
									
									
									
									
								
							@@ -2170,14 +2170,10 @@ bool tf_ssb_db_generate_invite(sqlite3* db, const char* id, const char* host, in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	bool inserted = false;
 | 
						bool inserted = false;
 | 
				
			||||||
	sqlite3_stmt* statement;
 | 
						sqlite3_stmt* statement;
 | 
				
			||||||
	if (sqlite3_prepare(db,
 | 
						if (sqlite3_prepare(db, "INSERT INTO invites (invite_public_key, account, use_count, expires) VALUES (?, ?, ?, ?)", -1, &statement, NULL) == SQLITE_OK)
 | 
				
			||||||
		"INSERT INTO invites (invite_public_key, account, use_count, expires) VALUES (?, ?, ?, ?)",
 | 
					 | 
				
			||||||
		-1, &statement, NULL) == SQLITE_OK)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (sqlite3_bind_text(statement, 1, public, -1, NULL) == SQLITE_OK &&
 | 
							if (sqlite3_bind_text(statement, 1, public, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, id, -1, NULL) == SQLITE_OK &&
 | 
				
			||||||
			sqlite3_bind_text(statement, 2, id, -1, NULL) == SQLITE_OK &&
 | 
								sqlite3_bind_int(statement, 3, use_count) == SQLITE_OK && sqlite3_bind_int64(statement, 4, (int64_t)time(NULL) + expires_seconds) == SQLITE_OK)
 | 
				
			||||||
			sqlite3_bind_int(statement, 3, use_count) == SQLITE_OK &&
 | 
					 | 
				
			||||||
			sqlite3_bind_int64(statement, 4, (int64_t)time(NULL) + expires_seconds) == SQLITE_OK)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			inserted = sqlite3_step(statement) == SQLITE_DONE;
 | 
								inserted = sqlite3_step(statement) == SQLITE_DONE;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -2192,15 +2188,12 @@ bool tf_ssb_db_use_invite(sqlite3* db, const char* id)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	bool used = false;
 | 
						bool used = false;
 | 
				
			||||||
	sqlite3_stmt* statement;
 | 
						sqlite3_stmt* statement;
 | 
				
			||||||
	if (sqlite3_prepare(db,
 | 
						if (sqlite3_prepare(db, "UPDATE invites SET use_count = use_count - 1 WHERE invite_public_key = ? AND expires > ? AND (use_count > 0 OR use_count = -1)", -1, &statement,
 | 
				
			||||||
		"UPDATE invites SET use_count = use_count - 1 WHERE invite_public_key = ? AND expires > ? AND (use_count > 0 OR use_count = -1)",
 | 
								NULL) == SQLITE_OK)
 | 
				
			||||||
		-1, &statement, NULL) == SQLITE_OK)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK &&
 | 
							if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && sqlite3_bind_int64(statement, 2, (int64_t)time(NULL)) == SQLITE_OK)
 | 
				
			||||||
			sqlite3_bind_int64(statement, 2, (int64_t)time(NULL)) == SQLITE_OK)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			used = sqlite3_step(statement) == SQLITE_DONE &&
 | 
								used = sqlite3_step(statement) == SQLITE_DONE && sqlite3_changes(db) > 0;
 | 
				
			||||||
				sqlite3_changes(db) > 0;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		sqlite3_finalize(statement);
 | 
							sqlite3_finalize(statement);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1202,6 +1202,18 @@ static void _tf_ssb_rpc_ebt_replicate_server(
 | 
				
			|||||||
	tf_ssb_connection_add_request(connection, -request_number, "ebt.replicate", _tf_ssb_rpc_ebt_replicate, NULL, NULL, NULL);
 | 
						tf_ssb_connection_add_request(connection, -request_number, "ebt.replicate", _tf_ssb_rpc_ebt_replicate, NULL, NULL, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void _tf_ssb_rpc_invite_use_callback(
 | 
				
			||||||
 | 
						tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						** Follow the pub back:
 | 
				
			||||||
 | 
						** { "type": "contact", "contact": "@VJM7w1W19ZsKmG2KnfaoKIM66BRoreEkzaVm/J//wl8=.ed25519", "following": true }
 | 
				
			||||||
 | 
						**
 | 
				
			||||||
 | 
						** Post a pub message:
 | 
				
			||||||
 | 
						** { "type": "pub", "address": { "host": "one.butt.nz", "port": 8008, "key": "@VJM7w1W19ZsKmG2KnfaoKIM66BRoreEkzaVm/J//wl8=.ed25519" } }
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void _tf_ssb_rpc_send_invite_use(tf_ssb_connection_t* connection)
 | 
					static void _tf_ssb_rpc_send_invite_use(tf_ssb_connection_t* connection)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection);
 | 
						tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection);
 | 
				
			||||||
@@ -1219,8 +1231,8 @@ static void _tf_ssb_rpc_send_invite_use(tf_ssb_connection_t* connection)
 | 
				
			|||||||
	JS_SetPropertyStr(context, object, "feed", JS_NewString(context, id));
 | 
						JS_SetPropertyStr(context, object, "feed", JS_NewString(context, id));
 | 
				
			||||||
	JS_SetPropertyUint32(context, args, 0, object);
 | 
						JS_SetPropertyUint32(context, args, 0, object);
 | 
				
			||||||
	JS_SetPropertyStr(context, message, "args", args);
 | 
						JS_SetPropertyStr(context, message, "args", args);
 | 
				
			||||||
	tf_ssb_connection_rpc_send_json(connection, k_ssb_rpc_flag_new_request, tf_ssb_connection_next_request_number(connection), "invite.use", message,
 | 
						tf_ssb_connection_rpc_send_json(
 | 
				
			||||||
		_tf_ssb_rpc_connection_tunnel_isRoom_callback, NULL, NULL);
 | 
							connection, k_ssb_rpc_flag_new_request, tf_ssb_connection_next_request_number(connection), "invite.use", message, _tf_ssb_rpc_invite_use_callback, NULL, NULL);
 | 
				
			||||||
	JS_FreeValue(context, message);
 | 
						JS_FreeValue(context, message);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1679,13 +1691,13 @@ static void _tf_ssb_invite_use_message_store_callback(const char* id, bool verif
 | 
				
			|||||||
	tf_ssb_connection_t* connection = work->connection;
 | 
						tf_ssb_connection_t* connection = work->connection;
 | 
				
			||||||
	if (verified && is_new)
 | 
						if (verified && is_new)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		tf_ssb_connection_rpc_send(connection, k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error, -work->request_number, NULL,
 | 
							tf_ssb_connection_rpc_send(
 | 
				
			||||||
			(const uint8_t*)work->message, strlen(work->message), NULL, NULL, NULL);
 | 
								connection, k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error, -work->request_number, NULL, (const uint8_t*)work->message, strlen(work->message), NULL, NULL, NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		tf_ssb_connection_rpc_send(connection, k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error, -work->request_number, NULL,
 | 
							tf_ssb_connection_rpc_send(
 | 
				
			||||||
			(const uint8_t*)"false", strlen("false"), NULL, NULL, NULL);
 | 
								connection, k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error, -work->request_number, NULL, (const uint8_t*)"false", strlen("false"), NULL, NULL, NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (work->message)
 | 
						if (work->message)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -1722,16 +1734,15 @@ static void _tf_ssb_rpc_invite_use_after_work(tf_ssb_connection_t* connection, i
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		tf_ssb_connection_rpc_send(connection, k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error, -work->request_number, NULL,
 | 
							tf_ssb_connection_rpc_send(
 | 
				
			||||||
			(const uint8_t*)"false", strlen("false"), NULL, NULL, NULL);
 | 
								connection, k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error, -work->request_number, NULL, (const uint8_t*)"false", strlen("false"), NULL, NULL, NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void _tf_ssb_rpc_invite_use(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
 | 
					static void _tf_ssb_rpc_invite_use(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	invite_t* work = tf_malloc(sizeof(invite_t));
 | 
						invite_t* work = tf_malloc(sizeof(invite_t));
 | 
				
			||||||
	*work = (invite_t)
 | 
						*work = (invite_t) {
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		.connection = connection,
 | 
							.connection = connection,
 | 
				
			||||||
		.request_number = request_number,
 | 
							.request_number = request_number,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user