summaryrefslogtreecommitdiff
path: root/src/system.c
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2014-09-18 14:52:51 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2014-09-18 14:52:51 +0200
commitd3bf01e1c5c60113d012537ee52f69515cf5ecb7 (patch)
treee36cb2d8a7f9dffabc652b8172b4599f86c955b8 /src/system.c
parentf8a83ea88eacf744f9bde5e3f96e29ad627ec2f5 (diff)
downloadbiruda-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.c80
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
}