diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2014-09-18 14:52:51 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2014-09-18 14:52:51 +0200 |
commit | d3bf01e1c5c60113d012537ee52f69515cf5ecb7 (patch) | |
tree | e36cb2d8a7f9dffabc652b8172b4599f86c955b8 /src/system.c | |
parent | f8a83ea88eacf744f9bde5e3f96e29ad627ec2f5 (diff) | |
download | biruda-d3bf01e1c5c60113d012537ee52f69515cf5ecb7.tar.gz biruda-d3bf01e1c5c60113d012537ee52f69515cf5ecb7.tar.bz2 |
first /etc/os-release parser for system
Diffstat (limited to 'src/system.c')
-rw-r--r-- | src/system.c | 80 |
1 files changed, 76 insertions, 4 deletions
diff --git a/src/system.c b/src/system.c index 2751bcf..6e5e054 100644 --- a/src/system.c +++ b/src/system.c @@ -9,6 +9,8 @@ #endif #include <stdio.h> +#include <string.h> +#include <stdlib.h> unsigned int system_available_cpus( void ) { @@ -37,15 +39,85 @@ void system_cpe_name( char *name, size_t len ) /* TODO: test for Windows versions */ snprintf( name, len, "cpe:/o:microsoft:windows:unknown" ); #elif defined( linux ) || defined( __linux ) || defined( __linux__ ) - /* TOPO: /etc/os-release */ - struct utsname uts; - uname( &uts ); - snprintf( name, len, "cpe:/o:archlinux:archlinux:unknown" ); + /* new systemd-way on modern Linux systems */ + FILE *f = fopen( "/etc/os-release", "r" ); + if( f == NULL ) { + f = fopen( "/usr/lib/os-release", "r" ); + if( f == NULL ) { + /* TODO: test for /etc/xxx-release, /etc/xxx-version, + not sure if we should also check and run + lsb_release + */ + snprintf( name, len, "cpe:/o:linux" ); + return; + } + } + + char line[100]; + char *key; + char *os = NULL; + char *version = NULL; + while( !feof( f ) ) { + fgets( line, sizeof( line ), f ); + if( line[0] == '#' ) continue; + char *value = strchr( line, '=' ); + if( value == NULL ) continue; + key = line; + *value++ = '\0'; + char *p = value; + char *q = p; + while( *p != '\0' ) { + if( *p == '\\' ) { + ++p; + if( *p == '\0' ) { + break; + } + *q++ = *p++; + } + if( *p == '\"' || *p == '\'' || *p == '\n' ) { + p++; + } else { + *q++ = *p++; + } + } + *q = '\0'; + + if( strcmp( key, "CPE_NAME" ) == 0 ) { + snprintf( name, len, "%s", value ); + if( os != NULL ) free( os ); + if( version != NULL ) free( version ); + fclose( f ); + return; + } else if( strcmp( key, "NAME" ) == 0 ) { + os = strdup( value ); + } else if( strcmp( key, "VERSION_ID" ) == 0 ) { + version = strdup( value ); + } + } + + fclose( f ) ; + + if( strcmp( os, "Arch Linux" ) == 0 ) { + free( os ); + os = strdup( "archlinux" ); + } + + if( version == NULL ) { + version = strdup( "rolling" ); + } + + snprintf( name, len, "cpe:/o:%s:%s:%s", os, os, version ); + + if( os != NULL ) free( os ); + if( version != NULL ) free( version ); + #elif defined( __FreeBSD__ ) + /* resort to uname */ struct utsname uts; uname( &uts ); snprintf( name, len, "cpe:/o:%s:%s:%s", uts.sysname, uts.release, uts.version ); #else + /* TODO: or should this be a compilation error? */ snprintf( name, len, "cpe:/o:unknown:unknown:unknown" ); #endif } |