2006-05-17 00:04:09 +00:00
/** \ingroup popt
* \ file popt / poptconfig . c
*/
/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
2001-10-23 14:16:22 +00:00
file accompanying popt source distributions , available from
2006-05-17 00:04:09 +00:00
ftp : //ftp.rpm.org/pub/rpm/dist. */
2001-10-23 14:16:22 +00:00
# include "system.h"
# include "poptint.h"
2006-05-17 00:04:09 +00:00
/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */
static void configLine ( poptContext con , char * line )
/*@modifies con @*/
{
/*@-type@*/
2001-10-23 14:16:22 +00:00
int nameLength = strlen ( con - > appName ) ;
2006-05-17 00:04:09 +00:00
/*@=type@*/
const char * entryType ;
const char * opt ;
2007-07-25 18:47:40 +00:00
poptItem item = ( poptItem ) alloca ( sizeof ( * item ) ) ;
2006-05-17 00:04:09 +00:00
int i , j ;
2001-10-23 14:16:22 +00:00
2006-05-17 00:04:09 +00:00
/*@-boundswrite@*/
memset ( item , 0 , sizeof ( * item ) ) ;
/*@-type@*/
2001-10-23 14:16:22 +00:00
if ( strncmp ( line , con - > appName , nameLength ) ) return ;
2006-05-17 00:04:09 +00:00
/*@=type@*/
2001-10-23 14:16:22 +00:00
line + = nameLength ;
2006-05-17 00:04:09 +00:00
if ( * line = = ' \0 ' | | ! isspace ( * line ) ) return ;
2001-10-23 14:16:22 +00:00
2006-05-17 00:04:09 +00:00
while ( * line ! = ' \0 ' & & isspace ( * line ) ) line + + ;
entryType = line ;
while ( * line = = ' \0 ' | | ! isspace ( * line ) ) line + + ;
2001-10-23 14:16:22 +00:00
* line + + = ' \0 ' ;
2006-05-17 00:04:09 +00:00
while ( * line ! = ' \0 ' & & isspace ( * line ) ) line + + ;
if ( * line = = ' \0 ' ) return ;
opt = line ;
while ( * line = = ' \0 ' | | ! isspace ( * line ) ) line + + ;
2001-10-23 14:16:22 +00:00
* line + + = ' \0 ' ;
2006-05-17 00:04:09 +00:00
while ( * line ! = ' \0 ' & & isspace ( * line ) ) line + + ;
if ( * line = = ' \0 ' ) return ;
/*@-temptrans@*/ /* FIX: line alias is saved */
2001-10-23 14:16:22 +00:00
if ( opt [ 0 ] = = ' - ' & & opt [ 1 ] = = ' - ' )
2006-05-17 00:04:09 +00:00
item - > option . longName = opt + 2 ;
else if ( opt [ 0 ] = = ' - ' & & opt [ 2 ] = = ' \0 ' )
item - > option . shortName = opt [ 1 ] ;
/*@=temptrans@*/
if ( poptParseArgvString ( line , & item - > argc , & item - > argv ) ) return ;
/*@-modobserver@*/
item - > option . argInfo = POPT_ARGFLAG_DOC_HIDDEN ;
for ( i = 0 , j = 0 ; i < item - > argc ; i + + , j + + ) {
const char * f ;
if ( ! strncmp ( item - > argv [ i ] , " --POPTdesc= " , sizeof ( " --POPTdesc= " ) - 1 ) ) {
f = item - > argv [ i ] + sizeof ( " --POPTdesc= " ) ;
if ( f [ 0 ] = = ' $ ' & & f [ 1 ] = = ' " ' ) f + + ;
item - > option . descrip = f ;
item - > option . argInfo & = ~ POPT_ARGFLAG_DOC_HIDDEN ;
j - - ;
} else
if ( ! strncmp ( item - > argv [ i ] , " --POPTargs= " , sizeof ( " --POPTargs= " ) - 1 ) ) {
f = item - > argv [ i ] + sizeof ( " --POPTargs= " ) ;
if ( f [ 0 ] = = ' $ ' & & f [ 1 ] = = ' " ' ) f + + ;
item - > option . argDescrip = f ;
item - > option . argInfo & = ~ POPT_ARGFLAG_DOC_HIDDEN ;
item - > option . argInfo | = POPT_ARG_STRING ;
j - - ;
} else
if ( j ! = i )
item - > argv [ j ] = item - > argv [ i ] ;
}
if ( j ! = i ) {
item - > argv [ j ] = NULL ;
item - > argc = j ;
2001-10-23 14:16:22 +00:00
}
2006-05-17 00:04:09 +00:00
/*@=modobserver@*/
/*@=boundswrite@*/
/*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
if ( ! strcmp ( entryType , " alias " ) )
( void ) poptAddItem ( con , item , 0 ) ;
else if ( ! strcmp ( entryType , " exec " ) )
( void ) poptAddItem ( con , item , 1 ) ;
/*@=nullstate@*/
2001-10-23 14:16:22 +00:00
}
2006-05-17 00:04:09 +00:00
/*@=compmempass@*/
2001-10-23 14:16:22 +00:00
2006-05-17 00:04:09 +00:00
int poptReadConfigFile ( poptContext con , const char * fn )
{
const char * file , * chptr , * end ;
char * buf ;
/*@dependent@*/ char * dst ;
2001-10-23 14:16:22 +00:00
int fd , rc ;
2006-05-17 00:04:09 +00:00
off_t fileLength ;
2001-10-23 14:16:22 +00:00
fd = open ( fn , O_RDONLY ) ;
2006-05-17 00:04:09 +00:00
if ( fd < 0 )
return ( errno = = ENOENT ? 0 : POPT_ERROR_ERRNO ) ;
2001-10-23 14:16:22 +00:00
fileLength = lseek ( fd , 0 , SEEK_END ) ;
2006-05-17 00:04:09 +00:00
if ( fileLength = = - 1 | | lseek ( fd , 0 , 0 ) = = - 1 ) {
rc = errno ;
( void ) close ( fd ) ;
/*@-mods@*/
errno = rc ;
/*@=mods@*/
return POPT_ERROR_ERRNO ;
}
2001-10-23 14:16:22 +00:00
2007-07-25 18:47:40 +00:00
file = ( const char * ) alloca ( fileLength + 1 ) ;
2006-05-17 00:04:09 +00:00
if ( read ( fd , ( char * ) file , fileLength ) ! = fileLength ) {
2001-10-23 14:16:22 +00:00
rc = errno ;
2006-05-17 00:04:09 +00:00
( void ) close ( fd ) ;
/*@-mods@*/
2001-10-23 14:16:22 +00:00
errno = rc ;
2006-05-17 00:04:09 +00:00
/*@=mods@*/
2001-10-23 14:16:22 +00:00
return POPT_ERROR_ERRNO ;
}
2006-05-17 00:04:09 +00:00
if ( close ( fd ) = = - 1 )
return POPT_ERROR_ERRNO ;
2001-10-23 14:16:22 +00:00
2006-05-17 00:04:09 +00:00
/*@-boundswrite@*/
2007-07-25 18:47:40 +00:00
dst = buf = ( char * ) alloca ( fileLength + 1 ) ;
2001-10-23 14:16:22 +00:00
chptr = file ;
end = ( file + fileLength ) ;
2006-05-17 00:04:09 +00:00
/*@-infloops@*/ /* LCL: can't detect chptr++ */
2001-10-23 14:16:22 +00:00
while ( chptr < end ) {
switch ( * chptr ) {
case ' \n ' :
* dst = ' \0 ' ;
dst = buf ;
while ( * dst & & isspace ( * dst ) ) dst + + ;
2006-05-17 00:04:09 +00:00
if ( * dst & & * dst ! = ' # ' )
2001-10-23 14:16:22 +00:00
configLine ( con , dst ) ;
chptr + + ;
2006-05-17 00:04:09 +00:00
/*@switchbreak@*/ break ;
2001-10-23 14:16:22 +00:00
case ' \\ ' :
* dst + + = * chptr + + ;
if ( chptr < end ) {
if ( * chptr = = ' \n ' )
dst - - , chptr + + ;
/* \ at the end of a line does not insert a \n */
else
* dst + + = * chptr + + ;
}
2006-05-17 00:04:09 +00:00
/*@switchbreak@*/ break ;
2001-10-23 14:16:22 +00:00
default :
* dst + + = * chptr + + ;
2006-05-17 00:04:09 +00:00
/*@switchbreak@*/ break ;
2001-10-23 14:16:22 +00:00
}
}
2006-05-17 00:04:09 +00:00
/*@=infloops@*/
/*@=boundswrite@*/
2001-10-23 14:16:22 +00:00
return 0 ;
}
2006-05-17 00:04:09 +00:00
int poptReadDefaultConfig ( poptContext con , /*@unused@*/ int useEnv )
{
2001-10-23 14:16:22 +00:00
char * fn , * home ;
int rc ;
2006-05-17 00:04:09 +00:00
/*@-type@*/
2001-10-23 14:16:22 +00:00
if ( ! con - > appName ) return 0 ;
2006-05-17 00:04:09 +00:00
/*@=type@*/
2001-10-23 14:16:22 +00:00
rc = poptReadConfigFile ( con , " /etc/popt " ) ;
if ( rc ) return rc ;
2006-05-17 00:04:09 +00:00
# if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
2001-10-23 14:16:22 +00:00
if ( getuid ( ) ! = geteuid ( ) ) return 0 ;
2006-05-17 00:04:09 +00:00
# endif
2001-10-23 14:16:22 +00:00
if ( ( home = getenv ( " HOME " ) ) ) {
2007-07-25 18:47:40 +00:00
fn = ( char * ) alloca ( strlen ( home ) + 20 ) ;
2001-10-23 14:16:22 +00:00
strcpy ( fn , home ) ;
strcat ( fn , " /.popt " ) ;
rc = poptReadConfigFile ( con , fn ) ;
if ( rc ) return rc ;
}
return 0 ;
}