You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
2.7 KiB
C
139 lines
2.7 KiB
C
#include "peer.h"
|
|
|
|
#include "json/json.h"
|
|
#include "json/layout.h"
|
|
#include "ffdb/trie.h"
|
|
#include "ffdb/fs_list.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <sys/stat.h>
|
|
|
|
#define PEERS_BY_DOMAIN "data/peers/by_domain"
|
|
|
|
#define OBJ_TYPE struct peer
|
|
static struct json_object_field peer_layout[] = {
|
|
JSON_FIELD_STRING( domain, true ),
|
|
JSON_FIELD_STRING( tor_hidden_service, false ),
|
|
|
|
JSON_FIELD_DATETIME( last_successful_delivery, false ),
|
|
JSON_FIELD_DATETIME( last_failed_delivery, false ),
|
|
JSON_FIELD_DATETIME( last_hidden_service_delivery, false ),
|
|
JSON_FIELD_DATETIME( last_tor_delivery, false ),
|
|
|
|
JSON_FIELD_BOOL( admin_disable_outbox, false ),
|
|
JSON_FIELD_BOOL( admin_disable_tor, false ),
|
|
|
|
JSON_FIELD_END,
|
|
};
|
|
#undef OBJ_TYPE
|
|
|
|
void peer_model_init()
|
|
{
|
|
mkdir( "data", 0755 );
|
|
mkdir( "data/peers", 0755 );
|
|
}
|
|
|
|
struct peer* peer_new()
|
|
{
|
|
struct peer* p;
|
|
p = malloc(sizeof(*p));
|
|
memset(p,0,sizeof(*p));
|
|
return p;
|
|
}
|
|
struct peer* peer_from_id( int id )
|
|
{
|
|
if( id == 0 ) { return NULL; }
|
|
|
|
struct peer* p = peer_new();
|
|
char filename[512];
|
|
snprintf( filename,sizeof(filename), "data/peers/%d.json", id );
|
|
|
|
if( !json_read_object_layout_from_file( filename, peer_layout, p ) ) {
|
|
peer_free(p);
|
|
return NULL;
|
|
}
|
|
|
|
p->id = id;
|
|
|
|
return p;
|
|
}
|
|
struct peer* peer_from_domain( const char* domain )
|
|
{
|
|
struct peer* res = NULL;
|
|
|
|
for( const char* p = domain; *p; ++p ) {
|
|
if( !isprint(*p) ) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
char* id_str = ffdb_trie_get( PEERS_BY_DOMAIN, domain );
|
|
if( !id_str ) { return NULL; }
|
|
|
|
int id = 0;
|
|
if( sscanf( id_str, "%d", &id ) ) {
|
|
res = peer_from_id(id);
|
|
}
|
|
|
|
free(id_str);
|
|
|
|
// Make sure the index is still valid
|
|
if( 0 == strcmp(res->domain,domain) ) {
|
|
return res;
|
|
}
|
|
if( 0 == strcmp(res->tor_hidden_service,domain) ) {
|
|
return res;
|
|
}
|
|
|
|
// Nope. Index entry is invalid, clear
|
|
ffdb_trie_set( PEERS_BY_DOMAIN, domain, NULL );
|
|
|
|
peer_free(res);
|
|
return NULL;
|
|
}
|
|
void peer_save( struct peer* p )
|
|
{
|
|
char filename[512];
|
|
|
|
if( !p->id ) {
|
|
p->id = fs_list_inc( "data/peers/HEAD" );
|
|
}
|
|
|
|
snprintf( filename,sizeof(filename), "data/peers/%d.json", p->id );
|
|
json_write_object_layout_to_file( filename, "\t", peer_layout, p );
|
|
|
|
char id_str[32];
|
|
snprintf( id_str,sizeof(id_str), "%d", p->id );
|
|
|
|
if( p->domain ) {
|
|
ffdb_trie_set( PEERS_BY_DOMAIN, p->domain, id_str );
|
|
}
|
|
if( p->tor_hidden_service ) {
|
|
ffdb_trie_set( PEERS_BY_DOMAIN, p->tor_hidden_service, id_str );
|
|
}
|
|
}
|
|
struct peer* peer_create_from_domain( const char* domain )
|
|
{
|
|
struct peer* p = peer_from_domain(domain);
|
|
if( p ) { return p; }
|
|
|
|
p = peer_new();
|
|
p->domain = strdup(domain);
|
|
peer_save(p);
|
|
|
|
return p;
|
|
}
|
|
void peer_free( struct peer* p )
|
|
{
|
|
if( !p ) { return; }
|
|
|
|
free( p->domain );
|
|
free( p->tor_hidden_service );
|
|
|
|
free(p);
|
|
}
|
|
|
|
|