|
|
|
|
@ -85,6 +85,38 @@ static int profile_copy_pair(const char* key, const char* value, void* arg) {
|
|
|
|
|
return profile_pair(p, key, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int chat_core_name_userinfo(const char* name, char* out, size_t capacity) { |
|
|
|
|
struct profile_json p = { .text = "{", .used = 1 }; |
|
|
|
|
if (!name || !out || profile_pair(&p, "name", name) < 0 || p.used + 2 > capacity || p.used >= MS_USERINFO_MAX) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "profile: cannot encode display name capacity=%zu", capacity); return -1; |
|
|
|
|
} |
|
|
|
|
p.text[p.used++] = '}'; p.text[p.used] = 0; memcpy(out, p.text, p.used + 1); return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int chat_core_get_my_profile(struct UTUN_INSTANCE* inst, const char* channel, char* out, size_t capacity, |
|
|
|
|
uint8_t signature[64], uint64_t* timestamp) { |
|
|
|
|
struct chat_core_ctx* cc = CC(inst); |
|
|
|
|
if (!cc || !cc->db || !channel || !out || !signature || !timestamp) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "profile: invalid read request"); return -1; |
|
|
|
|
} |
|
|
|
|
char table[80], sql[256]; peers_table_name(channel, table, sizeof(table)); |
|
|
|
|
snprintf(sql, sizeof(sql), "SELECT userinfo,update_sig,update_ts FROM \"%s\" WHERE node_id=?", table); |
|
|
|
|
sqlite3_stmt* st = NULL; int result = -1; |
|
|
|
|
if (sqlite3_prepare_v2(cc->db, sql, -1, &st, NULL) == SQLITE_OK) { |
|
|
|
|
sqlite3_bind_int64(st, 1, (sqlite3_int64)cc->my_node_id); |
|
|
|
|
if (sqlite3_step(st) == SQLITE_ROW) { |
|
|
|
|
const char* json = (const char*)sqlite3_column_text(st, 0); size_t size = json ? strlen(json) : 0; |
|
|
|
|
if (json && size <= MS_USERINFO_MAX && size < capacity && sqlite3_column_bytes(st, 1) == 64 && sqlite3_column_int64(st, 2) > 0) { |
|
|
|
|
memcpy(out, json, size + 1); memcpy(signature, sqlite3_column_blob(st, 1), 64); |
|
|
|
|
*timestamp = (uint64_t)sqlite3_column_int64(st, 2); result = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
sqlite3_finalize(st); |
|
|
|
|
} |
|
|
|
|
if (result) DEBUG_WARN(DEBUG_CATEGORY_CHAT, "profile: signed local profile unavailable channel=%s capacity=%zu", channel, capacity); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int profile_update_channel(struct UTUN_INSTANCE* inst, const char* ch, int avatar, uint64_t server, const char* file) { |
|
|
|
|
struct chat_core_ctx* cc = CC(inst); |
|
|
|
|
if (!cc || !cc->initialized || !cc->db) { |
|
|
|
|
|