forked from enlightenment/enlightenment
480 lines
13 KiB
C
480 lines
13 KiB
C
# ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
# endif
|
|
|
|
#include <Eet.h>
|
|
|
|
typedef struct _E_Static_Grab E_Static_Grab;
|
|
typedef struct _E_Static_Grab_Module E_Static_Grab_Module;
|
|
|
|
struct _E_Static_Grab
|
|
{
|
|
struct
|
|
{
|
|
int core_count;
|
|
int thread_count;
|
|
int bogo;
|
|
int model;
|
|
int family;
|
|
int stepping;
|
|
int cache_size;
|
|
int addr_space;
|
|
|
|
const char *vendor;
|
|
const char *model_name;
|
|
|
|
Eina_Bool fpu;
|
|
} cpu;
|
|
|
|
struct
|
|
{
|
|
const char *name;
|
|
const char *release;
|
|
const char *os;
|
|
const char *kernel_release;
|
|
} distribution;
|
|
|
|
struct
|
|
{
|
|
struct
|
|
{
|
|
const char *vendor;
|
|
const char *renderer;
|
|
const char *version;
|
|
} gpu;
|
|
|
|
const char *name;
|
|
const char *release_date;
|
|
const char *build_date;
|
|
|
|
Eina_List *modules;
|
|
} x;
|
|
};
|
|
|
|
struct _E_Static_Grab_Module
|
|
{
|
|
const char *name;
|
|
const char *vendor;
|
|
const char *compiled_for;
|
|
const char *version;
|
|
const char *class;
|
|
const char *ABI_class;
|
|
const char *ABI_version;
|
|
};
|
|
|
|
/* For /proc/cpuinfo */
|
|
#define CPU_CORES "cpu cores"
|
|
#define CACHE_SIZE "cache size"
|
|
#define CPU_FAMILY "cpu family"
|
|
#define STEPPING "stepping"
|
|
#define SIBLINGS "siblings"
|
|
#define BOGOMIPS "bogomips"
|
|
#define MODEL "model"
|
|
#define MODEL_NAME "model name"
|
|
#define VENDOR_ID "vendor_id"
|
|
#define FPU "fpu"
|
|
|
|
/* For /var/log/Xorg.0.log */
|
|
#define RELEASE_DATE "Release Date"
|
|
#define BUILD_DATE "Build Date"
|
|
#define LOAD_MODULE "(II) LoadModule"
|
|
#define UNLOAD_MODULE "(II) UnloadModule"
|
|
#define MODULE_OF "(II) Module %s"
|
|
#define LOADING "(II) Loading"
|
|
#define VENDOR "vendor=\""
|
|
#define COMPILED "compiled for "
|
|
#define MODULE_CLASS "Module class"
|
|
#define ABI_CLASS "ABI class"
|
|
#undef VERSION
|
|
#define VERSION ", version "
|
|
|
|
static const char *
|
|
_e_static_grab_name(const char *line, const char *end, const char *name)
|
|
{
|
|
size_t l;
|
|
|
|
l = strlen(name);
|
|
if (line + l + 3 > end) return end;
|
|
if (strncmp(name, line, l)) return end;
|
|
|
|
return line + l;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_e_static_grab_int(const char *line, const char *end, const char *txt, int *v)
|
|
{
|
|
static const char *value = "0123456789";
|
|
const char *over;
|
|
int r = 0;
|
|
|
|
over = _e_static_grab_name(line, end, txt);
|
|
while (over < end)
|
|
{
|
|
if (strchr(value, *over)) break;
|
|
over++;
|
|
}
|
|
if (over == end) return EINA_FALSE;
|
|
|
|
while (over < end)
|
|
{
|
|
const char *offset = strchr(value, *over);
|
|
|
|
if (!offset) break;
|
|
r = r * 10 + (offset - value);
|
|
|
|
over++;
|
|
}
|
|
|
|
*v = r;
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_e_static_grab_string(const char *line, const char *end, const char *txt, const char **s)
|
|
{
|
|
static const char *value = " :\t";
|
|
const char *over;
|
|
|
|
over = _e_static_grab_name(line, end, txt);
|
|
while (over < end)
|
|
{
|
|
if (!strchr(value, *over)) break;
|
|
over++;
|
|
}
|
|
if (over == end) return EINA_FALSE;
|
|
|
|
if (*over == '"' && *(end - 2) == '"')
|
|
{
|
|
over++;
|
|
end--;
|
|
}
|
|
|
|
*s = eina_stringshare_add_length(over, end - over - 1);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static const char *
|
|
_e_static_grab_discard(const char *current, Eina_File_Line *line, int begin, int end)
|
|
{
|
|
while (current < line->end &&
|
|
strchr(" \t", *current))
|
|
current++;
|
|
|
|
if (*current != begin) return current;
|
|
|
|
while (current < line->end &&
|
|
*current != end)
|
|
current++;
|
|
|
|
if (current == line->end) return current;
|
|
|
|
for (current++;
|
|
current < line->end && strchr(" \t", *current);
|
|
current++)
|
|
;
|
|
|
|
return current;
|
|
}
|
|
|
|
static void
|
|
_e_static_grab_cpu(E_Static_Grab *grab)
|
|
{
|
|
char buf[4096];
|
|
FILE *f;
|
|
const char *fpu = NULL;
|
|
int siblings = 0;
|
|
|
|
grab->cpu.addr_space = sizeof (void *);
|
|
|
|
f = fopen("/proc/cpuinfo", "r");
|
|
if (!f) return;
|
|
|
|
while (!feof(f))
|
|
{
|
|
char *end;
|
|
size_t length = 0;
|
|
|
|
if (!fgets(buf, sizeof (buf), f)) break;
|
|
length = strlen(buf);
|
|
end = buf + length;
|
|
|
|
if (length < 3) continue;
|
|
|
|
switch (*buf)
|
|
{
|
|
case 'c':
|
|
if (_e_static_grab_int(buf, end, CPU_CORES, &grab->cpu.core_count)) break;
|
|
if (_e_static_grab_int(buf, end, CACHE_SIZE, &grab->cpu.cache_size)) break;
|
|
_e_static_grab_int(buf, end, CPU_FAMILY, &grab->cpu.family);
|
|
break;
|
|
|
|
case 's':
|
|
if (_e_static_grab_int(buf, end, STEPPING, &grab->cpu.stepping)) break;
|
|
_e_static_grab_int(buf, end, SIBLINGS, &siblings);
|
|
break;
|
|
|
|
case 'b':
|
|
_e_static_grab_int(buf, end, BOGOMIPS, &grab->cpu.bogo);
|
|
break;
|
|
|
|
case 'm':
|
|
if (_e_static_grab_string(buf, end, MODEL_NAME, &grab->cpu.model_name)) break;
|
|
_e_static_grab_int(buf, end, MODEL, &grab->cpu.model);
|
|
break;
|
|
|
|
case 'v':
|
|
_e_static_grab_string(buf, end, VENDOR_ID, &grab->cpu.vendor);
|
|
break;
|
|
|
|
case 'f':
|
|
_e_static_grab_string(buf, end, FPU, &fpu);
|
|
break;
|
|
}
|
|
}
|
|
fclose(f);
|
|
|
|
if (siblings) grab->cpu.thread_count = siblings / grab->cpu.core_count;
|
|
if (fpu)
|
|
{
|
|
if (!strcmp(fpu, "yes")) grab->cpu.fpu = EINA_TRUE;
|
|
eina_stringshare_del(fpu);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_e_static_grab_x(E_Static_Grab *grab)
|
|
{
|
|
Eina_Bool in_module = EINA_FALSE;
|
|
E_Static_Grab_Module *module;
|
|
Eina_File_Line *line;
|
|
Eina_Iterator *it;
|
|
Eina_File *f;
|
|
|
|
f = eina_file_open("/var/log/Xorg.0.log", EINA_FALSE);
|
|
if (!f) return;
|
|
|
|
module = calloc(1, sizeof (E_Static_Grab_Module));
|
|
if (!module)
|
|
{
|
|
eina_file_close(f);
|
|
return;
|
|
}
|
|
|
|
it = eina_file_map_lines(f);
|
|
EINA_ITERATOR_FOREACH(it, line)
|
|
{
|
|
const char *current;
|
|
|
|
current = _e_static_grab_discard(line->start, line, '[', ']');
|
|
if (current >= line->end) continue;
|
|
|
|
if (!grab->x.name)
|
|
{
|
|
if (line->end - current - 1 <= 0) continue;
|
|
grab->x.name = eina_stringshare_add_length(current, line->end - current - 1);
|
|
continue;
|
|
}
|
|
|
|
if (!in_module)
|
|
{
|
|
switch (*current)
|
|
{
|
|
case 'R':
|
|
_e_static_grab_string(current, line->end, RELEASE_DATE, &grab->x.release_date);
|
|
break;
|
|
|
|
case 'B':
|
|
_e_static_grab_string(current, line->end, BUILD_DATE, &grab->x.build_date);
|
|
break;
|
|
|
|
case '(':
|
|
{
|
|
E_Static_Grab_Module *md;
|
|
Eina_List *l;
|
|
const char *tmp;
|
|
|
|
if (_e_static_grab_string(current, line->end, LOAD_MODULE, &module->name))
|
|
{
|
|
EINA_LIST_FOREACH(grab->x.modules, l, md)
|
|
if (md->name == module->name)
|
|
{
|
|
eina_stringshare_del(module->name);
|
|
module->name = NULL;
|
|
break;
|
|
}
|
|
|
|
if (module->name) in_module = EINA_TRUE;
|
|
break;
|
|
}
|
|
else if (_e_static_grab_string(current, line->end, UNLOAD_MODULE, &tmp))
|
|
{
|
|
EINA_LIST_FOREACH(grab->x.modules, l, md)
|
|
if (md->name == tmp)
|
|
{
|
|
grab->x.modules = eina_list_remove_list(grab->x.modules, l);
|
|
|
|
eina_stringshare_del(md->name);
|
|
eina_stringshare_del(md->vendor);
|
|
eina_stringshare_del(md->compiled_for);
|
|
eina_stringshare_del(md->version);
|
|
eina_stringshare_del(md->class);
|
|
eina_stringshare_del(md->ABI_class);
|
|
eina_stringshare_del(md->ABI_version);
|
|
free(md);
|
|
break;
|
|
}
|
|
eina_stringshare_del(tmp);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char *buffer;
|
|
Eina_Bool found = EINA_FALSE;
|
|
|
|
switch (*current)
|
|
{
|
|
case '(':
|
|
{
|
|
const char *vendor;
|
|
|
|
if (strncmp(current, LOADING, strlen(LOADING)) == 0)
|
|
{
|
|
found = EINA_TRUE;
|
|
break;
|
|
}
|
|
|
|
buffer = alloca(strlen(MODULE_OF) + strlen(module->name) + 1);
|
|
sprintf(buffer, MODULE_OF, module->name);
|
|
|
|
if (_e_static_grab_string(current, line->end, buffer, &vendor))
|
|
{
|
|
if (strncmp(vendor, VENDOR, strlen(VENDOR)) == 0)
|
|
{
|
|
module->vendor = eina_stringshare_add_length(vendor + strlen(VENDOR),
|
|
eina_stringshare_strlen(vendor) - strlen(VENDOR) - 1);
|
|
found = EINA_TRUE;
|
|
}
|
|
eina_stringshare_del(vendor);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 'c':
|
|
if (strncmp(current, COMPILED, strlen(COMPILED)) == 0)
|
|
{
|
|
const char *lookup = current + strlen(COMPILED);
|
|
|
|
while (lookup < line->end && *lookup != ',')
|
|
lookup++;
|
|
|
|
module->compiled_for = eina_stringshare_add_length(current + strlen(COMPILED),
|
|
lookup - current - strlen(COMPILED));
|
|
found = EINA_TRUE;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 'M':
|
|
if (_e_static_grab_string(current, line->end, MODULE_CLASS, &module->class))
|
|
{
|
|
found = EINA_TRUE;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 'A':
|
|
{
|
|
const char *tmp;
|
|
|
|
if (_e_static_grab_string(current, line->end, ABI_CLASS, &tmp))
|
|
{
|
|
const char *lookup = strchr(tmp, ',');
|
|
|
|
if (lookup)
|
|
{
|
|
module->ABI_class = eina_stringshare_add_length(tmp, lookup - tmp);
|
|
if (strncmp(lookup, VERSION, strlen(VERSION)) == 0)
|
|
{
|
|
module->ABI_version = eina_stringshare_add_length(lookup + strlen(VERSION),
|
|
eina_stringshare_strlen(tmp) - (lookup - tmp + strlen(VERSION) - 1));
|
|
}
|
|
eina_stringshare_del(tmp);
|
|
}
|
|
else
|
|
{
|
|
module->ABI_class = tmp;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
{
|
|
in_module = EINA_FALSE;
|
|
grab->x.modules = eina_list_append(grab->x.modules, module);
|
|
module = calloc(1, sizeof (E_Static_Grab_Module));
|
|
}
|
|
}
|
|
}
|
|
|
|
free(module);
|
|
|
|
eina_iterator_free(it);
|
|
eina_file_close(f);
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv EINA_UNUSED)
|
|
{
|
|
E_Static_Grab_Module *module;
|
|
Eina_List *l;
|
|
E_Static_Grab grab;
|
|
|
|
if (argc != 2) exit(0);
|
|
|
|
#if 0
|
|
/* FIXME: Latter push information into an eet file when updated */
|
|
if ((!strcmp(argv[1], "-h")) ||
|
|
(!strcmp(argv[1], "-help")) ||
|
|
(!strcmp(argv[1], "--help")))
|
|
{
|
|
printf("This is an internal tool for Enlightenment.\n"
|
|
"do not use it.\n");
|
|
exit(0);
|
|
}
|
|
#endif
|
|
|
|
eina_init();
|
|
eet_init();
|
|
|
|
memset(&grab, 0, sizeof (grab));
|
|
_e_static_grab_cpu(&grab); /* FIXME: please provide patch for more Unix */
|
|
_e_static_grab_x(&grab);
|
|
|
|
fprintf(stderr, "%i core with %i thread running in %i bits at %i bogomips with %i cache from vendor %s with model %s\n",
|
|
grab.cpu.core_count, grab.cpu.thread_count, grab.cpu.addr_space * 8, grab.cpu.bogo, grab.cpu.cache_size, grab.cpu.vendor, grab.cpu.model_name);
|
|
fprintf(stderr, "X Server: '%s' released '%s' and build '%s'\n",
|
|
grab.x.name, grab.x.release_date, grab.x.build_date);
|
|
fprintf(stderr, "*** X Modules ***\n");
|
|
EINA_LIST_FOREACH(grab.x.modules, l, module)
|
|
fprintf(stderr, "[%s - '%s' - '%s' - '%s' - '%s','%s' ]\n",
|
|
module->name, module->vendor, module->compiled_for,
|
|
module->class, module->ABI_class, module->ABI_version);
|
|
fprintf(stderr, "*** ***\n");
|
|
|
|
/* FIXME: Get information about what Unix (Linux, BSD, ...) it is run on */
|
|
/* FIXME: run a mainloop and start gathering result from df, free, lspci and lsusb */
|
|
/* FIXME: use xrandr to figure out the screen config */
|
|
|
|
eet_shutdown();
|
|
eina_shutdown();
|
|
|
|
return 0;
|
|
}
|
|
|