2014-08-12 18:58:56 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd .
Copyright 2014 Kay Sievers , Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
( at your option ) any later version .
systemd is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public License
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include "timesyncd-server.h"
2014-08-12 21:48:24 +04:00
int server_address_new (
ServerName * n ,
ServerAddress * * ret ,
const union sockaddr_union * sockaddr ,
socklen_t socklen ) {
ServerAddress * a , * tail ;
assert ( n ) ;
assert ( sockaddr ) ;
assert ( socklen > = offsetof ( struct sockaddr , sa_data ) ) ;
assert ( socklen < = sizeof ( union sockaddr_union ) ) ;
a = new0 ( ServerAddress , 1 ) ;
if ( ! a )
return - ENOMEM ;
memcpy ( & a - > sockaddr , sockaddr , socklen ) ;
a - > socklen = socklen ;
LIST_FIND_TAIL ( addresses , n - > addresses , tail ) ;
LIST_INSERT_AFTER ( addresses , n - > addresses , tail , a ) ;
a - > name = n ;
if ( ret )
* ret = a ;
return 0 ;
}
ServerAddress * server_address_free ( ServerAddress * a ) {
if ( ! a )
return NULL ;
if ( a - > name ) {
LIST_REMOVE ( addresses , a - > name - > addresses , a ) ;
if ( a - > name - > manager & & a - > name - > manager - > current_server_address = = a )
manager_set_server_address ( a - > name - > manager , NULL ) ;
}
free ( a ) ;
return NULL ;
}
int server_name_new (
Manager * m ,
ServerName * * ret ,
ServerType type ,
const char * string ) {
ServerName * n , * tail ;
assert ( m ) ;
assert ( string ) ;
n = new0 ( ServerName , 1 ) ;
if ( ! n )
return - ENOMEM ;
n - > type = type ;
n - > string = strdup ( string ) ;
if ( ! n - > string ) {
free ( n ) ;
return - ENOMEM ;
}
if ( type = = SERVER_SYSTEM ) {
LIST_FIND_TAIL ( names , m - > system_servers , tail ) ;
LIST_INSERT_AFTER ( names , m - > system_servers , tail , n ) ;
} else if ( type = = SERVER_LINK ) {
LIST_FIND_TAIL ( names , m - > link_servers , tail ) ;
LIST_INSERT_AFTER ( names , m - > link_servers , tail , n ) ;
} else if ( type = = SERVER_FALLBACK ) {
LIST_FIND_TAIL ( names , m - > fallback_servers , tail ) ;
LIST_INSERT_AFTER ( names , m - > fallback_servers , tail , n ) ;
} else
assert_not_reached ( " Unknown server type " ) ;
n - > manager = m ;
if ( type ! = SERVER_FALLBACK & &
m - > current_server_name & &
m - > current_server_name - > type = = SERVER_FALLBACK )
manager_set_server_name ( m , NULL ) ;
log_debug ( " Added new server %s. " , string ) ;
if ( ret )
* ret = n ;
return 0 ;
}
ServerName * server_name_free ( ServerName * n ) {
if ( ! n )
return NULL ;
server_name_flush_addresses ( n ) ;
if ( n - > manager ) {
if ( n - > type = = SERVER_SYSTEM )
LIST_REMOVE ( names , n - > manager - > system_servers , n ) ;
else if ( n - > type = = SERVER_LINK )
LIST_REMOVE ( names , n - > manager - > link_servers , n ) ;
else if ( n - > type = = SERVER_FALLBACK )
LIST_REMOVE ( names , n - > manager - > fallback_servers , n ) ;
else
assert_not_reached ( " Unknown server type " ) ;
if ( n - > manager - > current_server_name = = n )
manager_set_server_name ( n - > manager , NULL ) ;
}
log_debug ( " Removed server %s. " , n - > string ) ;
free ( n - > string ) ;
free ( n ) ;
return NULL ;
}
void server_name_flush_addresses ( ServerName * n ) {
assert ( n ) ;
while ( n - > addresses )
server_address_free ( n - > addresses ) ;
}