# ifdef HAVE_CONFIG_H # include "config.h" # endif #include 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; }