2009-11-20 01:13:20 +03:00
/*-*- Mode: C; c-basic-offset: 8 -*-*/
# include <assert.h>
# include <errno.h>
# include <string.h>
# include "name.h"
# include "strv.h"
# include "conf-parser.h"
# include "load-fragment.h"
2010-01-20 21:19:53 +03:00
# include "log.h"
2009-11-20 01:13:20 +03:00
2010-01-19 04:56:37 +03:00
static int config_parse_deps (
2009-11-20 01:13:20 +03:00
const char * filename ,
unsigned line ,
const char * section ,
const char * lvalue ,
const char * rvalue ,
void * data ,
void * userdata ) {
Set * * set = data ;
Name * name = userdata ;
char * w ;
size_t l ;
char * state ;
assert ( filename ) ;
assert ( lvalue ) ;
assert ( rvalue ) ;
assert ( data ) ;
FOREACH_WORD ( w , & l , rvalue , state ) {
char * t ;
int r ;
Name * other ;
if ( ! ( t = strndup ( w , l ) ) )
return - ENOMEM ;
r = manager_load_name ( name - > meta . manager , t , & other ) ;
free ( t ) ;
if ( r < 0 )
return r ;
if ( ! * set )
if ( ! ( * set = set_new ( trivial_hash_func , trivial_compare_func ) ) )
return - ENOMEM ;
if ( ( r = set_put ( * set , other ) ) < 0 )
return r ;
}
return 0 ;
}
2010-01-19 04:56:37 +03:00
static int config_parse_names (
2010-01-19 01:50:13 +03:00
const char * filename ,
unsigned line ,
const char * section ,
const char * lvalue ,
const char * rvalue ,
void * data ,
void * userdata ) {
Set * * set = data ;
Name * name = userdata ;
char * w ;
size_t l ;
char * state ;
assert ( filename ) ;
assert ( lvalue ) ;
assert ( rvalue ) ;
assert ( data ) ;
FOREACH_WORD ( w , & l , rvalue , state ) {
char * t ;
int r ;
Name * other ;
if ( ! ( t = strndup ( w , l ) ) )
return - ENOMEM ;
other = manager_get_name ( name - > meta . manager , t ) ;
if ( other ) {
if ( other ! = name ) {
if ( other - > meta . state ! = NAME_STUB ) {
free ( t ) ;
return - EEXIST ;
}
2010-01-20 07:03:52 +03:00
if ( ( r = name_merge ( name , other ) ) < 0 ) {
2010-01-19 01:50:13 +03:00
free ( t ) ;
return r ;
}
}
} else {
if ( ! * set )
if ( ! ( * set = set_new ( trivial_hash_func , trivial_compare_func ) ) ) {
free ( t ) ;
return - ENOMEM ;
}
if ( ( r = set_put ( * set , t ) ) < 0 ) {
free ( t ) ;
return r ;
}
2010-01-19 06:15:20 +03:00
t = NULL ;
2010-01-19 01:50:13 +03:00
}
free ( t ) ;
}
return 0 ;
}
2010-01-19 04:56:37 +03:00
static int config_parse_listen (
const char * filename ,
unsigned line ,
const char * section ,
const char * lvalue ,
const char * rvalue ,
void * data ,
void * userdata ) {
2010-01-20 21:19:53 +03:00
int r ;
2010-01-19 04:56:37 +03:00
assert ( filename ) ;
assert ( lvalue ) ;
assert ( rvalue ) ;
assert ( data ) ;
2010-01-20 21:19:53 +03:00
if ( ( r = address_parse ( data , rvalue ) ) < 0 ) {
log_error ( " [%s:%u] Failed to parse address value: %s " , filename , line , rvalue ) ;
return r ;
}
return 0 ;
2010-01-19 04:56:37 +03:00
}
static int config_parse_type (
const char * filename ,
unsigned line ,
const char * section ,
const char * lvalue ,
const char * rvalue ,
void * data ,
void * userdata ) {
int * type = data ;
assert ( filename ) ;
assert ( lvalue ) ;
assert ( rvalue ) ;
assert ( data ) ;
if ( streq ( rvalue , " stream " ) )
* type = SOCK_STREAM ;
else if ( streq ( rvalue , " dgram " ) )
* type = SOCK_DGRAM ;
2010-01-20 21:19:53 +03:00
else {
log_error ( " [%s:%u] Failed to parse socket type value: %s " , filename , line , rvalue ) ;
2010-01-19 04:56:37 +03:00
return - EINVAL ;
2010-01-20 21:19:53 +03:00
}
2010-01-19 04:56:37 +03:00
return 0 ;
}
2009-11-20 01:13:20 +03:00
int name_load_fragment ( Name * n ) {
2010-01-19 04:56:37 +03:00
const char * const section_table [ _NAME_TYPE_MAX ] = {
[ NAME_SERVICE ] = " Service " ,
[ NAME_TIMER ] = " Timer " ,
[ NAME_SOCKET ] = " Socket " ,
[ NAME_MILESTONE ] = " Milestone " ,
[ NAME_DEVICE ] = " Device " ,
[ NAME_MOUNT ] = " Mount " ,
[ NAME_AUTOMOUNT ] = " Automount " ,
[ NAME_SNAPSHOT ] = " Snapshot "
} ;
2009-11-20 01:13:20 +03:00
const ConfigItem items [ ] = {
2010-01-19 04:56:37 +03:00
{ " Names " , config_parse_names , & n - > meta . names , " Meta " } ,
{ " Description " , config_parse_string , & n - > meta . description , " Meta " } ,
{ " Requires " , config_parse_deps , n - > meta . dependencies + NAME_REQUIRES , " Meta " } ,
{ " SoftRequires " , config_parse_deps , n - > meta . dependencies + NAME_SOFT_REQUIRES , " Meta " } ,
{ " Wants " , config_parse_deps , n - > meta . dependencies + NAME_WANTS , " Meta " } ,
{ " Requisite " , config_parse_deps , n - > meta . dependencies + NAME_REQUISITE , " Meta " } ,
{ " SoftRequisite " , config_parse_deps , n - > meta . dependencies + NAME_SOFT_REQUISITE , " Meta " } ,
{ " Conflicts " , config_parse_deps , n - > meta . dependencies + NAME_CONFLICTS , " Meta " } ,
{ " Before " , config_parse_deps , n - > meta . dependencies + NAME_BEFORE , " Meta " } ,
{ " After " , config_parse_deps , n - > meta . dependencies + NAME_AFTER , " Meta " } ,
{ " Listen " , config_parse_listen , & n - > socket . address , " Socket " } ,
{ " Type " , config_parse_type , & n - > socket . address . type , " Socket " } ,
2009-11-20 01:13:20 +03:00
{ NULL , NULL , NULL , NULL }
} ;
2010-01-19 04:56:37 +03:00
const
2010-01-19 01:50:13 +03:00
char * t ;
2009-11-20 01:13:20 +03:00
int r ;
2010-01-19 01:50:13 +03:00
void * state ;
2010-01-19 04:56:37 +03:00
const char * sections [ 3 ] ;
2009-11-20 01:13:20 +03:00
assert ( n ) ;
assert ( n - > meta . state = = NAME_STUB ) ;
2010-01-19 04:56:37 +03:00
sections [ 0 ] = " Meta " ;
sections [ 1 ] = section_table [ n - > meta . type ] ;
sections [ 2 ] = NULL ;
2010-01-19 01:50:13 +03:00
SET_FOREACH ( t , n - > meta . names , state )
2010-01-19 04:56:37 +03:00
if ( ( r = config_parse ( t , sections , items , n ) ) < 0 )
2009-11-20 01:13:20 +03:00
goto fail ;
2010-01-19 01:50:13 +03:00
r = 0 ;
2009-11-20 01:13:20 +03:00
fail :
2010-01-19 01:50:13 +03:00
return r ;
2009-11-20 01:13:20 +03:00
}