uncommitted - hardinfo

Ready changes

Summary

Import uploads missing from VCS:

Diff

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9774431
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+Makefile
+config.h
+*.so
+*.o
+*~
+arch/this
+build/
+test/build-*
+po/*.old
+
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..43026ff
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "deps/uber-graph"]
+	path = deps/uber-graph
+	url = https://github.com/chergert/uber-graph.git
diff --git a/AUTHORS.md b/AUTHORS.md
new file mode 100644
index 0000000..dc7b7de
--- /dev/null
+++ b/AUTHORS.md
@@ -0,0 +1,54 @@
+HardInfo was started in 2003, by Leandro Pereira, and has received
+contributions from many people over the years.
+
+There was a time it didn't even use a version control system. The early
+notes and changelogs were lost. Some important contributions were made
+by simply submitting bug reports or comments. For these reasons, it
+would be difficult to gather the names of all the people that
+contributed to the project.
+
+Here is an incomplete list of contributors:
+
+* Leandro A. F. Pereira <leandro@hardinfo.org>
+* Stewart Adam <s.adam@diffingo.com>
+* Pascal F. Martin <pascalmartin@earthlink.net>
+* Burt P. <pburt0@gmail.com>
+* TotalCaesar659 <x24cm5b8c54q6szxw@yandex.ru>
+* Andrey Esin <gmlastik@gmail.com>
+* Julian Ospald <julian.ospald@googlemail.com>
+* Julien Lavergne <gilir@ubuntu.com>
+* Fernando López <fernando.e.lopez@gmail.com>
+* PICCORO Lenz McKAY <mckaygerhard@gmail.com>
+* Alexander Münch <git@thehacker.biz>
+* Simon Quigley <tsimonq2@ubuntu.com>
+* AsciiWolf <mail@asciiwolf.com>
+* George Schneeloch <george@editshare.com>
+* Mattia Rizzolo <mattia@mapreri.org>
+* Yo <yoldc22@free.fr>
+* "jamesbond" (http://chiselapp.com/user/jamesbond/)
+
+Includes code from or based on:
+
+* uber-graph by Christian Hergert <chris@dronelabs.com>, and others.
+* BinReloc by Hongli Lai <h.lai@chello.nl>
+* decode-dimms.pl by Philip Edelbrock <phil@netroedge.com>,
+  Christian Zuckschwerdt <zany@triq.net>, and
+  Burkart Lingner <burkart@bollchen.de>
+* x86cpucaps by Osamu Kayasono <jacobi@jcom.home.ne.jp>
+* MD5 implementation by Colin Plumb (see md5.c for details)
+* SHA1 implementation by Steve Reid (see sha1.c for details)
+* Blowfish implementation by Paul Kocher (see blowfish.c for details)
+* Raytracing benchmark by John Walker (see fbench.c for details)
+* FFT benchmark by Scott Robert Ladd (see fftbench.c for details)
+* Vendor list based on GtkSysInfo by Pissens Sebastien
+
+Artwork:
+
+* Jakub Szypulka
+* Tango Project
+* The GNOME Project
+* VMWare, Inc. (USB icon from VMWare Workstation 6)
+
+See also:
+
+* https://github.com/lpereira/hardinfo/graphs/contributors
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..ab62cad
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,301 @@
+project(HardInfo)
+cmake_minimum_required(VERSION 2.6)
+cmake_policy(VERSION 2.6)
+
+set(HARDINFO_VERSION "0.6-alpha")
+option(HARDINFO_NOSYNC "Disable database sync via libsoup" 1)
+option(HARDINFO_GTK3 "Attempt to build for GTK3 (0/off for GTK2)" 0)
+set(OVRARCH "" CACHE STRING "Override HARDINFO_ARCH value")
+set(OVRCPUINFO "" CACHE STRING "Specify a different file for /proc/cpuinfo")
+set(OVRDTRROOT "" CACHE STRING "Specify a different path for /proc/device-tree")
+SET( CMAKE_MODULE_PATH  "${CMAKE_CURRENT_SOURCE_DIR}/cmake" )
+include(GNUInstallDirs)
+
+if(${CMAKE_BUILD_TYPE} MATCHES [Dd]ebug)
+	set(HARDINFO_DEBUG 1)
+	set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
+endif()
+
+if(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Linux")
+	set(HARDINFO_OS "linux")
+else()
+	message(FATAL_ERROR "Unsupported operating system: ${CMAKE_HOST_SYSTEM_NAME}")
+endif()
+
+if(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "i[3-6]86")
+	set(HARDINFO_ARCH "x86")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "x86_64")
+	set(HARDINFO_ARCH "x86")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "(ppc|ppc32|ppc64|ppc64le)")
+	set(HARDINFO_ARCH "ppc")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "mips")
+	set(HARDINFO_ARCH "mips")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "parisc.*")
+	set(HARDINFO_ARCH "parisc")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "sparc{32,64}")
+	set(HARDINFO_ARCH "sparc")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "arm.*")
+	set(HARDINFO_ARCH "arm")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "aarch64.*")
+	set(HARDINFO_ARCH "arm")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "ia64")
+	set(HARDINFO_ARCH "ia64")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "alpha")
+	set(HARDINFO_ARCH "alpha")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "s390.*")
+	set(HARDINFO_ARCH "s390")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "m68k")
+	set(HARDINFO_ARCH "m68k")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "sh[3-5]")
+	set(HARDINFO_ARCH "sh")
+elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "(riscv|riscv32|riscv64)")
+	set(HARDINFO_ARCH "riscv")
+else()
+	message(FATAL_ERROR "Unsupported architecture: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
+endif()
+
+if (OVRARCH)
+	set(HARDINFO_ARCH ${OVRARCH})
+endif()
+if (OVRCPUINFO)
+	add_definitions(-DPROC_CPUINFO=${OVRCPUINFO})
+	message(STATUS "/proc/cpuinfo override: ${OVRCPUINFO}")
+endif()
+if (OVRDTRROOT)
+	add_definitions(-DDTR_ROOT=${OVRDTRROOT})
+	message(STATUS "/proc/device-tree override: ${OVRDTRROOT}")
+endif()
+add_definitions(-DLOCALEDIR="${CMAKE_INSTALL_PREFIX}/share/locale")
+message(STATUS "LOCALEDIR = ${CMAKE_INSTALL_PREFIX}/share/locale")
+
+message(STATUS "Building HardInfo for architecture: ${HARDINFO_OS}-${HARDINFO_ARCH}")
+
+add_definitions("-std=gnu89")
+
+add_subdirectory(po)
+
+include(FindPkgConfig)
+if (HARDINFO_GTK3)
+	message(STATUS "Building for GTK3 (experimental!)")
+	pkg_check_modules(GTK REQUIRED gtk+-3.0>=3.0 cairo>=1.0 cairo-png>=1.0 glib-2.0>=2.10 gthread-2.0>=2.10 gmodule-export-2.0>=2.10)
+	add_definitions(-DGTK_DISABLE_SINGLE_INCLUDES)
+else()
+	message(STATUS "Building for GTK2")
+	pkg_check_modules(GTK REQUIRED gtk+-2.0>=2.10 glib-2.0>=2.10 gthread-2.0>=2.10 gmodule-export-2.0>=2.10)
+endif()
+
+if(NOT HARDINFO_NOSYNC)
+	pkg_check_modules(LIBSOUP libsoup-2.4>=2.24)
+endif()
+
+include(FindZLIB REQUIRED)
+
+include_directories(
+	${CMAKE_SOURCE_DIR}
+	${CMAKE_SOURCE_DIR}/includes
+	${CMAKE_SOURCE_DIR}/includes/${HARDINFO_ARCH}
+	${CMAKE_SOURCE_DIR}/deps/uber-graph/uber
+	${CMAKE_BINARY_DIR}
+	${GTK_INCLUDE_DIRS}
+	${LIBSOUP_INCLUDE_DIRS}
+	${ZLIB_INCLUDE_DIRS}
+)
+link_directories(
+	${GTK_LIBRARY_DIRS}
+	${LIBSOUP_LIBRARY_DIRS}
+)
+
+set(HARDINFO_MODULES
+	computer
+	devices
+	benchmark
+	network
+)
+set(HARDINFO_RESOURCES
+	"benchmark.conf"
+	"benchmark.data"
+)
+
+set(HARDINFO_MANPAGES
+	"hardinfo.1"
+)
+
+set(MODULE_computer_SOURCES
+	modules/computer.c
+	modules/computer/alsa.c
+	modules/computer/boots.c
+	modules/computer/display.c
+	modules/computer/environment.c
+	modules/computer/filesystem.c
+	modules/computer/languages.c
+	modules/computer/loadavg.c
+	modules/computer/memory.c
+	modules/computer/modules.c
+	modules/computer/os.c
+	modules/computer/uptime.c
+	modules/computer/users.c
+	modules/computer/groups.c
+)
+set(MODULE_devices_SOURCES
+	modules/devices.c
+	modules/devices/${HARDINFO_ARCH}/processor.c
+	modules/devices/battery.c
+	modules/devices/devmemory.c
+	modules/devices/dmi.c
+	modules/devices/devicetree.c
+	modules/devices/inputdevices.c
+	modules/devices/pci.c
+	modules/devices/printers.c
+	modules/devices/resources.c
+	modules/devices/sensors.c
+	modules/devices/spd-decode.c
+	modules/devices/storage.c
+	modules/devices/usb.c
+)
+set(MODULE_network_SOURCES
+	modules/network.c
+	modules/network/net.c
+	modules/network/nfs.c
+	modules/network/samba.c
+)
+set(MODULE_benchmark_SOURCES_GTKANY
+	modules/benchmark.c
+	modules/benchmark/blowfish.c
+	modules/benchmark/cryptohash.c
+	modules/benchmark/drawing.c
+	modules/benchmark/fbench.c
+	modules/benchmark/fftbench.c
+	modules/benchmark/fft.c
+	modules/benchmark/fib.c
+	modules/benchmark/md5.c
+	modules/benchmark/nqueens.c
+	modules/benchmark/raytrace.c
+	modules/benchmark/sha1.c
+	modules/benchmark/zlib.c
+)
+set(MODULE_benchmark_SOURCES_GTK2
+	modules/benchmark/guibench.c
+)
+if (HARDINFO_GTK3)
+	set(MODULE_benchmark_SOURCES ${MODULE_benchmark_SOURCES_GTKANY})
+else()
+	set(MODULE_benchmark_SOURCES ${MODULE_benchmark_SOURCES_GTKANY} ${MODULE_benchmark_SOURCES_GTK2})
+endif()
+
+set_source_files_properties(
+	modules/benchmark/blowfish.c
+	modules/benchmark/fftbench.c
+	modules/benchmark/md5.c
+	modules/benchmark/sha1.c
+	PROPERTIES
+	COMPILE_FLAGS "-O0"
+)
+
+foreach (_module ${HARDINFO_MODULES})
+	add_library(${_module} MODULE ${MODULE_${_module}_SOURCES})
+	set_target_properties(${_module} PROPERTIES PREFIX "")
+endforeach()
+
+if (HARDINFO_GTK3)
+add_library(uber-graph STATIC
+	deps/uber-graph/uber/g-ring.c
+	deps/uber-graph/uber/uber-frame-source.c
+	deps/uber-graph/uber/uber-graph.c
+	deps/uber-graph/uber/uber-heat-map.c
+	deps/uber-graph/uber/uber-label.c
+	deps/uber-graph/uber/uber-line-graph.c
+	deps/uber-graph/uber/uber-range.c
+	deps/uber-graph/uber/uber-scale.c
+	deps/uber-graph/uber/uber-scatter.c
+	deps/uber-graph/uber/uber-timeout-interval.c
+	deps/uber-graph/uber/uber-window.c
+)
+endif()
+
+if (HARDINFO_GTK3)
+add_executable(hardinfo
+	hardinfo/binreloc.c
+	hardinfo/expr.c
+        hardinfo/hardinfo.c
+	hardinfo/socket.c
+	hardinfo/util.c
+	hardinfo/vendor.c
+	hardinfo/info.c
+	hardinfo/cpu_util.c
+	hardinfo/dmi_util.c
+	hardinfo/dt_util.c
+	shell/callbacks.c
+	shell/iconcache.c
+	shell/menu.c
+	shell/report.c
+	shell/shell.c
+	shell/stock.c
+	shell/syncmanager.c
+	shell/loadgraph-uber.c
+)
+target_link_libraries(hardinfo
+	uber-graph
+	${GTK_LIBRARIES}
+	${LIBSOUP_LIBRARIES}
+	m
+	${ZLIB_LIBRARIES}
+)
+else()
+add_executable(hardinfo
+	hardinfo/binreloc.c
+	hardinfo/expr.c
+        hardinfo/hardinfo.c
+	hardinfo/socket.c
+	hardinfo/util.c
+	hardinfo/vendor.c
+	hardinfo/info.c
+	hardinfo/cpu_util.c
+	hardinfo/dmi_util.c
+	hardinfo/dt_util.c
+	shell/callbacks.c
+	shell/iconcache.c
+	shell/menu.c
+	shell/report.c
+	shell/shell.c
+	shell/stock.c
+	shell/syncmanager.c
+	shell/loadgraph.c
+)
+target_link_libraries(hardinfo
+	${GTK_LIBRARIES}
+	${LIBSOUP_LIBRARIES}
+	m
+	${ZLIB_LIBRARIES}
+)
+endif()
+
+configure_file(config.h.cmake ${CMAKE_BINARY_DIR}/config.h @ONLY)
+configure_file(hardinfo.desktop.cmake ${CMAKE_BINARY_DIR}/hardinfo.desktop @ONLY)
+
+install(TARGETS hardinfo ${HARDINFO_MODULES}
+	RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+	LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/hardinfo/modules
+	PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+install(FILES ${CMAKE_BINARY_DIR}/hardinfo.desktop
+	DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications
+	PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+)
+install(FILES ${HARDINFO_RESOURCES}
+	DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/hardinfo
+	PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+)
+install(DIRECTORY pixmaps
+	DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/hardinfo
+	PATTERN "*.{png,svg}"
+	PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+)
+install(DIRECTORY doc
+	DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/hardinfo
+	PATTERN "*.{hlp,png}"
+	PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+)
+install(FILES ${HARDINFO_MANPAGES}
+	DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/man/man1
+	PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+)
diff --git a/CONTRIBUTING b/CONTRIBUTING
new file mode 100644
index 0000000..0b82439
--- /dev/null
+++ b/CONTRIBUTING
@@ -0,0 +1,16 @@
+Project
+=======
+
+Issues and Pull Requests via GitHub:
+
+* https://github.com/lpereira/hardinfo
+
+Translators
+===========
+
+If possible, run `bash updatepo.sh` in the po/ directory before begining.
+This will regenerate hardinfo.pot and update all the .po files.
+Nothing is lost if this isn't done, but it prevents wasting time translating
+strings that have changed, or are no longer used.
+
+DO NOT use `make pot`!
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..21b9363
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,341 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+               51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..04f172f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,78 @@
+HARDINFO
+========
+
+HardInfo is a system profiler and benchmark for Linux systems. It is able to
+obtain information from both hardware and basic software, and organize them
+in a simple to use GUI.
+
+Features include:
+- Report generation (in either HTML or plain text)
+- Benchmark result synchronization
+- Ability to explore the information on remote computers
+
+Status
+------
+
+Capabilities: Hardinfo currently decteds software and detected hardware by the OS, mostly almost all.
+Features: the remote sync was disable due server was lost
+Development: currently are made by contribution, a stable and fixed/dedicated maintainer are required.
+
+DEPENDENCIES
+------------
+
+Required:
+- GTK+ 2.10 (or newer)
+- GLib 2.10 (or newer)
+- Zlib (for zlib benchmark)
+
+Optional (for synchronization/remote):
+- Libsoup 2.24 (or newer)
+
+BUILDING
+--------
+
+Create a build directory and build from there:
+
+``` bash
+	hardinfo $ mkdir build
+	hardinfo $ cd build
+	build $ cmake ..
+	build $ make
+```
+
+There are some variables that can be changed:
+
+ * `CMAKE_BUILD_TYPE` : Can be either Release or Debug
+   * `[Default: Release]` Debug builds prints messages to console and are not recommended for general use
+ * `CMAKE_INSTALL_PREFIX` : Sets the installation prefix.
+   * `[Default: /usr/local]` : distributions generalli changes to `/usr`
+ * `HARDINFO_NOSYNC` : Disables network synchronization
+   * `[Default: 1]` : Disabled by default due the server service was lost.
+
+To set a variable, pass use cmake's -D command-line parameter. For example:
+
+`	build $ cmake .. -DCMAKE_BUILD_TYPE=Debug `
+
+Network sync are enabled if libsoup are detected, if having trouble building with libsoup, disable it with:
+
+`	build $ cmake -DHARDINFO_NOSYNC=1`
+
+SETTING UP
+----------
+
+Most things in HardInfo are detected automatically. However, some things
+depends on manual set up. They are:
+
+### Sensors
+
+**lm-sensors**: If your computer is compatible with lm-sensors module, use by example the
+`sensors-detect` program included with the lm-sensors package of Debian based distros, and be sure
+to have the detected kernel modules loaded.
+
+**hddtemp**: To obtain the hard disk drive temperature, be sure to run hddtemp
+in daemon mode, using the default port.
+
+### Memory Speed
+
+The module `eeeprom` mus be loaded to display info about memory hardware instaled.
+Load with `modprobe eeprom` and refres the module screen.
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..b65d77f
--- /dev/null
+++ b/TODO
@@ -0,0 +1,43 @@
+
+- Report Generation
+
+    * Ability to create more detailed reports
+    * Public web page to host user's reports
+
+- Benchmark
+
+    * New benchmarks
+          o FPU+CPU
+          o Disk
+	  o Phoronix?
+    * Change current benchmarks
+          o Remove CPU Fibonacci
+          * Add CPU Rubik Cube solver? :P
+
+- More information
+
+    * PCMCIA/Cardbus information
+    * S.M.A.R.T.
+    * Show USB devices as a tree instead of a list
+    * x86info integration?
+
+- i18n, build system
+
+    * GNU gettext
+
+- Misc
+
+    * Round benchmark results to two decimal places at most,
+      or get rid of decimal places altogether.
+    * Add preferences window
+	* Save/restore
+		* Window position
+		* Window size
+	* Proxy configuration
+		* Use HTTP_PROXY variable;
+		* Use GNOME settings;
+		* Manual configuration.
+	* Default browser
+		* Auto-detect;
+		* Use GNOME settings;
+		* Manual configuration.
diff --git a/benchmark.conf b/benchmark.conf
new file mode 100644
index 0000000..6f327aa
--- /dev/null
+++ b/benchmark.conf
@@ -0,0 +1,316 @@
+[param]
+last_update=1241368430
+[FPU FFT]
+Intel(R) Pentium(R) DualCPUT3200@ 2.00GHz=5.500|2x 2000 MHz|Unknown
+Intel(R) Celeron(R) CPU 2.53GHz=10.122|2527 MHz|Unknown
+Genuine Intel(R) CPU T1350@ 1.86GHz=83.465|1867 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-60=8.225|2x 2000 MHz|Unknown
+AMD Turion(tm) X2 Dual-Core Mobile RM-70=8.312|2x 500 MHz|Unknown
+Intel(R) Core(TM) Duo CPUT2350@ 1.86GHz=5.356|2x 1867 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T5750@ 2.00GHz=4.231|2x 1994 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T9500@ 2.60GHz=3.124|2x 2593 MHz|Unknown
+AMD Athlon(tm) X2 Dual-Core QL-60=9.080|2x 1900 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T5250@ 1.50GHz=5.507|2x 1000 MHz|Unknown
+Mobile AMD Athlon(tm) XP-M Processor 3000+=43.154|799 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 4000+=7.997|2x 1000 MHz|Unknown
+AMD Athlon(tm) XP processor 1800+=25.139|1533 MHz|Unknown
+Genuine Intel(R) CPU2140@ 1.60GHz=5.442|2x 1595 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ6600@ 2.40GHz=1.631|4x 1603 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU P7350@ 2.00GHz=4.758|2x 2000 MHz|Unknown
+Genuine Intel(R) CPU T2080@ 1.73GHz=4.985|2x 800 MHz|Unknown
+Intel(R) Celeron(R) CPU 2.50GHz=14.459|2492 MHz|Unknown
+Intel(R) Pentium(R) M processor 1.86GHz=11.875|1867 MHz|Unknown
+Intel(R) Core(TM)2 CPU T5200@ 1.60GHz=6.486|2x 1067 MHz|Unknown
+Intel(R) Core(TM)2 CPU6320@ 1.86GHz=4.908|2x 1600 MHz|Unknown
+AMD Athlon(tm) XP=84.350|906 MHz|Unknown
+AMD Athlon(tm) 64 Processor 3000+=25.187|1800 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.60GHz=8.536|2x 2600 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ9400@ 2.66GHz=1.485|4x 2003 MHz|Unknown
+Intel(R) Pentium(R) M processor 1600MHz=13.500|1600 MHz|Unknown
+Pentium(R) Dual-Core CPU T4200@ 2.00GHz=4.615|2x 1200 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPU @ 2.40GHz=1.696|4x 2400 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ8300@ 2.50GHz=1.659|4x 2497 MHz|Unknown
+Intel(R) Core(TM)2 Extreme CPU X7900@ 2.80GHz=3.065|2x 2800 MHz|Unknown
+Intel(R) Celeron(R) D CPU 3.20GHz=8.552|3196 MHz|Unknown
+AMD Sempron(tm) 2600+=20.952|1840 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 4400+=6.805|2x 1000 MHz|Unknown
+Intel(R) Celeron(R) CPU 2.66GHz=9.887|2666 MHz|Unknown
+Intel(R) Core(TM) Duo CPUT2450@ 2.00GHz=4.331|2x 800 MHz|Unknown
+Intel(R) Celeron(R) M CPU520@ 1.60GHz=11.346|1600 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 3.06GHz=12.724|3058 MHz|Unknown
+Intel(R) Core(TM)2 CPU4300@ 1.80GHz=5.368|2x 1200 MHz|Unknown
+Intel(R) Core(TM)2 CPU6400@ 2.13GHz=4.678|2x 2128 MHz|Unknown
+AMD Turion(tm) 64 Mobile Technology MK-36=19.958|800 MHz|Unknown
+Intel(R) Core(TM)2 CPU6600@ 2.40GHz=3.546|2x 1596 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T7250@ 2.00GHz=4.160|2x 2001 MHz|Unknown
+Intel(R) Celeron(R) M processor900MHz=24.212|900 MHz|Unknown
+AMD Sempron(tm) Processor 3400+=17.114|1000 MHz|Unknown
+AMD Athlon(tm) XP 2500+=27.327|1792 MHz|Unknown
+AMD Sempron(tm) Processor 3000+=18.941|1800 MHz|Unknown
+AMD Athlon(tm) XP 2200+=22.197|1782 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 3.06GHz=7.454|2x 3065 MHz|Unknown
+AMD Processor model unknown=5.242|2x 3006 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-62=7.519|2x 800 MHz|Unknown
+[CPU CryptoHash]
+Intel(R) Atom(TM) CPU330 @ 1.60GHz=105.569|4x 1596 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T5250@ 1.50GHz=102.949|2x 1000 MHz|Unknown
+Intel(R) Celeron(R) M processor900MHz=24.338|900 MHz|Unknown
+Intel(R) Core(TM)2 CPU E8400@ 3.00GHz=163.391|2x 3000 MHz|Unknown
+Intel(R) Xeon(R) CPU E5405@ 2.00GHz=117.480|2x 1995 MHz|Unknown
+Intel(R) Core(TM) Duo CPUT2450@ 2.00GHz=127.241|2x 800 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.00GHz=24.650|1994 MHz|Unknown
+AMD Phenom(tm) 9350e Quad-Core Processor=237.011|4x 2000 MHz|Unknown
+AMD Turion(tm) X2 Ultra Dual-Core Mobile ZM-82=100.065|2x 600 MHz|Unknown
+AMD Athlon(tm) XP 3000+=66.539|2158 MHz|Unknown
+Intel(R) Celeron(R) M CPU520@ 1.60GHz=52.308|1600 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ6700@ 2.66GHz=264.055|4x 2669 MHz|Unknown
+AMD Athlon(tm) XP 1900+=31.633|1593 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 3.20GHz=66.611|2x 2400 MHz|Unknown
+AMD Sempron(tm) 2600+=53.870|1840 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 3800+=94.123|2x 2200 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-62=119.427|2x 800 MHz|Unknown
+AMD Athlon(tm) XP 2000+=45.755|1667 MHz|Unknown
+AMD Athlon(tm) 64 Processor 3500+=62.204|1000 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-56=92.191|2x 800 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 4000+=97.036|2x 1000 MHz|Unknown
+Intel(R) Pentium(R) D CPU 3.00GHz=96.755|2x 3000 MHz|Unknown
+Mobile AMD Sempron(tm) Processor 3600+=54.437|800 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ9650@ 3.00GHz=303.512|4x 2997 MHz|Unknown
+AMD Sempron(tm) Processor 3600+=43.977|1000 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T9400@ 2.53GHz=148.711|2x 800 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-58=101.693|2x 1900 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU P7350@ 2.00GHz=103.950|2x 2000 MHz|Unknown
+VIA Esther processor 1500MHz=7.752|1499 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU P8600@ 2.40GHz=150.445|2x 800 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T7700@ 2.40GHz=142.537|2x 800 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T5550@ 1.83GHz=122.423|2x 1829 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T7250@ 2.00GHz=121.915|2x 2001 MHz|Unknown
+Intel(R) Core(TM)2 CPU6700@ 2.66GHz=163.639|2x 2667 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.40GHz=30.963|2400 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ9400@ 2.66GHz=296.869|4x 2003 MHz|Unknown
+AMD Athlon(tm) 64 Processor 3200+=42.300|1000 MHz|Unknown
+Intel(R) Pentium(R) DualCPUT3200@ 2.00GHz=88.536|2x 2000 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.26GHz=29.413|2267 MHz|Unknown
+AMD Sempron(tm) Processor 3400+=53.845|1000 MHz|Unknown
+AMD Sempron(tm) Processor 3000+=47.787|1800 MHz|Unknown
+AMD Athlon(tm) XP 2400+=61.644|1991 MHz|Unknown
+Intel(R) Atom(TM) CPU Z530 @ 1.60GHz=54.891|2x 1067 MHz|Unknown
+Pentium III (Coppermine)=26.992|700 MHz|Unknown
+Intel(R) Core(TM) i7 CPU 920@ 2.67GHz=390.240|8x 3799 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 6000+=146.744|2x 3051 MHz|Unknown
+AMD Turion(tm) 64 Mobile Technology ML-37=42.208|2000 MHz|Unknown
+Intel(R) Xeon(R) CPU3040@ 1.86GHz=127.825|2x 1862 MHz|Unknown
+AMD Athlon(tm) XP 2500+=39.659|1792 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T9500@ 2.60GHz=172.640|2x 2593 MHz|Unknown
+[CPU N-Queens]
+AMD Athlon(tm) 64 X2 Dual Core Processor 5400+=15.057|2x 1000 MHz|Unknown
+Genuine Intel(R) CPU T2080@ 1.73GHz=33.309|2x 800 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T5450@ 1.66GHz=14.488|2x 1000 MHz|Unknown
+Intel(R) Core(TM)2 QuadCPU Q9300@ 2.50GHz=14.100|4x 3000 MHz|Unknown
+Intel(R) Atom(TM) CPU Z530 @ 1.60GHz=18.703|2x 1067 MHz|Unknown
+Intel(R) Atom(TM) CPU330 @ 1.60GHz=26.065|4x 1596 MHz|Unknown
+AMD Athlon(tm) XP 1600+=19.852|1398 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ6700@ 2.66GHz=17.009|4x 2669 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.60GHz=14.827|2x 2600 MHz|Unknown
+Intel(R) Core(TM)2 CPU6320@ 1.86GHz=16.536|2x 1600 MHz|Unknown
+Intel(R) Core(TM)2 Extreme CPU X7900@ 2.80GHz=7.020|2x 2800 MHz|Unknown
+Intel(R) Core(TM)2 QuadCPU Q9450@ 2.66GHz=12.973|4x 2000 MHz|Unknown
+Intel(R) Core(TM)2 CPU E8400@ 3.00GHz=7.841|2x 3000 MHz|Unknown
+Pentium III (Coppermine)=27.983|700 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 4000+=19.510|2x 1000 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-50=23.257|2x 800 MHz|Unknown
+Intel(R) Pentium(R) D CPU 3.40GHz=13.512|2x 2400 MHz|Unknown
+Pentium III (Coppermine)=35.147|2x 999 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 3600+=22.980|2x 1000 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 5200+=14.954|2x 2705 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual-Core Processor TK-55=20.494|2x 800 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU E6850@ 3.00GHz=7.522|2x 1998 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU P8400@ 2.26GHz=10.388|2x 800 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ9400@ 2.66GHz=18.246|4x 2003 MHz|Unknown
+AMD Athlon(tm) XP 1900+=26.739|1593 MHz|Unknown
+Intel(R) Core(TM) Duo CPUT2350@ 1.86GHz=22.009|2x 1867 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU E8400@ 3.00GHz=7.663|2x 2997 MHz|Unknown
+AMD Athlon(tm) XP 2800+=13.555|2087 MHz|Unknown
+Genuine Intel(R) CPU T2500@ 2.00GHz=28.389|2x 1000 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-58=20.024|2x 1900 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 3.40GHz=15.298|2x 2400 MHz|Unknown
+Intel(R) Celeron(R) M processor900MHz=33.259|900 MHz|Unknown
+AMD Athlon(tm) X2 Dual-Core QL-60=20.337|2x 1900 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T5850@ 2.16GHz=10.372|2x 2167 MHz|Unknown
+Mobile AMD Athlon(tm) XP-M Processor 3000+=52.785|799 MHz|Unknown
+AMD Phenom(tm) 9500 Quad-Core Processor=10.061|4x 1100 MHz|Unknown
+Intel(R) Celeron(R) M processor 1.40GHz=94.050|1395 MHz|Unknown
+Mobile AMD Athlon(tm) XP 2800+=13.362|1459 MHz|Unknown
+AMD Athlon(tm) 64 Processor 3000+=18.076|1800 MHz|Unknown
+Genuine Intel(R) CPU L2400@ 1.66GHz=19.551|2x 1000 MHz|Unknown
+AMD Sempron(tm) Processor 2800+=17.227|1999 MHz|Unknown
+AMD Sempron(tm) 2600+=14.693|1840 MHz|Unknown
+Intel(R) Pentium(R) M processor 1600MHz=15.228|1600 MHz|Unknown
+Genuine Intel(R) CPU 575@ 2.00GHz=15.876|1995 MHz|Unknown
+Genuine Intel(R) CPU T2300@ 1.66GHz=27.251|2x 1000 MHz|Unknown
+Intel(R) Pentium(R) M processor 1.70GHz=22.545|600 MHz|Unknown
+AMD Athlon(tm) XP processor 1800+=17.547|1533 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T5750@ 2.00GHz=11.140|2x 1994 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T7250@ 2.00GHz=11.387|2x 2001 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 1500MHz=28.460|1495 MHz|Unknown
+[FPU Raytracing]
+Intel(R) Core(TM) Duo CPUT2450@ 2.00GHz=28.359|2x 800 MHz|Unknown
+AMD Athlon(tm) XP 2200+=29.739|1782 MHz|Unknown
+Intel(R) Pentium(R) DualCPUT2370@ 1.73GHz=25.822|2x 1733 MHz|Unknown
+AMD Sempron(tm) Processor 3200+=30.191|1000 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual-Core Processor TK-55=16.469|2x 800 MHz|Unknown
+Intel(R) Core(TM)2 CPU6600@ 2.40GHz=11.244|2x 1596 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T5270@ 1.40GHz=32.813|2x 800 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual-Core Processor TK-53=18.472|2x 800 MHz|Unknown
+Intel(R) Pentium(R) M processor 1.86GHz=28.196|1867 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T5750@ 2.00GHz=16.383|2x 1994 MHz|Unknown
+AMD Turion(tm) 64 Mobile Technology ML-32=28.432|800 MHz|Unknown
+Intel(R) Celeron(R) CPU530@ 1.73GHz=17.548|2593 MHz|Unknown
+Intel(R) Core(TM) i7 CPU 920@ 2.67GHz=4.731|8x 3799 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ9650@ 3.00GHz=18.842|4x 2997 MHz|Unknown
+AMD Turion(tm) 64 Mobile Technology MK-36=30.838|800 MHz|Unknown
+Intel(R) Pentium(R) D CPU 3.40GHz=25.418|2x 2400 MHz|Unknown
+AMD Athlon(tm) X2 Dual-Core QL-60=18.295|2x 1900 MHz|Unknown
+Intel(R) Pentium(R) III CPU - S 1400MHz=33.361|1392 MHz|Unknown
+AMD Phenom(tm) II X4 20 Processor=13.290|4x 3654 MHz|Unknown
+Intel(R) Core(TM)2 CPU E8400@ 3.00GHz=15.790|2x 3000 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.66GHz=32.384|2676 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.60GHz=57.371|2x 2600 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU P9500@ 2.53GHz=5.507|2x 2535 MHz|Unknown
+Intel(R) Celeron(R) M processor900MHz=64.668|900 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 4800+=12.799|2x 2512 MHz|Unknown
+Intel(R) Pentium(R) M processor 1.73GHz=27.691|798 MHz|Unknown
+Genuine Intel(R) CPU T2080@ 1.73GHz=31.108|2x 800 MHz|Unknown
+AMD Athlon(tm) 64 Processor 4000+=20.492|1000 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.53GHz=36.544|2525 MHz|Unknown
+Intel(R) Celeron(R) CPU560@ 2.13GHz=21.147|2128 MHz|Unknown
+Intel(R) Core(TM)2 Extreme CPU X7900@ 2.80GHz=18.268|2x 2800 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T9400@ 2.53GHz=5.586|2x 800 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 6400+=10.933|2x 1000 MHz|Unknown
+Intel(R) Celeron(R) M CPU420@ 1.60GHz=36.998|1599 MHz|Unknown
+Intel(R) Xeon(R) CPU E5405@ 2.00GHz=17.808|2x 1995 MHz|Unknown
+Genuine Intel(R) CPU2140@ 1.60GHz=22.055|2x 1595 MHz|Unknown
+Intel(R) Pentium(R) M processor 1700MHz=27.284|600 MHz|Unknown
+Pentium II (Deschutes)=124.072|401 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T8100@ 2.10GHz=23.759|2x 2094 MHz|Unknown
+Intel(R) Core(TM)2 CPU4300@ 1.80GHz=18.171|2x 1200 MHz|Unknown
+AMD Athlon(tm) XP 3000+=23.066|2158 MHz|Unknown
+AMD Phenom(tm) 8450 Triple-Core Processor=18.564|3x 1100 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU P8400@ 2.26GHz=12.067|2x 800 MHz|Unknown
+AMD Athlon(tm) XP 1800+=31.725|1540 MHz|Unknown
+Intel(R) Celeron(R) CPU550@ 2.00GHz=23.904|1995 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 3.20GHz=31.439|2x 2400 MHz|Unknown
+Intel(R) Pentium(R) M processor 1.80GHz=27.133|600 MHz|Unknown
+Intel(R) Celeron(R) CPU 2.80GHz=81.047|2793 MHz|Unknown
+Genuine Intel(R) CPU T1350@ 1.86GHz=222.178|1867 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.80GHz=28.658|2791 MHz|Unknown
+PowerPC 740/750=161.312647|280.00 MHz|Unknown
+[CPU Blowfish]
+Intel(R) Pentium(R) D CPU 3.00GHz=10.838|2x 3000 MHz|Unknown
+Intel(R) Celeron(R) CPU540@ 1.86GHz=25.494|1861 MHz|Unknown
+AMD Turion(tm) 64 X2 TL-58=12.576|2x 800 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 3800+=10.707|2x 2200 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 6400+=6.421|2x 1000 MHz|Unknown
+Intel(R) Core(TM)2 Extreme CPU X7900@ 2.80GHz=6.809|2x 2800 MHz|Unknown
+Intel(R) Pentium(R) M processor 1.70GHz=28.279|600 MHz|Unknown
+AMD Phenom(tm) 8650 Triple-Core Processor=5.965|3x 2300 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.40GHz=24.567|2400 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 4400+=7.918|2x 1000 MHz|Unknown
+AMD Phenom(tm) II X4 940 Processor=3.488|4x 800 MHz|Unknown
+Pentium III (Coppermine)=17.808|2x 999 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 3.20GHz=12.058|2x 2400 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 1500MHz=46.556|1495 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-58=10.104|2x 1900 MHz|Unknown
+Intel(R) Celeron(R) M processor 1.40GHz=80.940|1395 MHz|Unknown
+Mobile AMD Athlon(tm) XP 2800+=18.040|1459 MHz|Unknown
+Intel(R) Celeron(R) CPU420@ 1.60GHz=21.238|1600 MHz|Unknown
+AMD Phenom(tm) 9750 Quad-Core Processor=4.291|4x 1200 MHz|Unknown
+Intel(R) Atom(TM) CPU N280 @ 1.66GHz=16.764|2x 1000 MHz|Unknown
+AMD Athlon(tm) X2 Dual-Core QL-60=10.585|2x 1900 MHz|Unknown
+Intel(R) Pentium(R) DualCPUT2370@ 1.73GHz=9.581|2x 1733 MHz|Unknown
+AMD Athlon(tm) XP 1900+=31.620|1593 MHz|Unknown
+AMD Athlon(tm) XP 1800+=23.128|1540 MHz|Unknown
+Intel(R) Pentium(R) M processor 1.73GHz=19.657|798 MHz|Unknown
+AMD Sempron(tm) Processor 3200+=25.468|1000 MHz|Unknown
+VIA Esther processor 1500MHz=41.594|1499 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ6700@ 2.66GHz=3.174|4x 2669 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 5000+=7.489|2x 1000 MHz|Unknown
+Intel(R) Xeon(R) CPU3040@ 1.86GHz=9.113|2x 1862 MHz|Unknown
+Intel(R) Pentium(R) DualCPUT2310@ 1.46GHz=11.596|2x 1463 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU P8400@ 2.26GHz=8.293|2x 800 MHz|Unknown
+AMD Turion(tm) X2 Dual-Core Mobile RM-74=8.970|2x 600 MHz|Unknown
+Genuine Intel(R) CPU 575@ 2.00GHz=20.357|1995 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-62=8.836|2x 800 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-56=10.790|2x 800 MHz|Unknown
+Intel(R) Celeron(R) CPU 2.80GHz=40.872|2793 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.80GHz=11.699|2x 2800 MHz|Unknown
+Genuine Intel(R) CPU2140@ 1.60GHz=10.672|2x 1595 MHz|Unknown
+AMD Athlon(tm) 7750 Dual-Core Processor=7.449|2x 1350 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU E8400@ 3.00GHz=5.538|2x 2997 MHz|Unknown
+Intel(R) Core(TM)2 CPU T7400@ 2.16GHz=9.372|2x 2161 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.53GHz=48.077|2525 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ9550@ 2.83GHz=3.244|4x 2830 MHz|Unknown
+Intel(R) Core(TM)2 CPU6700@ 2.66GHz=6.902|2x 2667 MHz|Unknown
+AMD Turion(tm) X2 Dual-Core Mobile RM-72=11.859|2x 500 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T9400@ 2.53GHz=6.757|2x 800 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 4800+=8.735|2x 2512 MHz|Unknown
+Intel(R) Celeron(R) M CPU520@ 1.60GHz=22.072|1600 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ8300@ 2.50GHz=3.346|4x 2497 MHz|Unknown
+PowerPC 740/750=172.816713|280.00 MHz|Unknown
+[CPU SHA1]
+[CPU MD5]
+[CPU Fibonacci]
+AMD Phenom(tm) 9500 Quad-Core Processor=3.061|4x 1100 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T7250@ 2.00GHz=4.572|2x 2001 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.80GHz=4.603|2x 2800 MHz|Unknown
+AMD Athlon(tm) Processor=7.342|1210 MHz|Unknown
+Intel(R) Core(TM)2 CPU T5200@ 1.60GHz=7.274|2x 1067 MHz|Unknown
+Intel(R) Atom(TM) CPU330 @ 1.60GHz=8.789|4x 1596 MHz|Unknown
+AMD Phenom(tm) 9150e Quad-Core Processor=3.281|4x 900 MHz|Unknown
+AMD Turion(tm) 64 Mobile Technology MK-36=6.202|800 MHz|Unknown
+AMD Athlon(tm) 64 Processor 3200+=5.764|1000 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ9400@ 2.66GHz=2.759|4x 2003 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T7500@ 2.20GHz=4.090|2x 800 MHz|Unknown
+AMD Athlon(tm) XP=33.451|906 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ6700@ 2.66GHz=3.537|4x 2669 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.00GHz=8.698|1994 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU E6550@ 2.33GHz=3.657|2x 2700 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T7100@ 1.80GHz=4.788|2x 1801 MHz|Unknown
+Dual Core AMD Opteron(tm) Processor 165=4.257|2x 1979 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.40GHz=6.348|2400 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU P8600@ 2.40GHz=3.374|2x 800 MHz|Unknown
+AMD Turion(tm) X2 Dual-Core Mobile RM-70=4.974|2x 500 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.53GHz=10.356|2525 MHz|Unknown
+Unknown CPU Type=5.728|1660 MHz|Unknown
+Pentium III (Coppermine)=10.217|2x 999 MHz|Unknown
+Intel(R) Core(TM)2 CPU T5600@ 1.83GHz=5.239|2x 1000 MHz|Unknown
+Intel(R) Celeron(R) CPU 3.06GHz=3.961|3059 MHz|Unknown
+AMD Phenom(tm) 9850 Quad-Core Processor=2.594|4x 1300 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 3.00GHz=4.977|2x 3458 MHz|Unknown
+AMD Sempron(tm) Processor LE-1200=6.085|2109 MHz|Unknown
+Intel(R) Pentium(R) 4 CPU 2.80GHz=5.654|2791 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 4000+=4.124|2x 1000 MHz|Unknown
+AMD Athlon(tm) XP 1600+=6.387|1398 MHz|Unknown
+Genuine Intel(R) CPU T2050@ 1.60GHz=6.104|2x 800 MHz|Unknown
+Intel(R) Celeron(R) CPU560@ 2.13GHz=4.776|2128 MHz|Unknown
+AMD Phenom(tm) 8650 Triple-Core Processor=3.093|3x 2300 MHz|Unknown
+Intel(R) Core(TM) i7 CPU 920@ 2.67GHz=2.787|8x 3799 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 5000+=3.110|2x 1000 MHz|Unknown
+AMD Athlon(tm) XP 2500+=7.183|1792 MHz|Unknown
+Intel(R) Xeon(R) CPU3040@ 1.86GHz=4.808|2x 1862 MHz|Unknown
+AMD Athlon(tm) X2 Dual-Core QL-60=4.354|2x 1900 MHz|Unknown
+Intel(R) Core(TM)2 CPU T7400@ 2.16GHz=4.984|2x 2161 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-60=4.189|2x 2000 MHz|Unknown
+AMD Turion(tm) 64 X2 Mobile Technology TL-52=5.447|2x 1600 MHz|Unknown
+AMD Athlon(tm) 64 X2 Dual Core Processor 6000+=2.747|2x 3051 MHz|Unknown
+Intel(R) Atom(TM) CPU N280 @ 1.66GHz=8.973|2x 1000 MHz|Unknown
+Intel(R) Core(TM)2 Quad CPUQ9550@ 2.83GHz=2.724|4x 2830 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU T7300@ 2.00GHz=4.773|2x 2001 MHz|Unknown
+AMD Sempron(tm) Processor 3600+=5.696|1000 MHz|Unknown
+AMD Athlon(tm)=4.475|2305 MHz|Unknown
+AMD Athlon(tm) X2 Dual Core Processor BE-2300=4.373|2x 1899 MHz|Unknown
+Intel(R) Core(TM)2 Duo CPU E6750@ 2.66GHz=4.096|2x 2671 MHz|Unknown
+PowerPC 740/750=58.07682|280.00 MHz|Unknown
+[CPU Zlib]
+PowerPC 740/750=2150.597408|280.00 MHz|Unknown
+[GPU Drawing]
diff --git a/benchmark.data b/benchmark.data
new file mode 100644
index 0000000..efb964d
Binary files /dev/null and b/benchmark.data differ
diff --git a/cmake/GNUInstallDirs.cmake b/cmake/GNUInstallDirs.cmake
new file mode 100644
index 0000000..8f55515
--- /dev/null
+++ b/cmake/GNUInstallDirs.cmake
@@ -0,0 +1,201 @@
+# - Define GNU standard installation directories
+# Provides install directory variables as defined for GNU software:
+#  https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+# Inclusion of this module defines the following variables:
+#  CMAKE_INSTALL_<dir>      - destination for files of a given type
+#  CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
+# where <dir> is one of:
+#  BINDIR           - user executables (bin)
+#  SBINDIR          - system admin executables (sbin)
+#  LIBEXECDIR       - program executables (libexec)
+#  SYSCONFDIR       - read-only single-machine data (etc)
+#  SHAREDSTATEDIR   - modifiable architecture-independent data (com)
+#  LOCALSTATEDIR    - modifiable single-machine data (var)
+#  LIBDIR           - object code libraries (lib or lib64)
+#  INCLUDEDIR       - C header files (include)
+#  OLDINCLUDEDIR    - C header files for non-gcc (/usr/include)
+#  DATAROOTDIR      - read-only architecture-independent data root (share)
+#  DATADIR          - read-only architecture-independent data (DATAROOTDIR)
+#  INFODIR          - info documentation (DATAROOTDIR/info)
+#  LOCALEDIR        - locale-dependent data (DATAROOTDIR/locale)
+#  MANDIR           - man documentation (DATAROOTDIR/man)
+#  DOCDIR           - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
+# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
+# install() commands for the corresponding file type.  If the includer does
+# not define a value the above-shown default will be used and the value will
+# appear in the cache for editing by the user.
+# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
+# from the corresponding destination by prepending (if necessary) the value
+# of CMAKE_INSTALL_PREFIX.
+
+#=============================================================================
+# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
+# Copyright 2011 Kitware, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+#
+# * Neither the name of Kitware, Inc. nor the names of Contributors
+#   may be used to endorse or promote products derived from this
+#   software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#=============================================================================
+
+# Installation directories
+#
+if(NOT DEFINED CMAKE_INSTALL_BINDIR)
+  set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_SBINDIR)
+  set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR)
+  set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
+  set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR)
+  set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
+  set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
+  set(_LIBDIR_DEFAULT "lib")
+  # Override this default 'lib' with 'lib64' iff:
+  #  - we are on Linux system but NOT cross-compiling
+  #  - we are NOT on debian
+  #  - we are on a 64 bits system
+  # reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
+  # Note that the future of multi-arch handling may be even
+  # more complicated than that: https://wiki.debian.org/Multiarch
+  if(CMAKE_SYSTEM_NAME MATCHES "Linux"
+      AND NOT CMAKE_CROSSCOMPILING
+      AND NOT EXISTS "/etc/debian_version")
+    if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
+      message(AUTHOR_WARNING
+        "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
+        "Please enable at least one language before including GNUInstallDirs.")
+    else()
+      if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+        set(_LIBDIR_DEFAULT "lib64")
+      endif()
+    endif()
+  endif()
+  set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
+  set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR)
+  set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR)
+  set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)")
+endif()
+
+#-----------------------------------------------------------------------------
+# Values whose defaults are relative to DATAROOTDIR.  Store empty values in
+# the cache and store the defaults in local variables if the cache values are
+# not set explicitly.  This auto-updates the defaults as DATAROOTDIR changes.
+
+if(NOT CMAKE_INSTALL_DATADIR)
+  set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)")
+  set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}")
+endif()
+
+if(NOT CMAKE_INSTALL_INFODIR)
+  set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
+  set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
+endif()
+
+if(NOT CMAKE_INSTALL_LOCALEDIR)
+  set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)")
+  set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale")
+endif()
+
+if(NOT CMAKE_INSTALL_MANDIR)
+  set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
+  set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
+endif()
+
+if(NOT CMAKE_INSTALL_DOCDIR)
+  set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)")
+  set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}")
+endif()
+
+#-----------------------------------------------------------------------------
+
+mark_as_advanced(
+  CMAKE_INSTALL_BINDIR
+  CMAKE_INSTALL_SBINDIR
+  CMAKE_INSTALL_LIBEXECDIR
+  CMAKE_INSTALL_SYSCONFDIR
+  CMAKE_INSTALL_SHAREDSTATEDIR
+  CMAKE_INSTALL_LOCALSTATEDIR
+  CMAKE_INSTALL_LIBDIR
+  CMAKE_INSTALL_INCLUDEDIR
+  CMAKE_INSTALL_OLDINCLUDEDIR
+  CMAKE_INSTALL_DATAROOTDIR
+  CMAKE_INSTALL_DATADIR
+  CMAKE_INSTALL_INFODIR
+  CMAKE_INSTALL_LOCALEDIR
+  CMAKE_INSTALL_MANDIR
+  CMAKE_INSTALL_DOCDIR
+  )
+
+# Result directories
+#
+foreach(dir
+    BINDIR
+    SBINDIR
+    LIBEXECDIR
+    SYSCONFDIR
+    SHAREDSTATEDIR
+    LOCALSTATEDIR
+    LIBDIR
+    INCLUDEDIR
+    OLDINCLUDEDIR
+    DATAROOTDIR
+    DATADIR
+    INFODIR
+    LOCALEDIR
+    MANDIR
+    DOCDIR
+    )
+  if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
+    set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
+  else()
+    set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
+  endif()
+endforeach()
diff --git a/cmake/Translations.cmake b/cmake/Translations.cmake
new file mode 100644
index 0000000..dd06cee
--- /dev/null
+++ b/cmake/Translations.cmake
@@ -0,0 +1,40 @@
+# Translations.cmake, CMake macros written for Marlin, feel free to re-use them
+
+macro(add_translations_directory NLS_PACKAGE)
+    add_custom_target (i18n ALL COMMENT “Building i18n messages.”)
+    find_program (MSGFMT_EXECUTABLE msgfmt)
+    file (GLOB PO_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.po)
+    foreach (PO_INPUT ${PO_FILES})
+        get_filename_component (PO_INPUT_BASE ${PO_INPUT} NAME_WE)
+        set (MO_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PO_INPUT_BASE}.mo)
+        add_custom_command (TARGET i18n COMMAND ${MSGFMT_EXECUTABLE} -o ${MO_OUTPUT} ${PO_INPUT})
+
+        install (FILES ${MO_OUTPUT} DESTINATION
+            share/locale/${PO_INPUT_BASE}/LC_MESSAGES
+            RENAME ${NLS_PACKAGE}.mo)
+    endforeach (PO_INPUT ${PO_FILES})
+endmacro(add_translations_directory)
+
+
+macro(add_translations_catalog NLS_PACKAGE)
+    add_custom_target (pot COMMENT “Building translation catalog.”)
+    find_program (XGETTEXT_EXECUTABLE xgettext)
+
+    set(C_SOURCE "")
+
+    foreach(FILES_INPUT ${ARGN})
+        file (GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${FILES_INPUT}/*.c)
+        foreach(C_FILE ${SOURCE_FILES})
+            set(C_SOURCE ${C_SOURCE} ${C_FILE})
+        endforeach()
+        file (GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${FILES_INPUT}/*.vala)
+        foreach(C_FILE ${SOURCE_FILES})
+            set(C_SOURCE ${C_SOURCE} ${C_FILE})
+        endforeach()
+    endforeach()
+
+    add_custom_command (TARGET pot COMMAND
+        ${XGETTEXT_EXECUTABLE} -d ${NLS_PACKAGE} -o ${CMAKE_CURRENT_SOURCE_DIR}/${NLS_PACKAGE}.pot
+        ${VALA_SOURCE} ${C_SOURCE} -k_ -kN_ -kC_:1c,2 -kNC_:1c,2 -c/ --from-code=UTF-8
+        )
+endmacro()
diff --git a/config.h.cmake b/config.h.cmake
new file mode 100644
index 0000000..496f753
--- /dev/null
+++ b/config.h.cmake
@@ -0,0 +1,36 @@
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define VERSION			"@HARDINFO_VERSION@"
+
+#define ARCH			"ARCH_@HARDINFO_ARCH@"
+#define OS			"@HARDINFO_OS@"
+#define PLATFORM		OS "-" ARCH
+#define KERNEL			""
+#define HOSTNAME		""
+#define ARCH_@HARDINFO_ARCH@
+
+#define LIBDIR			"@CMAKE_INSTALL_LIBDIR@"
+#define LIBPREFIX		"@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/hardinfo"
+#define PREFIX			"@CMAKE_INSTALL_PREFIX@/share/hardinfo"
+
+#cmakedefine LIBSOUP_FOUND
+#cmakedefine HARDINFO_DEBUG	@HARDINFO_DEBUG@
+
+#ifdef LIBSOUP_FOUND
+#	define HAS_LIBSOUP
+#endif	/* LIBSOUP_FOUND */
+
+#if defined(HARDINFO_DEBUG) && (HARDINFO_DEBUG==1)
+#	define RELEASE 0
+#	define DEBUG(msg,...) fprintf(stderr, "*** %s:%d (%s) *** " msg "\n", \
+        	           __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
+#else
+#	define RELEASE 1
+#	define DEBUG(msg,...)
+#endif	/* HARDINFO_DEBUG */
+
+#define ENABLE_BINRELOC 1
+#define HAS_LINUX_WE 1
+
+#endif	/* __CONFIG_H__ */
diff --git a/debian/changelog b/debian/changelog
index f6eb8d6..2c52ae3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+hardinfo (0.5.1+git20180227-2.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * Fix ftbfs with GCC-10. (Closes: #957327)
+
+ -- Sudip Mukherjee <sudipm.mukherjee@gmail.com>  Sun, 09 Aug 2020 22:16:41 +0100
+
 hardinfo (0.5.1+git20180227-2) unstable; urgency=medium
 
   * Change my email to tsimonq2@debian.org now that I am a Debian Developer.
diff --git a/debian/patches/fix_ftbfs.patch b/debian/patches/fix_ftbfs.patch
new file mode 100644
index 0000000..b60306a
--- /dev/null
+++ b/debian/patches/fix_ftbfs.patch
@@ -0,0 +1,29 @@
+Description: Fix ftbfs with GCC-10
+ The enum variable is not used, use that as the enum name to declare it.
+
+Author: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Bug-Debian: https://bugs.debian.org/957327
+Forwarded: no
+
+---
+
+--- hardinfo-0.5.1+git20180227.orig/includes/benchmark.h
++++ hardinfo-0.5.1+git20180227/includes/benchmark.h
+@@ -5,7 +5,7 @@
+ 
+ extern ProgramParameters params;
+ 
+-enum {
++enum BenchmarkEntries {
+     BENCHMARK_BLOWFISH,
+     BENCHMARK_CRYPTOHASH,
+     BENCHMARK_FIB,
+@@ -15,7 +15,7 @@ enum {
+     BENCHMARK_RAYTRACE,
+     BENCHMARK_GUI,
+     BENCHMARK_N_ENTRIES
+-} BenchmarkEntries;
++};
+ 
+ void benchmark_bfish(void);
+ void benchmark_cryptohash(void);
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..54778ff
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1 @@
+fix_ftbfs.patch
diff --git a/doc/index.hlp b/doc/index.hlp
new file mode 100644
index 0000000..649a7a4
--- /dev/null
+++ b/doc/index.hlp
@@ -0,0 +1,35 @@
+# HardInfo Documentation
+
+## Introduction
+
+HardInfo can gather information about your system's hardware and operating system, perform benchmarks, and generate printable reports either in HTML or in plain text formats.
+
+## Feature Overview
+
+* Obtains information about basic hardware items;
+* Obtains information about basic operating system items;
+* Performs CPU and FPU benchmarks;
+* Allows [network-updater.hlp synchronization of benchmark results] with other HardInfo users;
+* Some tables can be [network-updater.hlp updated] from the Internet;
+* Can be used either in local or in [remote.hlp remote] mode;
+* Generates repots in HTML or plain text formats;
+* Can be used either with a GTK+ GUI or on a terminal.
+
+## Using
+
+* [report-generation.hlp Generating Reports]
+* [network-updater.hlp Using the Network Updater]
+* [remote.hlp Obtaining Information from a Remote Machine]
+* [benchmark.hlp Performing and Understanding Benchmarks]
+* [command-line.hlp Using HardInfo from the command line]
+
+## Improving
+
+* [bug-reporting.hlp How to Report Bugs]
+* [feature-requests.hlp How to Request a Feature]
+* [http://hardinfo.org/developer Developer Documentation]
+
+## Following
+
+* [https://twitter.com/hardinfo Twitter] (for GitHub commits)
+* [http://lists.hardinfo.org Mailing Lists]
diff --git a/hardinfo.1 b/hardinfo.1
new file mode 100644
index 0000000..2425457
--- /dev/null
+++ b/hardinfo.1
@@ -0,0 +1,69 @@
+.\" Manpage for hardinfo.
+.\" https://github.com/lpereira/hardinfo/.
+.TH HARDINFO "1" "July 2017" "0.6" "User Commands"
+.SH NAME
+\fBHardInfo\fR \- System profiler and benchmark for Linux systems.
+.SH USAGE
+\fBhardinfo\fR [OPTION...]
+.SH DESCRIPTION
+Is a system profiler and benchmark for Linux systems, that gathers information about the 
+hardware and operating system, performs benchmarks, and generates reports.  
+The information gathered is presented on an simple and intuitive GUI.
+
+Information is grouped in \fIfour main groups\fR: \fBComputer\fR, \fBDevices\fR, \fBNetwork\fR, and \fBBenchmarks\fR.
+
+The \fBComputer group\fR contains mostly information about basic software.  This includes but
+is not limited to information about the operating system (kernel version, C library,
+distribution, etc.), kernel modules, locale information, filesystem usage, users/groups, and
+development tools.
+
+The \fBDevices group\fR contains information about the hardware, as detected by the operating
+system.  \fBHardinfo\fR is incapable of detecting hardware by itself, it merely lists what the
+operating system was able to find.  This includes, but does not limit to, information about the
+processor (including cache layout, known bugs, and feature flags with their explanation),
+devices (such as USB, PCI, and Input devices), among other things.
+
+The \fBNetwork group\fR lists information about network interfaces, routing table, DNS servers,
+and other networking-related topics.
+
+The \fBBenchmarks group\fR allow performing simple benchmarks to test CPU and FPU capabilities,
+as well as some of the graphical user interface capabilities as well.  In previous versions, it
+was possible to send the benchmark results to a central server, so it was possible to compare
+the benchmarks with other \fBHardinfo\fR users; this service has been deactivated in the mean time.
+
+\fIReports\fR can be generated either by invoking \fBHardinfo\fR with special command-line parameters
+(see below), or by clicking the "Generate Report" button in the GUI.  Reports can be customized
+in the GUI and saved in either HTML or plain text formats.
+
+.SH OPTIONS
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Show help options
+.TP
+\fB\-r\fR, \fB\-\-generate\-report\fR
+creates a report and prints to standard output
+.TP
+\fB\-f\fR, \fB\-\-report\-format\fR
+chooses a report format (text, html)
+.TP
+\fB\-b\fR, \fB\-\-run\-benchmark\fR
+run benchmark; requires benchmark.so to be loaded
+.TP
+\fB\-l\fR, \fB\-\-list\-modules\fR
+lists modules
+.TP
+\fB\-m\fR, \fB\-\-load\-module\fR
+specify module to load
+.TP
+\fB\-a\fR, \fB\-\-autoload\-deps\fR
+automatically load module dependencies
+.TP
+\fB\-v\fR, \fB\-\-version\fR
+shows program version and quit
+.SH AUTHORS/CONTRIBUTORS
+For current maintainers committing, see AUTHORS.md file and more info are at \fIhttps://github.com/lpereira/hardinfo/graphs/contributors\fR . 
+More contributions are in each files source headers.
+.SH COPYRIGHT
+\fBHardInfo\fR its Copyright \(co 2003, 2009\-2017 Leandro A. F. Pereira \fI<leandro@hardinfo.org>\fR.
+This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+This manpage was created by PICCORO Lenz McKAY \fI<mckaygerhard@gmail.com>\fR for the hardinfo project.
diff --git a/hardinfo.desktop.cmake b/hardinfo.desktop.cmake
new file mode 100644
index 0000000..53dbee5
--- /dev/null
+++ b/hardinfo.desktop.cmake
@@ -0,0 +1,15 @@
+[Desktop Entry]
+Name=System Profiler and Benchmark
+Name[es]=Informacion y Rendimiento del Sistema
+Name[fr]=Informations et Benchmarks du Système
+Name[pt_BR]=Informações e Testes do Sistema
+Name[ru]=Информация о системе и тестирование
+Comment=Displays system information
+Comment[ru]=Показывает информацию о системе
+Exec=@CMAKE_INSTALL_FULL_BINDIR@/hardinfo
+Icon=@CMAKE_INSTALL_FULL_DATAROOTDIR@/hardinfo/pixmaps/logo.png
+Terminal=false
+Type=Application
+StartupNotify=true
+Categories=System;
+Keywords=linux;kernel;system;hardware;cpu;processor;capabilities;frequency;memory;ram;board;resources;sensors;devices;usb;pci;display;network;benchmark;test;
diff --git a/hardinfo/binreloc.c b/hardinfo/binreloc.c
new file mode 100644
index 0000000..f47a3fa
--- /dev/null
+++ b/hardinfo/binreloc.c
@@ -0,0 +1,668 @@
+/*
+ * BinReloc - a library for creating relocatable executables
+ * Written by: Hongli Lai <h.lai@chello.nl>
+ * http://autopackage.org/
+ *
+ * This source code is public domain. You can relicense this code
+ * under whatever license you want.
+ *
+ * See http://autopackage.org/docs/binreloc/ for
+ * more information and how to use this.
+ */
+
+#ifndef __BINRELOC_C__
+#define __BINRELOC_C__
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include "binreloc.h"
+#include "config.h"
+
+G_BEGIN_DECLS
+/** @internal
+ * Find the canonical filename of the executable. Returns the filename
+ * (which must be freed) or NULL on error. If the parameter 'error' is
+ * not NULL, the error code will be stored there, if an error occured.
+ */
+static char *_br_find_exe(GbrInitError * error)
+{
+    char *path, *path2, *line, *result;
+    size_t buf_size;
+    ssize_t size;
+    struct stat stat_buf;
+    FILE *f;
+
+    /* Read from /proc/self/exe (symlink) */
+    if (sizeof(path) > SSIZE_MAX)
+	buf_size = SSIZE_MAX - 1;
+    else
+	buf_size = PATH_MAX - 1;
+    path = (char *) g_try_malloc(buf_size);
+    if (path == NULL) {
+	/* Cannot allocate memory. */
+	if (error)
+	    *error = GBR_INIT_ERROR_NOMEM;
+	return NULL;
+    }
+    path2 = (char *) g_try_malloc(buf_size);
+    if (path2 == NULL) {
+	/* Cannot allocate memory. */
+	if (error)
+	    *error = GBR_INIT_ERROR_NOMEM;
+	g_free(path);
+	return NULL;
+    }
+
+    strncpy(path2, "/proc/self/exe", buf_size - 1);
+
+    while (1) {
+	int i;
+
+	size = readlink(path2, path, buf_size - 1);
+	if (size == -1) {
+	    /* Error. */
+	    g_free(path2);
+	    break;
+	}
+
+	/* readlink() success. */
+	path[size] = '\0';
+
+	/* Check whether the symlink's target is also a symlink.
+	 * We want to get the final target. */
+	i = stat(path, &stat_buf);
+	if (i == -1) {
+	    /* Error. */
+	    g_free(path2);
+	    break;
+	}
+
+	/* stat() success. */
+	if (!S_ISLNK(stat_buf.st_mode)) {
+	    /* path is not a symlink. Done. */
+	    g_free(path2);
+	    return path;
+	}
+
+	/* path is a symlink. Continue loop and resolve this. */
+	strncpy(path, path2, buf_size - 1);
+    }
+
+
+    /* readlink() or stat() failed; this can happen when the program is
+     * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
+
+    buf_size = PATH_MAX + 128;
+    line = (char *) g_try_realloc(path, buf_size);
+    if (line == NULL) {
+	/* Cannot allocate memory. */
+	g_free(path);
+	if (error)
+	    *error = GBR_INIT_ERROR_NOMEM;
+	return NULL;
+    }
+
+    f = fopen("/proc/self/maps", "r");
+    if (f == NULL) {
+	g_free(line);
+	if (error)
+	    *error = GBR_INIT_ERROR_OPEN_MAPS;
+	return NULL;
+    }
+
+    /* The first entry should be the executable name. */
+    result = fgets(line, (int) buf_size, f);
+    if (result == NULL) {
+	fclose(f);
+	g_free(line);
+	if (error)
+	    *error = GBR_INIT_ERROR_READ_MAPS;
+	return NULL;
+    }
+
+    /* Get rid of newline character. */
+    buf_size = strlen(line);
+    if (buf_size <= 0) {
+	/* Huh? An empty string? */
+	fclose(f);
+	g_free(line);
+	if (error)
+	    *error = GBR_INIT_ERROR_INVALID_MAPS;
+	return NULL;
+    }
+    if (line[buf_size - 1] == 10)
+	line[buf_size - 1] = 0;
+
+    /* Extract the filename; it is always an absolute path. */
+    path = strchr(line, '/');
+
+    /* Sanity check. */
+    if (strstr(line, " r-xp ") == NULL || path == NULL) {
+	fclose(f);
+	g_free(line);
+	if (error)
+	    *error = GBR_INIT_ERROR_INVALID_MAPS;
+	return NULL;
+    }
+
+    path = g_strdup(path);
+    g_free(line);
+    fclose(f);
+    return path;
+}
+
+
+/** @internal
+ * Find the canonical filename of the executable which owns symbol.
+ * Returns a filename which must be freed, or NULL on error.
+ */
+static char *_br_find_exe_for_symbol(const void *symbol,
+				     GbrInitError * error)
+{
+#define SIZE PATH_MAX + 100
+    FILE *f;
+    size_t address_string_len;
+    char *address_string, line[SIZE], *found;
+
+    if (symbol == NULL)
+	return (char *) NULL;
+
+    f = fopen("/proc/self/maps", "r");
+    if (f == NULL)
+	return (char *) NULL;
+
+    address_string_len = 4;
+    address_string = (char *) g_try_malloc(address_string_len);
+    found = (char *) NULL;
+
+    while (!feof(f)) {
+	char *start_addr, *end_addr, *end_addr_end, *file;
+	void *start_addr_p, *end_addr_p;
+	size_t len;
+
+	if (fgets(line, SIZE, f) == NULL)
+	    break;
+
+	/* Sanity check. */
+	if (strstr(line, " r-xp ") == NULL || strchr(line, '/') == NULL)
+	    continue;
+
+	/* Parse line. */
+	start_addr = line;
+	end_addr = strchr(line, '-');
+	file = strchr(line, '/');
+
+	/* More sanity check. */
+	if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
+	    continue;
+
+	end_addr[0] = '\0';
+	end_addr++;
+	end_addr_end = strchr(end_addr, ' ');
+	if (end_addr_end == NULL)
+	    continue;
+
+	end_addr_end[0] = '\0';
+	len = strlen(file);
+	if (len == 0)
+	    continue;
+	if (file[len - 1] == '\n')
+	    file[len - 1] = '\0';
+
+	/* Get rid of "(deleted)" from the filename. */
+	len = strlen(file);
+	if (len > 10 && strcmp(file + len - 10, " (deleted)") == 0)
+	    file[len - 10] = '\0';
+
+	/* I don't know whether this can happen but better safe than sorry. */
+	len = strlen(start_addr);
+	if (len != strlen(end_addr))
+	    continue;
+
+
+	/* Transform the addresses into a string in the form of 0xdeadbeef,
+	 * then transform that into a pointer. */
+	if (address_string_len < len + 3) {
+	    address_string_len = len + 3;
+	    address_string =
+		(char *) g_try_realloc(address_string, address_string_len);
+	}
+
+	memcpy(address_string, "0x", 2);
+	memcpy(address_string + 2, start_addr, len);
+	address_string[2 + len] = '\0';
+	sscanf(address_string, "%p", &start_addr_p);
+
+	memcpy(address_string, "0x", 2);
+	memcpy(address_string + 2, end_addr, len);
+	address_string[2 + len] = '\0';
+	sscanf(address_string, "%p", &end_addr_p);
+
+
+	if (symbol >= start_addr_p && symbol < end_addr_p) {
+	    found = file;
+	    break;
+	}
+    }
+
+    g_free(address_string);
+    fclose(f);
+
+    if (found == NULL)
+	return (char *) NULL;
+    else
+	return g_strdup(found);
+}
+
+
+static gchar *exe = NULL;
+
+static void set_gerror(GError ** error, GbrInitError errcode);
+
+
+/** Initialize the BinReloc library (for applications).
+ *
+ * This function must be called before using any other BinReloc functions.
+ * It attempts to locate the application's canonical filename.
+ *
+ * @note If you want to use BinReloc for a library, then you should call
+ *       gbr_init_lib() instead.
+ *
+ * @param error  If BinReloc failed to initialize, then the error report will
+ *               be stored in this variable. Set to NULL if you don't want an
+ *               error report. See the #GbrInitError for a list of error
+ *               codes.
+ *
+ * @returns TRUE on success, FALSE if BinReloc failed to initialize.
+ */
+gboolean gbr_init(GError ** error)
+{
+    GbrInitError errcode = 0;
+
+    /* Locate the application's filename. */
+    exe = _br_find_exe(&errcode);
+    if (exe != NULL)
+	/* Success! */
+	return TRUE;
+    else {
+	/* Failed :-( */
+	set_gerror(error, errcode);
+	return FALSE;
+    }
+}
+
+
+/** Initialize the BinReloc library (for libraries).
+ *
+ * This function must be called before using any other BinReloc functions.
+ * It attempts to locate the calling library's canonical filename.
+ *
+ * @note The BinReloc source code MUST be included in your library, or this
+ *       function won't work correctly.
+ *
+ * @returns TRUE on success, FALSE if a filename cannot be found.
+ */
+gboolean gbr_init_lib(GError ** error)
+{
+    GbrInitError errcode = 0;
+
+    exe = _br_find_exe_for_symbol((const void *) "", &errcode);
+    if (exe != NULL)
+	/* Success! */
+	return TRUE;
+    else {
+	/* Failed :-( */
+	set_gerror(error, errcode);
+	return exe != NULL;
+    }
+}
+
+
+static void set_gerror(GError ** error, GbrInitError errcode)
+{
+    gchar *error_message;
+
+    if (error == NULL)
+	return;
+
+    switch (errcode) {
+    case GBR_INIT_ERROR_NOMEM:
+	error_message = "Cannot allocate memory.";
+	break;
+    case GBR_INIT_ERROR_OPEN_MAPS:
+	error_message = "Unable to open /proc/self/maps for reading.";
+	break;
+    case GBR_INIT_ERROR_READ_MAPS:
+	error_message = "Unable to read from /proc/self/maps.";
+	break;
+    case GBR_INIT_ERROR_INVALID_MAPS:
+	error_message = "The file format of /proc/self/maps is invalid.";
+	break;
+    case GBR_INIT_ERROR_DISABLED:
+	error_message = "Binary relocation support is disabled.";
+	break;
+    default:
+	error_message = "Unknown error.";
+	break;
+    };
+    g_set_error(error, g_quark_from_static_string("GBinReloc"),
+		errcode, "%s", error_message);
+}
+
+
+/** Find the canonical filename of the current application.
+ *
+ * @param default_exe  A default filename which will be used as fallback.
+ * @returns A string containing the application's canonical filename,
+ *          which must be freed when no longer necessary. If BinReloc is
+ *          not initialized, or if the initialization function failed,
+ *          then a copy of default_exe will be returned. If default_exe
+ *          is NULL, then NULL will be returned.
+ */
+gchar *gbr_find_exe(const gchar * default_exe)
+{
+    if (exe == NULL) {
+	/* BinReloc is not initialized. */
+	if (default_exe != NULL)
+	    return g_strdup(default_exe);
+	else
+	    return NULL;
+    }
+    return g_strdup(exe);
+}
+
+
+/** Locate the directory in which the current application is installed.
+ *
+ * The prefix is generated by the following pseudo-code evaluation:
+ * \code
+ * dirname(exename)
+ * \endcode
+ *
+ * @param default_dir  A default directory which will used as fallback.
+ * @return A string containing the directory, which must be freed when no
+ *         longer necessary. If BinReloc is not initialized, or if the
+ *         initialization function failed, then a copy of default_dir
+ *         will be returned. If default_dir is NULL, then NULL will be
+ *         returned.
+ */
+gchar *gbr_find_exe_dir(const gchar * default_dir)
+{
+    if (exe == NULL) {
+	/* BinReloc not initialized. */
+	if (default_dir != NULL)
+	    return g_strdup(default_dir);
+	else
+	    return NULL;
+    }
+
+    return g_path_get_dirname(exe);
+}
+
+
+/** Locate the prefix in which the current application is installed.
+ *
+ * The prefix is generated by the following pseudo-code evaluation:
+ * \code
+ * dirname(dirname(exename))
+ * \endcode
+ *
+ * @param default_prefix  A default prefix which will used as fallback.
+ * @return A string containing the prefix, which must be freed when no
+ *         longer necessary. If BinReloc is not initialized, or if the
+ *         initialization function failed, then a copy of default_prefix
+ *         will be returned. If default_prefix is NULL, then NULL will be
+ *         returned.
+ */
+gchar *gbr_find_prefix(const gchar * default_prefix)
+{
+    gchar *dir1, *dir2;
+
+    if (exe == NULL) {
+	/* BinReloc not initialized. */
+	if (default_prefix != NULL)
+	    return g_strdup(default_prefix);
+	else
+	    return NULL;
+    }
+
+    dir1 = g_path_get_dirname(exe);
+    dir2 = g_path_get_dirname(dir1);
+    g_free(dir1);
+    return dir2;
+}
+
+
+/** Locate the application's binary folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/bin"
+ * \endcode
+ *
+ * @param default_bin_dir  A default path which will used as fallback.
+ * @return A string containing the bin folder's path, which must be freed when
+ *         no longer necessary. If BinReloc is not initialized, or if the
+ *         initialization function failed, then a copy of default_bin_dir will
+ *         be returned. If default_bin_dir is NULL, then NULL will be returned.
+ */
+gchar *gbr_find_bin_dir(const gchar * default_bin_dir)
+{
+    gchar *prefix, *dir;
+
+    prefix = gbr_find_prefix(NULL);
+    if (prefix == NULL) {
+	/* BinReloc not initialized. */
+	if (default_bin_dir != NULL)
+	    return g_strdup(default_bin_dir);
+	else
+	    return NULL;
+    }
+
+    dir = g_build_filename(prefix, "bin", NULL);
+    g_free(prefix);
+    return dir;
+}
+
+
+/** Locate the application's superuser binary folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/sbin"
+ * \endcode
+ *
+ * @param default_sbin_dir  A default path which will used as fallback.
+ * @return A string containing the sbin folder's path, which must be freed when
+ *         no longer necessary. If BinReloc is not initialized, or if the
+ *         initialization function failed, then a copy of default_sbin_dir will
+ *         be returned. If default_bin_dir is NULL, then NULL will be returned.
+ */
+gchar *gbr_find_sbin_dir(const gchar * default_sbin_dir)
+{
+    gchar *prefix, *dir;
+
+    prefix = gbr_find_prefix(NULL);
+    if (prefix == NULL) {
+	/* BinReloc not initialized. */
+	if (default_sbin_dir != NULL)
+	    return g_strdup(default_sbin_dir);
+	else
+	    return NULL;
+    }
+
+    dir = g_build_filename(prefix, "sbin", NULL);
+    g_free(prefix);
+    return dir;
+}
+
+
+/** Locate the application's data folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/share"
+ * \endcode
+ *
+ * @param default_data_dir  A default path which will used as fallback.
+ * @return A string containing the data folder's path, which must be freed when
+ *         no longer necessary. If BinReloc is not initialized, or if the
+ *         initialization function failed, then a copy of default_data_dir
+ *         will be returned. If default_data_dir is NULL, then NULL will be
+ *         returned.
+ */
+gchar *gbr_find_data_dir(const gchar * default_data_dir)
+{
+    gchar *prefix, *dir;
+
+    prefix = gbr_find_prefix(NULL);
+    if (prefix == NULL) {
+	/* BinReloc not initialized. */
+	if (default_data_dir != NULL)
+	    return g_strdup(default_data_dir);
+	else
+	    return NULL;
+    }
+
+    dir = g_build_filename(prefix, "share", NULL);
+    g_free(prefix);
+    return dir;
+}
+
+
+/** Locate the application's localization folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/share/locale"
+ * \endcode
+ *
+ * @param default_locale_dir  A default path which will used as fallback.
+ * @return A string containing the localization folder's path, which must be freed when
+ *         no longer necessary. If BinReloc is not initialized, or if the
+ *         initialization function failed, then a copy of default_locale_dir will be returned.
+ *         If default_locale_dir is NULL, then NULL will be returned.
+ */
+gchar *gbr_find_locale_dir(const gchar * default_locale_dir)
+{
+    gchar *data_dir, *dir;
+
+    data_dir = gbr_find_data_dir(NULL);
+    if (data_dir == NULL) {
+	/* BinReloc not initialized. */
+	if (default_locale_dir != NULL)
+	    return g_strdup(default_locale_dir);
+	else
+	    return NULL;
+    }
+
+    dir = g_build_filename(data_dir, "locale", NULL);
+    g_free(data_dir);
+    return dir;
+}
+
+
+/** Locate the application's library folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/lib"
+ * \endcode
+ *
+ * @param default_lib_dir  A default path which will used as fallback.
+ * @return A string containing the library folder's path, which must be freed when
+ *         no longer necessary. If BinReloc is not initialized, or if the
+ *         initialization function failed, then a copy of default_lib_dir will be returned.
+ *         If default_lib_dir is NULL, then NULL will be returned.
+ */
+gchar *gbr_find_lib_dir(const gchar * default_lib_dir)
+{
+    gchar *prefix, *dir;
+
+    prefix = gbr_find_prefix(NULL);
+    if (prefix == NULL) {
+	/* BinReloc not initialized. */
+	if (default_lib_dir != NULL)
+	    return g_strdup(default_lib_dir);
+	else
+	    return NULL;
+    }
+
+    dir = g_build_filename(prefix, LIBDIR, NULL);
+
+    g_free(prefix);
+    return dir;
+}
+
+
+/** Locate the application's libexec folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/libexec"
+ * \endcode
+ *
+ * @param default_libexec_dir  A default path which will used as fallback.
+ * @return A string containing the libexec folder's path, which must be freed when
+ *         no longer necessary. If BinReloc is not initialized, or if the initialization
+ *         function failed, then a copy of default_libexec_dir will be returned.
+ *         If default_libexec_dir is NULL, then NULL will be returned.
+ */
+gchar *gbr_find_libexec_dir(const gchar * default_libexec_dir)
+{
+    gchar *prefix, *dir;
+
+    prefix = gbr_find_prefix(NULL);
+    if (prefix == NULL) {
+	/* BinReloc not initialized. */
+	if (default_libexec_dir != NULL)
+	    return g_strdup(default_libexec_dir);
+	else
+	    return NULL;
+    }
+
+    dir = g_build_filename(prefix, "libexec", NULL);
+    g_free(prefix);
+    return dir;
+}
+
+
+/** Locate the application's configuration files folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/etc"
+ * \endcode
+ *
+ * @param default_etc_dir  A default path which will used as fallback.
+ * @return A string containing the etc folder's path, which must be freed when
+ *         no longer necessary. If BinReloc is not initialized, or if the initialization
+ *         function failed, then a copy of default_etc_dir will be returned.
+ *         If default_etc_dir is NULL, then NULL will be returned.
+ */
+gchar *gbr_find_etc_dir(const gchar * default_etc_dir)
+{
+    gchar *prefix, *dir;
+
+    prefix = gbr_find_prefix(NULL);
+    if (prefix == NULL) {
+	/* BinReloc not initialized. */
+	if (default_etc_dir != NULL)
+	    return g_strdup(default_etc_dir);
+	else
+	    return NULL;
+    }
+
+    dir = g_build_filename(prefix, "etc", NULL);
+    g_free(prefix);
+    return dir;
+}
+
+
+G_END_DECLS
+#endif				/* __BINRELOC_C__ */
diff --git a/hardinfo/cpu_util.c b/hardinfo/cpu_util.c
new file mode 100644
index 0000000..a598d2e
--- /dev/null
+++ b/hardinfo/cpu_util.c
@@ -0,0 +1,231 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *    This file by Burt P. <pburt0@gmail.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+#include "hardinfo.h"
+#include "cpu_util.h"
+
+#include "cpubits.c"
+
+#define CPU_TOPO_NULL -9877
+
+const gchar *byte_order_str() {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+    return _("Little Endian");
+#else
+    return _("Big Endian");
+#endif
+}
+
+int processor_has_flag(gchar * strflags, gchar * strflag)
+{
+    gchar **flags;
+    gint ret = 0;
+    if (strflags == NULL || strflag == NULL)
+        return 0;
+    flags = g_strsplit(strflags, " ", 0);
+    ret = g_strv_contains((const gchar * const *)flags, strflag);
+    g_strfreev(flags);
+    return ret;
+}
+
+gchar* get_cpu_str(const gchar* file, gint cpuid) {
+    gchar *tmp0 = NULL;
+    gchar *tmp1 = NULL;
+    tmp0 = g_strdup_printf("/sys/devices/system/cpu/cpu%d/%s", cpuid, file);
+    g_file_get_contents(tmp0, &tmp1, NULL, NULL);
+    g_free(tmp0);
+    return tmp1;
+}
+
+gint get_cpu_int(const char* item, int cpuid, int null_val) {
+    gchar *fc = NULL;
+    int ret = null_val;
+    fc = get_cpu_str(item, cpuid);
+    if (fc) {
+        ret = atol(fc);
+        g_free(fc);
+    }
+    return ret;
+}
+
+/* cpubits is 32768 bits long
+ * core_ids are not unique among physical_ids
+ * hack up cpubits into 128 packs of 256 cores
+ * to make cores unique in cpubits */
+#define MAX_CORES_PER_PACK 256
+#define MAX_PACKS 128
+
+int cpu_procs_cores_threads(int *p, int *c, int *t) {
+    cpubits *threads, *cores, *packs;
+    char *tmp;
+    int i, m, pack_id, core_id;
+    g_file_get_contents("/sys/devices/system/cpu/present", &tmp, NULL, NULL);
+    if (tmp != NULL) {
+        threads = cpubits_from_str(tmp);
+        cores = cpubits_from_str("");
+        packs = cpubits_from_str("");
+        m = cpubits_max(threads);
+        for (i = 0; i <= m; i++) {
+            pack_id = get_cpu_int("topology/physical_package_id", i, CPU_TOPO_NULL);
+            core_id = get_cpu_int("topology/core_id", i, CPU_TOPO_NULL);
+            if (pack_id < 0) pack_id = 0;
+            CPUBIT_SET(packs, pack_id);
+            if (core_id >= 0) { CPUBIT_SET(cores, (pack_id * MAX_CORES_PER_PACK) + core_id ); }
+        }
+        *t = cpubits_count(threads);
+        *c = cpubits_count(cores);
+        *p = cpubits_count(packs);
+        if (!*c) *c = 1;
+        if (!*p) *p = 1;
+        free(threads);
+        free(cores);
+        free(packs);
+        free(tmp);
+        return 1;
+    } else {
+        *p = *c = *t = -1;
+        return 0;
+    }
+}
+
+cpufreq_data *cpufreq_new(gint id)
+{
+    cpufreq_data *cpufd;
+    cpufd = malloc(sizeof(cpufreq_data));
+    if (cpufd) {
+        memset(cpufd, 0, sizeof(cpufreq_data));
+        cpufd->id = id;
+        cpufreq_update(cpufd, 0);
+    }
+    return cpufd;
+}
+
+void cpufreq_update(cpufreq_data *cpufd, int cur_only)
+{
+    if (cpufd) {
+        cpufd->cpukhz_cur = get_cpu_int("cpufreq/scaling_cur_freq", cpufd->id, 0);
+        if (cur_only) return;
+        cpufd->scaling_driver = get_cpu_str("cpufreq/scaling_driver", cpufd->id);
+        cpufd->scaling_governor = get_cpu_str("cpufreq/scaling_governor", cpufd->id);
+        cpufd->transition_latency = get_cpu_int("cpufreq/cpuinfo_transition_latency", cpufd->id, 0);
+        cpufd->cpukhz_min = get_cpu_int("cpufreq/scaling_min_freq", cpufd->id, 0);
+        cpufd->cpukhz_max = get_cpu_int("cpufreq/scaling_max_freq", cpufd->id, 0);
+        if (cpufd->scaling_driver == NULL) cpufd->scaling_driver = g_strdup("(Unknown)");
+        if (cpufd->scaling_governor == NULL) cpufd->scaling_governor = g_strdup("(Unknown)");
+
+        /* x86 uses freqdomain_cpus, all others use affected_cpus */
+        cpufd->shared_list = get_cpu_str("cpufreq/freqdomain_cpus", cpufd->id);
+        if (cpufd->shared_list == NULL) cpufd->shared_list = get_cpu_str("cpufreq/affected_cpus", cpufd->id);
+        if (cpufd->shared_list == NULL) cpufd->shared_list = g_strdup_printf("%d", cpufd->id);
+    }
+}
+
+void cpufreq_free(cpufreq_data *cpufd)
+{
+    if (cpufd) {
+        g_free(cpufd->scaling_driver);
+        g_free(cpufd->scaling_governor);
+    }
+    g_free(cpufd);
+}
+
+cpu_topology_data *cputopo_new(gint id)
+{
+    cpu_topology_data *cputd;
+    cputd = malloc(sizeof(cpu_topology_data));
+    if (cputd) {
+        memset(cputd, 0, sizeof(cpu_topology_data));
+        cputd->id = id;
+        cputd->socket_id = get_cpu_int("topology/physical_package_id", id, CPU_TOPO_NULL);
+        cputd->core_id = get_cpu_int("topology/core_id", id, CPU_TOPO_NULL);
+        cputd->book_id = get_cpu_int("topology/book_id", id, CPU_TOPO_NULL);
+        cputd->drawer_id = get_cpu_int("topology/drawer_id", id, CPU_TOPO_NULL);
+    }
+    return cputd;
+
+}
+
+void cputopo_free(cpu_topology_data *cputd)
+{
+    g_free(cputd);
+}
+
+gchar *cpufreq_section_str(cpufreq_data *cpufd)
+{
+    if (cpufd == NULL)
+        return g_strdup("");
+
+    if (cpufd->cpukhz_min || cpufd->cpukhz_max || cpufd->cpukhz_cur) {
+        return g_strdup_printf(
+                    "[%s]\n"
+                    "%s=%d %s\n"
+                    "%s=%d %s\n"
+                    "%s=%d %s\n"
+                    "%s=%d %s\n"
+                    "%s=%s\n"
+                    "%s=%s\n",
+                   _("Frequency Scaling"),
+                   _("Minimum"), cpufd->cpukhz_min, _("kHz"),
+                   _("Maximum"), cpufd->cpukhz_max, _("kHz"),
+                   _("Current"), cpufd->cpukhz_cur, _("kHz"),
+                   _("Transition Latency"), cpufd->transition_latency, _("ns"),
+                   _("Governor"), cpufd->scaling_governor,
+                   _("Driver"), cpufd->scaling_driver);
+    } else {
+        return g_strdup_printf(
+                    "[%s]\n"
+                    "%s=%s\n",
+                   _("Frequency Scaling"),
+                   _("Driver"), cpufd->scaling_driver);
+    }
+}
+
+gchar *cputopo_section_str(cpu_topology_data *cputd)
+{
+    static const char na[] = N_("(Not Available)");
+    char sock_str[64] = "", core_str[64] = "";
+    char book_str[64] = "", drawer_str[64] = "";
+
+    if (cputd == NULL)
+        return g_strdup("");
+
+    if (cputd->socket_id != CPU_TOPO_NULL && cputd->socket_id != -1)
+        sprintf(sock_str, "%s=%d\n", _("Socket"), cputd->socket_id);
+    else
+        sprintf(sock_str, "%s=%s\n", _("Socket"), na);
+
+    if (cputd->core_id != CPU_TOPO_NULL)
+        sprintf(core_str, "%s=%d\n", _("Core"), cputd->core_id);
+    else
+        sprintf(core_str, "%s=%s\n", _("Core"), na);
+
+    if (cputd->book_id != CPU_TOPO_NULL)
+        sprintf(core_str, "%s=%d\n", _("Book"), cputd->book_id);
+    if (cputd->book_id != CPU_TOPO_NULL)
+        sprintf(core_str, "%s=%d\n", _("Drawer"), cputd->drawer_id);
+
+    return g_strdup_printf(
+                    "[%s]\n"
+                    "%s=%d\n"
+                    "%s%s%s%s",
+                   _("Topology"),
+                   _("ID"), cputd->id,
+                   sock_str, core_str, book_str, drawer_str );
+}
diff --git a/hardinfo/cpubits.c b/hardinfo/cpubits.c
new file mode 100644
index 0000000..7ab03be
--- /dev/null
+++ b/hardinfo/cpubits.c
@@ -0,0 +1,113 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * Copyright (C) 2017  Burt P. <pburt0@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <stdint.h>
+
+typedef uint32_t cpubits;
+uint32_t cpubits_count(cpubits *b);
+cpubits *cpubits_from_str(char *str);
+char *cpubits_to_str(cpubits *bits, char *str, int max_len);
+
+#define CPUBITS_SIZE 4096 /* bytes, multiple of sizeof(uint32_t) */
+#define CPUBIT_SET(BITS, BIT) (BITS[BIT/32] |= (1 << BIT%32))
+#define CPUBIT_GET(BITS, BIT) ((BITS[BIT/32] & (1 << BIT%32)) >> BIT%32)
+#define CPUBITS_CLEAR(BITS) memset(BITS, 0, CPUBITS_SIZE)
+
+uint32_t cpubits_count(cpubits *b) {
+    static const uint32_t max = CPUBITS_SIZE * 8;
+    uint32_t count = 0, i = 0;
+    while (i < max) {
+        count += CPUBIT_GET(b, i);
+        i++;
+    }
+    return count;
+}
+
+int cpubits_max(cpubits *b) {
+    int i = CPUBITS_SIZE * 8 - 1;
+    while (i >= 0) {
+        if (CPUBIT_GET(b, i))
+            break;
+        i--;
+    }
+    return i;
+}
+
+cpubits *cpubits_from_str(char *str) {
+    char *v, *nv, *hy;
+    int r0, r1;
+    cpubits *newbits = malloc(CPUBITS_SIZE);
+    if (newbits) {
+        memset(newbits, 0, CPUBITS_SIZE);
+        if (str != NULL) {
+            v = (char*)str;
+            while ( *v != 0 ) {
+                nv = strchr(v, ',');                /* strchrnul() */
+                if (nv == NULL) nv = strchr(v, 0);  /* equivalent  */
+                hy = strchr(v, '-');
+                if (hy && hy < nv) {
+                    r0 = strtol(v, NULL, 0);
+                    r1 = strtol(hy + 1, NULL, 0);
+                } else {
+                    r0 = r1 = strtol(v, NULL, 0);
+                }
+                for (; r0 <= r1; r0++) {
+                    CPUBIT_SET(newbits, r0);
+                }
+                v = (*nv == ',') ? nv + 1 : nv;
+            }
+        }
+    }
+    return newbits;
+}
+
+char *cpubits_to_str(cpubits *bits, char *str, int max_len) {
+    static const uint32_t max = CPUBITS_SIZE * 8;
+    uint32_t i = 1, seq_start = 0, seq_last = 0, seq = 0, l = 0;
+    char buffer[65536] = "";
+    if (CPUBIT_GET(bits, 0)) {
+        seq = 1;
+        strcpy(buffer, "0");
+    }
+    while (i < max) {
+        if (CPUBIT_GET(bits, i) ) {
+            seq_last = i;
+            if (!seq) {
+                seq = 1;
+                seq_start = i;
+                l = strlen(buffer);
+                sprintf(buffer + l, "%s%d", l ? "," : "", i);
+            }
+        } else {
+            if (seq && seq_last != seq_start) {
+                l = strlen(buffer);
+                sprintf(buffer + l, "-%d", seq_last);
+            }
+            seq = 0;
+        }
+        i++;
+    }
+    if (str == NULL)
+        return strdup(buffer);
+    else {
+        strncpy(str, buffer, max_len);
+        return str;
+    }
+}
diff --git a/hardinfo/dmi_util.c b/hardinfo/dmi_util.c
new file mode 100644
index 0000000..28b2c19
--- /dev/null
+++ b/hardinfo/dmi_util.c
@@ -0,0 +1,157 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2017 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *    This file
+ *    Copyright (C) 2017 Burt P. <pburt0@gmail.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "dmi_util.h"
+
+static const char *dmi_sysfs_root(void) {
+    char *candidates[] = {
+        "/sys/devices/virtual/dmi",
+        "/sys/class/dmi",
+        NULL
+    };
+    int i = 0;
+    while (candidates[i] != NULL) {
+        if(access(candidates[i], F_OK) != -1)
+            return candidates[i];
+        i++;
+    }
+    return NULL;
+}
+
+char *dmi_get_str(const char *id_str) {
+    static struct {
+        char *id;
+        char *path;
+    } tab_dmi_sysfs[] = {
+        /* dmidecode -> sysfs */
+        { "bios-release-date", "id/bios_date" },
+        { "bios-vendor", "id/bios_vendor" },
+        { "bios-version", "id/bios_version" },
+        { "baseboard-product-name", "id/board_name" },
+        { "baseboard-manufacturer", "id/board_vendor" },
+        { "baseboard-version", "id/board_version" },
+        { "baseboard-serial-number", "id/board_serial" },
+        { "baseboard-asset-tag", "id/board_asset_tag" },
+        { "system-product-name", "id/product_name" },
+        { "system-manufacturer", "id/sys_vendor" },
+        { "system-serial-number", "id/product_serial" },
+        { "system-product-family", "id/product_family" },
+        { "system-version", "id/product_version" },
+        { "system-uuid", "product_uuid" },
+        { "chassis-type", "id/chassis_type" },
+        { "chassis-serial-number", "id/chassis_serial" },
+        { "chassis-manufacturer", "id/chassis_vendor" },
+        { "chassis-version", "id/chassis_version" },
+        { "chassis-asset-tag", "id/chassis_asset_tag" },
+        { NULL, NULL }
+    };
+    const gchar *dmi_root = dmi_sysfs_root();
+    gchar *ret = NULL;
+    gchar full_path[PATH_MAX];
+    gboolean spawned;
+    gchar *out, *err;
+
+    int i = 0;
+
+    /* try sysfs first */
+    if (dmi_root) {
+        while (tab_dmi_sysfs[i].id != NULL) {
+            if (strcmp(id_str, tab_dmi_sysfs[i].id) == 0) {
+                snprintf(full_path, PATH_MAX, "%s/%s", dmi_root, tab_dmi_sysfs[i].path);
+                if (g_file_get_contents(full_path, &ret, NULL, NULL) )
+                    goto dmi_str_done;
+            }
+            i++;
+        }
+    }
+
+    /* try dmidecode, but may require root */
+    snprintf(full_path, PATH_MAX, "dmidecode -s %s", id_str);
+    spawned = g_spawn_command_line_sync(full_path,
+            &out, &err, &i, NULL);
+    if (spawned) {
+        if (i == 0)
+            ret = out;
+        else
+            g_free(out);
+
+        g_free(err);
+    }
+
+dmi_str_done:
+    if (ret != NULL) {
+        ret = strend(ret, '\n');
+        ret = g_strstrip(ret);
+        /* return NULL on empty */
+        if (*ret == 0) {
+            g_free(ret);
+            ret = NULL;
+        }
+    }
+    return ret;
+}
+
+char *dmi_chassis_type_str(int chassis_type, gboolean with_val) {
+    static const char *types[] = {
+        N_("Invalid chassis type (0)"),
+        N_("Unknown chassis type"), /* 1 is "Other", but not helpful in HardInfo */
+        N_("Unknown chassis type"),
+        N_("Desktop"),
+        N_("Low-profile Desktop"),
+        N_("Pizza Box"),
+        N_("Mini Tower"),
+        N_("Tower"),
+        N_("Portable"),
+        N_("Laptop"),
+        N_("Notebook"),
+        N_("Handheld"),
+        N_("Docking Station"),
+        N_("All-in-one"),
+        N_("Subnotebook"),
+        N_("Space-saving"),
+        N_("Lunch Box"),
+        N_("Main Server Chassis"),
+        N_("Expansion Chassis"),
+        N_("Sub Chassis"),
+        N_("Bus Expansion Chassis"),
+        N_("Peripheral Chassis"),
+        N_("RAID Chassis"),
+        N_("Rack Mount Chassis"),
+        N_("Sealed-case PC"),
+    };
+
+    if (chassis_type <= 0) {
+        gchar *chassis = dmi_get_str("chassis-type");
+        if (chassis) {
+            chassis_type = atoi(chassis);
+            g_free(chassis);
+        } else
+            chassis_type = -1;
+    }
+
+    if (chassis_type >= 0 && chassis_type < G_N_ELEMENTS(types)) {
+        if (with_val)
+            return g_strdup_printf("[%d] %s", chassis_type, _(types[chassis_type]));
+
+        return g_strdup(_(types[chassis_type]));
+    }
+    return NULL;
+}
diff --git a/hardinfo/dt_util.c b/hardinfo/dt_util.c
new file mode 100644
index 0000000..9678042
--- /dev/null
+++ b/hardinfo/dt_util.c
@@ -0,0 +1,1040 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+/*
+ * Device Tree support by Burt P. <pburt0@gmail.com>
+ * Sources:
+ *   http://elinux.org/Device_Tree_Usage
+ *   http://elinux.org/Device_Tree_Mysteries
+ */
+#include <unistd.h>
+#include <sys/types.h>
+#include <endian.h>
+#include "hardinfo.h"
+#include "dt_util.h"
+
+static struct {
+    char *name; int type;
+} prop_types[] = {
+    { "name", DTP_STR },
+    { "compatible", DTP_STR },
+    { "model", DTP_STR },
+    { "reg", DTP_REG },
+    { "clocks", DTP_CLOCKS },
+    { "gpios", DTP_GPIOS },
+    { "cs-gpios", DTP_GPIOS },
+    { "phandle", DTP_PH },
+    { "interrupts", DTP_INTRUPT },
+    { "interrupts-extended", DTP_INTRUPT_EX },
+    { "interrupt-parent", DTP_PH_REF },
+    { "interrupt-controller", DTP_EMPTY },
+    { "regulator-min-microvolt", DTP_UINT },
+    { "regulator-max-microvolt", DTP_UINT },
+    { "clock-frequency", DTP_UINT },
+    { "dmas", DTP_DMAS },
+    { "dma-channels", DTP_UINT },
+    { "dma-requests", DTP_UINT },
+    { NULL, 0 },
+};
+
+static struct {
+    char *name; uint32_t v;
+} default_values[] = {
+    { "#address-cells", 2 },
+    { "#size-cells", 1 },
+    { "#dma-cells", 1 },
+    { NULL, 0 },
+};
+
+struct _dtr_map {
+    uint32_t v;  /* phandle */
+    char *label;  /* alias */
+    char *path;
+    struct _dtr_map *next;
+};
+typedef struct _dtr_map dtr_map;
+
+struct _dtr {
+    dtr_map *aliases;
+    dtr_map *symbols;
+    dtr_map *phandles;
+    char *base_path;
+    char *log;
+};
+
+struct _dtr_obj {
+    char *path;
+    union {
+        void *data;
+        char *data_str;
+        dt_uint *data_int;
+    };
+    char *name;
+    uint32_t length;
+    int type;
+    char *prefix;        /* if the name has a manufacturer's prefix or null */
+    char *np_name;       /* the name without any prefix. points into .prefix or .name, do not free */
+    const char *alias;  /* null until first dtr_obj_alias(). do not free */
+    const char *symbol; /* null until first dtr_obj_symbol(). do not free */
+    dtr *dt;
+};
+
+dtr_map *dtr_map_add(dtr_map *map, uint32_t v, const char *label, const char *path) {
+    dtr_map *it;
+    dtr_map *nmap = malloc(sizeof(dtr_map));
+    memset(nmap, 0, sizeof(dtr_map));
+    nmap->v = v;
+
+    if (label != NULL) nmap->label = strdup(label);
+    if (path != NULL) nmap->path = strdup(path);
+    if (map == NULL)
+        return nmap;
+
+    it = map;
+    while(it->next != NULL)
+        it = it->next;
+    it->next = nmap;
+
+    return nmap;
+}
+
+void dtr_map_free(dtr_map *map) {
+    dtr_map *it;
+    while(map != NULL) {
+        it = map->next;
+        free(map->label);
+        free(map->path);
+        free(map);
+        map = it;
+    }
+}
+
+/* simple sort for maps
+ * sv: 1 = sort by v, 0 = sort by label */
+void dtr_map_sort(dtr_map *map, int sv)
+{
+    int done = 0, cmp;
+    dtr_map *this, *next, *top, *next_top;
+    uint32_t tmp_v;
+    char *tmp_l, *tmp_p;
+    if (map == NULL) return;
+    do {
+        this = map;
+        next_top = NULL;
+        while(this != NULL) {
+            next = this->next;
+            if (this == top)
+                break;
+            if (next == NULL)
+                break;
+            if (sv)
+                cmp = (this->v > next->v) ? 1 : 0;
+            else
+                cmp = strcmp(this->label, next->label);
+            if (cmp > 0) {
+                tmp_v = this->v; this->v = next->v; next->v = tmp_v;
+                tmp_l = this->label; this->label = next->label; next->label = tmp_l;
+                tmp_p = this->path; this->path = next->path; next->path = tmp_p;
+                next_top = this;
+            }
+            this = next;
+        }
+        if (next_top == NULL)
+            done = 1;
+        else
+            top = next_top;
+    } while (!done);
+}
+
+const char *dtr_phandle_lookup(dtr *s, uint32_t v) {
+    dtr_map *phi = s->phandles;
+    /* 0 and 0xffffffff are invalid phandle values */
+    /* TODO: perhaps "INVALID" or something */
+    if (v == 0 || v == 0xffffffff)
+        return NULL;
+    while(phi != NULL) {
+        if (phi->v == v)
+            return phi->path;
+        phi = phi->next;
+    }
+    return NULL;
+}
+
+const char *dtr_alias_lookup(dtr *s, const char* label) {
+    dtr_map *ali = s->aliases;
+    while(ali != NULL) {
+        if (strcmp(ali->label, label) == 0)
+            return ali->path;
+        ali = ali->next;
+    }
+    return NULL;
+}
+
+const char *dtr_alias_lookup_by_path(dtr *s, const char* path) {
+    dtr_map *ali = s->aliases;
+    while(ali != NULL) {
+        if (strcmp(ali->path, path) == 0)
+            return ali->label;
+        ali = ali->next;
+    }
+    return NULL;
+}
+
+const char *dtr_symbol_lookup_by_path(dtr *s, const char* path) {
+    dtr_map *ali = s->symbols;
+    while(ali != NULL) {
+        if (strcmp(ali->path, path) == 0)
+            return ali->label;
+        ali = ali->next;
+    }
+    return NULL;
+}
+
+void _dtr_read_aliases(dtr *);
+void _dtr_read_symbols(dtr *);
+void _dtr_map_phandles(dtr *, char *np);
+
+const char *dtr_find_device_tree_root() {
+    char *candidates[] = {
+        "/proc/device-tree",
+        "/sys/firmware/devicetree/base",
+        /* others? */
+        NULL
+    };
+    int i = 0;
+    while (candidates[i] != NULL) {
+        if(access(candidates[i], F_OK) != -1)
+            return candidates[i];
+        i++;
+    }
+    return NULL;
+}
+
+dtr *dtr_new_x(const char *base_path, int fast) {
+    dtr *dt = malloc(sizeof(dtr));
+    if (dt != NULL) {
+        memset(dt, 0, sizeof(dtr));
+        dt->log = strdup("");
+
+        if (base_path == NULL)
+            base_path = DTR_ROOT;
+
+        if (base_path != NULL)
+            dt->base_path = strdup(base_path);
+        else {
+            dtr_msg(dt, "%s", "Device Tree not found.");
+            return dt;
+        }
+
+        /* build alias and phandle lists */
+        dt->aliases = NULL;
+        dt->symbols = NULL;
+        dt->phandles = NULL;
+        if (!fast) {
+            _dtr_read_aliases(dt);
+            _dtr_read_symbols(dt);
+            _dtr_map_phandles(dt, "");
+        }
+    }
+    return dt;
+}
+
+dtr *dtr_new(const char *base_path) {
+    return dtr_new_x(base_path, 0);
+}
+
+void dtr_free(dtr *s) {
+    if (s != NULL) {
+        dtr_map_free(s->aliases);
+        dtr_map_free(s->symbols);
+        dtr_map_free(s->phandles);
+        free(s->base_path);
+        free(s->log);
+        free(s);
+    }
+}
+
+int dtr_was_found(dtr *s) {
+    if (s != NULL) {
+        if (s->base_path != NULL)
+            return 1;
+    }
+    return 0;
+}
+
+void dtr_msg(dtr *s, char *fmt, ...) {
+    gchar *buf, *tmp;
+    va_list args;
+
+    va_start(args, fmt);
+    buf = g_strdup_vprintf(fmt, args);
+    va_end(args);
+
+    tmp = g_strdup_printf("%s%s", s->log, buf);
+    g_free(s->log);
+    s->log = tmp;
+}
+
+char *dtr_messages(dtr *s) {
+    if (s != NULL)
+        return strdup(s->log);
+    else
+        return NULL;
+}
+
+const char *dtr_base_path(dtr *s) {
+    if (s)
+        return s->base_path;
+    return NULL;
+}
+
+/*glib, but _dt_obj *prop uses malloc() and std types */
+dtr_obj *dtr_obj_read(dtr *s, const char *dtp) {
+    char *full_path;
+    char *slash, *coma;
+    dtr_obj *obj;
+
+    if (dtp == NULL)
+        return NULL;
+
+    obj = malloc(sizeof(dtr_obj));
+    if (obj != NULL) {
+        memset(obj, 0, sizeof(dtr_obj));
+
+        obj->dt = s;
+        if (*dtp != '/') {
+            /* doesn't start with slash, use alias */
+            obj->path = (char*)dtr_alias_lookup(s, dtp);
+            if (obj->path != NULL)
+                obj->path = strdup(obj->path);
+            else {
+                dtr_obj_free(obj);
+                return NULL;
+            }
+        } else
+            obj->path = strdup(dtp);
+
+        /* find name after last slash, or start */
+        slash = strrchr(obj->path, '/');
+        if (slash != NULL)
+            obj->name = strdup(slash + 1);
+        else
+            obj->name = strdup(obj->path);
+
+        /* find manufacturer prefix */
+        obj->prefix = strdup(obj->name);
+        coma = strchr(obj->prefix, ',');
+        if (coma != NULL) {
+            /* coma -> null; .np_name starts after */
+            *coma = 0;
+            obj->np_name = coma + 1;
+        } else {
+            obj->np_name = obj->name;
+            free(obj->prefix);
+            obj->prefix = NULL;
+        }
+
+        /* read data */
+        full_path = g_strdup_printf("%s%s", s->base_path, obj->path);
+        if ( g_file_test(full_path, G_FILE_TEST_IS_DIR) ) {
+            obj->type = DT_NODE;
+        } else {
+            if (!g_file_get_contents(full_path, (gchar**)&obj->data, (gsize*)&obj->length, NULL)) {
+                dtr_obj_free(obj);
+                g_free(full_path);
+                return NULL;
+            }
+            obj->type = dtr_guess_type(obj);
+        }
+        g_free(full_path);
+
+        return obj;
+    }
+    return NULL;
+}
+
+void dtr_obj_free(dtr_obj *s) {
+    if (s != NULL) {
+        free(s->path);
+        free(s->name);
+        free(s->prefix);
+        free(s->data);
+        free(s);
+    }
+}
+
+int dtr_obj_type(dtr_obj *s) {
+    if (s)
+        return s->type;
+    return DT_TYPE_ERR;
+}
+
+char *dtr_obj_alias(dtr_obj *s) {
+    if (s) {
+        if (s->alias == NULL)
+            s->alias = dtr_alias_lookup_by_path(s->dt, s->path);
+        return (char*)s->alias;
+    }
+    return NULL;
+}
+
+char *dtr_obj_symbol(dtr_obj *s) {
+    if (s) {
+        if (s->symbol == NULL)
+            s->symbol = dtr_symbol_lookup_by_path(s->dt, s->path);
+        return (char*)s->symbol;
+    }
+    return NULL;
+}
+
+char *dtr_obj_path(dtr_obj *s) {
+    if (s)
+        return s->path;
+    return NULL;
+}
+
+char *dtr_obj_full_path(dtr_obj *s) {
+    if (s) {
+        if (strcmp(s->path, "/") == 0)
+            return g_strdup_printf("%s", s->dt->base_path);
+        else
+            return g_strdup_printf("%s%s", s->dt->base_path, s->path);
+    }
+    return NULL;
+}
+
+dtr_obj *dtr_get_prop_obj(dtr *s, dtr_obj *node, const char *name) {
+    dtr_obj *prop;
+    char *ptmp;
+    ptmp = g_strdup_printf("%s/%s", (node == NULL) ? "" : node->path, name);
+    prop = dtr_obj_read(s, ptmp);
+    g_free(ptmp);
+    return prop;
+}
+
+char *dtr_get_prop_str(dtr *s, dtr_obj *node, const char *name) {
+    dtr_obj *prop;
+    char *ptmp;
+    char *ret = NULL;
+
+    ptmp = g_strdup_printf("%s/%s", (node == NULL) ? "" : node->path, name);
+    prop = dtr_obj_read(s, ptmp);
+    if (prop != NULL && prop->data != NULL) {
+        ret = strdup(prop->data_str);
+        dtr_obj_free(prop);
+    }
+    g_free(ptmp);
+    return ret;
+}
+
+char *dtr_get_string(const char *p, int decode) {
+    dtr *dt = dtr_new_x(NULL, 1);
+    dtr_obj *obj;
+    char *ret = NULL;
+    if (decode) {
+        obj = dtr_get_prop_obj(dt, NULL, p);
+        ret = dtr_str(obj);
+        dtr_obj_free(obj);
+    } else
+        ret = dtr_get_prop_str(dt, NULL, p);
+    dtr_free(dt);
+    return ret;
+}
+
+uint32_t dtr_get_prop_u32(dtr *s, dtr_obj *node, const char *name) {
+    dtr_obj *prop;
+    char *ptmp;
+    uint32_t ret = 0;
+
+    ptmp = g_strdup_printf("%s/%s", (node == NULL) ? "" : node->path, name);
+    prop = dtr_obj_read(s, ptmp);
+    if (prop != NULL && prop->data != NULL) {
+        ret = be32toh(*prop->data_int);
+        dtr_obj_free(prop);
+    }
+    g_free(ptmp);
+    return ret;
+}
+
+int dtr_guess_type(dtr_obj *obj) {
+    char *tmp, *dash;
+    int i = 0, anc = 0, might_be_str = 1;
+
+    if (obj->length == 0)
+        return DTP_EMPTY;
+
+    /* special #(.*)-cells names are UINT */
+    if (*obj->name == '#') {
+        dash = strrchr(obj->name, '-');
+        if (dash != NULL) {
+            if (strcmp(dash, "-cells") == 0)
+                return DTP_UINT;
+        }
+    }
+
+    /* /aliases/* and /__symbols__/* are always strings */
+    if (strncmp(obj->path, "/aliases/", strlen("/aliases/") ) == 0)
+        return DTP_STR;
+    if (strncmp(obj->path, "/__symbols__/", strlen("/__symbols__/") ) == 0)
+        return DTP_STR;
+
+    /* /__overrides__/* */
+    if (strncmp(obj->path, "/__overrides__/", strlen("/__overrides__/") ) == 0)
+        if (strcmp(obj->name, "name") != 0)
+            return DTP_OVR;
+
+    /* lookup known type */
+    while (prop_types[i].name != NULL) {
+        if (strcmp(obj->name, prop_types[i].name) == 0)
+            return prop_types[i].type;
+        i++;
+    }
+
+    /* maybe a string? */
+    for (i = 0; i < obj->length; i++) {
+        tmp = obj->data_str + i;
+        if ( isalnum(*tmp) ) anc++; /* count the alpha-nums */
+        if ( isprint(*tmp) || *tmp == 0 )
+            continue;
+        might_be_str = 0;
+        break;
+    }
+    if (might_be_str &&
+        ( anc >= obj->length - 2 /* all alpha-nums but ^/ and \0$ */
+          || anc >= 5 ) /*arbitrary*/)
+        return DTP_STR;
+
+    /* multiple of 4 bytes, try list of hex values */
+    if (!(obj->length % 4))
+        return DTP_HEX;
+
+    return DTP_UNK;
+}
+
+char *dtr_elem_phref(dtr *s, dt_uint e, int show_path) {
+    const char *ph_path, *al_label;
+    char *ret = NULL;
+    ph_path = dtr_phandle_lookup(s, be32toh(e));
+    if (ph_path != NULL) {
+        /* TODO: alias or symbol? */
+        al_label = dtr_symbol_lookup_by_path(s, ph_path);
+        if (al_label != NULL) {
+            if (show_path)
+                ret = g_strdup_printf("&%s (%s)", al_label, ph_path);
+            else
+                ret = g_strdup_printf("&%s", al_label);
+        } else {
+            if (show_path)
+                ret = g_strdup_printf("0x%x (%s)", be32toh(e), ph_path);
+        }
+    }
+    if (ret == NULL)
+        ret = dtr_elem_hex(e);
+    return ret;
+}
+
+char *dtr_elem_hex(dt_uint e) {
+    return g_strdup_printf("0x%x", be32toh(e) );
+}
+
+char *dtr_elem_byte(uint8_t e) {
+    return g_strdup_printf("%x", e);
+}
+
+char *dtr_elem_uint(dt_uint e) {
+    return g_strdup_printf("%u", be32toh(e) );
+}
+
+char *dtr_list_byte(uint8_t *bytes, unsigned long count) {
+    char *ret, *dest;
+    char buff[4] = "";  /* max element: " 00\0" */
+    uint32_t v;
+    unsigned long i, l;
+    l = count * 4 + 1;
+    ret = malloc(l);
+    memset(ret, 0, l);
+    strcpy(ret, "[");
+    dest = ret + 1;
+    for (i = 0; i < count; i++) {
+        v = bytes[i];
+        sprintf(buff, "%s%02x", (i) ? " " : "", v);
+        l = strlen(buff);
+        strncpy(dest, buff, l);
+        dest += l;
+    }
+    strcpy(dest, "]");
+    return ret;
+}
+
+char *dtr_list_hex(dt_uint *list, unsigned long count) {
+    char *ret, *dest;
+    char buff[12] = "";  /* max element: " 0x00000000\0" */
+    unsigned long i, l;
+    l = count * 12 + 1;
+    dest = ret = malloc(l);
+    memset(ret, 0, l);
+    for (i = 0; i < count; i++) {
+        sprintf(buff, "%s0x%x", (i) ? " " : "", be32toh(list[i]));
+        l = strlen(buff);
+        strncpy(dest, buff, l);
+        dest += l;
+    }
+    return ret;
+}
+
+/*cstd, except for g_strescape()*/
+char *dtr_list_str0(const char *data, uint32_t length) {
+    char *tmp, *esc, *next_str;
+    char ret[1024] = "";
+    uint32_t l, tl;
+
+    /* treat as null-separated string list */
+    tl = 0;
+    strcpy(ret, "");
+    tmp = ret;
+    next_str = (char*)data;
+    while(next_str != NULL) {
+        l = strlen(next_str);
+        esc = g_strescape(next_str, NULL);
+        sprintf(tmp, "%s\"%s\"",
+                strlen(ret) ? ", " : "", esc);
+        free(esc);
+        tmp += strlen(tmp);
+        tl += l + 1; next_str += l + 1;
+        if (tl >= length) break;
+    }
+
+    return strdup(ret);
+}
+
+char *dtr_list_override(dtr_obj *obj) {
+    /* <phref, string "property:value"> ... */
+    char *ret = NULL;
+    char *ph, *str;
+    char *src;
+    int l, consumed = 0;
+    src = obj->data_str;
+    while (consumed + 5 <= obj->length) {
+        ph = dtr_elem_phref(obj->dt, *(dt_uint*)src, 1);
+        src += 4; consumed += 4;
+        l = strlen(src) + 1; /* consume the null */
+        str = dtr_list_str0(src, l);
+        ret = appf(ret, "<%s -> %s>", ph, str);
+        src += l; consumed += l;
+        free(ph);
+        free(str);
+    }
+    if (consumed < obj->length) {
+        str = dtr_list_byte(src, obj->length - consumed);
+        ret = appf(ret, "%s", str);
+        free(str);
+    }
+    return ret;
+}
+
+uint32_t dtr_get_phref_prop(dtr *s, uint32_t phandle, char *prop) {
+    const char *ph_path;
+    char *tmp;
+    uint32_t ret;
+    ph_path = dtr_phandle_lookup(s, phandle);
+    tmp = g_strdup_printf("%s/%s", ph_path, prop);
+    ret = dtr_get_prop_u32(s, NULL, tmp);
+    free(tmp);
+    return ret;
+}
+
+char *dtr_list_phref(dtr_obj *obj, char *ext_cell_prop) {
+    /* <phref, #XXX-cells> */
+    int count = obj->length / 4;
+    int i = 0, ext_cells = 0;
+    char *ph_path;
+    char *ph, *ext, *ret = NULL;
+    while (i < count) {
+        if (ext_cell_prop == NULL)
+            ext_cells = 0;
+        else
+            ext_cells = dtr_get_phref_prop(obj->dt, be32toh(obj->data_int[i]), ext_cell_prop);
+        ph = dtr_elem_phref(obj->dt, obj->data_int[i], 0); i++;
+        if (ext_cells > count - i) ext_cells = count - i;
+        ext = dtr_list_hex((obj->data_int + i), ext_cells); i+=ext_cells;
+        ret = appf(ret, "<%s%s%s>",
+            ph, (ext_cells) ? " " : "", ext);
+        g_free(ph);
+        g_free(ext);
+    }
+    return ret;
+}
+
+char *dtr_list_interrupts(dtr_obj *obj) {
+    char *ext, *ret = NULL;
+    uint32_t iparent, icells;
+    int count, i = 0;
+
+    iparent = dtr_inh_find(obj, "interrupt-parent", 0);
+    if (!iparent) {
+        dtr_msg(obj->dt, "Did not find an interrupt-parent for %s", obj->path);
+        goto intr_err;
+    }
+    icells = dtr_get_phref_prop(obj->dt, iparent, "#interrupt-cells");
+    if (!icells) {
+        dtr_msg(obj->dt, "Invalid #interrupt-cells value %d for %s", icells, obj->path);
+        goto intr_err;
+    }
+
+    count = obj->length / 4;
+    while (i < count) {
+        icells = MIN(icells, count - i);
+        ext = dtr_list_hex((obj->data_int + i), icells); i+=icells;
+        ret = appf(ret, "<%s>", ext);
+    }
+    return ret;
+
+intr_err:
+    return dtr_list_hex(obj->data_int, obj->length);
+
+}
+
+char *dtr_list_reg(dtr_obj *obj) {
+    char *tup_str, *ret = NULL;
+    uint32_t acells, scells, tup_len;
+    uint32_t tups, extra, consumed; /* extra and consumed are bytes */
+    uint32_t *next;
+
+    acells = dtr_inh_find(obj, "#address-cells", 2);
+    scells = dtr_inh_find(obj, "#size-cells", 2);
+    tup_len = acells + scells;
+    tups = obj->length / (tup_len * 4);
+    extra = obj->length % (tup_len * 4);
+    consumed = 0; /* bytes */
+
+    //printf("list reg: %s\n ... acells: %u, scells: %u, extra: %u\n", obj->path, acells, scells, extra);
+
+    if (extra) {
+        /* error: length is not a multiple of tuples */
+        dtr_msg(obj->dt, "Data length (%u) is not a multiple of (#address-cells:%u + #size-cells:%u) for %s\n",
+            obj->length, acells, scells, obj->path);
+        return dtr_list_hex(obj->data, obj->length / 4);
+    }
+
+    next = obj->data_int;
+    consumed = 0;
+    while (consumed + (tup_len * 4) <= obj->length) {
+        tup_str = dtr_list_hex(next, tup_len);
+        ret = appf(ret, "<%s>", tup_str);
+        free(tup_str);
+        consumed += (tup_len * 4);
+        next += tup_len;
+    }
+
+    //printf(" ... %s\n", ret);
+    return ret;
+}
+
+char* dtr_str(dtr_obj *obj) {
+    char *ret;
+    int type;
+
+    if (obj == NULL) return NULL;
+    type = obj->type;
+
+    if (type == DTP_PH_REF) {
+        if (!DTEX_PHREFS || obj->length != 4)
+            type = DTP_HEX;
+    }
+
+    switch(type) {
+        case DT_NODE:
+            ret = strdup("{node}");
+            break;
+        case DTP_EMPTY:
+            ret = strdup("{empty}");
+            break;
+        case DTP_STR:
+            ret = dtr_list_str0(obj->data_str, obj->length);
+            break;
+        case DTP_OVR:
+            ret = dtr_list_override(obj);
+            break;
+        case DTP_REG:
+            /* <#address-cells #size-cells> */
+            ret = dtr_list_reg(obj);
+            break;
+        case DTP_INTRUPT:
+            ret = dtr_list_interrupts(obj);
+            break;
+        case DTP_INTRUPT_EX:
+            /* <phref, #interrupt-cells"> */
+            ret = dtr_list_phref(obj, "#interrupt-cells");
+            break;
+        case DTP_CLOCKS:
+            /* <phref, #clock-cells"> */
+            ret = dtr_list_phref(obj, "#clock-cells");
+            break;
+        case DTP_GPIOS:
+            /* <phref, #gpio-cells"> */
+            ret = dtr_list_phref(obj, "#gpio-cells");
+            break;
+        case DTP_DMAS:
+            /* <phref, #dma-cells"> */
+            ret = dtr_list_phref(obj, "#dma-cells");
+            break;
+        case DTP_PH:
+        case DTP_HEX:
+            if (obj->length % 4)
+                ret = dtr_list_byte((uint8_t*)obj->data, obj->length);
+            else
+                ret = dtr_list_hex(obj->data, obj->length / 4);
+            break;
+        case DTP_PH_REF:
+            ret = dtr_elem_phref(obj->dt, *obj->data_int, 1);
+            break;
+        case DTP_UINT:
+            ret = dtr_elem_uint(*obj->data_int);
+            break;
+        case DTP_UNK:
+        default:
+            if (obj->length > 64) /* maybe should use #define at the top */
+                ret = g_strdup_printf(ret, "{data} (%lu bytes)", obj->length);
+            else
+                ret = dtr_list_byte((uint8_t*)obj->data, obj->length);
+            break;
+    }
+
+    return ret;
+}
+
+dtr_obj *dtr_get_parent_obj(dtr_obj *obj) {
+    char *slash, *parent;
+    dtr_obj *ret = NULL;
+
+    if (obj == NULL)
+        return NULL;
+
+    parent = strdup(obj->path);
+    slash = strrchr(parent, '/');
+    if (slash != NULL) {
+        *slash = 0;
+        if (strlen(parent) > 0)
+            ret = dtr_obj_read(obj->dt, parent);
+        else
+            ret = dtr_obj_read(obj->dt, "/");
+    }
+    free(parent);
+    return ret;
+}
+
+/* find the value of a path-inherited property by climbing the path */
+int dtr_inh_find(dtr_obj *obj, char *qprop, int limit) {
+    dtr_obj *tobj, *pobj, *qobj;
+    uint32_t ret = 0;
+    int i, found = 0;
+
+    if (!limit) limit = 1000;
+
+    tobj = obj;
+    while (tobj != NULL) {
+        pobj = dtr_get_parent_obj(tobj);
+        if (tobj != obj)
+            dtr_obj_free(tobj);
+        if (!limit || pobj == NULL) break;
+        qobj = dtr_get_prop_obj(obj->dt, pobj, qprop);
+        if (qobj != NULL) {
+            ret = be32toh(*qobj->data_int);
+            found = 1;
+            dtr_obj_free(qobj);
+            break;
+        }
+        tobj = pobj;
+        limit--;
+    }
+    dtr_obj_free(pobj);
+
+    if (!found) {
+        i = 0;
+        while(default_values[i].name != NULL) {
+            if (strcmp(default_values[i].name, qprop) == 0) {
+                ret = default_values[i].v;
+                dtr_msg(obj->dt, "Using default value %d for %s in %s\n", ret, qprop, obj->path);
+                break;
+            }
+            i++;
+        }
+    }
+
+    return ret;
+}
+
+void _dtr_read_aliases(dtr *s) {
+    gchar *dir_path;
+    GDir *dir;
+    const gchar *fn;
+    dtr_obj *anode, *prop;
+    dtr_map *al;
+    anode = dtr_obj_read(s, "/aliases");
+
+    dir_path = g_strdup_printf("%s/aliases", s->base_path);
+    dir = g_dir_open(dir_path, 0 , NULL);
+    if (dir) {
+        while((fn = g_dir_read_name(dir)) != NULL) {
+            prop = dtr_get_prop_obj(s, anode, fn);
+            if (prop->type == DTP_STR) {
+                if (*prop->data_str == '/') {
+                    al = dtr_map_add(s->aliases, 0, prop->name, prop->data_str);
+                    if (s->aliases == NULL)
+                        s->aliases = al;
+                }
+            }
+            dtr_obj_free(prop);
+        }
+    }
+    g_dir_close(dir);
+    g_free(dir_path);
+    dtr_obj_free(anode);
+    dtr_map_sort(s->aliases, 0);
+}
+
+void _dtr_read_symbols(dtr *s) {
+    gchar *dir_path;
+    GDir *dir;
+    const gchar *fn;
+    dtr_obj *anode, *prop;
+    dtr_map *al;
+    anode = dtr_obj_read(s, "/__symbols__");
+
+    dir_path = g_strdup_printf("%s/__symbols__", s->base_path);
+    dir = g_dir_open(dir_path, 0 , NULL);
+    if (dir) {
+        while((fn = g_dir_read_name(dir)) != NULL) {
+            prop = dtr_get_prop_obj(s, anode, fn);
+            if (prop->type == DTP_STR) {
+                if (*prop->data_str == '/') {
+                    al = dtr_map_add(s->symbols, 0, prop->name, prop->data_str);
+                    if (s->symbols == NULL)
+                        s->symbols = al;
+                }
+            }
+            dtr_obj_free(prop);
+        }
+    }
+    g_dir_close(dir);
+    g_free(dir_path);
+    dtr_obj_free(anode);
+    dtr_map_sort(s->symbols, 0);
+}
+
+/* TODO: rewrite */
+void _dtr_map_phandles(dtr *s, char *np) {
+    gchar *dir_path;
+    gchar *ftmp, *ntmp, *ptmp;
+    const gchar *fn;
+    GDir *dir;
+    dtr_obj *prop, *ph_prop;
+    dtr_map *ph;
+    uint32_t phandle;
+
+    if (np == NULL) np = "";
+    dir_path = g_strdup_printf("%s/%s", s->base_path, np);
+
+    prop = dtr_obj_read(s, np);
+    dir = g_dir_open(dir_path, 0 , NULL);
+    if (dir) {
+        while((fn = g_dir_read_name(dir)) != NULL) {
+            ftmp = g_strdup_printf("%s/%s", dir_path, fn);
+            if ( g_file_test(ftmp, G_FILE_TEST_IS_DIR) ) {
+                ntmp = g_strdup_printf("%s/%s", np, fn);
+                ptmp = g_strdup_printf("%s/phandle", ntmp);
+                ph_prop = dtr_obj_read(s, ptmp);
+                if (ph_prop != NULL) {
+                    ph = dtr_map_add(s->phandles, be32toh(*ph_prop->data_int), NULL, ntmp);
+                    if (s->phandles == NULL)
+                        s->phandles = ph;
+                }
+                _dtr_map_phandles(s, ntmp);
+                g_free(ptmp);
+                g_free(ntmp);
+                dtr_obj_free(ph_prop);
+            }
+            g_free(ftmp);
+        }
+    }
+    g_dir_close(dir);
+    dtr_obj_free(prop);
+    dtr_map_sort(s->phandles, 1);
+}
+
+/*
+ * Maybe these should move to devicetree.c, but would have to expose
+ * struct internals.
+ */
+
+/* kvl: 0 = key is label, 1 = key is v */
+char *dtr_map_info_section(dtr *s, dtr_map *map, char *title, int kvl) {
+    gchar *tmp, *ret;
+    const gchar *sym;
+    ret = g_strdup_printf("[%s]\n", _(title));
+    dtr_map *it = map;
+    while(it != NULL) {
+        if (kvl) {
+            sym = dtr_symbol_lookup_by_path(s, it->path);
+            if (sym != NULL)
+                tmp = g_strdup_printf("%s0x%x (%s)=%s\n", ret,
+                    it->v, sym, it->path);
+            else
+                tmp = g_strdup_printf("%s0x%x=%s\n", ret,
+                    it->v, it->path);
+        } else
+            tmp = g_strdup_printf("%s%s=%s\n", ret,
+                it->label, it->path);
+        g_free(ret);
+        ret = tmp;
+        it = it->next;
+    }
+
+    return ret;
+}
+
+char *dtr_maps_info(dtr *s) {
+    gchar *ph_map, *al_map, *sy_map, *ret;
+
+    ph_map = dtr_map_info_section(s, s->phandles, _("phandle Map"), 1);
+    al_map = dtr_map_info_section(s, s->aliases, _("Alias Map"), 0);
+    sy_map = dtr_map_info_section(s, s->symbols, _("Symbol Map"), 0);
+    ret = g_strdup_printf("%s%s%s", ph_map, sy_map, al_map);
+    g_free(ph_map);
+    g_free(al_map);
+    g_free(sy_map);
+    return ret;
+}
+
+char *appf(char *src, char *fmt, ...) {
+    gchar *buf, *ret;
+    va_list args;
+
+    va_start(args, fmt);
+    buf = g_strdup_vprintf(fmt, args);
+    va_end(args);
+
+    if (src != NULL) {
+        ret = g_strdup_printf("%s%s%s", src, sp_sep(src), buf);
+        g_free(buf);
+        g_free(src);
+    } else
+        ret = buf;
+
+    return ret;
+}
+
diff --git a/hardinfo/expr.c b/hardinfo/expr.c
new file mode 100644
index 0000000..32e303d
--- /dev/null
+++ b/hardinfo/expr.c
@@ -0,0 +1,250 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+/*
+ * This is only used to compute sensor values, hence the only variable supported is '@'.
+ * The '`' operator (ln(x)) is not available, nor multi-line formulas.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "expr.h"
+#include "config.h"
+
+static MathToken *new_operator(gchar op)
+{
+    MathToken *t = g_new0(MathToken, 1);
+
+    t->val.op = op;
+    t->type = TOKEN_OPERATOR;	/* operator */
+
+    return t;
+}
+
+static MathToken *new_variable(gchar var)
+{
+    MathToken *t = g_new0(MathToken, 1);
+
+    t->val.op = '@';
+    t->type = TOKEN_VARIABLE;	/* variable */
+
+    return t;
+}
+
+static MathToken *new_value(gfloat value)
+{
+    MathToken *t = g_new0(MathToken, 1);
+
+    t->val.value = value;
+    t->type = TOKEN_VALUE;	/* value */
+
+    return t;
+}
+
+static inline gint priority(char operation)
+{
+    switch (operation) {
+    case '^':
+	return 3;
+    case '*':
+    case '/':
+	return 2;
+    case '+':
+    case '-':
+	return 1;
+    case '(':
+	return 0;
+    }
+
+    return 0;
+}
+
+GSList *math_infix_to_postfix(GSList * infix)
+{
+    MathToken *stack[500];
+    gint t_sp = 0;
+
+    GSList *postfix = NULL, *p;
+    MathToken *top;
+
+    for (p = infix; p; p = p->next) {
+	MathToken *t = (MathToken *) p->data;
+
+	if (t->type == TOKEN_OPERATOR && t->val.op == '(') {
+	    stack[++t_sp] = t;
+	} else if (t->type == TOKEN_OPERATOR && t->val.op == ')') {
+	    for (top = stack[t_sp]; t_sp != 0 && top->val.op != '(';
+		 top = stack[t_sp]) {
+                postfix = g_slist_append(postfix, stack[t_sp--]);
+            }
+	    t_sp--;
+	} else if (t->type != TOKEN_OPERATOR) {
+	    postfix = g_slist_append(postfix, t);
+	} else if (t_sp == 0) {
+	    stack[++t_sp] = t;
+	} else {
+	    while (t_sp != 0
+		   && priority(t->val.op) <= priority(stack[t_sp]->val.op))
+		postfix = g_slist_append(postfix, stack[t_sp--]);
+	    stack[++t_sp] = t;
+	}
+    }
+
+    while (t_sp)
+	postfix = g_slist_append(postfix, stack[t_sp--]);
+	
+    return postfix;
+}
+
+static inline gfloat __result(gfloat op1, gfloat op2, gchar operation)
+{
+    switch (operation) {
+    case '^':
+	return powf(op1, op2);
+    case '+':
+	return op1 + op2;
+    case '-':
+	return op1 - op2;
+    case '/':
+	return op1 / op2;
+    case '*':
+	return op1 * op2;
+    }
+
+    return 0;
+}
+
+gfloat math_postfix_eval(GSList * postfix, gfloat at_value)
+{
+    GSList *p;
+    gfloat stack[500];
+    gint sp = 0;
+
+    memset(stack, 0, sizeof(gfloat) * 500);
+
+    for (p = postfix; p; p = p->next) {
+	MathToken *t = (MathToken *) p->data;
+
+	if (t->type == TOKEN_VARIABLE) {
+	    stack[++sp] = at_value;
+	} else if (t->type == TOKEN_VALUE) {
+	    stack[++sp] = t->val.value;
+	} else {
+	    gfloat op1, op2;
+
+	    op2 = stack[sp--];
+	    op1 = stack[sp];
+	    
+	    stack[sp] = __result(op1, op2, t->val.op);
+	}
+    }
+    
+    return stack[sp];
+}
+
+GSList *math_string_to_infix(gchar * string)
+{
+    GSList *infix = NULL;
+    gchar *expr = string;
+    
+    for (; *expr; expr++) {
+	if (strchr("+-/*^()", *expr)) {
+	    infix = g_slist_append(infix, new_operator(*expr));
+	} else if (strchr("@", *expr)) {
+	    infix = g_slist_append(infix, new_variable(*expr));
+	} else if (strchr("-.1234567890", *expr)) {
+	    gchar value[32], *v = value;
+	    gfloat floatval;
+	    
+	    do {
+	      *v++ = *expr++;
+	    } while (*expr && strchr("-.1234567890", *expr));
+	    expr--;
+	    *v = '\0';
+	    
+	    sscanf(value, "%f", &floatval);
+
+	    infix = g_slist_append(infix, new_value(floatval));
+	} else if (!isspace(*expr)) {
+	    g_print("Invalid token: [%c][%d]\n", *expr, *expr);
+	    math_infix_free(infix, TRUE);
+	    return NULL;
+	}
+    }
+
+    return infix;
+}
+
+void math_infix_free(GSList * infix, gboolean free_tokens)
+{
+    GSList *p;
+
+    if (!free_tokens)
+	for (p = infix; p; p = g_slist_delete_link(p, p));
+    else
+	for (p = infix; p; p = g_slist_delete_link(p, p)) {
+	    MathToken *t = (MathToken *) p->data;
+	    g_free(t);
+	}
+}
+
+GSList *math_string_to_postfix(gchar * string)
+{
+    GSList *infix;
+    GSList *postfix;
+
+    infix = math_string_to_infix(string);
+    if (!infix)
+	return NULL;
+
+    postfix = math_infix_to_postfix(infix);
+    math_infix_free(infix, FALSE);
+
+    return postfix;
+}
+
+gfloat math_string_eval(gchar * string, gfloat at_value)
+{
+    GSList *postfix;
+    gfloat val;
+
+    postfix = math_string_to_postfix(string);
+    val = math_postfix_eval(postfix, at_value);
+    math_postfix_free(postfix, TRUE);
+
+    return val;
+}
+
+#ifdef MATH_TEST
+int main(void)
+{
+    GSList *postfix;
+
+    gchar *expr = "0.9*(@+(5.2*0.923+3*(2.0)))";
+
+    postfix = math_string_to_postfix(expr);
+    g_print("%s = %f (must be 18.71964)\n", expr,
+	    math_postfix_eval(postfix, 10));
+    math_postfix_free(postfix, TRUE);
+
+    return 0;
+}
+#endif
diff --git a/hardinfo/hardinfo.c b/hardinfo/hardinfo.c
new file mode 100644
index 0000000..b3bef9b
--- /dev/null
+++ b/hardinfo/hardinfo.c
@@ -0,0 +1,160 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <config.h>
+#include <shell.h>
+
+#include <report.h>
+#include <hardinfo.h>
+#include <iconcache.h>
+#include <stock.h>
+#include <vendor.h>
+
+#include <binreloc.h>
+
+ProgramParameters params = { 0 };
+
+int main(int argc, char **argv)
+{
+    GSList *modules;
+
+    setlocale(LC_ALL, "");
+    bindtextdomain("hardinfo", LOCALEDIR);
+    textdomain("hardinfo");
+
+    DEBUG("HardInfo version " VERSION ". Debug version.");
+
+    /* parse all command line parameters */
+    parameters_init(&argc, &argv, &params);
+
+    /* show version information and quit */
+    if (params.show_version) {
+        g_print("HardInfo version " VERSION "\n");
+        g_print
+            (_(/*/ %d will be latest year of copyright*/ "Copyright (C) 2003-%d Leandro A. F. Pereira. See COPYING for details.\n\n"), HARDINFO_COPYRIGHT_LATEST_YEAR );
+
+	g_print(_("Compile-time options:\n"
+		"  Release version:   %s (%s)\n"
+		"  BinReloc enabled:  %s\n"
+		"  Data prefix:       %s\n"
+		"  Library prefix:    %s\n"
+		"  Compiled for:      %s\n"),
+		RELEASE ? _("Yes") : "No (" VERSION ")", ARCH,
+		ENABLE_BINRELOC ? _("Yes") : _("No"),
+		PREFIX, LIBPREFIX, PLATFORM);
+
+	DEBUG("  Debugging is enabled.");
+
+	/* show also available modules */
+	params.list_modules = TRUE;
+    }
+
+    /* initialize the binreloc library, so we can load program data */
+    if (!binreloc_init(FALSE))
+	g_error(_("Failed to find runtime data.\n\n"
+		"\342\200\242 Is HardInfo correctly installed?\n"
+		"\342\200\242 See if %s and %s exists and you have read permission."),
+		PREFIX, LIBPREFIX);
+
+    /* list all module names */
+    if (params.list_modules) {
+	g_print(_("Modules:\n"
+		"%-20s %-15s %-12s\n"), _("File Name"), _("Name"), _("Version"));
+
+	for (modules = modules_load_all(); modules;
+	     modules = modules->next) {
+	    ShellModule *module = (ShellModule *) modules->data;
+	    ModuleAbout *ma = module_get_about(module);
+	    gchar *name = g_path_get_basename(g_module_name(module->dll));
+
+	    g_print("%-20s %-15s %-12s\n", name, module->name, ma->version);
+
+	    g_free(name);
+	}
+
+	return 0;
+    }
+
+    if (!params.create_report && !params.run_benchmark) {
+	/* we only try to open the UI if the user didn't ask for a report. */
+	params.gui_running = ui_init(&argc, &argv);
+
+	/* as a fallback, if GTK+ initialization failed, run in report
+	   generation mode. */
+	if (!params.gui_running)
+	    params.create_report = TRUE;
+    }
+
+    if (params.use_modules) {
+	/* load only selected modules */
+	DEBUG("loading user-selected modules");
+	modules = modules_load_selected();
+    } else {
+	/* load all modules */
+	DEBUG("loading all modules");
+	modules = modules_load_all();
+    }
+
+    /* initialize vendor database */
+    vendor_init();
+
+    /* initialize moreinfo */
+    moreinfo_init();
+
+    if (params.run_benchmark) {
+        gchar *result;
+
+        result = module_call_method_param("benchmark::runBenchmark", params.run_benchmark);
+        if (!result) {
+          g_error(_("Unknown benchmark ``%s'' or benchmark.so not loaded"), params.run_benchmark);
+        } else {
+          fprintf(stderr, "\n");
+          g_print("%s\n", result);
+          g_free(result);
+        }
+    } else if (params.gui_running) {
+	/* initialize gui and start gtk+ main loop */
+	icon_cache_init();
+	stock_icons_init();
+
+	shell_init(modules);
+
+	DEBUG("entering gtk+ main loop");
+
+	gtk_main();
+    } else if (params.create_report) {
+	/* generate report */
+	gchar *report;
+
+	DEBUG("generating report");
+
+	report = report_create_from_module_list_format(modules,
+						       params.
+						       report_format);
+	g_print("%s", report);
+
+	g_free(report);
+    } else {
+        g_error(_("Don't know what to do. Exiting."));
+    }
+
+    moreinfo_shutdown();
+
+    DEBUG("finished");
+    return 0;
+}
diff --git a/hardinfo/info.c b/hardinfo/info.c
new file mode 100644
index 0000000..0bbf7a0
--- /dev/null
+++ b/hardinfo/info.c
@@ -0,0 +1,249 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2017 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+
+static const gchar *info_column_titles[] = {
+    "TextValue", "Value", "Progress", "Extra1", "Extra2"
+};
+
+struct Info *info_new(void)
+{
+    struct Info *info = g_new0(struct Info, 1);
+
+    info->groups = g_array_new(FALSE, FALSE, sizeof(struct InfoGroup));
+    info->view_type = SHELL_VIEW_NORMAL;
+    info->column_headers_visible = FALSE;
+    info->zebra_visible = FALSE;
+    info->normalize_percentage = TRUE;
+
+    return info;
+}
+
+void info_add_group(struct Info *info, const gchar *group_name, ...)
+{
+    struct InfoGroup group = {
+        .name = group_name,
+        .fields = g_array_new(FALSE, FALSE, sizeof(struct InfoField))
+    };
+    va_list ap;
+
+    va_start(ap, group_name);
+    while (1) {
+        struct InfoField field = va_arg(ap, struct InfoField );
+
+        if (!field.name)
+            break;
+        g_array_append_val(group.fields, field);
+    }
+    va_end(ap);
+
+    g_array_append_val(info->groups, group);
+}
+
+struct InfoField info_field(const gchar *name, gchar *value)
+{
+    return (struct InfoField) {
+        .name = name,
+        .value = value,
+    };
+}
+
+struct InfoField info_field_update(const gchar *name, int update_interval)
+{
+    return (struct InfoField) {
+        .name = name,
+        .value = "...",
+        .update_interval = update_interval,
+    };
+}
+
+struct InfoField info_field_printf(const gchar *name, const gchar *format, ...)
+{
+    gchar *value;
+    va_list ap;
+
+    va_start(ap, format);
+    value = g_strdup_vprintf(format, ap);
+    va_end(ap);
+
+    return (struct InfoField) {
+        .name = name,
+        .value = value,
+        .free_value_on_flatten = TRUE,
+    };
+}
+
+struct InfoField info_field_last(void)
+{
+    return (struct InfoField) {};
+}
+
+void info_add_computed_group(struct Info *info, const gchar *name, const gchar *value)
+{
+    /* This is a scaffolding method: HardInfo should move away from pre-computing
+     * the strings in favor of storing InfoGroups instead; while modules are not
+     * fully converted, use this instead. */
+    struct InfoGroup group = {
+        .name = name,
+        .computed = value,
+    };
+
+    g_array_append_val(info->groups, group);
+}
+
+void info_set_column_title(struct Info *info, const gchar *column, const gchar *title)
+{
+    int i;
+
+    for (i = 0; i < G_N_ELEMENTS(info_column_titles); i++) {
+        if (g_str_equal(info_column_titles[i], column)) {
+            info->column_titles[i] = title;
+            return;
+        }
+    }
+}
+
+void info_set_column_headers_visible(struct Info *info, gboolean setting)
+{
+    info->column_headers_visible = setting;
+}
+
+void info_set_zebra_visible(struct Info *info, gboolean setting)
+{
+    info->zebra_visible = setting;
+}
+
+void info_set_normalize_percentage(struct Info *info, gboolean setting)
+{
+    info->normalize_percentage = setting;
+}
+
+void info_set_view_type(struct Info *info, ShellViewType setting)
+{
+    info->view_type = setting;
+}
+
+void info_set_reload_interval(struct Info *info, int setting)
+{
+    info->reload_interval = setting;
+}
+
+static void flatten_group(GString *output, const struct InfoGroup *group)
+{
+    guint i;
+
+    if (group->name != NULL)
+        g_string_append_printf(output, "[%s]\n", group->name);
+
+    if (group->fields) {
+        for (i = 0; i < group->fields->len; i++) {
+            struct InfoField field;
+
+            field = g_array_index(group->fields, struct InfoField, i);
+
+            g_string_append_printf(output, "%s=%s\n", field.name, field.value);
+
+            if (field.free_value_on_flatten)
+                g_free(field.value);
+        }
+    } else if (group->computed) {
+        g_string_append_printf(output, "%s\n", group->computed);
+    }
+}
+
+static void flatten_shell_param(GString *output, const struct InfoGroup *group)
+{
+    guint i;
+
+    if (!group->fields)
+        return;
+
+    for (i = 0; i < group->fields->len; i++) {
+        struct InfoField field;
+
+        field = g_array_index(group->fields, struct InfoField, i);
+
+        if (field.update_interval) {
+            g_string_append_printf(output, "UpdateInterval$%s=%d\n",
+                field.name, field.update_interval);
+        }
+    }
+}
+
+static void flatten_shell_param_global(GString *output, const struct Info *info)
+{
+    int i;
+
+    g_string_append_printf(output, "ViewType=%d\n", info->view_type);
+    g_string_append_printf(output, "ShowColumnHeaders=%s\n",
+        info->column_headers_visible ? "true" : "false");
+
+    if (info->zebra_visible)
+        g_string_append(output, "Zebra=1\n");
+
+    if (info->reload_interval)
+        g_string_append_printf(output, "ReloadInterval=%d\n", info->reload_interval);
+
+    if (!info->normalize_percentage)
+        g_string_append(output, "NormalizePercentage=false\n");
+
+    for (i = 0; i < G_N_ELEMENTS(info_column_titles); i++) {
+        if (!info->column_titles[i])
+            continue;
+
+        g_string_append_printf(output, "ColumnTitle$%s=%s\n",
+            info_column_titles[i], info->column_titles[i]);
+    }
+}
+
+gchar *info_flatten(struct Info *info)
+{
+    /* This is a scaffolding method: eventually the HardInfo shell should
+     * understand a struct Info instead of parsing these strings, which are
+     * brittle and unnecessarily complicates things.  Being a temporary
+     * method, no attention is paid to improve the memory allocation
+     * strategy. */
+    GString *values;
+    GString *shell_param;
+    guint i;
+
+    values = g_string_new(NULL);
+    shell_param = g_string_new(NULL);
+
+    if (info->groups) {
+        for (i = 0; i < info->groups->len; i++) {
+            struct InfoGroup group =
+                g_array_index(info->groups, struct InfoGroup, i);
+
+            flatten_group(values, &group);
+            flatten_shell_param(shell_param, &group);
+
+            if (group.fields)
+                g_array_free(group.fields, TRUE);
+        }
+
+        g_array_free(info->groups, TRUE);
+    }
+
+    flatten_shell_param_global(shell_param, info);
+    g_string_append_printf(values, "[$ShellParam$]\n%s", shell_param->str);
+
+    g_string_free(shell_param, TRUE);
+    return g_string_free(values, FALSE);
+}
diff --git a/hardinfo/socket.c b/hardinfo/socket.c
new file mode 100644
index 0000000..40cb8e5
--- /dev/null
+++ b/hardinfo/socket.c
@@ -0,0 +1,127 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "socket.h"
+
+Socket *sock_connect(gchar * host, gint port)
+{
+    struct sockaddr_in server;
+    Socket *s;
+    int sock;
+
+    sock = socket(AF_INET, SOCK_STREAM, 0);
+    if (sock > 0) {
+	memset(&server, 0, sizeof(server));
+	server.sin_family = AF_INET;
+	server.sin_addr.s_addr = inet_addr(host);
+	server.sin_port = htons(port);
+
+	if (connect(sock, (struct sockaddr *) (void *) &server, sizeof(server)) < 0) {
+	     goto cleanup;
+	}
+
+	s = g_new0(Socket, 1);
+	s->sock = sock;
+
+	return s;
+    }
+
+cleanup:    
+    close(sock);
+
+    return NULL;
+}
+
+/* From: http://www.erlenstar.demon.co.uk/unix/faq_3.html#SEC26 */
+static inline int __sock_is_ready(Socket * s, int mode)
+{
+    int rc, fd = s->sock;
+    fd_set fds;
+    struct timeval tv;
+
+    FD_ZERO(&fds);
+    FD_SET(fd, &fds);
+    tv.tv_sec = tv.tv_usec = 0;
+
+    if (mode == 0) {
+	/* read */
+	rc = select(fd + 1, &fds, NULL, NULL, &tv);
+    } else {
+	/* write */
+	rc = select(fd + 1, NULL, &fds, NULL, &tv);
+    }
+
+    if (rc < 0)
+	return -1;
+
+    return FD_ISSET(fd, &fds) ? 1 : 0;
+}
+
+int sock_ready_to_read(Socket * s)
+{
+    return __sock_is_ready(s, 0);
+}
+
+int sock_ready_to_write(Socket * s)
+{
+    return __sock_is_ready(s, 1);
+}
+
+int sock_read(Socket * s, gchar * buffer, gint size)
+{
+    if (size > 2 && sock_ready_to_read(s)) {
+	gint n;
+
+	n = read(s->sock, buffer, size - 1);
+	if (n > 0) {
+            buffer[n] = '\0';
+        } else {
+            return 0;
+        }
+
+	return n;
+    }
+
+    return 0;
+}
+
+int sock_write(Socket * s, gchar * str)
+{
+    while (!sock_ready_to_write(s));
+
+    return write(s->sock, str, strlen(str));
+}
+
+void sock_close(Socket * s)
+{
+    shutdown(s->sock, 2);
+    close(s->sock);
+    g_free(s);
+}
diff --git a/hardinfo/util.c b/hardinfo/util.c
new file mode 100644
index 0000000..7bcc5dd
--- /dev/null
+++ b/hardinfo/util.c
@@ -0,0 +1,1389 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/*
+ * Functions h_strdup_cprintf and h_strconcat are based on GLib version 2.4.6
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <config.h>
+
+#include <report.h>
+#include <string.h>
+#include <shell.h>
+#include <iconcache.h>
+#include <hardinfo.h>
+#include <gtk/gtk.h>
+
+#include <binreloc.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#define KiB 1024
+#define MiB 1048576
+#define GiB 1073741824
+#define TiB 1099511627776
+#define PiB 1125899906842624
+
+static GSList *modules_list = NULL;
+
+void sync_manager_clear_entries(void);
+
+gchar *find_program(gchar *program_name)
+{
+    int i;
+    char *temp;
+    static GHashTable *cache = NULL;
+    const char *path[] = { "/usr/local/bin", "/usr/local/sbin",
+		                   "/usr/bin", "/usr/sbin",
+		                   "/bin", "/sbin",
+		                   NULL };
+
+    /* we don't need to call stat() every time: cache the results */
+    if (!cache) {
+    	cache = g_hash_table_new(g_str_hash, g_str_equal);
+    } else if ((temp = g_hash_table_lookup(cache, program_name))) {
+    	return g_strdup(temp);
+    }
+
+    for (i = 0; path[i]; i++) {
+    	temp = g_build_filename(path[i], program_name, NULL);
+
+    	if (g_file_test(temp, G_FILE_TEST_IS_EXECUTABLE)) {
+    		g_hash_table_insert(cache, program_name, g_strdup(temp));
+		return temp;
+    	}
+
+    	g_free(temp);
+    }
+
+    /* our search has failed; use GLib's search (which uses $PATH env var) */
+    if ((temp = g_find_program_in_path(program_name))) {
+    	g_hash_table_insert(cache, program_name, g_strdup(temp));
+    	return temp;
+    }
+
+    return NULL;
+}
+
+gchar *seconds_to_string(unsigned int seconds)
+{
+    unsigned int hours, minutes, days;
+    const gchar *days_fmt, *hours_fmt, *minutes_fmt, *seconds_fmt;
+    gchar *full_fmt, *ret = g_strdup("");
+
+    minutes = seconds / 60;
+    seconds %= 60;
+    hours = minutes / 60;
+    minutes %= 60;
+    days = hours / 24;
+    hours %= 24;
+
+    days_fmt = ngettext("%d day", "%d days", days);
+    hours_fmt = ngettext("%d hour", "%d hours", hours);
+    minutes_fmt = ngettext("%d minute", "%d minutes", minutes);
+    seconds_fmt = ngettext("%d second", "%d seconds", seconds);
+
+    if (days) {
+        full_fmt = g_strdup_printf("%s %s %s %s", days_fmt, hours_fmt, minutes_fmt, seconds_fmt);
+        ret = g_strdup_printf(full_fmt, days, hours, minutes, seconds);
+    } else if (hours) {
+        full_fmt = g_strdup_printf("%s %s %s", hours_fmt, minutes_fmt, seconds_fmt);
+        ret = g_strdup_printf(full_fmt, hours, minutes, seconds);
+    } else if (minutes) {
+        full_fmt = g_strdup_printf("%s %s", minutes_fmt, seconds_fmt);
+        ret = g_strdup_printf(full_fmt, minutes, seconds);
+    } else {
+        ret = g_strdup_printf(seconds_fmt, seconds);
+    }
+    g_free(full_fmt);
+    return ret;
+}
+
+gchar *size_human_readable(gfloat size)
+{
+    if (size < KiB)
+        return g_strdup_printf(_("%.1f B"), size);
+    if (size < MiB)
+        return g_strdup_printf(_("%.1f KiB"), size / KiB);
+    if (size < GiB)
+        return g_strdup_printf(_("%.1f MiB"), size / MiB);
+    if (size < TiB)
+        return g_strdup_printf(_("%.1f GiB"), size / GiB);
+    if (size < PiB)
+        return g_strdup_printf(_("%.1f TiB"), size / TiB);
+
+    return g_strdup_printf(_("%.1f PiB"), size / PiB);
+}
+
+char *strend(gchar * str, gchar chr)
+{
+    if (!str)
+	return NULL;
+
+    char *p;
+    if ((p = g_utf8_strchr(str, -1, chr)))
+	*p = 0;
+
+    return str;
+}
+
+void remove_quotes(gchar * str)
+{
+    if (!str)
+	return;
+
+    while (*str == '"')
+	*(str++) = ' ';
+
+    strend(str, '"');
+}
+
+void remove_linefeed(gchar * str)
+{
+    strend(str, '\n');
+}
+
+void widget_set_cursor(GtkWidget * widget, GdkCursorType cursor_type)
+{
+    GdkCursor *cursor;
+    GdkDisplay *display;
+    GdkWindow *gdk_window;
+
+    display = gtk_widget_get_display(widget);
+    cursor = gdk_cursor_new_for_display(display, cursor_type);
+    gdk_window = gtk_widget_get_window(widget);
+    if (cursor) {
+        gdk_window_set_cursor(gdk_window, cursor);
+        gdk_display_flush(display);
+#if GTK_CHECK_VERSION(3, 0, 0)
+        g_object_unref(cursor);
+#else
+        gdk_cursor_unref(cursor);
+#endif
+    }
+
+    while (gtk_events_pending())
+        gtk_main_iteration();
+}
+
+static gboolean __nonblock_cb(gpointer data)
+{
+    gtk_main_quit();
+    return FALSE;
+}
+
+void nonblock_sleep(guint msec)
+{
+    g_timeout_add(msec, (GSourceFunc) __nonblock_cb, NULL);
+    gtk_main();
+}
+
+static void __expand_cb(GtkWidget * widget, gpointer data)
+{
+    if (GTK_IS_EXPANDER(widget)) {
+	gtk_expander_set_expanded(GTK_EXPANDER(widget), TRUE);
+    } else if (GTK_IS_CONTAINER(widget)) {
+	gtk_container_foreach(GTK_CONTAINER(widget),
+			      (GtkCallback) __expand_cb, NULL);
+    }
+}
+
+void file_chooser_open_expander(GtkWidget * chooser)
+{
+    gtk_container_foreach(GTK_CONTAINER(chooser),
+			  (GtkCallback) __expand_cb, NULL);
+}
+
+void file_chooser_add_filters(GtkWidget * chooser, FileTypes * filters)
+{
+    GtkFileFilter *filter;
+    gint i;
+
+    for (i = 0; filters[i].name; i++) {
+	filter = gtk_file_filter_new();
+	gtk_file_filter_add_mime_type(filter, filters[i].mime_type);
+	gtk_file_filter_set_name(filter, filters[i].name);
+	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser), filter);
+    }
+}
+
+gchar *file_chooser_get_extension(GtkWidget * chooser, FileTypes * filters)
+{
+    GtkFileFilter *filter;
+    const gchar *filter_name;
+    gint i;
+
+    filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(chooser));
+    filter_name = gtk_file_filter_get_name(filter);
+    for (i = 0; filters[i].name; i++) {
+	if (g_str_equal(filter_name, filters[i].name)) {
+	    return filters[i].extension;
+	}
+    }
+
+    return NULL;
+}
+
+gpointer file_types_get_data_by_name(FileTypes * filters, gchar * filename)
+{
+    gint i;
+
+    for (i = 0; filters[i].name; i++) {
+	if (g_str_has_suffix(filename, filters[i].extension)) {
+	    return filters[i].data;
+	}
+    }
+
+    return NULL;
+}
+
+gchar *file_chooser_build_filename(GtkWidget * chooser, gchar * extension)
+{
+    gchar *filename =
+	gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
+    gchar *retval;
+
+    if (g_str_has_suffix(filename, extension)) {
+	return filename;
+    }
+
+    retval = g_strconcat(filename, extension, NULL);
+    g_free(filename);
+
+    return retval;
+}
+
+gboolean binreloc_init(gboolean try_hardcoded)
+{
+    GError *error = NULL;
+    gchar *tmp;
+
+    DEBUG("initializing binreloc (hardcoded = %d)", try_hardcoded);
+
+    /* If the runtime data directories we previously found, don't even try
+       to find them again. */
+    if (params.path_data && params.path_lib) {
+	DEBUG("data and lib path already found.");
+	return TRUE;
+    }
+
+    if (try_hardcoded || !gbr_init(&error)) {
+	/* We were asked to try hardcoded paths or BinReloc failed to initialize. */
+	params.path_data = g_strdup(PREFIX);
+	params.path_lib = g_strdup(LIBPREFIX);
+
+	if (error) {
+	    g_error_free(error);
+	}
+
+	DEBUG("%strying hardcoded paths.",
+	      try_hardcoded ? "" : "binreloc init failed. ");
+    } else {
+	/* If we were able to initialize BinReloc, build the default data
+	   and library paths. */
+	DEBUG("done, trying to use binreloc paths.");
+
+	tmp = gbr_find_data_dir(PREFIX);
+	params.path_data = g_build_filename(tmp, "hardinfo", NULL);
+	g_free(tmp);
+
+	tmp = gbr_find_lib_dir(PREFIX);
+	params.path_lib = g_build_filename(tmp, "hardinfo", NULL);
+	g_free(tmp);
+    }
+
+    DEBUG("searching for runtime data on these locations:");
+    DEBUG("  lib: %s", params.path_lib);
+    DEBUG(" data: %s", params.path_data);
+
+    /* Try to see if the uidefs.xml file isn't missing. This isn't the
+       definitive test, but it should do okay for most situations. */
+    tmp = g_build_filename(params.path_data, "benchmark.data", NULL);
+    if (!g_file_test(tmp, G_FILE_TEST_EXISTS)) {
+	DEBUG("runtime data not found");
+
+	g_free(params.path_data);
+	g_free(params.path_lib);
+	g_free(tmp);
+
+	params.path_data = params.path_lib = NULL;
+
+	if (try_hardcoded) {
+	    /* We tried the hardcoded paths, but still was unable to find the
+	       runtime data. Give up. */
+	    DEBUG("giving up");
+	    return FALSE;
+	} else {
+	    /* Even though BinReloc worked OK, the runtime data was not found.
+	       Try the hardcoded paths. */
+	    DEBUG("trying to find elsewhere");
+	    return binreloc_init(TRUE);
+	}
+    }
+    g_free(tmp);
+
+    DEBUG("runtime data found!");
+    /* We found the runtime data; hope everything is fine */
+    return TRUE;
+}
+
+static void
+log_handler(const gchar * log_domain,
+	    GLogLevelFlags log_level,
+	    const gchar * message, gpointer user_data)
+{
+    if (!params.gui_running) {
+	/* No GUI running: spit the message to the terminal */
+	g_print("\n\n*** %s: %s\n\n",
+		(log_level & G_LOG_FLAG_FATAL) ? _("Error") : _("Warning"),
+		message);
+    } else {
+	/* Hooray! We have a GUI running! */
+	GtkWidget *dialog;
+
+	dialog = gtk_message_dialog_new_with_markup(NULL, GTK_DIALOG_MODAL,
+						    (log_level &
+						     G_LOG_FLAG_FATAL) ?
+						    GTK_MESSAGE_ERROR :
+						    GTK_MESSAGE_WARNING,
+						    GTK_BUTTONS_CLOSE,
+						    "<big><b>%s</b></big>\n\n%s",
+						    (log_level &
+						     G_LOG_FLAG_FATAL) ?
+						    _("Fatal Error") :
+						    _("Warning"), message);
+
+	gtk_dialog_run(GTK_DIALOG(dialog));
+	gtk_widget_destroy(dialog);
+    }
+}
+
+void parameters_init(int *argc, char ***argv, ProgramParameters * param)
+{
+    static gboolean create_report = FALSE;
+    static gboolean show_version = FALSE;
+    static gboolean list_modules = FALSE;
+    static gboolean autoload_deps = FALSE;
+    static gboolean run_xmlrpc_server = FALSE;
+    static gchar *report_format = NULL;
+    static gchar *run_benchmark = NULL;
+    static gchar *result_format = NULL;
+    static gchar **use_modules = NULL;
+
+    static GOptionEntry options[] = {
+	{
+	 .long_name = "generate-report",
+	 .short_name = 'r',
+	 .arg = G_OPTION_ARG_NONE,
+	 .arg_data = &create_report,
+	 .description = N_("creates a report and prints to standard output")},
+	{
+	 .long_name = "report-format",
+	 .short_name = 'f',
+	 .arg = G_OPTION_ARG_STRING,
+	 .arg_data = &report_format,
+	 .description = N_("chooses a report format (text, html)")},
+	{
+	 .long_name = "run-benchmark",
+	 .short_name = 'b',
+	 .arg = G_OPTION_ARG_STRING,
+	 .arg_data = &run_benchmark,
+	 .description = N_("run benchmark; requires benchmark.so to be loaded")},
+	{
+	 .long_name = "result-format",
+	 .short_name = 'g',
+	 .arg = G_OPTION_ARG_STRING,
+	 .arg_data = &result_format,
+	 .description = N_("benchmark result format ([short], conf, shell)")},
+	{
+	 .long_name = "list-modules",
+	 .short_name = 'l',
+	 .arg = G_OPTION_ARG_NONE,
+	 .arg_data = &list_modules,
+	 .description = N_("lists modules")},
+	{
+	 .long_name = "load-module",
+	 .short_name = 'm',
+	 .arg = G_OPTION_ARG_STRING_ARRAY,
+	 .arg_data = &use_modules,
+	 .description = N_("specify module to load")},
+	{
+	 .long_name = "autoload-deps",
+	 .short_name = 'a',
+	 .arg = G_OPTION_ARG_NONE,
+	 .arg_data = &autoload_deps,
+	 .description = N_("automatically load module dependencies")},
+#ifdef HAS_LIBSOUP
+	{
+	 .long_name = "xmlrpc-server",
+	 .short_name = 'x',
+	 .arg = G_OPTION_ARG_NONE,
+	 .arg_data = &run_xmlrpc_server,
+	 .description = N_("run in XML-RPC server mode")},
+#endif	/* HAS_LIBSOUP */
+	{
+	 .long_name = "version",
+	 .short_name = 'v',
+	 .arg = G_OPTION_ARG_NONE,
+	 .arg_data = &show_version,
+	 .description = N_("shows program version and quit")},
+	{NULL}
+    };
+    GOptionContext *ctx;
+
+    ctx = g_option_context_new(_("- System Profiler and Benchmark tool"));
+    g_option_context_set_ignore_unknown_options(ctx, FALSE);
+    g_option_context_set_help_enabled(ctx, TRUE);
+
+    g_option_context_add_main_entries(ctx, options, *(argv)[0]);
+    g_option_context_parse(ctx, argc, argv, NULL);
+
+    g_option_context_free(ctx);
+
+    if (*argc >= 2) {
+	g_print(_("Unrecognized arguments.\n"
+		"Try ``%s --help'' for more information.\n"), *(argv)[0]);
+	exit(1);
+    }
+
+    param->create_report = create_report;
+    param->report_format = REPORT_FORMAT_TEXT;
+    param->show_version = show_version;
+    param->list_modules = list_modules;
+    param->use_modules = use_modules;
+    param->run_benchmark = run_benchmark;
+    param->result_format = result_format;
+    param->autoload_deps = autoload_deps;
+    param->run_xmlrpc_server = run_xmlrpc_server;
+    param->argv0 = *(argv)[0];
+
+    if (report_format && g_str_equal(report_format, "html"))
+	param->report_format = REPORT_FORMAT_HTML;
+
+    gchar *confdir = g_build_filename(g_get_home_dir(), ".hardinfo", NULL);
+    if (!g_file_test(confdir, G_FILE_TEST_EXISTS)) {
+	mkdir(confdir, 0744);
+    }
+    g_free(confdir);
+}
+
+gboolean ui_init(int *argc, char ***argv)
+{
+    DEBUG("initializing gtk+ UI");
+
+    g_set_application_name("HardInfo");
+    g_log_set_handler(NULL,
+		      G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL |
+		      G_LOG_LEVEL_ERROR, log_handler, NULL);
+
+    return gtk_init_check(argc, argv);
+}
+
+void open_url(gchar * url)
+{
+    const gchar *browsers[] = {
+	"xdg-open", "gnome-open", "kfmclient openURL",
+	"sensible-browser", "firefox", "epiphany",
+	"iceweasel", "seamonkey", "galeon", "mozilla",
+	"opera", "konqueror", "netscape", "links -g",
+	NULL
+    };
+    gint i = 0;
+    gchar *browser = (gchar *)g_getenv("BROWSER");
+
+    if (!browser || *browser == '\0') {
+    	browser = (gchar *)browsers[i++];
+    }
+
+    do {
+	gchar *cmdline = g_strdup_printf("%s '%s'", browser, url);
+
+	if (g_spawn_command_line_async(cmdline, NULL)) {
+	    g_free(cmdline);
+	    return;
+	}
+
+	g_free(cmdline);
+
+    	browser = (gchar *)browsers[i++];
+    } while (browser);
+
+    g_warning(_("Couldn't find a Web browser to open URL %s."), url);
+}
+
+/* Copyright: Jens Låås, SLU 2002 */
+gchar *strreplacechr(gchar * string, gchar * replace, gchar new_char)
+{
+    gchar *s;
+    for (s = string; *s; s++)
+	if (strchr(replace, *s))
+	    *s = new_char;
+
+    return string;
+}
+
+gchar *strreplace(gchar *string, gchar *replace, gchar *replacement)
+{
+    gchar **tmp, *ret;
+
+    tmp = g_strsplit(string, replace, 0);
+    ret = g_strjoinv(replacement, tmp);
+    g_strfreev(tmp);
+
+    return ret;
+}
+
+static GHashTable *__module_methods = NULL;
+
+static void module_register_methods(ShellModule * module)
+{
+    ShellModuleMethod *(*get_methods) (void);
+    gchar *method_name;
+
+    if (__module_methods == NULL) {
+	__module_methods = g_hash_table_new(g_str_hash, g_str_equal);
+    }
+
+    if (g_module_symbol
+	(module->dll, "hi_exported_methods", (gpointer) & get_methods)) {
+	ShellModuleMethod *methods;
+
+	for (methods = get_methods(); methods->name; methods++) {
+	    ShellModuleMethod method = *methods;
+	    gchar *name = g_path_get_basename(g_module_name(module->dll));
+	    gchar *simple_name = strreplace(name, "lib", "");
+
+	    strend(simple_name, '.');
+
+	    method_name = g_strdup_printf("%s::%s", simple_name, method.name);
+	    g_hash_table_insert(__module_methods, method_name,
+				method.function);
+	    g_free(name);
+	    g_free(simple_name);
+	}
+    }
+
+}
+
+gchar *module_call_method(gchar * method)
+{
+    gchar *(*function) (void);
+
+    if (__module_methods == NULL) {
+	return NULL;
+    }
+
+    function = g_hash_table_lookup(__module_methods, method);
+    return function ? g_strdup(function()) : NULL;
+}
+
+/* FIXME: varargs? */
+gchar *module_call_method_param(gchar * method, gchar * parameter)
+{
+    gchar *(*function) (gchar *param);
+
+    if (__module_methods == NULL) {
+	return NULL;
+    }
+
+    function = g_hash_table_lookup(__module_methods, method);
+    return function ? g_strdup(function(parameter)) : NULL;
+}
+
+static gboolean remove_module_methods(gpointer key, gpointer value, gpointer data)
+{
+    return g_str_has_prefix(key, data);
+}
+
+static void module_unload(ShellModule * module)
+{
+    GSList *entry;
+
+    if (module->dll) {
+        gchar *name;
+
+        if (module->deinit) {
+        	DEBUG("cleaning up module \"%s\"", module->name);
+		module->deinit();
+	} else {
+		DEBUG("module \"%s\" does not need cleanup", module->name);
+	}
+
+        name = g_path_get_basename(g_module_name(module->dll));
+        g_hash_table_foreach_remove(__module_methods, remove_module_methods, name);
+
+    	g_module_close(module->dll);
+    	g_free(name);
+    }
+
+    g_free(module->name);
+    g_object_unref(module->icon);
+
+    for (entry = module->entries; entry; entry = entry->next) {
+	ShellModuleEntry *e = (ShellModuleEntry *)entry->data;
+
+	g_source_remove_by_user_data(e);
+    	g_free(e);
+    }
+
+    g_slist_free(module->entries);
+    g_free(module);
+}
+
+
+void module_unload_all(void)
+{
+    Shell *shell;
+    GSList *module, *merge_id;
+
+    shell = shell_get_main_shell();
+
+    sync_manager_clear_entries();
+    shell_clear_timeouts(shell);
+    shell_clear_tree_models(shell);
+    shell_clear_field_updates();
+    shell_set_title(shell, NULL);
+
+    for (module = shell->tree->modules; module; module = module->next) {
+    	module_unload((ShellModule *)module->data);
+    }
+
+    for (merge_id = shell->merge_ids; merge_id; merge_id = merge_id->next) {
+    	gtk_ui_manager_remove_ui(shell->ui_manager,
+			         GPOINTER_TO_INT(merge_id->data));
+    }
+    g_slist_free(shell->tree->modules);
+    g_slist_free(shell->merge_ids);
+
+    shell->merge_ids = NULL;
+    shell->tree->modules = NULL;
+    shell->selected = NULL;
+}
+
+static ShellModule *module_load(gchar * filename)
+{
+    ShellModule *module;
+    gchar *tmp;
+
+    module = g_new0(ShellModule, 1);
+
+    if (params.gui_running) {
+	gchar *tmpicon, *dot, *simple_name;
+
+	tmpicon = g_strdup(filename);
+	dot = g_strrstr(tmpicon, "." G_MODULE_SUFFIX);
+
+	*dot = '\0';
+
+	simple_name = strreplace(tmpicon, "lib", "");
+
+	tmp = g_strdup_printf("%s.png", simple_name);
+	module->icon = icon_cache_get_pixbuf(tmp);
+
+	g_free(tmp);
+	g_free(tmpicon);
+	g_free(simple_name);
+    }
+
+    tmp = g_build_filename(params.path_lib, "modules", filename, NULL);
+    module->dll = g_module_open(tmp, G_MODULE_BIND_LAZY);
+    DEBUG("gmodule resource for ``%s'' is %p", tmp, module->dll);
+    g_free(tmp);
+
+    if (module->dll) {
+	void (*init) (void);
+	ModuleEntry *(*get_module_entries) (void);
+	gint(*weight_func) (void);
+	gchar *(*name_func) (void);
+	ModuleEntry *entries;
+	gint i = 0;
+
+	if (!g_module_symbol(module->dll, "hi_module_get_entries", (gpointer) & get_module_entries) ||
+	    !g_module_symbol(module->dll, "hi_module_get_name",	(gpointer) & name_func)) {
+	    DEBUG("cannot find needed symbols; is ``%s'' a real module?", filename);
+	    goto failed;
+	}
+
+	if (g_module_symbol(module->dll, "hi_module_init", (gpointer) & init)) {
+	    DEBUG("initializing module ``%s''", filename);
+	    init();
+	}
+
+	g_module_symbol(module->dll, "hi_module_get_weight",
+			(gpointer) & weight_func);
+
+	module->weight = weight_func ? weight_func() : 0;
+	module->name = name_func();
+
+        g_module_symbol(module->dll, "hi_module_get_about",
+   	 	        (gpointer) & (module->aboutfunc));
+        g_module_symbol(module->dll, "hi_module_deinit",
+   	 	        (gpointer) & (module->deinit));
+        g_module_symbol(module->dll, "hi_module_get_summary",
+   	 	        (gpointer) & (module->summaryfunc));
+
+	entries = get_module_entries();
+	while (entries[i].name) {
+        if (*entries[i].name == '#') { i++; continue; } /* skip */
+
+	    ShellModuleEntry *entry = g_new0(ShellModuleEntry, 1);
+
+	    if (params.gui_running) {
+		entry->icon = icon_cache_get_pixbuf(entries[i].icon);
+	    }
+	    entry->icon_file = entries[i].icon;
+
+	    g_module_symbol(module->dll, "hi_more_info",
+			    (gpointer) & (entry->morefunc));
+	    g_module_symbol(module->dll, "hi_get_field",
+			    (gpointer) & (entry->fieldfunc));
+	    g_module_symbol(module->dll, "hi_note_func",
+			    (gpointer) & (entry->notefunc));
+
+	    entry->name = _(entries[i].name); //gettext unname N_() in computer.c line 67 etc...
+	    entry->scan_func = entries[i].scan_callback;
+	    entry->func = entries[i].callback;
+	    entry->number = i;
+	    entry->flags = entries[i].flags;
+
+	    module->entries = g_slist_append(module->entries, entry);
+
+	    i++;
+	}
+
+	DEBUG("registering methods for module ``%s''", filename);
+	module_register_methods(module);
+    } else {
+    	DEBUG("cannot g_module_open(``%s''). permission problem?", filename);
+      failed:
+	DEBUG("loading module %s failed: %s", filename, g_module_error());
+
+	g_free(module->name);
+	g_free(module);
+	module = NULL;
+    }
+
+    return module;
+}
+
+static gboolean module_in_module_list(gchar * module, gchar ** module_list)
+{
+    int i = 0;
+
+    if (!module_list)
+	return TRUE;
+
+    for (; module_list[i]; i++) {
+	if (g_str_equal(module_list[i], module))
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+static gint module_cmp(gconstpointer m1, gconstpointer m2)
+{
+    ShellModule *a = (ShellModule *) m1;
+    ShellModule *b = (ShellModule *) m2;
+
+    return a->weight - b->weight;
+}
+
+#if 0
+static void module_entry_free(gpointer data, gpointer user_data)
+{
+    ShellModuleEntry *entry = (ShellModuleEntry *) data;
+
+    if (entry) {
+	g_free(entry->name);
+	g_object_unref(entry->icon);
+
+	g_free(entry);
+    }
+}
+#endif
+
+ModuleAbout *module_get_about(ShellModule * module)
+{
+    if (module->aboutfunc) {
+    	return module->aboutfunc();
+    }
+
+    return NULL;
+}
+
+static GSList *modules_check_deps(GSList * modules)
+{
+    GSList *mm;
+    ShellModule *module;
+
+    for (mm = modules; mm; mm = mm->next) {
+	gchar **(*get_deps) (void);
+	gchar **deps;
+	gint i;
+
+	module = (ShellModule *) mm->data;
+
+	if (g_module_symbol(module->dll, "hi_module_get_dependencies",
+			    (gpointer) & get_deps)) {
+	    for (i = 0, deps = get_deps(); deps[i]; i++) {
+		GSList *l;
+		ShellModule *m;
+		gboolean found = FALSE;
+
+		for (l = modules; l && !found; l = l->next) {
+		    m = (ShellModule *) l->data;
+		    gchar *name = g_path_get_basename(g_module_name(m->dll));
+
+		    found = g_str_equal(name, deps[i]);
+		    g_free(name);
+		}
+
+		if (!found) {
+		    if (params.autoload_deps) {
+			ShellModule *mod = module_load(deps[i]);
+
+			if (mod)
+			    modules = g_slist_append(modules, mod);
+			modules = modules_check_deps(modules);	/* re-check dependencies */
+
+			break;
+		    }
+
+		    if (params.gui_running) {
+			GtkWidget *dialog;
+
+			dialog = gtk_message_dialog_new(NULL,
+							GTK_DIALOG_DESTROY_WITH_PARENT,
+							GTK_MESSAGE_QUESTION,
+							GTK_BUTTONS_NONE,
+							_("Module \"%s\" depends on module \"%s\", load it?"),
+							module->name,
+							deps[i]);
+			gtk_dialog_add_buttons(GTK_DIALOG(dialog),
+					       "_No",
+					       GTK_RESPONSE_REJECT,
+					       "_Open",
+					       GTK_RESPONSE_ACCEPT, NULL);
+
+			if (gtk_dialog_run(GTK_DIALOG(dialog)) ==
+			    GTK_RESPONSE_ACCEPT) {
+			    ShellModule *mod = module_load(deps[i]);
+
+			    if (mod)
+				modules = g_slist_prepend(modules, mod);
+			    modules = modules_check_deps(modules);	/* re-check dependencies */
+			} else {
+			    g_error("HardInfo cannot run without loading the additional module.");
+			    exit(1);
+			}
+
+			gtk_widget_destroy(dialog);
+		    } else {
+			g_error(_("Module \"%s\" depends on module \"%s\"."),
+				module->name, deps[i]);
+		    }
+		}
+	    }
+	}
+    }
+
+    return modules;
+}
+
+
+GSList *modules_get_list()
+{
+    return modules_list;
+}
+
+static GSList *modules_load(gchar ** module_list)
+{
+    GDir *dir;
+    GSList *modules = NULL;
+    ShellModule *module;
+    gchar *filename;
+
+    filename = g_build_filename(params.path_lib, "modules", NULL);
+    dir = g_dir_open(filename, 0, NULL);
+    g_free(filename);
+
+    if (dir) {
+	while ((filename = (gchar *) g_dir_read_name(dir))) {
+	    if (g_strrstr(filename, "." G_MODULE_SUFFIX) &&
+		module_in_module_list(filename, module_list) &&
+		((module = module_load(filename)))) {
+		modules = g_slist_prepend(modules, module);
+	    }
+	}
+
+	g_dir_close(dir);
+    }
+
+    modules = modules_check_deps(modules);
+
+    if (g_slist_length(modules) == 0) {
+	if (params.use_modules == NULL) {
+	    g_error
+		(_("No module could be loaded. Check permissions on \"%s\" and try again."),
+		 params.path_lib);
+	} else {
+	    g_error
+		(_("No module could be loaded. Please use hardinfo -l to list all avai"
+		 "lable modules and try again with a valid module list."));
+
+	}
+    }
+
+    modules_list = g_slist_sort(modules, module_cmp);
+    return modules_list;
+}
+
+GSList *modules_load_selected(void)
+{
+    return modules_load(params.use_modules);
+}
+
+GSList *modules_load_all(void)
+{
+    return modules_load(NULL);
+}
+
+gint tree_view_get_visible_height(GtkTreeView * tv)
+{
+    GtkTreePath *path;
+    GdkRectangle rect;
+    GtkTreeIter iter;
+    GtkTreeModel *model = gtk_tree_view_get_model(tv);
+    gint nrows = 1;
+
+    path = gtk_tree_path_new_first();
+    gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, &rect);
+
+    /* FIXME: isn't there any easier way to tell the number of rows? */
+    gtk_tree_model_get_iter_first(model, &iter);
+    do {
+	nrows++;
+    } while (gtk_tree_model_iter_next(model, &iter));
+
+    gtk_tree_path_free(path);
+
+    return nrows * rect.height;
+}
+
+static gboolean __idle_free_do(gpointer ptr)
+{
+    g_free(ptr);
+
+    return FALSE;
+}
+
+#if RELEASE == 1
+gpointer idle_free(gpointer ptr)
+#else
+gpointer __idle_free(gpointer ptr, gchar * f, gint l)
+#endif
+{
+    DEBUG("file: %s, line: %d, ptr %p", f, l, ptr);
+
+    if (ptr) {
+	g_timeout_add(10000, __idle_free_do, ptr);
+    }
+
+    return ptr;
+}
+
+void module_entry_scan_all_except(ModuleEntry * entries, gint except_entry)
+{
+    ModuleEntry entry;
+    gint i = 0;
+    void (*scan_callback) (gboolean reload);
+    gchar *text;
+
+    shell_view_set_enabled(FALSE);
+
+    for (entry = entries[0]; entry.name; entry = entries[++i]) {
+	if (i == except_entry)
+	    continue;
+
+	text = g_strdup_printf(_("Scanning: %s..."), _(entry.name));
+	shell_status_update(text);
+	g_free(text);
+
+	if ((scan_callback = entry.scan_callback)) {
+	    scan_callback(FALSE);
+	}
+    }
+
+    shell_view_set_enabled(TRUE);
+    shell_status_update(_("Done."));
+}
+
+void module_entry_scan_all(ModuleEntry * entries)
+{
+    module_entry_scan_all_except(entries, -1);
+}
+
+void module_entry_reload(ShellModuleEntry * module_entry)
+{
+
+    if (module_entry->scan_func) {
+	module_entry->scan_func(TRUE);
+    }
+}
+
+void module_entry_scan(ShellModuleEntry * module_entry)
+{
+    if (module_entry->scan_func) {
+	module_entry->scan_func(FALSE);
+    }
+}
+
+gchar *module_entry_get_field(ShellModuleEntry * module_entry, gchar * field)
+{
+   if (module_entry->fieldfunc) {
+   	return module_entry->fieldfunc(field);
+   }
+
+   return NULL;
+}
+
+gchar *module_entry_function(ShellModuleEntry * module_entry)
+{
+    if (module_entry->func) {
+	return module_entry->func();
+    }
+
+    return NULL;
+}
+
+gchar *module_entry_get_moreinfo(ShellModuleEntry * module_entry, gchar * field)
+{
+    if (module_entry->morefunc) {
+	return module_entry->morefunc(field);
+    }
+
+    return NULL;
+}
+
+const gchar *module_entry_get_note(ShellModuleEntry * module_entry)
+{
+    if (module_entry->notefunc) {
+	return module_entry->notefunc(module_entry->number);
+    }
+
+    return NULL;
+}
+
+gchar *h_strdup_cprintf(const gchar * format, gchar * source, ...)
+{
+    gchar *buffer, *retn;
+    va_list args;
+
+    va_start(args, source);
+    buffer = g_strdup_vprintf(format, args);
+    va_end(args);
+
+    if (source) {
+	retn = g_strconcat(source, buffer, NULL);
+	g_free(buffer);
+        g_free(source);
+    } else {
+	retn = buffer;
+    }
+
+    return retn;
+}
+
+gchar *h_strconcat(gchar * string1, ...)
+{
+    gsize l;
+    va_list args;
+    gchar *s;
+    gchar *concat;
+    gchar *ptr;
+
+    if (!string1)
+	return NULL;
+
+    l = 1 + strlen(string1);
+    va_start(args, string1);
+    s = va_arg(args, gchar *);
+    while (s) {
+	l += strlen(s);
+	s = va_arg(args, gchar *);
+    }
+    va_end(args);
+
+    concat = g_new(gchar, l);
+    ptr = concat;
+
+    ptr = g_stpcpy(ptr, string1);
+    va_start(args, string1);
+    s = va_arg(args, gchar *);
+    while (s) {
+	ptr = g_stpcpy(ptr, s);
+	s = va_arg(args, gchar *);
+    }
+    va_end(args);
+
+    g_free(string1);
+
+    return concat;
+}
+
+static gboolean h_hash_table_remove_all_true(gpointer key, gpointer data, gpointer user_data)
+{
+    return TRUE;
+}
+
+void
+h_hash_table_remove_all(GHashTable *hash_table)
+{
+    g_hash_table_foreach_remove(hash_table,
+				h_hash_table_remove_all_true,
+				NULL);
+}
+
+gfloat
+h_sysfs_read_float(gchar *endpoint, gchar *entry)
+{
+	gchar *tmp, *buffer;
+	gfloat return_value = 0.0f;
+
+	tmp = g_build_filename(endpoint, entry, NULL);
+	if (g_file_get_contents(tmp, &buffer, NULL, NULL))
+		return_value = atof(buffer);
+
+	g_free(tmp);
+	g_free(buffer);
+
+	return return_value;
+}
+
+gint
+h_sysfs_read_int(gchar *endpoint, gchar *entry)
+{
+	gchar *tmp, *buffer;
+	gint return_value = 0;
+
+	tmp = g_build_filename(endpoint, entry, NULL);
+	if (g_file_get_contents(tmp, &buffer, NULL, NULL))
+		return_value = atoi(buffer);
+
+	g_free(tmp);
+	g_free(buffer);
+
+	return return_value;
+}
+
+gchar *
+h_sysfs_read_string(gchar *endpoint, gchar *entry)
+{
+	gchar *tmp, *return_value;
+
+	tmp = g_build_filename(endpoint, entry, NULL);
+	if (!g_file_get_contents(tmp, &return_value, NULL, NULL)) {
+		g_free(return_value);
+
+		return_value = NULL;
+	} else {
+		return_value = g_strstrip(return_value);
+	}
+
+	g_free(tmp);
+
+	return return_value;
+}
+
+static GHashTable *_moreinfo = NULL;
+
+void
+moreinfo_init(void)
+{
+	if (G_UNLIKELY(_moreinfo)) {
+		DEBUG("moreinfo already initialized");
+		return;
+	}
+	DEBUG("initializing moreinfo");
+	_moreinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+}
+
+void
+moreinfo_shutdown(void)
+{
+	if (G_UNLIKELY(!_moreinfo)) {
+		DEBUG("moreinfo not initialized");
+		return;
+	}
+	DEBUG("shutting down moreinfo");
+	g_hash_table_destroy(_moreinfo);
+	_moreinfo = NULL;
+}
+
+void
+moreinfo_add_with_prefix(gchar *prefix, gchar *key, gchar *value)
+{
+	if (G_UNLIKELY(!_moreinfo)) {
+		DEBUG("moreinfo not initialized");
+		return;
+	}
+
+	if (prefix) {
+		gchar *hashkey = g_strconcat(prefix, ":", key, NULL);
+		g_hash_table_insert(_moreinfo, hashkey, value);
+		return;
+	}
+
+	g_hash_table_insert(_moreinfo, g_strdup(key), value);
+}
+
+void
+moreinfo_add(gchar *key, gchar *value)
+{
+	moreinfo_add_with_prefix(NULL, key, value);
+}
+
+static gboolean
+_moreinfo_del_cb(gpointer key, gpointer value, gpointer data)
+{
+	return g_str_has_prefix(key, data);
+}
+
+void
+moreinfo_del_with_prefix(gchar *prefix)
+{
+	if (G_UNLIKELY(!_moreinfo)) {
+		DEBUG("moreinfo not initialized");
+		return;
+	}
+
+	g_hash_table_foreach_remove(_moreinfo, _moreinfo_del_cb, prefix);
+}
+
+void
+moreinfo_clear(void)
+{
+	if (G_UNLIKELY(!_moreinfo)) {
+		DEBUG("moreinfo not initialized");
+		return;
+	}
+	h_hash_table_remove_all(_moreinfo);
+}
+
+gchar *
+moreinfo_lookup_with_prefix(gchar *prefix, gchar *key)
+{
+	if (G_UNLIKELY(!_moreinfo)) {
+		DEBUG("moreinfo not initialized");
+		return 0;
+	}
+
+	if (prefix) {
+		gchar *lookup_key = g_strconcat(prefix, ":", key, NULL);
+		gchar *result = g_hash_table_lookup(_moreinfo, lookup_key);
+		g_free(lookup_key);
+		return result;
+	}
+
+	return g_hash_table_lookup(_moreinfo, key);
+}
+
+gchar *
+moreinfo_lookup(gchar *key)
+{
+	return moreinfo_lookup_with_prefix(NULL, key);
+}
+
+#if !GLIB_CHECK_VERSION(2,44,0)
+gboolean g_strv_contains(const gchar * const * strv, const gchar *str) {
+    /* g_strv_contains() requires glib>2.44
+     * fallback for older versions */
+    gint i = 0;
+    while(strv[i] != NULL) {
+        if (g_strcmp0(strv[i], str) == 0)
+            return 1;
+        i++;
+    }
+    return 0;
+}
+#endif
+
+/* Hardinfo labels that have # are truncated and/or hidden.
+ * Labels can't have $ because that is the delimiter in
+ * moreinfo. */
+gchar *hardinfo_clean_label(const gchar *v, int replacing) {
+    gchar *clean, *p;
+
+    p = clean = g_strdup(v);
+    while (*p != 0) {
+        switch(*p) {
+            case '#': case '$':
+                *p = '_';
+                break;
+            default:
+                break;
+        }
+        p++;
+    }
+    if (replacing)
+        g_free((gpointer)v);
+    return clean;
+}
+
+/* hardinfo uses the values as {ht,x}ml, apparently */
+gchar *hardinfo_clean_value(const gchar *v, int replacing) {
+    gchar *clean, *tmp;
+    gchar **vl;
+    if (v == NULL) return NULL;
+
+    vl = g_strsplit(v, "&", -1);
+    if (g_strv_length(vl) > 1)
+        clean = g_strjoinv("&amp;", vl);
+    else
+        clean = g_strdup(v);
+    g_strfreev(vl);
+
+    vl = g_strsplit(clean, "<", -1);
+    if (g_strv_length(vl) > 1) {
+        tmp = g_strjoinv("&lt;", vl);
+        g_free(clean);
+        clean = tmp;
+    }
+    g_strfreev(vl);
+
+    vl = g_strsplit(clean, ">", -1);
+    if (g_strv_length(vl) > 1) {
+        tmp = g_strjoinv("&gt;", vl);
+        g_free(clean);
+        clean = tmp;
+    }
+    g_strfreev(vl);
+
+    if (replacing)
+        g_free((gpointer)v);
+    return clean;
+}
diff --git a/hardinfo/vendor.c b/hardinfo/vendor.c
new file mode 100644
index 0000000..47def3f
--- /dev/null
+++ b/hardinfo/vendor.c
@@ -0,0 +1,217 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    List of vendors based on GtkSysInfo (c) Pissens Sebastien.
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include "vendor.h"
+#include "syncmanager.h"
+#include "config.h"
+#include "hardinfo.h"
+
+static const Vendor vendors[] = {
+    {"ATI", "ATI Technologies", "www.ati.com"},
+    {"nVidia", "nVidia", "www.nvidia.com"},
+    {"NVidia", "nVidia", "www.nvidia.com"},
+    {"3Com", "3Com", "www.3com.com"},
+    {"Intel", "Intel", "www.intel.com"},
+    {"Cirrus Logic", "Cirrus Logic", "www.cirrus.com"},
+    {"VIA Technologies", "VIA Technologies", "www.via.com.tw"},
+    {"VIA", "VIA Technologies", "www.via.com.tw"},
+    {"hp", "Hewlett-Packard", "www.hp.com"},
+    {"NEC Corporation", "NEC Coporation", "www.nec.com"},
+    {"MAXTOR", "MAXTOR", "www.maxtor.com"},
+    {"SAMSUNG", "SAMSUNG", "www.samsung.com"},
+    {"PIONEER", "PIONEER", "www.pioneer-eur.com"},
+    {"PLEXTOR", "PLEXTOR", "www.plextor.be"},
+    {"Realtek Semiconductor", "Realtek", "www.realtek.com.tw"},
+    {"TOSHIBA", "TOSHIBA", "www.toshiba.com"},
+    {"LITE-ON", "LITE-ON", "www.liteonit.com"},
+    {"WDC", "Western Digital", "www.wdc.com"},
+    {"HL-DT-ST", "LG Electronics", "www.lge.com"},
+    {"ST", "SEAGATE", "www.seagate.com"},
+    {"Lexmark", "Lexmark", "www.lexmark.com"},
+    {"_NEC", "NEC Corporation", "www.nec.com"},
+    {"Creative Labs", "Creative Labs", "www.creative.com"},
+    {"Brooktree", "Conexant", "www.brooktree.com"},
+    {"Atheros", "Atheros Communications", "www.atheros.com"},
+    {"MATSHITA", "Panasonic", "www.panasonic.com"},
+    {"Silicon Image", "Silicon Image", "www.siliconimage.com"},
+    {"Silicon Integrated Image", "Silicon Image", "www.siliconimage.com"},
+    {"KYE", "KYE Systems", "www.genius-kye.com"},
+    {"Broadcom", "Broadcom", "www.broadcom.com"},
+    {"Apple", "Apple", "www.apple.com"},
+    {"IBM", "IBM", "www.ibm.com"},
+    {"Dell", "Dell Computer", "www.dell.com"},
+    {"Logitech", "Logitech International", "www.logitech.com"},
+    {"FUJITSU", "Fujitsu", "www.fujitsu.com"},
+    {"CDU", "Sony", "www.sony.com"},
+    {"SanDisk", "SanDisk", "www.sandisk.com"},
+    {"ExcelStor", "ExcelStor Technology", "www.excelstor.com"},
+    {"D-Link", "D-Link", "www.dlink.com.tw"},
+    {"Giga-byte", "Gigabyte Technology", "www.gigabyte.com.tw"},
+    {"Gigabyte", "Gigabyte Technology", "www.gigabyte.com.tw"},
+    {"C-Media", "C-Media Electronics", "www.cmedia.com.tw"},
+    {"Avermedia", "AVerMedia Technologies", "www.aver.com"},
+    {"Philips", "Philips", "www.philips.com"},
+    {"RaLink", "Ralink Technology", "www.ralinktech.com"},
+    {"Siemens", "Siemens AG", "www.siemens.com"},
+    {"HP", "Hewlett-Packard", "www.hp.com"},
+    {"Hewlett-Packard", "Hewlett-Packard", "www.hp.com"},
+    {"TEAC", "TEAC America", "www.teac.com"},
+    {"Microsoft", "Microsoft", "www.microsoft.com"},
+    {"Memorex", "Memorex Products", "www.memorex.com"},
+    {"eMPIA", "eMPIA Technology", "www.empiatech.com.tw"},
+    {"Canon", "Canon", "www.canon.com"},
+    {"A4Tech", "A4tech", "www.a4tech.com"},
+    {"ALCOR", "Alcor", "www.alcor.org"},
+    {"Vimicro", "Vimicro", "www.vimicro.com"},
+    {"OTi", "Ours Technology", "www.oti.com.tw"},
+    {"BENQ", "BenQ", "www.benq.com"},
+    {"Acer", "Acer", "www.acer.com"},
+    {"QUANTUM", "Quantum", "www.quantum.com"},
+    {"Kingston", "Kingston", "www.kingston.com"},
+    {"Chicony", "Chicony", "www.chicony.com.tw"},
+    {"Genius", "Genius", "www.genius.ru"},
+    /* BIOS manufacturers */
+    {"American Megatrends", "American Megatrends", "www.ami.com"},
+    {"Award", "Award Software International", "www.award-bios.com"},
+    {"Phoenix", "Phoenix Technologies", "www.phoenix.com"},
+    /* x86 vendor strings */
+    { "AMDisbetter!", "Advanced Micro Devices", "www.amd.com" },
+    { "AuthenticAMD", "Advanced Micro Devices", "www.amd.com" },
+    { "CentaurHauls", "VIA (formerly Centaur Technology)", "www.via.tw" },
+    { "CyrixInstead", "Cyrix", "" },
+    { "GenuineIntel", "Intel", "www.intel.com" },
+    { "TransmetaCPU", "Transmeta", "" },
+    { "GenuineTMx86", "Transmeta", "" },
+    { "Geode by NSC", "National Semiconductor", "" },
+    { "NexGenDriven", "NexGen", "" },
+    { "RiseRiseRise", "Rise Technology", "" },
+    { "SiS SiS SiS", "Silicon Integrated Systems", "" },
+    { "UMC UMC UMC", "United Microelectronics Corporation", "" },
+    { "VIA VIA VIA", "VIA", "www.via.tw" },
+    { "Vortex86 SoC", "DMP Electronics", "" },
+    /* x86 VM vendor strings */
+    { "KVMKVMKVM", "KVM", "" },
+    { "Microsoft Hv", "Microsoft Hyper-V", "www.microsoft.com" },
+    { "lrpepyh vr", "Parallels", "" },
+    { "VMwareVMware", "VMware", "" },
+    { "XenVMMXenVMM", "Xen HVM", "" },
+};
+
+static GSList *vendor_list = NULL;
+
+void vendor_init(void)
+{
+    gint i;
+    gchar *path;
+    static SyncEntry se = {
+       .fancy_name = "Update vendor list",
+       .name = "RecvVendorList",
+       .save_to = "vendor.conf",
+       .get_data = NULL
+    };
+
+    DEBUG("initializing vendor list");
+    sync_manager_add_entry(&se);
+
+    path = g_build_filename(g_get_home_dir(), ".hardinfo", "vendor.conf", NULL);
+    if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
+      DEBUG("local vendor.conf not found, trying system-wise");
+      g_free(path);
+      path = g_build_filename(params.path_data, "vendor.conf", NULL);
+    }
+
+    if (g_file_test(path, G_FILE_TEST_EXISTS)) {
+      GKeyFile *vendors;
+      gchar *tmp;
+      gint num_vendors;
+
+      DEBUG("loading %s", path);
+
+      vendors = g_key_file_new();
+      if (g_key_file_load_from_file(vendors, path, 0, NULL)) {
+        num_vendors = g_key_file_get_integer(vendors, "vendors", "number", NULL);
+
+        for (i = num_vendors - 1; i >= 0; i--) {
+          Vendor *v = g_new0(Vendor, 1);
+
+          tmp = g_strdup_printf("vendor%d", i);
+
+          v->id   = g_key_file_get_string(vendors, tmp, "id", NULL);
+          v->name = g_key_file_get_string(vendors, tmp, "name", NULL);
+          v->url  = g_key_file_get_string(vendors, tmp, "url", NULL);
+
+          vendor_list = g_slist_prepend(vendor_list, v);
+
+          g_free(tmp);
+        }
+      }
+
+      g_key_file_free(vendors);
+    } else {
+      DEBUG("system-wise vendor.conf not found, using internal database");
+
+      for (i = G_N_ELEMENTS(vendors) - 1; i >= 0; i--) {
+        vendor_list = g_slist_prepend(vendor_list, (gpointer) &vendors[i]);
+      }
+    }
+
+    g_free(path);
+}
+
+const gchar *vendor_get_name(const gchar * id)
+{
+    GSList *vendor;
+
+    if (!id) {
+      return NULL;
+    }
+
+    for (vendor = vendor_list; vendor; vendor = vendor->next) {
+      Vendor *v = (Vendor *)vendor->data;
+
+      if (v && v->id && strstr(id, v->id)) {
+        return v->name;
+      }
+    }
+
+    return id; /* What about const? */
+}
+
+const gchar *vendor_get_url(const gchar * id)
+{
+    GSList *vendor;
+
+    if (!id) {
+      return NULL;
+    }
+
+    for (vendor = vendor_list; vendor; vendor = vendor->next) {
+      Vendor *v = (Vendor *)vendor->data;
+
+      if (v && v->id && strstr(id, v->id)) {
+        return v->url;
+      }
+    }
+
+    return NULL;
+}
diff --git a/includes/alpha/processor-platform.h b/includes/alpha/processor-platform.h
new file mode 100644
index 0000000..778a1a8
--- /dev/null
+++ b/includes/alpha/processor-platform.h
@@ -0,0 +1,29 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+struct _Processor {
+    gchar *model_name;
+    gfloat bogomips, cpu_mhz;
+    gchar *strmodel;
+    gchar *cycle_frequency_hz_str;
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/arm/processor-platform.h b/includes/arm/processor-platform.h
new file mode 100644
index 0000000..0ffdac2
--- /dev/null
+++ b/includes/arm/processor-platform.h
@@ -0,0 +1,44 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+#include "cpu_util.h"
+
+struct _Processor {
+    gchar *model_name;
+    gchar *linux_name;
+    gchar *flags;
+    gfloat bogomips;
+
+    gint id;
+    gfloat cpu_mhz; /* for devices.c, identical to cpukhz_max/1000 */
+    cpu_topology_data *cputopo;
+    cpufreq_data *cpufreq;
+
+    gchar *cpu_implementer;
+    gchar *cpu_architecture;
+    gchar *cpu_variant;
+    gchar *cpu_part;
+    gchar *cpu_revision;
+
+    gint mode;
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/benchmark.h b/includes/benchmark.h
new file mode 100644
index 0000000..277f0c0
--- /dev/null
+++ b/includes/benchmark.h
@@ -0,0 +1,55 @@
+#ifndef __BENCHMARK_H__
+#define __BENCHMARK_H__
+
+#include "hardinfo.h"
+
+extern ProgramParameters params;
+
+enum {
+    BENCHMARK_BLOWFISH,
+    BENCHMARK_CRYPTOHASH,
+    BENCHMARK_FIB,
+    BENCHMARK_NQUEENS,
+    BENCHMARK_ZLIB,
+    BENCHMARK_FFT,
+    BENCHMARK_RAYTRACE,
+    BENCHMARK_GUI,
+    BENCHMARK_N_ENTRIES
+} BenchmarkEntries;
+
+void benchmark_bfish(void);
+void benchmark_cryptohash(void);
+void benchmark_fft(void);
+void benchmark_fib(void);
+void benchmark_fish(void);
+void benchmark_gui(void);
+void benchmark_nqueens(void);
+void benchmark_raytrace(void);
+void benchmark_zlib(void);
+
+typedef struct {
+    double result;
+    double elapsed_time;
+    int threads_used;
+} bench_value;
+
+#define EMPTY_BENCH_VALUE {-1.0f,0,0}
+
+char *bench_value_to_str(bench_value r);
+bench_value bench_value_from_str(const char* str);
+
+/* Note:
+ *    benchmark_parallel_for(): element [start] included, but [end] is excluded.
+ *    callback(): expected to processes elements [start] through [end] inclusive.
+ */
+bench_value benchmark_parallel_for(gint n_threads, guint start, guint end,
+                               gpointer callback, gpointer callback_data);
+
+bench_value benchmark_parallel(gint n_threads, gpointer callback, gpointer callback_data);
+
+bench_value benchmark_crunch_for(float seconds, gint n_threads,
+                               gpointer callback, gpointer callback_data);
+
+extern bench_value bench_results[BENCHMARK_N_ENTRIES];
+
+#endif /* __BENCHMARK_H__ */
diff --git a/includes/binreloc.h b/includes/binreloc.h
new file mode 100644
index 0000000..3bf48bc
--- /dev/null
+++ b/includes/binreloc.h
@@ -0,0 +1,68 @@
+/*
+ * BinReloc - a library for creating relocatable executables
+ * Written by: Hongli Lai <h.lai@chello.nl>
+ * http://autopackage.org/
+ *
+ * This source code is public domain. You can relicense this code
+ * under whatever license you want.
+ *
+ * See http://autopackage.org/docs/binreloc/ for
+ * more information and how to use this.
+ */
+
+#ifndef __BINRELOC_H__
+#define __BINRELOC_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+
+/** These error codes can be returned by br_init(), br_init_lib(), gbr_init() or gbr_init_lib(). */
+typedef enum {
+	/** Cannot allocate memory. */
+	GBR_INIT_ERROR_NOMEM,
+	/** Unable to open /proc/self/maps; see errno for details. */
+	GBR_INIT_ERROR_OPEN_MAPS,
+	/** Unable to read from /proc/self/maps; see errno for details. */
+	GBR_INIT_ERROR_READ_MAPS,
+	/** The file format of /proc/self/maps is invalid; kernel bug? */
+	GBR_INIT_ERROR_INVALID_MAPS,
+	/** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
+	GBR_INIT_ERROR_DISABLED
+} GbrInitError;
+
+
+#ifndef BINRELOC_RUNNING_DOXYGEN
+/* Mangle symbol names to avoid symbol collisions with other ELF objects. */
+	#define gbr_find_exe         UfUy21856259474323_gbr_find_exe
+	#define gbr_find_exe_dir     UfUy21856259474323_gbr_find_exe_dir
+	#define gbr_find_prefix      UfUy21856259474323_gbr_find_prefix
+	#define gbr_find_bin_dir     UfUy21856259474323_gbr_find_bin_dir
+	#define gbr_find_sbin_dir    UfUy21856259474323_gbr_find_sbin_dir
+	#define gbr_find_data_dir    UfUy21856259474323_gbr_find_data_dir
+	#define gbr_find_locale_dir  UfUy21856259474323_gbr_find_locale_dir
+	#define gbr_find_lib_dir     UfUy21856259474323_gbr_find_lib_dir
+	#define gbr_find_libexec_dir UfUy21856259474323_gbr_find_libexec_dir
+	#define gbr_find_etc_dir     UfUy21856259474323_gbr_find_etc_dir
+
+
+#endif
+gboolean gbr_init             (GError **error);
+gboolean gbr_init_lib         (GError **error);
+
+gchar   *gbr_find_exe         (const gchar *default_exe);
+gchar   *gbr_find_exe_dir     (const gchar *default_dir);
+gchar   *gbr_find_prefix      (const gchar *default_prefix);
+gchar   *gbr_find_bin_dir     (const gchar *default_bin_dir);
+gchar   *gbr_find_sbin_dir    (const gchar *default_sbin_dir);
+gchar   *gbr_find_data_dir    (const gchar *default_data_dir);
+gchar   *gbr_find_locale_dir  (const gchar *default_locale_dir);
+gchar   *gbr_find_lib_dir     (const gchar *default_lib_dir);
+gchar   *gbr_find_libexec_dir (const gchar *default_libexec_dir);
+gchar   *gbr_find_etc_dir     (const gchar *default_etc_dir);
+
+
+G_END_DECLS
+
+#endif /* __BINRELOC_H__ */
diff --git a/includes/blowfish.h b/includes/blowfish.h
new file mode 100644
index 0000000..3f33e94
--- /dev/null
+++ b/includes/blowfish.h
@@ -0,0 +1,33 @@
+/*
+blowfish.h:  Header file for blowfish.c
+
+Copyright (C) 1997 by Paul Kocher
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+See blowfish.c for more information about this file.
+*/
+
+  
+typedef struct {
+  unsigned long P[16 + 2];
+  unsigned long S[4][256];
+} BLOWFISH_CTX;
+
+void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen);
+void Blowfish_Encrypt(BLOWFISH_CTX *ctx, unsigned long *xl, unsigned long *xr);
+void Blowfish_Decrypt(BLOWFISH_CTX *ctx, unsigned long *xl, unsigned long *xr);
+
+
+
diff --git a/includes/callbacks.h b/includes/callbacks.h
new file mode 100644
index 0000000..392d576
--- /dev/null
+++ b/includes/callbacks.h
@@ -0,0 +1,44 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __CALLBACKS_H__
+#define __CALLBACKS_H__
+
+#include <gtk/gtk.h>
+
+void cb_about();
+void cb_about_module(GtkAction *action);
+void cb_generate_report();
+void cb_quit();
+void cb_refresh();
+void cb_copy_to_clipboard();
+void cb_side_pane();
+void cb_toolbar();
+void cb_open_web_page();
+void cb_open_online_docs();
+void cb_open_online_docs_context();
+void cb_sync_manager();
+void cb_report_bug();
+void cb_donate();
+void cb_connect_to();
+void cb_manage_hosts();
+void cb_connect_host(GtkAction * action);
+void cb_local_computer();
+void cb_act_as_server();
+
+#endif	/* __CALLBACKS_H__ */
diff --git a/includes/computer.h b/includes/computer.h
new file mode 100644
index 0000000..5a69a17
--- /dev/null
+++ b/includes/computer.h
@@ -0,0 +1,152 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#ifndef __COMPUTER_H__
+#define __COMPUTER_H__
+
+#include "hardinfo.h"
+
+typedef struct _Computer	Computer;
+typedef struct _OperatingSystem	OperatingSystem;
+typedef struct _MemoryInfo	MemoryInfo;
+typedef struct _UptimeInfo	UptimeInfo;
+typedef struct _LoadInfo	LoadInfo;
+typedef struct _DisplayInfo	DisplayInfo;
+
+typedef struct _AlsaInfo	AlsaInfo;
+typedef struct _AlsaCard	AlsaCard;
+
+typedef struct _FileSystem	FileSystem;
+typedef struct _FileSystemEntry	FileSystemEntry;
+
+struct _AlsaCard {
+    gchar *alsa_name;
+    gchar *friendly_name;
+/*  
+  gchar   *board;
+  gchar    revision, compat_class;
+  gint     subsys_vendorid, subsys_id;
+  
+  gint     cap_dac_res, cap_adc_res;
+  gboolean cap_3d_enh;
+  
+  gint     curr_mic_gain;
+  gboolean curr_3d_enh,
+           curr_loudness,
+           curr_simstereo;
+  gchar   *curr_mic_select;
+*/
+};
+
+struct _AlsaInfo {
+    GSList *cards;
+};
+
+struct _DisplayInfo {
+    gchar *ogl_vendor, *ogl_renderer, *ogl_version;
+    gboolean dri;
+    
+    gchar *display_name, *vendor, *version;
+    gchar *extensions;
+    gchar *monitors;
+    
+    gint width, height;
+};
+
+struct _LoadInfo {
+    float load1, load5, load15;
+};
+
+struct _UptimeInfo {
+    int days, hours, minutes;
+};
+
+struct _Computer {
+    MemoryInfo *memory;
+    OperatingSystem *os;
+    DisplayInfo *display;
+    AlsaInfo *alsa;
+
+    gchar *date_time;
+};
+
+struct _OperatingSystem {
+    gchar *kernel;
+    gchar *libc;
+    gchar *distrocode, *distro;
+    gchar *hostname;
+    gchar *language;
+    gchar *homedir;
+    gchar *kernel_version;
+
+    gchar *languages;
+
+    gchar *desktop;
+    gchar *username;
+    
+    gchar *boots;
+
+    gchar *entropy_avail;
+};
+
+struct _MemoryInfo {
+    gint total, used, free, cached;
+    gfloat ratio;
+};
+
+#define get_str(field_name,ptr)               \
+  if (g_str_has_prefix(tmp[0], field_name)) { \
+    ptr = g_strdup(tmp[1]);                   \
+    g_strfreev(tmp);                          \
+    continue;                                 \
+  }
+#define get_int(field_name,ptr)               \
+  if (g_str_has_prefix(tmp[0], field_name)) { \
+    ptr = atoi(tmp[1]);                       \
+    g_strfreev(tmp);                          \
+    continue;                                 \
+  }
+#define get_float(field_name,ptr)             \
+  if (g_str_has_prefix(tmp[0], field_name)) { \
+    ptr = atof(tmp[1]);                       \
+    g_strfreev(tmp);                          \
+    continue;                                 \
+  }
+
+extern gchar *users;
+extern gchar *groups;
+extern gchar *fs_list;
+extern GHashTable *_module_hash_table;
+extern Computer *computer;
+extern gchar *module_list;
+
+gchar *computer_get_formatted_loadavg();
+gchar *computer_get_formatted_uptime();
+gchar *computer_get_alsacards(Computer * computer);
+gchar *computer_get_entropy_avail();
+
+OperatingSystem *computer_get_os(void);
+AlsaInfo *computer_get_alsainfo(void);
+MemoryInfo *computer_get_memory(void);
+UptimeInfo *computer_get_uptime(void);
+DisplayInfo *computer_get_display(void);
+
+void scan_modules_do(void);
+void scan_filesystems(void);
+void scan_users_do(void);
+
+#endif				/* __COMPUTER_H__ */
diff --git a/includes/cpu_util.h b/includes/cpu_util.h
new file mode 100644
index 0000000..c11d3f6
--- /dev/null
+++ b/includes/cpu_util.h
@@ -0,0 +1,50 @@
+#ifndef __CPU_UTIL_H__
+#define __CPU_UTIL_H__
+
+#include "hardinfo.h"
+
+#ifndef PROC_CPUINFO
+#define PROC_CPUINFO "/proc/cpuinfo"
+#endif
+
+#define STRIFNULL(f,cs) if (f == NULL) f = g_strdup(cs);
+#define UNKIFNULL(f) STRIFNULL(f, _("(Unknown)") )
+#define EMPIFNULL(f) STRIFNULL(f, "")
+
+const gchar *byte_order_str(void);
+
+/* from /sys/devices/system/cpu/cpu%d/%s */
+gchar* get_cpu_str(const gchar* file, gint cpuid);
+gint get_cpu_int(const char* item, int cpuid, int null_val);
+
+/* space delimted list of flags, finds flag */
+int processor_has_flag(gchar * strflags, gchar * strflag);
+
+typedef struct {
+    gint id;
+    gint cpukhz_max, cpukhz_min, cpukhz_cur;
+    gchar *scaling_driver, *scaling_governor;
+    gint transition_latency;
+    gchar *shared_list;
+} cpufreq_data;
+
+typedef struct {
+    gint id; /* thread */
+    gint socket_id;
+    gint core_id;
+    gint book_id;
+    gint drawer_id;
+} cpu_topology_data;
+
+cpufreq_data *cpufreq_new(gint id);
+void cpufreq_update(cpufreq_data *cpufd, int cur_only);
+void cpufreq_free(cpufreq_data *cpufd);
+
+gchar *cpufreq_section_str(cpufreq_data *cpufd);
+
+cpu_topology_data *cputopo_new(gint id);
+void cputopo_free(cpu_topology_data *cputd);
+
+gchar *cputopo_section_str(cpu_topology_data *cputd);
+
+#endif
diff --git a/includes/devices.h b/includes/devices.h
new file mode 100644
index 0000000..e18a383
--- /dev/null
+++ b/includes/devices.h
@@ -0,0 +1,102 @@
+#ifndef __DEVICES_H__
+#define __DEVICES_H__
+
+#include "hardinfo.h"
+#include "processor-platform.h"
+#include "dmi_util.h"
+
+typedef struct _Processor Processor;
+
+#define WALK_UNTIL(x)   while((*buf != '\0') && (*buf != x)) buf++
+
+#define GET_STR(field_name,ptr)      					\
+  if (!ptr && strstr(tmp[0], field_name)) {				\
+    ptr = g_markup_escape_text(g_strstrip(tmp[1]), strlen(tmp[1]));	\
+    g_strfreev(tmp);                 					\
+    continue;                        					\
+  }
+
+#define get_str(field_name,ptr)               \
+  if (g_str_has_prefix(tmp[0], field_name)) { \
+    ptr = g_strdup(tmp[1]);                   \
+    g_strfreev(tmp);                          \
+    continue;                                 \
+  }
+#define get_int(field_name,ptr)               \
+  if (g_str_has_prefix(tmp[0], field_name)) { \
+    ptr = atoi(tmp[1]);                       \
+    g_strfreev(tmp);                          \
+    continue;                                 \
+  }
+#define get_float(field_name,ptr)             \
+  if (g_str_has_prefix(tmp[0], field_name)) { \
+    ptr = atof(tmp[1]);                       \
+    g_strfreev(tmp);                          \
+    continue;                                 \
+  }
+
+
+/* Processor */
+GSList *processor_scan(void);
+void get_processor_strfamily(Processor * processor);
+gchar *processor_get_detailed_info(Processor * processor);
+gchar *processor_get_info(GSList * processors);
+gchar *processor_name(GSList * processors);
+gchar *processor_name_default(GSList * processors);
+gchar *processor_describe(GSList * processors);
+gchar *processor_describe_default(GSList * processors);
+gchar *processor_describe_by_counting_names(GSList * processors);
+gchar *processor_frequency_desc(GSList *processors);
+
+/* Memory */
+void init_memory_labels(void);
+void scan_memory_do(void);
+
+/* Printers */
+void init_cups(void);
+
+/* Battery */
+void scan_battery_do(void);
+
+/* PCI */
+void scan_pci_do(void);
+
+/* Printers */
+void scan_printers_do(void);
+
+/* Sensors */
+void scan_sensors_do(void);
+void sensors_init(void);
+void sensors_shutdown(void);
+
+#if defined(ARCH_x86) || defined(ARCH_x86_64)
+/* SPD */
+void scan_spd_do(void);
+#endif /* ARCH_x86 */
+
+extern gchar *battery_list;
+extern gchar *input_icons;
+extern gchar *input_list;
+extern gchar *lginterval;
+extern gchar *meminfo;
+extern gchar *pci_list;
+extern gchar *printer_icons;
+extern gchar *printer_list;
+extern gchar *sensors;
+extern gchar *storage_icons;
+extern gchar *storage_list;
+extern gchar *usb_list;
+extern GHashTable *memlabels;
+extern GHashTable *_pci_devices;
+extern GHashTable *sensor_compute;
+extern GHashTable *sensor_labels;
+extern GModule *cups;
+
+#if defined(ARCH_x86) || defined(ARCH_x86_64)
+extern gchar *spd_info;
+extern gchar *dmi_info;
+#endif
+
+extern gchar *dtree_info;
+
+#endif /* __DEVICES_H__ */
diff --git a/includes/dmi_util.h b/includes/dmi_util.h
new file mode 100644
index 0000000..aecda73
--- /dev/null
+++ b/includes/dmi_util.h
@@ -0,0 +1,31 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2017 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *    This file
+ *    Copyright (C) 2017 Burt P. <pburt0@gmail.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __DMI_UTIL_H__
+#define __DMI_UTIL_H__
+
+char *dmi_get_str(const char *id_str);
+
+/* if chassis_type is <=0 it will be fetched from DMI.
+ * with_val = true, will return a string like "[3] Desktop" instead of just
+ * "Desktop". */
+char *dmi_chassis_type_str(int chassis_type, gboolean with_val);
+
+#endif
diff --git a/includes/dt_util.h b/includes/dt_util.h
new file mode 100644
index 0000000..7ef6808
--- /dev/null
+++ b/includes/dt_util.h
@@ -0,0 +1,89 @@
+
+#ifndef _DT_UTIL_H_
+#define _DT_UTIL_H_
+
+#include <stdint.h>
+
+/* some not-quite-complete stuff that can be disabled */
+#define DTEX_PHREFS 1
+
+#ifndef DTR_ROOT
+#define DTR_ROOT dtr_find_device_tree_root()
+#endif
+
+enum {
+    DT_TYPE_ERR,
+
+    DT_NODE,
+    DTP_UNK,     /* arbitrary-length byte sequence */
+    DTP_EMPTY,   /* empty property */
+    DTP_STR,     /* null-delimited list of strings */
+    DTP_HEX,     /* list of 32-bit values displayed in hex */
+    DTP_UINT,    /* unsigned int list */
+    DTP_INTRUPT, /* interrupt-specifier list */
+    DTP_INTRUPT_EX, /* extended interrupt-specifier list */
+    DTP_OVR,     /* all in /__overrides__ */
+    DTP_PH,      /* phandle */
+    DTP_PH_REF,  /* reference to phandle */
+    DTP_REG,     /* <#address-cells, #size-cells> */
+    DTP_CLOCKS,  /* <phref, #clock-cells> */
+    DTP_GPIOS,   /* <phref, #gpio-cells> */
+    DTP_DMAS,    /* dma-specifier list */
+};
+
+/* simplest, no aliases, doesn't require an existing dt.
+ * use dtr_get_prop_str() for complete. */
+char* dtr_get_string(const char *p, int decode);
+
+typedef uint32_t dt_uint; /* big-endian */
+
+typedef struct _dtr dtr;
+typedef struct _dtr_obj dtr_obj;
+
+dtr *dtr_new(const char *base_path); /* NULL for DTR_ROOT */
+void dtr_free(dtr *);
+int dtr_was_found(dtr *);
+const char *dtr_base_path(dtr *);
+char *dtr_messages(dtr *); /* returns a message log */
+
+dtr_obj *dtr_obj_read(dtr *, const char *dtp);
+void dtr_obj_free(dtr_obj *);
+int dtr_obj_type(dtr_obj *);
+char *dtr_obj_alias(dtr_obj *);
+char *dtr_obj_symbol(dtr_obj *);
+char *dtr_obj_path(dtr_obj *);        /* device tree path */
+char *dtr_obj_full_path(dtr_obj *);   /* system path */
+
+/* find property/node 'name' relative to node
+ * if node is NULL, then from root */
+dtr_obj *dtr_get_prop_obj(dtr *, dtr_obj *node, const char *name);
+char *dtr_get_prop_str(dtr *, dtr_obj *node, const char *name);
+uint32_t dtr_get_prop_u32(dtr *, dtr_obj *node, const char *name);
+
+/* attempts to render the object as a string */
+char* dtr_str(dtr_obj *obj);
+
+int dtr_guess_type(dtr_obj *obj);
+char *dtr_elem_phref(dtr *, dt_uint e, int show_path);
+char *dtr_elem_hex(dt_uint e);
+char *dtr_elem_byte(uint8_t e);
+char *dtr_elem_uint(dt_uint e);
+char *dtr_list_byte(uint8_t *bytes, unsigned long count);
+char *dtr_list_hex(dt_uint *list, unsigned long count);
+
+int dtr_cellv_find(dtr_obj *obj, char *qprop, int limit);
+
+char *dtr_maps_info(dtr *); /* returns hardinfo shell section */
+
+const char *dtr_find_device_tree_root(void);
+
+/* write to the message log */
+void dtr_msg(dtr *s, char *fmt, ...);
+
+#define sp_sep(STR) (strlen(STR) ? " " : "")
+/* appends an element to a string, adding a space if
+ * the string is not empty.
+ * ex: ret = appf(ret, "%s=%s\n", name, value); */
+char *appf(char *src, char *fmt, ...);
+
+#endif
diff --git a/includes/egg-markdown.h b/includes/egg-markdown.h
new file mode 100644
index 0000000..4475b9f
--- /dev/null
+++ b/includes/egg-markdown.h
@@ -0,0 +1,84 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard@hughsie.com>
+ * Copyright (C) 2009 Leandro Pereira <leandro@hardinfo.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EGG_MARKDOWN_H
+#define __EGG_MARKDOWN_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_MARKDOWN		(egg_markdown_get_type ())
+#define EGG_MARKDOWN(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), EGG_TYPE_MARKDOWN, EggMarkdown))
+#define EGG_MARKDOWN_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), EGG_TYPE_MARKDOWN, EggMarkdownClass))
+#define EGG_IS_MARKDOWN(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), EGG_TYPE_MARKDOWN))
+#define EGG_IS_MARKDOWN_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), EGG_TYPE_MARKDOWN))
+#define EGG_MARKDOWN_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), EGG_TYPE_MARKDOWN, EggMarkdownClass))
+#define EGG_MARKDOWN_ERROR		(egg_markdown_error_quark ())
+#define EGG_MARKDOWN_TYPE_ERROR	(egg_markdown_error_get_type ())
+
+#define EGG_MARKDOWN_MAX_LINE_LENGTH	2048
+
+typedef struct EggMarkdownPrivate EggMarkdownPrivate;
+
+typedef struct
+{
+	 GObject		 parent;
+	 EggMarkdownPrivate	*priv;
+} EggMarkdown;
+
+typedef struct
+{
+	GObjectClass	parent_class;
+	void		(* active_changed)		(EggMarkdown	*self,
+							 gboolean	 active);
+} EggMarkdownClass;
+
+typedef enum {
+	EGG_MARKDOWN_OUTPUT_TEXT,
+	EGG_MARKDOWN_OUTPUT_PANGO,
+	EGG_MARKDOWN_OUTPUT_HTML,
+	EGG_MARKDOWN_OUTPUT_UNKNOWN
+} EggMarkdownOutput;
+
+GType		 egg_markdown_get_type	  		(void);
+EggMarkdown	*egg_markdown_new			(void);
+gboolean	 egg_markdown_set_output		(EggMarkdown		*self,
+							 EggMarkdownOutput	 output);
+gboolean	 egg_markdown_set_max_lines		(EggMarkdown		*self,
+							 gint			 max_lines);
+gboolean	 egg_markdown_set_smart_quoting		(EggMarkdown		*self,
+							 gboolean		 smart_quoting);
+gboolean	 egg_markdown_set_escape		(EggMarkdown		*self,
+							 gboolean		 escape);
+gboolean	 egg_markdown_set_autocode		(EggMarkdown		*self,
+							 gboolean		 autocode);
+gchar		*egg_markdown_parse			(EggMarkdown		*self,
+							 const gchar		*text);
+void		 egg_markdown_clear			(EggMarkdown		*self);
+gchar 		*egg_markdown_get_link_uri		(EggMarkdown		*self,
+                                                         const gint		link_id);
+
+G_END_DECLS
+
+#endif /* __EGG_MARKDOWN_H */
+
diff --git a/includes/expr.h b/includes/expr.h
new file mode 100644
index 0000000..4bda6b7
--- /dev/null
+++ b/includes/expr.h
@@ -0,0 +1,48 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#ifndef __EXPR_H__
+#define __EXPR_H__
+
+typedef struct _MathToken MathToken;
+
+typedef enum {
+    TOKEN_OPERATOR,
+    TOKEN_VARIABLE,
+    TOKEN_VALUE
+} MathTokenType;
+
+struct _MathToken {
+    union {
+	gfloat	value;
+	gchar	op;
+    } val;
+    MathTokenType type;
+};
+
+#define math_postfix_free math_infix_free
+
+GSList	*math_infix_to_postfix(GSList *infix);
+void	 math_infix_free(GSList *infix, gboolean free_tokens);
+
+GSList	*math_string_to_infix(gchar *string);
+GSList	*math_string_to_postfix(gchar *string);
+
+gfloat	 math_postfix_eval(GSList *postfix, gfloat at_value);
+gfloat	 math_string_eval(gchar *string, gfloat at_value);
+
+#endif	/* __EXPR_H__ */
diff --git a/includes/fftbench.h b/includes/fftbench.h
new file mode 100644
index 0000000..7c0afc3
--- /dev/null
+++ b/includes/fftbench.h
@@ -0,0 +1,19 @@
+#ifndef __FFTBENCH_H__ 
+#define __FFTBENCH_H__
+
+#include <glib.h>
+
+typedef struct _FFTBench	FFTBench;
+
+struct _FFTBench {
+  double **a, *b, *r;
+  int *p;
+};
+
+FFTBench *fft_bench_new(void);
+void fft_bench_run(FFTBench *fftbench);
+void fft_bench_free(FFTBench *fftbench);
+
+#endif /* __FFTBENCH_H__ */
+
+
diff --git a/includes/gettext.h b/includes/gettext.h
new file mode 100644
index 0000000..fcdb205
--- /dev/null
+++ b/includes/gettext.h
@@ -0,0 +1,47 @@
+
+#ifndef __GETTEXT_H__
+#define __GETTEXT_H__
+
+#include <string.h>
+#include <libintl.h>
+#include <locale.h>
+
+static const char *
+__pgettext_expr (const char *msgctxt, const char *msgid)
+{
+  size_t msgctxt_len = strlen (msgctxt) + 1;
+  size_t msgid_len = strlen (msgid) + 1;
+  const char *translation;
+#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+  char msg_ctxt_id[msgctxt_len + msgid_len];
+#else
+  char buf[1024];
+  char *msg_ctxt_id =
+    (msgctxt_len + msgid_len <= sizeof (buf)
+     ? buf
+     : (char *) malloc (msgctxt_len + msgid_len));
+  if (msg_ctxt_id != NULL)
+#endif
+    {
+      int found_translation;
+      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+      msg_ctxt_id[msgctxt_len - 1] = '\004';
+      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+      translation = gettext (msg_ctxt_id);
+      found_translation = (translation != msg_ctxt_id);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+      if (msg_ctxt_id != buf)
+        free (msg_ctxt_id);
+#endif
+      if (found_translation)
+        return translation;
+    }
+  return msgid;
+}
+
+#define _(STRING) gettext(STRING)
+#define N_(STRING) (STRING)
+#define C_(CTX, STRING) __pgettext_expr(CTX, STRING)
+#define NC_(CTX, STRING) (STRING)
+
+#endif
diff --git a/includes/guibench.h b/includes/guibench.h
new file mode 100644
index 0000000..d24403b
--- /dev/null
+++ b/includes/guibench.h
@@ -0,0 +1,24 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __GUIBENCH_H__
+#define __GUIBENCH_H__
+
+double guibench(void);
+
+#endif	/* __GUIBENCH_H__ */
\ No newline at end of file
diff --git a/includes/hardinfo.h b/includes/hardinfo.h
new file mode 100644
index 0000000..637aa1f
--- /dev/null
+++ b/includes/hardinfo.h
@@ -0,0 +1,182 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __HARDINFO_H__
+#define __HARDINFO_H__
+
+#include <gtk/gtk.h>
+#include "config.h"
+#include "shell.h"
+#include "vendor.h"
+#include "gettext.h"
+#include "info.h"
+
+#define HARDINFO_COPYRIGHT_LATEST_YEAR 2017
+
+#ifndef LOCALEDIR
+#define LOCALEDIR "/usr/share/locale"
+#endif
+
+typedef enum {
+  MODULE_FLAG_NONE = 0,
+  MODULE_FLAG_NO_REMOTE = 1<<0,
+  MODULE_FLAG_HAS_HELP = 1<<1,
+} ModuleEntryFlags;
+
+typedef struct _ModuleEntry		ModuleEntry;
+typedef struct _ModuleAbout		ModuleAbout;
+typedef struct _FileTypes		FileTypes;
+typedef struct _ProgramParameters	ProgramParameters;
+
+struct _ProgramParameters {
+  gboolean create_report;
+  gboolean show_version;
+  gboolean gui_running;
+  gboolean list_modules;
+  gboolean autoload_deps;
+  gboolean run_xmlrpc_server;
+
+  gint     report_format;
+
+  gchar  **use_modules;
+  gchar   *run_benchmark;
+  gchar   *result_format;
+  gchar   *path_lib;
+  gchar   *path_data;
+  gchar   *argv0;
+};
+
+struct _FileTypes {
+  gchar	*name;
+  gchar *mime_type;
+  gchar *extension;
+  gpointer data;
+};
+
+struct _ModuleEntry {
+    gchar	*name;
+    gchar	*icon;
+    gpointer	 callback;
+    gpointer	 scan_callback;
+    guint32	 flags;
+};
+
+struct _ModuleAbout {
+    const gchar *description;
+    const gchar	*author;
+    const gchar	*version;
+    const gchar	*license;
+};
+
+/* String utility functions */
+inline void  remove_quotes(gchar *str);
+inline char *strend(gchar *str, gchar chr);
+inline void  remove_linefeed(gchar *str);
+gchar       *strreplacechr(gchar *string, gchar *replace, gchar new_char);
+gchar       *strreplace(gchar *string, gchar *replace, gchar *replacement);
+
+/* Widget utility functions */
+void widget_set_cursor(GtkWidget *widget, GdkCursorType cursor_type);
+gint tree_view_get_visible_height(GtkTreeView *tv);
+
+/* File Chooser utility functions */
+void      file_chooser_open_expander(GtkWidget *chooser);
+void      file_chooser_add_filters(GtkWidget *chooser, FileTypes *filters);
+gchar    *file_chooser_get_extension(GtkWidget *chooser, FileTypes *filters);
+gchar    *file_chooser_build_filename(GtkWidget *chooser, gchar *extension);
+gpointer  file_types_get_data_by_name(FileTypes *file_types, gchar *name);
+
+/* Misc utility functions */
+#if RELEASE == 1
+gpointer idle_free(gpointer ptr);
+#else
+gpointer __idle_free(gpointer ptr, gchar *f, gint l);
+#define  idle_free(p) __idle_free(p, __FILE__, __LINE__)
+#endif	/* RELEASE == 1 */
+
+gchar	     *find_program(gchar *program_name);
+inline gchar *size_human_readable(gfloat size);
+void          nonblock_sleep(guint msec);
+void          open_url(gchar *url);
+GSList	     *modules_get_list(void);
+GSList	     *modules_load_selected(void);
+GSList       *modules_load_all(void);
+void	      module_unload_all(void);
+ModuleAbout  *module_get_about(ShellModule *module);
+gchar        *seconds_to_string(unsigned int seconds);
+
+gchar        *h_strdup_cprintf(const gchar *format, gchar *source, ...);
+gchar	     *h_strconcat(gchar *string1, ...);
+void          h_hash_table_remove_all (GHashTable *hash_table);
+
+void	      module_entry_scan_all_except(ModuleEntry *entries, gint except_entry);
+void	      module_entry_scan_all(ModuleEntry *entries);
+void	      module_entry_reload(ShellModuleEntry *module_entry);
+void	      module_entry_scan(ShellModuleEntry *module_entry);
+gchar	     *module_entry_function(ShellModuleEntry *module_entry);
+const gchar  *module_entry_get_note(ShellModuleEntry *module_entry);
+gchar        *module_entry_get_field(ShellModuleEntry * module_entry, gchar * field);
+gchar        *module_entry_get_moreinfo(ShellModuleEntry * module_entry, gchar * field);
+
+/* BinReloc stuff */
+gboolean binreloc_init(gboolean try_hardcoded);
+
+/* GTK UI stuff */
+gboolean ui_init(int *argc, char ***argv);
+void     parameters_init(int *argc, char ***argv, ProgramParameters *params);
+extern   ProgramParameters params;
+
+/* Module stuff */
+gchar		*module_call_method(gchar *method);
+gchar           *module_call_method_param(gchar * method, gchar * parameter);
+
+/* Sysfs stuff */
+gfloat		h_sysfs_read_float(gchar *endpoint, gchar *entry);
+gint		h_sysfs_read_int(gchar *endpoint, gchar *entry);
+gchar	       *h_sysfs_read_string(gchar *endpoint, gchar *entry);
+
+#define SCAN_START()  static gboolean scanned = FALSE; if (reload) scanned = FALSE; if (scanned) return;
+#define SCAN_END()    scanned = TRUE;
+
+#define _CONCAT(a,b) a ## b
+#define CONCAT(a,b) _CONCAT(a,b)
+
+void moreinfo_init(void);
+void moreinfo_shutdown(void);
+void moreinfo_add_with_prefix(gchar *prefix, gchar *key, gchar *value);
+void moreinfo_add(gchar *key, gchar *value);
+void moreinfo_del_with_prefix(gchar *prefix);
+void moreinfo_clear(void);
+gchar *moreinfo_lookup_with_prefix(gchar *prefix, gchar *key);
+gchar *moreinfo_lookup(gchar *key);
+
+#if !GLIB_CHECK_VERSION(2,44,0)
+    /* g_strv_contains() requires glib>2.44
+     * fallback for older versions in hardinfo/util.c */
+gboolean g_strv_contains(const gchar * const * strv, const gchar *str);
+#endif
+
+/* Hardinfo labels that have # are truncated and/or hidden.
+ * Labels can't have $ because that is the delimiter in
+ * moreinfo.
+ * replacing = true will free v */
+gchar *hardinfo_clean_label(const gchar *v, int replacing);
+/* hardinfo uses the values as {ht,x}ml, apparently */
+gchar *hardinfo_clean_value(const gchar *v, int replacing);
+
+#endif				/* __HARDINFO_H__ */
diff --git a/includes/help-viewer.h b/includes/help-viewer.h
new file mode 100644
index 0000000..688ff32
--- /dev/null
+++ b/includes/help-viewer.h
@@ -0,0 +1,43 @@
+/*
+ *    HelpViewer - Simple Help file browser
+ *    Copyright (C) 2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __HELP_VIEWER_H__
+#define __HELP_VIEWER_H__
+
+typedef struct _HelpViewer	HelpViewer;
+
+struct _HelpViewer {
+    GtkWidget *window;
+    GtkWidget *status_bar;
+    
+    GtkWidget *btn_back, *btn_forward;
+    GtkWidget *text_view;
+    GtkWidget *text_search;
+    
+    gchar *current_file;
+    gchar *help_directory;
+
+    GSList *back_stack, *forward_stack;
+};
+
+HelpViewer *help_viewer_new(const gchar *help_dir, const gchar *help_file);
+void help_viewer_open_page(HelpViewer *help_viewer, const gchar *page);
+void help_viewer_destroy(HelpViewer *help_viewer);
+
+#endif	/* __HELP_VIEWER_H__ */
+
diff --git a/includes/ia64/processor-platform.h b/includes/ia64/processor-platform.h
new file mode 100644
index 0000000..5d52563
--- /dev/null
+++ b/includes/ia64/processor-platform.h
@@ -0,0 +1,40 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+#include "cpu_util.h"
+
+struct _Processor {
+    gint id;
+    gfloat cpu_mhz; /* for devices.c, identical to cpukhz_max/1000 */
+    cpu_topology_data *cputopo;
+    cpufreq_data *cpufreq;
+
+    gchar *model_name;
+    gchar *vendor_id;
+    gfloat bogomips;
+    gchar *strmodel;
+
+    gchar *family, *arch, *archrev, *features;
+    gint model, revision;
+    gint cpu_regs;
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/iconcache.h b/includes/iconcache.h
new file mode 100644
index 0000000..97f59a8
--- /dev/null
+++ b/includes/iconcache.h
@@ -0,0 +1,30 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __ICONCACHE_H__
+#define __ICONCACHE_H__
+
+#include <gtk/gtk.h>
+
+void		 icon_cache_init(void);
+GdkPixbuf	*icon_cache_get_pixbuf(const gchar *file);
+GtkWidget	*icon_cache_get_image(const gchar *file);
+GdkPixbuf	*icon_cache_get_pixbuf_at_size(const gchar *file, gint wid, gint hei);
+GtkWidget	*icon_cache_get_image_at_size(const gchar *file, gint wid, gint hei);
+
+#endif	/* __ICONCACHE_H__ */
diff --git a/includes/info.h b/includes/info.h
new file mode 100644
index 0000000..253c06e
--- /dev/null
+++ b/includes/info.h
@@ -0,0 +1,73 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2017 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#pragma once
+
+#include <glib.h>
+
+struct Info {
+    GArray *groups;
+
+    const gchar *column_titles[5];
+
+    ShellViewType view_type;
+
+    int reload_interval;
+
+    gboolean column_headers_visible;
+    gboolean zebra_visible;
+    gboolean normalize_percentage;
+};
+
+struct InfoGroup {
+    const gchar *name;
+
+    GArray *fields;
+
+     /* scaffolding fields */
+    const gchar *computed;
+};
+
+struct InfoField {
+    const gchar *name;
+    gchar *value;
+
+    int update_interval;
+
+    gboolean free_value_on_flatten;
+};
+
+struct Info *info_new(void);
+
+void info_add_group(struct Info *info, const gchar *group_name, ...);
+void info_add_computed_group(struct Info *info, const gchar *name, const gchar *value);
+
+struct InfoField info_field(const gchar *name, gchar *value);
+struct InfoField info_field_printf(const gchar *name, const gchar *format, ...)
+    __attribute__((format(printf, 2, 3)));
+struct InfoField info_field_update(const gchar *name, int update_interval);
+struct InfoField info_field_last(void);
+
+void info_set_column_title(struct Info *info, const gchar *column, const gchar *title);
+void info_set_column_headers_visible(struct Info *info, gboolean setting);
+void info_set_zebra_visible(struct Info *info, gboolean setting);
+void info_set_normalize_percentage(struct Info *info, gboolean setting);
+void info_set_view_type(struct Info *info, ShellViewType setting);
+void info_set_reload_interval(struct Info *info, int setting);
+
+gchar *info_flatten(struct Info *info);
diff --git a/includes/loadgraph.h b/includes/loadgraph.h
new file mode 100644
index 0000000..d79ca39
--- /dev/null
+++ b/includes/loadgraph.h
@@ -0,0 +1,52 @@
+/*
+ * Simple Load Graph
+ * Copyright (C) 2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ * The Simple Load Graph is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License, version 2.1, as published by the Free Software Foundation.
+ *
+ * The Simple Load Graph is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the Simple Load Graph; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ */
+
+
+#ifndef __LOADGRAPH_H__
+#define __LOADGRAPH_H__
+
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <math.h>
+
+typedef struct _LoadGraph LoadGraph;
+
+typedef enum {
+    LG_COLOR_GREEN = 0x4FB05A,
+    LG_COLOR_BLUE  = 0x4F58B0,
+    LG_COLOR_RED   = 0xB04F4F
+} LoadGraphColor;
+
+LoadGraph   *load_graph_new(gint size);
+void         load_graph_destroy(LoadGraph *lg);
+void         load_graph_configure_expose(LoadGraph *lg);
+GtkWidget   *load_graph_get_framed(LoadGraph *lg);
+
+void         load_graph_update(LoadGraph *lg, gdouble value);
+void         load_graph_update_ex(LoadGraph *lg, guint line, gdouble value);
+
+void         load_graph_set_color(LoadGraph *lg, LoadGraphColor color);
+void         load_graph_clear(LoadGraph *lg);
+
+void         load_graph_set_data_suffix(LoadGraph *lg, gchar *suffix);
+gchar       *load_graph_get_data_suffix(LoadGraph *lg);
+
+gint         load_graph_get_height(LoadGraph *lg);
+
+#endif  /* __LOADGRAPH_H__ */
diff --git a/includes/m68k/processor-platform.h b/includes/m68k/processor-platform.h
new file mode 100644
index 0000000..9aea1df
--- /dev/null
+++ b/includes/m68k/processor-platform.h
@@ -0,0 +1,29 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+struct _Processor {
+    gchar *model_name;
+    gfloat bogomips, cpu_mhz;
+
+    gchar *fpu_name, *mmu_name, *calibration;
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/markdown-text-view.h b/includes/markdown-text-view.h
new file mode 100644
index 0000000..648ea39
--- /dev/null
+++ b/includes/markdown-text-view.h
@@ -0,0 +1,70 @@
+/*
+ * Markdown Text View
+ * GtkTextView subclass that supports Markdown syntax
+ *
+ * Copyright (C) 2009 Leandro Pereira <leandro@hardinfo.org>
+ * Portions Copyright (C) 2007-2008 Richard Hughes <richard@hughsie.com>
+ * Portions Copyright (C) GTK+ Team (based on hypertext textview demo)
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __MARKDOWN_TEXTVIEW_H__
+#define __MARKDOWN_TEXTVIEW_H__
+
+#include <gtk/gtk.h>
+#include "egg-markdown.h"
+
+G_BEGIN_DECLS
+#define TYPE_MARKDOWN_TEXTVIEW			(markdown_textview_get_type())
+#define MARKDOWN_TEXTVIEW(obj)			(G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_MARKDOWN_TEXTVIEW, MarkdownTextView))
+#define MARKDOWN_TEXTVIEW_CLASS(obj)		(G_TYPE_CHECK_CLASS_CAST((obj), MARKDOWN_TEXTVIEW, MarkdownTextViewClass))
+#define IS_MARKDOWN_TEXTVIEW(obj)		(G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_MARKDOWN_TEXTVIEW))
+#define IS_MARKDOWN_TEXTVIEW_CLASS(obj)		(G_TYPE_CHECK_CLASS_TYPE((obj), TYPE_MARKDOWN_TEXTVIEW))
+#define MARKDOWN_TEXTVIEW_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_MARKDOWN_TEXTVIEW, MarkdownTextViewClass))
+
+typedef struct _MarkdownTextView MarkdownTextView;
+typedef struct _MarkdownTextViewClass MarkdownTextViewClass;
+
+struct _MarkdownTextView {
+    GtkTextView parent;
+
+    EggMarkdown *markdown;
+    gboolean hovering_over_link;
+    gchar *image_directory;
+};
+
+struct _MarkdownTextViewClass {
+    GtkTextViewClass parent_class;
+    
+    void	(*link_clicked)		(MarkdownTextView *text_view, gchar *uri);
+    void	(*hovering_over_link)	(MarkdownTextView *text_view, gchar *uri);
+    void	(*hovering_over_text)	(MarkdownTextView *text_view);
+    void	(*file_load_complete)	(MarkdownTextView *text_view, gchar *file);
+};
+
+GtkWidget	*markdown_textview_new();
+gboolean	 markdown_textview_load_file(MarkdownTextView * textview,
+		  	                     const gchar * file_name);
+gboolean 	 markdown_textview_set_text(MarkdownTextView * textview,
+                                            const gchar * text);
+void		 markdown_textview_clear(MarkdownTextView * textview);
+void		 markdown_textview_set_image_directory(MarkdownTextView * self,
+                                                       const gchar * directory);
+GType		 markdown_textview_get_type();
+G_END_DECLS
+
+#endif				/* __MARKDOWN_TEXTVIEW_H__ */
diff --git a/includes/md5.h b/includes/md5.h
new file mode 100644
index 0000000..1522170
--- /dev/null
+++ b/includes/md5.h
@@ -0,0 +1,26 @@
+/* See md5.c for explanation and copyright information.  */
+
+#ifndef MD5_H
+#define MD5_H
+
+/* Unlike previous versions of this code, uint32 need not be exactly
+   32 bits, merely 32 bits or more.  Choosing a data type which is 32
+   bits instead of 64 is not important; speed is considerably more
+   important.  ANSI guarantees that "unsigned long" will be big enough,
+   and always using it seems to have few disadvantages.  */
+typedef unsigned long uint32;
+
+struct MD5Context {
+        uint32 buf[4];
+        uint32 bits[2];
+        unsigned char in[64];
+};
+
+void MD5Init (struct MD5Context *context);
+void MD5Update (struct MD5Context *context,
+                           unsigned char const *buf, unsigned len);
+void MD5Final (unsigned char digest[16],
+                          struct MD5Context *context);
+void MD5Transform (uint32 buf[4], const unsigned char in[64]);
+
+#endif /* !MD5_H */
diff --git a/includes/menu.h b/includes/menu.h
new file mode 100644
index 0000000..3c80400
--- /dev/null
+++ b/includes/menu.h
@@ -0,0 +1,26 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#ifndef __MENU_H__
+#define __MENU_H__
+
+#include <shell.h>
+
+
+void	menu_init(Shell *shell);
+
+#endif	/* __MENU_H__ */
diff --git a/includes/mips/processor-platform.h b/includes/mips/processor-platform.h
new file mode 100644
index 0000000..9bdae18
--- /dev/null
+++ b/includes/mips/processor-platform.h
@@ -0,0 +1,28 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+struct _Processor {
+    gchar *model_name;
+    gchar *vendor_id;
+    gfloat bogomips, cpu_mhz;
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/network.h b/includes/network.h
new file mode 100644
index 0000000..1e71126
--- /dev/null
+++ b/includes/network.h
@@ -0,0 +1,13 @@
+#ifndef __NETWORK_H__
+#define __NETWORK_H__
+
+#include "hardinfo.h"
+
+extern gchar *smb_shares_list;
+extern gchar *nfs_shares_list;
+extern gchar *network_interfaces;
+extern gchar *network_icons;
+
+void scan_net_interfaces(void);
+
+#endif /* __NETWORK_H__ */
\ No newline at end of file
diff --git a/includes/nqueens.h b/includes/nqueens.h
new file mode 100644
index 0000000..a4be93f
--- /dev/null
+++ b/includes/nqueens.h
@@ -0,0 +1,13 @@
+/*
+ * N-Queens Problem Solver
+ * Found somewhere on the Internet; can't remember where. Possibly Wikipedia.
+ */
+#ifndef __NQUEENS_H__ 
+#define __NQUEENS_H__
+
+int nqueens(int y);
+
+
+#endif /* __NQUEENS_H__ */
+
+
diff --git a/includes/parisc/processor-platform.h b/includes/parisc/processor-platform.h
new file mode 100644
index 0000000..c55c69e
--- /dev/null
+++ b/includes/parisc/processor-platform.h
@@ -0,0 +1,42 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+#include "cpu_util.h"
+
+struct _Processor {
+    gint id;
+    gfloat cpu_mhz; /* for devices.c, identical to cpukhz_max/1000 */
+    cpu_topology_data *cputopo;
+    cpufreq_data *cpufreq;
+
+    gchar *model_name;
+    gchar *vendor_id;
+    gchar *flags;
+    gfloat bogomips;
+    gchar *has_fpu;
+    gchar *strmodel;
+
+    gchar *cpu_family;
+    gchar *icache_str, *dcache_str;
+    gchar *hversion, *sversion;
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/ppc/processor-platform.h b/includes/ppc/processor-platform.h
new file mode 100644
index 0000000..d3d1a56
--- /dev/null
+++ b/includes/ppc/processor-platform.h
@@ -0,0 +1,36 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+#include "cpu_util.h"
+
+struct _Processor {
+    gint id;
+    gfloat cpu_mhz; /* for devices.c, identical to cpukhz_max/1000 */
+    cpu_topology_data *cputopo;
+    cpufreq_data *cpufreq;
+
+    gchar *model_name;
+    gchar *revision;
+    /* gint cache_size; */
+    gfloat bogomips;
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/remote.h b/includes/remote.h
new file mode 100644
index 0000000..6a988a3
--- /dev/null
+++ b/includes/remote.h
@@ -0,0 +1,29 @@
+/*
+ *    Remote Client
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __REMOTE_H__
+#define __REMOTE_H__
+
+void remote_disconnect_all(gboolean ssh);
+gboolean remote_connect_host(gchar * hostname);
+void connect_dialog_show(GtkWidget * parent);
+void host_manager_show(GtkWidget * parent);
+
+#endif	/* __REMOTE_H__ */
+
diff --git a/includes/report.h b/includes/report.h
new file mode 100644
index 0000000..782621c
--- /dev/null
+++ b/includes/report.h
@@ -0,0 +1,93 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+ 
+#ifndef __REPORT_H__
+#define __REPORT_H__
+#include <gtk/gtk.h>
+#include <shell.h>
+
+typedef enum {
+    REPORT_FORMAT_HTML,
+    REPORT_FORMAT_TEXT,
+    N_REPORT_FORMAT
+} ReportFormat;
+
+typedef enum {
+    REPORT_COL_PROGRESS = 1<<0,
+    REPORT_COL_VALUE    = 1<<1,
+    REPORT_COL_EXTRA1   = 1<<2,
+    REPORT_COL_EXTRA2   = 1<<3,
+    REPORT_COL_TEXTVALUE= 1<<4
+} ReportColumn;
+
+typedef struct _ReportDialog	ReportDialog;
+typedef struct _ReportContext	ReportContext;
+
+struct _ReportContext {
+  ShellModuleEntry	*entry;
+  gchar			*output;
+  
+  void (*header)      	(ReportContext *ctx);
+  void (*footer)      	(ReportContext *ctx);
+  void (*title)      	(ReportContext *ctx, gchar *text);
+  void (*subtitle)    	(ReportContext *ctx, gchar *text);
+  void (*subsubtitle)	(ReportContext *ctx, gchar *text);
+  void (*keyvalue)   	(ReportContext *ctx, gchar *key, gchar *value);
+  
+  ReportFormat		format;
+  
+  gboolean		is_image_enabled;
+  gboolean		first_table;
+
+  gboolean		show_column_headers;
+  guint			columns;
+  GHashTable		*column_titles;
+};
+
+struct _ReportDialog {
+  GtkWidget *dialog;
+  GtkWidget *filechooser;
+  GtkWidget *btn_cancel;
+  GtkWidget *btn_generate;
+  GtkWidget *btn_sel_all;
+  GtkWidget *btn_sel_none;
+  GtkWidget *treeview;
+  
+  GtkTreeModel *model;
+};
+
+void		 report_dialog_show();
+
+ReportContext	*report_context_html_new();
+ReportContext	*report_context_text_new();
+
+void		 report_header		(ReportContext *ctx);
+void		 report_footer		(ReportContext *ctx);
+void		 report_title		(ReportContext *ctx, gchar *text);
+void 		 report_subtitle	(ReportContext *ctx, gchar *text);
+void 		 report_subsubtitle	(ReportContext *ctx, gchar *text);
+void		 report_key_value	(ReportContext *ctx, gchar *key, gchar *value);
+void		 report_table		(ReportContext *ctx, gchar *text);
+
+void             report_create_from_module_list(ReportContext *ctx, GSList *modules);
+gchar           *report_create_from_module_list_format(GSList *modules, ReportFormat format);
+
+void		 report_context_free(ReportContext *ctx);
+void             report_module_list_free(GSList *modules);
+
+#endif	/* __REPORT_H__ */
diff --git a/includes/riscv/processor-platform.h b/includes/riscv/processor-platform.h
new file mode 100644
index 0000000..07cbf86
--- /dev/null
+++ b/includes/riscv/processor-platform.h
@@ -0,0 +1,36 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+#include "cpu_util.h"
+
+struct _Processor {
+    gint id; /* hart */
+    gfloat cpu_mhz; /* for devices.c, identical to cpukhz_max/1000 */
+    cpu_topology_data *cputopo;
+    cpufreq_data *cpufreq;
+
+    gchar *model_name;
+    gchar *mmu, *isa, *uarch;
+    gchar *flags; /* expanded from isa */
+    gfloat bogomips; /* not used */
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/s390/processor-platform.h b/includes/s390/processor-platform.h
new file mode 100644
index 0000000..9164a7f
--- /dev/null
+++ b/includes/s390/processor-platform.h
@@ -0,0 +1,36 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+#include "cpu_util.h"
+
+struct _Processor {
+    gint id;
+    gfloat cpu_mhz; /* for devices.c, identical to cpukhz_max/1000 */
+    cpu_topology_data *cputopo;
+    cpufreq_data *cpufreq;
+
+    gchar *model_name; /* vendor_id */
+    gchar *proc_str;
+    gfloat bogomips;
+
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/sh/processor-platform.h b/includes/sh/processor-platform.h
new file mode 100644
index 0000000..26b58ec
--- /dev/null
+++ b/includes/sh/processor-platform.h
@@ -0,0 +1,32 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+struct _Processor {
+    gchar *model_name;
+    gchar *vendor_id;
+    gfloat bogomips, cpu_mhz;
+
+    gfloat bus_mhz, mod_mhz;
+
+    gchar *family;
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/sha1.h b/includes/sha1.h
new file mode 100644
index 0000000..573ff8a
--- /dev/null
+++ b/includes/sha1.h
@@ -0,0 +1,30 @@
+/*
+ * SHA-1 in C
+ * By Steve Reid <steve@edmweb.com>
+ * 100% Public Domain
+ */
+
+#ifndef __SHA1_H__
+#define __SHA1_H__
+
+#include <glib.h>
+
+#ifndef LITTLE_ENDIAN
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define LITTLE_ENDIAN		/* This should be #define'd if true. */
+#endif /* G_BYTE_ORDER */
+#endif /* LITTLE_ENDIAN */
+
+
+typedef struct {
+    guint32 state[5];
+    guint32 count[2];
+    guchar buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform(guint32 state[5], guchar buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, guchar* data, unsigned int len);
+void SHA1Final(guchar digest[20], SHA1_CTX* context);
+
+#endif	/* __SHA1_H__ */
diff --git a/includes/shell.h b/includes/shell.h
new file mode 100644
index 0000000..2eb9e6d
--- /dev/null
+++ b/includes/shell.h
@@ -0,0 +1,225 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#ifndef __SHELL_H__
+#define __SHELL_H__
+
+#include <gtk/gtk.h>
+
+#include "loadgraph.h"
+#include "help-viewer.h"
+
+typedef struct _Shell			Shell;
+typedef struct _ShellTree		ShellTree;
+typedef struct _ShellInfoTree		ShellInfoTree;
+typedef struct _ShellNote		ShellNote;
+typedef struct _ShellSummary		ShellSummary;
+
+typedef struct _ShellModule		ShellModule;
+typedef struct _ShellModuleMethod	ShellModuleMethod;
+typedef struct _ShellModuleEntry	ShellModuleEntry;
+
+typedef struct _ShellFieldUpdate	ShellFieldUpdate;
+typedef struct _ShellFieldUpdateSource	ShellFieldUpdateSource;
+
+typedef enum {
+    SHELL_ORDER_DESCENDING,
+    SHELL_ORDER_ASCENDING,
+} ShellOrderType;
+
+typedef enum {
+    SHELL_PACK_RESIZE = 1 << 0,
+    SHELL_PACK_SHRINK = 1 << 1
+} ShellPackOptions;
+
+typedef enum {
+    SHELL_VIEW_NORMAL,
+    SHELL_VIEW_DUAL,
+    SHELL_VIEW_LOAD_GRAPH,
+    SHELL_VIEW_PROGRESS,
+    SHELL_VIEW_PROGRESS_DUAL,
+    SHELL_VIEW_SUMMARY,
+    SHELL_VIEW_N_VIEWS
+} ShellViewType;
+
+typedef enum {
+    TREE_COL_PBUF,
+    TREE_COL_NAME,
+    TREE_COL_MODULE_ENTRY,
+    TREE_COL_MODULE,
+    TREE_COL_SEL,
+    TREE_NCOL
+} ShellTreeColumns;
+
+typedef enum {
+    INFO_TREE_COL_NAME,
+    INFO_TREE_COL_VALUE,
+    INFO_TREE_COL_DATA,
+    INFO_TREE_COL_PBUF,
+    INFO_TREE_COL_PROGRESS,
+    INFO_TREE_COL_EXTRA1,
+    INFO_TREE_COL_EXTRA2,
+    INFO_TREE_NCOL
+} ShellInfoTreeColumns;
+
+struct _Shell {
+    GtkWidget		*window, *vbox;
+    GtkWidget		*status, *progress;
+    GtkWidget		*remote_label;
+    GtkWidget		*notebook;
+    GtkWidget		*hpaned, *vpaned;
+
+    ShellTree		*tree;
+    ShellInfoTree	*info, *moreinfo;
+    ShellModule		*selected_module;
+    ShellModuleEntry	*selected;
+    ShellNote		*note;
+    ShellSummary	*summary;
+    LoadGraph		*loadgraph;
+
+    GtkActionGroup	*action_group;
+    GtkUIManager	*ui_manager;
+    GSList		*merge_ids;
+
+    ShellViewType	 view_type;
+    gboolean		 normalize_percentage;
+    
+    gint		_pulses;
+    ShellOrderType	_order_type;
+    
+    GKeyFile		*hosts;
+    HelpViewer		*help_viewer;
+};
+
+struct _ShellSummary {
+    GtkWidget		*header;
+    GtkWidget		*scroll;
+    GtkWidget		*view;
+    
+    GSList		*items;
+};
+
+struct _ShellTree {
+    GtkWidget		*scroll;
+    GtkWidget		*view;
+    GtkTreeModel	*model;
+    GtkTreeSelection	*selection;
+
+    GSList		*modules;
+};
+
+struct _ShellInfoTree {
+    GtkWidget		*scroll;
+    GtkWidget		*view;
+    GtkTreeModel        *model;
+    GtkTreeSelection	*selection;
+    
+    GtkTreeViewColumn	 *col_progress, *col_value, *col_extra1, *col_extra2, *col_textvalue;
+};
+
+struct _ShellNote {
+    GtkWidget		*event_box;
+    GtkWidget		*label;
+};
+
+struct _ShellModule {
+    gchar		*name;
+    GdkPixbuf		*icon;
+    GModule		*dll;
+
+    gpointer		(*aboutfunc) ();
+    gchar		*(*summaryfunc) ();
+    void		(*deinit) ();
+    
+    guchar		 weight;
+
+    GSList		*entries;
+};
+
+struct _ShellModuleMethod {
+    gchar	*name;
+    gpointer	function;
+};
+
+struct _ShellModuleEntry {
+    gchar		*name;
+    GdkPixbuf		*icon;
+    gchar		*icon_file;
+    gboolean		 selected;
+    gint		 number;
+    guint32		 flags;
+    
+    gchar		*(*func) ();
+    void		(*scan_func) ();
+
+    gchar		*(*fieldfunc) (gchar * entry);
+    gchar 		*(*morefunc)  (gchar * entry);
+    gchar		*(*notefunc)  (gint entry);
+};
+
+struct _ShellFieldUpdate {
+    ShellModuleEntry	*entry;
+    gchar		*field_name;
+};
+
+struct _ShellFieldUpdateSource {
+    guint		 source_id;
+    ShellFieldUpdate	*sfu;
+};
+
+void		shell_init(GSList *modules);
+void		shell_do_reload(void);
+
+Shell	       *shell_get_main_shell();
+
+void		shell_action_set_enabled(const gchar *action_name,
+                                         gboolean setting);
+gboolean	shell_action_get_enabled(const gchar *action_name);
+gboolean	shell_action_get_active(const gchar *action_name);
+void		shell_action_set_active(const gchar *action_name,
+                                        gboolean setting);
+void		shell_action_set_property(const gchar *action_name,
+                                          const gchar *property,
+                                          gboolean setting);
+
+void		shell_set_side_pane_visible(gboolean setting);
+void		shell_set_note_from_entry(ShellModuleEntry *entry);
+void		shell_ui_manager_set_visible(const gchar *path,
+                                             gboolean setting);
+
+void		shell_status_update(const gchar *message);
+void		shell_status_pulse(void);
+void		shell_status_set_percentage(gint percentage);
+void		shell_status_set_enabled(gboolean setting);
+
+void		shell_view_set_enabled(gboolean setting);
+
+void		shell_clear_timeouts(Shell *shell);
+void		shell_clear_tree_models(Shell *shell);
+void		shell_clear_field_updates(void);
+void		shell_set_title(Shell *shell, char *subtitle);
+
+void		shell_add_modules_to_gui(gpointer _shell_module, gpointer _shell_tree);
+
+void		shell_save_hosts_file(void);
+void		shell_update_remote_menu(void);
+
+void		shell_set_remote_label(Shell *shell, gchar *label);
+
+#endif				/* __SHELL_H__ */
+
+
diff --git a/includes/socket.h b/includes/socket.h
new file mode 100644
index 0000000..7c44837
--- /dev/null
+++ b/includes/socket.h
@@ -0,0 +1,36 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __HI_SOCKET_H__
+#define __HI_SOCKET_H__
+
+typedef struct _Socket	Socket;
+
+struct _Socket {
+  gint   sock;
+};
+
+Socket *sock_connect(gchar * host, gint port);
+int	sock_write(Socket * s, gchar * str);
+int	sock_read(Socket * s, gchar * buffer, gint size);
+void	sock_close(Socket * s);
+
+int	sock_ready_to_read(Socket *s);
+int	sock_ready_to_write(Socket *s);
+
+#endif	/* __HI_SOCKET_H__ */
diff --git a/includes/sparc/processor-platform.h b/includes/sparc/processor-platform.h
new file mode 100644
index 0000000..31748a5
--- /dev/null
+++ b/includes/sparc/processor-platform.h
@@ -0,0 +1,29 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+struct _Processor {
+    gchar *model_name;
+    gchar *has_fpu;
+    gfloat cpu_mhz;
+    gchar *cpucaps;
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/ssh-conn.h b/includes/ssh-conn.h
new file mode 100644
index 0000000..b1b0a9c
--- /dev/null
+++ b/includes/ssh-conn.h
@@ -0,0 +1,66 @@
+/* 
+   Remote Client
+   HardInfo - Displays System Information
+   Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+
+   Based on ssh-method.c from GnomeVFS
+   Copyright (C) 1999 Free Software Foundation
+   Original author: Ian McKellar <yakk@yakk.net>
+
+   The Gnome Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+#ifndef __SSH_CONN_H__
+#define __SSH_CONN_H__
+
+#include "config.h"
+#ifdef HAS_LIBSOUP
+#include <libsoup/soup.h>
+
+typedef struct _SSHConn SSHConn;
+
+typedef enum {
+    SSH_CONN_OK,
+    SSH_CONN_NO_URI,
+    SSH_CONN_UNKNOWN_PROTOCOL,
+    SSH_CONN_UNKNOWN_ERROR,
+    SSH_CONN_CANNOT_SPAWN_SSH,
+    SSH_CONN_BAD_PARAMS,
+    SSH_CONN_PERMISSION_DENIED,
+    SSH_CONN_HOST_KEY_CHECK_FAIL,
+    SSH_CONN_REFUSED,
+    SSH_CONN_INVALID_USER_PASS,
+} SSHConnResponse;
+
+struct _SSHConn {
+    SoupURI *uri;
+    int fd_read, fd_write, fd_error;
+    GPid pid;
+    gchar *askpass_path;
+    
+    gint exit_status;
+};
+
+SSHConnResponse ssh_new(SoupURI * uri,
+			SSHConn ** conn_return, gchar * command);
+void ssh_close(SSHConn * conn);
+
+int ssh_write(SSHConn * conn,
+	      gconstpointer buffer, gint num_bytes, gint * bytes_written);
+int ssh_read(gint fd, gpointer buffer, gint num_bytes, gint * bytes_read);
+
+const char *ssh_conn_errors[10];
+#endif				/* HAS_LIBSOUP */
+#endif				/* __SSH_CONN_H__ */
diff --git a/includes/stock.h b/includes/stock.h
new file mode 100644
index 0000000..706e5c5
--- /dev/null
+++ b/includes/stock.h
@@ -0,0 +1,34 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __STOCK_H__
+#define __STOCK_H__
+
+#define HI_STOCK_REPORT		"hi-stock-report"
+#define HI_STOCK_INTERNET	"hi-stock-internet"
+#define HI_STOCK_MODULE		"hi-stock-module"
+#define HI_STOCK_ABOUT_MODULES	"hi-stock-about-modules"
+#define HI_STOCK_SYNC_MENU	"hi-stock-sync-menu"
+#define HI_STOCK_DONATE		"hi-stock-donate"
+#define HI_STOCK_SERVER		"hi-stock-server"
+
+void stock_icons_init(void);
+void stock_icon_register(gchar *filename, gchar *stock_id);
+void stock_icon_register_pixbuf(GdkPixbuf *pixbuf, gchar *stock_id);
+
+#endif	/* __STOCK_H__ */
diff --git a/includes/syncmanager.h b/includes/syncmanager.h
new file mode 100644
index 0000000..ae0ed26
--- /dev/null
+++ b/includes/syncmanager.h
@@ -0,0 +1,42 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __SYNCMANAGER_H__
+#define __SYNCMANAGER_H__
+
+#include <gtk/gtk.h>
+
+typedef struct _SyncEntry	SyncEntry;
+
+struct _SyncEntry {
+  gchar *name;
+  gchar	*fancy_name;
+  gchar	*save_to;
+
+  gchar	*(*get_data)(void);
+  void   (*callback)(SyncEntry *entry, const gchar *response);
+  
+  gboolean selected;
+};
+
+void sync_manager_add_entry(SyncEntry *entry);
+void sync_manager_clear_entries(void);
+void sync_manager_show(GtkWidget *parent);
+gint sync_manager_count_entries(void);
+
+#endif	/* __SYNCMANAGER_H__ */
diff --git a/includes/test-utils.h b/includes/test-utils.h
new file mode 100644
index 0000000..21cac6b
--- /dev/null
+++ b/includes/test-utils.h
@@ -0,0 +1,24 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "libsoup/soup-types.h"
+
+void test_init    (int argc, char **argv, GOptionEntry *entries);
+void test_cleanup (void);
+
+extern int debug_level, errors;
+extern gboolean expect_warning;
+void debug_printf (int level, const char *format, ...) G_GNUC_PRINTF (2, 3);
+
+#ifdef HAVE_APACHE
+void apache_init    (void);
+void apache_cleanup (void);
+#endif
+
+SoupSession *soup_test_session_new         (GType type, ...);
+void         soup_test_session_abort_unref (SoupSession *session);
+
+SoupServer  *soup_test_server_new     (gboolean in_own_thread);
+SoupServer  *soup_test_server_new_ssl (gboolean in_own_thread);
+
diff --git a/includes/uidefs.h b/includes/uidefs.h
new file mode 100644
index 0000000..70d2de1
--- /dev/null
+++ b/includes/uidefs.h
@@ -0,0 +1,59 @@
+#ifndef __UIDEFS_H__
+#define __UIDEFS_H__
+
+#include "config.h"
+
+#if RELEASE
+#define DEBUG_TOOLBAR_ITEMS
+#else 		/* !RELEASE */
+#define DEBUG_TOOLBAR_ITEMS	"<separator/>" \
+                                "<toolitem name=\"ReportBug\" action=\"ReportBugAction\" />"
+#endif		/* !RELEASE */
+
+#ifdef HAS_LIBSOUP
+#define SYNC_MANAGER_ITEMS "		<separator/>" \
+"		<menuitem name=\"SyncManager\" action=\"SyncManagerAction\" />"
+
+#else		/* !HAS_LIBSOUP */
+#define SYNC_MANAGER_ITEMS
+#endif		/* !HAS_LIBSOUP */
+
+char *uidefs_str = "<ui>" \
+"	<menubar>" \
+"	<menu name=\"InformationMenu\" action=\"InformationMenuAction\">" \
+"		<menuitem name=\"Report\" action=\"ReportAction\" />" \
+"		<menuitem name=\"Copy\" action=\"CopyAction\" />" \
+SYNC_MANAGER_ITEMS
+"		<separator/>" \
+"		<menuitem name=\"Quit\" action=\"QuitAction\" />" \
+"	</menu>" \
+"	<menu name=\"ViewMenu\" action=\"ViewMenuAction\">" \
+"		<menuitem name=\"SidePane\" action=\"SidePaneAction\"/>" \
+"		<menuitem name=\"Toolbar\" action=\"ToolbarAction\"/>" \
+"		<separator/>"\
+"		<separator name=\"LastSep\"/>" \
+"		<menuitem name=\"Refresh\" action=\"RefreshAction\"/>" \
+"	</menu>" \
+"	<menu name=\"HelpMenu\" action=\"HelpMenuAction\">" \
+"		<menuitem name=\"WebPage\" action=\"HomePageAction\"/>" \
+"		<menuitem name=\"ReportBug\" action=\"ReportBugAction\"/>" \
+"		<separator/>" \
+"		<menu name=\"HelpMenuModules\" action=\"HelpMenuModulesAction\">" \
+"			<separator name=\"LastSep\"/>" \
+"		</menu>" \
+"		<menuitem name=\"About\" action=\"AboutAction\"/>" \
+"	</menu>" \
+"	</menubar>" \
+"	<toolbar action=\"MainMenuBar\" action=\"MainMenuBarAction\">" \
+"		<placeholder name=\"ToolItems\">" \
+"			<toolitem name=\"Refresh\" action=\"RefreshAction\"/>" \
+"			<separator/>" \
+"			<toolitem name=\"Report\" action=\"ReportAction\"/>" \
+"			<toolitem name=\"Copy\" action=\"CopyAction\"/>" \
+"			<separator/>" \
+DEBUG_TOOLBAR_ITEMS \
+"		</placeholder>" \
+"	</toolbar>" \
+"</ui>";
+
+#endif	/* __UIDEFS_H__ */
diff --git a/includes/vendor.h b/includes/vendor.h
new file mode 100644
index 0000000..778e2ea
--- /dev/null
+++ b/includes/vendor.h
@@ -0,0 +1,33 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __VENDOR_H__
+#define __VENDOR_H__
+
+typedef struct _Vendor	Vendor;
+struct _Vendor {
+  char *id;
+  char *name;
+  char *url;
+};
+
+void  vendor_init(void);
+const gchar *vendor_get_name(const gchar *id);
+const gchar *vendor_get_url(const gchar *id);
+
+#endif	/* __VENDOR_H__ */
diff --git a/includes/x86/processor-platform.h b/includes/x86/processor-platform.h
new file mode 100644
index 0000000..a89a831
--- /dev/null
+++ b/includes/x86/processor-platform.h
@@ -0,0 +1,63 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __PROCESSOR_PLATFORM_H__
+#define __PROCESSOR_PLATFORM_H__
+
+#include "cpu_util.h"
+
+typedef struct _ProcessorCache ProcessorCache;
+
+struct _ProcessorCache {
+    gint level;
+    gint number_of_sets;
+    gint physical_line_partition;
+    gint size;
+    gchar *type;
+    gint ways_of_associativity;
+    gint uid; /* uid is unique among caches with the same (type, level) */
+    gchar *shared_cpu_list; /* some kernel's don't give a uid, so try shared_cpu_list */
+    gint phy_sock;
+};
+
+struct _Processor {
+    gchar *model_name;
+    gchar *vendor_id;
+    gchar *flags;
+    gchar *bugs;
+    gchar *pm;             /* power management features */
+    gint cache_size;
+    gfloat bogomips;
+    gchar *microcode;
+
+    gint id;
+    gfloat cpu_mhz; /* for devices.c, identical to cpukhz_max/1000 */
+    cpu_topology_data *cputopo;
+    cpufreq_data *cpufreq;
+
+    gchar *has_fpu;
+    gchar *bug_fdiv, *bug_hlt, *bug_f00f, *bug_coma;
+
+    gint model, family, stepping;
+    gchar *strmodel;
+
+    GSList *cache;
+
+};
+
+#endif	/* __PROCESSOR_PLATFORM_H__ */
diff --git a/includes/xmlrpc-client.h b/includes/xmlrpc-client.h
new file mode 100644
index 0000000..32fad08
--- /dev/null
+++ b/includes/xmlrpc-client.h
@@ -0,0 +1,43 @@
+/*
+ *    XMLRPC Client
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __XMLRPC_CLIENT_H__
+#define __XMLRPC_CLIENT_H__
+
+#include "config.h"
+
+#ifdef HAS_LIBSOUP
+#include <libsoup/soup.h>
+
+void xmlrpc_init(void);
+gint xmlrpc_get_integer(gchar *addr,
+                        gchar *method,
+                        const gchar *param_types,
+                        ...);
+gchar *xmlrpc_get_string(gchar *addr,
+                         gchar *method,
+                         const gchar *param_types,
+                         ...);
+GValueArray *xmlrpc_get_array(gchar *addr,
+                              gchar *method,
+                              const gchar *param_types,
+                              ...);
+#endif /* HAS_LIBSOUP */
+
+#endif	/* __XMLRPC_CLIENT_H__ */
diff --git a/includes/xmlrpc-server.h b/includes/xmlrpc-server.h
new file mode 100644
index 0000000..e608b71
--- /dev/null
+++ b/includes/xmlrpc-server.h
@@ -0,0 +1,25 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#ifndef __XMLRPC_SERVER_H__
+#define __XMLRPC_SERVER_H__
+
+void xmlrpc_server_start(GMainLoop *main_loop);
+void xmlrpc_server_init(void);
+
+#endif	/* __XMLRPC_SERVER_H__ */
+
diff --git a/modules/benchmark.c b/modules/benchmark.c
new file mode 100644
index 0000000..26de955
--- /dev/null
+++ b/modules/benchmark.c
@@ -0,0 +1,720 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <hardinfo.h>
+#include <iconcache.h>
+#include <shell.h>
+#include <config.h>
+#include <syncmanager.h>
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <sys/types.h>
+#include <signal.h>
+
+#include "benchmark.h"
+
+#include "benchmark/bench_results.c"
+
+bench_value bench_results[BENCHMARK_N_ENTRIES];
+
+static void do_benchmark(void (*benchmark_function)(void), int entry);
+static gchar *benchmark_include_results_reverse(bench_value result, const gchar * benchmark);
+static gchar *benchmark_include_results(bench_value result, const gchar * benchmark);
+
+/* ModuleEntry entries, scan_*(), callback_*(), etc. */
+#include "benchmark/benches.c"
+
+static gboolean sending_benchmark_results = FALSE;
+
+char *bench_value_to_str(bench_value r) {
+    return g_strdup_printf("%lf; %lf; %d", r.result, r.elapsed_time, r.threads_used);
+}
+
+bench_value bench_value_from_str(const char* str) {
+    bench_value ret = EMPTY_BENCH_VALUE;
+    double r, e;
+    int t, c;
+    if (str) {
+        c = sscanf(str, "%lf; %lf; %d", &r, &e, &t);
+        if (c >= 3) {
+            ret.result = r;
+            ret.elapsed_time = e;
+            ret.threads_used = t;
+        }
+    }
+    return ret;
+}
+
+typedef struct _ParallelBenchTask ParallelBenchTask;
+
+struct _ParallelBenchTask {
+    gint	thread_number;
+    guint	start, end;
+    gpointer	data, callback;
+    int *stop;
+};
+
+static gpointer benchmark_crunch_for_dispatcher(gpointer data)
+{
+    ParallelBenchTask 	*pbt = (ParallelBenchTask *)data;
+    gpointer (*callback)(void *data, gint thread_number);
+    gpointer return_value = g_malloc(sizeof(int));
+    int count = 0;
+
+    if ((callback = pbt->callback)) {
+        while(!*pbt->stop) {
+            callback(pbt->data, pbt->thread_number);
+            /* don't count if didn't finish in time */
+            if (!*pbt->stop)
+                count++;
+        }
+    } else {
+        DEBUG("this is thread %p; callback is NULL and it should't be!", g_thread_self());
+    }
+
+    g_free(pbt);
+
+    *(double*)return_value = (double)count;
+    return return_value;
+}
+
+bench_value benchmark_crunch_for(float seconds, gint n_threads,
+                               gpointer callback, gpointer callback_data) {
+    int cpu_procs, cpu_cores, cpu_threads, thread_number, stop = 0;
+    GSList *threads = NULL, *t;
+    GTimer *timer;
+    bench_value ret = EMPTY_BENCH_VALUE;
+
+    timer = g_timer_new();
+
+    cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads);
+    if (n_threads > 0)
+        ret.threads_used = n_threads;
+    else if (n_threads < 0)
+        ret.threads_used = cpu_cores;
+    else
+        ret.threads_used = cpu_threads;
+
+    g_timer_start(timer);
+    for (thread_number = 0; thread_number < ret.threads_used; thread_number++) {
+        ParallelBenchTask *pbt = g_new0(ParallelBenchTask, 1);
+        GThread *thread;
+
+        DEBUG("launching thread %d", thread_number);
+
+        pbt->thread_number = thread_number;
+        pbt->data     = callback_data;
+        pbt->callback = callback;
+        pbt->stop = &stop;
+
+        thread = g_thread_new("dispatcher",
+            (GThreadFunc)benchmark_crunch_for_dispatcher, pbt);
+        threads = g_slist_prepend(threads, thread);
+
+        DEBUG("thread %d launched as context %p", thread_number, thread);
+    }
+
+    /* wait for time */
+    //while ( g_timer_elapsed(timer, NULL) < seconds ) { }
+    g_usleep(seconds * 1000000);
+
+    /* signal all threads to stop */
+    stop = 1;
+    g_timer_stop(timer);
+
+    ret.result = 0;
+    DEBUG("waiting for all threads to finish");
+    for (t = threads; t; t = t->next) {
+        DEBUG("waiting for thread with context %p", t->data);
+        gpointer *rv = g_thread_join((GThread *)t->data);
+        ret.result += *(double*)rv;
+        g_free(rv);
+    }
+
+    ret.elapsed_time = g_timer_elapsed(timer, NULL);
+
+    g_slist_free(threads);
+    g_timer_destroy(timer);
+
+    return ret;
+}
+
+static gpointer benchmark_parallel_for_dispatcher(gpointer data)
+{
+    ParallelBenchTask 	*pbt = (ParallelBenchTask *)data;
+    gpointer 		(*callback)(unsigned int start, unsigned int end, void *data, gint thread_number);
+    gpointer		return_value = NULL;
+
+    if ((callback = pbt->callback)) {
+        DEBUG("this is thread %p; items %d -> %d, data %p", g_thread_self(),
+              pbt->start, pbt->end, pbt->data);
+        return_value = callback(pbt->start, pbt->end, pbt->data, pbt->thread_number);
+        DEBUG("this is thread %p; return value is %p", g_thread_self(), return_value);
+    } else {
+        DEBUG("this is thread %p; callback is NULL and it should't be!", g_thread_self());
+    }
+
+    g_free(pbt);
+
+    return return_value;
+}
+
+/* one call for each thread to be used */
+bench_value benchmark_parallel(gint n_threads, gpointer callback, gpointer callback_data) {
+    int cpu_procs, cpu_cores, cpu_threads;
+    cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads);
+    if (n_threads == 0) n_threads = cpu_threads;
+    else if (n_threads == -1) n_threads = cpu_cores;
+    return  benchmark_parallel_for(n_threads, 0, n_threads, callback, callback_data);
+}
+
+/* Note:
+ *    benchmark_parallel_for(): element [start] included, but [end] is excluded.
+ *    callback(): expected to processes elements [start] through [end] inclusive.
+ */
+bench_value benchmark_parallel_for(gint n_threads, guint start, guint end,
+                               gpointer callback, gpointer callback_data) {
+    gchar	*temp;
+    int 	cpu_procs, cpu_cores, cpu_threads;
+    guint	iter_per_thread, iter, thread_number = 0;
+    GSList	*threads = NULL, *t;
+    GTimer	*timer;
+
+    bench_value ret = EMPTY_BENCH_VALUE;
+
+    timer = g_timer_new();
+
+    cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads);
+
+    if (n_threads > 0)
+        ret.threads_used = n_threads;
+    else if (n_threads < 0)
+        ret.threads_used = cpu_cores;
+    else
+        ret.threads_used = cpu_threads;
+
+    while (ret.threads_used > 0) {
+        iter_per_thread = (end - start) / ret.threads_used;
+
+        if (iter_per_thread == 0) {
+          DEBUG("not enough items per thread; disabling one thread");
+          ret.threads_used--;
+        } else {
+          break;
+        }
+    }
+
+    DEBUG("Using %d threads across %d logical processors; processing %d elements (%d per thread)",
+          ret.threads_used, cpu_threads, (end - start), iter_per_thread);
+
+    g_timer_start(timer);
+    for (iter = start; iter < end; ) {
+        ParallelBenchTask *pbt = g_new0(ParallelBenchTask, 1);
+        GThread *thread;
+
+        guint ts = iter, te = iter + iter_per_thread;
+        /* add the remainder of items/iter_per_thread to the last thread */
+        if (end - te < iter_per_thread)
+            te = end;
+        iter = te;
+
+        DEBUG("launching thread %d", 1 + thread_number);
+
+        pbt->thread_number = thread_number++;
+        pbt->start    = ts;
+        pbt->end      = te - 1;
+        pbt->data     = callback_data;
+        pbt->callback = callback;
+
+        thread = g_thread_new("dispatcher",
+            (GThreadFunc)benchmark_parallel_for_dispatcher, pbt);
+        threads = g_slist_prepend(threads, thread);
+
+        DEBUG("thread %d launched as context %p", thread_number, thread);
+    }
+
+    DEBUG("waiting for all threads to finish");
+    for (t = threads; t; t = t->next) {
+        DEBUG("waiting for thread with context %p", t->data);
+        gpointer *rv = g_thread_join((GThread *)t->data);
+        if (rv) {
+            if (ret.result == -1.0) ret.result = 0;
+            ret.result += *(double*)rv;
+        }
+        g_free(rv);
+    }
+
+    g_timer_stop(timer);
+    ret.elapsed_time = g_timer_elapsed(timer, NULL);
+
+    g_slist_free(threads);
+    g_timer_destroy(timer);
+
+    DEBUG("finishing; all threads took %f seconds to finish", ret.elapsed_time);
+
+    return ret;
+}
+
+static gchar *clean_cpuname(gchar *cpuname)
+{
+    gchar *ret = NULL, *tmp;
+    gchar *remove[] = {
+        "(R)", "(r)", "(TM)", "(tm)", "Processor",
+        "Technology", "processor", "CPU",
+        "cpu", "Genuine", "Authentic", NULL
+    };
+    gint i;
+
+    ret = g_strdup(cpuname);
+    for (i = 0; remove[i]; i++) {
+      tmp = strreplace(ret, remove[i], "");
+      g_free(ret);
+      ret = tmp;
+    }
+
+    ret = strend(ret, '@');
+    ret = g_strstrip(ret);
+
+    tmp = g_strdup(ret);
+    g_free(ret);
+
+    return tmp;
+}
+
+gchar *hi_more_info(gchar * entry)
+{
+    gchar *info = moreinfo_lookup_with_prefix("BENCH", entry);
+    if (info)
+        return g_strdup(info);
+    return g_strdup("?");
+}
+
+gchar *hi_get_field(gchar * field)
+{
+    gchar *info = moreinfo_lookup_with_prefix("BENCH", field);
+    if (info)
+        return g_strdup(info);
+    return g_strdup(field);
+}
+
+static void br_mi_add(char **results_list, bench_result *b, gboolean select) {
+    gchar *ckey, *rkey;
+
+    ckey = hardinfo_clean_label(b->machine->cpu_name, 0);
+    rkey = strdup(b->machine->mid);
+
+    *results_list = h_strdup_cprintf("$%s%s$%s=%.2f|%s\n", *results_list,
+        select ? "*" : "", rkey, ckey,
+        b->bvalue.result, b->machine->cpu_config);
+
+    moreinfo_add_with_prefix("BENCH", rkey, bench_result_more_info(b) );
+
+    g_free(ckey);
+    g_free(rkey);
+}
+
+static gchar *__benchmark_include_results(bench_value r,
+					  const gchar * benchmark,
+					  ShellOrderType order_type)
+{
+    bench_result *b = NULL;
+    GKeyFile *conf;
+    gchar **machines, *temp = NULL;;
+    gchar *path, *results = g_strdup(""), *return_value, *processor_frequency, *processor_name;
+    int i, n_threads;
+
+    moreinfo_del_with_prefix("BENCH");
+
+    if (r.result > 0.0) {
+        b = bench_result_this_machine(benchmark, r);
+        br_mi_add(&results, b, 1);
+
+        temp = bench_result_benchmarkconf_line(b);
+        printf("[%s]\n%s", benchmark, temp);
+        g_free(temp); temp = NULL;
+    }
+
+    conf = g_key_file_new();
+
+    path = g_build_filename(g_get_home_dir(), ".hardinfo", "benchmark.conf", NULL);
+    if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
+        DEBUG("local benchmark.conf not found, trying system-wide");
+        g_free(path);
+        path = g_build_filename(params.path_data, "benchmark.conf", NULL);
+    }
+
+    g_key_file_load_from_file(conf, path, 0, NULL);
+    g_key_file_set_list_separator(conf, '|');
+
+    machines = g_key_file_get_keys(conf, benchmark, NULL, NULL);
+    for (i = 0; machines && machines[i]; i++) {
+        gchar **values;
+        bench_result *sbr;
+
+        values = g_key_file_get_string_list(conf, benchmark, machines[i], NULL, NULL);
+
+        sbr = bench_result_benchmarkconf(benchmark, machines[i], values);
+        br_mi_add(&results, sbr, 0);
+
+        bench_result_free(sbr);
+        g_strfreev(values);
+    }
+
+    g_strfreev(machines);
+    g_free(path);
+    g_key_file_free(conf);
+
+    return_value = g_strdup_printf("[$ShellParam$]\n"
+                   "Zebra=1\n"
+                   "OrderType=%d\n"
+                   "ViewType=4\n"
+                   "ColumnTitle$Extra1=%s\n" /* CPU Clock */
+                   "ColumnTitle$Progress=%s\n" /* Results */
+                   "ColumnTitle$TextValue=%s\n" /* CPU */
+                   "ShowColumnHeaders=true\n"
+                   "[%s]\n%s",
+                   order_type,
+                   _("CPU Config"), _("Results"), _("CPU"),
+                   benchmark, results);
+
+    bench_result_free(b);
+    return return_value;
+}
+
+static gchar *benchmark_include_results_reverse(bench_value result, const gchar * benchmark)
+{
+    return __benchmark_include_results(result, benchmark, SHELL_ORDER_DESCENDING);
+}
+
+static gchar *benchmark_include_results(bench_value result, const gchar * benchmark)
+{
+    return __benchmark_include_results(result, benchmark, SHELL_ORDER_ASCENDING);
+}
+
+typedef struct _BenchmarkDialog BenchmarkDialog;
+struct _BenchmarkDialog {
+    GtkWidget *dialog;
+    bench_value r;
+};
+
+static gboolean do_benchmark_handler(GIOChannel *source,
+                                     GIOCondition condition,
+                                     gpointer data)
+{
+    BenchmarkDialog *bench_dialog = (BenchmarkDialog*)data;
+    GIOStatus status;
+    gchar *result;
+    bench_value r = EMPTY_BENCH_VALUE;
+
+    status = g_io_channel_read_line(source, &result, NULL, NULL, NULL);
+    if (status != G_IO_STATUS_NORMAL) {
+        DEBUG("error while reading benchmark result");
+        r.result = -1.0f;
+        bench_dialog->r = r;
+        gtk_widget_destroy(bench_dialog->dialog);
+        return FALSE;
+    }
+
+    r = bench_value_from_str(result);
+    bench_dialog->r = r;
+
+    gtk_widget_destroy(bench_dialog->dialog);
+    g_free(result);
+
+    return FALSE;
+}
+
+static void do_benchmark(void (*benchmark_function)(void), int entry)
+{
+    int old_priority = 0;
+
+    if (params.gui_running && !sending_benchmark_results) {
+       gchar *argv[] = { params.argv0, "-b", entries[entry].name,
+                         "-m", "benchmark.so", "-a", NULL };
+       GPid bench_pid;
+       gint bench_stdout;
+       GtkWidget *bench_dialog;
+       GtkWidget *bench_image;
+       BenchmarkDialog *benchmark_dialog;
+       GSpawnFlags spawn_flags = G_SPAWN_STDERR_TO_DEV_NULL;
+       gchar *bench_status;
+
+       bench_value r = EMPTY_BENCH_VALUE;
+       bench_results[entry] = r;
+
+       bench_status = g_strdup_printf(_("Benchmarking: <b>%s</b>."), entries[entry].name);
+
+       shell_view_set_enabled(FALSE);
+       shell_status_update(bench_status);
+
+       g_free(bench_status);
+
+       bench_image = icon_cache_get_image("benchmark.png");
+       gtk_widget_show(bench_image);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+       GtkWidget *button;
+       GtkWidget *content_area;
+       GtkWidget *hbox;
+       GtkWidget *label;
+
+       bench_dialog = gtk_dialog_new_with_buttons("",
+                                                  NULL,
+                                                  GTK_DIALOG_MODAL,
+                                                  _("Cancel"),
+                                                  GTK_RESPONSE_ACCEPT,
+                                                  NULL);
+       content_area = gtk_dialog_get_content_area(GTK_DIALOG(bench_dialog));
+       label = gtk_label_new(_("Benchmarking. Please do not move your mouse " \
+                                             "or press any keys."));
+       hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+       gtk_box_pack_start(GTK_BOX(hbox), bench_image, TRUE, TRUE, 5);
+       gtk_box_pack_end(GTK_BOX(hbox), label, TRUE, TRUE, 5);
+       gtk_container_add(GTK_CONTAINER (content_area), hbox);
+       gtk_widget_show_all(bench_dialog);
+#else
+       bench_dialog = gtk_message_dialog_new(GTK_WINDOW(shell_get_main_shell()->window),
+                                             GTK_DIALOG_MODAL,
+                                             GTK_MESSAGE_INFO,
+                                             GTK_BUTTONS_NONE,
+                                             _("Benchmarking. Please do not move your mouse " \
+                                             "or press any keys."));
+       gtk_dialog_add_buttons(GTK_DIALOG(bench_dialog),
+                              _("Cancel"), GTK_RESPONSE_ACCEPT, NULL);
+       gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(bench_dialog), bench_image);
+#endif
+
+       while (gtk_events_pending()) {
+         gtk_main_iteration();
+       }
+
+       benchmark_dialog = g_new0(BenchmarkDialog, 1);
+       benchmark_dialog->dialog = bench_dialog;
+       benchmark_dialog->r = r;
+
+       if (!g_path_is_absolute(params.argv0)) {
+          spawn_flags |= G_SPAWN_SEARCH_PATH;
+       }
+
+       if (g_spawn_async_with_pipes(NULL,
+                                    argv, NULL,
+                                    spawn_flags,
+                                    NULL, NULL,
+                                    &bench_pid,
+                                    NULL, &bench_stdout, NULL,
+                                    NULL)) {
+          GIOChannel *channel;
+          guint watch_id;
+
+          DEBUG("spawning benchmark; pid=%d", bench_pid);
+
+          channel = g_io_channel_unix_new(bench_stdout);
+          watch_id = g_io_add_watch(channel, G_IO_IN, do_benchmark_handler,
+                                    benchmark_dialog);
+
+          switch (gtk_dialog_run(GTK_DIALOG(bench_dialog))) {
+            case GTK_RESPONSE_NONE:
+              DEBUG("benchmark finished");
+              break;
+            case GTK_RESPONSE_ACCEPT:
+              DEBUG("cancelling benchmark");
+
+              gtk_widget_destroy(bench_dialog);
+              g_source_remove(watch_id);
+              kill(bench_pid, SIGINT);
+          }
+
+          bench_results[entry] = benchmark_dialog->r;
+
+          g_io_channel_unref(channel);
+          shell_view_set_enabled(TRUE);
+          shell_status_set_enabled(TRUE);
+          g_free(benchmark_dialog);
+
+          shell_status_update(_("Done."));
+
+          return;
+       }
+
+       gtk_widget_destroy(bench_dialog);
+       g_free(benchmark_dialog);
+       shell_status_set_enabled(TRUE);
+       shell_status_update(_("Done."));
+    }
+
+    setpriority(PRIO_PROCESS, 0, -20);
+    benchmark_function();
+    setpriority(PRIO_PROCESS, 0, old_priority);
+}
+
+gchar *hi_module_get_name(void)
+{
+    return g_strdup(_("Benchmarks"));
+}
+
+guchar hi_module_get_weight(void)
+{
+    return 240;
+}
+
+ModuleEntry *hi_module_get_entries(void)
+{
+    return entries;
+}
+
+ModuleAbout *hi_module_get_about(void)
+{
+    static ModuleAbout ma[] = {
+	{
+	 .author = "Leandro A. F. Pereira",
+	 .description = N_("Perform tasks and compare with other systems"),
+	 .version = VERSION,
+	 .license = "GNU GPL version 2"}
+    };
+
+    return ma;
+}
+
+static gchar *get_benchmark_results()
+{
+    gint i;
+    void (*scan_callback) (gboolean rescan);
+
+    sending_benchmark_results = TRUE;
+
+    gchar *machine = module_call_method("devices::getProcessorName");
+    gchar *machineclock = module_call_method("devices::getProcessorFrequency");
+    gchar *machineram = module_call_method("devices::getMemoryTotal");
+    gchar *result = g_strdup_printf("[param]\n"
+				    "machine=%s\n"
+				    "machineclock=%s\n"
+				    "machineram=%s\n"
+				    "nbenchmarks=%zu\n",
+				    machine,
+				    machineclock,
+				    machineram,
+				    G_N_ELEMENTS(entries) - 1);
+    for (i = 0; i < G_N_ELEMENTS(entries); i++) {
+        scan_callback = entries[i].scan_callback;
+        if (!scan_callback)
+            continue;
+
+        if (bench_results[i].result < 0.0) {
+           /* benchmark was cancelled */
+           scan_callback(TRUE);
+        } else {
+           scan_callback(FALSE);
+        }
+
+        result = h_strdup_cprintf("[bench%d]\n"
+                                  "name=%s\n"
+                                  "value=%f\n",
+                                  result,
+                                  i, entries[i].name, bench_results[i]);
+    }
+
+    g_free(machine);
+    g_free(machineclock);
+    g_free(machineram);
+
+    sending_benchmark_results = FALSE;
+
+    return result;
+}
+
+static gchar *run_benchmark(gchar *name)
+{
+    int i;
+
+    DEBUG("name = %s", name);
+
+    for (i = 0; entries[i].name; i++) {
+      if (g_str_equal(entries[i].name, name)) {
+        void (*scan_callback)(gboolean rescan);
+
+        if ((scan_callback = entries[i].scan_callback)) {
+          scan_callback(FALSE);
+
+#define CHK_RESULT_FORMAT(F) (params.result_format && strcmp(params.result_format, F) == 0)
+
+          if (params.run_benchmark) {
+            if (CHK_RESULT_FORMAT("conf") ) {
+               bench_result *b = bench_result_this_machine(name, bench_results[i]);
+               char *temp = bench_result_benchmarkconf_line(b);
+               bench_result_free(b);
+               return temp;
+            } else if (CHK_RESULT_FORMAT("shell") ) {
+               bench_result *b = bench_result_this_machine(name, bench_results[i]);
+               char *temp = bench_result_more_info_complete(b);
+               bench_result_free(b);
+               return temp;
+            }
+            /* defaults to "short" which is below*/
+          }
+
+          return bench_value_to_str(bench_results[i]);
+        }
+      }
+    }
+
+    return NULL;
+}
+
+ShellModuleMethod *hi_exported_methods(void)
+{
+    static ShellModuleMethod m[] = {
+        {"runBenchmark", run_benchmark},
+        {NULL}
+    };
+
+    return m;
+}
+
+void hi_module_init(void)
+{
+    static SyncEntry se[] = {
+	{
+	 .fancy_name = N_("Send benchmark results"),
+	 .name = "SendBenchmarkResults",
+	 .save_to = NULL,
+	 .get_data = get_benchmark_results},
+	{
+	 .fancy_name = N_("Receive benchmark results"),
+	 .name = "RecvBenchmarkResults",
+	 .save_to = "benchmark.conf",
+	 .get_data = NULL}
+    };
+
+    sync_manager_add_entry(&se[0]);
+    sync_manager_add_entry(&se[1]);
+
+    bench_value er = EMPTY_BENCH_VALUE;
+    int i;
+    for (i = 0; i < G_N_ELEMENTS(entries) - 1; i++) {
+         bench_results[i] = er;
+    }
+}
+
+gchar **hi_module_get_dependencies(void)
+{
+    static gchar *deps[] = { "devices.so", NULL };
+
+    return deps;
+}
diff --git a/modules/benchmark/bench_results.c b/modules/benchmark/bench_results.c
new file mode 100644
index 0000000..27a33a6
--- /dev/null
+++ b/modules/benchmark/bench_results.c
@@ -0,0 +1,442 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2017 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *    This file:
+ *    Copyright (C) 2017 Burt P. <pburt0@gmail.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/*/ Used for an unknown value. Having it in only one place cleans up the .po line references */
+static const char *unk = N_("(Unknown)");
+
+typedef struct {
+    char *board;
+    int memory_kiB;
+    char *cpu_name;
+    char *cpu_desc;
+    char *cpu_config;
+    char *ogl_renderer;
+    int processors;
+    int cores;
+    int threads;
+    char *mid;
+} bench_machine;
+
+typedef struct {
+    char *name;
+    bench_value bvalue;
+    bench_machine *machine;
+    int legacy; /* an old benchmark.conf result */
+} bench_result;
+
+static char *cpu_config_retranslate(char *str, int force_en, int replacing) {
+    char *new_str = NULL;
+    char *mhz = (force_en) ? "MHz" : _("MHz");
+    char *c = str, *tmp;
+    int t;
+    float f;
+
+    if (str != NULL) {
+        new_str = strdup("");
+        if (strchr(str, 'x')) {
+            while (c != NULL && sscanf(c, "%dx %f", &t, &f) ) {
+                tmp = g_strdup_printf("%s%s%dx %.2f %s",
+                        new_str, strlen(new_str) ? " + " : "",
+                        t, f, mhz );
+                free(new_str);
+                new_str = tmp;
+                c = strchr(c+1, '+');
+            }
+        } else {
+            sscanf(c, "%f", &f);
+            tmp = g_strdup_printf("%s%s%dx %.2f %s",
+                    new_str, strlen(new_str) ? " + " : "",
+                    1, f, mhz );
+            free(new_str);
+            new_str = tmp;
+        }
+
+        if (replacing)
+            free(str);
+    }
+    return new_str;
+}
+
+/* "2x 1400.00 MHz + 2x 800.00 MHz" -> 4400.0 */
+static float cpu_config_val(char *str) {
+    char *c = str;
+    int t;
+    float f, r = 0.0;
+    if (str != NULL) {
+        if (strchr(str, 'x')) {
+            while (c != NULL && sscanf(c, "%dx %f", &t, &f) ) {
+                r += f * t;
+                c = strchr(c+1, '+');
+            }
+        } else {
+            sscanf(c, "%f", &r);
+        }
+    }
+    return r;
+}
+
+static int cpu_config_cmp(char *str0, char *str1) {
+    float r0, r1;
+    r0 = cpu_config_val(str0);
+    r1 = cpu_config_val(str1);
+    if (r0 == r1) return 0;
+    if (r0 < r1) return -1;
+    return 1;
+}
+
+static int cpu_config_is_close(char *str0, char *str1) {
+    float r0, r1, r1n;
+    r0 = cpu_config_val(str0);
+    r1 = cpu_config_val(str1);
+    r1n = r1 * .9;
+    if (r0 > r1n && r0 < r1)
+        return 1;
+    return 0;
+}
+
+static gen_machine_id(bench_machine *m) {
+    char *s;
+    if (m) {
+        if (m->mid != NULL)
+            free(m->mid);
+        /* Don't try and translate unknown. The mid string needs to be made of all
+         * untranslated elements.*/
+        m->mid = g_strdup_printf("%s;%s;%.2f",
+            (m->board != NULL) ? m->board : "(Unknown)", m->cpu_name, cpu_config_val(m->cpu_config) );
+        s = m->mid;
+        while (*s != 0) {
+            if (!isalnum(*s)) {
+                if (*s != ';'
+                    && *s != '('
+                    && *s != '('
+                    && *s != ')')
+                *s = '_';
+            }
+            s++;
+        }
+    }
+}
+
+bench_machine *bench_machine_new() {
+    bench_machine *m = NULL;
+    m = malloc(sizeof(bench_machine));
+    if (m)
+        memset(m, 0, sizeof(bench_machine));
+    return m;
+}
+
+bench_machine *bench_machine_this() {
+    bench_machine *m = NULL;
+    char *tmp;
+
+    m = bench_machine_new();
+    if (m) {
+        m->board = module_call_method("devices::getMotherboard");
+        m->cpu_name = module_call_method("devices::getProcessorName");
+        m->cpu_desc = module_call_method("devices::getProcessorDesc");
+        m->cpu_config = module_call_method("devices::getProcessorFrequencyDesc");
+        m->ogl_renderer = module_call_method("computer::getOGLRenderer");
+        tmp = module_call_method("devices::getMemoryTotal");
+        m->memory_kiB = atoi(tmp);
+        free(tmp);
+
+        cpu_procs_cores_threads(&m->processors, &m->cores, &m->threads);
+        gen_machine_id(m);
+    }
+    return m;
+}
+
+void bench_machine_free(bench_machine *s) {
+    if (s) {
+        free(s->board);
+        free(s->cpu_name);
+        free(s->cpu_desc);
+        free(s->cpu_config);
+        free(s->mid);
+    }
+}
+
+void bench_result_free(bench_result *s) {
+    if (s) {
+        free(s->name);
+        bench_machine_free(s->machine);
+    }
+}
+
+bench_result *bench_result_this_machine(const char *bench_name, bench_value r) {
+    bench_result *b = NULL;
+
+    b = malloc(sizeof(bench_result));
+    if (b) {
+        memset(b, 0, sizeof(bench_result));
+        b->machine = bench_machine_this();
+        b->name = strdup(bench_name);
+        b->bvalue = r;
+        b->legacy = 0;
+    }
+    return b;
+}
+
+/* -1 for none */
+static int nx_prefix(const char *str) {
+    char *s, *x;
+    if (str != NULL) {
+        s = (char*)str;
+        x = strchr(str, 'x');
+        if (x && x-s >= 1) {
+            while(s != x) {
+                if (!isdigit(*s))
+                    return -1;
+                s++;
+            }
+            *x = 0;
+            return atoi(str);
+        }
+    }
+    return -1;
+}
+
+/* old results didn't store the actual number of threads used */
+static int guess_threads_old_result(const char *bench_name, int threads_available) {
+#define CHKBNAME(BN) (strcmp(bench_name, BN) == 0)
+    if (CHKBNAME("CPU Fibonacci") )
+        return 1;
+    if (CHKBNAME("FPU FFT") ) {
+        if (threads_available >= 4)
+            return 4;
+        else if (threads_available >= 2)
+            return 2;
+        else
+            return 1;
+    }
+    if (CHKBNAME("CPU N-Queens") ) {
+        if (threads_available >= 10)
+            return 10;
+        else if (threads_available >= 5)
+            return 5;
+        else if (threads_available >= 2)
+            return 2;
+        else
+            return 1;
+    }
+    return threads_available;
+}
+
+bench_result *bench_result_benchmarkconf(const char *section, const char *key, char **values) {
+    bench_result *b = NULL;
+    char *s0, *s1, *s2;
+    int nx = 0, vl = 0;
+    float n, m;
+
+    vl = g_strv_length(values);
+
+    b = malloc(sizeof(bench_result));
+    if (b) {
+        memset(b, 0, sizeof(bench_result));
+        b->machine = bench_machine_new();
+        b->name = strdup(section);
+
+        if (vl >= 10) { /* the 11th could be empty */
+            b->machine->mid = strdup(key);
+            /* first try as bench_value, then try as double 'result' only */
+            b->bvalue = bench_value_from_str(values[0]);
+            if (b->bvalue.result == -1)
+                b->bvalue.result = atoi(values[0]);
+            b->bvalue.threads_used = atoi(values[1]);
+            b->machine->board = strdup(values[2]);
+            b->machine->cpu_name = strdup(values[3]);
+            b->machine->cpu_desc = strdup(values[4]);
+            b->machine->cpu_config = strdup(values[5]);
+            b->machine->memory_kiB = atoi(values[6]);
+            b->machine->processors = atoi(values[7]);
+            b->machine->cores = atoi(values[8]);
+            b->machine->threads = atoi(values[9]);
+            if (vl >= 11)
+                b->machine->ogl_renderer = strdup(values[10]);
+            b->legacy = 0;
+        } else if (vl >= 2) {
+            b->bvalue.result = atof(values[0]);
+            b->legacy = 1;
+
+            /* old old format has prefix before cpu name (ex: 4x Pentium...) */
+            nx = nx_prefix(key);
+            if (nx > 0) {
+                b->machine->cpu_name = strdup(strchr(key, 'x') + 1);
+                b->machine->threads = nx;
+            } else {
+                b->machine->cpu_name = strdup(key);
+                b->machine->threads = 1;
+            }
+
+            b->machine->cpu_config = strdup(values[1]);
+            /* new old format has cpu_config string with nx prefix */
+            nx = nx_prefix(values[1]);
+            if (nx > 0) {
+                b->machine->threads = nx;
+            }
+
+            b->bvalue.threads_used = guess_threads_old_result(section, b->machine->threads);
+
+            /* If the clock rate in the id string is more than the
+             * config string, use that. Older hardinfo used current cpu freq
+             * instead of max freq.
+             * "...@ 2.00GHz" -> 2000.0 */
+            s0 = b->machine->cpu_name;
+            s2 = strstr(s0, "Hz");
+            if (s2 && s2 > s0 + 2) {
+                m = 1; /* assume M */
+                if (*(s2-1) == 'G')
+                    m = 1000;
+                s1 = s2 - 2;
+                while (s1 > s0) {
+                    if (!( isdigit(*s1) || *s1 == '.' || *s1 == ' '))
+                        break;
+                    s1--;
+                }
+
+                if (s1 > s0) {
+                    n = atof(s1+1);
+                    n *= m;
+
+                    s1 = g_strdup_printf("%dx %.2f %s", b->bvalue.threads_used, n, _("MHz"));
+                    if ( cpu_config_cmp(b->machine->cpu_config, s1) == -1
+                         && !cpu_config_is_close(b->machine->cpu_config, s1) ) {
+                        free(b->machine->cpu_config);
+                        b->machine->cpu_config = s1;
+                    } else {
+                        free(s1);
+                    }
+                }
+            }
+
+            /* old results only give threads */
+            b->machine->processors = -1;
+            b->machine->cores = -1;
+        }
+
+        b->machine->cpu_config = cpu_config_retranslate(b->machine->cpu_config, 0, 1);
+        if (b->machine->board != NULL && strlen(b->machine->board) == 0) {
+            free(b->machine->board);
+            b->machine->board = NULL;
+        }
+        if (b->machine->cpu_desc != NULL && strlen(b->machine->cpu_desc) == 0) {
+            free(b->machine->cpu_desc);
+            b->machine->cpu_desc = NULL;
+        }
+        gen_machine_id(b->machine);
+    }
+    return b;
+}
+
+char *bench_result_benchmarkconf_line(bench_result *b) {
+    char *cpu_config = cpu_config_retranslate(b->machine->cpu_config, 1, 0);
+    char *bv = bench_value_to_str(b->bvalue);
+    char *ret = g_strdup_printf("%s=%s|%d|%s|%s|%s|%s|%d|%d|%d|%d|%s\n",
+            b->machine->mid, bv, b->bvalue.threads_used,
+            (b->machine->board != NULL) ? b->machine->board : "",
+            b->machine->cpu_name,
+            (b->machine->cpu_desc != NULL) ? b->machine->cpu_desc : "",
+            cpu_config,
+            b->machine->memory_kiB,
+            b->machine->processors, b->machine->cores, b->machine->threads,
+            (b->machine->ogl_renderer != NULL) ? b->machine->ogl_renderer : ""
+            );
+    free(cpu_config);
+    free(bv);
+    return ret;
+}
+
+static char *bench_result_more_info_less(bench_result *b) {
+    char *memory =
+        (b->machine->memory_kiB > 0)
+        ? g_strdup_printf("%d %s", b->machine->memory_kiB, _("kiB") )
+        : g_strdup(_(unk) );
+
+    char *ret = g_strdup_printf("[%s]\n"
+        /* threads */   "%s=%d\n"
+        /* legacy */    "%s=%s\n"
+                        "[%s]\n"
+        /* board */     "%s=%s\n"
+        /* cpu   */     "%s=%s\n"
+        /* cpudesc */   "%s=%s\n"
+        /* cpucfg */    "%s=%s\n"
+        /* threads */   "%s=%d\n"
+        /* ogl rend */  "%s=%s\n"
+        /* mem */       "%s=%s\n",
+                        _("Benchmark Result"),
+                        _("Threads"), b->bvalue.threads_used,
+                        b->legacy ? _("Note") : "#Note",
+                        b->legacy ? _("This result is from an old version of HardInfo. Results might not be comparable to current version. Some details are missing.") : "",
+                        _("Machine"),
+                        _("Board"), (b->machine->board != NULL) ? b->machine->board : _(unk),
+                        _("CPU Name"), b->machine->cpu_name,
+                        _("CPU Description"), (b->machine->cpu_desc != NULL) ? b->machine->cpu_desc : _(unk),
+                        _("CPU Config"), b->machine->cpu_config,
+                        _("Threads Available"), b->machine->threads,
+                        _("OpenGL Renderer"), (b->machine->ogl_renderer != NULL) ? b->machine->ogl_renderer : _(unk),
+                        _("Memory"), memory
+                        );
+    free(memory);
+    return ret;
+}
+
+static char *bench_result_more_info_complete(bench_result *b) {
+    return g_strdup_printf("[%s]\n"
+        /* bench name */"%s=%s\n"
+        /* threads */   "%s=%d\n"
+        /* result */    "%s=%0.2f\n"
+        /* elapsed */   "%s=%0.2f\n"
+        /* legacy */    "%s=%s\n"
+                        "[%s]\n"
+        /* board */     "%s=%s\n"
+        /* cpu   */     "%s=%s\n"
+        /* cpudesc */   "%s=%s\n"
+        /* cpucfg */    "%s=%s\n"
+        /* threads */   "%s=%d\n"
+        /* ogl rend */  "%s=%s\n"
+        /* mem */       "%s=%d %s\n"
+                        "[%s]\n"
+        /* mid */       "%s=%s\n"
+        /* cfg_val */   "%s=%.2f\n",
+                        _("Benchmark Result"),
+                        _("Benchmark"), b->name,
+                        _("Threads"), b->bvalue.threads_used,
+                        _("Result"), b->bvalue.result,
+                        _("Elapsed Time"), b->bvalue.elapsed_time,
+                        b->legacy ? _("Note") : "#Note",
+                        b->legacy ? _("This result is from an old version of HardInfo. Results might not be comparable to current version. Some details are missing.") : "",
+                        _("Machine"),
+                        _("Board"), (b->machine->board != NULL) ? b->machine->board : _(unk),
+                        _("CPU Name"), b->machine->cpu_name,
+                        _("CPU Description"), (b->machine->cpu_desc != NULL) ? b->machine->cpu_desc : _(unk),
+                        _("CPU Config"), b->machine->cpu_config,
+                        _("Threads Available"), b->machine->threads,
+                        _("OpenGL Renderer"), (b->machine->ogl_renderer != NULL) ? b->machine->ogl_renderer : _(unk),
+                        _("Memory"), b->machine->memory_kiB, _("kiB"),
+                        _("Handles"),
+                        _("mid"), b->machine->mid,
+                        _("cfg_val"), cpu_config_val(b->machine->cpu_config)
+                        );
+}
+
+char *bench_result_more_info(bench_result *b) {
+    //return bench_result_more_info_complete(b);
+    return bench_result_more_info_less(b);
+}
diff --git a/modules/benchmark/benches.c b/modules/benchmark/benches.c
new file mode 100644
index 0000000..e09dedc
--- /dev/null
+++ b/modules/benchmark/benches.c
@@ -0,0 +1,106 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2017 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/* These are parts of modules/benchmark.c where specific benchmarks are defined. */
+
+#define BENCH_CALLBACK(CN, BN, BID, R) \
+gchar *CN() { \
+    if (R)    \
+        return benchmark_include_results_reverse(bench_results[BID], BN); \
+    else      \
+        return benchmark_include_results(bench_results[BID], BN); \
+}
+
+BENCH_CALLBACK(callback_gui, "GPU Drawing", BENCHMARK_GUI, 1);
+BENCH_CALLBACK(callback_fft, "FPU FFT", BENCHMARK_FFT, 0);
+BENCH_CALLBACK(callback_nqueens, "CPU N-Queens", BENCHMARK_NQUEENS, 0);
+BENCH_CALLBACK(callback_raytr, "FPU Raytracing", BENCHMARK_RAYTRACE, 0);
+BENCH_CALLBACK(callback_bfsh, "CPU Blowfish", BENCHMARK_BLOWFISH, 0);
+BENCH_CALLBACK(callback_cryptohash, "CPU CryptoHash", BENCHMARK_CRYPTOHASH, 1);
+BENCH_CALLBACK(callback_fib, "CPU Fibonacci", BENCHMARK_FIB, 0);
+BENCH_CALLBACK(callback_zlib, "CPU Zlib", BENCHMARK_ZLIB, 0);
+
+#define BENCH_SCAN_SIMPLE(SN, BF, BID) \
+void SN(gboolean reload) { \
+    SCAN_START(); \
+    do_benchmark(BF, BID); \
+    SCAN_END(); \
+}
+
+BENCH_SCAN_SIMPLE(scan_fft, benchmark_fft, BENCHMARK_FFT);
+BENCH_SCAN_SIMPLE(scan_nqueens, benchmark_nqueens, BENCHMARK_NQUEENS);
+BENCH_SCAN_SIMPLE(scan_raytr, benchmark_raytrace, BENCHMARK_RAYTRACE);
+BENCH_SCAN_SIMPLE(scan_bfsh, benchmark_fish, BENCHMARK_BLOWFISH);
+BENCH_SCAN_SIMPLE(scan_cryptohash, benchmark_cryptohash, BENCHMARK_CRYPTOHASH);
+BENCH_SCAN_SIMPLE(scan_fib, benchmark_fib, BENCHMARK_FIB);
+BENCH_SCAN_SIMPLE(scan_zlib, benchmark_zlib, BENCHMARK_ZLIB);
+
+void scan_gui(gboolean reload)
+{
+    SCAN_START();
+
+    bench_value er = EMPTY_BENCH_VALUE;
+
+    if (params.run_benchmark) {
+        int argc = 0;
+
+        ui_init(&argc, NULL);
+    }
+
+    if (params.gui_running || params.run_benchmark) {
+        do_benchmark(benchmark_gui, BENCHMARK_GUI);
+    } else {
+        bench_results[BENCHMARK_GUI] = er;
+    }
+    SCAN_END();
+}
+
+static ModuleEntry entries[] = {
+    {N_("CPU Blowfish"), "blowfish.png", callback_bfsh, scan_bfsh, MODULE_FLAG_NONE},
+    {N_("CPU CryptoHash"), "cryptohash.png", callback_cryptohash, scan_cryptohash, MODULE_FLAG_NONE},
+    {N_("CPU Fibonacci"), "nautilus.png", callback_fib, scan_fib, MODULE_FLAG_NONE},
+    {N_("CPU N-Queens"), "nqueens.png", callback_nqueens, scan_nqueens, MODULE_FLAG_NONE},
+    {N_("CPU Zlib"), "file-roller.png", callback_zlib, scan_zlib, MODULE_FLAG_NONE},
+    {N_("FPU FFT"), "fft.png", callback_fft, scan_fft, MODULE_FLAG_NONE},
+    {N_("FPU Raytracing"), "raytrace.png", callback_raytr, scan_raytr, MODULE_FLAG_NONE},
+#if !GTK_CHECK_VERSION(3,0,0)
+    {N_("GPU Drawing"), "module.png", callback_gui, scan_gui, MODULE_FLAG_NO_REMOTE},
+#endif
+    {NULL}
+};
+
+const gchar *hi_note_func(gint entry)
+{
+    switch (entry) {
+    case BENCHMARK_CRYPTOHASH:
+        return _("Results in MiB/second. Higher is better.");
+
+    case BENCHMARK_ZLIB:
+    case BENCHMARK_GUI:
+        return _("Results in HIMarks. Higher is better.");
+
+    case BENCHMARK_FFT:
+    case BENCHMARK_RAYTRACE:
+    case BENCHMARK_BLOWFISH:
+    case BENCHMARK_FIB:
+    case BENCHMARK_NQUEENS:
+        return _("Results in seconds. Lower is better.");
+    }
+
+    return NULL;
+}
diff --git a/modules/benchmark/blowfish.c b/modules/benchmark/blowfish.c
new file mode 100644
index 0000000..2aa11a2
--- /dev/null
+++ b/modules/benchmark/blowfish.c
@@ -0,0 +1,538 @@
+/*
+blowfish.c:  C implementation of the Blowfish algorithm.
+
+Copyright (C) 1997 by Paul Kocher
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+
+
+COMMENTS ON USING THIS CODE:
+
+Normal usage is as follows:
+   [1] Allocate a BLOWFISH_CTX.  (It may be too big for the stack.)
+   [2] Call Blowfish_Init with a pointer to your BLOWFISH_CTX, a pointer to
+       the key, and the number of bytes in the key.
+   [3] To encrypt a 64-bit block, call Blowfish_Encrypt with a pointer to
+       BLOWFISH_CTX, a pointer to the 32-bit left half of the plaintext
+	   and a pointer to the 32-bit right half.  The plaintext will be
+	   overwritten with the ciphertext.
+   [4] Decryption is the same as encryption except that the plaintext and
+       ciphertext are reversed.
+
+Warning #1:  The code does not check key lengths. (Caveat encryptor.)
+Warning #2:  Beware that Blowfish keys repeat such that "ab" = "abab".
+Warning #3:  It is normally a good idea to zeroize the BLOWFISH_CTX before
+  freeing it.
+Warning #4:  Endianness conversions are the responsibility of the caller.
+  (To encrypt bytes on a little-endian platforms, you'll probably want
+  to swap bytes around instead of just casting.)
+Warning #5:  Make sure to use a reasonable mode of operation for your
+  application.  (If you don't know what CBC mode is, see Warning #7.)
+Warning #6:  This code is susceptible to timing attacks.
+Warning #7:  Security engineering is risky and non-intuitive.  Have someone
+  check your work.  If you don't know what you are doing, get help.
+
+
+This is code is fast enough for most applications, but is not optimized for
+speed.
+
+If you require this code under a license other than LGPL, please ask.  (I
+can be located using your favorite search engine.)  Unfortunately, I do not
+have time to provide unpaid support for everyone who uses this code.
+
+                                             -- Paul Kocher
+*/
+
+#include "hardinfo.h"
+#include "benchmark.h"
+#include "blowfish.h"
+
+#define N               16
+static const unsigned long ORIG_P[16 + 2] =
+    { 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L, 0xA4093822L,
+    0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L, 0x452821E6L, 0x38D01377L,
+	0xBE5466CFL, 0x34E90C6CL, 0xC0AC29B7L,
+    0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, 0x9216D5D9L, 0x8979FB1BL
+};
+
+static const unsigned long ORIG_S[4][256] = {
+	{0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L, 0xB8E1AFEDL,
+	 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L, 0x24A19947L, 0xB3916CF7L,
+	 0x0801F2E2L, 0x858EFC16L, 0x636920D8L, 0x71574E69L, 0xA458FEA3L,
+	 0xF4933D7EL, 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
+	 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L, 0xC5D1B023L,
+	 0x286085F0L, 0xCA417918L, 0xB8DB38EFL, 0x8E79DCB0L, 0x603A180EL,
+	 0x6C9E0E8BL, 0xB01E8A3EL, 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL,
+	 0x55605C60L, 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
+	 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL, 0xA15486AFL,
+	 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL, 0x2BA9C55DL, 0x741831F6L,
+	 0xCE5C3E16L, 0x9B87931EL, 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L,
+	 0x28958677L, 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
+	 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L, 0xEF845D5DL,
+	 0xE98575B1L, 0xDC262302L, 0xEB651B88L, 0x23893E81L, 0xD396ACC5L,
+	 0x0F6D6FF3L, 0x83F44239L, 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL,
+	 0x9E1F9B5EL, 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
+	 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L, 0x6EEF0B6CL,
+	 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L, 0xA1F1651DL, 0x39AF0176L,
+	 0x66CA593EL, 0x82430E88L, 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L,
+	 0x3B8B5EBEL, 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
+	 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL, 0x37D0D724L,
+	 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL, 0x075372C9L, 0x80991B7BL,
+	 0x25D479D8L, 0xF6E8DEF7L, 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL,
+	 0x04C006BAL, 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
+	 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL, 0x6DFC511FL,
+	 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L, 0xBEE3D004L, 0xDE334AFDL,
+	 0x660F2807L, 0x192E4BB3L, 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L,
+	 0xB9D3FBDBL, 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
+	 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L, 0x3C7516DFL,
+	 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL, 0x323DB5FAL, 0xFD238760L,
+	 0x53317B48L, 0x3E00DF82L, 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL,
+	 0xDF1769DBL, 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
+	 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L, 0x10FA3D98L,
+	 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL, 0x9A53E479L, 0xB6F84565L,
+	 0xD28E49BCL, 0x4BFB9790L, 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L,
+	 0xCEE4C6E8L, 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
+	 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L, 0xD08ED1D0L,
+	 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L, 0x8FF6E2FBL, 0xF2122B64L,
+	 0x8888B812L, 0x900DF01CL, 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L,
+	 0xB3A8C1ADL, 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
+	 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L, 0xB4A84FE0L,
+	 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L, 0x165FA266L, 0x80957705L,
+	 0x93CC7314L, 0x211A1477L, 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L,
+	 0xFB9D35CFL, 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
+	 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL, 0x2464369BL,
+	 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL, 0x78C14389L, 0xD95A537FL,
+	 0x207D5BA2L, 0x02E5B9C5L, 0x83260376L, 0x6295CFA9L, 0x11C81968L,
+	 0x4E734A41L, 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
+	 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L, 0x08BA6FB5L,
+	 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L, 0xB6636521L, 0xE7B9F9B6L,
+	 0xFF34052EL, 0xC5855664L, 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L,
+	 0x6E85076AL}, {0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL,
+			0xC4192623L, 0xAD6EA6B0L, 0x49A7DF7DL,
+			0x9CEE60B8L, 0x8FEDB266L, 0xECAA8C71L,
+			0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
+			0x193602A5L, 0x75094C29L, 0xA0591340L,
+			0xE4183A3EL, 0x3F54989AL, 0x5B429D65L,
+			0x6B8FE4D6L, 0x99F73FD6L, 0xA1D29C07L,
+			0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
+			0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L,
+			0x021ECC5EL, 0x09686B3FL, 0x3EBAEFC9L,
+			0x3C971814L, 0x6B6A70A1L, 0x687F3584L,
+			0x52A0E286L, 0xB79C5305L, 0xAA500737L,
+			0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL,
+			0x5716F2B8L, 0xB03ADA37L, 0xF0500C0DL,
+			0xF01C1F04L, 0x0200B3FFL, 0xAE0CF51AL,
+			0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
+			0xD19113F9L, 0x7CA92FF6L, 0x94324773L,
+			0x22F54701L, 0x3AE5E581L, 0x37C2DADCL,
+			0xC8B57634L, 0x9AF3DDA7L, 0xA9446146L,
+			0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
+			0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L,
+			0x183EB331L, 0x4E548B38L, 0x4F6DB908L,
+			0x6F420D03L, 0xF60A04BFL, 0x2CB81290L,
+			0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
+			0xDE9A771FL, 0xD9930810L, 0xB38BAE12L,
+			0xDCCF3F2EL, 0x5512721FL, 0x2E6B7124L,
+			0x501ADDE6L, 0x9F84CD87L, 0x7A584718L,
+			0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
+			0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L,
+			0xC464C3D2L, 0xEF1C1847L, 0x3215D908L,
+			0xDD433B37L, 0x24C2BA16L, 0x12A14D43L,
+			0x2A65C451L, 0x50940002L, 0x133AE4DDL,
+			0x71DFF89EL, 0x10314E55L, 0x81AC77D6L,
+			0x5F11199BL, 0x043556F1L, 0xD7A3C76BL,
+			0x3C11183BL, 0x5924A509L, 0xF28FE6EDL,
+			0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
+			0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL,
+			0x5A3E2AB3L, 0x771FE71CL, 0x4E3D06FAL,
+			0x2965DCB9L, 0x99E71D0FL, 0x803E89D6L,
+			0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
+			0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L,
+			0x1E0A2DF4L, 0xF2F74EA7L, 0x361D2B3DL,
+			0x1939260FL, 0x19C27960L, 0x5223A708L,
+			0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
+			0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L,
+			0x018CFF28L, 0xC332DDEFL, 0xBE6C5AA5L,
+			0x65582185L, 0x68AB9802L, 0xEECEA50FL,
+			0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
+			0x1521B628L, 0x29076170L, 0xECDD4775L,
+			0x619F1510L, 0x13CCA830L, 0xEB61BD96L,
+			0x0334FE1EL, 0xAA0363CFL, 0xB5735C90L,
+			0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
+			0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL,
+			0xB2F3846EL, 0x648B1EAFL, 0x19BDF0CAL,
+			0xA02369B9L, 0x655ABB50L, 0x40685A32L,
+			0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
+			0x9B540B19L, 0x875FA099L, 0x95F7997EL,
+			0x623D7DA8L, 0xF837889AL, 0x97E32D77L,
+			0x11ED935FL, 0x16681281L, 0x0E358829L,
+			0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
+			0x57F584A5L, 0x1B227263L, 0x9B83C3FFL,
+			0x1AC24696L, 0xCDB30AEBL, 0x532E3054L,
+			0x8FD948E4L, 0x6DBC3128L, 0x58EBF2EFL,
+			0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
+			0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L,
+			0x203E13E0L, 0x45EEE2B6L, 0xA3AAABEAL,
+			0xDB6C4F15L, 0xFACB4FD0L, 0xC742F442L,
+			0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
+			0xD81E799EL, 0x86854DC7L, 0xE44B476AL,
+			0x3D816250L, 0xCF62A1F2L, 0x5B8D2646L,
+			0xFC8883A0L, 0xC1C7B6A3L, 0x7F1524C3L,
+			0x69CB7492L, 0x47848A0BL, 0x5692B285L,
+			0x095BBF00L, 0xAD19489DL, 0x1462B174L,
+			0x23820E00L, 0x58428D2AL, 0x0C55F5EAL,
+			0x1DADF43EL, 0x233F7061L, 0x3372F092L,
+			0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
+			0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L,
+			0xCE77326EL, 0xA6078084L, 0x19F8509EL,
+			0xE8EFD855L, 0x61D99735L, 0xA969A7AAL,
+			0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
+			0x9E447A2EL, 0xC3453484L, 0xFDD56705L,
+			0x0E1E9EC9L, 0xDB73DBD3L, 0x105588CDL,
+			0x675FDA79L, 0xE3674340L, 0xC5C43465L,
+			0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
+			0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL,
+			0xDB83ADF7L}, {0xE93D5A68L, 0x948140F7L,
+				       0xF64C261CL, 0x94692934L,
+				       0x411520F7L, 0x7602D4F7L,
+				       0xBCF46B2EL, 0xD4A20068L,
+				       0xD4082471L, 0x3320F46AL,
+				       0x43B7D4B7L, 0x500061AFL,
+				       0x1E39F62EL, 0x97244546L,
+				       0x14214F74L, 0xBF8B8840L,
+				       0x4D95FC1DL, 0x96B591AFL,
+				       0x70F4DDD3L, 0x66A02F45L,
+				       0xBFBC09ECL, 0x03BD9785L,
+				       0x7FAC6DD0L, 0x31CB8504L,
+				       0x96EB27B3L, 0x55FD3941L,
+				       0xDA2547E6L, 0xABCA0A9AL,
+				       0x28507825L, 0x530429F4L,
+				       0x0A2C86DAL, 0xE9B66DFBL,
+				       0x68DC1462L, 0xD7486900L,
+				       0x680EC0A4L, 0x27A18DEEL,
+				       0x4F3FFEA2L, 0xE887AD8CL,
+				       0xB58CE006L, 0x7AF4D6B6L,
+				       0xAACE1E7CL, 0xD3375FECL,
+				       0xCE78A399L, 0x406B2A42L,
+				       0x20FE9E35L, 0xD9F385B9L,
+				       0xEE39D7ABL, 0x3B124E8BL,
+				       0x1DC9FAF7L, 0x4B6D1856L,
+				       0x26A36631L, 0xEAE397B2L,
+				       0x3A6EFA74L, 0xDD5B4332L,
+				       0x6841E7F7L, 0xCA7820FBL,
+				       0xFB0AF54EL, 0xD8FEB397L,
+				       0x454056ACL, 0xBA489527L,
+				       0x55533A3AL, 0x20838D87L,
+				       0xFE6BA9B7L, 0xD096954BL,
+				       0x55A867BCL, 0xA1159A58L,
+				       0xCCA92963L, 0x99E1DB33L,
+				       0xA62A4A56L, 0x3F3125F9L,
+				       0x5EF47E1CL, 0x9029317CL,
+				       0xFDF8E802L, 0x04272F70L,
+				       0x80BB155CL, 0x05282CE3L,
+				       0x95C11548L, 0xE4C66D22L,
+				       0x48C1133FL, 0xC70F86DCL,
+				       0x07F9C9EEL, 0x41041F0FL,
+				       0x404779A4L, 0x5D886E17L,
+				       0x325F51EBL, 0xD59BC0D1L,
+				       0xF2BCC18FL, 0x41113564L,
+				       0x257B7834L, 0x602A9C60L,
+				       0xDFF8E8A3L, 0x1F636C1BL,
+				       0x0E12B4C2L, 0x02E1329EL,
+				       0xAF664FD1L, 0xCAD18115L,
+				       0x6B2395E0L, 0x333E92E1L,
+				       0x3B240B62L, 0xEEBEB922L,
+				       0x85B2A20EL, 0xE6BA0D99L,
+				       0xDE720C8CL, 0x2DA2F728L,
+				       0xD0127845L, 0x95B794FDL,
+				       0x647D0862L, 0xE7CCF5F0L,
+				       0x5449A36FL, 0x877D48FAL,
+				       0xC39DFD27L, 0xF33E8D1EL,
+				       0x0A476341L, 0x992EFF74L,
+				       0x3A6F6EABL, 0xF4F8FD37L,
+				       0xA812DC60L, 0xA1EBDDF8L,
+				       0x991BE14CL, 0xDB6E6B0DL,
+				       0xC67B5510L, 0x6D672C37L,
+				       0x2765D43BL, 0xDCD0E804L,
+				       0xF1290DC7L, 0xCC00FFA3L,
+				       0xB5390F92L, 0x690FED0BL,
+				       0x667B9FFBL, 0xCEDB7D9CL,
+				       0xA091CF0BL, 0xD9155EA3L,
+				       0xBB132F88L, 0x515BAD24L,
+				       0x7B9479BFL, 0x763BD6EBL,
+				       0x37392EB3L, 0xCC115979L,
+				       0x8026E297L, 0xF42E312DL,
+				       0x6842ADA7L, 0xC66A2B3BL,
+				       0x12754CCCL, 0x782EF11CL,
+				       0x6A124237L, 0xB79251E7L,
+				       0x06A1BBE6L, 0x4BFB6350L,
+				       0x1A6B1018L, 0x11CAEDFAL,
+				       0x3D25BDD8L, 0xE2E1C3C9L,
+				       0x44421659L, 0x0A121386L,
+				       0xD90CEC6EL, 0xD5ABEA2AL,
+				       0x64AF674EL, 0xDA86A85FL,
+				       0xBEBFE988L, 0x64E4C3FEL,
+				       0x9DBC8057L, 0xF0F7C086L,
+				       0x60787BF8L, 0x6003604DL,
+				       0xD1FD8346L, 0xF6381FB0L,
+				       0x7745AE04L, 0xD736FCCCL,
+				       0x83426B33L, 0xF01EAB71L,
+				       0xB0804187L, 0x3C005E5FL,
+				       0x77A057BEL, 0xBDE8AE24L,
+				       0x55464299L, 0xBF582E61L,
+				       0x4E58F48FL, 0xF2DDFDA2L,
+				       0xF474EF38L, 0x8789BDC2L,
+				       0x5366F9C3L, 0xC8B38E74L,
+				       0xB475F255L, 0x46FCD9B9L,
+				       0x7AEB2661L, 0x8B1DDF84L,
+				       0x846A0E79L, 0x915F95E2L,
+				       0x466E598EL, 0x20B45770L,
+				       0x8CD55591L, 0xC902DE4CL,
+				       0xB90BACE1L, 0xBB8205D0L,
+				       0x11A86248L, 0x7574A99EL,
+				       0xB77F19B6L, 0xE0A9DC09L,
+				       0x662D09A1L, 0xC4324633L,
+				       0xE85A1F02L, 0x09F0BE8CL,
+				       0x4A99A025L, 0x1D6EFE10L,
+				       0x1AB93D1DL, 0x0BA5A4DFL,
+				       0xA186F20FL, 0x2868F169L,
+				       0xDCB7DA83L, 0x573906FEL,
+				       0xA1E2CE9BL, 0x4FCD7F52L,
+				       0x50115E01L, 0xA70683FAL,
+				       0xA002B5C4L, 0x0DE6D027L,
+				       0x9AF88C27L, 0x773F8641L,
+				       0xC3604C06L, 0x61A806B5L,
+				       0xF0177A28L, 0xC0F586E0L,
+				       0x006058AAL, 0x30DC7D62L,
+				       0x11E69ED7L, 0x2338EA63L,
+				       0x53C2DD94L, 0xC2C21634L,
+				       0xBBCBEE56L, 0x90BCB6DEL,
+				       0xEBFC7DA1L, 0xCE591D76L,
+				       0x6F05E409L, 0x4B7C0188L,
+				       0x39720A3DL, 0x7C927C24L,
+				       0x86E3725FL, 0x724D9DB9L,
+				       0x1AC15BB4L, 0xD39EB8FCL,
+				       0xED545578L, 0x08FCA5B5L,
+				       0xD83D7CD3L, 0x4DAD0FC4L,
+				       0x1E50EF5EL, 0xB161E6F8L,
+				       0xA28514D9L, 0x6C51133CL,
+				       0x6FD5C7E7L, 0x56E14EC4L,
+				       0x362ABFCEL, 0xDDC6C837L,
+				       0xD79A3234L, 0x92638212L,
+				       0x670EFA8EL, 0x406000E0L},
+{0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL, 0x5CB0679EL,
+ 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL, 0xD5118E9DL, 0xBF0F7315L,
+ 0xD62D1C7EL, 0xC700C47BL, 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL,
+ 0x6A366EB4L, 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
+ 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L, 0x2939BBDBL,
+ 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L, 0xA1FAD5F0L, 0x6A2D519AL,
+ 0x63EF8CE2L, 0x9A86EE22L, 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL,
+ 0x9CF2D0A4L, 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
+ 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L, 0xC72FEFD3L,
+ 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L, 0x80E4A915L, 0x87B08601L,
+ 0x9B09E6ADL, 0x3B3EE593L, 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L,
+ 0x022B8B51L, 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
+ 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL, 0xE029AC71L,
+ 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL, 0xE8D3C48DL, 0x283B57CCL,
+ 0xF8D56629L, 0x79132E28L, 0x785F0191L, 0xED756055L, 0xF7960E44L,
+ 0xE3D35E8CL, 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
+ 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL, 0x1B3F6D9BL,
+ 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L, 0x7533D928L, 0xB155FDF5L,
+ 0x03563482L, 0x8ABA3CBBL, 0x28517711L, 0xC20AD9F8L, 0xABCC5167L,
+ 0xCCAD925FL, 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
+ 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L, 0xA8B6E37EL,
+ 0xC3293D46L, 0x48DE5369L, 0x6413E680L, 0xA2AE0810L, 0xDD6DB224L,
+ 0x69852DFDL, 0x09072166L, 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL,
+ 0x1C20C8AEL, 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
+ 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L, 0x72EACEA8L,
+ 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L, 0xD29BE463L, 0x542F5D9EL,
+ 0xAEC2771BL, 0xF64E6370L, 0x740E0D8DL, 0xE75B1357L, 0xF8721671L,
+ 0xAF537D5DL, 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
+ 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L, 0x6F3F3B82L,
+ 0x3520AB82L, 0x011A1D4BL, 0x277227F8L, 0x611560B1L, 0xE7933FDCL,
+ 0xBB3A792BL, 0x344525BDL, 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L,
+ 0xA01FBAC9L, 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
+ 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L, 0x0339C32AL,
+ 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL, 0xF79E59B7L, 0x43F5BB3AL,
+ 0xF2D519FFL, 0x27D9459CL, 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L,
+ 0x9B941525L, 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
+ 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L, 0xE0EC6E0EL,
+ 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L, 0x9F1F9532L, 0xE0D392DFL,
+ 0xD3A0342BL, 0x8971F21EL, 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L,
+ 0xC37632D8L, 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
+ 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL, 0x1618B166L,
+ 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L, 0xF523F357L, 0xA6327623L,
+ 0x93A83531L, 0x56CCCD02L, 0xACF08162L, 0x5A75EBB5L, 0x6E163697L,
+ 0x88D273CCL, 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
+ 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL, 0xC9AA53FDL,
+ 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L, 0x71126905L, 0xB2040222L,
+ 0xB6CBCF7CL, 0xCD769C2BL, 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L,
+ 0x2547ADF0L, 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
+ 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL, 0x1948C25CL,
+ 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L, 0x90D4F869L, 0xA65CDEA0L,
+ 0x3F09252DL, 0xC208E69FL, 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L,
+ 0x3AC372E6L}
+};
+
+static unsigned long F(BLOWFISH_CTX * ctx, unsigned long x)
+{
+    unsigned short a, b, c, d;
+    unsigned long y;
+    d = (unsigned short) (x & 0xFF);
+    x >>= 8;
+    c = (unsigned short) (x & 0xFF);
+    x >>= 8;
+    b = (unsigned short) (x & 0xFF);
+    x >>= 8;
+    a = (unsigned short) (x & 0xFF);
+    y = ctx->S[0][a] + ctx->S[1][b];
+    y = y ^ ctx->S[2][c];
+    y = y + ctx->S[3][d];
+    return y;
+}
+
+void Blowfish_Encrypt(BLOWFISH_CTX * ctx, unsigned long *xl,
+		      unsigned long *xr)
+{
+    unsigned long Xl;
+    unsigned long Xr;
+    unsigned long temp;
+    short i;
+    Xl = *xl;
+    Xr = *xr;
+    for (i = 0; i < N; ++i) {
+	Xl = Xl ^ ctx->P[i];
+	Xr = F(ctx, Xl) ^ Xr;
+	temp = Xl;
+	Xl = Xr;
+	Xr = temp;
+    }
+    temp = Xl;
+    Xl = Xr;
+    Xr = temp;
+    Xr = Xr ^ ctx->P[N];
+    Xl = Xl ^ ctx->P[N + 1];
+    *xl = Xl;
+    *xr = Xr;
+}
+
+void Blowfish_Decrypt(BLOWFISH_CTX * ctx, unsigned long *xl,
+		      unsigned long *xr)
+{
+    unsigned long Xl;
+    unsigned long Xr;
+    unsigned long temp;
+    short i;
+    Xl = *xl;
+    Xr = *xr;
+    for (i = N + 1; i > 1; --i) {
+	Xl = Xl ^ ctx->P[i];
+	Xr = F(ctx, Xl) ^ Xr;
+
+	    /* Exchange Xl and Xr */
+	    temp = Xl;
+	Xl = Xr;
+	Xr = temp;
+    }
+
+	/* Exchange Xl and Xr */
+	temp = Xl;
+    Xl = Xr;
+    Xr = temp;
+    Xr = Xr ^ ctx->P[1];
+    Xl = Xl ^ ctx->P[0];
+    *xl = Xl;
+    *xr = Xr;
+}
+
+void Blowfish_Init(BLOWFISH_CTX * ctx, unsigned char *key, int keyLen)
+{
+    int i, j, k;
+    unsigned long data, datal, datar;
+    for (i = 0; i < 4; i++) {
+	for (j = 0; j < 256; j++)
+	    ctx->S[i][j] = ORIG_S[i][j];
+    }
+    j = 0;
+    for (i = 0; i < N + 2; ++i) {
+	data = 0x00000000;
+	for (k = 0; k < 4; ++k) {
+	    data = (data << 8) | key[j];
+	    j = j + 1;
+	    if (j >= keyLen)
+		j = 0;
+	}
+	ctx->P[i] = ORIG_P[i] ^ data;
+    }
+    datal = 0x00000000;
+    datar = 0x00000000;
+    for (i = 0; i < N + 2; i += 2) {
+	Blowfish_Encrypt(ctx, &datal, &datar);
+	ctx->P[i] = datal;
+	ctx->P[i + 1] = datar;
+    }
+    for (i = 0; i < 4; ++i) {
+	for (j = 0; j < 256; j += 2) {
+	    Blowfish_Encrypt(ctx, &datal, &datar);
+	    ctx->S[i][j] = datal;
+	    ctx->S[i][j + 1] = datar;
+	}
+    }
+}
+
+static gpointer
+parallel_blowfish(unsigned int start, unsigned int end, void *data, gint thread_number)
+{
+    BLOWFISH_CTX ctx;
+    unsigned int i;
+    unsigned long L, R;
+
+    L = 0xBEBACAFE;
+    R = 0xDEADBEEF;
+
+    for (i = start; i <= end; i++) {
+        Blowfish_Init(&ctx, (unsigned char*)data, 65536);
+        Blowfish_Encrypt(&ctx, &L, &R);
+        Blowfish_Decrypt(&ctx, &L, &R);
+    }
+
+    return NULL;
+}
+
+void
+benchmark_fish(void)
+{
+    bench_value r = EMPTY_BENCH_VALUE;
+
+    gchar *tmpsrc;
+    gchar *bdata_path;
+
+    bdata_path = g_build_filename(params.path_data, "benchmark.data", NULL);
+    if (!g_file_get_contents(bdata_path, &tmpsrc, NULL, NULL)) {
+        bench_results[BENCHMARK_BLOWFISH] = r;
+        g_free(bdata_path);
+        return;
+    }
+
+    shell_view_set_enabled(FALSE);
+    shell_status_update("Performing Blowfish benchmark...");
+
+    r = benchmark_parallel_for(0, 0, 50000, parallel_blowfish, tmpsrc);
+    r.result = r.elapsed_time;
+
+    bench_results[BENCHMARK_BLOWFISH] = r;
+    g_free(bdata_path);
+    g_free(tmpsrc);
+}
diff --git a/modules/benchmark/cryptohash.c b/modules/benchmark/cryptohash.c
new file mode 100644
index 0000000..6150f3e
--- /dev/null
+++ b/modules/benchmark/cryptohash.c
@@ -0,0 +1,80 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "md5.h"
+#include "sha1.h"
+#include "benchmark.h"
+
+void inline md5_step(char *data, glong srclen)
+{
+    struct MD5Context ctx;
+    guchar checksum[16];
+
+    MD5Init(&ctx);
+    MD5Update(&ctx, (guchar *)data, srclen);
+    MD5Final(checksum, &ctx);
+}
+
+void inline sha1_step(char *data, glong srclen)
+{
+    SHA1_CTX ctx;
+    guchar checksum[20];
+
+    SHA1Init(&ctx);
+    SHA1Update(&ctx, (guchar*)data, srclen);
+    SHA1Final(checksum, &ctx);
+}
+
+static gpointer cryptohash_for(unsigned int start, unsigned int end, void *data, gint thread_number)
+{
+    unsigned int i;
+
+    for (i = start; i <= end; i++) {
+        if (i & 1) {
+            md5_step(data, 65536);
+        } else {
+            sha1_step(data, 65536);
+        }
+    }
+
+    return NULL;
+}
+
+void
+benchmark_cryptohash(void)
+{
+    bench_value r = EMPTY_BENCH_VALUE;
+    gchar *tmpsrc, *bdata_path;
+
+    bdata_path = g_build_filename(params.path_data, "benchmark.data", NULL);
+    if (!g_file_get_contents(bdata_path, &tmpsrc, NULL, NULL)) {
+        g_free(bdata_path);
+        return;
+    }
+
+    shell_view_set_enabled(FALSE);
+    shell_status_update("Running CryptoHash benchmark...");
+
+    r = benchmark_parallel_for(0, 0, 5000, cryptohash_for, tmpsrc);
+
+    g_free(bdata_path);
+    g_free(tmpsrc);
+
+    r.result = 312.0 / r.elapsed_time; //TODO: explain in code comments
+    bench_results[BENCHMARK_CRYPTOHASH] = r;
+}
diff --git a/modules/benchmark/drawing.c b/modules/benchmark/drawing.c
new file mode 100644
index 0000000..d090595
--- /dev/null
+++ b/modules/benchmark/drawing.c
@@ -0,0 +1,33 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "benchmark.h"
+#include "guibench.h"
+
+void
+benchmark_gui(void)
+{
+    bench_value r = EMPTY_BENCH_VALUE;
+
+    shell_view_set_enabled(FALSE);
+    shell_status_update("Running drawing benchmark...");
+
+    r.result = guibench(); //TODO: explain in code comments
+
+    bench_results[BENCHMARK_GUI] = r;
+}
diff --git a/modules/benchmark/fbench.c b/modules/benchmark/fbench.c
new file mode 100644
index 0000000..b5afc1b
--- /dev/null
+++ b/modules/benchmark/fbench.c
@@ -0,0 +1,745 @@
+/*
+
+        John Walker's Floating Point Benchmark, derived from...
+
+	Marinchip Interactive Lens Design System
+
+				     John Walker   December 1980
+
+	By John Walker
+	   https://www.fourmilab.ch/
+
+	This  program may be used, distributed, and modified freely as
+	long as the origin information is preserved.
+
+	This  is  a  complete  optical	design	raytracing  algorithm,
+	stripped of its user interface and recast into portable C.  It
+	not only determines execution speed on an  extremely  floating
+	point	(including   trig   function)	intensive   real-world
+	application, it  checks  accuracy  on  an  algorithm  that  is
+	exquisitely  sensitive	to  errors.   The  performance of this
+	program is typically far more  sensitive  to  changes  in  the
+	efficiency  of	the  trigonometric  library  routines than the
+	average floating point program.
+
+	The benchmark may be compiled in two  modes.   If  the	symbol
+	INTRIG	is  defined,  built-in	trigonometric  and square root
+	routines will be used for all calculations.  Timings made with
+        INTRIG  defined  reflect  the  machine's  basic floating point
+	performance for the arithmetic operators.  If  INTRIG  is  not
+	defined,  the  system  library	<math.h>  functions  are used.
+        Results with INTRIG not defined reflect the  system's  library
+	performance  and/or  floating  point hardware support for trig
+	functions and square root.  Results with INTRIG defined are  a
+	good  guide  to  general  floating  point  performance,  while
+	results with INTRIG undefined indicate the performance	of  an
+	application which is math function intensive.
+
+	Special  note  regarding  errors in accuracy: this program has
+	generated numbers identical to the last digit it  formats  and
+	checks on the following machines, floating point
+	architectures, and languages:
+
+	Marinchip 9900	  QBASIC    IBM 370 double-precision (REAL * 8) format
+
+	IBM PC / XT / AT  Lattice C IEEE 64 bit, 80 bit temporaries
+			  High C    same, in line 80x87 code
+                          BASICA    "Double precision"
+			  Quick BASIC IEEE double precision, software routines
+
+	Sun 3		  C	    IEEE 64 bit, 80 bit temporaries,
+				    in-line 68881 code, in-line FPA code.
+
+        MicroVAX II       C         Vax "G" format floating point
+
+	Macintosh Plus	  MPW C     SANE floating point, IEEE 64 bit format
+				    implemented in ROM.
+
+	Inaccuracies  reported	by  this  program should be taken VERY
+	SERIOUSLY INDEED, as the program has been demonstrated	to  be
+	invariant  under  changes in floating point format, as long as
+	the format is a recognised double precision  format.   If  you
+	encounter errors, please remember that they are just as likely
+	to  be	in  the  floating  point  editing   library   or   the
+	trigonometric  libraries  as  in  the low level operator code.
+
+	The benchmark assumes that results are basically reliable, and
+	only tests the last result computed against the reference.  If
+        you're running on  a  suspect  system  you  can  compile  this
+	program  with  ACCURACY defined.  This will generate a version
+	which executes as an infinite loop, performing the  ray  trace
+	and checking the results on every pass.  All incorrect results
+	will be reported.
+
+	Representative	timings  are  given  below.   All  have   been
+	normalised as if run for 1000 iterations.
+
+  Time in seconds		   Computer, Compiler, and notes
+ Normal      INTRIG
+
+ 3466.00    4031.00	Commodore 128, 2 Mhz 8510 with software floating
+			point.	Abacus Software/Data-Becker Super-C 128,
+			version 3.00, run in fast (2 Mhz) mode.  Note:
+			the results generated by this system differed
+			from the reference results in the 8th to 10th
+			decimal place.
+
+ 3290.00		IBM PC/AT 6 Mhz, Microsoft/IBM BASICA version A3.00.
+                        Run with the "/d" switch, software floating point.
+
+ 2131.50		IBM PC/AT 6 Mhz, Lattice C version 2.14, small model.
+			This version of Lattice compiles subroutine
+			calls which either do software floating point
+			or use the 80x87.  The machine on which I ran
+			this had an 80287, but the results were so bad
+			I wonder if it was being used.
+
+ 1598.00		Macintosh Plus, MPW C, SANE Software floating point.
+
+ 1582.13		Marinchip 9900 2 Mhz, QBASIC compiler with software
+			floating point.  This was a QBASIC version of the
+			program which contained the identical algorithm.
+
+  404.00		IBM PC/AT 6 Mhz, Microsoft QuickBASIC version 2.0.
+			Software floating point.
+
+  165.15		IBM PC/AT 6 Mhz, Metaware High C version 1.3, small
+			model.	This was compiled to call subroutines for
+			floating point, and the machine contained an 80287
+			which was used by the subroutines.
+
+  143.20		Macintosh II, MPW C, SANE calls.  I was unable to
+			determine whether SANE was using the 68881 chip or
+			not.
+
+  121.80		Sun 3/160 16 Mhz, Sun C.  Compiled with -fsoft switch
+			which executes floating point in software.
+
+   78.78     110.11	IBM RT PC (Model 6150).  IBM AIX 1.0 C compiler
+			with -O switch.
+
+   75.2      254.0	Microsoft Quick C 1.0, in-line 8087 instructions,
+			compiled with 80286 optimisation on.  (Switches
+			were -Ol -FPi87-G2 -AS).  Small memory model.
+
+   69.50		IBM PC/AT 6Mhz, Borland Turbo BASIC 1.0.  Compiled
+                        in "8087 required" mode to generate in-line
+			code for the math coprocessor.
+
+   66.96		IBM PC/AT 6Mhz, Microsoft QuickBASIC 4.0.  This
+			release of QuickBASIC compiles code for the
+			80287 math coprocessor.
+
+   66.36     206.35	IBM PC/AT 6Mhz, Metaware High C version 1.3, small
+			model.	This was compiled with in-line code for the
+			80287 math coprocessor.  Trig functions still call
+			library routines.
+
+   63.07     220.43	IBM PC/AT, 6Mhz, Borland Turbo C, in-line 8087 code,
+			small model, word alignment, no stack checking,
+			8086 code mode.
+
+   17.18		Apollo DN-3000, 12 Mhz 68020 with 68881, compiled
+			with in-line code for the 68881 coprocessor.
+			According to Apollo, the library routines are chosen
+			at runtime based on coprocessor presence.  Since the
+			coprocessor was present, the library is supposed to
+			use in-line floating point code.
+
+   15.55      27.56	VAXstation II GPX.  Compiled and executed under
+			VAX/VMS C.
+
+   15.14      37.93	Macintosh II, Unix system V.  Green Hills 68020
+			Unix compiler with in-line code for the 68881
+			coprocessor (-O -ZI switches).
+
+   12.69		Sun 3/160 16 Mhz, Sun C.  Compiled with -fswitch,
+			which calls a subroutine to select the fastest
+			floating point processor.  This was using the 68881.
+
+   11.74      26.73	Compaq Deskpro 386, 16 Mhz 80386 with 16 Mhz 80387.
+			Metaware High C version 1.3, compiled with in-line
+			for the math coprocessor (but not optimised for the
+			80386/80387).  Trig functions still call library
+			routines.
+
+    8.43      30.49	Sun 3/160 16 Mhz, Sun C.  Compiled with -f68881,
+			generating in-line MC68881 instructions.  Trig
+			functions still call library routines.
+
+    6.29      25.17	Sun 3/260 25 Mhz, Sun C.  Compiled with -f68881,
+			generating in-line MC68881 instructions.  Trig
+			functions still call library routines.
+
+    4.57		Sun 3/260 25 Mhz, Sun FORTRAN 77.  Compiled with
+			-O -f68881, generating in-line MC68881 instructions.
+			Trig functions are compiled in-line.  This used
+			the FORTRAN 77 version of the program, FBFORT77.F.
+
+    4.00      14.20	Sun386i/25 Mhz model 250, Sun C compiler.
+
+    4.00      14.00	Sun386i/25 Mhz model 250, Metaware C.
+
+    3.10      12.00	Compaq 386/387 25 Mhz running SCO Xenix 2.
+			Compiled with Metaware HighC 386, optimized
+			for 386.
+
+    3.00      12.00	Compaq 386/387 25MHZ optimized for 386/387.
+
+    2.96       5.17	Sun 4/260, Sparc RISC processor.  Sun C,
+			compiled with the -O2 switch for global
+			optimisation.
+
+    2.47		COMPAQ 486/25, secondary cache disabled, High C,
+			486/387, inline f.p., small memory model.
+
+    2.20       3.40	Data General Motorola 88000, 16 Mhz, Gnu C.
+
+    1.56		COMPAQ 486/25, 128K secondary cache, High C, 486/387,
+			inline f.p., small memory model.
+
+    0.66       1.50	DEC Pmax, Mips processor.
+
+    0.63       0.91	Sun SparcStation 2, Sun C (SunOS 4.1.1) with
+                        -O4 optimisation and "/usr/lib/libm.il" inline
+			floating point.
+
+    0.60       1.07	Intel 860 RISC processor, 33 Mhz, Greenhills
+			C compiler.
+
+    0.40       0.90	Dec 3MAX, MIPS 3000 processor, -O4.
+
+    0.31       0.90	IBM RS/6000, -O.
+
+    0.1129     0.2119	Dell Dimension XPS P133c, Pentium 133 MHz,
+			Windows 95, Microsoft Visual C 5.0.
+
+    0.0883     0.2166	Silicon Graphics Indigo², MIPS R4400,
+                        175 Mhz, "-O3".
+
+    0.0351     0.0561	Dell Dimension XPS R100, Pentium II 400 MHz,
+			Windows 98, Microsoft Visual C 5.0.
+
+    0.0312     0.0542	Sun Ultra 2, UltraSPARC V9, 300 MHz, Solaris
+			2.5.1.
+			
+    0.00862    0.01074  Dell Inspiron 9100, Pentium 4, 3.4 GHz, gcc -O3.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef INTRIG
+#include <math.h>
+#endif
+
+#define cot(x) (1.0 / tan(x))
+
+#define TRUE  1
+#define FALSE 0
+
+#define max_surfaces 10
+
+/*  Local variables  */
+
+/*static char tbfr[132];*/
+
+static short current_surfaces;
+static short paraxial;
+
+static double clear_aperture;
+
+static double aberr_lspher;
+static double aberr_osc;
+static double aberr_lchrom;
+
+static double max_lspher;
+static double max_osc;
+static double max_lchrom;
+
+static double radius_of_curvature;
+static double object_distance;
+static double ray_height;
+static double axis_slope_angle;
+static double from_index;
+static double to_index;
+
+static double spectral_line[9];
+static double s[max_surfaces][5];
+static double od_sa[2][2];
+
+				/*static char outarr[8][80];*//* Computed output of program goes here */
+
+static int itercount;			/* The iteration counter for the main loop
+				   in the program is made global so that
+				   the compiler should not be allowed to
+				   optimise out the loop over the ray
+				   tracing code. */
+
+#ifndef ITERATIONS
+#define ITERATIONS 1000
+#endif
+static int niter = ITERATIONS;		/* Iteration counter */
+
+#if 0
+static char *refarr[] = {	/* Reference results.  These happen to
+				   be derived from a run on Microsoft 
+				   Quick BASIC on the IBM PC/AT. */
+
+    "   Marginal ray          47.09479120920   0.04178472683",
+    "   Paraxial ray          47.08372160249   0.04177864821",
+    "Longitudinal spherical aberration:        -0.01106960671",
+    "    (Maximum permissible):                 0.05306749907",
+    "Offense against sine condition (coma):     0.00008954761",
+    "    (Maximum permissible):                 0.00250000000",
+    "Axial chromatic aberration:                0.00448229032",
+    "    (Maximum permissible):                 0.05306749907"
+};
+#endif
+
+/* The	test  case  used  in  this program is the  design for a 4 inch
+   achromatic telescope  objective  used  as  the  example  in  Wyld's
+   classic  work  on  ray  tracing by hand, given in Amateur Telescope
+   Making, Volume 3.  */
+
+static double testcase[4][4] = {
+    {27.05, 1.5137, 63.6, 0.52},
+    {-16.68, 1, 0, 0.138},
+    {-16.68, 1.6164, 36.7, 0.38},
+    {-78.1, 1, 0, 0}
+};
+
+/*  Internal trig functions (used only if INTRIG is  defined).	 These
+    standard  functions  may be enabled to obtain timings that reflect
+    the machine's floating point performance rather than the speed  of
+    its trig function evaluation.  */
+
+#ifdef INTRIG
+
+/*  The following definitions should keep you from getting intro trouble
+    with compilers which don't let you redefine intrinsic functions.  */
+
+#define sin I_sin
+#define cos I_cos
+#define tan I_tan
+#define sqrt I_sqrt
+#define atan I_atan
+#define atan2 I_atan2
+#define asin I_asin
+
+#define fabs(x)  ((x < 0.0) ? -x : x)
+
+#define pic 3.1415926535897932
+
+/*  Commonly used constants  */
+
+static double pi = pic,
+    twopi = pic * 2.0,
+    piover4 = pic / 4.0, fouroverpi = 4.0 / pic, piover2 = pic / 2.0;
+
+/*  Coefficients for ATAN evaluation  */
+
+static double atanc[] = {
+    0.0,
+    0.4636476090008061165,
+    0.7853981633974483094,
+    0.98279372324732906714,
+    1.1071487177940905022,
+    1.1902899496825317322,
+    1.2490457723982544262,
+    1.2924966677897852673,
+    1.3258176636680324644
+};
+
+/*  aint(x)	  Return integer part of number.  Truncates towards 0	 */
+
+double aint(x)
+double x;
+{
+    long l;
+
+    /*  Note that this routine cannot handle the full floating point
+       number range.  This function should be in the machine-dependent
+       floating point library!  */
+
+    l = x;
+    if ((int) (-0.5) != 0 && l < 0)
+	l++;
+    x = l;
+    return x;
+}
+
+/*  sin(x)	  Return sine, x in radians  */
+
+static double sin(x)
+double x;
+{
+    int sign;
+    double y, r, z;
+
+    x = (((sign = (x < 0.0)) != 0) ? -x : x);
+
+    if (x > twopi)
+	x -= (aint(x / twopi) * twopi);
+
+    if (x > pi) {
+	x -= pi;
+	sign = !sign;
+    }
+
+    if (x > piover2)
+	x = pi - x;
+
+    if (x < piover4) {
+	y = x * fouroverpi;
+	z = y * y;
+	r = y *
+	    (((((((-0.202253129293E-13 * z + 0.69481520350522E-11) * z -
+		  0.17572474176170806E-8) * z +
+		 0.313361688917325348E-6) * z -
+		0.365762041821464001E-4) * z +
+	       0.249039457019271628E-2) * z - 0.0807455121882807815) * z +
+	     0.785398163397448310);
+    } else {
+	y = (piover2 - x) * fouroverpi;
+	z = y * y;
+	r = ((((((-0.38577620372E-12 * z + 0.11500497024263E-9) * z -
+		 0.2461136382637005E-7) * z +
+		0.359086044588581953E-5) * z -
+	       0.325991886926687550E-3) * z + 0.0158543442438154109) * z -
+	     0.308425137534042452) * z + 1.0;
+    }
+    return sign ? -r : r;
+}
+
+/*  cos(x)	  Return cosine, x in radians, by identity  */
+
+static double cos(x)
+double x;
+{
+    x = (x < 0.0) ? -x : x;
+    if (x > twopi)		/* Do range reduction here to limit */
+	x = x - (aint(x / twopi) * twopi);	/* roundoff on add of PI/2    */
+    return sin(x + piover2);
+}
+
+/*  tan(x)	  Return tangent, x in radians, by identity  */
+
+static double tan(x)
+double x;
+{
+    return sin(x) / cos(x);
+}
+
+/*  sqrt(x)	  Return square root.  Initial guess, then Newton-
+		  Raphson refinement  */
+
+double sqrt(x)
+double x;
+{
+    double c, cl, y;
+    int n;
+
+    if (x == 0.0)
+	return 0.0;
+
+    if (x < 0.0) {
+	fprintf(stderr,
+		"\nGood work!  You tried to take the square root of %g",
+		x);
+	fprintf(stderr,
+		"\nunfortunately, that is too complex for me to handle.\n");
+	exit(1);
+    }
+
+    y = (0.154116 + 1.893872 * x) / (1.0 + 1.047988 * x);
+
+    c = (y - x / y) / 2.0;
+    cl = 0.0;
+    for (n = 50; c != cl && n--;) {
+	y = y - c;
+	cl = c;
+	c = (y - x / y) / 2.0;
+    }
+    return y;
+}
+
+/*  atan(x)	  Return arctangent in radians,
+		  range -pi/2 to pi/2  */
+
+static double atan(x)
+double x;
+{
+    int sign, l, y;
+    double a, b, z;
+
+    x = (((sign = (x < 0.0)) != 0) ? -x : x);
+    l = 0;
+
+    if (x >= 4.0) {
+	l = -1;
+	x = 1.0 / x;
+	y = 0;
+	goto atl;
+    } else {
+	if (x < 0.25) {
+	    y = 0;
+	    goto atl;
+	}
+    }
+
+    y = aint(x / 0.5);
+    z = y * 0.5;
+    x = (x - z) / (x * z + 1);
+
+  atl:
+    z = x * x;
+    b = ((((893025.0 * z + 49116375.0) * z + 425675250.0) * z +
+	  1277025750.0) * z + 1550674125.0) * z + 654729075.0;
+    a = (((13852575.0 * z + 216602100.0) * z + 891080190.0) * z +
+	 1332431100.0) * z + 654729075.0;
+    a = (a / b) * x + atanc[y];
+    if (l)
+	a = piover2 - a;
+    return sign ? -a : a;
+}
+
+/*  atan2(y,x)	  Return arctangent in radians of y/x,
+		  range -pi to pi  */
+
+static double atan2(y, x)
+double y, x;
+{
+    double temp;
+
+    if (x == 0.0) {
+	if (y == 0.0)		/*  Special case: atan2(0,0) = 0  */
+	    return 0.0;
+	else if (y > 0)
+	    return piover2;
+	else
+	    return -piover2;
+    }
+    temp = atan(y / x);
+    if (x < 0.0) {
+	if (y >= 0.0)
+	    temp += pic;
+	else
+	    temp -= pic;
+    }
+    return temp;
+}
+
+/*  asin(x)	  Return arcsine in radians of x  */
+
+static double asin(x)
+double x;
+{
+    if (fabs(x) > 1.0) {
+	fprintf(stderr,
+		"\nInverse trig functions lose much of their gloss when");
+	fprintf(stderr,
+		"\ntheir arguments are greater than 1, such as the");
+	fprintf(stderr, "\nvalue %g you passed.\n", x);
+	exit(1);
+    }
+    return atan2(x, sqrt(1 - x * x));
+}
+#endif
+
+/*	      Calculate passage through surface
+
+	      If  the variable PARAXIAL is true, the trace through the
+	      surface will be done using the paraxial  approximations.
+	      Otherwise,  the normal trigonometric trace will be done.
+
+	      This routine takes the following inputs:
+
+	      RADIUS_OF_CURVATURE	  Radius of curvature of surface
+					  being crossed.  If 0, surface is
+					  plane.
+
+	      OBJECT_DISTANCE		  Distance of object focus from
+					  lens vertex.	If 0, incoming
+					  rays are parallel and
+					  the following must be specified:
+
+	      RAY_HEIGHT		  Height of ray from axis.  Only
+					  relevant if OBJECT.DISTANCE == 0
+
+	      AXIS_SLOPE_ANGLE		  Angle incoming ray makes with axis
+					  at intercept
+
+	      FROM_INDEX		  Refractive index of medium being left
+
+	      TO_INDEX			  Refractive index of medium being
+					  entered.
+
+	      The outputs are the following variables:
+
+	      OBJECT_DISTANCE		  Distance from vertex to object focus
+					  after refraction.
+
+	      AXIS_SLOPE_ANGLE		  Angle incoming ray makes with axis
+					  at intercept after refraction.
+
+*/
+
+static void transit_surface()
+{
+    double iang,		/* Incidence angle */
+     rang,			/* Refraction angle */
+     iang_sin,			/* Incidence angle sin */
+     rang_sin,			/* Refraction angle sin */
+     old_axis_slope_angle, sagitta;
+
+    if (paraxial) {
+	if (radius_of_curvature != 0.0) {
+	    if (object_distance == 0.0) {
+		axis_slope_angle = 0.0;
+		iang_sin = ray_height / radius_of_curvature;
+	    } else
+		iang_sin = ((object_distance -
+			     radius_of_curvature) / radius_of_curvature) *
+		    axis_slope_angle;
+
+	    rang_sin = (from_index / to_index) * iang_sin;
+	    old_axis_slope_angle = axis_slope_angle;
+	    axis_slope_angle = axis_slope_angle + iang_sin - rang_sin;
+	    if (object_distance != 0.0)
+		ray_height = object_distance * old_axis_slope_angle;
+	    object_distance = ray_height / axis_slope_angle;
+	    return;
+	}
+	object_distance = object_distance * (to_index / from_index);
+	axis_slope_angle = axis_slope_angle * (from_index / to_index);
+	return;
+    }
+
+    if (radius_of_curvature != 0.0) {
+	if (object_distance == 0.0) {
+	    axis_slope_angle = 0.0;
+	    iang_sin = ray_height / radius_of_curvature;
+	} else {
+	    iang_sin = ((object_distance -
+			 radius_of_curvature) / radius_of_curvature) *
+		sin(axis_slope_angle);
+	}
+	iang = asin(iang_sin);
+	rang_sin = (from_index / to_index) * iang_sin;
+	old_axis_slope_angle = axis_slope_angle;
+	axis_slope_angle = axis_slope_angle + iang - asin(rang_sin);
+	sagitta = sin((old_axis_slope_angle + iang) / 2.0);
+	sagitta = 2.0 * radius_of_curvature * sagitta * sagitta;
+	object_distance =
+	    ((radius_of_curvature * sin(old_axis_slope_angle + iang)) *
+	     cot(axis_slope_angle)) + sagitta;
+	return;
+    }
+
+    rang = -asin((from_index / to_index) * sin(axis_slope_angle));
+    object_distance = object_distance * ((to_index *
+					  cos(-rang)) / (from_index *
+							 cos
+							 (axis_slope_angle)));
+    axis_slope_angle = -rang;
+}
+
+/*  Perform ray trace in specific spectral line  */
+
+static void trace_line(line, ray_h)
+int line;
+double ray_h;
+{
+    int i;
+
+    object_distance = 0.0;
+    ray_height = ray_h;
+    from_index = 1.0;
+
+    for (i = 1; i <= current_surfaces; i++) {
+	radius_of_curvature = s[i][1];
+	to_index = s[i][2];
+	if (to_index > 1.0)
+	    to_index = to_index + ((spectral_line[4] -
+				    spectral_line[line]) /
+				   (spectral_line[3] -
+				    spectral_line[6])) * ((s[i][2] -
+							   1.0) / s[i][3]);
+	transit_surface();
+	from_index = to_index;
+	if (i < current_surfaces)
+	    object_distance = object_distance - s[i][4];
+    }
+}
+
+/*  Initialise when called the first time  */
+
+void fbench()
+{
+    int i, j;
+    double od_fline, od_cline;
+
+    spectral_line[1] = 7621.0;	/* A */
+    spectral_line[2] = 6869.955;	/* B */
+    spectral_line[3] = 6562.816;	/* C */
+    spectral_line[4] = 5895.944;	/* D */
+    spectral_line[5] = 5269.557;	/* E */
+    spectral_line[6] = 4861.344;	/* F */
+    spectral_line[7] = 4340.477;	/* G' */
+    spectral_line[8] = 3968.494;	/* H */
+
+    niter = 3000;
+
+    /* Load test case into working array */
+
+    clear_aperture = 4.0;
+    current_surfaces = 4;
+    for (i = 0; i < current_surfaces; i++)
+	for (j = 0; j < 4; j++)
+	    s[i + 1][j + 1] = testcase[i][j];
+
+    for (itercount = 0; itercount < niter; itercount++) {
+	for (paraxial = 0; paraxial <= 1; paraxial++) {
+
+	    /* Do main trace in D light */
+
+	    trace_line(4, clear_aperture / 2.0);
+	    od_sa[paraxial][0] = object_distance;
+	    od_sa[paraxial][1] = axis_slope_angle;
+	}
+	paraxial = FALSE;
+
+	/* Trace marginal ray in C */
+
+	trace_line(3, clear_aperture / 2.0);
+	od_cline = object_distance;
+
+	/* Trace marginal ray in F */
+
+	trace_line(6, clear_aperture / 2.0);
+	od_fline = object_distance;
+
+	aberr_lspher = od_sa[1][0] - od_sa[0][0];
+	aberr_osc = 1.0 - (od_sa[1][0] * od_sa[1][1]) /
+	    (sin(od_sa[0][1]) * od_sa[0][0]);
+	aberr_lchrom = od_fline - od_cline;
+	max_lspher = sin(od_sa[0][1]);
+
+	/* D light */
+
+	max_lspher = 0.0000926 / (max_lspher * max_lspher);
+	max_osc = 0.0025;
+	max_lchrom = max_lspher;
+    }
+}
+
+#ifdef __FBENCH_TEST__
+int main(void)
+{
+    fbench();
+
+    return 0;
+}
+#endif
diff --git a/modules/benchmark/fft.c b/modules/benchmark/fft.c
new file mode 100644
index 0000000..caa52d3
--- /dev/null
+++ b/modules/benchmark/fft.c
@@ -0,0 +1,67 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "benchmark.h"
+#include "fftbench.h"
+
+static gpointer fft_for(unsigned int start, unsigned int end, void *data, gint thread_number)
+{
+    unsigned int i;
+    FFTBench **benches = (FFTBench **)data;
+    FFTBench *fftbench = (FFTBench *)(benches[thread_number]);
+
+    for (i = start; i <= end; i++) {
+        fft_bench_run(fftbench);
+    }
+
+    return NULL;
+}
+
+#define FFT_MAXT 4
+
+void
+benchmark_fft(void)
+{
+    bench_value r = EMPTY_BENCH_VALUE;
+
+    int n_cores, i;
+    gchar *temp;
+    FFTBench **benches;
+
+    shell_view_set_enabled(FALSE);
+    shell_status_update("Running FFT benchmark...");
+
+    /* Pre-allocate all benchmarks */
+    benches = g_new0(FFTBench *, FFT_MAXT);
+    for (i = 0; i < FFT_MAXT; i++) {
+      benches[i] = fft_bench_new();
+    }
+
+    /* Run the benchmark */
+    r = benchmark_parallel_for(FFT_MAXT, 0, FFT_MAXT, fft_for, benches);
+
+    /* Free up the memory */
+    for (i = 0; i < FFT_MAXT; i++) {
+      fft_bench_free(benches[i]);
+    }
+    g_free(benches);
+
+    r.result = r.elapsed_time;
+    bench_results[BENCHMARK_FFT] = r;
+}
diff --git a/modules/benchmark/fftbench.c b/modules/benchmark/fftbench.c
new file mode 100644
index 0000000..89fd5a7
--- /dev/null
+++ b/modules/benchmark/fftbench.c
@@ -0,0 +1,212 @@
+/*
+    fftbench.c
+
+    Written by Scott Robert Ladd (scott@coyotegulch.com)
+    No rights reserved. This is public domain software, for use by anyone.
+
+    A number-crunching benchmark using LUP-decomposition to solve a large
+    linear equation.
+
+    The code herein is design for the purpose of testing computational
+    performance; error handling is minimal.
+    
+    In fact, this is a weak implementation of the FFT; unfortunately, all
+    of my really nifty FFTs are in commercial code, and I haven't had time
+    to write a new FFT routine for this benchmark. I may add a Hartley
+    transform to the seat, too.
+
+    Actual benchmark results can be found at:
+            http://scottrobertladd.net/coyotegulch/
+
+    Please do not use this information or algorithm in any way that might
+    upset the balance of the universe or otherwise cause a disturbance in
+    the space-time continuum.
+*/
+
+#include <time.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "fftbench.h"
+
+// embedded random number generator; ala Park and Miller
+static long seed = 1325;
+static const long IA = 16807;
+static const long IM = 2147483647;
+static const double AM = 4.65661287525E-10;
+static const long IQ = 127773;
+static const long IR = 2836;
+static const long MASK = 123459876;
+
+static double random_double()
+{
+    long k;
+    double result;
+
+    seed ^= MASK;
+    k = seed / IQ;
+    seed = IA * (seed - k * IQ) - IR * k;
+
+    if (seed < 0)
+	seed += IM;
+
+    result = AM * seed;
+    seed ^= MASK;
+
+    return result;
+}
+
+static const int N = 800;
+static const int NM1 = 799;	// N - 1
+static const int NP1 = 801;	// N + 1
+
+static void lup_decompose(FFTBench *fftbench)
+{
+    int i, j, k, k2, t;
+    double p, temp, **a;
+
+    int *perm = (int *) malloc(sizeof(double) * N);
+    
+    fftbench->p = perm;
+    a = fftbench->a;
+    
+    for (i = 0; i < N; ++i)
+	perm[i] = i;
+
+    for (k = 0; k < NM1; ++k) {
+	p = 0.0;
+
+	for (i = k; i < N; ++i) {
+	    temp = fabs(a[i][k]);
+
+	    if (temp > p) {
+		p = temp;
+		k2 = i;
+	    }
+	}
+
+	// check for invalid a
+	if (p == 0.0)
+	    return;
+
+	// exchange rows
+	t = perm[k];
+	perm[k] = perm[k2];
+	perm[k2] = t;
+
+	for (i = 0; i < N; ++i) {
+	    temp = a[k][i];
+	    a[k][i] = a[k2][i];
+	    a[k2][i] = temp;
+	}
+
+	for (i = k + 1; i < N; ++i) {
+	    a[i][k] /= a[k][k];
+
+	    for (j = k + 1; j < N; ++j)
+		a[i][j] -= a[i][k] * a[k][j];
+	}
+    }
+}
+
+static double *lup_solve(FFTBench *fftbench)
+{
+    int i, j, j2;
+    double sum, u;
+
+    double *y = (double *) malloc(sizeof(double) * N);
+    double *x = (double *) malloc(sizeof(double) * N);
+    
+    double **a = fftbench->a;
+    double *b = fftbench->b;
+    int *perm = fftbench->p;
+
+    for (i = 0; i < N; ++i) {
+	y[i] = 0.0;
+	x[i] = 0.0;
+    }
+
+    for (i = 0; i < N; ++i) {
+	sum = 0.0;
+	j2 = 0;
+
+	for (j = 1; j <= i; ++j) {
+	    sum += a[i][j2] * y[j2];
+	    ++j2;
+	}
+
+	y[i] = b[perm[i]] - sum;
+    }
+
+    i = NM1;
+
+    while (1) {
+	sum = 0.0;
+	u = a[i][i];
+
+	for (j = i + 1; j < N; ++j)
+	    sum += a[i][j] * x[j];
+
+	x[i] = (y[i] - sum) / u;
+
+	if (i == 0)
+	    break;
+
+	--i;
+    }
+
+    free(y);
+
+    return x;
+}
+
+FFTBench *fft_bench_new(void)
+{
+    FFTBench *fftbench;
+    int i, j;
+    
+    fftbench = g_new0(FFTBench, 1);
+
+    // generate test data            
+    fftbench->a = (double **) malloc(sizeof(double *) * N);
+
+    for (i = 0; i < N; ++i) {
+	fftbench->a[i] = (double *) malloc(sizeof(double) * N);
+
+	for (j = 0; j < N; ++j)
+	    fftbench->a[i][j] = random_double();
+    }
+
+    fftbench->b = (double *) malloc(sizeof(double) * N);
+
+    for (i = 0; i < N; ++i)
+	fftbench->b[i] = random_double();
+
+    return fftbench;
+}
+
+void fft_bench_run(FFTBench *fftbench)
+{
+    lup_decompose(fftbench);
+    double *x = lup_solve(fftbench);
+    free(x);
+}
+
+void fft_bench_free(FFTBench *fftbench)
+{
+    int i;
+    
+    // clean up
+    for (i = 0; i < N; ++i)
+	free(fftbench->a[i]);
+
+    free(fftbench->a);
+    free(fftbench->b);
+    free(fftbench->p);
+    free(fftbench->r);
+    
+    g_free(fftbench);
+}
diff --git a/modules/benchmark/fib.c b/modules/benchmark/fib.c
new file mode 100644
index 0000000..d75ac36
--- /dev/null
+++ b/modules/benchmark/fib.c
@@ -0,0 +1,52 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "benchmark.h"
+
+gulong fib(gulong n)
+{
+    if (n == 0)
+        return 0;
+    else if (n <= 2)
+        return 1;
+    return fib(n - 1) + fib(n - 2);
+}
+
+void
+benchmark_fib(void)
+{
+    GTimer *timer = g_timer_new();
+    bench_value r = EMPTY_BENCH_VALUE;
+
+    shell_view_set_enabled(FALSE);
+    shell_status_update("Calculating the 42nd Fibonacci number...");
+
+    g_timer_reset(timer);
+    g_timer_start(timer);
+
+    fib(42);
+
+    g_timer_stop(timer);
+    r.elapsed_time = g_timer_elapsed(timer, NULL);
+    g_timer_destroy(timer);
+
+    r.threads_used = 1;
+    r.result = r.elapsed_time;
+
+    bench_results[BENCHMARK_FIB] = r;
+}
diff --git a/modules/benchmark/guibench.c b/modules/benchmark/guibench.c
new file mode 100644
index 0000000..b957327
--- /dev/null
+++ b/modules/benchmark/guibench.c
@@ -0,0 +1,353 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <gtk/gtk.h>
+
+#include "iconcache.h"
+#include "config.h"
+
+#define N_ITERATIONS 100000
+#define PHRASE "I \342\231\245 HardInfo"
+
+typedef double (*BenchCallback)(GtkWindow *window);
+
+static double test_lines(GtkWindow *window);
+static double test_shapes(GtkWindow *window);
+static double test_filled_shapes(GtkWindow *window);
+static double test_text(GtkWindow *window);
+static double test_icons(GtkWindow *window);
+
+/*
+Results on a AMD Athlon 3200+ (Barton), 1GB RAM,
+nVidia Geforce 6200 with nvidia Xorg driver,
+running Linux 2.6.28, Xorg 1.6.0, Ubuntu 9.04
+desktop, GNOME 2.26.1, composite enabled.
+
+Test                  Time       Iter/Sec       
+Line Drawing          3.9570     25271.7663 
+Shape Drawing         22.2499    4494.4065  
+Filled Shape Drawing  4.0377     24766.2806 
+Text Drawing          59.1565    1690.4309  
+Icon Blitting	      51.720941	 1933.4528
+
+Results are normalized according to these values.
+A guibench() result of 1000.0 is roughly equivalent
+to this same setup. 
+*/
+
+static struct {
+  BenchCallback callback;
+  gchar *title;
+  gdouble weight;
+} tests[] = {
+  { test_lines, "Line Drawing", 25271.77 },
+  { test_shapes, "Shape Drawing", 4494.49 },
+  { test_filled_shapes, "Filled Shape Drawing", 24766.28 },
+  { test_text, "Text Drawing", 1690.43  },
+  { test_icons, "Icon Blitting", 1933.45 },
+  { NULL, NULL }
+};
+
+static gchar *phrase = NULL;
+
+static gboolean keypress_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
+{
+  const int magic[] = { 0x1b, 0x33, 0x3a, 0x35, 0x51 };
+  const int states[] = { 0xff52, 0xff52, 0xff54, 0xff54,
+                         0xff51, 0xff53, 0xff51, 0xff53,
+                         0x62, 0x61 };
+  static int state = 0;
+  
+  if (event->keyval == states[state]) {
+    state++;
+  } else {
+    state = 0;
+  }
+  
+  if (state == G_N_ELEMENTS(states)) {
+    int i;
+    
+    for (i = 0; i < G_N_ELEMENTS(magic); i++) {
+      phrase[i + 6] = magic[i] ^ (states[i] & (states[i] >> 8));
+    }
+    
+    state = 0;
+  }
+  
+  return FALSE;
+}
+
+static double test_icons(GtkWindow *window)
+{
+  GdkPixbuf *pixbufs[3];
+  GdkGC *gc;
+  GRand *rand;
+  GTimer *timer;
+  double time;
+  GdkWindow *gdk_window = GTK_WIDGET(window)->window;
+  int icons;
+  
+  gdk_window_clear(gdk_window);
+  
+  rand = g_rand_new();
+  gc = gdk_gc_new(GDK_DRAWABLE(gdk_window));
+  timer = g_timer_new();
+  
+  pixbufs[0] = icon_cache_get_pixbuf("logo.png");
+  pixbufs[1] = icon_cache_get_pixbuf("syncmanager.png");
+  pixbufs[2] = icon_cache_get_pixbuf("report-large.png");
+  
+  g_timer_start(timer);
+  for (icons = N_ITERATIONS; icons >= 0; icons--) {
+    int x, y;
+
+    x = g_rand_int_range(rand, 0, 800);
+    y = g_rand_int_range(rand, 0, 600);
+    
+    gdk_draw_pixbuf(GDK_DRAWABLE(gdk_window), gc,
+                    pixbufs[icons % G_N_ELEMENTS(pixbufs)],
+                    0, 0, x, y, 48, 48,
+                    GDK_RGB_DITHER_NONE, 0, 0);
+    
+    while (gtk_events_pending()) {
+      gtk_main_iteration();
+    }
+  }
+  g_timer_stop(timer);
+  
+  time = g_timer_elapsed(timer, NULL);
+  
+  g_rand_free(rand);
+  gdk_gc_destroy(gc);
+  g_timer_destroy(timer);
+  
+  return time;
+}
+
+static double test_text(GtkWindow *window)
+{
+  GRand *rand;
+  GTimer *timer;
+  GdkGC *gc;
+  double time;
+  PangoLayout *layout;
+  PangoFontDescription *font;
+  GdkWindow *gdk_window = GTK_WIDGET(window)->window;
+  int strings;
+  
+  gdk_window_clear(gdk_window);
+  
+  rand = g_rand_new();
+  gc = gdk_gc_new(GDK_DRAWABLE(gdk_window));
+  timer = g_timer_new();
+  
+  font = pango_font_description_new();
+  layout = pango_layout_new(gtk_widget_get_pango_context(GTK_WIDGET(window)));
+  pango_layout_set_text(layout, phrase, -1);
+  
+  g_timer_start(timer);
+  for (strings = N_ITERATIONS; strings >= 0; strings--) {
+    int x, y, size;
+
+    x = g_rand_int_range(rand, 0, 800);
+    y = g_rand_int_range(rand, 0, 600);
+    size = g_rand_int_range(rand, 1, 96) * PANGO_SCALE;
+    
+    pango_font_description_set_size(font, size);
+    pango_layout_set_font_description(layout, font);
+    gdk_draw_layout(GDK_DRAWABLE(gdk_window), gc, x, y, layout);
+    
+    gdk_rgb_gc_set_foreground(gc, strings << 8);
+
+    while (gtk_events_pending()) {
+      gtk_main_iteration();
+    }
+    
+  }
+  g_timer_stop(timer);
+  
+  time = g_timer_elapsed(timer, NULL);
+  
+  g_rand_free(rand);
+  gdk_gc_destroy(gc);
+  g_timer_destroy(timer);
+  g_object_unref(layout);
+  pango_font_description_free(font);
+  
+  return time;
+}
+
+static double test_filled_shapes(GtkWindow *window)
+{
+  GRand *rand;
+  GTimer *timer;
+  GdkGC *gc;
+  double time;
+  GdkWindow *gdk_window = GTK_WIDGET(window)->window;
+  int lines;
+  
+  gdk_window_clear(gdk_window);
+  
+  rand = g_rand_new();
+  gc = gdk_gc_new(GDK_DRAWABLE(gdk_window));
+  timer = g_timer_new();
+  
+  g_timer_start(timer);
+  for (lines = N_ITERATIONS; lines >= 0; lines--) {
+    int x1, y1;
+    
+    x1 = g_rand_int_range(rand, 0, 800);
+    y1 = g_rand_int_range(rand, 0, 600);
+    
+    gdk_rgb_gc_set_foreground(gc, lines << 8);
+
+    gdk_draw_rectangle(GDK_DRAWABLE(gdk_window), gc, TRUE,
+                       x1, y1,
+                       g_rand_int_range(rand, 0, 400),
+                       g_rand_int_range(rand, 0, 300));
+
+    while (gtk_events_pending()) {
+      gtk_main_iteration();
+    }
+  }
+  g_timer_stop(timer);
+  
+  time = g_timer_elapsed(timer, NULL);
+  
+  g_rand_free(rand);
+  gdk_gc_destroy(gc);
+  g_timer_destroy(timer);
+  
+  return time;
+}
+
+static double test_shapes(GtkWindow *window)
+{
+  GRand *rand;
+  GTimer *timer;
+  GdkGC *gc;
+  double time;
+  GdkWindow *gdk_window = GTK_WIDGET(window)->window;
+  int lines;
+  
+  gdk_window_clear(gdk_window);
+  
+  rand = g_rand_new();
+  gc = gdk_gc_new(GDK_DRAWABLE(gdk_window));
+  timer = g_timer_new();
+  
+  g_timer_start(timer);
+  for (lines = N_ITERATIONS; lines >= 0; lines--) {
+    int x1, y1;
+    
+    x1 = g_rand_int_range(rand, 0, 800);
+    y1 = g_rand_int_range(rand, 0, 600);
+    
+    gdk_rgb_gc_set_foreground(gc, lines << 8);
+
+    gdk_draw_rectangle(GDK_DRAWABLE(gdk_window), gc, FALSE,
+                       x1, y1,
+                       g_rand_int_range(rand, 0, 400),
+                       g_rand_int_range(rand, 0, 300));
+    while (gtk_events_pending()) {
+      gtk_main_iteration();
+    }
+  }
+  g_timer_stop(timer);
+  
+  time = g_timer_elapsed(timer, NULL);
+  
+  g_rand_free(rand);
+  gdk_gc_destroy(gc);
+  g_timer_destroy(timer);
+  
+  return time;
+}
+
+static double test_lines(GtkWindow *window)
+{
+  GRand *rand;
+  GTimer *timer;
+  GdkGC *gc;
+  double time;
+  GdkWindow *gdk_window = GTK_WIDGET(window)->window;
+  int lines;
+  
+  gdk_window_clear(gdk_window);
+  
+  rand = g_rand_new();
+  gc = gdk_gc_new(GDK_DRAWABLE(gdk_window));
+  timer = g_timer_new();
+  
+  g_timer_start(timer);
+  for (lines = N_ITERATIONS; lines >= 0; lines--) {
+    int x1, y1, x2, y2;
+    
+    x1 = g_rand_int_range(rand, 0, 800);
+    y1 = g_rand_int_range(rand, 0, 600);
+    x2 = g_rand_int_range(rand, 0, 800);
+    y2 = g_rand_int_range(rand, 0, 600);
+    
+    gdk_draw_line(GDK_DRAWABLE(gdk_window), gc, x1, y1, x2, y2);
+    gdk_rgb_gc_set_foreground(gc, lines << 8);
+    
+    while (gtk_events_pending()) {
+      gtk_main_iteration();
+    }
+  }
+  g_timer_stop(timer);
+  
+  time = g_timer_elapsed(timer, NULL);
+  
+  g_rand_free(rand);
+  gdk_gc_destroy(gc);
+  g_timer_destroy(timer);
+  
+  return time;
+}
+
+double guibench(void)
+{
+  GtkWidget *window;
+  gdouble score = 0.0f;
+  gint i;
+
+  phrase = g_strdup(PHRASE);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  gtk_widget_set_size_request(window, 800, 600);
+  gtk_window_set_title(GTK_WINDOW(window), "guibench");
+  
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
+  gtk_widget_show(window);
+  
+  g_signal_connect(window, "key-press-event", G_CALLBACK(keypress_event), NULL);
+
+  for (i = 0; tests[i].title; i++) {
+    double time;
+    
+    gtk_window_set_title(GTK_WINDOW(window), tests[i].title); 
+    time = tests[i].callback(GTK_WINDOW(window));
+    score += (N_ITERATIONS / time) / tests[i].weight;
+  }
+  
+  gtk_widget_destroy(window);
+  g_free(phrase);
+  
+  return (score / i) * 1000.0f;
+}
diff --git a/modules/benchmark/md5.c b/modules/benchmark/md5.c
new file mode 100644
index 0000000..f4032dd
--- /dev/null
+++ b/modules/benchmark/md5.c
@@ -0,0 +1,317 @@
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+/* This code was modified in 1997 by Jim Kingdon of Cyclic Software to
+   not require an integer type which is exactly 32 bits.  This work
+   draws on the changes for the same purpose by Tatu Ylonen
+   <ylo@cs.hut.fi> as part of SSH, but since I didn't actually use
+   that code, there is no copyright issue.  I hereby disclaim
+   copyright in any changes I have made; this code remains in the
+   public domain.  */
+
+#include <string.h>		/* for memcpy() and memset() */
+
+/* Add prototype support.  */
+#ifndef PROTO
+#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
+#define PROTO(ARGS) ARGS
+#else
+#define PROTO(ARGS) ()
+#endif
+#endif
+
+#include "md5.h"
+
+#if defined(__OPTIMIZE__)
+#error You must compile this program without "-O". (Or else the benchmark results may be different!)
+#endif
+
+/* Little-endian byte-swapping routines.  Note that these do not
+   depend on the size of datatypes such as uint32, nor do they require
+   us to detect the endianness of the machine we are running on.  It
+   is possible they should be macros for speed, but I would be
+   surprised if they were a performance bottleneck for MD5.  */
+
+static uint32 getu32(addr)
+const unsigned char *addr;
+{
+    return (((((unsigned long) addr[3] << 8) | addr[2]) << 8)
+	    | addr[1]) << 8 | addr[0];
+}
+
+static void putu32(data, addr)
+uint32 data;
+unsigned char *addr;
+{
+    addr[0] = (unsigned char) data;
+    addr[1] = (unsigned char) (data >> 8);
+    addr[2] = (unsigned char) (data >> 16);
+    addr[3] = (unsigned char) (data >> 24);
+}
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(ctx)
+struct MD5Context *ctx;
+{
+    ctx->buf[0] = 0x67452301;
+    ctx->buf[1] = 0xefcdab89;
+    ctx->buf[2] = 0x98badcfe;
+    ctx->buf[3] = 0x10325476;
+
+    ctx->bits[0] = 0;
+    ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(ctx, buf, len)
+struct MD5Context *ctx;
+unsigned char const *buf;
+unsigned len;
+{
+    uint32 t;
+
+    /* Update bitcount */
+
+    t = ctx->bits[0];
+    if ((ctx->bits[0] = (t + ((uint32) len << 3)) & 0xffffffff) < t)
+	ctx->bits[1]++;		/* Carry from low to high */
+    ctx->bits[1] += len >> 29;
+
+    t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
+
+    /* Handle any leading odd-sized chunks */
+
+    if (t) {
+	unsigned char *p = ctx->in + t;
+
+	t = 64 - t;
+	if (len < t) {
+	    memcpy(p, buf, len);
+	    return;
+	}
+	memcpy(p, buf, t);
+	MD5Transform(ctx->buf, ctx->in);
+	buf += t;
+	len -= t;
+    }
+
+    /* Process data in 64-byte chunks */
+
+    while (len >= 64) {
+	memcpy(ctx->in, buf, 64);
+	MD5Transform(ctx->buf, ctx->in);
+	buf += 64;
+	len -= 64;
+    }
+
+    /* Handle any remaining bytes of data. */
+
+    memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern 
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(digest, ctx)
+unsigned char digest[16];
+struct MD5Context *ctx;
+{
+    unsigned count;
+    unsigned char *p;
+
+    /* Compute number of bytes mod 64 */
+    count = (ctx->bits[0] >> 3) & 0x3F;
+
+    /* Set the first char of padding to 0x80.  This is safe since there is
+       always at least one byte free */
+    p = ctx->in + count;
+    *p++ = 0x80;
+
+    /* Bytes of padding needed to make 64 bytes */
+    count = 64 - 1 - count;
+
+    /* Pad out to 56 mod 64 */
+    if (count < 8) {
+	/* Two lots of padding:  Pad the first block to 64 bytes */
+	memset(p, 0, count);
+	MD5Transform(ctx->buf, ctx->in);
+
+	/* Now fill the next block with 56 bytes */
+	memset(ctx->in, 0, 56);
+    } else {
+	/* Pad block to 56 bytes */
+	memset(p, 0, count - 8);
+    }
+
+    /* Append length in bits and transform */
+    putu32(ctx->bits[0], ctx->in + 56);
+    putu32(ctx->bits[1], ctx->in + 60);
+
+    MD5Transform(ctx->buf, ctx->in);
+    putu32(ctx->buf[0], digest);
+    putu32(ctx->buf[1], digest + 4);
+    putu32(ctx->buf[2], digest + 8);
+    putu32(ctx->buf[3], digest + 12);
+    memset(ctx, 0, sizeof(*ctx));	/* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+        ( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Transform(buf, inraw)
+uint32 buf[4];
+const unsigned char inraw[64];
+{
+    register uint32 a, b, c, d;
+    uint32 in[16];
+    int i;
+
+    for (i = 0; i < 16; ++i)
+	in[i] = getu32(inraw + 4 * i);
+
+    a = buf[0];
+    b = buf[1];
+    c = buf[2];
+    d = buf[3];
+
+    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+    buf[0] += a;
+    buf[1] += b;
+    buf[2] += c;
+    buf[3] += d;
+}
+#endif
+
+#ifdef TEST
+/* Simple test program.  Can use it to manually run the tests from
+   RFC1321 for example.  */
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    struct MD5Context context;
+    unsigned char checksum[16];
+    int i;
+    int j;
+
+    if (argc < 2) {
+	fprintf(stderr, "usage: %s string-to-hash\n", argv[0]);
+	exit(1);
+    }
+    for (j = 1; j < argc; ++j) {
+	printf("MD5 (\"%s\") = ", argv[j]);
+	MD5Init(&context);
+	MD5Update(&context, argv[j], strlen(argv[j]));
+	MD5Final(checksum, &context);
+	for (i = 0; i < 16; i++) {
+	    printf("%02x", (unsigned int) checksum[i]);
+	}
+	printf("\n");
+    }
+    return 0;
+}
+#endif				/* TEST */
diff --git a/modules/benchmark/nqueens.c b/modules/benchmark/nqueens.c
new file mode 100644
index 0000000..78293ab
--- /dev/null
+++ b/modules/benchmark/nqueens.c
@@ -0,0 +1,67 @@
+/*
+ * N-Queens Problem Solver
+ * Found somewhere on the Internet; can't remember where. Possibly Wikipedia.
+ */
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include "hardinfo.h"
+#include "benchmark.h"
+
+#define QUEENS 11
+
+int row[QUEENS];
+
+bool safe(int x, int y)
+{
+    int i;
+    for (i = 1; i <= y; i++)
+	if (row[y - i] == x || row[y - i] == x - i || row[y - i] == x + i)
+	    return false;
+    return true;
+}
+
+int nqueens(int y)
+{
+    int x;
+
+    for (x = 0; x < QUEENS; x++) {
+	if (safe((row[y - 1] = x), y - 1)) {
+	    if (y < QUEENS) {
+		nqueens(y + 1);
+	    } else {
+	        break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+static gpointer nqueens_for(unsigned int start, unsigned int end, void *data, gint thread_number)
+{
+    unsigned int i;
+
+    for (i = start; i <= end; i++) {
+        nqueens(0);
+    }
+
+    return NULL;
+}
+
+void
+benchmark_nqueens(void)
+{
+    bench_value r = EMPTY_BENCH_VALUE;
+
+    shell_view_set_enabled(FALSE);
+    shell_status_update("Running N-Queens benchmark...");
+
+    r = benchmark_parallel_for(0, 0, 10, nqueens_for, NULL);
+    r.result = r.elapsed_time;
+
+    bench_results[BENCHMARK_NQUEENS] = r;
+}
+
+
diff --git a/modules/benchmark/raytrace.c b/modules/benchmark/raytrace.c
new file mode 100644
index 0000000..c796358
--- /dev/null
+++ b/modules/benchmark/raytrace.c
@@ -0,0 +1,48 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "benchmark.h"
+
+void fbench();	/* fbench.c */
+
+static gpointer
+parallel_raytrace(unsigned int start, unsigned int end, gpointer data, gint thread_number)
+{
+    unsigned int i;
+
+    for (i = start; i <= end; i++) {
+        fbench();
+    }
+
+    return NULL;
+}
+
+void
+benchmark_raytrace(void)
+{
+    bench_value r = EMPTY_BENCH_VALUE;
+
+    shell_view_set_enabled(FALSE);
+    shell_status_update("Performing John Walker's FBENCH...");
+
+    r = benchmark_parallel_for(0, 0, 1000, parallel_raytrace, NULL);
+    r.result = r.elapsed_time;
+
+    bench_results[BENCHMARK_RAYTRACE] = r;
+}
+
diff --git a/modules/benchmark/sha1.c b/modules/benchmark/sha1.c
new file mode 100644
index 0000000..b94ce25
--- /dev/null
+++ b/modules/benchmark/sha1.c
@@ -0,0 +1,329 @@
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+
+/* #define SHA1HANDSOFF * Copies data before messing with it. */
+
+#include <stdio.h>
+#include <string.h>
+#include <sha1.h>
+
+#if defined(__OPTIMIZE__)
+#error You must compile this program without "-O".
+#endif
+
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifdef LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(guint32 state[5], guchar buffer[64])
+{
+    guint32 a, b, c, d, e;
+    typedef union {
+	guchar c[64];
+	guint32 l[16];
+    } CHAR64LONG16;
+    CHAR64LONG16 *block;
+#ifdef SHA1HANDSOFF
+    static guchar workspace[64];
+    block = (CHAR64LONG16 *) workspace;
+    memcpy(block, buffer, 64);
+#else
+    block = (CHAR64LONG16 *) buffer;
+#endif
+    /* Copy context->state[] to working vars */
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a, b, c, d, e, 0);
+    R0(e, a, b, c, d, 1);
+    R0(d, e, a, b, c, 2);
+    R0(c, d, e, a, b, 3);
+    R0(b, c, d, e, a, 4);
+    R0(a, b, c, d, e, 5);
+    R0(e, a, b, c, d, 6);
+    R0(d, e, a, b, c, 7);
+    R0(c, d, e, a, b, 8);
+    R0(b, c, d, e, a, 9);
+    R0(a, b, c, d, e, 10);
+    R0(e, a, b, c, d, 11);
+    R0(d, e, a, b, c, 12);
+    R0(c, d, e, a, b, 13);
+    R0(b, c, d, e, a, 14);
+    R0(a, b, c, d, e, 15);
+    R1(e, a, b, c, d, 16);
+    R1(d, e, a, b, c, 17);
+    R1(c, d, e, a, b, 18);
+    R1(b, c, d, e, a, 19);
+    R2(a, b, c, d, e, 20);
+    R2(e, a, b, c, d, 21);
+    R2(d, e, a, b, c, 22);
+    R2(c, d, e, a, b, 23);
+    R2(b, c, d, e, a, 24);
+    R2(a, b, c, d, e, 25);
+    R2(e, a, b, c, d, 26);
+    R2(d, e, a, b, c, 27);
+    R2(c, d, e, a, b, 28);
+    R2(b, c, d, e, a, 29);
+    R2(a, b, c, d, e, 30);
+    R2(e, a, b, c, d, 31);
+    R2(d, e, a, b, c, 32);
+    R2(c, d, e, a, b, 33);
+    R2(b, c, d, e, a, 34);
+    R2(a, b, c, d, e, 35);
+    R2(e, a, b, c, d, 36);
+    R2(d, e, a, b, c, 37);
+    R2(c, d, e, a, b, 38);
+    R2(b, c, d, e, a, 39);
+    R3(a, b, c, d, e, 40);
+    R3(e, a, b, c, d, 41);
+    R3(d, e, a, b, c, 42);
+    R3(c, d, e, a, b, 43);
+    R3(b, c, d, e, a, 44);
+    R3(a, b, c, d, e, 45);
+    R3(e, a, b, c, d, 46);
+    R3(d, e, a, b, c, 47);
+    R3(c, d, e, a, b, 48);
+    R3(b, c, d, e, a, 49);
+    R3(a, b, c, d, e, 50);
+    R3(e, a, b, c, d, 51);
+    R3(d, e, a, b, c, 52);
+    R3(c, d, e, a, b, 53);
+    R3(b, c, d, e, a, 54);
+    R3(a, b, c, d, e, 55);
+    R3(e, a, b, c, d, 56);
+    R3(d, e, a, b, c, 57);
+    R3(c, d, e, a, b, 58);
+    R3(b, c, d, e, a, 59);
+    R4(a, b, c, d, e, 60);
+    R4(e, a, b, c, d, 61);
+    R4(d, e, a, b, c, 62);
+    R4(c, d, e, a, b, 63);
+    R4(b, c, d, e, a, 64);
+    R4(a, b, c, d, e, 65);
+    R4(e, a, b, c, d, 66);
+    R4(d, e, a, b, c, 67);
+    R4(c, d, e, a, b, 68);
+    R4(b, c, d, e, a, 69);
+    R4(a, b, c, d, e, 70);
+    R4(e, a, b, c, d, 71);
+    R4(d, e, a, b, c, 72);
+    R4(c, d, e, a, b, 73);
+    R4(b, c, d, e, a, 74);
+    R4(a, b, c, d, e, 75);
+    R4(e, a, b, c, d, 76);
+    R4(d, e, a, b, c, 77);
+    R4(c, d, e, a, b, 78);
+    R4(b, c, d, e, a, 79);
+    /* Add the working vars back into context.state[] */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+    /* Wipe variables */
+    a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX * context)
+{
+    /* SHA1 initialization constants */
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+    context->state[4] = 0xC3D2E1F0;
+    context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX * context, guchar * data, guint32 len)
+{
+    guint32 i, j;
+
+    j = (context->count[0] >> 3) & 63;
+    if ((context->count[0] += len << 3) < (len << 3))
+	context->count[1]++;
+    context->count[1] += (len >> 29);
+    if ((j + len) > 63) {
+	memcpy(&context->buffer[j], data, (i = 64 - j));
+	SHA1Transform(context->state, context->buffer);
+	for (; i + 63 < len; i += 64) {
+	    SHA1Transform(context->state, &data[i]);
+	}
+	j = 0;
+    } else
+	i = 0;
+    memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(guchar digest[20], SHA1_CTX * context)
+{
+    guint32 i, j;
+    guchar finalcount[8];
+
+    for (i = 0; i < 8; i++) {
+	finalcount[i] = (guchar) ((context->count[(i >= 4 ? 0 : 1)]
+				   >> ((3 - (i & 3)) * 8)) & 255);	/* Endian independent */
+    }
+    SHA1Update(context, (guchar *) "\200", 1);
+    while ((context->count[0] & 504) != 448) {
+	SHA1Update(context, (guchar *) "\0", 1);
+    }
+    SHA1Update(context, finalcount, 8);	/* Should cause a SHA1Transform() */
+    for (i = 0; i < 20; i++) {
+	digest[i] = (guchar)
+	    ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
+    }
+    /* Wipe variables */
+    i = j = 0;
+    memset(context->buffer, 0, 64);
+    memset(context->state, 0, 20);
+    memset(context->count, 0, 8);
+    memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF		/* make SHA1Transform overwrite it's own static vars */
+    SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+#ifdef SHA1_TEST
+static char *b32_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+
+static void base32_encode_exactly(guchar * buf, gint len,
+				  guchar * encbuf, gint enclen)
+{
+    gint i = 0;
+    guchar *ip = buf + len;
+    guchar *op = encbuf + enclen;
+
+    switch (len % 5) {
+    case 0:
+	do {
+	    g_assert(op - encbuf >= 8);
+	    i = *--ip;		/* Input #4 */
+	    *--op = b32_alphabet[i & 0x1f];	/* Ouput #7 */
+	    i >>= 5;		/* upper <234>, input #4 */
+	    /* FALLTHROUGH */
+    case 4:
+	    i |= ((guint32) * --ip) << 3;	/* had 3 bits in `i' */
+	    *--op = b32_alphabet[i & 0x1f];	/* Output #6 */
+	    i >>= 5;		/* upper <401234>, input #3 */
+	    *--op = b32_alphabet[i & 0x1f];	/* Output #5 */
+	    i >>= 5;		/* upper <4>, input #3 */
+	    /* FALLTHROUGH */
+    case 3:
+	    i |= ((guint32) * --ip) << 1;	/* had 1 bits in `i' */
+	    *--op = b32_alphabet[i & 0x1f];	/* Output #4 */
+	    i >>= 5;		/* upper <1234>, input #2 */
+	    /* FALLTHROUGH */
+    case 2:
+	    i |= ((guint32) * --ip) << 4;	/* had 4 bits in `i' */
+	    *--op = b32_alphabet[i & 0x1f];	/* Output #3 */
+	    i >>= 5;		/* upper <3401234>, input #1 */
+	    *--op = b32_alphabet[i & 0x1f];	/* Output #2 */
+	    i >>= 5;		/* upper <34>, input #1 */
+	    /* FALLTHROUGH */
+    case 1:
+	    i |= ((guint32) * --ip) << 2;	/* had 2 bits in `i' */
+	    *--op = b32_alphabet[i & 0x1f];	/* Output #1 */
+	    i >>= 5;		/* upper <01234>, input #0 */
+	    *--op = b32_alphabet[i & 0x1f];	/* Output #0 */
+	    i >>= 5;		/* Holds nothing, MBZ */
+	    g_assert(i == 0);
+	    g_assert(op >= encbuf);
+	} while (op > encbuf);
+    }
+}
+
+
+
+/*************************************************************/
+
+int main(int argc, char **argv)
+{
+    gint i, j;
+    SHA1_CTX context;
+    guchar digest[20], buffer[16384];
+    FILE *file;
+
+    if (argc > 2) {
+	puts("Public domain SHA-1 implementation - by Steve Reid <steve@edmweb.com>");
+	puts("Produces the SHA-1 hash of a file, or stdin if no file is specified.");
+	exit(0);
+    }
+    if (argc < 2) {
+	file = stdin;
+    } else {
+	if (!(file = fopen(argv[1], "rb"))) {
+	    fputs("Unable to open file.", stderr);
+	    exit(-1);
+	}
+    }
+    SHA1Init(&context);
+    while (!feof(file)) {	/* note: what if ferror(file) */
+	i = fread(buffer, 1, 16384, file);
+	SHA1Update(&context, buffer, i);
+    }
+    SHA1Final(digest, &context);
+    fclose(file);
+
+    for (i = 0; i < 5; i++) {
+        for (j = 0; j < 4; j++) {
+            printf("%02X", digest[i*4+j]);
+        }
+        putchar(' ');
+    }
+    putchar('\n');
+
+    {
+	guchar tmp[33];
+	tmp[32] = '\0';
+	base32_encode_exactly(digest, 20, tmp, 32);
+	printf("%s\n", tmp);
+    }
+
+    exit(0);
+}
+#endif				/* SHA1_TEST */
diff --git a/modules/benchmark/zlib.c b/modules/benchmark/zlib.c
new file mode 100644
index 0000000..2ded59a
--- /dev/null
+++ b/modules/benchmark/zlib.c
@@ -0,0 +1,73 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2017 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <zlib.h>
+
+#include "benchmark.h"
+
+static gpointer zlib_for(unsigned int start, unsigned int end, void *data, gint thread_number)
+{
+    char *compressed;
+    uLong bound = compressBound(bound);
+    unsigned int i;
+
+    compressed = malloc(bound);
+    if (!compressed)
+        return NULL;
+
+    for (i = start; i <= end; i++) {
+        char uncompressed[65536];
+        uLong compressedBound = bound;
+        uLong destBound = sizeof(uncompressed);
+
+        compress(compressed, &compressedBound, data, 65536);
+        uncompress(uncompressed, &destBound, compressed, compressedBound);
+    }
+
+    free(compressed);
+
+    return NULL;
+}
+
+void
+benchmark_zlib(void)
+{
+    bench_value r = EMPTY_BENCH_VALUE;
+    gchar *tmpsrc, *bdata_path;
+
+    bdata_path = g_build_filename(params.path_data, "benchmark.data", NULL);
+    if (!g_file_get_contents(bdata_path, &tmpsrc, NULL, NULL)) {
+        g_free(bdata_path);
+        return;
+    }
+
+    shell_view_set_enabled(FALSE);
+    shell_status_update("Running Zlib benchmark...");
+
+    r = benchmark_parallel_for(0, 0, 50000, zlib_for, tmpsrc);
+
+    g_free(bdata_path);
+    g_free(tmpsrc);
+
+    //TODO: explain in code comments
+    gdouble marks = (50000. * 65536.) / (r.elapsed_time * 840205128.);
+    r.result = marks;
+    bench_results[BENCHMARK_ZLIB] = r;
+}
diff --git a/modules/computer.c b/modules/computer.c
new file mode 100644
index 0000000..ea6762a
--- /dev/null
+++ b/modules/computer.c
@@ -0,0 +1,812 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2008 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include <hardinfo.h>
+#include <iconcache.h>
+#include <shell.h>
+
+#include <vendor.h>
+
+#include "computer.h"
+
+#include "dmi_util.h" /* for dmi_get_str() */
+#include "dt_util.h" /* for dtr_get_string() */
+
+#include "info.h"
+
+/* Callbacks */
+gchar *callback_summary(void);
+gchar *callback_os(void);
+gchar *callback_modules(void);
+gchar *callback_boots(void);
+gchar *callback_locales(void);
+gchar *callback_fs(void);
+gchar *callback_display(void);
+gchar *callback_network(void);
+gchar *callback_users(void);
+gchar *callback_groups(void);
+gchar *callback_env_var(void);
+#if GLIB_CHECK_VERSION(2,14,0)
+gchar *callback_dev(void);
+#endif /* GLIB_CHECK_VERSION(2,14,0) */
+
+/* Scan callbacks */
+void scan_summary(gboolean reload);
+void scan_os(gboolean reload);
+void scan_modules(gboolean reload);
+void scan_boots(gboolean reload);
+void scan_locales(gboolean reload);
+void scan_fs(gboolean reload);
+void scan_display(gboolean reload);
+void scan_network(gboolean reload);
+void scan_users(gboolean reload);
+void scan_groups(gboolean reload);
+void scan_env_var(gboolean reload);
+#if GLIB_CHECK_VERSION(2,14,0)
+void scan_dev(gboolean reload);
+#endif /* GLIB_CHECK_VERSION(2,14,0) */
+
+static ModuleEntry entries[] = {
+    {N_("Summary"), "summary.png", callback_summary, scan_summary, MODULE_FLAG_NONE},
+    {N_("Operating System"), "os.png", callback_os, scan_os, MODULE_FLAG_NONE},
+    {N_("Kernel Modules"), "module.png", callback_modules, scan_modules, MODULE_FLAG_NONE},
+    {N_("Boots"), "boot.png", callback_boots, scan_boots, MODULE_FLAG_NONE},
+    {N_("Languages"), "language.png", callback_locales, scan_locales, MODULE_FLAG_NONE},
+    {N_("Filesystems"), "dev_removable.png", callback_fs, scan_fs, MODULE_FLAG_NONE},
+    {N_("Display"), "monitor.png", callback_display, scan_display, MODULE_FLAG_NONE},
+    {N_("Environment Variables"), "environment.png", callback_env_var, scan_env_var, MODULE_FLAG_NONE},
+#if GLIB_CHECK_VERSION(2,14,0)
+    {N_("Development"), "devel.png", callback_dev, scan_dev, MODULE_FLAG_NONE},
+#endif /* GLIB_CHECK_VERSION(2,14,0) */
+    {N_("Users"), "users.png", callback_users, scan_users, MODULE_FLAG_NONE},
+    {N_("Groups"), "users.png", callback_groups, scan_groups, MODULE_FLAG_NONE},
+    {NULL},
+};
+
+
+gchar *module_list = NULL;
+Computer *computer = NULL;
+
+gchar *hi_more_info(gchar * entry)
+{
+    gchar *info = moreinfo_lookup_with_prefix("COMP", entry);
+
+    if (info)
+        return g_strdup(info);
+
+    return g_strdup_printf("[%s]", entry);
+}
+
+gchar *hi_get_field(gchar * field)
+{
+    gchar *tmp;
+
+    if (g_str_equal(field, _("Memory"))) {
+        MemoryInfo *mi = computer_get_memory();
+        tmp = g_strdup_printf(_("%dMB (%dMB used)"), mi->total, mi->used);
+        g_free(mi);
+    } else if (g_str_equal(field, _("Uptime"))) {
+        tmp = computer_get_formatted_uptime();
+    } else if (g_str_equal(field, _("Date/Time"))) {
+        time_t t = time(NULL);
+
+        tmp = g_new0(gchar, 64);
+        strftime(tmp, 64, "%c", localtime(&t));
+    } else if (g_str_equal(field, _("Load Average"))) {
+        tmp = computer_get_formatted_loadavg();
+    } else if (g_str_equal(field, _("Available entropy in /dev/random"))) {
+        tmp = computer_get_entropy_avail();
+    } else {
+        tmp = g_strdup_printf("Unknown field: %s", field);
+    }
+    return tmp;
+}
+
+void scan_summary(gboolean reload)
+{
+    SCAN_START();
+    module_entry_scan_all_except(entries, 0);
+    computer->alsa = computer_get_alsainfo();
+    SCAN_END();
+}
+
+void scan_os(gboolean reload)
+{
+    SCAN_START();
+    computer->os = computer_get_os();
+    SCAN_END();
+}
+
+void scan_modules(gboolean reload)
+{
+    SCAN_START();
+    scan_modules_do();
+    SCAN_END();
+}
+
+void scan_boots(gboolean reload)
+{
+    SCAN_START();
+    scan_boots_real();
+    SCAN_END();
+}
+
+void scan_locales(gboolean reload)
+{
+    SCAN_START();
+    scan_os(FALSE);
+    scan_languages(computer->os);
+    SCAN_END();
+}
+
+void scan_fs(gboolean reload)
+{
+    SCAN_START();
+    scan_filesystems();
+    SCAN_END();
+}
+
+void scan_display(gboolean reload)
+{
+    SCAN_START();
+    computer->display = computer_get_display();
+    SCAN_END();
+}
+
+void scan_users(gboolean reload)
+{
+    SCAN_START();
+    scan_users_do();
+    SCAN_END();
+}
+
+void scan_groups(gboolean reload)
+{
+    SCAN_START();
+    scan_groups_do();
+    SCAN_END();
+}
+
+#if GLIB_CHECK_VERSION(2,14,0)
+static gchar *dev_list = NULL;
+void scan_dev(gboolean reload)
+{
+    SCAN_START();
+
+    int i;
+    struct {
+       gchar *compiler_name;
+       gchar *version_command;
+       gchar *regex;
+       gboolean stdout;
+    } detect_lang[] = {
+       { N_("Scripting Languages"), NULL, FALSE },
+       { N_("Gambas3 (gbr3)"), "gbr3 --version", "\\d+\\.\\d+\\.\\d+", TRUE },
+       { N_("Python"), "python -V", "\\d+\\.\\d+\\.\\d+", FALSE },
+       { N_("Python2"), "python2 -V", "\\d+\\.\\d+\\.\\d+", FALSE },
+       { N_("Python3"), "python3 -V", "\\d+\\.\\d+\\.\\d+", TRUE },
+       { N_("Perl"), "perl -v", "\\d+\\.\\d+\\.\\d+", TRUE },
+       { N_("Perl6 (VM)"), "perl6 -v", "(?<=This is ).*", TRUE },
+       { N_("Perl6"), "perl6 -v", "(?<=implementing Perl )\\w*\\.\\w*", TRUE },
+       { N_("PHP"), "php --version", "\\d+\\.\\d+\\.\\S+", TRUE},
+       { N_("Ruby"), "ruby --version", "\\d+\\.\\d+\\.\\d+", TRUE },
+       { N_("Bash"), "bash --version", "\\d+\\.\\d+\\.\\S+", TRUE},
+       { N_("Compilers"), NULL, FALSE },
+       { N_("C (GCC)"), "gcc -v", "\\d+\\.\\d+\\.\\d+", FALSE },
+       { N_("C (Clang)"), "clang -v", "\\d+\\.\\d+", FALSE },
+       { N_("D (dmd)"), "dmd --help", "\\d+\\.\\d+", TRUE },
+       { N_("Gambas3 (gbc3)"), "gbc3 --version", "\\d+\\.\\d+\\.\\d+", TRUE },
+       { N_("Java"), "javac -version", "\\d+\\.\\d+\\.\\d+", FALSE },
+       { N_("CSharp (Mono, old)"), "mcs --version", "\\d+\\.\\d+\\.\\d+\\.\\d+", TRUE },
+       { N_("CSharp (Mono)"), "gmcs --version", "\\d+\\.\\d+\\.\\d+\\.\\d+", TRUE },
+       { N_("Vala"), "valac --version", "\\d+\\.\\d+\\.\\d+", TRUE },
+       { N_("Haskell (GHC)"), "ghc -v", "\\d+\\.\\d+\\.\\d+", FALSE },
+       { N_("FreePascal"), "fpc -iV", "\\d+\\.\\d+\\.?\\d*", TRUE },
+       { N_("Go"), "go version", "\\d+\\.\\d+\\.?\\d* ", TRUE },
+       { N_("Tools"), NULL, FALSE },
+       { N_("make"), "make --version", "\\d+\\.\\d+", TRUE },
+       { N_("GDB"), "gdb --version", "(?<=^GNU gdb ).*", TRUE },
+       { N_("strace"), "strace -V", "\\d+\\.\\d+\\.?\\d*", TRUE },
+       { N_("valgrind"), "valgrind --version", "\\d+\\.\\d+\\.\\S+", TRUE },
+       { N_("QMake"), "qmake --version", "\\d+\\.\\S+", TRUE},
+       { N_("CMake"), "cmake --version", "\\d+\\.\\d+\\.?\\d*", TRUE},
+       { N_("Gambas3 IDE"), "gambas3 --version", "\\d+\\.\\d+\\.\\d+", TRUE },
+    };
+
+    g_free(dev_list);
+
+    dev_list = g_strdup("");
+
+    for (i = 0; i < G_N_ELEMENTS(detect_lang); i++) {
+       gchar *version = NULL;
+       gchar *output, *ignored;
+       gchar *temp;
+       GRegex *regex;
+       GMatchInfo *match_info;
+       gboolean found;
+
+       if (!detect_lang[i].regex) {
+            dev_list = h_strdup_cprintf("[%s]\n", dev_list, _(detect_lang[i].compiler_name));
+            continue;
+       }
+
+       if (detect_lang[i].stdout) {
+            found = g_spawn_command_line_sync(detect_lang[i].version_command, &output, &ignored, NULL, NULL);
+       } else {
+            found = g_spawn_command_line_sync(detect_lang[i].version_command, &ignored, &output, NULL, NULL);
+       }
+       g_free(ignored);
+
+       if (found) {
+           regex = g_regex_new(detect_lang[i].regex, 0, 0, NULL);
+
+           g_regex_match(regex, output, 0, &match_info);
+           if (g_match_info_matches(match_info)) {
+               version = g_match_info_fetch(match_info, 0);
+           }
+
+           g_match_info_free(match_info);
+           g_regex_unref(regex);
+           g_free(output);
+       }
+
+       if (version == NULL)
+           version = strdup(_("Not found"));
+
+       dev_list = h_strdup_cprintf("%s=%s\n", dev_list, detect_lang[i].compiler_name, version);
+       g_free(version);
+
+       temp = g_strdup_printf(_("Detecting version: %s"),
+                              detect_lang[i].compiler_name);
+       shell_status_update(temp);
+       g_free(temp);
+    }
+
+    SCAN_END();
+}
+
+gchar *callback_dev(void)
+{
+    return g_strdup_printf(
+                "[$ShellParam$]\n"
+                "ColumnTitle$TextValue=%s\n" /* Program */
+                "ColumnTitle$Value=%s\n" /* Version */
+                "ShowColumnHeaders=true\n"
+                "%s",
+                _("Program"), _("Version"),
+                dev_list);
+}
+#endif /* GLIB_CHECK_VERSION(2,14,0) */
+
+static gchar *detect_machine_type(void)
+{
+    GDir *dir;
+    gchar *chassis;
+
+    chassis = dmi_chassis_type_str(-1, 0);
+    if (chassis)
+        return chassis;
+
+    chassis = dtr_get_string("/model", 0);
+    if (chassis) {
+        if (strstr(chassis, "Raspberry Pi") != NULL
+            || strstr(chassis, "ODROID") != NULL
+            /* FIXME: consider making a table when adding more models */ ) {
+                g_free(chassis);
+                return g_strdup(_("Single-board computer"));
+        }
+        g_free(chassis);
+    }
+
+    if (g_file_test("/proc/pmu/info", G_FILE_TEST_EXISTS))
+        return g_strdup(_("Laptop"));
+
+    dir = g_dir_open("/proc/acpi/battery", 0, NULL);
+    if (dir) {
+        const gchar *name = g_dir_read_name(dir);
+
+        g_dir_close(dir);
+
+        if (name)
+            return g_strdup(_("Laptop"));
+    }
+
+    dir = g_dir_open("/sys/class/power_supply", 0, NULL);
+    if (dir) {
+        const gchar *name;
+
+        while ((name = g_dir_read_name(dir))) {
+            gchar *contents;
+            gchar type[PATH_MAX];
+            int r;
+
+            r = snprintf(type, sizeof(type), "%s/%s/type",
+                         "/sys/class/power_supply", name);
+            if (r < 0 || r > PATH_MAX)
+                continue;
+
+            if (g_file_get_contents(type, &contents, NULL, NULL)) {
+                if (g_str_has_prefix(contents, "Battery")) {
+                    g_free(contents);
+                    g_dir_close(dir);
+
+                    return g_strdup(_("Laptop"));
+                }
+
+                g_free(contents);
+            }
+        }
+
+        g_dir_close(dir);
+    }
+
+    /* FIXME: check if batteries are found using /proc/apm */
+
+    return g_strdup(_("Unknown physical machine type"));
+}
+
+/* Table based off imvirt by Thomas Liske <liske@ibh.de>
+   Copyright (c) 2008 IBH IT-Service GmbH under GPLv2. */
+gchar *computer_get_virtualization(void)
+{
+    gboolean found = FALSE;
+    gint i, j;
+    gchar *files[] = {
+        "/proc/scsi/scsi",
+        "/proc/cpuinfo",
+        "/var/log/dmesg",
+        NULL
+    };
+    const static struct {
+        gchar *str;
+        gchar *vmtype;
+    } vm_types[] = {
+        /* VMware */
+        { "VMware", N_("Virtual (VMware)") },
+        { ": VMware Virtual IDE CDROM Drive", N_("Virtual (VMware)") },
+        /* QEMU */
+        { "QEMU", N_("Virtual (QEMU)") },
+        { "QEMU Virtual CPU", N_("Virtual (QEMU)") },
+        { ": QEMU HARDDISK", N_("Virtual (QEMU)") },
+        { ": QEMU CD-ROM", N_("Virtual (QEMU)") },
+        /* Generic Virtual Machine */
+        { ": Virtual HD,", N_("Virtual (Unknown)") },
+        { ": Virtual CD,", N_("Virtual (Unknown)") },
+        /* Virtual Box */
+        { "VBOX", N_("Virtual (VirtualBox)") },
+        { ": VBOX HARDDISK", N_("Virtual (VirtualBox)") },
+        { ": VBOX CD-ROM", N_("Virtual (VirtualBox)") },
+        /* Xen */
+        { "Xen virtual console", N_("Virtual (Xen)") },
+        { "Xen reported: ", N_("Virtual (Xen)") },
+        { "xen-vbd: registered block device", N_("Virtual (Xen)") },
+        /* Generic */
+        { " hypervisor", N_("Virtual (hypervisor present)") } ,
+        { NULL }
+    };
+    gchar *tmp;
+
+    DEBUG("Detecting virtual machine");
+
+    if (g_file_test("/proc/xen", G_FILE_TEST_EXISTS)) {
+         DEBUG("/proc/xen found; assuming Xen");
+         return g_strdup(_("Virtual (Xen)"));
+    }
+
+    tmp = module_call_method("devices::getMotherboard");
+    if (strstr(tmp, "VirtualBox") != NULL) {
+        g_free(tmp);
+        return g_strdup(_("Virtual (VirtualBox)"));
+    }
+    g_free(tmp);
+
+    for (i = 0; files[i+1]; i++) {
+         gchar buffer[512];
+         FILE *file;
+
+         if ((file = fopen(files[i], "r"))) {
+              while (!found && fgets(buffer, 512, file)) {
+                  for (j = 0; vm_types[j+1].str; j++) {
+                      if (strstr(buffer, vm_types[j].str)) {
+                         found = TRUE;
+                         break;
+                      }
+                  }
+              }
+
+              fclose(file);
+
+              if (found) {
+                  DEBUG("%s found (by reading file %s)",
+                        vm_types[j].vmtype, files[i]);
+                  return g_strdup(_(vm_types[j].vmtype));
+              }
+         }
+
+    }
+
+    DEBUG("no virtual machine detected; assuming physical machine");
+
+    return detect_machine_type();
+}
+
+gchar *callback_summary(void)
+{
+    struct Info *info = info_new();
+
+    info_add_group(info, _("Computer"),
+        info_field_printf(_("Processor"), "%s",
+            module_call_method("devices::getProcessorName")),
+        info_field_update(_("Memory"), 1000),
+        info_field_printf(_("Machine Type"), "%s",
+            computer_get_virtualization()),
+        info_field(_("Operating System"), computer->os->distro),
+        info_field(_("User Name"), computer->os->username),
+        info_field_update(_("Date/Time"), 1000),
+        info_field_last());
+
+    info_add_group(info, _("Display"),
+        info_field_printf(_("Resolution"), _(/* label for resolution */ "%dx%d pixels"),
+            computer->display->width, computer->display->height),
+        info_field(_("OpenGL Renderer"), computer->display->ogl_renderer),
+        info_field(_("X11 Vendor"), computer->display->vendor),
+        info_field_last());
+
+    info_add_computed_group(info, _("Audio Devices"),
+        idle_free(computer_get_alsacards(computer)));
+    info_add_computed_group(info, _("Input Devices"),
+        idle_free(module_call_method("devices::getInputDevices")));
+    info_add_computed_group(info, NULL, /* getPrinters provides group headers */
+        idle_free(module_call_method("devices::getPrinters")));
+    info_add_computed_group(info, NULL,  /* getStorageDevices provides group headers */
+        idle_free(module_call_method("devices::getStorageDevices")));
+
+    return info_flatten(info);
+}
+
+gchar *callback_os(void)
+{
+    struct Info *info = info_new();
+
+    info_add_group(info, _("Version"),
+        info_field(_("Kernel"), computer->os->kernel),
+        info_field(_("Version"), computer->os->kernel_version),
+        info_field(_("C Library"), computer->os->libc),
+        info_field(_("Distribution"), computer->os->distro),
+        info_field_last());
+
+    info_add_group(info, _("Current Session"),
+        info_field(_("Computer Name"), computer->os->hostname),
+        info_field(_("User Name"), computer->os->username),
+        info_field(_("Language"), computer->os->language),
+        info_field(_("Home Directory"), computer->os->homedir),
+        info_field_last());
+
+    info_add_group(info, _("Misc"),
+        info_field_update(_("Uptime"), 1000),
+        info_field_update(_("Load Average"), 10000),
+        info_field_update(_("Available entropy in /dev/random"), 1000),
+        info_field_last());
+
+    return info_flatten(info);
+}
+
+gchar *callback_modules(void)
+{
+    struct Info *info = info_new();
+
+    info_add_computed_group(info, _("Loaded Modules"), module_list);
+
+    info_set_column_title(info, "TextValue", _("Name"));
+    info_set_column_title(info, "Value", _("Description"));
+    info_set_column_headers_visible(info, TRUE);
+    info_set_view_type(info, SHELL_VIEW_DUAL);
+
+    return info_flatten(info);
+}
+
+gchar *callback_boots(void)
+{
+    struct Info *info = info_new();
+
+    info_add_computed_group(info, _("Boots"), computer->os->boots);
+
+    info_set_column_title(info, "TextValue", _("Date & Time"));
+    info_set_column_title(info, "Value", _("Kernel Version"));
+    info_set_column_headers_visible(info, TRUE);
+
+    return info_flatten(info);
+}
+
+gchar *callback_locales(void)
+{
+    struct Info *info = info_new();
+
+    info_add_computed_group(info, _("Available Languages"), computer->os->languages);
+
+    info_set_column_title(info, "TextValue", _("Language Code"));
+    info_set_column_title(info, "Value", _("Name"));
+    info_set_view_type(info, SHELL_VIEW_DUAL);
+    info_set_column_headers_visible(info, TRUE);
+
+    return info_flatten(info);
+}
+
+gchar *callback_fs(void)
+{
+    struct Info *info = info_new();
+
+    info_add_computed_group(info, _("Mounted File Systems"), fs_list);
+
+    info_set_column_title(info, "Extra1", _("Mount Point"));
+    info_set_column_title(info, "Progress", _("Usage"));
+    info_set_column_title(info, "TextValue", _("Device"));
+    info_set_column_headers_visible(info, TRUE);
+    info_set_view_type(info, SHELL_VIEW_PROGRESS_DUAL);
+    info_set_zebra_visible(info, TRUE);
+    info_set_normalize_percentage(info, FALSE);
+
+    return info_flatten(info);
+}
+
+gchar *callback_display(void)
+{
+    struct Info *info = info_new();
+
+    info_add_group(info, _("Display"),
+        info_field_printf(_("Resolution"), _(/* resolution WxH unit */ "%dx%d pixels"),
+                computer->display->width, computer->display->height),
+        info_field(_("Vendor"), computer->display->vendor),
+        info_field(_("Version"), computer->display->version),
+        info_field(_("Current Display Name"), computer->display->display_name),
+        info_field_last());
+
+    info_add_computed_group(info, _("Monitors"), computer->display->monitors);
+
+    info_add_group(info, _("OpenGL"),
+        info_field(_("Vendor"), computer->display->ogl_vendor),
+        info_field(_("Renderer"), computer->display->ogl_renderer),
+        info_field(_("Version"), computer->display->ogl_version),
+        info_field(_("Direct Rendering"),
+            computer->display->dri ? _("Yes") : _("No")),
+        info_field_last());
+
+    info_add_computed_group(info, _("Extensions"), computer->display->extensions);
+
+    return info_flatten(info);
+}
+
+gchar *callback_users(void)
+{
+    struct Info *info = info_new();
+
+    info_add_computed_group(info, _("Users"), users);
+    info_set_view_type(info, SHELL_VIEW_DUAL);
+    info_set_reload_interval(info, 10000);
+
+    return info_flatten(info);
+}
+
+gchar *callback_groups(void)
+{
+    struct Info *info = info_new();
+
+    info_add_computed_group(info, _("Group"), groups);
+
+    info_set_column_title(info, "TextValue", _("Name"));
+    info_set_column_title(info, "Value", _("Group ID"));
+    info_set_column_headers_visible(info, TRUE);
+    info_set_reload_interval(info, 10000);
+
+    return info_flatten(info);
+}
+
+gchar *get_os_kernel(void)
+{
+    scan_os(FALSE);
+    return g_strdup(computer->os->kernel);
+}
+
+gchar *get_os(void)
+{
+    scan_os(FALSE);
+    return g_strdup(computer->os->distro);
+}
+
+gchar *get_ogl_renderer(void)
+{
+    scan_display(FALSE);
+
+    return g_strdup(computer->display->ogl_renderer);
+}
+
+gchar *get_display_summary(void)
+{
+    scan_display(FALSE);
+
+    return g_strdup_printf("%dx%d\n"
+                           "%s\n"
+                           "%s",
+                           computer->display->width,
+                           computer->display->height,
+                           computer->display->ogl_renderer,
+                           computer->display->vendor);
+}
+
+gchar *get_kernel_module_description(gchar *module)
+{
+    gchar *description;
+
+    if (!_module_hash_table) {
+        scan_modules(FALSE);
+    }
+
+    description = g_hash_table_lookup(_module_hash_table, module);
+    if (!description) {
+        return NULL;
+    }
+
+    return g_strdup(description);
+}
+
+gchar *get_audio_cards(void)
+{
+    if (!computer->alsa) {
+      computer->alsa = computer_get_alsainfo();
+    }
+
+    return computer_get_alsacards(computer);
+}
+
+ShellModuleMethod *hi_exported_methods(void)
+{
+    static ShellModuleMethod m[] = {
+        {"getOSKernel", get_os_kernel},
+        {"getOS", get_os},
+        {"getDisplaySummary", get_display_summary},
+        {"getOGLRenderer", get_ogl_renderer},
+        {"getAudioCards", get_audio_cards},
+        {"getKernelModuleDescription", get_kernel_module_description},
+        {NULL}
+    };
+
+    return m;
+}
+
+ModuleEntry *hi_module_get_entries(void)
+{
+    return entries;
+}
+
+gchar *hi_module_get_name(void)
+{
+    return g_strdup(_("Computer"));
+}
+
+guchar hi_module_get_weight(void)
+{
+    return 80;
+}
+
+gchar **hi_module_get_dependencies(void)
+{
+    static gchar *deps[] = { "devices.so", NULL };
+
+    return deps;
+}
+
+gchar *hi_module_get_summary(void)
+{
+    return g_strdup_printf("[%s]\n"
+                    "Icon=os.png\n"
+                    "Method=computer::getOS\n"
+                    "[%s]\n"
+                    "Icon=processor.png\n"
+                    "Method=devices::getProcessorNameAndDesc\n"
+                    "[%s]\n"
+                    "Icon=memory.png\n"
+                    "Method=devices::getMemoryTotal\n"
+                    "[%s]\n"
+                    "Icon=module.png\n"
+                    "Method=devices::getMotherboard\n"
+                    "[%s]\n"
+                    "Icon=monitor.png\n"
+                    "Method=computer::getDisplaySummary\n"
+                    "[%s]\n"
+                    "Icon=hdd.png\n"
+                    "Method=devices::getStorageDevices\n"
+                    "[%s]\n"
+                    "Icon=printer.png\n"
+                    "Method=devices::getPrinters\n"
+                    "[%s]\n"
+                    "Icon=audio.png\n"
+                    "Method=computer::getAudioCards\n",
+                    _("Operating System"),
+                    _("CPU"), _("RAM"), _("Motherboard"), _("Graphics"),
+                    _("Storage"), _("Printers"), _("Audio")
+                    );
+}
+
+void hi_module_deinit(void)
+{
+    if (computer->os) {
+        g_free(computer->os->kernel);
+        g_free(computer->os->libc);
+        g_free(computer->os->distrocode);
+        g_free(computer->os->distro);
+        g_free(computer->os->hostname);
+        g_free(computer->os->language);
+        g_free(computer->os->homedir);
+        g_free(computer->os->kernel_version);
+        g_free(computer->os->languages);
+        g_free(computer->os->desktop);
+        g_free(computer->os->username);
+        g_free(computer->os->boots);
+        g_free(computer->os);
+    }
+
+    if (computer->display) {
+        g_free(computer->display->ogl_vendor);
+        g_free(computer->display->ogl_renderer);
+        g_free(computer->display->ogl_version);
+        g_free(computer->display->display_name);
+        g_free(computer->display->vendor);
+        g_free(computer->display->version);
+        g_free(computer->display->extensions);
+        g_free(computer->display->monitors);
+        g_free(computer->display);
+    }
+
+    if (computer->alsa) {
+        g_slist_free(computer->alsa->cards);
+        g_free(computer->alsa);
+    }
+
+    g_free(computer->date_time);
+    g_free(computer);
+
+    moreinfo_del_with_prefix("COMP");
+}
+
+void hi_module_init(void)
+{
+    computer = g_new0(Computer, 1);
+}
+
+ModuleAbout *hi_module_get_about(void)
+{
+    static ModuleAbout ma[] = {
+    {
+     .author = "Leandro A. F. Pereira",
+     .description = N_("Gathers high-level computer information"),
+     .version = VERSION,
+     .license = "GNU GPL version 2"}
+    };
+
+    return ma;
+}
+
diff --git a/modules/computer/alsa.c b/modules/computer/alsa.c
new file mode 100644
index 0000000..00c1fce
--- /dev/null
+++ b/modules/computer/alsa.c
@@ -0,0 +1,71 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "computer.h"
+
+gchar *
+computer_get_alsacards(Computer * computer)
+{
+    GSList *p;
+    gchar *tmp = g_strdup_printf("[%s]\n", _("Audio Devices"));
+    gint n = 0;
+
+    if (computer->alsa) {
+        for (p = computer->alsa->cards; p; p = p->next) {
+            AlsaCard *ac = (AlsaCard *) p->data;
+
+            tmp = h_strdup_cprintf("%s#%d=%s\n", tmp,
+                        _("Audio Adapter"), ++n, ac->friendly_name);
+        }
+    }
+
+    return tmp;
+}
+
+AlsaInfo *
+computer_get_alsainfo(void)
+{
+    AlsaInfo *ai;
+    AlsaCard *ac;
+    FILE *cards;
+    gchar buffer[128];
+
+    cards = fopen("/proc/asound/cards", "r");
+    if (!cards)
+        return NULL;
+
+    ai = g_new0(AlsaInfo, 1);
+
+    while (fgets(buffer, 128, cards)) {
+        gchar **tmp;
+
+        ac = g_new0(AlsaCard, 1);
+
+        tmp = g_strsplit(buffer, ":", 0);
+
+        ac->friendly_name = g_strdup(tmp[1]);
+        ai->cards = g_slist_append(ai->cards, ac);
+
+        g_strfreev(tmp);
+        (void)fgets(buffer, 128, cards);  /* skip next line */
+    }
+    fclose(cards);
+
+    return ai;
+}
diff --git a/modules/computer/boots.c b/modules/computer/boots.c
new file mode 100644
index 0000000..ba45824
--- /dev/null
+++ b/modules/computer/boots.c
@@ -0,0 +1,66 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "hardinfo.h"
+#include "computer.h"
+
+void
+scan_boots_real(void)
+{
+    gchar **tmp;
+    gboolean spawned;
+    gchar *out, *err, *p, *s, *next_nl;
+
+    scan_os(FALSE);
+
+    if (!computer->os->boots)
+      computer->os->boots = strdup("");
+    else
+      return;
+
+    spawned = g_spawn_command_line_sync("last",
+            &out, &err, NULL, NULL);
+    if (spawned && out != NULL) {
+        p = out;
+        while(next_nl = strchr(p, '\n')) {
+            strend(p, '\n');
+            if (strstr(p, "system boot")) {
+                s = p;
+                while (*s) {
+                  if (*s == ' ' && *(s + 1) == ' ') {
+                    memmove(s, s + 1, strlen(s) + 1);
+                    s--;
+                  } else {
+                    s++;
+                  }
+                }
+                tmp = g_strsplit(p, " ", 0);
+                computer->os->boots =
+                  h_strdup_cprintf("\n%s %s %s %s=%s",
+                    computer->os->boots,
+                    tmp[4], tmp[5], tmp[6], tmp[7], tmp[3]);
+                g_strfreev(tmp);
+            }
+            p = next_nl + 1;
+        }
+      g_free(out);
+      g_free(err);
+    }
+}
diff --git a/modules/computer/display.c b/modules/computer/display.c
new file mode 100644
index 0000000..61eac4e
--- /dev/null
+++ b/modules/computer/display.c
@@ -0,0 +1,151 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "hardinfo.h"
+#include "computer.h"
+
+static void
+get_glx_info(DisplayInfo *di)
+{
+    gchar *output;
+    if (g_spawn_command_line_sync("glxinfo", &output, NULL, NULL, NULL)) {
+        gchar **output_lines;
+        gint i = 0;
+
+        for (output_lines = g_strsplit(output, "\n", 0);
+             output_lines && output_lines[i];
+             i++) {
+            if (strstr(output_lines[i], "OpenGL")) {
+                gchar **tmp = g_strsplit(output_lines[i], ":", 0);
+
+                tmp[1] = g_strchug(tmp[1]);
+
+                get_str("OpenGL vendor str", di->ogl_vendor);
+                get_str("OpenGL renderer str", di->ogl_renderer);
+                get_str("OpenGL version str", di->ogl_version);
+
+                g_strfreev(tmp);
+            } else if (strstr(output_lines[i], "direct rendering: Yes")) {
+                di->dri = TRUE;
+            }
+        }
+
+        g_free(output);
+        g_strfreev(output_lines);
+
+        if (!di->ogl_vendor)
+            di->ogl_vendor = _("(Unknown)");
+        if (!di->ogl_renderer)
+            di->ogl_renderer = _("(Unknown)");
+        if (!di->ogl_version)
+            di->ogl_version = _("(Unknown)");
+
+    } else {
+        di->ogl_vendor = di->ogl_renderer = di->ogl_version = _("(Unknown)");
+    }
+
+}
+
+static void
+get_x11_info(DisplayInfo *di)
+{
+    gchar *output;
+
+    if (g_spawn_command_line_sync("xdpyinfo", &output, NULL, NULL, NULL)) {
+	gchar **output_lines, **old;
+
+	output_lines = g_strsplit(output, "\n", 0);
+	g_free(output);
+
+	old = output_lines;
+	while (*output_lines) {
+            gchar **tmp = g_strsplit(*output_lines, ":", 2);
+            output_lines++;
+
+            if (tmp[1] && tmp[0]) {
+              tmp[1] = g_strchug(tmp[1]);
+
+              get_str("vendor string", di->vendor);
+              get_str("X.Org version", di->version);
+              get_str("XFree86 version", di->version);
+              get_str("name of display", di->display_name);
+
+              if (g_str_has_prefix(tmp[0], "number of extensions")) {
+                int n;
+
+                di->extensions = g_strdup("");
+
+                for (n = atoi(tmp[1]); n; n--) {
+                  di->extensions = h_strconcat(di->extensions,
+                                               g_strstrip(*(++output_lines)),
+                                               "=\n",
+                                               NULL);
+                }
+                g_strfreev(tmp);
+
+                break;
+              }
+            }
+
+            g_strfreev(tmp);
+	}
+
+	g_strfreev(old);
+    }
+
+    GdkScreen *screen = gdk_screen_get_default();
+
+    if (screen && GDK_IS_SCREEN(screen)) {
+        gint n_monitors = gdk_screen_get_n_monitors(screen);
+        gint i;
+
+        di->monitors = NULL;
+        for (i = 0; i < n_monitors; i++) {
+            GdkRectangle rect;
+
+            gdk_screen_get_monitor_geometry(screen, i, &rect);
+
+            di->monitors = h_strdup_cprintf(_("Monitor %d=%dx%d pixels\n"),
+                                            di->monitors, i, rect.width, rect.height);
+        }
+      } else {
+          di->monitors = "";
+      }
+}
+
+DisplayInfo *
+computer_get_display(void)
+{
+    DisplayInfo *di = g_new0(DisplayInfo, 1);
+
+    GdkScreen *screen = gdk_screen_get_default();
+
+    if (screen && GDK_IS_SCREEN(screen)) {
+        di->width = gdk_screen_get_width(screen);
+        di->height = gdk_screen_get_height(screen);
+    } else {
+        di->width = di->height = 0;
+    }
+
+    get_glx_info(di);
+    get_x11_info(di);
+
+    return di;
+}
diff --git a/modules/computer/environment.c b/modules/computer/environment.c
new file mode 100644
index 0000000..dc0fb6f
--- /dev/null
+++ b/modules/computer/environment.c
@@ -0,0 +1,45 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2008 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "computer.h"
+
+static gchar *_env = NULL;
+void scan_env_var(gboolean reload)
+{
+    SCAN_START();
+
+    gchar **envlist;
+    gint i;
+
+    g_free(_env);
+
+    _env = g_strdup_printf("[%s]\n", _("Environment Variables") );
+    for (i = 0, envlist = g_listenv(); envlist[i]; i++) {
+      _env = h_strdup_cprintf("%s=%s\n", _env,
+                              envlist[i], g_getenv(envlist[i]));
+    }
+    g_strfreev(envlist);
+
+    SCAN_END();
+}
+
+gchar *callback_env_var(void)
+{
+    return g_strdup(_env);
+}
diff --git a/modules/computer/filesystem.c b/modules/computer/filesystem.c
new file mode 100644
index 0000000..397dc63
--- /dev/null
+++ b/modules/computer/filesystem.c
@@ -0,0 +1,105 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Some code from xfce4-mount-plugin, version 0.4.3
+ *  Copyright (C) 2005 Jean-Baptiste jb_dul@yahoo.com
+ *  Distributed under the terms of GNU GPL 2.
+ */
+
+#include <string.h>
+#include <sys/vfs.h>
+#include "hardinfo.h"
+#include "computer.h"
+
+gchar *fs_list = NULL;
+
+void
+scan_filesystems(void)
+{
+    FILE *mtab;
+    gchar buf[1024];
+    struct statfs sfs;
+    int count = 0;
+
+    g_free(fs_list);
+    fs_list = g_strdup("");
+    moreinfo_del_with_prefix("COMP:FS");
+
+    mtab = fopen("/etc/mtab", "r");
+    if (!mtab)
+        return;
+
+    while (fgets(buf, 1024, mtab)) {
+        gfloat size, used, avail;
+        gchar **tmp;
+
+        tmp = g_strsplit(buf, " ", 0);
+        if (!statfs(tmp[1], &sfs)) {
+                gfloat use_ratio;
+
+                size = (float) sfs.f_bsize * (float) sfs.f_blocks;
+                avail = (float) sfs.f_bsize * (float) sfs.f_bavail;
+                used = size - avail;
+
+                if (size == 0.0f) {
+                        continue;
+                }
+
+                if (avail == 0.0f) {
+                        use_ratio = 100.0f;
+                } else {
+                        use_ratio = 100.0f * (used / size);
+                }
+
+                gchar *strsize = size_human_readable(size),
+                      *stravail = size_human_readable(avail),
+                      *strused = size_human_readable(used);
+
+                gchar *strhash;
+
+                strreplacechr(tmp[0], "#", '_');
+                strhash = g_strdup_printf("[%s]\n"
+                        "%s=%s\n"
+                        "%s=%s\n"
+                        "%s=%s\n"
+                        "%s=%s\n"
+                        "%s=%s\n"
+                        "%s=%s\n",
+                        tmp[0], /* path */
+                        _("Filesystem"), tmp[2],
+                        _("Mounted As"), ( strstr(tmp[3], "rw") != NULL) ? _("Read-Write") : _("Read-Only"),
+                        _("Mount Point"), tmp[1],
+                        _("Size"), strsize,
+                        _("Used"), strused,
+                        _("Available"), stravail);
+                gchar *key = g_strdup_printf("FS%d", ++count);
+                moreinfo_add_with_prefix("COMP", key, strhash);
+                g_free(key);
+
+                fs_list = h_strdup_cprintf("$FS%d$%s=%.2f %% (%s of %s)|%s\n",
+                                          fs_list,
+                                          count, tmp[0], use_ratio, stravail, strsize, tmp[1]);
+
+                g_free(strsize);
+                g_free(stravail);
+                g_free(strused);
+        }
+        g_strfreev(tmp);
+    }
+
+    fclose(mtab);
+}
diff --git a/modules/computer/groups.c b/modules/computer/groups.c
new file mode 100644
index 0000000..244b800
--- /dev/null
+++ b/modules/computer/groups.c
@@ -0,0 +1,45 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2012 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <sys/types.h>
+#include <grp.h>
+#include "hardinfo.h"
+#include "computer.h"
+
+gchar *groups = NULL;
+
+void
+scan_groups_do(void)
+{
+    struct group *group_;
+
+    setgrent();
+    group_ = getgrent();
+    if (!group_)
+        return;
+
+    g_free(groups);
+    groups = g_strdup("");
+
+    while (group_) {
+        groups = h_strdup_cprintf("%s=%d\n", groups, group_->gr_name, group_->gr_gid);
+        group_ = getgrent();
+    }
+    
+    endgrent();
+}
diff --git a/modules/computer/languages.c b/modules/computer/languages.c
new file mode 100644
index 0000000..d468183
--- /dev/null
+++ b/modules/computer/languages.c
@@ -0,0 +1,134 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "hardinfo.h"
+#include "computer.h"
+#include "cpu_util.h" /* for UNKIFNULL() */
+
+void
+scan_languages(OperatingSystem * os)
+{
+    FILE *locale;
+    gchar buf[512], *retval = NULL;
+
+    locale = popen("locale -va && echo", "r");
+    if (!locale)
+	return;
+
+    gchar name[32];
+    gchar *title = NULL,
+          *source = NULL,
+	  *address = NULL,
+	  *email = NULL,
+	  *language = NULL,
+	  *territory = NULL,
+	  *revision = NULL,
+	  *date = NULL,
+	  *codeset = NULL;
+
+    while (fgets(buf, 512, locale)) {
+	if (!strncmp(buf, "locale:", 7)) {
+	    sscanf(buf, "locale: %s", name);
+	    (void)fgets(buf, 128, locale);
+	} else if (strchr(buf, '|')) {
+	    gchar **tmp = g_strsplit(buf, "|", 2);
+
+	    tmp[0] = g_strstrip(tmp[0]);
+
+	    if (tmp[1]) {
+		tmp[1] = g_strstrip(tmp[1]);
+
+		get_str("title", title);
+		get_str("source", source);
+		get_str("address", address);
+		get_str("email", email);
+		get_str("language", language);
+		get_str("territory", territory);
+		get_str("revision", revision);
+		get_str("date", date);
+		get_str("codeset", codeset);
+	    }
+
+	    g_strfreev(tmp);
+	} else {
+        gchar *currlocale;
+
+        retval = h_strdup_cprintf("$%s$%s=%s\n", retval, name, name, title);
+
+        UNKIFNULL(title);
+        UNKIFNULL(source);
+        UNKIFNULL(address);
+        UNKIFNULL(email);
+        UNKIFNULL(language);
+        UNKIFNULL(territory);
+        UNKIFNULL(revision);
+        UNKIFNULL(date);
+        UNKIFNULL(codeset);
+
+        /* values may have & */
+        title = hardinfo_clean_value(title, 1);
+        source = hardinfo_clean_value(source, 1);
+        address = hardinfo_clean_value(address, 1);
+        email = hardinfo_clean_value(email, 1);
+        language = hardinfo_clean_value(language, 1);
+        territory = hardinfo_clean_value(territory, 1);
+
+        currlocale = g_strdup_printf("[%s]\n"
+        /* Name */     "%s=%s (%s)\n"
+        /* Source */   "%s=%s\n"
+        /* Address */  "%s=%s\n"
+        /* Email */    "%s=%s\n"
+        /* Language */ "%s=%s\n"
+        /* Territory */"%s=%s\n"
+        /* Revision */ "%s=%s\n"
+        /* Date */     "%s=%s\n"
+        /* Codeset */  "%s=%s\n",
+                     _("Locale Information"),
+                     _("Name"), name, title,
+                     _("Source"), source,
+                     _("Address"), address,
+                     _("E-mail"), email,
+                     _("Language"), language,
+                     _("Territory"), territory,
+                     _("Revision"), revision,
+                     _("Date"), date,
+                     _("Codeset"), codeset );
+
+        moreinfo_add_with_prefix("COMP", name, currlocale);
+
+        g_free(title);
+        g_free(source);
+        g_free(address);
+        g_free(email);
+        g_free(language);
+        g_free(territory);
+        g_free(revision);
+        g_free(date);
+        g_free(codeset);
+
+        title = source = address = email = language = territory = \
+            revision = date = codeset = NULL;
+    }
+    }
+
+    fclose(locale);
+
+    os->languages = retval;
+}
diff --git a/modules/computer/loadavg.c b/modules/computer/loadavg.c
new file mode 100644
index 0000000..7311dbf
--- /dev/null
+++ b/modules/computer/loadavg.c
@@ -0,0 +1,68 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "hardinfo.h"
+#include "computer.h"
+
+static gboolean
+computer_get_loadinfo(LoadInfo *li)
+{
+    FILE *procloadavg;
+    char buf[64];
+    int ret;
+
+    procloadavg = fopen("/proc/loadavg", "r");
+    if (!procloadavg)
+        return FALSE;
+
+    if (!fgets(buf, sizeof(buf), procloadavg)) {
+        fclose(procloadavg);
+        return FALSE;
+    }
+
+    ret = sscanf(buf, "%f %f %f", &li->load1, &li->load5, &li->load15);
+    if (ret != 3) {
+        size_t len = strlen(buf);
+        size_t i;
+
+        for (i = 0; i < len; i++) {
+            if (buf[i] == '.')
+                buf[i] = ',';
+        }
+
+        ret = sscanf(buf, "%f %f %f", &li->load1, &li->load5, &li->load15);
+    }
+
+    fclose(procloadavg);
+
+    return ret == 3;
+}
+
+gchar *
+computer_get_formatted_loadavg()
+{
+    LoadInfo li;
+
+    if (!computer_get_loadinfo(&li))
+        return g_strdup(_("Couldn't obtain load average"));
+
+    return g_strdup_printf("%.2f, %.2f, %.2f", li.load1, li.load5,
+        li.load15);
+}
diff --git a/modules/computer/memory.c b/modules/computer/memory.c
new file mode 100644
index 0000000..dc8599c
--- /dev/null
+++ b/modules/computer/memory.c
@@ -0,0 +1,62 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "computer.h"
+
+MemoryInfo *
+computer_get_memory(void)
+{
+    MemoryInfo *mi;
+    FILE *procmem;
+    gchar buffer[128];
+
+    procmem = fopen("/proc/meminfo", "r");
+    if (!procmem)
+        return NULL;
+    mi = g_new0(MemoryInfo, 1);
+
+    while (fgets(buffer, 128, procmem)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+        if (tmp[1] == NULL) {
+            g_strfreev(tmp);
+            continue;
+        }
+        tmp[0] = g_strstrip(tmp[0]);
+        tmp[1] = g_strstrip(tmp[1]);
+
+        get_int("MemTotal", mi->total);
+        get_int("MemFree", mi->free);
+        get_int("Cached", mi->cached);
+
+        g_strfreev(tmp);
+    }
+    fclose(procmem);
+
+    mi->used = mi->total - mi->free;
+
+    mi->total  /= 1000;
+    mi->cached /= 1000;
+    mi->used   /= 1000;
+    mi->free   /= 1000;
+
+    mi->used -= mi->cached;
+    mi->ratio = 1 - (gdouble) mi->used / mi->total;
+
+    return mi;
+}
diff --git a/modules/computer/modules.c b/modules/computer/modules.c
new file mode 100644
index 0000000..df876e3
--- /dev/null
+++ b/modules/computer/modules.c
@@ -0,0 +1,177 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "hardinfo.h"
+#include "computer.h"
+#include "cpu_util.h" /* for STRIFNULL() */
+
+#define GET_STR(field_name,ptr)      					\
+  if (!ptr && strstr(tmp[0], field_name)) {				\
+    ptr = g_markup_escape_text(g_strstrip(tmp[1]), strlen(tmp[1]));	\
+    g_strfreev(tmp);                 					\
+    continue;                        					\
+  }
+
+GHashTable *_module_hash_table = NULL;
+
+void
+scan_modules_do(void)
+{
+    FILE *lsmod;
+    gchar buffer[1024];
+    gchar *lsmod_path;
+
+    if (!_module_hash_table) {
+        _module_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
+    }
+
+    g_free(module_list);
+
+    module_list = NULL;
+    moreinfo_del_with_prefix("COMP:MOD");
+
+    lsmod_path = find_program("lsmod");
+    if (!lsmod_path)
+        return;
+    lsmod = popen(lsmod_path, "r");
+    if (!lsmod) {
+        g_free(lsmod_path);
+	return;
+    }
+
+    (void)fgets(buffer, 1024, lsmod);	/* Discards the first line */
+
+    while (fgets(buffer, 1024, lsmod)) {
+	gchar *buf, *strmodule, *hashkey;
+	gchar *author = NULL,
+	    *description = NULL,
+	    *license = NULL,
+	    *deps = NULL, *vermagic = NULL, *filename = NULL, modname[64];
+	FILE *modi;
+	glong memory;
+
+	shell_status_pulse();
+
+	buf = buffer;
+
+	sscanf(buf, "%s %ld", modname, &memory);
+
+	hashkey = g_strdup_printf("MOD%s", modname);
+	buf = g_strdup_printf("/sbin/modinfo %s 2>/dev/null", modname);
+
+	modi = popen(buf, "r");
+	while (fgets(buffer, 1024, modi)) {
+	    gchar **tmp = g_strsplit(buffer, ":", 2);
+
+	    GET_STR("author", author);
+	    GET_STR("description", description);
+	    GET_STR("license", license);
+	    GET_STR("depends", deps);
+	    GET_STR("vermagic", vermagic);
+	    GET_STR("filename", filename);
+
+	    g_strfreev(tmp);
+	}
+	pclose(modi);
+	g_free(buf);
+
+	/* old modutils includes quotes in some strings; strip them */
+	/*remove_quotes(modname);
+	   remove_quotes(description);
+	   remove_quotes(vermagic);
+	   remove_quotes(author);
+	   remove_quotes(license); */
+
+	/* old modutils displays <none> when there's no value for a
+	   given field; this is not desirable in the module name
+	   display, so change it to an empty string */
+	if (description && g_str_equal(description, "&lt;none&gt;")) {
+	    g_free(description);
+	    description = g_strdup("");
+
+            g_hash_table_insert(_module_hash_table,
+                                g_strdup(modname),
+                                g_strdup_printf("Kernel module (%s)", modname));
+	} else {
+            g_hash_table_insert(_module_hash_table,
+                                g_strdup(modname),
+                                g_strdup(description));
+        }
+
+	/* append this module to the list of modules */
+	module_list = h_strdup_cprintf("$%s$%s=%s\n",
+				      module_list,
+				      hashkey,
+				      modname,
+				      description ? description : "");
+
+    STRIFNULL(filename, _("(Not available)") );
+    STRIFNULL(description, _("(Not available)") );
+    STRIFNULL(vermagic, _("(Not available)") );
+    STRIFNULL(author, _("(Not available)") );
+    STRIFNULL(license, _("(Not available)") );
+
+    /* create the module information string */
+    strmodule = g_strdup_printf("[%s]\n"
+                        "%s=%s\n"
+                        "%s=%.2f %s\n"
+                        "[%s]\n"
+                        "%s=%s\n"
+                        "%s=%s\n"
+                        "%s=%s\n"
+                        "[%s]\n"
+                        "%s=%s\n"
+                        "%s=%s\n",
+                        _("Module Information"),
+                        _("Path"), filename,
+                        _("Used Memory"), memory / 1024.0, _("KiB"),
+                        _("Description"),
+                        _("Name"), modname,
+                        _("Description"), description,
+                        _("Version Magic"), vermagic,
+                        _("Copyright"),
+                        _("Author"), author,
+                        _("License"), license );
+
+    /* if there are dependencies, append them to that string */
+    if (deps && strlen(deps)) {
+        gchar **tmp = g_strsplit(deps, ",", 0);
+
+        strmodule = h_strconcat(strmodule,
+                                "\n[", _("Dependencies"), "]\n",
+                                g_strjoinv("=\n", tmp),
+                                "=\n", NULL);
+        g_strfreev(tmp);
+        g_free(deps);
+    }
+
+	moreinfo_add_with_prefix("COMP", hashkey, strmodule);
+	g_free(hashkey);
+
+	g_free(license);
+	g_free(description);
+	g_free(author);
+	g_free(vermagic);
+	g_free(filename);
+    }
+    pclose(lsmod);
+
+    g_free(lsmod_path);
+}
diff --git a/modules/computer/os.c b/modules/computer/os.c
new file mode 100644
index 0000000..a8886f6
--- /dev/null
+++ b/modules/computer/os.c
@@ -0,0 +1,393 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <gdk/gdkx.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include "hardinfo.h"
+#include "computer.h"
+
+static gchar *
+get_libc_version(void)
+{
+    static const struct {
+        const char *test_cmd;
+        const char *match_str;
+        const char *lib_name;
+        gboolean try_ver_str;
+        gboolean use_stderr;
+    } libs[] = {
+        { "ldd --version", "GLIBC", N_("GNU C Library"), TRUE, FALSE},
+        { "ldd --version", "GNU libc", N_("GNU C Library"), TRUE, FALSE},
+        { "ldconfig -V", "GLIBC", N_("GNU C Library"), TRUE, FALSE},
+        { "ldconfig -V", "GNU libc", N_("GNU C Library"), TRUE, FALSE},
+        { "ldconfig -v", "uClibc", N_("uClibc or uClibc-ng"), FALSE, FALSE},
+        { "diet", "diet version", N_("diet libc"), TRUE, TRUE},
+        { NULL }
+    };
+    int i;
+
+    for (i = 0; libs[i].test_cmd; i++) {
+        gboolean spawned;
+        gchar *out, *err, *p;
+
+        spawned = g_spawn_command_line_sync(libs[i].test_cmd,
+            &out, &err, NULL, NULL);
+        if (!spawned)
+            continue;
+
+        if (libs[i].use_stderr) {
+            p = strend(idle_free(err), '\n');
+            g_free(out);
+        } else {
+            p = strend(idle_free(out), '\n');
+            g_free(err);
+        }
+
+        if (!p || !strstr(p, libs[i].match_str))
+            continue;
+
+        if (libs[i].try_ver_str) {
+            /* skip the first word, likely "ldconfig" or name of utility */
+            const gchar *ver_str = strchr(p, ' ');
+
+            if (ver_str) {
+                return g_strdup_printf("%s / %s", _(libs[i].lib_name),
+                    ver_str + 1);
+            }
+        }
+
+	return g_strdup(_(libs[i].lib_name));
+    }
+
+    return g_strdup(_("Unknown"));
+}
+
+static gchar *detect_kde_version(void)
+{
+    const gchar *cmd;
+    const gchar *tmp = g_getenv("KDE_SESSION_VERSION");
+    gchar *out;
+    gboolean spawned;
+
+    if (tmp && tmp[0] == '4') {
+        cmd = "kwin --version";
+    } else {
+        cmd = "kcontrol --version";
+    }
+
+    spawned = g_spawn_command_line_sync(cmd, &out, NULL, NULL, NULL);
+    if (!spawned)
+        return NULL;
+
+    tmp = strstr(idle_free(out), "KDE: ");
+    return tmp ? g_strdup(tmp + strlen("KDE: ")) : NULL;
+}
+
+static gchar *
+detect_gnome_version(void)
+{
+    gchar *tmp;
+    gchar *out;
+    gboolean spawned;
+
+    spawned = g_spawn_command_line_sync(
+        "gnome-shell --version", &out, NULL, NULL, NULL);
+    if (spawned) {
+        tmp = strstr(idle_free(out), _("GNOME Shell "));
+
+        if (tmp) {
+            tmp += strlen(_("GNOME Shell "));
+            return g_strdup_printf("GNOME %s", strend(tmp, '\n'));
+        }
+    }
+
+    spawned = g_spawn_command_line_sync(
+        "gnome-about --gnome-version", &out, NULL, NULL, NULL);
+    if (spawned) {
+        tmp = strstr(idle_free(out), _("Version: "));
+
+        if (tmp) {
+            tmp += strlen(_("Version: "));
+            return g_strdup_printf("GNOME %s", strend(tmp, '\n'));
+        }
+    }
+
+    return NULL;
+}
+
+static gchar *
+detect_window_manager(void)
+{
+    GdkScreen *screen = gdk_screen_get_default();
+    const gchar *windowman;
+    const gchar *curdesktop;
+
+    if (!screen || !GDK_IS_SCREEN(screen))
+        return NULL;
+
+    windowman = gdk_x11_screen_get_window_manager_name(screen);
+
+    if (g_str_equal(windowman, "Xfwm4"))
+        return g_strdup("XFCE 4");
+
+    curdesktop = g_getenv("XDG_CURRENT_DESKTOP");
+    if (curdesktop) {
+        const gchar *desksession = g_getenv("DESKTOP_SESSION");
+
+        if (desksession && !g_str_equal(curdesktop, desksession))
+            return g_strdup(desksession);
+    }
+
+    return g_strdup_printf(_("Unknown (Window Manager: %s)"), windowman);
+}
+
+static gchar *
+desktop_with_session_type(const gchar *desktop_env)
+{
+    const char *tmp;
+
+    tmp = g_getenv("XDG_SESSION_TYPE");
+    if (tmp) {
+        if (!g_str_equal(tmp, "unspecified"))
+            return g_strdup_printf(_(/*/{desktop environment} on {session type}*/ "%s on %s"), desktop_env, tmp);
+    }
+
+    return g_strdup(desktop_env);
+}
+
+static gchar *
+detect_xdg_environment(const gchar *env_var)
+{
+    const gchar *tmp;
+
+    tmp = g_getenv(env_var);
+    if (!tmp)
+        return NULL;
+
+    if (g_str_equal(tmp, "GNOME") || g_str_equal(tmp, "gnome")) {
+        gchar *maybe_gnome = detect_gnome_version();
+
+        if (maybe_gnome)
+            return maybe_gnome;
+    }
+    if (g_str_equal(tmp, "KDE") || g_str_equal(tmp, "kde")) {
+        gchar *maybe_kde = detect_kde_version();
+
+        if (maybe_kde)
+            return maybe_kde;
+    }
+
+    return g_strdup(tmp);
+}
+
+static gchar *
+detect_desktop_environment(void)
+{
+    const gchar *tmp;
+    gchar *windowman;
+
+    windowman = detect_xdg_environment("XDG_CURRENT_DESKTOP");
+    if (windowman)
+        return windowman;
+    windowman = detect_xdg_environment("XDG_SESSION_DESKTOP");
+    if (windowman)
+        return windowman;
+
+    tmp = g_getenv("KDE_FULL_SESSION");
+    if (tmp) {
+        gchar *maybe_kde = detect_kde_version();
+
+        if (maybe_kde)
+            return maybe_kde;
+    }
+    tmp = g_getenv("GNOME_DESKTOP_SESSION_ID");
+    if (tmp) {
+        gchar *maybe_gnome = detect_gnome_version();
+
+        if (maybe_gnome)
+            return maybe_gnome;
+    }
+
+    windowman = detect_window_manager();
+    if (windowman)
+        return windowman;
+
+    if (!g_getenv("DISPLAY"))
+        return g_strdup(_("Terminal"));
+
+    return g_strdup(_("Unknown"));
+}
+
+gchar *
+computer_get_entropy_avail(void)
+{
+    gchar tab_entropy_fstr[][32] = {
+      N_(/*/bits of entropy for rng (0)*/              "(None or not available)"),
+      N_(/*/bits of entropy for rng (low/poor value)*/  "%d bits (low)"),
+      N_(/*/bits of entropy for rng (medium value)*/    "%d bits (medium)"),
+      N_(/*/bits of entropy for rng (high/good value)*/ "%d bits (healthy)")
+    };
+    gint bits = h_sysfs_read_int("/proc/sys/kernel/random", "entropy_avail");
+    if (bits > 3000) return g_strdup_printf(_(tab_entropy_fstr[3]), bits);
+    if (bits > 200)  return g_strdup_printf(_(tab_entropy_fstr[2]), bits);
+    if (bits > 1)    return g_strdup_printf(_(tab_entropy_fstr[1]), bits);
+    return g_strdup_printf(_(tab_entropy_fstr[0]), bits);
+}
+
+gchar *
+computer_get_language(void)
+{
+    gchar *tab_lang_env[] =
+        { "LANGUAGE", "LANG", "LC_ALL", "LC_MESSAGES", NULL };
+    gchar *lc = NULL, *env = NULL, *ret = NULL;
+    gint i = 0;
+
+    lc = setlocale(LC_ALL, NULL);
+
+    while (tab_lang_env[i] != NULL) {
+        env = g_strdup( g_getenv(tab_lang_env[i]) );
+        if (env != NULL)  break;
+        i++;
+    }
+
+    if (env != NULL)
+        if (lc != NULL)
+            ret = g_strdup_printf("%s (%s)", lc, env);
+        else
+            ret = g_strdup_printf("%s", env);
+    else
+        if (lc != NULL)
+            ret = g_strdup_printf("%s", lc);
+
+    if (ret == NULL)
+        ret = g_strdup( _("(Unknown)") );
+
+    return ret;
+}
+
+static gchar *
+detect_distro(void)
+{
+    static const struct {
+        const gchar *file;
+        const gchar *codename;
+        const gchar *override;
+    } distro_db[] = {
+#define DB_PREFIX "/etc/"
+        { DB_PREFIX "arch-release", "arch", "Arch Linux" },
+        { DB_PREFIX "fatdog-version", "fatdog" },
+        { DB_PREFIX "debian_version", "deb" },
+        { DB_PREFIX "slackware-version", "slk" },
+        { DB_PREFIX "mandrake-release", "mdk" },
+        { DB_PREFIX "mandriva-release", "mdv" },
+        { DB_PREFIX "fedora-release", "fdra" },
+        { DB_PREFIX "coas", "coas" },
+        { DB_PREFIX "environment.corel", "corel"},
+        { DB_PREFIX "gentoo-release", "gnt" },
+        { DB_PREFIX "conectiva-release", "cnc" },
+        { DB_PREFIX "versão-conectiva", "cnc" },
+        { DB_PREFIX "turbolinux-release", "tl" },
+        { DB_PREFIX "yellowdog-release", "yd" },
+        { DB_PREFIX "sabayon-release", "sbn" },
+        { DB_PREFIX "arch-release", "arch" },
+        { DB_PREFIX "enlisy-release", "enlsy" },
+        { DB_PREFIX "SuSE-release", "suse" },
+        { DB_PREFIX "sun-release", "sun" },
+        { DB_PREFIX "zenwalk-version", "zen" },
+        { DB_PREFIX "DISTRO_SPECS", "ppy", "Puppy Linux" },
+        { DB_PREFIX "puppyversion", "ppy", "Puppy Linux" },
+        { DB_PREFIX "distro-release", "fl" },
+        { DB_PREFIX "vine-release", "vine" },
+        { DB_PREFIX "PartedMagic-version", "pmag" },
+         /*
+         * RedHat must be the *last* one to be checked, since
+         * some distros (like Mandrake) includes a redhat-relase
+         * file too.
+         */
+        { DB_PREFIX "redhat-release", "rh" },
+#undef DB_PREFIX
+        { NULL, NULL }
+    };
+    gchar *contents;
+    int i;
+
+    if (g_spawn_command_line_sync("lsb_release -d", &contents, NULL, NULL, NULL)) {
+        gchar *tmp = strstr(idle_free(contents), "Description:\t");
+
+        if (tmp)
+            return g_strdup(tmp + strlen("Description:\t"));
+    }
+
+    for (i = 0; distro_db[i].file; i++) {
+        if (!g_file_get_contents(distro_db[i].file, &contents, NULL, NULL))
+            continue;
+
+        if (distro_db[i].override) {
+            g_free(contents);
+            return g_strdup(distro_db[i].override);
+        }
+
+        if (g_str_equal(distro_db[i].codename, "deb")) {
+            /* HACK: Some Debian systems doesn't include the distribuition
+             * name in /etc/debian_release, so add them here. */
+            if (isdigit(contents[0]) || contents[0] != 'D')
+                return g_strdup_printf("Debian GNU/Linux %s", (char*)idle_free(contents));
+        }
+
+        if (g_str_equal(distro_db[i].codename, "fatdog"))
+            return g_strdup_printf("Fatdog64 [%.10s]", (char*)idle_free(contents));
+
+        return contents;
+    }
+
+    return g_strdup(_("Unknown"));
+}
+
+OperatingSystem *
+computer_get_os(void)
+{
+    struct utsname utsbuf;
+    OperatingSystem *os;
+    int i;
+
+    os = g_new0(OperatingSystem, 1);
+
+    os->distro = g_strstrip(detect_distro());
+
+    /* Kernel and hostname info */
+    uname(&utsbuf);
+    os->kernel_version = g_strdup(utsbuf.version);
+    os->kernel = g_strdup_printf("%s %s (%s)", utsbuf.sysname,
+				 utsbuf.release, utsbuf.machine);
+    os->hostname = g_strdup(utsbuf.nodename);
+    os->language = computer_get_language();
+    os->homedir = g_strdup(g_get_home_dir());
+    os->username = g_strdup_printf("%s (%s)",
+				   g_get_user_name(), g_get_real_name());
+    os->libc = get_libc_version();
+    scan_languages(os);
+
+    os->desktop = detect_desktop_environment();
+    if (os->desktop)
+        os->desktop = desktop_with_session_type(idle_free(os->desktop));
+
+    os->entropy_avail = computer_get_entropy_avail();
+
+    return os;
+}
diff --git a/modules/computer/uptime.c b/modules/computer/uptime.c
new file mode 100644
index 0000000..6ef3d25
--- /dev/null
+++ b/modules/computer/uptime.c
@@ -0,0 +1,72 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#include "hardinfo.h"
+#include "computer.h"
+
+UptimeInfo *
+computer_get_uptime(void)
+{
+    UptimeInfo *ui = g_new0(UptimeInfo, 1);
+    FILE *procuptime;
+    gulong minutes;
+
+    if ((procuptime = fopen("/proc/uptime", "r")) != NULL) {
+        (void)fscanf(procuptime, "%lu", &minutes);
+        ui->minutes = minutes / 60;
+        fclose(procuptime);
+    } else {
+        g_free(ui);
+        return NULL;
+    }
+
+    ui->hours = ui->minutes / 60;
+    ui->minutes %= 60;
+    ui->days = ui->hours / 24;
+    ui->hours %= 24;
+
+    return ui;
+}
+
+gchar *
+computer_get_formatted_uptime()
+{
+    UptimeInfo *ui;
+    const gchar *days_fmt, *hours_fmt, *minutes_fmt;
+    gchar *full_fmt = NULL, *ret = NULL;
+
+    ui = computer_get_uptime();
+
+    days_fmt = ngettext("%d day", "%d days", ui->days);
+    hours_fmt = ngettext("%d hour", "%d hours", ui->hours);
+    minutes_fmt = ngettext("%d minute", "%d minutes", ui->minutes);
+
+    if (ui->days < 1) {
+        if (ui->hours < 1) {
+            ret = g_strdup_printf(minutes_fmt, ui->minutes);
+        } else {
+            full_fmt = g_strdup_printf("%s %s", hours_fmt, minutes_fmt);
+            ret = g_strdup_printf(full_fmt, ui->hours, ui->minutes);
+        }
+    } else {
+        full_fmt = g_strdup_printf("%s %s %s", days_fmt, hours_fmt, minutes_fmt);
+        ret = g_strdup_printf(full_fmt, ui->days, ui->hours, ui->minutes);
+    }
+    g_free(full_fmt);
+    g_free(ui);
+    return ret;
+}
diff --git a/modules/computer/users.c b/modules/computer/users.c
new file mode 100644
index 0000000..f47320b
--- /dev/null
+++ b/modules/computer/users.c
@@ -0,0 +1,61 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <pwd.h>
+#include "hardinfo.h"
+#include "computer.h"
+
+gchar *users = NULL;
+
+void
+scan_users_do(void)
+{
+    struct passwd *passwd_;
+    passwd_ = getpwent();
+    if (!passwd_)
+        return;
+
+    if (users) {
+        g_free(users);
+        moreinfo_del_with_prefix("COMP:USER");
+    }
+
+    users = g_strdup("");
+
+    while (passwd_) {
+        gchar *key = g_strdup_printf("USER%s", passwd_->pw_name);
+        gchar *val = g_strdup_printf("[%s]\n"
+                "%s=%d\n"
+                "%s=%d\n"
+                "%s=%s\n"
+                "%s=%s\n",
+                _("User Information"),
+                _("User ID"), (gint) passwd_->pw_uid,
+                _("Group ID"), (gint) passwd_->pw_gid,
+                _("Home Directory"), passwd_->pw_dir,
+                _("Default Shell"), passwd_->pw_shell);
+        moreinfo_add_with_prefix("COMP", key, val);
+
+        strend(passwd_->pw_gecos, ',');
+        users = h_strdup_cprintf("$%s$%s=%s\n", users, key, passwd_->pw_name, passwd_->pw_gecos);
+        passwd_ = getpwent();
+        g_free(key);
+    }
+
+    endpwent();
+}
diff --git a/modules/devices.c b/modules/devices.c
new file mode 100644
index 0000000..152b683
--- /dev/null
+++ b/modules/devices.c
@@ -0,0 +1,725 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __USE_XOPEN
+#define __USE_XOPEN
+#endif /* __USE_XOPEN */
+
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE
+#endif /* _XOPEN_SOURCE */
+
+#include <gtk/gtk.h>
+#include <config.h>
+#include <string.h>
+
+#include <hardinfo.h>
+#include <shell.h>
+#include <iconcache.h>
+#include <syncmanager.h>
+
+#include <expr.h>
+#include <socket.h>
+
+#include "devices.h"
+#include "dt_util.h"
+
+gchar *callback_processors();
+gchar *callback_memory();
+gchar *callback_battery();
+gchar *callback_pci();
+gchar *callback_sensors();
+gchar *callback_printers();
+gchar *callback_storage();
+gchar *callback_input();
+gchar *callback_usb();
+#if defined(ARCH_x86) || defined(ARCH_x86_64)
+gchar *callback_dmi();
+gchar *callback_spd();
+#endif
+gchar *callback_dtree();
+gchar *callback_device_resources();
+
+void scan_processors(gboolean reload);
+void scan_memory(gboolean reload);
+void scan_battery(gboolean reload);
+void scan_pci(gboolean reload);
+void scan_sensors(gboolean reload);
+void scan_printers(gboolean reload);
+void scan_storage(gboolean reload);
+void scan_input(gboolean reload);
+void scan_usb(gboolean reload);
+#if defined(ARCH_x86) || defined(ARCH_x86_64)
+void scan_dmi(gboolean reload);
+void scan_spd(gboolean reload);
+#endif
+void scan_dtree(gboolean reload);
+void scan_device_resources(gboolean reload);
+
+gboolean root_required_for_resources(void);
+
+gchar *hi_more_info(gchar *entry);
+
+enum {
+    ENTRY_DTREE,
+    ENTRY_PROCESSOR,
+    ENTRY_MEMORY,
+    ENTRY_PCI,
+    ENTRY_USB,
+    ENTRY_PRINTERS,
+    ENTRY_BATTERY,
+    ENTRY_SENSORS,
+    ENTRY_INPUT,
+    ENTRY_STORAGE,
+    ENTRY_DMI,
+    ENTRY_SPD,
+    ENTRY_RESOURCES
+};
+
+static ModuleEntry entries[] = {
+    [ENTRY_PROCESSOR] = {N_("Processor"), "processor.png", callback_processors, scan_processors, MODULE_FLAG_NONE},
+    [ENTRY_MEMORY] = {N_("Memory"), "memory.png", callback_memory, scan_memory, MODULE_FLAG_NONE},
+    [ENTRY_PCI] = {N_("PCI Devices"), "devices.png", callback_pci, scan_pci, MODULE_FLAG_NONE},
+    [ENTRY_USB] = {N_("USB Devices"), "usb.png", callback_usb, scan_usb, MODULE_FLAG_NONE},
+    [ENTRY_PRINTERS] = {N_("Printers"), "printer.png", callback_printers, scan_printers, MODULE_FLAG_NONE},
+    [ENTRY_BATTERY] = {N_("Battery"), "battery.png", callback_battery, scan_battery, MODULE_FLAG_NONE},
+    [ENTRY_SENSORS] = {N_("Sensors"), "therm.png", callback_sensors, scan_sensors, MODULE_FLAG_NONE},
+    [ENTRY_INPUT] = {N_("Input Devices"), "inputdevices.png", callback_input, scan_input, MODULE_FLAG_NONE},
+    [ENTRY_STORAGE] = {N_("Storage"), "hdd.png", callback_storage, scan_storage, MODULE_FLAG_NONE},
+#if defined(ARCH_x86) || defined(ARCH_x86_64)
+    [ENTRY_DMI] = {N_("DMI"), "computer.png", callback_dmi, scan_dmi, MODULE_FLAG_NONE},
+    [ENTRY_SPD] = {N_("Memory SPD"), "memory.png", callback_spd, scan_spd, MODULE_FLAG_NONE},
+    [ENTRY_DTREE] = {"#"},
+#else
+    [ENTRY_DMI] = {"#"},
+    [ENTRY_SPD] = {"#"},
+    [ENTRY_DTREE] = {N_("Device Tree"), "devices.png", callback_dtree, scan_dtree, MODULE_FLAG_NONE},
+#endif	/* x86 or x86_64 */
+    [ENTRY_RESOURCES] = {N_("Resources"), "resources.png", callback_device_resources, scan_device_resources, MODULE_FLAG_NONE},
+    { NULL }
+};
+
+static GSList *processors = NULL;
+gchar *printer_list = NULL;
+gchar *printer_icons = NULL;
+gchar *pci_list = NULL;
+gchar *input_list = NULL;
+gchar *storage_list = NULL;
+gchar *battery_list = NULL;
+gchar *meminfo = NULL;
+gchar *lginterval = NULL;
+
+#include <vendor.h>
+
+static gint proc_cmp_model_name(Processor *a, Processor *b) {
+    return g_strcmp0(a->model_name, b->model_name);
+}
+
+static gint proc_cmp_max_freq(Processor *a, Processor *b) {
+    if (a->cpu_mhz == b->cpu_mhz)
+        return 0;
+    if (a->cpu_mhz > b->cpu_mhz)
+        return -1;
+    return 1;
+}
+
+gchar *processor_describe_default(GSList * processors)
+{
+    int packs, cores, threads;
+    const gchar  *packs_fmt, *cores_fmt, *threads_fmt;
+    gchar *ret, *full_fmt;
+
+    cpu_procs_cores_threads(&packs, &cores, &threads);
+
+    /* if topology info was available, else fallback to old method */
+    if (cores > 0) {
+        packs_fmt = ngettext("%d physical processor", "%d physical processors", packs);
+        cores_fmt = ngettext("%d core", "%d cores", cores);
+        threads_fmt = ngettext("%d thread", "%d threads", threads);
+        full_fmt = g_strdup_printf(_(/*/NP procs; NC cores; NT threads*/ "%s; %s; %s"), packs_fmt, cores_fmt, threads_fmt);
+        ret = g_strdup_printf(full_fmt, packs, cores, threads);
+        g_free(full_fmt);
+        return ret;
+    } else {
+        return processor_describe_by_counting_names(processors);
+    }
+}
+
+gchar *processor_name_default(GSList * processors)
+{
+    gchar *ret = g_strdup("");
+    GSList *tmp, *l;
+    Processor *p;
+    gchar *cur_str = NULL;
+    gint cur_count = 0;
+
+    tmp = g_slist_copy(processors);
+    tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_model_name);
+
+    for (l = tmp; l; l = l->next) {
+        p = (Processor*)l->data;
+        if (cur_str == NULL) {
+            cur_str = p->model_name;
+            cur_count = 1;
+        } else {
+            if(g_strcmp0(cur_str, p->model_name)) {
+                ret = h_strdup_cprintf("%s%s", ret, strlen(ret) ? "; " : "", cur_str);
+                cur_str = p->model_name;
+                cur_count = 1;
+            } else {
+                cur_count++;
+            }
+        }
+    }
+    ret = h_strdup_cprintf("%s%s", ret, strlen(ret) ? "; " : "", cur_str);
+    g_slist_free(tmp);
+    return ret;
+}
+
+/* TODO: prefix counts are threads when they should be cores. */
+gchar *processor_describe_by_counting_names(GSList * processors)
+{
+    gchar *ret = g_strdup("");
+    GSList *tmp, *l;
+    Processor *p;
+    gchar *cur_str = NULL;
+    gint cur_count = 0;
+
+    tmp = g_slist_copy(processors);
+    tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_model_name);
+
+    for (l = tmp; l; l = l->next) {
+        p = (Processor*)l->data;
+        if (cur_str == NULL) {
+            cur_str = p->model_name;
+            cur_count = 1;
+        } else {
+            if(g_strcmp0(cur_str, p->model_name)) {
+                ret = h_strdup_cprintf("%s%dx %s", ret, strlen(ret) ? " + " : "", cur_count, cur_str);
+                cur_str = p->model_name;
+                cur_count = 1;
+            } else {
+                cur_count++;
+            }
+        }
+    }
+    ret = h_strdup_cprintf("%s%dx %s", ret, strlen(ret) ? " + " : "", cur_count, cur_str);
+    g_slist_free(tmp);
+    return ret;
+}
+
+gchar *get_processor_name(void)
+{
+    scan_processors(FALSE);
+    return processor_name(processors);
+}
+
+gchar *get_processor_desc(void)
+{
+    scan_processors(FALSE);
+    return processor_describe(processors);
+}
+
+gchar *get_processor_name_and_desc(void)
+{
+    scan_processors(FALSE);
+    gchar* name = processor_name(processors);
+    gchar* desc = processor_describe(processors);
+    gchar* nd = g_strdup_printf("%s\n%s", name, desc);
+    g_free(name);
+    g_free(desc);
+    return nd;
+}
+
+
+gchar *get_storage_devices(void)
+{
+    scan_storage(FALSE);
+
+    return storage_list;
+}
+
+gchar *get_printers(void)
+{
+    scan_printers(FALSE);
+
+    return printer_list;
+}
+
+gchar *get_input_devices(void)
+{
+    scan_input(FALSE);
+
+    return input_list;
+}
+
+gchar *get_processor_count(void)
+{
+    scan_processors(FALSE);
+
+    return g_strdup_printf("%d", g_slist_length(processors));
+}
+
+/* TODO: maybe move into processor.c along with processor_name() etc.
+ * Could mention the big.LITTLE cluster arangement for ARM that kind of thing.
+ * TODO: prefix counts are threads when they should be cores. */
+gchar *processor_frequency_desc(GSList * processors)
+{
+    gchar *ret = g_strdup("");
+    GSList *tmp, *l;
+    Processor *p;
+    float cur_val = -1;
+    gint cur_count = 0;
+
+    tmp = g_slist_copy(processors);
+    tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_max_freq);
+
+    for (l = tmp; l; l = l->next) {
+        p = (Processor*)l->data;
+        if (cur_val == -1) {
+            cur_val = p->cpu_mhz;
+            cur_count = 1;
+        } else {
+            if(cur_val != p->cpu_mhz) {
+                ret = h_strdup_cprintf("%s%dx %.2f %s", ret, strlen(ret) ? " + " : "", cur_count, cur_val, _("MHz") );
+                cur_val = p->cpu_mhz;
+                cur_count = 1;
+            } else {
+                cur_count++;
+            }
+        }
+    }
+    ret = h_strdup_cprintf("%s%dx %.2f %s", ret, strlen(ret) ? " + " : "", cur_count, cur_val, _("MHz"));
+    g_slist_free(tmp);
+    return ret;
+}
+
+gchar *get_processor_frequency_desc(void)
+{
+    scan_processors(FALSE);
+    return processor_frequency_desc(processors);
+}
+
+gchar *get_processor_max_frequency(void)
+{
+    GSList *l;
+    Processor *p;
+    float max_freq = 0;
+
+    scan_processors(FALSE);
+
+    for (l = processors; l; l = l->next) {
+        p = (Processor*)l->data;
+        if (p->cpu_mhz > max_freq)
+            max_freq = p->cpu_mhz;
+    }
+
+    if (max_freq == 0.0f) {
+        return g_strdup(N_("Unknown"));
+    } else {
+        return g_strdup_printf("%.2f %s", max_freq, _("MHz") );
+    }
+}
+
+gchar *get_pci_device_description(gchar *pci_id)
+{
+    gchar *description;
+
+    if (!_pci_devices) {
+        scan_pci(FALSE);
+    }
+
+    if ((description = g_hash_table_lookup(_pci_devices, pci_id))) {
+        return g_strdup(description);
+    }
+
+    return NULL;
+}
+
+gchar *get_memory_total(void)
+{
+    scan_memory(FALSE);
+    return moreinfo_lookup ("DEV:MemTotal");
+}
+
+gchar *get_motherboard(void)
+{
+    char *board_name, *board_vendor, *system_version;
+    char *ret;
+
+#if defined(ARCH_x86) || defined(ARCH_x86_64)
+    scan_dmi(FALSE);
+
+    board_name = dmi_get_str("baseboard-product-name");
+    if (board_name == NULL)
+        board_name = dmi_get_str("system-product-name");
+
+    board_vendor = dmi_get_str("baseboard-manufacturer");
+    if (board_vendor == NULL)
+        board_vendor = dmi_get_str("system-manufacturer");
+
+    system_version = dmi_get_str("system-version");
+
+    if (board_name && board_vendor && system_version)
+        ret = g_strdup_printf("%s / %s (%s)", system_version, board_name, board_vendor);
+    else if (board_name && board_vendor)
+        ret = g_strconcat(board_vendor, " ", board_name, NULL);
+    else if (board_name)
+        ret = g_strdup(board_name);
+    else if (board_vendor)
+        ret = g_strdup(board_vendor);
+    else
+        ret = g_strdup(_("(Unknown)"));
+
+    free(board_name);
+    free(board_vendor);
+    free(system_version);
+    return ret;
+#endif
+
+    /* use device tree "model" */
+    board_vendor = dtr_get_string("/model", 0);
+    if (board_vendor != NULL)
+        return board_vendor;
+
+    return g_strdup(_("Unknown"));
+}
+
+ShellModuleMethod *hi_exported_methods(void)
+{
+    static ShellModuleMethod m[] = {
+	{"getProcessorCount", get_processor_count},
+	{"getProcessorName", get_processor_name},
+	{"getProcessorDesc", get_processor_desc},
+	{"getProcessorNameAndDesc", get_processor_name_and_desc},
+	{"getProcessorFrequency", get_processor_max_frequency},
+	{"getProcessorFrequencyDesc", get_processor_frequency_desc},
+	{"getMemoryTotal", get_memory_total},
+	{"getStorageDevices", get_storage_devices},
+	{"getPrinters", get_printers},
+	{"getInputDevices", get_input_devices},
+	{"getPCIDeviceDescription", get_pci_device_description},
+	{"getMotherboard", get_motherboard},
+	{NULL}
+    };
+
+    return m;
+}
+
+gchar *hi_more_info(gchar * entry)
+{
+    gchar *info = moreinfo_lookup_with_prefix("DEV", entry);
+
+    if (info)
+	return g_strdup(info);
+
+    return g_strdup("?");
+}
+
+gchar *hi_get_field(gchar * field)
+{
+    gchar *info = moreinfo_lookup_with_prefix("DEV", field);
+
+    if (info)
+	return g_strdup(info);
+
+    return g_strdup(field);
+}
+
+#if defined(ARCH_x86) || defined(ARCH_x86_64)
+void scan_dmi(gboolean reload)
+{
+    SCAN_START();
+    __scan_dmi();
+    SCAN_END();
+}
+
+void scan_spd(gboolean reload)
+{
+    SCAN_START();
+    scan_spd_do();
+    SCAN_END();
+}
+#endif
+
+void scan_dtree(gboolean reload)
+{
+    SCAN_START();
+    __scan_dtree();
+    SCAN_END();
+}
+
+void scan_processors(gboolean reload)
+{
+    SCAN_START();
+    if (!processors)
+	processors = processor_scan();
+    SCAN_END();
+}
+
+void scan_memory(gboolean reload)
+{
+    SCAN_START();
+    scan_memory_do();
+    SCAN_END();
+}
+
+void scan_battery(gboolean reload)
+{
+    SCAN_START();
+    scan_battery_do();
+    SCAN_END();
+}
+
+void scan_pci(gboolean reload)
+{
+    SCAN_START();
+    scan_pci_do();
+    SCAN_END();
+}
+
+void scan_sensors(gboolean reload)
+{
+    SCAN_START();
+    scan_sensors_do();
+    SCAN_END();
+}
+
+void scan_printers(gboolean reload)
+{
+    SCAN_START();
+    scan_printers_do();
+    SCAN_END();
+}
+
+void scan_storage(gboolean reload)
+{
+    SCAN_START();
+    g_free(storage_list);
+    storage_list = g_strdup("");
+
+    __scan_ide_devices();
+    __scan_scsi_devices();
+    SCAN_END();
+}
+
+void scan_input(gboolean reload)
+{
+    SCAN_START();
+    __scan_input_devices();
+    SCAN_END();
+}
+
+void scan_usb(gboolean reload)
+{
+    SCAN_START();
+    __scan_usb();
+    SCAN_END();
+}
+
+gchar *callback_processors()
+{
+    return processor_get_info(processors);
+}
+
+#if defined(ARCH_x86) || defined(ARCH_x86_64)
+gchar *callback_dmi()
+{
+    return g_strdup(dmi_info);
+}
+
+gchar *callback_spd()
+{
+    return g_strdup(spd_info);
+}
+#endif
+
+gchar *callback_dtree()
+{
+    return g_strdup_printf("%s"
+        "[$ShellParam$]\n"
+        "ViewType=1\n", dtree_info);
+}
+
+gchar *callback_memory()
+{
+    return g_strdup_printf("[Memory]\n"
+               "%s\n"
+               "[$ShellParam$]\n"
+               "ViewType=2\n"
+               "LoadGraphSuffix= kB\n"
+               "RescanInterval=2000\n"
+               "ColumnTitle$TextValue=%s\n"
+               "ColumnTitle$Extra1=%s\n"
+               "ColumnTitle$Value=%s\n"
+               "ShowColumnHeaders=true\n"
+               "%s\n", meminfo,
+               _("Field"), _("Description"), _("Value"), /* column labels */
+               lginterval);
+}
+
+gchar *callback_battery()
+{
+    return g_strdup_printf("%s\n"
+			   "[$ShellParam$]\n"
+			   "ReloadInterval=4000\n", battery_list);
+}
+
+gchar *callback_pci()
+{
+    return g_strdup_printf("[PCI Devices]\n"
+			   "%s"
+			   "[$ShellParam$]\n" "ViewType=1\n", pci_list);
+}
+
+gchar *callback_sensors()
+{
+    return g_strdup_printf("[Sensors]\n"
+                           "%s\n"
+                           "[$ShellParam$]\n"
+                           "ViewType=2\n"
+                           "LoadGraphSuffix=\n"
+                           "ColumnTitle$TextValue=%s\n"
+                           "ColumnTitle$Value=%s\n"
+                           "ColumnTitle$Extra1=%s\n"
+                           "ShowColumnHeaders=true\n"
+                           "RescanInterval=5000\n"
+                           "%s",
+                           sensors,
+                           _("Sensor"), _("Value"), _("Type"), /* column labels */
+                           lginterval);
+}
+
+gchar *callback_printers()
+{
+    return g_strdup_printf("%s\n"
+                           "[$ShellParam$]\n"
+                           "ViewType=1\n"
+			   "ReloadInterval=5000\n"
+			   "%s", printer_list, printer_icons);
+}
+
+gchar *callback_storage()
+{
+    return g_strdup_printf("%s\n"
+			   "[$ShellParam$]\n"
+			   "ReloadInterval=5000\n"
+			   "ViewType=1\n%s", storage_list, storage_icons);
+}
+
+gchar *callback_input()
+{
+    return g_strdup_printf("[Input Devices]\n"
+			   "%s"
+			   "[$ShellParam$]\n"
+			   "ViewType=1\n"
+			   "ReloadInterval=5000\n%s", input_list,
+			   input_icons);
+}
+
+gchar *callback_usb()
+{
+    return g_strdup_printf("%s"
+			   "[$ShellParam$]\n"
+			   "ViewType=1\n"
+			   "ReloadInterval=5000\n", usb_list);
+}
+
+ModuleEntry *hi_module_get_entries(void)
+{
+    return entries;
+}
+
+gchar *hi_module_get_name(void)
+{
+    return g_strdup(_("Devices"));
+}
+
+guchar hi_module_get_weight(void)
+{
+    return 85;
+}
+
+void hi_module_init(void)
+{
+    if (!g_file_test("/usr/share/misc/pci.ids", G_FILE_TEST_EXISTS)) {
+        static SyncEntry se = {
+             .fancy_name = N_("Update PCI ID listing"),
+             .name = "GetPCIIds",
+             .save_to = "pci.ids",
+             .get_data = NULL
+        };
+
+        sync_manager_add_entry(&se);
+    }
+
+#if defined(ARCH_x86) || defined(ARCH_x86_64)
+    {
+      static SyncEntry se = {
+        .fancy_name = N_("Update CPU feature database"),
+        .name = "RecvCPUFlags",
+        .save_to = "cpuflags.conf",
+        .get_data = NULL
+      };
+
+      sync_manager_add_entry(&se);
+    }
+#endif	/* defined(ARCH_x86) */
+
+    init_memory_labels();
+    init_cups();
+    sensors_init();
+}
+
+void hi_module_deinit(void)
+{
+    moreinfo_del_with_prefix("DEV");
+    sensors_shutdown();
+    g_hash_table_destroy(memlabels);
+    g_module_close(cups);
+}
+
+ModuleAbout *hi_module_get_about(void)
+{
+    static ModuleAbout ma[] = {
+	{
+	 .author = "Leandro A. F. Pereira",
+	 .description = N_("Gathers information about hardware devices"),
+	 .version = VERSION,
+	 .license = "GNU GPL version 2"}
+    };
+
+    return ma;
+}
+
+gchar **hi_module_get_dependencies(void)
+{
+    static gchar *deps[] = { "computer.so", NULL };
+
+    return deps;
+}
+
+const gchar *hi_note_func(gint entry)
+{
+    if (entry == ENTRY_RESOURCES) {
+        if (root_required_for_resources()) {
+            return g_strdup(_("Resource information requires superuser privileges"));
+        }
+    }
+    return NULL;
+}
diff --git a/modules/devices/alpha/processor.c b/modules/devices/alpha/processor.c
new file mode 100644
index 0000000..c786223
--- /dev/null
+++ b/modules/devices/alpha/processor.c
@@ -0,0 +1,94 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+
+GSList *
+processor_scan(void)
+{
+    Processor *processor;
+    FILE *cpuinfo;
+    gchar buffer[128];
+    long long hz = 0;
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+        return NULL;
+
+    processor = g_new0(Processor, 1);
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+
+        if (tmp[0] && tmp[1]) {
+            tmp[0] = g_strstrip(tmp[0]);
+            tmp[1] = g_strstrip(tmp[1]);
+
+            get_str("cpu model", processor->model_name);
+            get_float("BogoMIPS", processor->bogomips);
+            get_str("platform string", processor->strmodel);
+            get_str("cycle frequency [Hz]", processor->cycle_frequency_hz_str);
+
+        }
+        g_strfreev(tmp);
+    }
+
+    fclose(cpuinfo);
+
+    gchar *tmp = g_strconcat("Alpha ", processor->model_name, NULL);
+    g_free(processor->model_name);
+    processor->model_name = tmp;
+
+    if (processor->cycle_frequency_hz_str) {
+        hz = atoll(processor->cycle_frequency_hz_str);
+        processor->cpu_mhz = hz;
+        processor->cpu_mhz /= 1000000;
+    } else
+        processor->cpu_mhz = 0.0f;
+
+    return g_slist_append(NULL, processor);
+}
+
+gchar *processor_name(GSList * processors) {
+    return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_default(processors);
+}
+
+gchar *
+processor_get_info(GSList *processors)
+{
+    Processor *processor = (Processor *)processors->data;
+
+    return g_strdup_printf("[%s]\n"
+                        "%s=%s\n"
+                        "%s=%s\n"
+                        "%s=%.2f %s\n" /* frequency */
+                        "%s=%.2f\n"    /* bogomips */
+                        "%s=%s\n",     /* byte order */
+                    _("Processor"),
+                    _("Model"), processor->model_name,
+                    _("Platform String"), processor->strmodel,
+                    _("Frequency"), processor->cpu_mhz, _("MHz"),
+                    _("BogoMips"), processor->bogomips,
+                    _("Byte Order"), byte_order_str()
+                    );
+}
diff --git a/modules/devices/arm/arm_data.c b/modules/devices/arm/arm_data.c
new file mode 100644
index 0000000..60e8ea3
--- /dev/null
+++ b/modules/devices/arm/arm_data.c
@@ -0,0 +1,265 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * Copyright (C) 2017  Burt P. <pburt0@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "arm_data.h"
+
+#ifndef C_
+#define C_(Ctx, String) String
+#endif
+#ifndef NC_
+#define NC_(Ctx, String) String
+#endif
+
+/* sources:
+ *   https://unix.stackexchange.com/a/43563
+ *   git:linux/arch/arm/kernel/setup.c
+ *   git:linux/arch/arm64/kernel/cpuinfo.c
+ */
+static struct {
+    char *name, *meaning;
+} tab_flag_meaning[] = {
+    /* arm/hw_cap */
+    { "swp",      NC_("arm-flag", /*/flag:swp*/      "SWP instruction (atomic read-modify-write)") },
+    { "half",     NC_("arm-flag", /*/flag:half*/     "Half-word loads and stores") },
+    { "thumb",    NC_("arm-flag", /*/flag:thumb*/    "Thumb (16-bit instruction set)") },
+    { "26bit",    NC_("arm-flag", /*/flag:26bit*/    "26-Bit Model (Processor status register folded into program counter)") },
+    { "fastmult", NC_("arm-flag", /*/flag:fastmult*/ "32x32->64-bit multiplication") },
+    { "fpa",      NC_("arm-flag", /*/flag:fpa*/      "Floating point accelerator") },
+    { "vfp",      NC_("arm-flag", /*/flag:vfp*/      "VFP (early SIMD vector floating point instructions)") },
+    { "edsp",     NC_("arm-flag", /*/flag:edsp*/     "DSP extensions (the 'e' variant of the ARM9 CPUs, and all others above)") },
+    { "java",     NC_("arm-flag", /*/flag:java*/     "Jazelle (Java bytecode accelerator)") },
+    { "iwmmxt",   NC_("arm-flag", /*/flag:iwmmxt*/   "SIMD instructions similar to Intel MMX") },
+    { "crunch",   NC_("arm-flag", /*/flag:crunch*/   "MaverickCrunch coprocessor (if kernel support enabled)") },
+    { "thumbee",  NC_("arm-flag", /*/flag:thumbee*/  "ThumbEE") },
+    { "neon",     NC_("arm-flag", /*/flag:neon*/     "Advanced SIMD/NEON on AArch32") },
+    { "evtstrm",  NC_("arm-flag", /*/flag:evtstrm*/  "Kernel event stream using generic architected timer") },
+    { "vfpv3",    NC_("arm-flag", /*/flag:vfpv3*/    "VFP version 3") },
+    { "vfpv3d16", NC_("arm-flag", /*/flag:vfpv3d16*/ "VFP version 3 with 16 D-registers") },
+    { "vfpv4",    NC_("arm-flag", /*/flag:vfpv4*/    "VFP version 4 with fast context switching") },
+    { "vfpd32",   NC_("arm-flag", /*/flag:vfpd32*/   "VFP with 32 D-registers") },
+    { "tls",      NC_("arm-flag", /*/flag:tls*/      "TLS register") },
+    { "idiva",    NC_("arm-flag", /*/flag:idiva*/    "SDIV and UDIV hardware division in ARM mode") },
+    { "idivt",    NC_("arm-flag", /*/flag:idivt*/    "SDIV and UDIV hardware division in Thumb mode") },
+    { "lpae",     NC_("arm-flag", /*/flag:lpae*/     "40-bit Large Physical Address Extension") },
+    /* arm/hw_cap2 */
+    { "pmull",    NC_("arm-flag", /*/flag:pmull*/    "64x64->128-bit F2m multiplication (arch>8)") },
+    { "aes",      NC_("arm-flag", /*/flag:aes*/      "Crypto:AES (arch>8)") },
+    { "sha1",     NC_("arm-flag", /*/flag:sha1*/     "Crypto:SHA1 (arch>8)") },
+    { "sha2",     NC_("arm-flag", /*/flag:sha2*/     "Crypto:SHA2 (arch>8)") },
+    { "crc32",    NC_("arm-flag", /*/flag:crc32*/    "CRC32 checksum instructions (arch>8)") },
+    /* arm64/hw_cap */
+    { "fp",       NULL },
+    { "asimd",    NC_("arm-flag", /*/flag:asimd*/    "Advanced SIMD/NEON on AArch64 (arch>8)") },
+    { "atomics",  NULL },
+    { "fphp",     NULL },
+    { "asimdhp",  NULL },
+    { "cpuid",    NULL },
+    { "asimdrdm", NULL },
+    { "jscvt",    NULL },
+    { "fcma",     NULL },
+    { "lrcpc",    NULL },
+    { NULL, NULL }
+};
+
+static struct {
+    int code; char *name;
+} tab_arm_implementer[] = {
+    { 0x41,	"ARM" },
+    { 0x44,	"Intel (formerly DEC) StrongARM" },
+    { 0x4e,	"nVidia" },
+    { 0x54,	"Texas Instruments" },
+    { 0x56,	"Marvell" },
+    { 0x69,	"Intel XScale" },
+    { 0, NULL},
+};
+
+static struct {
+    /* source: t = tested, d = official docs, f = web */
+    int code; char *part_desc;
+} tab_arm_arm_part[] = { /* only valid for implementer 0x41 ARM */
+    /*d */ { 0x920,	"ARM920" },
+    /*d */ { 0x926,	"ARM926" },
+    /*d */ { 0x946,	"ARM946" },
+    /*d */ { 0x966,	"ARM966" },
+    /*d */ { 0xb02,	"ARM11 MPCore" },
+    /*d */ { 0xb36,	"ARM1136" },
+    /*d */ { 0xb56,	"ARM1156" },
+    /*dt*/ { 0xb76,	"ARM1176" },
+    /*dt*/ { 0xc05,	"Cortex-A5" },
+    /*d */ { 0xc07,	"Cortex-A7 MPCore" },
+    /*dt*/ { 0xc08,	"Cortex-A8" },
+    /*dt*/ { 0xc09,	"Cortex-A9" },
+    /*d */ { 0xc0e,	"Cortex-A17 MPCore" },
+    /*d */ { 0xc0f,	"Cortex-A15" },
+    /*d */ { 0xd01,	"Cortex-A32" },
+    /*dt*/ { 0xd03,	"Cortex-A53" },
+    /*d */ { 0xd04,	"Cortex-A35" },
+    /*d */ { 0xd05,	"Cortex-A55" },
+    /*d */ { 0xd07,	"Cortex-A57 MPCore" },
+    /*d */ { 0xd08,	"Cortex-A72" },
+    /*d */ { 0xd09,	"Cortex-A73" },
+    /*d */ { 0xd0a,	"Cortex-A75" },
+           { 0, NULL},
+};
+
+static struct {
+    char *code; char *name; char *more;
+} tab_arm_arch[] = {
+    { "7",	"AArch32",	"AArch32 (ARMv7)" },
+    { "8",	"AArch64",	"AArch64 (ARMv8)" },
+    { "AArch32",	"AArch32",	"AArch32 (ARMv7)" },
+    { "AArch64",	"AArch64",	"AArch64 (ARMv8)" },
+    { NULL, NULL, NULL },
+};
+
+static char all_flags[1024] = "";
+
+#define APPEND_FLAG(f) strcat(all_flags, f); strcat(all_flags, " ");
+const char *arm_flag_list() {
+    int i = 0, built = 0;
+    built = strlen(all_flags);
+    if (!built) {
+        while(tab_flag_meaning[i].name != NULL) {
+            APPEND_FLAG(tab_flag_meaning[i].name);
+            i++;
+        }
+    }
+    return all_flags;
+}
+
+const char *arm_flag_meaning(const char *flag) {
+    int i = 0;
+    if (flag)
+    while(tab_flag_meaning[i].name != NULL) {
+        if (strcmp(tab_flag_meaning[i].name, flag) == 0) {
+            if (tab_flag_meaning[i].meaning != NULL)
+                return C_("arm-flag", tab_flag_meaning[i].meaning);
+            else return NULL;
+        }
+        i++;
+    }
+    return NULL;
+}
+
+static int code_match(int c0, const char* code1) {
+    int c1;
+    if (code1 == NULL) return 0;
+    c1 = strtol(code1, NULL, 0);
+    return (c0 == c1) ? 1 : 0;
+}
+
+const char *arm_implementer(const char *code) {
+    int i = 0;
+    if (code)
+    while(tab_arm_implementer[i].code) {
+        if (code_match(tab_arm_implementer[i].code, code))
+            return tab_arm_implementer[i].name;
+        i++;
+    }
+    return NULL;
+}
+
+const char *arm_part(const char *imp_code, const char *part_code) {
+    int i = 0;
+    if (imp_code && part_code) {
+        if (code_match(0x41, imp_code)) {
+            /* 0x41=ARM parts */
+            while(tab_arm_arm_part[i].code) {
+                if (code_match(tab_arm_arm_part[i].code, part_code))
+                    return tab_arm_arm_part[i].part_desc;
+                i++;
+            }
+        }
+    }
+    return NULL;
+}
+
+const char *arm_arch(const char *cpuinfo_arch_str) {
+    int i = 0;
+    if (cpuinfo_arch_str)
+    while(tab_arm_arch[i].code) {
+        if (strcmp(tab_arm_arch[i].code, cpuinfo_arch_str) == 0)
+            return tab_arm_arch[i].name;
+        i++;
+    }
+    return cpuinfo_arch_str;
+}
+
+const char *arm_arch_more(const char *cpuinfo_arch_str) {
+    int i = 0;
+    if (cpuinfo_arch_str)
+    while(tab_arm_arch[i].code) {
+        if (strcmp(tab_arm_arch[i].code, cpuinfo_arch_str) == 0)
+            return tab_arm_arch[i].more;
+        i++;
+    }
+    return cpuinfo_arch_str;
+}
+
+char *arm_decoded_name(const char *imp, const char *part, const char *var, const char *rev, const char *arch, const char *model_name) {
+    char *dnbuff;
+    char *imp_name = NULL, *part_desc = NULL, *arch_name = NULL;
+    int r = 0, p = 0;
+    dnbuff = malloc(256);
+    if (dnbuff) {
+        memset(dnbuff, 0, 256);
+
+        if (imp && arch && part && rev) {
+            /* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0395b/CIHCAGHH.html
+             * variant and revision can be rendered r{variant}p{revision} */
+            r = strtol(var, NULL, 0);
+            p = strtol(rev, NULL, 0);
+            imp_name = (char*) arm_implementer(imp);
+            part_desc = (char*) arm_part(imp, part);
+            arch_name = (char*) arm_arch(arch);
+            if (imp_name || part_desc) {
+                if (arch_name != arch)
+                    sprintf(dnbuff, "%s %s r%dp%d (%s)",
+                        (imp_name) ? imp_name : imp,
+                        (part_desc) ? part_desc : part,
+                        r, p, arch_name);
+                else
+                    sprintf(dnbuff, "%s %s r%dp%d (arch:%s)",
+                        (imp_name) ? imp_name : imp,
+                        (part_desc) ? part_desc : part,
+                        r, p, arch);
+            } else {
+                /* fallback for now */
+                sprintf(dnbuff, "%s [imp:%s part:%s r%dp%d arch:%s]",
+                        model_name,
+                        (imp_name) ? imp_name : imp,
+                        (part_desc) ? part_desc : part,
+                        r, p, arch);
+            }
+        } else {
+            /* prolly not ARM arch at all */
+            if (model_name)
+                sprintf(dnbuff, "%s", model_name);
+            else {
+                free(dnbuff);
+                return NULL;
+            }
+        }
+    }
+    return dnbuff;
+}
diff --git a/modules/devices/arm/arm_data.h b/modules/devices/arm/arm_data.h
new file mode 100644
index 0000000..63b3c90
--- /dev/null
+++ b/modules/devices/arm/arm_data.h
@@ -0,0 +1,40 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * Copyright (C) 2017  Burt P. <pburt0@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef _ARMDATA_H_
+#define _ARMDATA_H_
+
+/* table lookups */
+const char *arm_implementer(const char *code);
+const char *arm_part(const char *imp_code, const char *part_code);
+const char *arm_arch(const char *cpuinfo_arch_str);
+const char *arm_arch_more(const char *cpuinfo_arch_str);
+
+/* cpu_implementer, cpu_part, cpu_variant, cpu_revision, cpu_architecture from /proc/cpuinfo
+ * model_name is returned as a fallback if not enough data is known */
+char *arm_decoded_name(
+    const char *imp, const char *part, const char *var, const char *rev,
+    const char *arch, const char *model_name);
+
+/* cpu flags from /proc/cpuinfo */
+const char *arm_flag_list(void);                  /* list of all known flags */
+const char *arm_flag_meaning(const char *flag);  /* lookup flag meaning */
+
+#endif
diff --git a/modules/devices/arm/processor.c b/modules/devices/arm/processor.c
new file mode 100644
index 0000000..3bee39f
--- /dev/null
+++ b/modules/devices/arm/processor.c
@@ -0,0 +1,493 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+#include "dt_util.h"
+
+#include "arm_data.h"
+#include "arm_data.c"
+
+enum {
+    ARM_A32 = 0,
+    ARM_A64 = 1,
+    ARM_A32_ON_A64 = 2,
+};
+
+static const gchar *arm_mode_str[] = {
+    "A32",
+    "A64",
+    "A32 on A64",
+};
+
+GSList *
+processor_scan(void)
+{
+    GSList *procs = NULL;
+    Processor *processor = NULL;
+    FILE *cpuinfo;
+    gchar buffer[128];
+    gchar *rep_pname = NULL;
+    GSList *pi = NULL;
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+    return NULL;
+
+#define CHECK_FOR(k) (g_str_has_prefix(tmp[0], k))
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+        if (tmp[0] && tmp[1]) {
+            tmp[0] = g_strstrip(tmp[0]);
+            tmp[1] = g_strstrip(tmp[1]);
+        } else {
+            g_strfreev(tmp);
+            continue;
+        }
+
+        get_str("Processor", rep_pname);
+
+        if ( CHECK_FOR("processor") ) {
+            /* finish previous */
+            if (processor) {
+                procs = g_slist_append(procs, processor);
+            }
+
+            /* start next */
+            processor = g_new0(Processor, 1);
+            processor->id = atol(tmp[1]);
+
+            if (rep_pname)
+                processor->linux_name = g_strdup(rep_pname);
+
+            g_strfreev(tmp);
+            continue;
+        }
+
+        if (!processor &&
+            (  CHECK_FOR("model name")
+            || CHECK_FOR("Features")
+            || CHECK_FOR("BogoMIPS") ) ) {
+
+            /* single proc/core may not have "processor : n" */
+            processor = g_new0(Processor, 1);
+            processor->id = 0;
+
+            if (rep_pname)
+                processor->linux_name = g_strdup(rep_pname);
+        }
+
+        if (processor) {
+            get_str("model name", processor->linux_name);
+            get_str("Features", processor->flags);
+            get_float("BogoMIPS", processor->bogomips);
+
+            get_str("CPU implementer", processor->cpu_implementer);
+            get_str("CPU architecture", processor->cpu_architecture);
+            get_str("CPU variant", processor->cpu_variant);
+            get_str("CPU part", processor->cpu_part);
+            get_str("CPU revision", processor->cpu_revision);
+        }
+        g_strfreev(tmp);
+    }
+
+    if (processor)
+        procs = g_slist_append(procs, processor);
+
+    g_free(rep_pname);
+    fclose(cpuinfo);
+
+    /* re-duplicate missing data for /proc/cpuinfo variant that de-duplicated it */
+#define REDUP(f) if (dproc->f && !processor->f) processor->f = g_strdup(dproc->f);
+    Processor *dproc;
+    GSList *l;
+    l = procs = g_slist_reverse(procs);
+    while (l) {
+        processor = l->data;
+        if (processor->flags) {
+            dproc = processor;
+        } else if (dproc) {
+            REDUP(flags);
+            REDUP(cpu_implementer);
+            REDUP(cpu_architecture);
+            REDUP(cpu_variant);
+            REDUP(cpu_part);
+            REDUP(cpu_revision);
+        }
+        l = g_slist_next(l);
+    }
+    procs = g_slist_reverse(procs);
+
+    /* data not from /proc/cpuinfo */
+    for (pi = procs; pi; pi = pi->next) {
+        processor = (Processor *) pi->data;
+
+        /* strings can't be null or segfault later */
+        STRIFNULL(processor->linux_name, _("ARM Processor") );
+        EMPIFNULL(processor->flags);
+        UNKIFNULL(processor->cpu_implementer);
+        UNKIFNULL(processor->cpu_architecture);
+        UNKIFNULL(processor->cpu_variant);
+        UNKIFNULL(processor->cpu_part);
+        UNKIFNULL(processor->cpu_revision);
+
+        processor->model_name = arm_decoded_name(
+            processor->cpu_implementer, processor->cpu_part,
+            processor->cpu_variant, processor->cpu_revision,
+            processor->cpu_architecture, processor->linux_name);
+        UNKIFNULL(processor->model_name);
+
+        /* topo & freq */
+        processor->cpufreq = cpufreq_new(processor->id);
+        processor->cputopo = cputopo_new(processor->id);
+
+        if (processor->cpufreq->cpukhz_max)
+            processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+        else
+            processor->cpu_mhz = 0.0f;
+
+        /* mode */
+        processor->mode = ARM_A32;
+        if ( processor_has_flag(processor->flags, "pmull")
+             || processor_has_flag(processor->flags, "crc32") ) {
+#ifdef __aarch64__
+                processor->mode = ARM_A64;
+#else
+                processor->mode = ARM_A32_ON_A64;
+#endif
+        }
+    }
+
+    return procs;
+}
+
+gchar *processor_get_capabilities_from_flags(gchar * strflags)
+{
+    gchar **flags, **old;
+    gchar *tmp = NULL;
+    gint j = 0;
+
+    flags = g_strsplit(strflags, " ", 0);
+    old = flags;
+
+    while (flags[j]) {
+        const gchar *meaning = arm_flag_meaning( flags[j] );
+
+        if (meaning) {
+            tmp = h_strdup_cprintf("%s=%s\n", tmp, flags[j], meaning);
+        } else {
+            tmp = h_strdup_cprintf("%s=\n", tmp, flags[j]);
+        }
+        j++;
+    }
+    if (tmp == NULL || g_strcmp0(tmp, "") == 0)
+        tmp = g_strdup_printf("%s=%s\n", "empty", _("Empty List"));
+
+    g_strfreev(old);
+    return tmp;
+}
+
+#define khzint_to_mhzdouble(k) (((double)k)/1000)
+#define cmp_clocks_test(f) if (a->f < b->f) return -1; if (a->f > b->f) return 1;
+
+static gint cmp_cpufreq_data(cpufreq_data *a, cpufreq_data *b) {
+        gint i = 0;
+        i = g_strcmp0(a->shared_list, b->shared_list); if (i!=0) return i;
+        cmp_clocks_test(cpukhz_max);
+        cmp_clocks_test(cpukhz_min);
+        return 0;
+}
+
+static gint cmp_cpufreq_data_ignore_affected(cpufreq_data *a, cpufreq_data *b) {
+        gint i = 0;
+        cmp_clocks_test(cpukhz_max);
+        cmp_clocks_test(cpukhz_min);
+        return 0;
+}
+
+gchar *clocks_summary(GSList * processors)
+{
+    gchar *ret = g_strdup_printf("[%s]\n", _("Clocks"));
+    GSList *all_clocks = NULL, *uniq_clocks = NULL;
+    GSList *tmp, *l;
+    Processor *p;
+    cpufreq_data *c, *cur = NULL;
+    gint cur_count = 0, i = 0;
+
+    /* create list of all clock references */
+    for (l = processors; l; l = l->next) {
+        p = (Processor*)l->data;
+        if (p->cpufreq) {
+            all_clocks = g_slist_prepend(all_clocks, p->cpufreq);
+        }
+    }
+
+    if (g_slist_length(all_clocks) == 0) {
+        ret = h_strdup_cprintf("%s=\n", ret, _("(Not Available)") );
+        g_slist_free(all_clocks);
+        return ret;
+    }
+
+    /* ignore duplicate references */
+    all_clocks = g_slist_sort(all_clocks, (GCompareFunc)cmp_cpufreq_data);
+    for (l = all_clocks; l; l = l->next) {
+        c = (cpufreq_data*)l->data;
+        if (!cur) {
+            cur = c;
+        } else {
+            if (cmp_cpufreq_data(cur, c) != 0) {
+                uniq_clocks = g_slist_prepend(uniq_clocks, cur);
+                cur = c;
+            }
+        }
+    }
+    uniq_clocks = g_slist_prepend(uniq_clocks, cur);
+    uniq_clocks = g_slist_reverse(uniq_clocks);
+    cur = 0, cur_count = 0;
+
+    /* count and list clocks */
+    for (l = uniq_clocks; l; l = l->next) {
+        c = (cpufreq_data*)l->data;
+        if (!cur) {
+            cur = c;
+            cur_count = 1;
+        } else {
+            if (cmp_cpufreq_data_ignore_affected(cur, c) != 0) {
+                ret = h_strdup_cprintf(_("%.2f-%.2f %s=%dx\n"),
+                                ret,
+                                khzint_to_mhzdouble(cur->cpukhz_min),
+                                khzint_to_mhzdouble(cur->cpukhz_max),
+                                _("MHz"),
+                                cur_count);
+                cur = c;
+                cur_count = 1;
+            } else {
+                cur_count++;
+            }
+        }
+    }
+    ret = h_strdup_cprintf(_("%.2f-%.2f %s=%dx\n"),
+                    ret,
+                    khzint_to_mhzdouble(cur->cpukhz_min),
+                    khzint_to_mhzdouble(cur->cpukhz_max),
+                    _("MHz"),
+                    cur_count);
+
+    g_slist_free(all_clocks);
+    g_slist_free(uniq_clocks);
+    return ret;
+}
+
+gchar *
+processor_get_detailed_info(Processor *processor)
+{
+    gchar *tmp_flags, *tmp_imp, *tmp_part, *tmp_arch, *tmp_cpufreq, *tmp_topology, *ret;
+    tmp_flags = processor_get_capabilities_from_flags(processor->flags);
+    tmp_imp = (char*)arm_implementer(processor->cpu_implementer);
+    tmp_part = (char*)arm_part(processor->cpu_implementer, processor->cpu_part);
+    tmp_arch = (char*)arm_arch_more(processor->cpu_architecture);
+
+    tmp_topology = cputopo_section_str(processor->cputopo);
+    tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+    ret = g_strdup_printf("[%s]\n"
+                       "%s=%s\n"       /* linux name */
+                       "%s=%s\n"       /* decoded name */
+                       "%s=%s\n"       /* mode */
+                       "%s=%.2f %s\n"  /* frequency */
+                       "%s=%.2f\n"     /* bogomips */
+                       "%s=%s\n"       /* byte order */
+                       "%s" /* topology */
+                       "%s" /* frequency scaling */
+                       "[%s]\n"    /* ARM */
+                       "%s=[%s] %s\n"  /* implementer */
+                       "%s=[%s] %s\n"  /* part */
+                       "%s=[%s] %s\n"  /* architecture */
+                       "%s=%s\n"       /* variant */
+                       "%s=%s\n"       /* revision */
+                       "[%s]\n" /* flags */
+                       "%s"
+                       "%s",    /* empty */
+                   _("Processor"),
+                   _("Linux Name"), processor->linux_name,
+                   _("Decoded Name"), processor->model_name,
+                   _("Mode"), arm_mode_str[processor->mode],
+                   _("Frequency"), processor->cpu_mhz, _("MHz"),
+                   _("BogoMips"), processor->bogomips,
+                   _("Byte Order"), byte_order_str(),
+                   tmp_topology,
+                   tmp_cpufreq,
+                   _("ARM"),
+                   _("Implementer"), processor->cpu_implementer, (tmp_imp) ? tmp_imp : "",
+                   _("Part"), processor->cpu_part, (tmp_part) ? tmp_part : "",
+                   _("Architecture"), processor->cpu_architecture, (tmp_arch) ? tmp_arch : "",
+                   _("Variant"), processor->cpu_variant,
+                   _("Revision"), processor->cpu_revision,
+                   _("Capabilities"), tmp_flags,
+                    "");
+    g_free(tmp_flags);
+    g_free(tmp_cpufreq);
+    g_free(tmp_topology);
+    return ret;
+}
+
+gchar *processor_name(GSList *processors) {
+    /* compatible contains a list of compatible hardware, so be careful
+     * with matching order.
+     * ex: "ti,omap3-beagleboard-xm", "ti,omap3450", "ti,omap3";
+     * matches "omap3 family" first.
+     * ex: "brcm,bcm2837", "brcm,bcm2836";
+     * would match 2836 when it is a 2837.
+     */
+#define UNKSOC "(Unknown)" /* don't translate this */
+    const struct {
+        char *search_str;
+        char *vendor;
+        char *soc;
+    } dt_compat_searches[] = {
+        { "brcm,bcm2837", "Broadcom", "BCM2837" },
+        { "brcm,bcm2836", "Broadcom", "BCM2836" },
+        { "brcm,bcm2835", "Broadcom", "BCM2835" },
+        { "ti,omap5432", "Texas Instruments", "OMAP5432" },
+        { "ti,omap5430", "Texas Instruments", "OMAP5430" },
+        { "ti,omap4470", "Texas Instruments", "OMAP4470" },
+        { "ti,omap4460", "Texas Instruments", "OMAP4460" },
+        { "ti,omap4430", "Texas Instruments", "OMAP4430" },
+        { "ti,omap3620", "Texas Instruments", "OMAP3620" },
+        { "ti,omap3450", "Texas Instruments", "OMAP3450" },
+        { "ti,omap5", "Texas Instruments", "OMAP5-family" },
+        { "ti,omap4", "Texas Instruments", "OMAP4-family" },
+        { "ti,omap3", "Texas Instruments", "OMAP3-family" },
+        { "ti,omap2", "Texas Instruments", "OMAP2-family" },
+        { "ti,omap1", "Texas Instruments", "OMAP1-family" },
+        { "mediatek,mt6799", "MediaTek", "MT6799 Helio X30" },
+        { "mediatek,mt6799", "MediaTek", "MT6799 Helio X30" },
+        { "mediatek,mt6797x", "MediaTek", "MT6797X Helio X27" },
+        { "mediatek,mt6797t", "MediaTek", "MT6797T Helio X25" },
+        { "mediatek,mt6797", "MediaTek", "MT6797 Helio X20" },
+        { "mediatek,mt6757T", "MediaTek", "MT6757T Helio P25" },
+        { "mediatek,mt6757", "MediaTek", "MT6757 Helio P20" },
+        { "mediatek,mt6795", "MediaTek", "MT6795 Helio X10" },
+        { "mediatek,mt6755", "MediaTek", "MT6755 Helio P10" },
+        { "mediatek,mt6750t", "MediaTek", "MT6750T" },
+        { "mediatek,mt6750", "MediaTek", "MT6750" },
+        { "mediatek,mt6753", "MediaTek", "MT6753" },
+        { "mediatek,mt6752", "MediaTek", "MT6752" },
+        { "mediatek,mt6738", "MediaTek", "MT6738" },
+        { "mediatek,mt6737t", "MediaTek", "MT6737T" },
+        { "mediatek,mt6735", "MediaTek", "MT6735" },
+        { "mediatek,mt6732", "MediaTek", "MT6732" },
+        { "qcom,msm8939", "Qualcomm", "Snapdragon 615"},
+        { "qcom,msm", "Qualcomm", "Snapdragon-family"},
+        { "nvidia,tegra" "nVidia", "Tegra-family" },
+        { "bcm,", "Broadcom", UNKSOC },
+        { "nvidia," "nVidia", UNKSOC },
+        { "rockchip," "Rockchip", UNKSOC },
+        { "ti,", "Texas Instruments", UNKSOC },
+        { "qcom,", "Qualcom", UNKSOC },
+        { "mediatek," "MediaTek", UNKSOC },
+        { NULL, NULL }
+    };
+    gchar *ret = NULL;
+    gchar *compat = NULL;
+    int i;
+
+    compat = dtr_get_string("/compatible", 1);
+
+    if (compat != NULL) {
+        i = 0;
+        while(dt_compat_searches[i].search_str != NULL) {
+            if (strstr(compat, dt_compat_searches[i].search_str) != NULL) {
+                ret = g_strdup_printf("%s %s", dt_compat_searches[i].vendor, dt_compat_searches[i].soc);
+                break;
+            }
+            i++;
+        }
+    }
+    g_free(compat);
+    UNKIFNULL(ret);
+    return ret;
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_by_counting_names(processors);
+}
+
+gchar *processor_meta(GSList * processors) {
+    gchar *meta_soc = processor_name(processors);
+    gchar *meta_cpu_desc = processor_describe(processors);
+    gchar *meta_cpu_topo = processor_describe_default(processors);
+    gchar *meta_freq_desc = processor_frequency_desc(processors);
+    gchar *meta_clocks = clocks_summary(processors);
+    gchar *ret = NULL;
+    UNKIFNULL(meta_cpu_desc);
+    ret = g_strdup_printf("[%s]\n"
+                            "%s=%s\n"
+                            "%s=%s\n"
+                            "%s=%s\n"
+                            "%s=%s\n"
+                            "%s",
+                            _("SOC/Package"),
+                            _("Name"), meta_soc,
+                            _("Description"), meta_cpu_desc,
+                            _("Topology"), meta_cpu_topo,
+                            _("Logical CPU Config"), meta_freq_desc,
+                            meta_clocks );
+    g_free(meta_soc);
+    g_free(meta_cpu_desc);
+    g_free(meta_cpu_topo);
+    g_free(meta_freq_desc);
+    g_free(meta_clocks);
+    return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
+{
+    Processor *processor;
+    gchar *ret, *tmp, *hashkey;
+    gchar *meta; /* becomes owned by more_info? no need to free? */
+    GSList *l;
+
+    tmp = g_strdup_printf("$CPU_META$%s=\n", _("SOC/Package Information") );
+
+    meta = processor_meta(processors);
+    moreinfo_add_with_prefix("DEV", "CPU_META", meta);
+
+    for (l = processors; l; l = l->next) {
+        processor = (Processor *) l->data;
+
+        tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+                  tmp, processor->id,
+                  processor->model_name,
+                  processor->cpu_mhz, _("MHz"));
+
+        hashkey = g_strdup_printf("CPU%d", processor->id);
+        moreinfo_add_with_prefix("DEV", hashkey,
+                processor_get_detailed_info(processor));
+        g_free(hashkey);
+    }
+
+    ret = g_strdup_printf("[$ShellParam$]\n"
+                  "ViewType=1\n"
+                  "[Processors]\n"
+                  "%s", tmp);
+    g_free(tmp);
+
+    return ret;
+}
diff --git a/modules/devices/battery.c b/modules/devices/battery.c
new file mode 100644
index 0000000..cbcebb1
--- /dev/null
+++ b/modules/devices/battery.c
@@ -0,0 +1,388 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+#include <time.h>
+
+#include "hardinfo.h"
+#include "devices.h"
+
+const struct {
+  gchar *key, *name;
+} ups_fields[] = {
+  { "UPS Status", NULL },
+  { "STATUS", "Status" },
+  { "TIMELEFT", "Time Left" },
+  { "LINEV", "Line Voltage" },
+  { "LOADPCT", "Load Percent" },
+
+  { "UPS Battery Information", NULL },
+  { "BATTV", "Battery Voltage" },
+  { "BCHARGE", "Battery Charge" },
+  { "BATTDATE", "Battery Date" },
+
+  { "UPS Information", NULL },
+  { "APCMODEL", "Model" },
+  { "FIRMWARE", "Firmware Version" },
+  { "SERIALNO", "Serial Number" },
+  { "UPSMODE", "UPS Mode" },
+  { "CABLE", "Cable" },
+  { "UPSNAME", "UPS Name" },
+
+  { "UPS Nominal Values", NULL },
+  { "NOMINV", "Voltage" },
+  { "NOMBATTV", "Battery Voltage" },
+  { "NOMPOWER", "Power" }
+};
+
+
+static void
+__scan_battery_apcupsd(void)
+{
+    GHashTable  *ups_data;
+    FILE	*apcaccess;
+    char	buffer[512], *apcaccess_path;
+    int		i;
+
+    apcaccess_path = find_program("apcaccess");
+    if (apcaccess_path && (apcaccess = popen(apcaccess_path, "r"))) {
+      /* first line isn't important */
+      if (fgets(buffer, 512, apcaccess)) {
+        /* allocate the key, value hash table */
+        ups_data = g_hash_table_new(g_str_hash, g_str_equal);
+
+        /* read up all the apcaccess' output, saving it in the key, value hash table */
+        while (fgets(buffer, 512, apcaccess)) {
+          buffer[9] = '\0';
+
+          g_hash_table_insert(ups_data,
+                              g_strdup(g_strstrip(buffer)),
+                              g_strdup(g_strstrip(buffer + 10)));
+        }
+
+        /* builds the ups info string, respecting the field order as found in ups_fields */
+        for (i = 0; i < G_N_ELEMENTS(ups_fields); i++) {
+          if (!ups_fields[i].name) {
+            /* there's no name: make a group with the key as its name */
+            battery_list = h_strdup_cprintf("[%s]\n", battery_list, ups_fields[i].key);
+          } else {
+            /* there's a name: adds a line */
+            battery_list = h_strdup_cprintf("%s=%s\n", battery_list,
+                                            ups_fields[i].name,
+                                            g_hash_table_lookup(ups_data, ups_fields[i].key));
+          }
+        }
+
+        g_hash_table_destroy(ups_data);
+      }
+
+      pclose(apcaccess);
+    }
+    
+    g_free(apcaccess_path);
+}
+
+static void
+__scan_battery_acpi(void)
+{
+    gchar *acpi_path;
+
+    gchar *present = NULL;
+    gchar *capacity = NULL;
+    gchar *technology = NULL;
+    gchar *voltage = NULL;
+    gchar *model = NULL, *serial = NULL, *type = NULL;
+    gchar *state = NULL, *rate = NULL;
+    gchar *remaining = NULL;
+    gchar *manufacturer = NULL;
+    
+    acpi_path = g_strdup("/proc/acpi/battery");
+    if (g_file_test(acpi_path, G_FILE_TEST_EXISTS)) {
+      GDir *acpi;
+      
+      if ((acpi = g_dir_open(acpi_path, 0, NULL))) {
+        const gchar *entry;
+        
+        while ((entry = g_dir_read_name(acpi))) {
+          gchar *path = g_strdup_printf("%s/%s/info", acpi_path, entry);
+          FILE *f;
+          gchar buffer[256];
+          gdouble charge_rate = 1.0;
+          
+          f = fopen(path, "r");
+          g_free(path);
+          
+          if (!f)
+            goto cleanup;
+          
+          while (fgets(buffer, 256, f)) {
+            gchar **tmp = g_strsplit(buffer, ":", 2);
+            
+            GET_STR("present", present);
+            GET_STR("design capacity", capacity);
+            GET_STR("battery technology", technology);
+            GET_STR("design voltage", voltage);
+            GET_STR("model number", model);
+            GET_STR("serial number", serial);
+            GET_STR("battery type", type);
+	    GET_STR("OEM info", manufacturer);
+            
+            g_strfreev(tmp);
+          }          
+          fclose(f);
+          
+          path = g_strdup_printf("%s/%s/state", acpi_path, entry);
+          f = fopen(path, "r");
+          g_free(path);
+          
+          if (!f)
+            goto cleanup;
+          
+          while (fgets(buffer, 256, f)) {
+            gchar **tmp = g_strsplit(buffer, ":", 2);
+            
+            GET_STR("charging state", state);
+            GET_STR("present rate", rate);
+            GET_STR("remaining capacity", remaining);
+          
+            g_strfreev(tmp);
+          }
+          
+          fclose(f);
+
+	 const gchar *url = vendor_get_url(manufacturer);
+	 if (url) {
+	   char *tmp = g_strdup_printf("%s (%s)", vendor_get_name(manufacturer), url);
+	   g_free(manufacturer);
+	   manufacturer = tmp;    
+	 }
+          
+          if (g_str_equal(present, "yes")) {
+            if (remaining && capacity)
+               charge_rate = atof(remaining) / atof(capacity);
+            else
+               charge_rate = 0;
+
+            battery_list = h_strdup_cprintf(_("\n[Battery: %s]\n"
+                                           "State=%s (load: %s)\n"
+                                           "Capacity=%s / %s (%.2f%%)\n"
+                                           "Battery Technology=%s (%s)\n"
+					   "Manufacturer=%s\n"
+                                           "Model Number=%s\n"
+                                           "Serial Number=%s\n"),
+                                           battery_list,
+                                           entry,
+                                           state, rate,
+                                           remaining, capacity, charge_rate * 100.0,
+                                           technology, type,
+					   manufacturer,
+                                           model,
+                                           serial);
+          }
+          
+         cleanup:
+          g_free(present);
+          g_free(capacity);
+          g_free(technology);
+          g_free(type);
+          g_free(model);
+          g_free(serial);
+          g_free(state);
+          g_free(remaining);
+          g_free(rate);
+	  g_free(manufacturer);
+
+          present = capacity = technology = type = \
+                model = serial = state = remaining = rate = manufacturer = NULL;
+        }
+      
+        g_dir_close(acpi);
+      }
+    }
+    
+    g_free(acpi_path);
+}
+
+static gchar *
+read_contents(const gchar *base, const gchar *key)
+{
+    gchar *value;
+    gchar *path;
+
+    path = g_strdup_printf("%s/%s", base, key);
+    if (!path)
+        return NULL;
+
+    if (!g_file_get_contents(path, &value, NULL, NULL)) {
+        free(path);
+        return NULL;
+    }
+
+    free(path);
+    return g_strchomp(value);
+}
+
+static void
+__scan_battery_sysfs_add_battery(const gchar *name)
+{
+    gchar *path = g_strdup_printf("/sys/class/power_supply/%s", name);
+    gchar *status, *capacity, *capacity_level, *technology, *manufacturer,
+        *model_name, *serial_number;
+
+    if (!path)
+        return;
+
+    status = read_contents(path, "status");
+    capacity = read_contents(path, "capacity");
+    capacity_level = read_contents(path, "capacity_level");
+    technology = read_contents(path, "technology");
+    manufacturer = read_contents(path, "manufacturer");
+    model_name = read_contents(path, "model_name");
+    serial_number = read_contents(path, "serial_number");
+
+    battery_list = h_strdup_cprintf(_("\n[Battery: %s]\n"
+        "State=%s\n"
+        "Capacity=%s / %s\n"
+        "Battery Technology=%s\n"
+        "Manufacturer=%s\n"
+        "Model Number=%s\n"
+        "Serial Number=%s\n"),
+        battery_list,
+        name,
+        status,
+        capacity, capacity_level,
+        technology,
+        manufacturer,
+        model_name,
+        serial_number);
+
+    free(status);
+    free(capacity);
+    free(capacity_level);
+    free(technology);
+    free(manufacturer);
+    free(model_name);
+    free(serial_number);
+}
+
+static void
+__scan_battery_sysfs(void)
+{
+    GDir *dir;
+    const gchar *entry;
+
+    dir = g_dir_open("/sys/class/power_supply", 0, NULL);
+    if (!dir)
+        return;
+
+    while ((entry = g_dir_read_name(dir))) {
+        if (g_str_has_prefix(entry, "BAT"))
+            __scan_battery_sysfs_add_battery(entry);
+    }
+
+    g_dir_close(dir);
+}
+
+static void
+__scan_battery_apm(void)
+{
+    FILE                *procapm;
+    static char         *sremaining = NULL, *stotal = NULL;
+    static unsigned int  last_time = 0;
+    static int           percentage = 0;
+    const  char         *ac_status[] = { "Battery",
+                                         "AC Power",
+                                         "Charging" };
+    int                  ac_bat;
+    char                 apm_bios_ver[16], apm_drv_ver[16];
+    char                 trash[10];
+    
+    if ((procapm = fopen("/proc/apm", "r"))) {
+        int old_percentage = percentage;
+        
+        (void)fscanf(procapm, "%s %s %s 0x%x %s %s %d%%",
+               apm_drv_ver, apm_bios_ver, trash,
+               &ac_bat, trash, trash, &percentage);
+        fclose(procapm);
+        
+        if (last_time == 0) {
+            last_time = time(NULL);
+            sremaining = stotal = NULL;
+        }
+
+        if (old_percentage - percentage > 0) {
+            if (sremaining && stotal) {
+                g_free(sremaining);
+                g_free(stotal);
+            }
+                        
+            int secs_remaining = (time(NULL) - last_time) * percentage /
+                                 (old_percentage - percentage);
+            sremaining = seconds_to_string(secs_remaining);
+            stotal = seconds_to_string((secs_remaining * 100) / percentage);
+            
+            last_time = time(NULL);
+        }
+    } else {
+        return;
+    }
+
+    if (stotal && sremaining) {
+        battery_list = h_strdup_cprintf(_("\n[Battery (APM)]\n"
+                                       "Charge=%d%%\n"
+                                       "Remaining Charge=%s of %s\n"
+                                       "Using=%s\n"
+                                       "APM driver version=%s\n"
+                                       "APM BIOS version=%s\n"),
+                                       battery_list,
+                                       percentage,
+                                       sremaining, stotal,
+                                       ac_status[ac_bat],
+                                       apm_drv_ver, apm_bios_ver);
+    } else {
+        battery_list = h_strdup_cprintf(_("\n[Battery (APM)]\n"
+                                       "Charge=%d%%\n"
+                                       "Using=%s\n"
+                                       "APM driver version=%s\n"
+                                       "APM BIOS version=%s\n"),
+                                       battery_list,
+                                       percentage,
+                                       ac_status[ac_bat],
+                                       apm_drv_ver, apm_bios_ver);
+    
+    }
+}
+
+void
+scan_battery_do(void)
+{
+    g_free(battery_list);
+    battery_list = g_strdup("");
+
+    __scan_battery_sysfs();
+    __scan_battery_acpi();
+    __scan_battery_apm();
+    __scan_battery_apcupsd();
+    
+    if (*battery_list == '\0') {
+        g_free(battery_list);
+        
+        battery_list = g_strdup(_("[No batteries]\n"
+                                "No batteries found on this system=\n"));
+    }
+}
diff --git a/modules/devices/devicetree.c b/modules/devices/devicetree.c
new file mode 100644
index 0000000..4f3c85a
--- /dev/null
+++ b/modules/devices/devicetree.c
@@ -0,0 +1,304 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+/*
+ * Device Tree support by Burt P. <pburt0@gmail.com>
+ * Sources:
+ *   http://elinux.org/Device_Tree_Usage
+ *   http://elinux.org/Device_Tree_Mysteries
+ */
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+#include "dt_util.h"
+
+/* These should really go into CMakeLists.txt */
+#if defined(__arm__)
+#include "devicetree/rpi_data.c"
+#elif defined(__powerpc__)
+#include "devicetree/pmac_data.c"
+#endif
+
+gchar *dtree_info = NULL;
+
+static gchar *get_node(dtr *dt, char *np) {
+    gchar *nodes = NULL, *props = NULL, *ret = NULL;
+    gchar *tmp = NULL, *pstr = NULL, *lstr = NULL;
+    gchar *dir_path;
+    gchar *node_path;
+    const gchar *fn;
+    GDir *dir;
+    dtr_obj *node, *child;
+
+    props = g_strdup_printf("[%s]\n", _("Properties") );
+    nodes = g_strdup_printf("[%s]\n", _("Children") );
+    node = dtr_obj_read(dt, np);
+    dir_path = dtr_obj_full_path(node);
+
+    dir = g_dir_open(dir_path, 0 , NULL);
+    if (dir) {
+        while((fn = g_dir_read_name(dir)) != NULL) {
+            child = dtr_get_prop_obj(dt, node, fn);
+            pstr = hardinfo_clean_value(dtr_str(child), 1);
+            lstr = hardinfo_clean_label(fn, 0);
+            if (dtr_obj_type(child) == DT_NODE) {
+                tmp = g_strdup_printf("%s%s=%s\n",
+                    nodes, lstr, pstr);
+                g_free(nodes);
+                nodes = tmp;
+            } else {
+                tmp = g_strdup_printf("%s%s=%s\n",
+                    props, lstr, pstr);
+                g_free(props);
+                props = tmp;
+            }
+            dtr_obj_free(child);
+            g_free(pstr);
+            g_free(lstr);
+        }
+    }
+    g_dir_close(dir);
+    g_free(dir_path);
+
+    lstr = dtr_obj_alias(node);
+    pstr = dtr_obj_symbol(node);
+    ret = g_strdup_printf("[%s]\n"
+                    "%s=%s\n"
+                    "%s=%s\n"
+                    "%s=%s\n"
+                    "%s%s",
+                    _("Node"),
+                    _("Node Path"), dtr_obj_path(node),
+                    _("Alias"), (lstr != NULL) ? lstr : _("(None)"),
+                    _("Symbol"), (pstr != NULL) ? pstr : _("(None)"),
+                    props, nodes);
+
+    dtr_obj_free(node);
+    g_free(props);
+    g_free(nodes);
+
+    return ret;
+}
+
+/* different from  dtr_get_string() in that it re-uses the existing dt */
+static char *get_dt_string(dtr *dt, char *path, gboolean decode) {
+    char *ret;
+
+    if (decode) {
+        dtr_obj *obj = dtr_get_prop_obj(dt, NULL, path);
+
+        ret = dtr_str(obj);
+
+        dtr_obj_free(obj);
+    } else {
+        ret = dtr_get_prop_str(dt, NULL, path);
+    }
+
+    return ret;
+}
+
+static gchar *get_summary(dtr *dt) {
+    char *model = NULL, *compat = NULL;
+    char *ret = NULL;
+
+    model = get_dt_string(dt, "/model", 0);
+    compat = get_dt_string(dt, "/compatible", 1);
+    UNKIFNULL(model);
+    EMPIFNULL(compat);
+
+#if defined(__arm__)
+    /* Expand on the DT information from known machines, like RPi.
+     * RPi stores a revision value in /proc/cpuinfo that can be used
+     * to look up details. This is just a nice place to pull it all
+     * together for DT machines, with a nice fallback.
+     * PPC Macs could be handled this way too. They store
+     * machine identifiers in /proc/cpuinfo. */
+    if (strstr(model, "Raspberry Pi")
+        || strstr(compat, "raspberrypi")) {
+        gchar *gpu_compat = get_dt_string(dt, "/soc/gpu/compatible", 1);
+        gchar *rpi_details = rpi_board_details();
+        gchar *basic_info;
+
+        basic_info = g_strdup_printf(
+                "[%s]\n"
+                "%s=%s\n"
+                "%s=%s\n",
+                _("Platform"),
+                _("Compatible"), compat,
+                _("GPU-compatible"), gpu_compat);
+
+        if (rpi_details) {
+            ret = g_strconcat(rpi_details, basic_info, NULL);
+
+            g_free(rpi_details);
+        } else {
+            gchar *serial_number = get_dt_string(dt, "/serial-number", 1);
+
+            ret = g_strdup_printf(
+                "[%s]\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s",
+                _("Raspberry Pi or Compatible"),
+                _("Model"), model,
+                _("Serial Number"), serial_number,
+                _("RCode"), _("No revision code available; unable to lookup model details."),
+                basic_info);
+
+            g_free(serial_number);
+        }
+
+        g_free(gpu_compat);
+        g_free(basic_info);
+    }
+#endif
+
+#if defined(__powerpc__)
+    /* Power Macintosh */
+    if (strstr(compat, "PowerBook") != NULL
+         || strstr(compat, "MacRISC") != NULL
+         || strstr(compat, "Power Macintosh") != NULL) {
+        gchar *mac_details = ppc_mac_details();
+
+        if (mac_details) {
+            gchar *serial_number = get_dt_string(dt, "/serial-number", 1);
+
+            ret = g_strdup_printf(
+                "%s[%s]\n"
+                "%s=%s\n",
+                mac_details,
+                _("More"),
+                _("Serial Number"), serial_number);
+
+            free(mac_details);
+            free(serial_number);
+        }
+    }
+#endif
+
+    /* fallback */
+    if (!ret) {
+        gchar *serial_number = get_dt_string(dt, "/serial-number", 1);
+        EMPIFNULL(serial_number);
+        ret = g_strdup_printf(
+                "[%s]\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n",
+                _("Board"),
+                _("Model"), model,
+                _("Serial Number"), serial_number,
+                _("Compatible"), compat);
+        free(serial_number);
+    }
+
+    free(model);
+    free(compat);
+
+    return ret;
+}
+
+static void mi_add(const char *key, const char *value) {
+    gchar *ckey, *rkey;
+
+    ckey = hardinfo_clean_label(key, 0);
+    rkey = g_strdup_printf("%s:%s", "DTREE", ckey);
+
+    dtree_info = h_strdup_cprintf("$%s$%s=\n", dtree_info, rkey, ckey);
+    moreinfo_add_with_prefix("DEV", rkey, g_strdup(value));
+
+    g_free(ckey);
+    g_free(rkey);
+}
+
+static void add_keys(dtr *dt, char *np) {
+    gchar *dir_path, *dt_path;
+    gchar *ftmp, *ntmp;
+    gchar *n_info;
+    const gchar *fn;
+    GDir *dir;
+    dtr_obj *obj;
+
+    /* add self */
+    obj = dtr_obj_read(dt, np);
+    dt_path = dtr_obj_path(obj);
+    n_info = get_node(dt, dt_path);
+    mi_add(dt_path, n_info);
+
+    dir_path = g_strdup_printf("%s/%s", dtr_base_path(dt), np);
+    dir = g_dir_open(dir_path, 0 , NULL);
+    if (dir) {
+        while((fn = g_dir_read_name(dir)) != NULL) {
+            ftmp = g_strdup_printf("%s/%s", dir_path, fn);
+            if ( g_file_test(ftmp, G_FILE_TEST_IS_DIR) ) {
+                if (strcmp(np, "/") == 0)
+                    ntmp = g_strdup_printf("/%s", fn);
+                else
+                    ntmp = g_strdup_printf("%s/%s", np, fn);
+                add_keys(dt, ntmp);
+                g_free(ntmp);
+            }
+            g_free(ftmp);
+        }
+    }
+    g_dir_close(dir);
+}
+
+static char *msg_section(dtr *dt, int dump) {
+    gchar *aslbl = NULL;
+    gchar *messages = dtr_messages(dt);
+    gchar *ret = g_strdup_printf("[%s]\n", _("Messages"));
+    gchar **lines = g_strsplit(messages, "\n", 0);
+    int i = 0;
+    while(lines[i] != NULL) {
+        aslbl = hardinfo_clean_label(lines[i], 0);
+        ret = appf(ret, "%s=\n", aslbl);
+        g_free(aslbl);
+        i++;
+    }
+    g_strfreev(lines);
+    if (dump)
+        printf("%s", messages);
+    g_free(messages);
+    return ret;
+}
+
+void __scan_dtree()
+{
+    dtr *dt = dtr_new(NULL);
+    gchar *summary = get_summary(dt);
+    gchar *maps = dtr_maps_info(dt);
+    gchar *messages = NULL;
+
+    dtree_info = g_strdup("[Device Tree]\n");
+    mi_add("Summary", summary);
+    mi_add("Maps", maps);
+
+    if(dtr_was_found(dt))
+        add_keys(dt, "/");
+    messages = msg_section(dt, 0);
+    mi_add("Messages", messages);
+
+    g_free(summary);
+    g_free(maps);
+    g_free(messages);
+    dtr_free(dt);
+}
diff --git a/modules/devices/devicetree/pmac_data.c b/modules/devices/devicetree/pmac_data.c
new file mode 100644
index 0000000..b236aef
--- /dev/null
+++ b/modules/devices/devicetree/pmac_data.c
@@ -0,0 +1,98 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "cpu_util.h" /* for PROC_CPUINFO */
+
+static gchar *ppc_mac_details(void) {
+    int i = 0;
+    gchar *ret = NULL;
+    gchar *platform = NULL;
+    gchar *model = NULL;
+    gchar *machine = NULL;
+    gchar *motherboard = NULL;
+    gchar *detected_as = NULL;
+    gchar *pmac_flags = NULL;
+    gchar *l2_cache = NULL;
+    gchar *pmac_gen = NULL;
+
+    FILE *cpuinfo;
+    gchar buffer[128];
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+        return NULL;
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+        if (tmp[1] == NULL) {
+            g_strfreev(tmp);
+            continue;
+        }
+        tmp[0] = g_strstrip(tmp[0]);
+        tmp[1] = g_strstrip(tmp[1]);
+        get_str("platform", platform);
+        get_str("model", model);
+        get_str("machine", machine);
+        get_str("motherboard", motherboard);
+        get_str("detected as", detected_as);
+        get_str("pmac flags", pmac_flags);
+        get_str("L2 cache", l2_cache);
+        get_str("pmac-generation", pmac_gen);
+    }
+    fclose(cpuinfo);
+
+    if (machine == NULL)
+        goto pmd_exit;
+
+    UNKIFNULL(platform);
+    UNKIFNULL(model);
+    UNKIFNULL(motherboard);
+    UNKIFNULL(detected_as);
+    UNKIFNULL(pmac_flags);
+    UNKIFNULL(l2_cache);
+    UNKIFNULL(pmac_gen);
+
+    ret = g_strdup_printf("[%s]\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n",
+                _("Apple Power Macintosh"),
+                _("Platform"), platform,
+                _("Model"), model,
+                _("Machine"), machine,
+                _("Motherboard"), motherboard,
+                _("Detected as"), detected_as,
+                _("PMAC Flags"), pmac_flags,
+                _("L2 Cache"), l2_cache,
+                _("PMAC Generation"), pmac_gen );
+
+pmd_exit:
+    g_free(platform);
+    g_free(model);
+    g_free(machine);
+    g_free(motherboard);
+    g_free(detected_as);
+    g_free(pmac_flags);
+    g_free(l2_cache);
+    g_free(pmac_gen);
+    return ret;
+}
diff --git a/modules/devices/devicetree/rpi_data.c b/modules/devices/devicetree/rpi_data.c
new file mode 100644
index 0000000..d0132e3
--- /dev/null
+++ b/modules/devices/devicetree/rpi_data.c
@@ -0,0 +1,166 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *    This file from: rpiz - https://github.com/bp0/rpiz
+ *    Copyright (C) 2017  Burt P. <pburt0@gmail.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+static char unk[] = "(Unknown)";
+
+/* information table from: http://elinux.org/RPi_HardwareHistory */
+static struct {
+    char *value, *intro, *model, *pcb, *mem, *mfg, *soc;
+} rpi_boardinfo[] = {
+/*  Value        Introduction  Model Name             PCB rev.  Memory(spec)   Manufacturer  SOC(spec) *
+ *                             Raspberry Pi %s                                                         */
+  { unk,         unk,          unk,                   unk,      unk,        unk,             NULL },
+  { "Beta",      "Q1 2012",    "B (Beta)",            unk,      "256MB",    "(Beta board)",  NULL },
+  { "0002",      "Q1 2012",    "B",                   "1.0",    "256MB",    unk,             "BCM2835" },
+  { "0003",      "Q3 2012",    "B (ECN0001)",         "1.0",    "256MB",    "(Fuses mod and D14 removed)",   NULL },
+  { "0004",      "Q3 2012",    "B",                   "2.0",    "256MB",    "Sony",          NULL },
+  { "0005",      "Q4 2012",    "B",                   "2.0",    "256MB",    "Qisda",         NULL },
+  { "0006",      "Q4 2012",    "B",                   "2.0",    "256MB",    "Egoman",        NULL },
+  { "0007",      "Q1 2013",    "A",                   "2.0",    "256MB",    "Egoman",        NULL },
+  { "0008",      "Q1 2013",    "A",                   "2.0",    "256MB",    "Sony",          NULL },
+  { "0009",      "Q1 2013",    "A",                   "2.0",    "256MB",    "Qisda",         NULL },
+  { "000d",      "Q4 2012",    "B",                   "2.0",    "512MB",    "Egoman",        NULL },
+  { "000e",      "Q4 2012",    "B",                   "2.0",    "512MB",    "Sony",          NULL },
+  { "000f",      "Q4 2012",    "B",                   "2.0",    "512MB",    "Qisda",         NULL },
+  { "0010",      "Q3 2014",    "B+",                  "1.0",    "512MB",    "Sony",          NULL },
+  { "0011",      "Q2 2014",    "Compute Module 1",    "1.0",    "512MB",    "Sony",          NULL },
+  { "0012",      "Q4 2014",    "A+",                  "1.1",    "256MB",    "Sony",          NULL },
+  { "0013",      "Q1 2015",    "B+",                  "1.2",    "512MB",    unk,             NULL },
+  { "0014",      "Q2 2014",    "Compute Module 1",    "1.0",    "512MB",    "Embest",        NULL },
+  { "0015",      unk,          "A+",                  "1.1",    "256MB/512MB",    "Embest",      NULL  },
+  { "a01040",    unk,          "2 Model B",           "1.0",    "1GB",      "Sony",          "BCM2836" },
+  { "a01041",    "Q1 2015",    "2 Model B",           "1.1",    "1GB",      "Sony",          "BCM2836" },
+  { "a21041",    "Q1 2015",    "2 Model B",           "1.1",    "1GB",      "Embest",        "BCM2836" },
+  { "a22042",    "Q3 2016",    "2 Model B",           "1.2",    "1GB",      "Embest",        "BCM2837" },  /* (with BCM2837) */
+  { "900021",    "Q3 2016",    "A+",                  "1.1",    "512MB",    "Sony",          NULL },
+  { "900032",    "Q2 2016?",    "B+",                 "1.2",    "512MB",    "Sony",          NULL },
+  { "900092",    "Q4 2015",    "Zero",                "1.2",    "512MB",    "Sony",          NULL },
+  { "900093",    "Q2 2016",    "Zero",                "1.3",    "512MB",    "Sony",          NULL },
+  { "920093",    "Q4 2016?",   "Zero",                "1.3",    "512MB",    "Embest",        NULL },
+  { "9000c1",    "Q1 2017",    "Zero W",              "1.1",    "512MB",    "Sony",          NULL },
+  { "a02082",    "Q1 2016",    "3 Model B",           "1.2",    "1GB",      "Sony",          "BCM2837" },
+  { "a020a0",    "Q1 2017",    "Compute Module 3 or CM3 Lite",  "1.0",    "1GB",    "Sony",          NULL },
+  { "a22082",    "Q1 2016",    "3 Model B",           "1.2",    "1GB",      "Embest",        "BCM2837" },
+  { "a32082",    "Q4 2016",    "3 Model B",           "1.2",    "1GB",      "Sony Japan",    NULL  },
+  { NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+};
+
+
+/* return number of chars to skip */
+static int rpi_ov_check(const char *r_code) {
+    /* sources differ. prefix is either 1000... or just 1... */
+    //if (strncmp(r, "1000", 4) == 0)
+    //    return 4;
+    if (strncmp(r_code, "1", 1) == 0)
+        return 1;
+    return 0;
+}
+
+static int rpi_code_match(const char* code0, const char* code1) {
+    int c0, c1;
+    if (code0 == NULL || code1 == NULL) return 0;
+    c0 = strtol(code0, NULL, 16);
+    c1 = strtol(code1, NULL, 16);
+    if (c0 && c1)
+        return (c0 == c1) ? 1 : 0;
+    else
+        return (strcmp(code0, code1) == 0) ? 1 : 0;
+}
+
+static int rpi_find_board(const char *r_code) {
+    int i = 0;
+    char *r = (char*)r_code;
+    if (r_code == NULL)
+        return 0;
+    /* ignore the overvolt prefix */
+    r += rpi_ov_check(r_code);
+    while (rpi_boardinfo[i].value != NULL) {
+        if (rpi_code_match(r, rpi_boardinfo[i].value))
+            return i;
+
+        i++;
+    }
+    return 0;
+}
+
+/* ------------------------- */
+
+#include "cpu_util.h" /* for PROC_CPUINFO */
+
+static gchar *rpi_board_details(void) {
+    int i = 0;
+    gchar *ret = NULL;
+    gchar *soc = NULL;
+    gchar *serial = NULL;
+    gchar *revision = NULL;
+    int ov = 0;
+    FILE *cpuinfo;
+    gchar buffer[128];
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+        return NULL;
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+        if (tmp[1] == NULL) {
+            g_strfreev(tmp);
+            continue;
+        }
+        tmp[0] = g_strstrip(tmp[0]);
+        tmp[1] = g_strstrip(tmp[1]);
+        get_str("Revision", revision);
+        get_str("Hardware", soc);
+        get_str("Serial", serial);
+    }
+    fclose(cpuinfo);
+
+    if (revision == NULL || soc == NULL) {
+        g_free(soc);
+        g_free(revision);
+        return NULL;
+    }
+
+    ov = rpi_ov_check(revision);
+    i = rpi_find_board(revision);
+    ret = g_strdup_printf("[%s]\n"
+                "%s=%s %s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n"
+                "%s=%s\n",
+                _("Raspberry Pi"),
+                _("Board Name"), _("Raspberry Pi"), rpi_boardinfo[i].model,
+                _("PCB Revision"), rpi_boardinfo[i].pcb,
+                _("Introduction"), rpi_boardinfo[i].intro,
+                _("Manufacturer"), rpi_boardinfo[i].mfg,
+                _("RCode"), rpi_boardinfo[i].value,
+                _("SOC (spec)"), rpi_boardinfo[i].soc,
+                _("Memory (spec)"), rpi_boardinfo[i].mem,
+                _("Serial Number"), serial,
+                _("Permanent overvolt bit"), (ov) ? C_("rpi-ov-bit", "Set") : C_("rpi-ov-bit", "Not set") );
+
+    g_free(soc);
+    g_free(revision);
+    return ret;
+}
diff --git a/modules/devices/devmemory.c b/modules/devices/devmemory.c
new file mode 100644
index 0000000..29094dd
--- /dev/null
+++ b/modules/devices/devmemory.c
@@ -0,0 +1,120 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+#include "devices.h"
+
+GHashTable *memlabels = NULL;
+
+void scan_memory_do(void)
+{
+    gchar **keys, *tmp, *tmp_label, *trans_val;
+    static gint offset = -1;
+    gint i;
+
+    if (offset == -1) {
+        /* gah. linux 2.4 adds three lines of data we don't need in
+           /proc/meminfo */
+        gchar *os_kernel = module_call_method("computer::getOSKernel");
+        if (os_kernel) {
+            offset = strstr(os_kernel, "Linux 2.4") ? 3 : 0;
+            g_free(os_kernel);
+        } else {
+            offset = 0;
+        }
+    }
+
+    g_file_get_contents("/proc/meminfo", &meminfo, NULL, NULL);
+
+    keys = g_strsplit(meminfo, "\n", 0);
+
+    g_free(meminfo);
+    g_free(lginterval);
+
+    meminfo = g_strdup("");
+    lginterval = g_strdup("");
+
+    for (i = offset; keys[i]; i++) {
+        gchar **newkeys = g_strsplit(keys[i], ":", 0);
+
+        if (!newkeys[0]) {
+            g_strfreev(newkeys);
+            break;
+        }
+
+        g_strstrip(newkeys[0]);
+        g_strstrip(newkeys[1]);
+
+        /* try to find a localizable label */
+        tmp = g_hash_table_lookup(memlabels, newkeys[0]);
+        if (tmp)
+            tmp_label = _(tmp);
+        else
+            tmp_label = ""; /* or newkeys[0] */
+        /* although it doesn't matter... */
+
+        if (strstr(newkeys[1], "kB")) {
+            trans_val = g_strdup_printf("%d %s", atoi(newkeys[1]), _("KiB") );
+        } else {
+            trans_val = strdup(newkeys[1]);
+        }
+
+        moreinfo_add_with_prefix("DEV", newkeys[0], g_strdup(trans_val));
+
+        tmp = g_strconcat(meminfo, newkeys[0], "=", trans_val, "|", tmp_label, "\n", NULL);
+        g_free(meminfo);
+        meminfo = tmp;
+
+        g_free(trans_val);
+
+        tmp = g_strconcat(lginterval,
+                          "UpdateInterval$", newkeys[0], "=1000\n", NULL);
+        g_free(lginterval);
+        lginterval = tmp;
+
+        g_strfreev(newkeys);
+    }
+    g_strfreev(keys);
+}
+
+void init_memory_labels(void)
+{
+    static const struct {
+        char *proc_label;
+        char *real_label;
+    } proc2real[] = {
+        { "MemTotal",   N_("Total Memory") },
+        { "MemFree",    N_("Free Memory") },
+        { "SwapCached", N_("Cached Swap") },
+        { "HighTotal",  N_("High Memory") },
+        { "HighFree",   N_("Free High Memory") },
+        { "LowTotal",   N_("Low Memory") },
+        { "LowFree",    N_("Free Low Memory") },
+        { "SwapTotal",  N_("Virtual Memory") },
+        { "SwapFree",   N_("Free Virtual Memory") },
+        { NULL },
+    };
+    gint i;
+
+    memlabels = g_hash_table_new(g_str_hash, g_str_equal);
+
+    for (i = 0; proc2real[i].proc_label; i++) {
+        g_hash_table_insert(memlabels, proc2real[i].proc_label,
+            _(proc2real[i].real_label));
+    }
+}
diff --git a/modules/devices/dmi.c b/modules/devices/dmi.c
new file mode 100644
index 0000000..b25cfe2
--- /dev/null
+++ b/modules/devices/dmi.c
@@ -0,0 +1,140 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+/*
+ * DMI support based on patch by Stewart Adam <s.adam@diffingo.com>
+ */
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "devices.h"
+#include "dmi_util.h"
+
+typedef struct _DMIInfo		DMIInfo;
+
+struct _DMIInfo {
+  const gchar *name;
+  const gchar *id_str;
+  int group;
+};
+
+DMIInfo dmi_info_table[] = {
+  { N_("Product"), NULL, 1 },
+  { N_("Name"), "system-product-name", 0 },
+  { N_("Family"), "system-product-family", 0 },
+  { N_("Vendor"), "system-manufacturer", 0 },
+  { N_("Version"), "system-version", 0 },
+  { N_("BIOS"), NULL, 1 },
+  { N_("Date"), "bios-release-date", 0 },
+  { N_("Vendor"), "bios-vendor", 0 },
+  { N_("Version"), "bios-version", 0 },
+  { N_("Board"), NULL, 1 },
+  { N_("Name"), "baseboard-product-name", 0 },
+  { N_("Vendor"), "baseboard-manufacturer", 0 },
+  { N_("Version"), "baseboard-version", 0 },
+  { N_("Serial Number"), "baseboard-serial-number", 0 },
+  { N_("Asset Tag"), "baseboard-asset-tag", 0 },
+  { N_("Chassis"), NULL, 1 },
+  { N_("Vendor"), "chassis-manufacturer", 0 },
+  { N_("Type"), "chassis-type", 0 },
+  { N_("Version"), "chassis-version", 0 },
+  { N_("Serial Number"), "chassis-serial-number", 0 },
+  { N_("Asset Tag"), "chassis-asset-tag", 0 },
+};
+
+gchar *dmi_info = NULL;
+
+static void add_to_moreinfo(const char *group, const char *key, char *value)
+{
+  char *new_key = g_strconcat("DMI:", group, ":", key, NULL);
+  moreinfo_add_with_prefix("DEV", new_key, g_strdup(g_strstrip(value)));
+}
+
+gboolean dmi_get_info()
+{
+  const gchar *group = NULL;
+  DMIInfo *info;
+  gboolean dmi_succeeded = FALSE;
+  gint i;
+  gchar *value;
+
+  if (dmi_info) {
+    g_free(dmi_info);
+    dmi_info = NULL;
+  }
+
+  for (i = 0; i < G_N_ELEMENTS(dmi_info_table); i++) {
+    info = &dmi_info_table[i];
+
+    if (info->group) {
+      group = info->name;
+      dmi_info = h_strdup_cprintf("[%s]\n", dmi_info, _(info->name) );
+    } else if (group && info->id_str) {
+      if (strcmp(info->id_str, "chassis-type") == 0)
+        value = dmi_chassis_type_str(-1, 1);
+      else
+        value = dmi_get_str(info->id_str);
+
+      if (value != NULL) {
+        add_to_moreinfo(group, info->name, value);
+
+        const gchar *url = vendor_get_url(value);
+        if (url) {
+          const gchar *vendor = vendor_get_name(value);
+          dmi_info = h_strdup_cprintf("%s=%s (%s, %s)\n",
+                                      dmi_info,
+                                      _(info->name),
+                                      value,
+                                      vendor, url);
+        } else {
+          dmi_info = h_strdup_cprintf("%s=%s\n",
+                                      dmi_info,
+                                      _(info->name),
+                                      value);
+        }
+        dmi_succeeded = TRUE;
+      } else {
+        dmi_info = h_strdup_cprintf("%s=%s\n",
+                                    dmi_info,
+                                    _(info->name),
+                                    (getuid() == 0)
+                                      ? _("(Not available)")
+                                      : _("(Not available; Perhaps try running HardInfo as root.)") );
+      }
+    }
+  }
+
+  if (!dmi_succeeded) {
+    g_free(dmi_info);
+    dmi_info = NULL;
+  }
+
+  return dmi_succeeded;
+}
+
+void __scan_dmi()
+{
+  gboolean dmi_ok;
+
+  dmi_ok = dmi_get_info();
+
+  if (!dmi_ok) {
+    dmi_info = g_strdup("[No DMI information]\n"
+                        "There was an error retrieving the information.=\n"
+                        "Please try running HardInfo as root.=\n");
+  }
+}
diff --git a/modules/devices/ia64/processor.c b/modules/devices/ia64/processor.c
new file mode 100644
index 0000000..c4d06a7
--- /dev/null
+++ b/modules/devices/ia64/processor.c
@@ -0,0 +1,215 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+
+GSList *
+processor_scan(void)
+{
+    GSList *procs = NULL;
+    Processor *processor = NULL;
+    FILE *cpuinfo;
+    gchar buffer[128];
+    gchar *rep_pname = NULL;
+    GSList *pi = NULL;
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+        return NULL;
+
+#define CHECK_FOR(k) (g_str_has_prefix(tmp[0], k))
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+        if (tmp[0] && tmp[1]) {
+            tmp[0] = g_strstrip(tmp[0]);
+            tmp[1] = g_strstrip(tmp[1]);
+        } else {
+            g_strfreev(tmp);
+            continue;
+        }
+
+        get_str("Processor", rep_pname);
+
+        if ( CHECK_FOR("processor") ) {
+            /* finish previous */
+            if (processor) {
+                procs = g_slist_append(procs, processor);
+            }
+
+            /* start next */
+            processor = g_new0(Processor, 1);
+            processor->id = atol(tmp[1]);
+
+            if (rep_pname)
+                processor->model_name = g_strdup(rep_pname);
+
+            g_strfreev(tmp);
+            continue;
+        }
+
+        if (!processor &&
+            (  CHECK_FOR("vendor")
+            || CHECK_FOR("arch")
+            || CHECK_FOR("family") ) ) {
+
+            /* single proc/core may not have "processor : n" */
+            processor = g_new0(Processor, 1);
+            processor->id = 0;
+
+            if (rep_pname)
+                processor->model_name = g_strdup(rep_pname);
+        }
+
+        if (processor) {
+            get_str("vendor", processor->vendor_id);
+            get_str("archrev", processor->archrev);
+            get_str("arch", processor->arch);
+            get_str("family", processor->family);
+            get_str("features", processor->features);
+            get_int("model", processor->model);
+            get_int("revision", processor->revision);
+            get_float("BogoMIPS", processor->bogomips);
+            get_float("cpu MHz", processor->cpu_mhz);
+            get_int("cpu regs", processor->cpu_regs);
+        }
+        g_strfreev(tmp);
+    }
+
+    if (processor)
+        procs = g_slist_append(procs, processor);
+
+    g_free(rep_pname);
+    fclose(cpuinfo);
+
+    /* TODO: redup */
+
+    /* data not from /proc/cpuinfo */
+    for (pi = procs; pi; pi = pi->next) {
+        processor = (Processor *) pi->data;
+
+        /* strings can't be null or segfault later */
+        STRIFNULL(processor->model_name, _("IA64 Processor") );
+        UNKIFNULL(processor->vendor_id);
+        STRIFNULL(processor->arch, "IA-64");
+        STRIFNULL(processor->archrev, "0");
+        UNKIFNULL(processor->family);
+        UNKIFNULL(processor->features);
+
+        /* topo & freq */
+        processor->cpufreq = cpufreq_new(processor->id);
+        processor->cputopo = cputopo_new(processor->id);
+
+        if (processor->cpufreq->cpukhz_max)
+            processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+
+    }
+
+    return procs;
+}
+
+gchar *processor_name(GSList * processors) {
+    return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_default(processors);
+}
+
+gchar *
+processor_get_detailed_info(Processor *processor)
+{
+    gchar *tmp_cpufreq, *tmp_topology, *ret;
+
+    tmp_topology = cputopo_section_str(processor->cputopo);
+    tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+    ret = g_strdup_printf("[%s]\n"
+                        "%s=%s\n"      /* name */
+                        "%s=%s\n"      /* vendor */
+                        "%s=%s\n"      /* arch */
+                        "%s=%s\n"      /* archrev */
+                        "%s=%s\n"      /* family */
+                        "%s=%d\n"      /* model no. */
+                        "%s=%d\n"      /* revision */
+                        "%s=%.2f %s\n" /* frequency */
+                        "%s=%.2f\n"    /* bogomips */
+                        "%s=%s\n"      /* byte order */
+                        "%s=%d\n"      /* regs */
+                        "%s=%s\n"      /* features */
+                        "%s" /* topology */
+                        "%s" /* frequency scaling */
+                        "%s",/* empty */
+                    _("Processor"),
+                    _("Name"), processor->model_name,
+                    _("Vendor"), processor->vendor_id,
+                    _("Architecture"), processor->arch,
+                    _("Architecture Revision"), processor->archrev,
+                    _("Family"), processor->family,
+                    _("Model"), processor->model,
+                    _("Revision"), processor->revision,
+                    _("Frequency"), processor->cpu_mhz, _("MHz"),
+                    _("BogoMips"), processor->bogomips,
+                    _("Byte Order"), byte_order_str(),
+                    _("CPU regs"), processor->cpu_regs,
+                    _("Features"), processor->features,
+                    tmp_topology,
+                    tmp_cpufreq,
+                    "");
+    g_free(tmp_cpufreq);
+    g_free(tmp_topology);
+    return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
+{
+    Processor *processor;
+
+    if (g_slist_length(processors) > 1) {
+    gchar *ret, *tmp, *hashkey;
+    GSList *l;
+
+    tmp = g_strdup("");
+
+    for (l = processors; l; l = l->next) {
+        processor = (Processor *) l->data;
+
+        tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+                  tmp, processor->id,
+                  processor->model_name,
+                  processor->cpu_mhz, _("MHz"));
+
+        hashkey = g_strdup_printf("CPU%d", processor->id);
+        moreinfo_add_with_prefix("DEV", hashkey,
+                processor_get_detailed_info(processor));
+           g_free(hashkey);
+    }
+
+    ret = g_strdup_printf("[$ShellParam$]\n"
+                  "ViewType=1\n"
+                  "[Processors]\n"
+                  "%s", tmp);
+    g_free(tmp);
+
+    return ret;
+    }
+
+    processor = (Processor *) processors->data;
+    return processor_get_detailed_info(processor);
+}
diff --git a/modules/devices/inputdevices.c b/modules/devices/inputdevices.c
new file mode 100644
index 0000000..cf1728a
--- /dev/null
+++ b/modules/devices/inputdevices.c
@@ -0,0 +1,140 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "hardinfo.h"
+#include "devices.h"
+
+gchar *input_icons = NULL;
+
+static struct {
+    char *name;
+    char *icon;
+} input_devices[] = {
+    { "Keyboard", "keyboard.png" },
+    { "Joystick", "joystick.png" },
+    { "Mouse",    "mouse.png"    },
+    { "Speaker",  "audio.png"  },
+    { "Unknown",  "module.png"   },
+};
+
+void
+__scan_input_devices(void)
+{
+    FILE *dev;
+    gchar buffer[1024];
+    gchar *tmp, *name = NULL, *phys = NULL;
+    gint bus = 0, vendor = 0, product = 0, version = 0;
+    int d = 0, n = 0;
+
+    dev = fopen("/proc/bus/input/devices", "r");
+    if (!dev)
+	return;
+
+    if (input_list) {
+        moreinfo_del_with_prefix("DEV:INP");
+	g_free(input_list);
+	g_free(input_icons);
+    }
+    input_list = g_strdup("");
+    input_icons = g_strdup("");
+
+    while (fgets(buffer, sizeof(buffer), dev)) {
+	tmp = buffer;
+
+	switch (*tmp) {
+	case 'N':
+	    tmp = strreplacechr(tmp + strlen("N: Name="), "=", ':');
+	    name = g_strdup(tmp);
+	    remove_quotes(name);
+	    break;
+	case 'P':
+	    phys = g_strdup(tmp + strlen("P: Phys="));
+	    break;
+	case 'I':
+	    sscanf(tmp, "I: Bus=%x Vendor=%x Product=%x Version=%x",
+		   &bus, &vendor, &product, &version);
+	    break;
+	case 'H':
+	    if (strstr(tmp, "kbd"))
+		d = 0;		//INPUT_KEYBOARD;
+	    else if (strstr(tmp, "js"))
+		d = 1;		//INPUT_JOYSTICK;
+	    else if (strstr(tmp, "mouse"))
+		d = 2;		//INPUT_MOUSE;
+	    else
+		d = 4;		//INPUT_UNKNOWN;
+	    break;
+	case '\n':
+	    if (name && strstr(name, "PC Speaker")) {
+	      d = 3;		// INPUT_PCSPKR
+	    }
+
+        tmp = g_strdup_printf("INP%d", ++n);
+        input_list = h_strdup_cprintf("$%s$%s=\n",
+                     input_list,
+                     tmp, name);
+        input_icons = h_strdup_cprintf("Icon$%s$%s=%s\n",
+                      input_icons,
+                      tmp, name,
+                      input_devices[d].icon);
+
+        const gchar *v_url = (gchar*)vendor_get_url(name);
+        const gchar *v_name = (gchar*)vendor_get_name(name);
+        gchar *v_str = NULL;
+        if (v_url != NULL)
+            v_str = g_strdup_printf("[0x%x] %s (%s)", vendor, v_name, v_url);
+        else
+            v_str = g_strdup_printf("0x%x", vendor);
+        v_str = hardinfo_clean_value(v_str, 1);
+        name = hardinfo_clean_value(name, 1);
+
+        gchar *strhash = g_strdup_printf("[%s]\n"
+                /* Name */   "%s=%s\n"
+                /* Type */   "%s=%s\n"
+                /* Bus */    "%s=0x%x\n"
+                /* Vendor */ "%s=%s\n"
+                /* Product */"%s=0x%x\n"
+                /* Version */"%s=0x%x\n",
+                        _("Device Information"),
+                        _("Name"), name,
+                        _("Type"), input_devices[d].name,
+                        _("Bus"), bus,
+                        _("Vendor"), v_str,
+                        _("Product"), product,
+                        _("Version"), version );
+
+        if (phys && phys[1] != 0) {
+             strhash = h_strdup_cprintf("%s=%s\n", strhash, _("Connected to"), phys);
+        }
+
+        if (phys && strstr(phys, "ir")) {
+            strhash = h_strdup_cprintf("%s=%s\n", strhash, _("InfraRed port"), _("Yes") );
+        }
+
+        moreinfo_add_with_prefix("DEV", tmp, strhash);
+        g_free(tmp);
+        g_free(v_str);
+        g_free(phys);
+        g_free(name);
+    }
+    }
+
+    fclose(dev);
+}
diff --git a/modules/devices/m68k/processor.c b/modules/devices/m68k/processor.c
new file mode 100644
index 0000000..e030732
--- /dev/null
+++ b/modules/devices/m68k/processor.c
@@ -0,0 +1,92 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+
+GSList *
+processor_scan(void)
+{
+    Processor *processor;
+    FILE *cpuinfo;
+    gchar buffer[128];
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+        return NULL;
+
+    processor = g_new0(Processor, 1);
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+
+        if (tmp[0] && tmp[1]) {
+            tmp[0] = g_strstrip(tmp[0]);
+            tmp[1] = g_strstrip(tmp[1]);
+
+            get_str("CPU", processor->model_name);
+            get_str("MMU", processor->mmu_name);
+            get_str("FPU", processor->fpu_name);
+            get_float("Clocking", processor->cpu_mhz);
+            get_float("BogoMips", processor->bogomips);
+            get_str("Calibration", processor->calibration);
+        }
+        g_strfreev(tmp);
+    }
+
+    gchar *tmp;
+    tmp = g_strconcat("Motorola ", processor->model_name, NULL);
+    g_free(processor->model_name);
+    processor->model_name = tmp;
+
+    fclose(cpuinfo);
+
+    return g_slist_append(NULL, processor);
+}
+
+gchar *processor_name(GSList * processors) {
+    return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_default(processors);
+}
+
+gchar *
+processor_get_info(GSList *processors)
+{
+    Processor *processor = (Processor *)processors->data;
+
+    return g_strdup_printf("[%s]\n"
+                        "%s=%s\n"      /* cpu */
+                        "%s=%s\n"      /* mmu */
+                        "%s=%s\n"      /* fpu */
+                        "%s=%.2f %s\n" /* frequency */
+                        "%s=%.2f\n"    /* bogomips */
+                        "%s=%s\n"      /* byte order */
+                        "%s=%s\n",     /* calibration */
+                    _("Processor"),
+                    _("Model"), processor->model_name,
+                    _("MMU"), processor->mmu_name,
+                    _("FPU"), processor->fpu_name,
+                    _("Frequency"), processor->cpu_mhz, _("MHz"),
+                    _("BogoMips"), processor->bogomips,
+                    _("Byte Order"), byte_order_str(),
+                    _("Calibration"), processor->calibration
+                        );
+}
diff --git a/modules/devices/mips/processor.c b/modules/devices/mips/processor.c
new file mode 100644
index 0000000..b31af7d
--- /dev/null
+++ b/modules/devices/mips/processor.c
@@ -0,0 +1,81 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+
+GSList *
+processor_scan(void)
+{
+    Processor *processor;
+    FILE *cpuinfo;
+    gchar buffer[128];
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+        return NULL;
+
+    processor = g_new0(Processor, 1);
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+
+        if (tmp[0] && tmp[1]) {
+            tmp[0] = g_strstrip(tmp[0]);
+            tmp[1] = g_strstrip(tmp[1]);
+
+            get_str("system type", processor->vendor_id);
+            get_str("cpu model", processor->model_name);
+            get_float("cpu MHz", processor->cpu_mhz);
+            get_float("BogoMIPS", processor->bogomips);
+        }
+        g_strfreev(tmp);
+    }
+
+    fclose(cpuinfo);
+
+    return g_slist_append(NULL, processor);
+}
+
+gchar *processor_name(GSList * processors) {
+    return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_default(processors);
+}
+
+gchar *
+processor_get_info(GSList *processors)
+{
+    Processor *processor = (Processor *)processors->data;
+
+    return g_strdup_printf("[%s]\n"
+                        "%s=%s\n"
+                        "%s=%s\n"
+                        "%s=%.2f %s\n" /* frequency */
+                        "%s=%.2f\n"    /* bogomips */
+                        "%s=%s\n",     /* byte order */
+                    _("Processor"),
+                    _("Model"), processor->model_name,
+                    _("System Type"), processor->vendor_id,
+                    _("Frequency"), processor->cpu_mhz, _("MHz"),
+                    _("BogoMips"), processor->bogomips,
+                    _("Byte Order"), byte_order_str()
+                   );
+}
diff --git a/modules/devices/parisc/processor.c b/modules/devices/parisc/processor.c
new file mode 100644
index 0000000..9ca38d1
--- /dev/null
+++ b/modules/devices/parisc/processor.c
@@ -0,0 +1,210 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+
+GSList *
+processor_scan(void)
+{
+    GSList *procs = NULL;
+    Processor *processor = NULL;
+    FILE *cpuinfo;
+    gchar buffer[128];
+    gchar *rep_pname = NULL;
+    GSList *pi = NULL;
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+        return NULL;
+
+#define CHECK_FOR(k) (g_str_has_prefix(tmp[0], k))
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+        if (tmp[0] && tmp[1]) {
+            tmp[0] = g_strstrip(tmp[0]);
+            tmp[1] = g_strstrip(tmp[1]);
+        } else {
+            g_strfreev(tmp);
+            continue;
+        }
+
+        get_str("Processor", rep_pname);
+
+        if ( CHECK_FOR("processor") ) {
+            /* finish previous */
+            if (processor) {
+                procs = g_slist_append(procs, processor);
+            }
+
+            /* start next */
+            processor = g_new0(Processor, 1);
+            processor->id = atol(tmp[1]);
+
+            if (rep_pname)
+                processor->model_name = g_strdup(rep_pname);
+
+            g_strfreev(tmp);
+            continue;
+        }
+
+        if (!processor &&
+            (  CHECK_FOR("cpu family")
+            || CHECK_FOR("cpu MHz")
+            || CHECK_FOR("cpu") ) ) {
+
+            /* single proc/core may not have "processor : n" */
+            processor = g_new0(Processor, 1);
+            processor->id = 0;
+
+            if (rep_pname)
+                processor->model_name = g_strdup(rep_pname);
+        }
+
+        if (processor) {
+            get_str("cpu family", processor->cpu_family);
+            get_float("cpu MHz", processor->cpu_mhz);
+            get_str("cpu", processor->model_name);
+            get_float("bogomips", processor->bogomips);
+            get_str("model name", processor->strmodel);
+            get_str("I-cache", processor->icache_str);
+            get_str("D-cache", processor->dcache_str);
+            get_str("hversion", processor->hversion);
+            get_str("sversion", processor->sversion);
+        }
+        g_strfreev(tmp);
+    }
+
+    if (processor)
+        procs = g_slist_append(procs, processor);
+
+    g_free(rep_pname);
+    fclose(cpuinfo);
+
+    /* TODO: redup */
+
+    /* data not from /proc/cpuinfo */
+    for (pi = procs; pi; pi = pi->next) {
+        processor = (Processor *) pi->data;
+
+        /* strings can't be null or segfault later */
+        STRIFNULL(processor->model_name, _("PA-RISC Processor") );
+        STRIFNULL(processor->cpu_family, "PA-RISC");
+        UNKIFNULL(processor->strmodel);
+
+        /* topo & freq */
+        processor->cpufreq = cpufreq_new(processor->id);
+        processor->cputopo = cputopo_new(processor->id);
+
+        if (processor->cpufreq->cpukhz_max)
+            processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+
+    }
+
+    return procs;
+}
+
+gchar *processor_name(GSList * processors) {
+    return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_default(processors);
+}
+
+gchar *
+processor_get_detailed_info(Processor *processor)
+{
+    gchar *tmp_cpufreq, *tmp_topology, *ret;
+
+    tmp_topology = cputopo_section_str(processor->cputopo);
+    tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+    ret = g_strdup_printf("[%s]\n"
+                        "%s=%s\n"
+                        "%s=%s\n"
+                        "%s=%s\n"      /* model name */
+                        "%s=%.2f %s\n" /* frequency */
+                        "%s=%.2f\n"    /* bogomips */
+                        "%s=%s\n"      /* byte order */
+                        "%s=%s\n"      /* hversion */
+                        "%s=%s\n"      /* sversion */
+                        "[%s]\n"
+                        "I-Cache=%s\n"
+                        "D-Cache=%s\n"
+                        "%s" /* topology */
+                        "%s" /* frequency scaling */
+                        "%s",/* empty */
+                   _("Processor"),
+                   _("Model"), processor->model_name,
+                   _("Architecture"), processor->cpu_family,
+                   _("System"), processor->strmodel,
+                   _("Frequency"), processor->cpu_mhz, _("MHz"),
+                   _("BogoMips"), processor->bogomips,
+                   _("Byte Order"), byte_order_str(),
+                   _("HVersion"), processor->hversion,
+                   _("SVersion"), processor->sversion,
+                   _("Cache"),
+                   processor->icache_str,
+                   processor->dcache_str,
+                   tmp_topology,
+                   tmp_cpufreq,
+                    "");
+
+    g_free(tmp_cpufreq);
+    g_free(tmp_topology);
+    return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
+{
+    Processor *processor;
+
+    if (g_slist_length(processors) > 1) {
+    gchar *ret, *tmp, *hashkey;
+    GSList *l;
+
+    tmp = g_strdup("");
+
+    for (l = processors; l; l = l->next) {
+        processor = (Processor *) l->data;
+
+        tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+                  tmp, processor->id,
+                  processor->model_name,
+                  processor->cpu_mhz, _("MHz"));
+
+        hashkey = g_strdup_printf("CPU%d", processor->id);
+        moreinfo_add_with_prefix("DEV", hashkey,
+                processor_get_detailed_info(processor));
+           g_free(hashkey);
+    }
+
+    ret = g_strdup_printf("[$ShellParam$]\n"
+                  "ViewType=1\n"
+                  "[Processors]\n"
+                  "%s", tmp);
+    g_free(tmp);
+
+    return ret;
+    }
+
+    processor = (Processor *) processors->data;
+    return processor_get_detailed_info(processor);
+}
diff --git a/modules/devices/pci.c b/modules/devices/pci.c
new file mode 100644
index 0000000..c1965a6
--- /dev/null
+++ b/modules/devices/pci.c
@@ -0,0 +1,254 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/*
+ * TODO: This thing must be rewritten. We really should have a struct with all the
+ *       PCI stuff we'll present to the user, and hash them by the PCI ID
+ *       (domain:bus:device.function).
+ *       This way we'll have ways to better organize the output, instead of relying
+ *       on the order the information appears on lspci's output.
+ *       Also, the "Resources" thing might be better implemented (and we won't need
+ *       copies of information scattered everywhere like we do today).
+ */
+
+#include <string.h>
+
+#include "hardinfo.h"
+#include "devices.h"
+
+GHashTable *_pci_devices = NULL;
+
+void
+scan_pci_do(void)
+{
+    FILE *lspci;
+    gchar buffer[256], *buf, *strhash = NULL, *strdevice = NULL;
+    gchar *category = NULL, *name = NULL, *icon, *lspci_path, *command_line = NULL;
+    gint n = 0, x = 0;
+
+    if ((lspci_path = find_program("lspci")) == NULL) {
+      goto pci_error;
+    } else {
+      command_line = g_strdup_printf("%s -v", lspci_path);
+    }
+
+    if (!_pci_devices) {
+      _pci_devices = g_hash_table_new(g_str_hash, g_str_equal);
+    }
+
+    buf = g_build_filename(g_get_home_dir(), ".hardinfo", "pci.ids", NULL);
+    if (!g_file_test(buf, G_FILE_TEST_EXISTS)) {
+      DEBUG("using system-provided PCI IDs");
+      g_free(buf);
+      if (!(lspci = popen(command_line, "r"))) {
+        goto pci_error;
+      }
+    } else {
+      gchar *tmp;
+
+      tmp = g_strdup_printf("%s -i '%s'", command_line, buf);
+      g_free(buf);
+      buf = tmp;
+
+      DEBUG("using updated PCI IDs (from %s)", buf);
+      if (!(lspci = popen(tmp, "r"))) {
+        g_free(buf);
+        goto pci_error;
+      } else {
+        g_free(buf);
+      }
+    }
+
+    while (fgets(buffer, 256, lspci)) {
+	buf = g_strstrip(buffer);
+
+	if (!strncmp(buf, "Flags", 5)) {
+	    gint irq = 0, freq = 0, latency = 0, i;
+	    gchar **list;
+	    gboolean bus_master;
+
+	    buf += 7;
+
+	    bus_master = FALSE;
+
+	    list = g_strsplit(buf, ", ", 10);
+	    for (i = 0; i <= 10; i++) {
+		if (!list[i])
+		    break;
+
+		if (!strncmp(list[i], "IRQ", 3))
+		    sscanf(list[i], "IRQ %d", &irq);
+		else if (strstr(list[i], "Mhz"))
+		    sscanf(list[i], "%dMhz", &freq);
+		else if (!strncmp(list[i], "bus master", 10))
+		    bus_master = TRUE;
+		else if (!strncmp(list[i], "latency", 7))
+		    sscanf(list[i], "latency %d", &latency);
+	    }
+	    g_strfreev(list);
+
+	    if (irq)
+		strdevice = h_strdup_cprintf("%s=%d\n", strdevice, _("IRQ"), irq);
+	    if (freq)
+		strdevice = h_strdup_cprintf("%s=%d %s\n", strdevice, _("Frequency"), freq, _("MHz") );
+	    if (latency)
+		strdevice = h_strdup_cprintf("%s=%d\n", strdevice, _("Latency"), latency);
+
+	    strdevice = h_strdup_cprintf("%s=%s\n", strdevice, _("Bus Master"), bus_master ? _("Yes") : _("No") );
+	} else if (!strncmp(buf, "Kernel modules", 14)) {
+	    WALK_UNTIL(' ');
+	    WALK_UNTIL(':');
+	    buf++;
+
+	    strdevice = h_strdup_cprintf("%s=%s\n", strdevice, _("Kernel modules"), buf);
+	} else if (!strncmp(buf, "Subsystem", 9)) {
+	    WALK_UNTIL(' ');
+	    buf++;
+	    const gchar *oem_vendor_url = vendor_get_url(buf);
+            if (oem_vendor_url)
+                strdevice = h_strdup_cprintf(_("%s=%s (%s)\n"),
+                                            strdevice,
+                                            _("OEM Vendor"),
+                                            vendor_get_name(buf),
+                                            oem_vendor_url);
+	} else if (!strncmp(buf, "Capabilities", 12)
+		   && !strstr(buf, "only to root") &&
+		      !strstr(buf, "access denied")) {
+	    WALK_UNTIL(' ');
+	    WALK_UNTIL(']');
+	    buf++;
+	    strdevice = h_strdup_cprintf("Capability#%d=%s\n", strdevice, ++x, buf);
+	} else if (!strncmp(buf, "Memory at", 9) && strstr(buf, "[size=")) {
+	    gint mem;
+	    gchar unit;
+	    gboolean prefetch;
+	    gboolean _32bit;
+
+	    prefetch = strstr(buf, "non-prefetchable") ? FALSE : TRUE;
+	    _32bit = strstr(buf, "32-bit") ? TRUE : FALSE;
+
+	    WALK_UNTIL('[');
+	    sscanf(buf, "[size=%d%c", &mem, &unit);
+
+	    strdevice = h_strdup_cprintf("%s#%d=%d%cB (%s%s)\n",
+					strdevice, _("Memory"), ++x,
+					mem,
+					(unit == ']') ? ' ' : unit,
+					_32bit ? "32-bit, " : "",
+					prefetch ? _("prefetchable") :
+					_("non-prefetchable") );
+
+	} else if (!strncmp(buf, "I/O ports at", 12)) {
+	    guint io_addr, io_size;
+
+	    sscanf(buf, "I/O ports at %x [size=%d]", &io_addr, &io_size);
+
+	    strdevice =
+		h_strdup_cprintf("%s#%d=0x%x - 0x%x\n",
+				strdevice, _("I/O ports at"), ++x, io_addr,
+				io_addr + io_size - 1);
+	} else if ((buf[0] >= '0' && buf[0] <= '9') && (buf[4] == ':' || buf[2] == ':')) {
+	    gint bus, device, function, domain;
+	    gpointer start, end;
+
+	    if (strdevice != NULL && strhash != NULL) {
+                moreinfo_add_with_prefix("DEV", strhash, strdevice);
+                g_free(strhash);
+                g_free(category);
+                g_free(name);
+	    }
+
+	    if (buf[4] == ':') {
+		sscanf(buf, "%x:%x:%x.%d", &domain, &bus, &device, &function);
+	    } else {
+	    	/* lspci without domain field */
+	    	sscanf(buf, "%x:%x.%x", &bus, &device, &function);
+	    	domain = 0;
+	    }
+
+	    WALK_UNTIL(' ');
+
+	    start = buf;
+
+	    WALK_UNTIL(':');
+	    end = buf + 1;
+	    *buf = 0;
+
+	    buf = start + 1;
+	    category = g_strdup(buf);
+
+	    buf = end;
+
+            if (strstr(category, "RAM memory")) icon = "mem";
+            else if (strstr(category, "Multimedia")) icon = "media";
+            else if (strstr(category, "USB")) icon = "usb";
+            else icon = "pci";
+
+	    name = g_strdup(buf);
+            g_hash_table_insert(_pci_devices,
+                                g_strdup_printf("0000:%02x:%02x.%x", bus, device, function),
+                                name);
+
+        strhash = g_strdup_printf("PCI%d", n);
+        strdevice = g_strdup_printf("[%s]\n"
+               /* Name */   "%s=%s\n"
+               /* Class */  "%s=%s\n"
+               /* Domain */ "%s=%d\n"
+               /* Bus, device, function */
+                            "%s=%d, %d, %d\n",
+                    _("Device Information"),
+                    _("Name"), name,
+                    _("Class"), category,
+                    _("Domain"), domain,
+                    _("Bus, device, function"),
+                    bus, device, function);
+
+            const gchar *url = vendor_get_url(name);
+            if (url) {
+                strdevice = h_strdup_cprintf("%s=%s (%s)\n",
+                                            strdevice,
+                                            _("Vendor"),
+                                            vendor_get_name(name),
+                                            url);
+            }
+
+            g_hash_table_insert(_pci_devices,
+                                g_strdup_printf("0000:%02x:%02x.%x", bus, device, function),
+                                g_strdup(name));
+
+	    pci_list = h_strdup_cprintf("$PCI%d$%s=%s\n", pci_list, n, category, name);
+
+	    n++;
+	}
+    }
+
+    if (pclose(lspci)) {
+pci_error:
+        /* error (no pci, perhaps?) */
+        pci_list = g_strconcat(pci_list, _("No PCI devices found"), "=\n", NULL);
+    } else if (strhash) {
+        /* insert the last device */
+        moreinfo_add_with_prefix("DEV", strhash, strdevice);
+        g_free(strhash);
+        g_free(category);
+        g_free(name);
+    }
+
+    g_free(lspci_path);
+    g_free(command_line);
+}
diff --git a/modules/devices/ppc/processor.c b/modules/devices/ppc/processor.c
new file mode 100644
index 0000000..3360a13
--- /dev/null
+++ b/modules/devices/ppc/processor.c
@@ -0,0 +1,206 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+
+GSList *
+processor_scan(void)
+{
+    GSList *procs = NULL;
+    Processor *processor = NULL;
+    FILE *cpuinfo;
+    gchar buffer[128];
+    gchar *rep_pname = NULL;
+    GSList *pi = NULL;
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+    return NULL;
+
+#define CHECK_FOR(k) (g_str_has_prefix(tmp[0], k))
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+        if (tmp[0] && tmp[1]) {
+            tmp[0] = g_strstrip(tmp[0]);
+            tmp[1] = g_strstrip(tmp[1]);
+        } else {
+            g_strfreev(tmp);
+            continue;
+        }
+
+        get_str("Processor", rep_pname);
+
+        if ( CHECK_FOR("processor") ) {
+            /* finish previous */
+            if (processor) {
+                procs = g_slist_append(procs, processor);
+            }
+
+            /* start next */
+            processor = g_new0(Processor, 1);
+            processor->id = atol(tmp[1]);
+
+            if (rep_pname)
+                processor->model_name = g_strdup(rep_pname);
+
+            g_strfreev(tmp);
+            continue;
+        }
+
+        if (!processor &&
+            (  CHECK_FOR("cpu")
+            || CHECK_FOR("clock")
+            || CHECK_FOR("revision") ) ) {
+
+            /* single proc/core may not have "processor : n" */
+            processor = g_new0(Processor, 1);
+            processor->id = 0;
+
+            if (rep_pname)
+                processor->model_name = g_strdup(rep_pname);
+        }
+
+        if (processor) {
+            get_str("cpu", processor->model_name);
+            get_str("revision", processor->revision);
+            get_float("clock", processor->cpu_mhz);
+            get_float("BogoMIPS", processor->bogomips);
+        }
+        g_strfreev(tmp);
+    }
+
+    if (processor)
+        procs = g_slist_append(procs, processor);
+
+    g_free(rep_pname);
+    fclose(cpuinfo);
+
+    /* re-duplicate missing data for /proc/cpuinfo variant that de-duplicated it */
+#define REDUP(f) if (dproc->f && !processor->f) processor->f = g_strdup(dproc->f);
+    Processor *dproc;
+    GSList *l;
+    l = procs = g_slist_reverse(procs);
+    while (l) {
+        processor = l->data;
+        if (processor->model_name) {
+            dproc = processor;
+        } else if (dproc) {
+            REDUP(model_name);
+            REDUP(revision);
+        }
+        l = g_slist_next(l);
+    }
+    procs = g_slist_reverse(procs);
+
+    /* data not from /proc/cpuinfo */
+    for (pi = procs; pi; pi = pi->next) {
+        processor = (Processor *) pi->data;
+
+        /* strings can't be null or segfault later */
+        STRIFNULL(processor->model_name, _("POWER Processor") );
+        UNKIFNULL(processor->revision);
+
+        /* topo & freq */
+        processor->cpufreq = cpufreq_new(processor->id);
+        processor->cputopo = cputopo_new(processor->id);
+
+        if (processor->cpufreq->cpukhz_max)
+            processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+
+    }
+
+    return procs;
+}
+
+gchar *processor_name(GSList * processors) {
+    return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_default(processors);
+}
+
+gchar *
+processor_get_detailed_info(Processor *processor)
+{
+    gchar *tmp_cpufreq, *tmp_topology, *ret;
+
+    tmp_topology = cputopo_section_str(processor->cputopo);
+    tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+    ret = g_strdup_printf("[%s]\n"
+                   "%s=%s\n"  /* model */
+                   "%s=%s\n"  /* revision */
+                   "%s=%.2f %s\n" /* frequency */
+                   "%s=%.2f\n"    /* bogomips */
+                   "%s=%s\n"      /* byte order */
+                   "%s" /* topology */
+                   "%s" /* frequency scaling */
+                   "%s",/* empty */
+                   _("Processor"),
+                   _("Model"), processor->model_name,
+                   _("Revision"), processor->revision,
+                   _("Frequency"), processor->cpu_mhz, _("MHz"),
+                   _("BogoMips"), processor->bogomips,
+                   _("Byte Order"), byte_order_str(),
+                   tmp_topology,
+                   tmp_cpufreq,
+                    "");
+    g_free(tmp_cpufreq);
+    g_free(tmp_topology);
+    return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
+{
+    Processor *processor;
+
+    if (g_slist_length(processors) > 1) {
+    gchar *ret, *tmp, *hashkey;
+    GSList *l;
+
+    tmp = g_strdup("");
+
+    for (l = processors; l; l = l->next) {
+        processor = (Processor *) l->data;
+
+        tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+                  tmp, processor->id,
+                  processor->model_name,
+                  processor->cpu_mhz, _("MHz"));
+
+        hashkey = g_strdup_printf("CPU%d", processor->id);
+        moreinfo_add_with_prefix("DEV", hashkey,
+                processor_get_detailed_info(processor));
+           g_free(hashkey);
+    }
+
+    ret = g_strdup_printf("[$ShellParam$]\n"
+                  "ViewType=1\n"
+                  "[Processors]\n"
+                  "%s", tmp);
+    g_free(tmp);
+
+    return ret;
+    }
+
+    processor = (Processor *) processors->data;
+    return processor_get_detailed_info(processor);
+}
diff --git a/modules/devices/printers.c b/modules/devices/printers.c
new file mode 100644
index 0000000..77b52a4
--- /dev/null
+++ b/modules/devices/printers.c
@@ -0,0 +1,266 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "devices.h"
+
+typedef struct _CUPSDest	CUPSDest;
+typedef struct _CUPSOption	CUPSOption;
+
+struct _CUPSOption {
+    char *name, *value;
+};
+
+struct _CUPSDest {
+    char *name, *instance;
+    int is_default;
+    int num_options;
+    CUPSOption *options;  
+};
+
+static int (*cups_dests_get) (CUPSDest **dests) = NULL;
+static int (*cups_dests_free) (int num_dests, CUPSDest *dests) = NULL;
+static gboolean cups_init = FALSE;
+
+GModule *cups;
+
+void
+init_cups(void)
+{
+    const char *libcups[] = { "libcups", "libcups.so", "libcups.so.1", "libcups.so.2", NULL };
+
+    if (!(cups_dests_get && cups_dests_free)) {
+        int i;
+        
+        for (i = 0; libcups[i] != NULL; i++) {
+            cups = g_module_open(libcups[i], G_MODULE_BIND_LAZY);
+            if (cups)
+                break; 
+        }
+        
+        if (!cups) {
+	    cups_init = FALSE;
+	    return;
+	}
+
+	if (!g_module_symbol(cups, "cupsGetDests", (gpointer) & cups_dests_get)
+	    || !g_module_symbol(cups, "cupsFreeDests", (gpointer) & cups_dests_free)) {
+            g_module_close(cups);
+	    cups_init = FALSE;
+	}
+    }
+    
+    cups_init = TRUE;
+}
+
+gchar *__cups_callback_ptype(gchar *strvalue)
+{
+  if (strvalue) {
+    unsigned value = atoi(strvalue);
+    gchar *output = g_strdup("\n");
+    
+    if (value & 0x0004)
+      output = h_strdup_cprintf(_("\342\232\254 Can do black and white printing=\n"), output);
+    if (value & 0x0008)
+      output = h_strdup_cprintf(_("\342\232\254 Can do color printing=\n"), output);
+    if (value & 0x0010)
+      output = h_strdup_cprintf(_("\342\232\254 Can do duplexing=\n"), output);
+    if (value & 0x0020)
+      output = h_strdup_cprintf(_("\342\232\254 Can do staple output=\n"), output);
+    if (value & 0x0040)
+      output = h_strdup_cprintf(_("\342\232\254 Can do copies=\n"), output);
+    if (value & 0x0080)
+      output = h_strdup_cprintf(_("\342\232\254 Can collate copies=\n"), output);
+    if (value & 0x80000)
+      output = h_strdup_cprintf(_("\342\232\254 Printer is rejecting jobs=\n"), output);
+    if (value & 0x1000000)
+      output = h_strdup_cprintf(_("\342\232\254 Printer was automatically discovered and added=\n"), output);
+
+    return output;
+  } else {
+    return g_strdup(_("Unknown"));
+  }
+}
+
+gchar *__cups_callback_state(gchar *value)
+{
+  if (!value) {
+    return g_strdup(_("Unknown"));
+  }
+
+  if (g_str_equal(value, "3")) {
+    return g_strdup(_("Idle"));
+  } else if (g_str_equal(value, "4")) {
+    return g_strdup(_("Printing a Job"));
+  } else if (g_str_equal(value, "5")) {
+    return g_strdup(_("Stopped"));
+  } else {
+    return g_strdup(_("Unknown"));
+  }
+}
+
+gchar *__cups_callback_state_change_time(gchar *value)
+{
+  struct tm tm;
+  char buf[255];
+  
+  if (value) {
+    strptime(value, "%s", &tm);
+    strftime(buf, sizeof(buf), "%c", &tm);
+
+    return g_strdup(buf);
+  } else {
+    return g_strdup(_("Unknown"));
+  }
+}
+
+gchar *__cups_callback_boolean(gchar *value)
+{
+  if (value) {
+    return g_strdup(g_str_equal(value, "1") ? _("Yes") : _("No"));
+  } else {
+    return g_strdup(_("Unknown"));
+  }
+}
+
+const struct {
+  char *key, *name;
+  gchar *(*callback)(gchar *value);
+} cups_fields[] = {
+  { "Printer Information", NULL, NULL },
+  { "printer-info", "Destination Name", NULL },
+  { "printer-make-and-model", "Make and Model", NULL },
+  
+  { "Capabilities", NULL, NULL },
+  { "printer-type", "#", __cups_callback_ptype },
+  
+  { "Printer State", NULL, NULL },
+  { "printer-state", "State", __cups_callback_state },
+  { "printer-state-change-time", "Change Time", __cups_callback_state_change_time },
+  { "printer-state-reasons", "State Reasons" },
+  
+  { "Sharing Information", NULL, NULL },
+  { "printer-is-shared", "Shared?", __cups_callback_boolean },
+  { "printer-location", "Physical Location" },
+  { "auth-info-required", "Authentication Required", __cups_callback_boolean },
+  
+  { "Jobs", NULL, NULL },
+  { "job-hold-until", "Hold Until", NULL },
+  { "job-priority", "Priority", NULL },
+  { "printer-is-accepting-jobs", "Accepting Jobs", __cups_callback_boolean },
+  
+  { "Media", NULL, NULL },
+  { "media", "Media", NULL },
+  { "finishings", "Finishings", NULL },
+  { "copies", "Copies", NULL },
+};
+
+void
+scan_printers_do(void)
+{
+    int num_dests, i, j;
+    CUPSDest *dests;
+    gchar *prn_id, *prn_moreinfo;
+
+    g_free(printer_list);
+    g_free(printer_icons);
+
+    if (!cups_init) {
+        init_cups();
+        
+        printer_icons = g_strdup("");
+        printer_list = g_strdup(_("[Printers]\n"
+                                "No suitable CUPS library found="));
+        return;
+    }
+
+    /* remove old devices from global device table */
+    moreinfo_del_with_prefix("DEV:PRN");
+
+    num_dests = cups_dests_get(&dests);
+    if (num_dests > 0) {
+	printer_list = g_strdup_printf(_("[Printers (CUPS)]\n"));
+        printer_icons = g_strdup("");
+	for (i = 0; i < num_dests; i++) {
+	    GHashTable *options;
+	    
+	    options = g_hash_table_new(g_str_hash, g_str_equal);
+	    
+	    for (j = 0; j < dests[i].num_options; j++) {
+	      g_hash_table_insert(options,
+	                          g_strdup(dests[i].options[j].name),
+	                          g_strdup(dests[i].options[j].value));
+	    }
+	
+            prn_id = g_strdup_printf("PRN%d", i);
+	
+	    printer_list = h_strdup_cprintf("\n$%s$%s=%s\n",
+					    printer_list,
+					    prn_id,						
+					    dests[i].name,
+					    dests[i].is_default ? "<i>Default</i>" : "");
+            printer_icons = h_strdup_cprintf("\nIcon$%s$%s=printer.png",
+                                             printer_icons,
+                                             prn_id,
+                                             dests[i].name);
+
+            prn_moreinfo = g_strdup("");
+            for (j = 0; j < G_N_ELEMENTS(cups_fields); j++) {
+              if (!cups_fields[j].name) {
+                prn_moreinfo = h_strdup_cprintf("[%s]\n",
+                                                prn_moreinfo,
+                                                cups_fields[j].key);
+              } else {
+                gchar *temp;
+                
+                temp = g_hash_table_lookup(options, cups_fields[j].key);
+                
+                if (cups_fields[j].callback) {
+                  temp = cups_fields[j].callback(temp);
+                } else {
+                  if (temp) {
+                    /* FIXME Do proper escaping */
+                    temp = g_strdup(strreplacechr(temp, "&=", ' '));
+                  } else {
+                    temp = g_strdup(_("Unknown"));
+                  }
+                }
+                
+                prn_moreinfo = h_strdup_cprintf("%s=%s\n",
+                                                prn_moreinfo,
+                                                cups_fields[j].name,
+                                                temp);
+                
+                g_free(temp);
+              }
+            }
+            
+            moreinfo_add_with_prefix("DEV", prn_id, prn_moreinfo);
+            g_free(prn_id);
+            g_hash_table_destroy(options);
+	}
+	
+	cups_dests_free(num_dests, dests);
+    } else {
+	printer_list = g_strdup(_("[Printers]\n"
+	                        "No printers found=\n"));
+    }
+}
diff --git a/modules/devices/resources.c b/modules/devices/resources.c
new file mode 100644
index 0000000..15cb8f2
--- /dev/null
+++ b/modules/devices/resources.c
@@ -0,0 +1,119 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2008 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "devices.h"
+
+static gchar *_resources = NULL;
+static gboolean _require_root = FALSE;
+
+#if GLIB_CHECK_VERSION(2,14,0)
+static GRegex *_regex_pci = NULL,
+              *_regex_module = NULL;
+
+static gchar *_resource_obtain_name(gchar *name)
+{
+    gchar *temp;
+
+    if (!_regex_pci && !_regex_module) {
+      _regex_pci = g_regex_new("^[0-9a-fA-F]{4}:[0-9a-fA-F]{2}:"
+                               "[0-9a-fA-F]{2}\\.[0-9a-fA-F]{1}$",
+                               0, 0, NULL);
+      _regex_module = g_regex_new("^[0-9a-zA-Z\\_\\-]+$", 0, 0, NULL);
+    }
+    
+    name = g_strstrip(name);
+    
+    if (g_regex_match(_regex_pci, name, 0, NULL)) {
+      temp = module_call_method_param("devices::getPCIDeviceDescription", name);
+      if (temp) {
+          return g_strdup_printf("<b><small>PCI</small></b> %s", (gchar *)idle_free(temp));
+      }
+    } else if (g_regex_match(_regex_module, name, 0, NULL)) {
+      temp = module_call_method_param("computer::getKernelModuleDescription", name);
+      if (temp) {
+          return g_strdup_printf("<b><small>Module</small></b> %s", (gchar *)idle_free(temp));
+      }
+    }
+    
+    return g_strdup(name);
+}
+#else
+static gchar *_resource_obtain_name(gchar *name)
+{
+    return g_strdup(name);
+}
+#endif
+
+void scan_device_resources(gboolean reload)
+{
+    SCAN_START();
+    FILE *io;
+    gchar buffer[256];
+    gint i;
+    gint zero_to_zero_addr = 0;
+
+    struct {
+      gchar *file;
+      gchar *description;
+    } resources[] = {
+      { "/proc/ioports", "[I/O Ports]\n" },
+      { "/proc/iomem", "[Memory]\n" },
+      { "/proc/dma", "[DMA]\n" }
+    };
+    
+    g_free(_resources);
+    _resources = g_strdup("");
+    
+    for (i = 0; i < G_N_ELEMENTS(resources); i++) {
+      if ((io = fopen(resources[i].file, "r"))) {
+        _resources = h_strconcat(_resources, resources[i].description, NULL);
+
+        while (fgets(buffer, 256, io)) {
+          gchar **temp = g_strsplit(buffer, ":", 2);
+          gchar *name = _resource_obtain_name(temp[1]);
+
+          if (strstr(temp[0], "0000-0000"))
+            zero_to_zero_addr++;
+
+          _resources = h_strdup_cprintf("<tt>%s</tt>=%s\n", _resources,
+                                        temp[0], name);
+
+          g_strfreev(temp);
+          g_free(name);
+        }
+
+        fclose(io);
+      }
+    }
+
+    _require_root = zero_to_zero_addr > 16;
+
+    SCAN_END();
+}
+
+gchar *callback_device_resources(void)
+{
+    return g_strdup(_resources);
+}
+
+gboolean root_required_for_resources(void)
+{
+    return _require_root;
+}
diff --git a/modules/devices/riscv/processor.c b/modules/devices/riscv/processor.c
new file mode 100644
index 0000000..afddf89
--- /dev/null
+++ b/modules/devices/riscv/processor.c
@@ -0,0 +1,233 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/* source: https://github.com/riscv/riscv-linux/blob/riscv-next/arch/riscv/kernel/cpu.c */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+
+#include "riscv_data.h"
+#include "riscv_data.c"
+
+GSList *
+processor_scan(void)
+{
+    GSList *procs = NULL;
+    Processor *processor = NULL;
+    FILE *cpuinfo;
+    gchar buffer[128];
+    gchar *rep_pname = NULL;
+    gchar *tmpfreq_str = NULL;
+    GSList *pi = NULL;
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+    return NULL;
+
+#define CHECK_FOR(k) (g_str_has_prefix(tmp[0], k))
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+        if (tmp[0] && tmp[1]) {
+            tmp[0] = g_strstrip(tmp[0]);
+            tmp[1] = g_strstrip(tmp[1]);
+        } else {
+            g_strfreev(tmp);
+            continue;
+        }
+
+        //get_str("Processor", rep_pname);
+
+        if ( CHECK_FOR("hart") ) {
+            /* finish previous */
+            if (processor) {
+                procs = g_slist_append(procs, processor);
+            }
+
+            /* start next */
+            processor = g_new0(Processor, 1);
+            processor->id = atol(tmp[1]);
+
+            if (rep_pname)
+                processor->model_name = g_strdup(rep_pname);
+
+            g_strfreev(tmp);
+            continue;
+        }
+
+        if (!processor &&
+            (  CHECK_FOR("mmu")
+            || CHECK_FOR("isa")
+            || CHECK_FOR("uarch") ) ) {
+
+            /* single proc/core may not have "hart : n" */
+            processor = g_new0(Processor, 1);
+            processor->id = 0;
+
+            if (rep_pname)
+                processor->model_name = g_strdup(rep_pname);
+        }
+
+        if (processor) {
+            get_str("mmu", processor->mmu);
+            get_str("isa", processor->isa);
+            get_str("uarch", processor->uarch);
+        }
+        g_strfreev(tmp);
+    }
+
+    if (processor)
+        procs = g_slist_append(procs, processor);
+
+    g_free(rep_pname);
+    fclose(cpuinfo);
+
+    /* TODO: redup */
+
+    /* data not from /proc/cpuinfo */
+    for (pi = procs; pi; pi = pi->next) {
+        processor = (Processor *) pi->data;
+
+        /* strings can't be null or segfault later */
+        STRIFNULL(processor->model_name, _("RISC-V Processor") );
+        UNKIFNULL(processor->mmu);
+        UNKIFNULL(processor->isa);
+        UNKIFNULL(processor->uarch);
+
+        processor->flags = riscv_isa_to_flags(processor->isa);
+
+        /* topo & freq */
+        processor->cpufreq = cpufreq_new(processor->id);
+        processor->cputopo = cputopo_new(processor->id);
+
+        if (processor->cpufreq->cpukhz_max)
+            processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+        else
+            processor->cpu_mhz = 0.0f;
+    }
+
+    return procs;
+}
+
+gchar *processor_get_capabilities_from_flags(gchar * strflags)
+{
+    gchar **flags, **old;
+    gchar *tmp = NULL;
+    gint j = 0;
+
+    flags = g_strsplit(strflags, " ", 0);
+    old = flags;
+
+    while (flags[j]) {
+        const gchar *meaning = riscv_ext_meaning( flags[j] );
+
+        if (meaning) {
+            tmp = h_strdup_cprintf("%s=%s\n", tmp, flags[j], meaning);
+        } else {
+            tmp = h_strdup_cprintf("%s=\n", tmp, flags[j]);
+        }
+        j++;
+    }
+    if (tmp == NULL || g_strcmp0(tmp, "") == 0)
+        tmp = g_strdup_printf("%s=%s\n", "empty", _("Empty List"));
+
+    g_strfreev(old);
+    return tmp;
+}
+
+gchar *processor_name(GSList * processors) {
+    return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_default(processors);
+}
+
+gchar *
+processor_get_detailed_info(Processor *processor)
+{
+    gchar *tmp_flags, *tmp_cpufreq, *tmp_topology, *ret;
+    tmp_flags = processor_get_capabilities_from_flags(processor->flags);
+    tmp_topology = cputopo_section_str(processor->cputopo);
+    tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+    ret = g_strdup_printf("[%s]\n"
+                   "%s=%s\n"  /* model */
+                   "%s=%s\n"  /* isa */
+                   "%s=%s\n"  /* uarch */
+                   "%s=%s\n"  /* mmu */
+                   "%s=%.2f %s\n" /* frequency */
+                   "%s=%s\n"      /* byte order */
+                   "%s" /* topology */
+                   "%s" /* frequency scaling */
+                   "[%s]\n" /* extensions */
+                   "%s"
+                   "%s",/* empty */
+                   _("Processor"),
+                   _("Model"), processor->model_name,
+                   _("Architecture"), processor->isa,
+                   _("uarch"), processor->uarch,
+                   _("MMU"), processor->mmu,
+                   _("Frequency"), processor->cpu_mhz, _("MHz"),
+                   _("Byte Order"), byte_order_str(),
+                   tmp_topology,
+                   tmp_cpufreq,
+                   _("Capabilities"), tmp_flags,
+                    "");
+    g_free(tmp_flags);
+    g_free(tmp_cpufreq);
+    g_free(tmp_topology);
+    return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
+{
+    Processor *processor;
+
+    if (g_slist_length(processors) > 1) {
+    gchar *ret, *tmp, *hashkey;
+    GSList *l;
+
+    tmp = g_strdup("");
+
+    for (l = processors; l; l = l->next) {
+        processor = (Processor *) l->data;
+
+        tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+                  tmp, processor->id,
+                  processor->model_name,
+                  processor->cpu_mhz, _("MHz"));
+
+        hashkey = g_strdup_printf("CPU%d", processor->id);
+        moreinfo_add_with_prefix("DEV", hashkey,
+                processor_get_detailed_info(processor));
+           g_free(hashkey);
+    }
+
+    ret = g_strdup_printf("[$ShellParam$]\n"
+                  "ViewType=1\n"
+                  "[Processors]\n"
+                  "%s", tmp);
+    g_free(tmp);
+
+    return ret;
+    }
+
+    processor = (Processor *) processors->data;
+    return processor_get_detailed_info(processor);
+}
diff --git a/modules/devices/riscv/riscv_data.c b/modules/devices/riscv/riscv_data.c
new file mode 100644
index 0000000..4ae68ef
--- /dev/null
+++ b/modules/devices/riscv/riscv_data.c
@@ -0,0 +1,212 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * Copyright (C) 2017  Burt P. <pburt0@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "riscv_data.h"
+
+#ifndef C_
+#define C_(Ctx, String) String
+#endif
+#ifndef NC_
+#define NC_(Ctx, String) String
+#endif
+
+static struct {
+    char *name, *meaning;
+} tab_ext_meaning[] = {
+    { "RV32",  NC_("rv-ext", /*/ext:RV32*/  "RISC-V 32-bit") },
+    { "RV64",  NC_("rv-ext", /*/ext:RV64*/  "RISC-V 64-bit") },
+    { "RV128", NC_("rv-ext", /*/ext:RV128*/ "RISC-V 128-bit") },
+    { "E",     NC_("rv-ext", /*/ext:E*/ "Base embedded integer instructions (15 registers)") },
+    { "I",     NC_("rv-ext", /*/ext:I*/ "Base integer instructions (31 registers)") },
+    { "M",     NC_("rv-ext", /*/ext:M*/ "Hardware integer multiply and divide") },
+    { "A",     NC_("rv-ext", /*/ext:A*/ "Atomic memory operations") },
+    { "C",     NC_("rv-ext", /*/ext:C*/ "Compressed 16-bit instructions") },
+    { "F",     NC_("rv-ext", /*/ext:F*/ "Floating-point instructions, single-precision") },
+    { "D",     NC_("rv-ext", /*/ext:D*/ "Floating-point instructions, double-precision") },
+    { "Q",     NC_("rv-ext", /*/ext:Q*/ "Floating-point instructions, quad-precision") },
+    { "B",     NC_("rv-ext", /*/ext:B*/ "Bit manipulation instructions") },
+    { "V",     NC_("rv-ext", /*/ext:V*/ "Vector operations") },
+    { "T",     NC_("rv-ext", /*/ext:T*/ "Transactional memory") },
+    { "P",     NC_("rv-ext", /*/ext:P*/ "Packed SIMD instructions") },
+    { "L",     NC_("rv-ext", /*/ext:L*/ "Decimal floating-point instructions") },
+    { "J",     NC_("rv-ext", /*/ext:J*/ "Dynamically translated languages") },
+    { "N",     NC_("rv-ext", /*/ext:N*/ "User-level interrupts") },
+    { NULL, NULL }
+};
+
+static char all_extensions[1024] = "";
+
+#define APPEND_EXT(f) strcat(all_extensions, f); strcat(all_extensions, " ");
+const char *riscv_ext_list() {
+    int i = 0, built = 0;
+    built = strlen(all_extensions);
+    if (!built) {
+        while(tab_ext_meaning[i].name != NULL) {
+            APPEND_EXT(tab_ext_meaning[i].name);
+            i++;
+        }
+    }
+    return all_extensions;
+}
+
+const char *riscv_ext_meaning(const char *ext) {
+    int i = 0, l = 0;
+    char *c = NULL;
+    if (ext) {
+        c = strchr(ext, ':'); /* allow extension:version, ignore version */
+        if (c != NULL)
+            l = c - ext;
+        else
+            l = strlen(ext);
+        while(tab_ext_meaning[i].name != NULL) {
+            if (strncasecmp(tab_ext_meaning[i].name, ext, l) == 0) {
+                if (tab_ext_meaning[i].meaning != NULL)
+                    return C_("rv-ext", tab_ext_meaning[i].meaning);
+                else return NULL;
+            }
+            i++;
+        }
+    }
+    return NULL;
+}
+
+/* see RISC-V spec 2.2: Chapter 22: ISA Subset Naming Conventions */
+
+/* Spec says case-insensitve, but I prefer single-letter extensions
+ * capped and version string (like "2p1") with a lowercase p. */
+#define RV_FIX_CASE(fstr,vo) \
+    p = fstr; while (*p != 0 && *p != ':') { if (!vo) *p = toupper(*p); p++; } \
+    if (*p == ':') while (*p != 0) { if (*p == 'P') *p = 'p'; p++; }
+
+static int riscv_isa_next(const char *isap, char *flag) {
+    char *p = NULL, *start = NULL;
+    char *next_sep = NULL, *next_digit = NULL;
+    int skip_len = 0, tag_len = 0, ver_len = 0;
+    char ext_str[32], ver_str[32];
+
+    if (isap == NULL)
+        return 0;
+
+    /* find start by skipping any '_' */
+    start = (char*)isap;
+    while (*start != 0 && *start == '_') { start++; skip_len++; };
+    if (*start == 0)
+        return 0;
+
+    /* find next '_' or \0 */
+    p = start; while (*p != 0 && *p != '_') { p++; }; next_sep = p;
+
+    /* find next digit that may be a version, find length of version */
+    p = start; while (*p != 0 && !isdigit(*p)) { p++; };
+    if (isdigit(*p)) next_digit = p;
+    if (next_digit) {
+        while (*p != 0 && (isdigit(*p) || *p == 'p' || *p == 'P') ) {
+            if ((*p == 'p' || *p == 'P') && !isdigit(*(p+1)) )
+                break;
+            ver_len++;
+            p++;
+        }
+    }
+
+    /* is next version nearer than next separator */
+    p = start;
+    if (next_digit && next_digit < next_sep)
+        tag_len = next_digit - p;
+    else {
+        tag_len = next_sep - p;
+        ver_len = 0;
+    }
+
+    switch(*p) {
+        case 'S': case 's': /* supervisor extension */
+        case 'X': case 'x': /* custom extension */
+            /* custom supervisor extension (SX..) handled by S */
+            break;
+        default: /* single character (standard) extension */
+            tag_len = 1;
+            if (next_digit != p+1) ver_len = 0;
+            break;
+    }
+
+    memset(ext_str, 0, 32);
+    memset(ver_str, 0, 32);
+    if (ver_len) {
+        strncpy(ext_str, p, tag_len);
+        strncpy(ver_str, next_digit, ver_len);
+        sprintf(flag, "%s:%s", ext_str, ver_str);
+        if (tag_len == 1) {
+            RV_FIX_CASE(flag, 0);
+        } else {
+            RV_FIX_CASE(flag, 1);
+        }
+        return skip_len + tag_len + ver_len;
+    } else {
+        strncpy(ext_str, p, tag_len);
+        sprintf(flag, "%s", ext_str);
+        if (tag_len == 1) { RV_FIX_CASE(flag, 0); }
+        return skip_len + tag_len;
+    }
+}
+
+#define FSTR_SIZE 1024
+#define RV_CHECK_FOR(e) ( strncasecmp(ps, e, 2) == 0 )
+#define ADD_EXT_FLAG(ext) el = strlen(ext); strncpy(pd, ext, el); strncpy(pd + el, " ", 1); pd += el + 1;
+char *riscv_isa_to_flags(const char *isa) {
+    char *flags = NULL, *ps = (char*)isa, *pd = NULL;
+    char flag_buf[64] = "";
+    int isa_len = 0, tl = 0, el = 0; /* el used in macro */
+
+    if (isa) {
+        isa_len = strlen(isa);
+        flags = malloc(FSTR_SIZE);
+        if (flags) {
+            memset(flags, 0, FSTR_SIZE);
+            ps = (char*)isa;
+            pd = flags;
+            if ( RV_CHECK_FOR("RV") )
+            { ps += 2; }
+            if ( RV_CHECK_FOR("32") )
+            { ADD_EXT_FLAG("RV32"); ps += 2; }
+            else if ( RV_CHECK_FOR("64") )
+            { ADD_EXT_FLAG("RV64"); ps += 2; }
+            else if ( RV_CHECK_FOR("128") )
+            { ADD_EXT_FLAG("RV128"); ps += 3; }
+
+            while( (tl = riscv_isa_next(ps, flag_buf)) ) {
+                if (flag_buf[0] == 'G') { /* G = IMAFD */
+                    flag_buf[0] = 'I'; ADD_EXT_FLAG(flag_buf);
+                    flag_buf[0] = 'M'; ADD_EXT_FLAG(flag_buf);
+                    flag_buf[0] = 'A'; ADD_EXT_FLAG(flag_buf);
+                    flag_buf[0] = 'F'; ADD_EXT_FLAG(flag_buf);
+                    flag_buf[0] = 'D'; ADD_EXT_FLAG(flag_buf);
+                } else {
+                    ADD_EXT_FLAG(flag_buf);
+                }
+                ps += tl;
+                if (ps - isa >= isa_len) break; /* just in case */
+            }
+        }
+    }
+    return flags;
+}
diff --git a/modules/devices/riscv/riscv_data.h b/modules/devices/riscv/riscv_data.h
new file mode 100644
index 0000000..1d3a0a4
--- /dev/null
+++ b/modules/devices/riscv/riscv_data.h
@@ -0,0 +1,33 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * Copyright (C) 2017  Burt P. <pburt0@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef _RISCVDATA_H_
+#define _RISCVDATA_H_
+
+/* convert RISC-V ISA string to flags list */
+char *riscv_isa_to_flags(const char *isa);
+
+/* all known extensions as flags list */
+const char *riscv_ext_list(void);
+
+/* get meaning of flag */
+const char *riscv_ext_meaning(const char *ext);
+
+#endif
diff --git a/modules/devices/s390/processor.c b/modules/devices/s390/processor.c
new file mode 100644
index 0000000..cf45c33
--- /dev/null
+++ b/modules/devices/s390/processor.c
@@ -0,0 +1,180 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "string.h"
+#include "cpu_util.h"
+
+GSList *
+processor_scan(void)
+{
+    GSList *procs = NULL;
+    Processor *processor = NULL;
+    FILE *cpuinfo;
+    gchar buffer[128];
+    gchar *vendor_id = NULL;
+    gint   num_procs = 0;
+    gfloat bogomips = 0.0f;
+    GSList *pi = NULL;
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+    return NULL;
+
+#define CHECK_FOR(k) (g_str_has_prefix(tmp[0], k))
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+        if (tmp[0] && tmp[1]) {
+            tmp[0] = g_strstrip(tmp[0]);
+            tmp[1] = g_strstrip(tmp[1]);
+        } else {
+            g_strfreev(tmp);
+            continue;
+        }
+
+        get_str("vendor_id", vendor_id);
+        get_int("# processors", num_procs);
+        get_int("bogomips per cpu", bogomips);
+
+        if ( CHECK_FOR("processor") ) {
+            /* finish previous */
+            if (processor) {
+                procs = g_slist_append(procs, processor);
+            }
+
+            /* start next */
+            processor = g_new0(Processor, 1);
+            if (strlen(tmp[0]) >= 10)
+                processor->id = atol(tmp[0] + 10); /* processor n: ... */
+            else
+                processor->id = 0; /* idk */
+            processor->proc_str = g_strdup(tmp[1]);
+
+            if (vendor_id)
+                processor->model_name = g_strdup(vendor_id);
+            if (bogomips)
+                processor->bogomips = bogomips;
+
+            g_strfreev(tmp);
+            continue;
+        }
+
+        g_strfreev(tmp);
+    }
+
+    if (processor)
+        procs = g_slist_append(procs, processor);
+
+    g_free(vendor_id);
+    fclose(cpuinfo);
+
+    /* data not from /proc/cpuinfo */
+    for (pi = procs; pi; pi = pi->next) {
+        processor = (Processor *) pi->data;
+
+        /* strings can't be null or segfault later */
+        STRIFNULL(processor->model_name, _("S390 Processor") );
+        UNKIFNULL(processor->proc_str);
+
+        /* topo & freq */
+        processor->cpufreq = cpufreq_new(processor->id);
+        processor->cputopo = cputopo_new(processor->id);
+
+        if (processor->cpufreq->cpukhz_max)
+            processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+        else
+            processor->cpu_mhz = 0.0f;
+
+    }
+
+    return procs;
+}
+
+gchar *processor_name(GSList * processors) {
+    return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_default(processors);
+}
+
+gchar *
+processor_get_detailed_info(Processor *processor)
+{
+    gchar *tmp_cpufreq, *tmp_topology, *ret;
+    tmp_topology = cputopo_section_str(processor->cputopo);
+    tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+    ret = g_strdup_printf("[%s]\n"
+                        "%s=%s\n"      /* model */
+                        "%s=%s\n"      /* proc string */
+                        "%s=%.2f\n"    /* bogomips */
+                        "%s=%s\n"      /* byte order */
+                        "%s"  /* topology */
+                        "%s", /* frequency scaling */
+                        _("Processor"),
+                        _("Model"), processor->model_name,
+                        _("ID String"), processor->proc_str,
+                        _("BogoMips"), processor->bogomips,
+                        _("Byte Order"), byte_order_str(),
+                        tmp_topology,
+                        tmp_cpufreq
+                        );
+    g_free(tmp_cpufreq);
+    g_free(tmp_topology);
+    return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
+{
+    Processor *processor;
+
+    if (g_slist_length(processors) > 1) {
+    gchar *ret, *tmp, *hashkey;
+    GSList *l;
+
+    tmp = g_strdup("");
+
+    for (l = processors; l; l = l->next) {
+        processor = (Processor *) l->data;
+
+        tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+                  tmp, processor->id,
+                  processor->model_name,
+                  processor->cpu_mhz, _("MHz"));
+
+        hashkey = g_strdup_printf("CPU%d", processor->id);
+        moreinfo_add_with_prefix("DEV", hashkey,
+                processor_get_detailed_info(processor));
+           g_free(hashkey);
+    }
+
+    ret = g_strdup_printf("[$ShellParam$]\n"
+                  "ViewType=1\n"
+                  "[Processors]\n"
+                  "%s", tmp);
+    g_free(tmp);
+
+    return ret;
+    }
+
+    processor = (Processor *) processors->data;
+    return processor_get_detailed_info(processor);
+}
+
diff --git a/modules/devices/sensors.c b/modules/devices/sensors.c
new file mode 100644
index 0000000..c9d78ff
--- /dev/null
+++ b/modules/devices/sensors.c
@@ -0,0 +1,453 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "devices.h"
+#include "expr.h"
+#include "hardinfo.h"
+#include "socket.h"
+
+gchar *sensors = NULL;
+GHashTable *sensor_compute = NULL;
+GHashTable *sensor_labels = NULL;
+
+static void read_sensor_labels(gchar *driver) {
+    FILE *conf;
+    gchar buf[256], *line, *p;
+    gboolean lock = FALSE;
+    gint i;
+
+    /* Try to open lm-sensors config file sensors3.conf */
+    conf = fopen("/etc/sensors3.conf", "r");
+
+    /* If it fails, try to open sensors.conf */
+    if (!conf)
+        conf = fopen("/etc/sensors.conf", "r");
+
+    if (!conf) {
+        /* Cannot open config file. */
+        return;
+    }
+
+    while (fgets(buf, 256, conf)) {
+        line = buf;
+
+        remove_linefeed(line);
+        strend(line, '#');
+
+        if (*line == '\0') {
+            continue;
+        } else if (lock && strstr(line, "label")) { /* label lines */
+            gchar **names = g_strsplit(strstr(line, "label") + 5, " ", 0);
+            gchar *name = NULL, *value = NULL;
+
+            for (i = 0; names[i]; i++) {
+                if (names[i][0] == '\0')
+                    continue;
+
+                if (!name)
+                    name = g_strdup(names[i]);
+                else if (!value)
+                    value = g_strdup(names[i]);
+                else
+                    value = g_strconcat(value, " ", names[i], NULL);
+            }
+
+            remove_quotes(value);
+            g_hash_table_insert(sensor_labels, name, value);
+
+            g_strfreev(names);
+        } else if (lock && strstr(line, "ignore")) { /* ignore lines */
+            p = strstr(line, "ignore") + 6;
+            if (!strchr(p, ' '))
+                continue;
+
+            while (*p == ' ')
+                p++;
+            g_hash_table_insert(sensor_labels, g_strdup(p), "ignore");
+        } else if (lock && strstr(line, "compute")) { /* compute lines */
+            gchar **formulas = g_strsplit(strstr(line, "compute") + 7, " ", 0);
+            gchar *name = NULL, *formula = NULL;
+
+            for (i = 0; formulas[i]; i++) {
+                if (formulas[i][0] == '\0')
+                    continue;
+                if (formulas[i][0] == ',')
+                    break;
+
+                if (!name)
+                    name = g_strdup(formulas[i]);
+                else if (!formula)
+                    formula = g_strdup(formulas[i]);
+                else
+                    formula = g_strconcat(formula, formulas[i], NULL);
+            }
+
+            g_strfreev(formulas);
+            g_hash_table_insert(sensor_compute, name,
+                                math_string_to_postfix(formula));
+        } else if (g_str_has_prefix(line,
+                                    "chip")) { /* chip lines (delimiter) */
+            if (lock == FALSE) {
+                gchar **chips = g_strsplit(line, " ", 0);
+
+                for (i = 1; chips[i]; i++) {
+                    strend(chips[i], '*');
+
+                    if (g_str_has_prefix(chips[i] + 1, driver)) {
+                        lock = TRUE;
+                        break;
+                    }
+                }
+
+                g_strfreev(chips);
+            } else {
+                break;
+            }
+        }
+    }
+
+    fclose(conf);
+}
+
+static void add_sensor(const char *type,
+                       const char *sensor,
+                       const char *driver,
+                       double value,
+                       const char *unit) {
+    char key[64];
+
+    sensors = h_strdup_cprintf("%s/%s=%.2f%s|%s\n", sensors,
+        driver, sensor, value, unit, type);
+
+    snprintf(key, sizeof(key), "%s/%s", driver, sensor);
+    moreinfo_add_with_prefix("DEV", key, g_strdup_printf("%.2f%s", value, unit));
+
+    lginterval = h_strdup_cprintf("UpdateInterval$%s=1000\n", lginterval, key);
+}
+
+static gchar *get_sensor_label(gchar *sensor) {
+    gchar *ret;
+
+    ret = g_hash_table_lookup(sensor_labels, sensor);
+    if (!ret)
+        ret = g_strdup(sensor);
+    else
+        ret = g_strdup(ret);
+
+    return ret;
+}
+
+static float adjust_sensor(gchar *name, float value) {
+    GSList *postfix;
+
+    postfix = g_hash_table_lookup(sensor_compute, name);
+    if (!postfix)
+        return value;
+
+    return math_postfix_eval(postfix, value);
+}
+
+static char *get_sensor_path(int number, const char *prefix) {
+    return g_strdup_printf("/sys/class/hwmon/hwmon%d/%s", number, prefix);
+}
+
+static char *determine_driver_for_hwmon_path(char *path) {
+    char *tmp, *driver;
+
+    tmp = g_strdup_printf("%s/device/driver", path);
+    driver = g_file_read_link(tmp, NULL);
+    g_free(tmp);
+
+    if (driver) {
+        tmp = g_path_get_basename(driver);
+        g_free(driver);
+        driver = tmp;
+    } else {
+        tmp = g_strdup_printf("%s/device", path);
+        driver = g_file_read_link(tmp, NULL);
+        g_free(tmp);
+    }
+
+    if (!driver) {
+        tmp = g_strdup_printf("%s/name", path);
+        if (!g_file_get_contents(tmp, &driver, NULL, NULL)) {
+            driver = g_strdup("unknown");
+        } else {
+            driver = g_strstrip(driver);
+        }
+        g_free(tmp);
+    }
+
+    return driver;
+}
+
+struct HwmonSensor {
+    const char *friendly_name;
+    const char *path_format;
+    const char *key_format;
+    const char *unit;
+    const float adjust_ratio;
+    const int begin_at;
+};
+
+static const struct HwmonSensor hwmon_sensors[] = {
+    {
+        "Fan",
+        "%s/fan%d_input",
+        "fan%d",
+        "RPM",
+        1.0,
+        1
+    },
+    {
+        "Temperature",
+        "%s/temp%d_input",
+        "temp%d",
+        "\302\260C",
+        1000.0,
+        1
+    },
+    {
+        "Voltage",
+        "%s/in%d_input",
+        "in%d",
+        "V",
+        1000.0,
+        0
+    },
+    { }
+};
+
+static const char *hwmon_prefix[] = {"device", "", NULL};
+
+static void read_sensors_hwmon(void) {
+    int hwmon, count;
+    gchar *path_hwmon, *path_sensor, *tmp, *driver, *name, *mon;
+    const char **prefix;
+
+    for (prefix = hwmon_prefix; *prefix; prefix++) {
+        hwmon = 0;
+        path_hwmon = get_sensor_path(hwmon, *prefix);
+        while (path_hwmon && g_file_test(path_hwmon, G_FILE_TEST_EXISTS)) {
+            const struct HwmonSensor *sensor;
+
+            driver = determine_driver_for_hwmon_path(path_hwmon);
+            DEBUG("hwmon%d has driver=%s", hwmon, driver);
+
+            if (!sensor_labels) {
+                read_sensor_labels(driver);
+            }
+
+            for (sensor = hwmon_sensors; sensor->friendly_name; sensor++) {
+                DEBUG("current sensor type=%s", sensor->friendly_name);
+
+                for (count = sensor->begin_at;; count++) {
+                    path_sensor =
+                        g_strdup_printf(sensor->path_format, path_hwmon, count);
+                    DEBUG("should be reading from %s", path_sensor);
+                    if (!g_file_get_contents(path_sensor, &tmp, NULL, NULL)) {
+                        g_free(path_sensor);
+                        if (count < 256)
+                            continue; // brute-force find all
+                        else
+                            break;
+                    }
+
+                    mon = g_strdup_printf(sensor->key_format, count);
+                    name = get_sensor_label(mon);
+                    if (!g_str_equal(name, "ignore")) {
+                        float adjusted = adjust_sensor(mon,
+                            atof(tmp) / sensor->adjust_ratio);
+
+                        add_sensor(sensor->friendly_name,
+                                   name,
+                                   driver,
+                                   adjusted,
+                                   sensor->unit);
+                    }
+
+                    g_free(tmp);
+                    g_free(mon);
+                    g_free(name);
+                    g_free(path_sensor);
+                }
+            }
+
+            g_free(path_hwmon);
+            g_free(driver);
+
+            path_hwmon = get_sensor_path(++hwmon, *prefix);
+        }
+
+        g_free(path_hwmon);
+    }
+}
+
+static void read_sensors_acpi(void) {
+    const gchar *path_tz = "/proc/acpi/thermal_zone";
+
+    if (g_file_test(path_tz, G_FILE_TEST_EXISTS)) {
+        GDir *tz;
+
+        if ((tz = g_dir_open(path_tz, 0, NULL))) {
+            const gchar *entry;
+
+            while ((entry = g_dir_read_name(tz))) {
+                gchar *path =
+                    g_strdup_printf("%s/%s/temperature", path_tz, entry);
+                gchar *contents;
+
+                if (g_file_get_contents(path, &contents, NULL, NULL)) {
+                    int temperature;
+
+                    sscanf(contents, "temperature: %d C", &temperature);
+
+                    add_sensor("Temperature",
+                               entry,
+                               "ACPI Thermal Zone",
+                               temperature,
+                               "\302\260C");
+                }
+            }
+
+            g_dir_close(tz);
+        }
+    }
+}
+
+static void read_sensors_sys_thermal(void) {
+    const gchar *path_tz = "/sys/class/thermal";
+
+    if (g_file_test(path_tz, G_FILE_TEST_EXISTS)) {
+        GDir *tz;
+
+        if ((tz = g_dir_open(path_tz, 0, NULL))) {
+            const gchar *entry;
+            gchar *temp = g_strdup("");
+
+            while ((entry = g_dir_read_name(tz))) {
+                gchar *path = g_strdup_printf("%s/%s/temp", path_tz, entry);
+                gchar *contents;
+
+                if (g_file_get_contents(path, &contents, NULL, NULL)) {
+                    int temperature;
+
+                    sscanf(contents, "%d", &temperature);
+
+                    add_sensor("Temperature",
+                               entry,
+                               "thermal",
+                               temperature / 1000.0,
+                               "\302\260C");
+
+                    g_free(contents);
+                }
+            }
+
+            g_dir_close(tz);
+        }
+    }
+}
+
+static void read_sensors_omnibook(void) {
+    const gchar *path_ob = "/proc/omnibook/temperature";
+    gchar *contents;
+
+    if (g_file_get_contents(path_ob, &contents, NULL, NULL)) {
+        int temperature;
+
+        sscanf(contents, "CPU temperature: %d C", &temperature);
+
+        add_sensor("Temperature",
+                   "CPU",
+                   "omnibook",
+                   temperature,
+                   "\302\260C\n");
+
+        g_free(contents);
+    }
+}
+
+static void read_sensors_hddtemp(void) {
+    Socket *s;
+    gchar buffer[1024];
+    gint len = 0;
+
+    if (!(s = sock_connect("127.0.0.1", 7634)))
+        return;
+
+    while (!len)
+        len = sock_read(s, buffer, sizeof(buffer));
+    sock_close(s);
+
+    if (len > 2 && buffer[0] == '|' && buffer[1] == '/') {
+        gchar **disks;
+        int i;
+
+        disks = g_strsplit(buffer, "\n", 0);
+        for (i = 0; disks[i]; i++) {
+            gchar **fields = g_strsplit(disks[i] + 1, "|", 5);
+
+            /*
+             * 0 -> /dev/hda
+             * 1 -> FUJITSU MHV2080AH
+             * 2 -> 41
+             * 3 -> C
+             */
+            const gchar *unit = strcmp(fields[3], "C")
+                ? "\302\260C" : "\302\260F";
+            add_sensor("Hard Drive",
+                       fields[1],
+                       "hddtemp",
+                       atoi(fields[2]),
+                       unit);
+
+            g_strfreev(fields);
+        }
+
+        g_strfreev(disks);
+    }
+}
+
+void scan_sensors_do(void) {
+    g_free(sensors);
+    sensors = g_strdup("");
+
+    g_free(lginterval);
+    lginterval = g_strdup("");
+
+    read_sensors_hwmon();
+    read_sensors_acpi();
+    read_sensors_sys_thermal();
+    read_sensors_omnibook();
+    read_sensors_hddtemp();
+    /* FIXME: Add support for  ibm acpi and more sensors */
+}
+
+void sensors_init(void) {
+    sensor_labels =
+        g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+    sensor_compute = g_hash_table_new(g_str_hash, g_str_equal);
+}
+
+void sensors_shutdown(void) {
+    g_hash_table_destroy(sensor_labels);
+    g_hash_table_destroy(sensor_compute);
+}
diff --git a/modules/devices/sh/processor.c b/modules/devices/sh/processor.c
new file mode 100644
index 0000000..9da2f9b
--- /dev/null
+++ b/modules/devices/sh/processor.c
@@ -0,0 +1,93 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+
+GSList *
+processor_scan(void)
+{
+    Processor *processor;
+    FILE *cpuinfo;
+    gchar buffer[128];
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+        return NULL;
+
+    processor = g_new0(Processor, 1);
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+
+        if (tmp[0] && tmp[1]) {
+            tmp[0] = g_strstrip(tmp[0]);
+            tmp[1] = g_strstrip(tmp[1]);
+
+            get_str("machine", processor->vendor_id);
+            get_str("cpu type", processor->model_name);
+            get_str("cpu family", processor->family);
+            get_float("cpu clock", processor->cpu_mhz);
+            get_float("bus clock", processor->bus_mhz);
+            get_float("module clock", processor->mod_mhz);
+            get_float("bogomips", processor->bogomips);
+        }
+        g_strfreev(tmp);
+    }
+
+    fclose(cpuinfo);
+
+    STRIFNULL(processor->model_name, _("SuperH Processor"));
+    UNKIFNULL(processor->vendor_id);
+
+    return g_slist_append(NULL, processor);
+}
+
+gchar *processor_name(GSList * processors) {
+    return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_default(processors);
+}
+
+gchar *
+processor_get_info(GSList *processors)
+{
+    Processor *processor = (Processor *)processors->data;
+
+    return g_strdup_printf("[%s]\n"
+                        "%s=%s\n"      /* cpu type */
+                        "%s=%s\n"      /* machine */
+                        "%s=%s\n"      /* family */
+                        "%s=%.2f %s\n" /* frequency */
+                        "%s=%.2f %s\n" /* bus frequency */
+                        "%s=%.2f %s\n" /* module frequency */
+                        "%s=%.2f\n"    /* bogomips */
+                        "%s=%s\n",     /* byte order */
+                    _("Processor"),
+                    _("Name"), processor->model_name,
+                    _("Machine"), processor->vendor_id,
+                    _("Family"), processor->family,
+                    _("Frequency"), processor->cpu_mhz, _("MHz"),
+                    _("Bus Frequency"), processor->bus_mhz, _("MHz"),
+                    _("Module Frequency"), processor->mod_mhz, _("MHz"),
+                    _("BogoMips"), processor->bogomips,
+                    _("Byte Order"), byte_order_str()
+                   );
+}
diff --git a/modules/devices/sparc/processor.c b/modules/devices/sparc/processor.c
new file mode 100644
index 0000000..32c7aa9
--- /dev/null
+++ b/modules/devices/sparc/processor.c
@@ -0,0 +1,80 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+
+GSList *
+processor_scan(void)
+{
+    Processor *processor;
+    FILE *cpuinfo;
+    gchar buffer[128];
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+        return NULL;
+
+    processor = g_new0(Processor, 1);
+    while (fgets(buffer, 128, cpuinfo)) {
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+
+        if (tmp[0] && tmp[1]) {
+            tmp[0] = g_strstrip(tmp[0]);
+            tmp[1] = g_strstrip(tmp[1]);
+
+            get_str("cpucaps", processor->cpucaps);
+            get_str("cpu", processor->model_name);
+            get_str("fpu", processor->has_fpu);
+        }
+        g_strfreev(tmp);
+    }
+
+    fclose(cpuinfo);
+
+    processor->cpu_mhz = 0.0f;
+
+    return g_slist_append(NULL, processor);
+}
+
+gchar *processor_name(GSList * processors) {
+    return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_default(processors);
+}
+
+gchar *
+processor_get_info(GSList *processors)
+{
+    Processor *processor = (Processor *)processors->data;
+
+    return g_strdup_printf("[%s]\n"
+                           "%s=%s\n"   /* cpu */
+                           "%s=%s\n"   /* fpu */
+                           "%s=%s\n"   /* byte order */
+                           "%s=%s\n",  /* caps */
+                   _("Processor"),
+                   _("CPU"), processor->model_name,
+                   _("FPU"), processor->has_fpu,
+                   _("Byte Order"), byte_order_str(),
+                   _("Capabilities"), processor->cpucaps
+                   );
+}
diff --git a/modules/devices/spd-decode.c b/modules/devices/spd-decode.c
new file mode 100644
index 0000000..2db4895
--- /dev/null
+++ b/modules/devices/spd-decode.c
@@ -0,0 +1,1512 @@
+/*
+ * spd-decode.c
+ * Copyright (c) 2010 Leandro A. F. Pereira
+ *
+ * Based on decode-dimms.pl
+ * Copyright 1998, 1999 Philip Edelbrock <phil@netroedge.com>
+ * modified by Christian Zuckschwerdt <zany@triq.net>
+ * modified by Burkart Lingner <burkart@bollchen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <ctype.h>
+#include <math.h>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include "hardinfo.h"
+#include "devices.h"
+
+typedef enum {
+    UNKNOWN,
+    DIRECT_RAMBUS,
+    RAMBUS,
+    FPM_DRAM,
+    EDO,
+    PIPELINED_NIBBLE,
+    SDR_SDRAM,
+    MULTIPLEXED_ROM,
+    DDR_SGRAM,
+    DDR_SDRAM,
+    DDR2_SDRAM,
+    DDR3_SDRAM
+} RamType;
+
+char *spd_info = NULL;
+
+static const char *ram_types[] = {
+    "Unknown",
+    "Direct Rambus",
+    "Rambus",
+    "FPM DRAM",
+    "EDO",
+    "Pipelined Nibble",
+    "SDR SDRAM",
+    "Multiplexed ROM",
+    "DDR SGRAM",
+    "DDR SDRAM",
+    "DDR2 SDRAM",
+    "DDR3 SDRAM"
+};
+
+static const char *vendors1[] = { "AMD", "AMI", "Fairchild", "Fujitsu",
+    "GTE", "Harris", "Hitachi", "Inmos",
+    "Intel", "I.T.T.", "Intersil",
+    "Monolithic Memories",
+    "Mostek",
+    "Freescale (former Motorola)",
+    "National", "NEC",
+    "RCA", "Raytheon",
+    "Conexant (Rockwell)", "Seeq",
+    "NXP (former Signetics, Philips Semi.)",
+    "Synertek",
+    "Texas Instruments", "Toshiba",
+    "Xicor", "Zilog", "Eurotechnique",
+    "Mitsubishi",
+    "Lucent (AT&T)", "Exel", "Atmel",
+    "SGS/Thomson",
+    "Lattice Semi.", "NCR",
+    "Wafer Scale Integration", "IBM",
+    "Tristar", "Visic",
+    "Intl. CMOS Technology", "SSSI",
+    "MicrochipTechnology", "Ricoh Ltd.",
+    "VLSI", "Micron Technology",
+    "Hyundai Electronics",
+    "OKI Semiconductor", "ACTEL",
+    "Sharp",
+    "Catalyst", "Panasonic", "IDT",
+    "Cypress",
+    "DEC", "LSI Logic",
+    "Zarlink (former Plessey)", "UTMC",
+    "Thinking Machine", "Thomson CSF",
+    "Integrated CMOS (Vertex)",
+    "Honeywell",
+    "Tektronix", "Sun Microsystems",
+    "SST", "ProMos/Mosel Vitelic",
+    "Infineon (former Siemens)",
+    "Macronix", "Xerox", "Plus Logic",
+    "SunDisk", "Elan Circuit Tech.",
+    "European Silicon Str.",
+    "Apple Computer",
+    "Xilinx", "Compaq",
+    "Protocol Engines", "SCI",
+    "Seiko Instruments", "Samsung",
+    "I3 Design System", "Klic",
+    "Crosspoint Solutions",
+    "Alliance Semiconductor", "Tandem",
+    "Hewlett-Packard",
+    "Intg. Silicon Solutions",
+    "Brooktree", "New Media",
+    "MHS Electronic",
+    "Performance Semi.",
+    "Winbond Electronic",
+    "Kawasaki Steel",
+    "Bright Micro",
+    "TECMAR", "Exar", "PCMCIA",
+    "LG Semi (former Goldstar)",
+    "Northern Telecom", "Sanyo",
+    "Array Microsystems",
+    "Crystal Semiconductor",
+    "Analog Devices", "PMC-Sierra",
+    "Asparix", "Convex Computer",
+    "Quality Semiconductor",
+    "Nimbus Technology", "Transwitch",
+    "Micronas (ITT Intermetall)",
+    "Cannon", "Altera", "NEXCOM",
+    "QUALCOMM",
+    "Sony", "Cray Research",
+    "AMS(Austria Micro)", "Vitesse",
+    "Aster Electronics",
+    "Bay Networks (Synoptic)",
+    "Zentrum or ZMD",
+    "TRW",
+    "Thesys", "Solbourne Computer",
+    "Allied-Signal", "Dialog",
+    "Media Vision",
+    "Level One Communication"
+};
+
+static const char *vendors2[] = { "Cirrus Logic",
+    "National Instruments",
+    "ILC Data Device",
+    "Alcatel Mietec",
+    "Micro Linear",
+    "Univ. of NC",
+    "JTAG Technologies",
+    "BAE Systems",
+    "Nchip",
+    "Galileo Tech",
+    "Bestlink Systems",
+    "Graychip",
+    "GENNUM",
+    "VideoLogic",
+    "Robert Bosch",
+    "Chip Express",
+    "DATARAM",
+    "United Microelec Corp.",
+    "TCSI",
+    "Smart Modular",
+    "Hughes Aircraft",
+    "Lanstar Semiconductor",
+    "Qlogic", "Kingston",
+    "Music Semi",
+    "Ericsson Components",
+    "SpaSE",
+    "Eon Silicon Devices",
+    "Programmable Micro Corp",
+    "DoD",
+    "Integ. Memories Tech.",
+    "Corollary Inc.",
+    "Dallas Semiconductor",
+    "Omnivision",
+    "EIV(Switzerland)",
+    "Novatel Wireless",
+    "Zarlink (former Mitel)",
+    "Clearpoint",
+    "Cabletron",
+    "STEC (former Silicon Technology)",
+    "Vanguard",
+    "Hagiwara Sys-Com",
+    "Vantis", "Celestica",
+    "Century",
+    "Hal Computers",
+    "Rohm Company Ltd.",
+    "Juniper Networks",
+    "Libit Signal Processing",
+    "Mushkin Enhanced Memory",
+    "Tundra Semiconductor",
+    "Adaptec Inc.",
+    "LightSpeed Semi.",
+    "ZSP Corp.",
+    "AMIC Technology",
+    "Adobe Systems",
+    "Dynachip",
+    "PNY Electronics",
+    "Newport Digital",
+    "MMC Networks",
+    "T Square",
+    "Seiko Epson",
+    "Broadcom",
+    "Viking Components",
+    "V3 Semiconductor",
+    "Flextronics (former Orbit)",
+    "Suwa Electronics",
+    "Transmeta",
+    "Micron CMS",
+    "American Computer & Digital Components Inc",
+    "Enhance 3000 Inc",
+    "Tower Semiconductor",
+    "CPU Design",
+    "Price Point",
+    "Maxim Integrated Product",
+    "Tellabs",
+    "Centaur Technology",
+    "Unigen Corporation",
+    "Transcend Information",
+    "Memory Card Technology",
+    "CKD Corporation Ltd.",
+    "Capital Instruments, Inc.",
+    "Aica Kogyo, Ltd.",
+    "Linvex Technology",
+    "MSC Vertriebs GmbH",
+    "AKM Company, Ltd.",
+    "Dynamem, Inc.",
+    "NERA ASA",
+    "GSI Technology",
+    "Dane-Elec (C Memory)",
+    "Acorn Computers",
+    "Lara Technology",
+    "Oak Technology, Inc.",
+    "Itec Memory",
+    "Tanisys Technology",
+    "Truevision",
+    "Wintec Industries",
+    "Super PC Memory",
+    "MGV Memory",
+    "Galvantech",
+    "Gadzoox Nteworks",
+    "Multi Dimensional Cons.",
+    "GateField",
+    "Integrated Memory System",
+    "Triscend", "XaQti",
+    "Goldenram",
+    "Clear Logic",
+    "Cimaron Communications",
+    "Nippon Steel Semi. Corp.",
+    "Advantage Memory",
+    "AMCC",
+    "LeCroy",
+    "Yamaha Corporation",
+    "Digital Microwave",
+    "NetLogic Microsystems",
+    "MIMOS Semiconductor",
+    "Advanced Fibre",
+    "BF Goodrich Data.",
+    "Epigram",
+    "Acbel Polytech Inc.",
+    "Apacer Technology",
+    "Admor Memory",
+    "FOXCONN",
+    "Quadratics Superconductor",
+    "3COM",
+};
+
+static const char *vendors3[] = { "Camintonn Corporation", "ISOA Incorporated",
+    "Agate Semiconductor", "ADMtek Incorporated",
+    "HYPERTEC", "Adhoc Technologies", "MOSAID Technologies",
+    "Ardent Technologies",
+    "Switchcore", "Cisco Systems, Inc.", "Allayer Technologies",
+    "WorkX AG",
+    "Oasis Semiconductor", "Novanet Semiconductor", "E-M Solutions",
+    "Power General",
+    "Advanced Hardware Arch.", "Inova Semiconductors GmbH", "Telocity",
+    "Delkin Devices",
+    "Symagery Microsystems", "C-Port Corporation",
+    "SiberCore Technologies", "Southland Microsystems",
+    "Malleable Technologies", "Kendin Communications",
+    "Great Technology Microcomputer", "Sanmina Corporation",
+    "HADCO Corporation", "Corsair", "Actrans System Inc.",
+    "ALPHA Technologies",
+    "Silicon Laboratories, Inc. (Cygnal)", "Artesyn Technologies",
+    "Align Manufacturing", "Peregrine Semiconductor",
+    "Chameleon Systems", "Aplus Flash Technology", "MIPS Technologies",
+    "Chrysalis ITS",
+    "ADTEC Corporation", "Kentron Technologies", "Win Technologies",
+    "Tachyon Semiconductor (former ASIC Designs Inc.)",
+    "Extreme Packet Devices", "RF Micro Devices", "Siemens AG",
+    "Sarnoff Corporation",
+    "Itautec Philco SA", "Radiata Inc.", "Benchmark Elect. (AVEX)",
+    "Legend",
+    "SpecTek Incorporated", "Hi/fn", "Enikia Incorporated",
+    "SwitchOn Networks",
+    "AANetcom Incorporated", "Micro Memory Bank", "ESS Technology",
+    "Virata Corporation",
+    "Excess Bandwidth", "West Bay Semiconductor", "DSP Group",
+    "Newport Communications",
+    "Chip2Chip Incorporated", "Phobos Corporation",
+    "Intellitech Corporation", "Nordic VLSI ASA",
+    "Ishoni Networks", "Silicon Spice", "Alchemy Semiconductor",
+    "Agilent Technologies",
+    "Centillium Communications", "W.L. Gore", "HanBit Electronics",
+    "GlobeSpan",
+    "Element 14", "Pycon", "Saifun Semiconductors", "Sibyte, Incorporated",
+    "MetaLink Technologies", "Feiya Technology", "I & C Technology",
+    "Shikatronics",
+    "Elektrobit", "Megic", "Com-Tier", "Malaysia Micro Solutions",
+    "Hyperchip", "Gemstone Communications", "Anadigm (former Anadyne)",
+    "3ParData",
+    "Mellanox Technologies", "Tenx Technologies", "Helix AG", "Domosys",
+    "Skyup Technology", "HiNT Corporation", "Chiaro",
+    "MDT Technologies GmbH (former MCI Computer GMBH)",
+    "Exbit Technology A/S", "Integrated Technology Express", "AVED Memory",
+    "Legerity",
+    "Jasmine Networks", "Caspian Networks", "nCUBE",
+    "Silicon Access Networks",
+    "FDK Corporation", "High Bandwidth Access", "MultiLink Technology",
+    "BRECIS",
+    "World Wide Packets", "APW", "Chicory Systems", "Xstream Logic",
+    "Fast-Chip", "Zucotto Wireless", "Realchip", "Galaxy Power",
+    "eSilicon", "Morphics Technology", "Accelerant Networks",
+    "Silicon Wave",
+    "SandCraft", "Elpida"
+};
+
+static const char *vendors4[] = { "Solectron", "Optosys Technologies",
+    "Buffalo (former Melco)",
+    "TriMedia Technologies",
+    "Cyan Technologies", "Global Locate",
+    "Optillion",
+    "Terago Communications",
+    "Ikanos Communications",
+    "Princeton Technology",
+    "Nanya Technology",
+    "Elite Flash Storage",
+    "Mysticom", "LightSand Communications",
+    "ATI Technologies",
+    "Agere Systems",
+    "NeoMagic", "AuroraNetics", "Golden Empire",
+    "Mushkin",
+    "Tioga Technologies", "Netlist", "TeraLogic",
+    "Cicada Semiconductor",
+    "Centon Electronics", "Tyco Electronics",
+    "Magis Works", "Zettacom",
+    "Cogency Semiconductor", "Chipcon AS",
+    "Aspex Technology",
+    "F5 Networks",
+    "Programmable Silicon Solutions",
+    "ChipWrights",
+    "Acorn Networks",
+    "Quicklogic",
+    "Kingmax Semiconductor", "BOPS", "Flasys",
+    "BitBlitz Communications",
+    "eMemory Technology", "Procket Networks",
+    "Purple Ray",
+    "Trebia Networks",
+    "Delta Electronics", "Onex Communications",
+    "Ample Communications",
+    "Memory Experts Intl",
+    "Astute Networks", "Azanda Network Devices",
+    "Dibcom", "Tekmos",
+    "API NetWorks", "Bay Microsystems",
+    "Firecron Ltd",
+    "Resonext Communications",
+    "Tachys Technologies", "Equator Technology",
+    "Concept Computer",
+    "SILCOM",
+    "3Dlabs", "c't Magazine", "Sanera Systems",
+    "Silicon Packets",
+    "Viasystems Group", "Simtek",
+    "Semicon Devices Singapore",
+    "Satron Handelsges",
+    "Improv Systems", "INDUSYS GmbH", "Corrent",
+    "Infrant Technologies",
+    "Ritek Corp", "empowerTel Networks",
+    "Hypertec",
+    "Cavium Networks",
+    "PLX Technology", "Massana Design",
+    "Intrinsity",
+    "Valence Semiconductor",
+    "Terawave Communications",
+    "IceFyre Semiconductor", "Primarion",
+    "Picochip Designs Ltd",
+    "Silverback Systems",
+    "Jade Star Technologies",
+    "Pijnenburg Securealink",
+    "TakeMS International AG",
+    "Cambridge Silicon Radio",
+    "Swissbit", "Nazomi Communications",
+    "eWave System",
+    "Rockwell Collins", "Picocel Co., Ltd.",
+    "Alphamosaic Ltd",
+    "Sandburst",
+    "SiCon Video", "NanoAmp Solutions",
+    "Ericsson Technology",
+    "PrairieComm",
+    "Mitac International", "Layer N Networks",
+    "MtekVision",
+    "Allegro Networks",
+    "Marvell Semiconductors",
+    "Netergy Microelectronic", "NVIDIA",
+    "Internet Machines",
+    "Peak Electronics",
+    "Litchfield Communication",
+    "Accton Technology",
+    "Teradiant Networks",
+    "Europe Technologies", "Cortina Systems",
+    "RAM Components",
+    "Raqia Networks",
+    "ClearSpeed", "Matsushita Battery",
+    "Xelerated",
+    "SimpleTech",
+    "Utron Technology", "Astec International",
+    "AVM gmbH",
+    "Redux Communications",
+    "Dot Hill Systems", "TeraChip"
+};
+
+static const char *vendors5[] = { "T-RAM Incorporated",
+    "Innovics Wireless", "Teknovus", "KeyEye Communications",
+    "Runcom Technologies", "RedSwitch", "Dotcast",
+    "Silicon Mountain Memory",
+    "Signia Technologies", "Pixim", "Galazar Networks",
+    "White Electronic Designs",
+    "Patriot Scientific", "Neoaxiom Corporation", "3Y Power Technology",
+    "Europe Technologies",
+    "Potentia Power Systems", "C-guys Incorporated",
+    "Digital Communications Technology Incorporated",
+    "Silicon-Based Technology",
+    "Fulcrum Microsystems", "Positivo Informatica Ltd",
+    "XIOtech Corporation", "PortalPlayer",
+    "Zhiying Software", "Direct2Data", "Phonex Broadband",
+    "Skyworks Solutions",
+    "Entropic Communications", "Pacific Force Technology", "Zensys A/S",
+    "Legend Silicon Corp.",
+    "sci-worx GmbH", "SMSC (former Oasis Silicon Systems)",
+    "Renesas Technology", "Raza Microelectronics",
+    "Phyworks", "MediaTek", "Non-cents Productions", "US Modular",
+    "Wintegra Ltd", "Mathstar", "StarCore", "Oplus Technologies",
+    "Mindspeed", "Just Young Computer", "Radia Communications", "OCZ",
+    "Emuzed", "LOGIC Devices", "Inphi Corporation", "Quake Technologies",
+    "Vixel", "SolusTek", "Kongsberg Maritime", "Faraday Technology",
+    "Altium Ltd.", "Insyte", "ARM Ltd.", "DigiVision",
+    "Vativ Technologies", "Endicott Interconnect Technologies", "Pericom",
+    "Bandspeed",
+    "LeWiz Communications", "CPU Technology", "Ramaxel Technology",
+    "DSP Group",
+    "Axis Communications", "Legacy Electronics", "Chrontel",
+    "Powerchip Semiconductor",
+    "MobilEye Technologies", "Excel Semiconductor", "A-DATA Technology",
+    "VirtualDigm",
+    "G Skill Intl", "Quanta Computer", "Yield Microelectronics",
+    "Afa Technologies",
+    "KINGBOX Technology Co. Ltd.", "Ceva", "iStor Networks",
+    "Advance Modules",
+    "Microsoft", "Open-Silicon", "Goal Semiconductor",
+    "ARC International",
+    "Simmtec", "Metanoia", "Key Stream", "Lowrance Electronics",
+    "Adimos", "SiGe Semiconductor", "Fodus Communications",
+    "Credence Systems Corp.",
+    "Genesis Microchip Inc.", "Vihana, Inc.", "WIS Technologies",
+    "GateChange Technologies",
+    "High Density Devices AS", "Synopsys", "Gigaram",
+    "Enigma Semiconductor Inc.",
+    "Century Micro Inc.", "Icera Semiconductor",
+    "Mediaworks Integrated Systems", "O'Neil Product Development",
+    "Supreme Top Technology Ltd.", "MicroDisplay Corporation",
+    "Team Group Inc.", "Sinett Corporation",
+    "Toshiba Corporation", "Tensilica", "SiRF Technology", "Bacoc Inc.",
+    "SMaL Camera Technologies", "Thomson SC", "Airgo Networks",
+    "Wisair Ltd.",
+    "SigmaTel", "Arkados", "Compete IT gmbH Co. KG",
+    "Eudar Technology Inc.",
+    "Focus Enhancements", "Xyratex"
+};
+
+static const char *vendors6[] = { "Specular Networks",
+    "Patriot Memory",
+    "U-Chip Technology Corp.",
+    "Silicon Optix",
+    "Greenfield Networks",
+    "CompuRAM GmbH", "Stargen, Inc.",
+    "NetCell Corporation",
+    "Excalibrus Technologies Ltd",
+    "SCM Microsystems",
+    "Xsigo Systems, Inc.",
+    "CHIPS & Systems Inc",
+    "Tier 1 Multichip Solutions",
+    "CWRL Labs", "Teradici",
+    "Gigaram, Inc.",
+    "g2 Microsystems",
+    "PowerFlash Semiconductor",
+    "P.A. Semi, Inc.",
+    "NovaTech Solutions, S.A.",
+    "c2 Microsystems, Inc.",
+    "Level5 Networks",
+    "COS Memory AG",
+    "Innovasic Semiconductor",
+    "02IC Co. Ltd", "Tabula, Inc.",
+    "Crucial Technology",
+    "Chelsio Communications",
+    "Solarflare Communications",
+    "Xambala Inc.", "EADS Astrium",
+    "ATO Semicon Co. Ltd.",
+    "Imaging Works, Inc.",
+    "Astute Networks, Inc.", "Tzero",
+    "Emulex",
+    "Power-One", "Pulse~LINK Inc.",
+    "Hon Hai Precision Industry",
+    "White Rock Networks Inc.",
+    "Telegent Systems USA, Inc.",
+    "Atrua Technologies, Inc.",
+    "Acbel Polytech Inc.",
+    "eRide Inc.",
+    "ULi Electronics Inc.",
+    "Magnum Semiconductor Inc.",
+    "neoOne Technology, Inc.",
+    "Connex Technology, Inc.",
+    "Stream Processors, Inc.",
+    "Focus Enhancements",
+    "Telecis Wireless, Inc.",
+    "uNav Microelectronics",
+    "Tarari, Inc.", "Ambric, Inc.",
+    "Newport Media, Inc.", "VMTS",
+    "Enuclia Semiconductor, Inc.",
+    "Virtium Technology Inc.",
+    "Solid State System Co., Ltd.",
+    "Kian Tech LLC",
+    "Artimi",
+    "Power Quotient International",
+    "Avago Technologies",
+    "ADTechnology", "Sigma Designs",
+    "SiCortex, Inc.",
+    "Ventura Technology Group",
+    "eASIC", "M.H.S. SAS",
+    "Micro Star International",
+    "Rapport Inc.",
+    "Makway International",
+    "Broad Reach Engineering Co.",
+    "Semiconductor Mfg Intl Corp",
+    "SiConnect", "FCI USA Inc.",
+    "Validity Sensors",
+    "Coney Technology Co. Ltd.",
+    "Spans Logic", "Neterion Inc.",
+    "Qimonda",
+    "New Japan Radio Co. Ltd.",
+    "Velogix", "Montalvo Systems",
+    "iVivity Inc.",
+    "Walton Chaintech",
+    "AENEON",
+    "Lorom Industrial Co. Ltd.",
+    "Radiospire Networks",
+    "Sensio Technologies, Inc.",
+    "Nethra Imaging",
+    "Hexon Technology Pte Ltd",
+    "CompuStocx (CSX)",
+    "Methode Electronics, Inc.",
+    "Connect One Ltd.",
+    "Opulan Technologies",
+    "Septentrio NV",
+    "Goldenmars Technology Inc.",
+    "Kreton Corporation",
+    "Cochlear Ltd.",
+    "Altair Semiconductor",
+    "NetEffect, Inc.",
+    "Spansion, Inc.",
+    "Taiwan Semiconductor Mfg",
+    "Emphany Systems Inc.",
+    "ApaceWave Technologies",
+    "Mobilygen Corporation", "Tego",
+    "Cswitch Corporation",
+    "Haier (Beijing) IC Design Co.",
+    "MetaRAM",
+    "Axel Electronics Co. Ltd.",
+    "Tilera Corporation",
+    "Aquantia",
+    "Vivace Semiconductor",
+    "Redpine Signals", "Octalica",
+    "InterDigital Communications",
+    "Avant Technology",
+    "Asrock, Inc.", "Availink",
+    "Quartics, Inc.",
+    "Element CXI",
+    "Innovaciones Microelectronicas",
+    "VeriSilicon Microelectronics",
+    "W5 Networks"
+};
+
+static const char *vendors7[] = { "MOVEKING", "Mavrix Technology, Inc.",
+    "CellGuide Ltd.", "Faraday Technology",
+    "Diablo Technologies, Inc.", "Jennic", "Octasic",
+    "Molex Incorporated",
+    "3Leaf Networks",
+    "Bright Micron Technology", "Netxen", "NextWave Broadband Inc.",
+    "DisplayLink", "ZMOS Technology",
+    "Tec-Hill", "Multigig, Inc.", "Amimon", "Euphonic Technologies, Inc.",
+    "BRN Phoenix",
+    "InSilica", "Ember Corporation", "Avexir Technologies Corporation",
+    "Echelon Corporation",
+    "Edgewater Computer Systems", "XMOS Semiconductor Ltd.",
+    "GENUSION, Inc.", "Memory Corp NV",
+    "SiliconBlue Technologies", "Rambus Inc."
+};
+
+static const char **vendors[7] = { vendors1, vendors2, vendors3, vendors4, vendors5, vendors6,
+    vendors7
+};
+
+/*
+ * We consider that no data was written to this area of the SPD EEPROM if
+ * all bytes read 0x00 or all bytes read 0xff
+ */
+static int spd_written(unsigned char *bytes, int len)
+{
+    do {
+	if (*bytes == 0x00 || *bytes == 0xFF)
+	    return 1;
+    } while (--len && bytes++);
+
+    return 0;
+}
+
+static int parity(int value)
+{
+    value ^= value >> 16;
+    value ^= value >> 8;
+    value ^= value >> 4;
+    value &= 0xf;
+
+    return (0x6996 >> value) & 1;
+}
+
+static void decode_sdr_module_size(unsigned char *bytes, int *size)
+{
+    int i, k = 0;
+
+    i = (bytes[3] & 0x0f) + (bytes[4] & 0x0f) - 17;
+    if (bytes[5] <= 8 && bytes[17] <= 8) {
+	k = bytes[5] * bytes[17];
+    }
+
+    if (i > 0 && i <= 12 && k > 0) {
+	if (size) {
+	    *size = (1 << i) * k;
+	}
+    } else {
+	if (size) {
+	    *size = -1;
+	}
+    }
+}
+
+static void decode_sdr_module_timings(unsigned char *bytes, float *tcl, float *trcd, float *trp, float *tras)
+{
+    float cas[3], ctime;
+    int i, j;
+
+    for (i = 0, j = 0; j < 7; j++) {
+	if (bytes[18] & 1 << j) {
+	    cas[i++] = j + 1;
+	}
+    }
+
+    ctime = (bytes[9] >> 4 + bytes[9] & 0xf) * 0.1;
+
+    if (trcd) {
+	*trcd = ceil(bytes[29] / ctime);
+    }
+    if (trp) {
+	*trp = ceil(bytes[27] / ctime);
+    }
+    if (tras) {
+	*tras = ceil(bytes[30] / ctime);
+    }
+    if (tcl) {
+	*tcl = cas[i];
+    }
+}
+
+static void decode_sdr_module_row_address_bits(unsigned char *bytes, char **bits)
+{
+    char *temp;
+
+    switch (bytes[3]) {
+    case 0:
+	temp = "Undefined";
+	break;
+    case 1:
+	temp = "1/16";
+	break;
+    case 2:
+	temp = "2/27";
+	break;
+    case 3:
+	temp = "3/18";
+	break;
+    default:
+	/* printf("%d\n", bytes[3]); */
+	temp = "Unknown";
+    }
+
+    if (bits) {
+	*bits = temp;
+    }
+}
+
+static void decode_sdr_module_col_address_bits(unsigned char *bytes, char **bits)
+{
+    char *temp;
+
+    switch (bytes[4]) {
+    case 0:
+	temp = "Undefined";
+	break;
+    case 1:
+	temp = "1/16";
+	break;
+    case 2:
+	temp = "2/17";
+	break;
+    case 3:
+	temp = "3/18";
+	break;
+    default:
+	/*printf("%d\n", bytes[4]); */
+	temp = "Unknown";
+    }
+
+    if (bits) {
+	*bits = temp;
+    }
+}
+
+static void decode_sdr_module_number_of_rows(unsigned char *bytes, int *rows)
+{
+    if (rows) {
+	*rows = bytes[5];
+    }
+}
+
+static void decode_sdr_module_data_with(unsigned char *bytes, int *width)
+{
+    if (width) {
+	if (bytes[7] > 1) {
+	    *width = 0;
+	} else {
+	    *width = (bytes[7] * 0xff) + bytes[6];
+	}
+    }
+}
+
+static void decode_sdr_module_interface_signal_levels(unsigned char *bytes, char **signal_levels)
+{
+    char *temp;
+
+    switch (bytes[8]) {
+    case 0:
+	temp = "5.0 Volt/TTL";
+	break;
+    case 1:
+	temp = "LVTTL";
+	break;
+    case 2:
+	temp = "HSTL 1.5";
+	break;
+    case 3:
+	temp = "SSTL 3.3";
+	break;
+    case 4:
+	temp = "SSTL 2.5";
+	break;
+    case 255:
+	temp = "New Table";
+	break;
+    default:
+	temp = "Undefined";
+    }
+
+    if (signal_levels) {
+	*signal_levels = temp;
+    }
+}
+
+static void decode_sdr_module_configuration_type(unsigned char *bytes, char **module_config_type)
+{
+    char *temp;
+
+    switch (bytes[11]) {
+    case 0:
+	temp = "No parity";
+	break;
+    case 1:
+	temp = "Parity";
+	break;
+    case 2:
+	temp = "ECC";
+	break;
+    default:
+	temp = "Undefined";
+    }
+
+    if (module_config_type) {
+	*module_config_type = temp;
+    }
+}
+
+static void decode_sdr_module_refresh_type(unsigned char *bytes, char **refresh_type)
+{
+    char *temp;
+
+    if (bytes[12] & 0x80) {
+	temp = "Self refreshing";
+    } else {
+	temp = "Not self refreshing";
+    }
+
+    if (refresh_type) {
+	*refresh_type = temp;
+    }
+}
+
+static void decode_sdr_module_refresh_rate(unsigned char *bytes, char **refresh_rate)
+{
+    char *temp;
+
+    switch (bytes[12] & 0x7f) {
+    case 0:
+	temp = "Normal (15.625us)";
+	break;
+    case 1:
+	temp = "Reduced (3.9us)";
+	break;
+    case 2:
+	temp = "Reduced (7.8us)";
+	break;
+    case 3:
+	temp = "Extended (31.3us)";
+	break;
+    case 4:
+	temp = "Extended (62.5us)";
+	break;
+    case 5:
+	temp = "Extended (125us)";
+	break;
+    default:
+	temp = "Undefined";
+    }
+
+    if (refresh_rate) {
+	*refresh_rate = temp;
+    }
+}
+
+static gchar *decode_sdr_sdram(unsigned char *bytes, int *size)
+{
+    int rows, data_width;
+    float tcl, trcd, trp, tras;
+    char *row_address_bits, *col_address_bits, *signal_level;
+    char *module_config_type, *refresh_type, *refresh_rate;
+
+    decode_sdr_module_size(bytes, size);
+    decode_sdr_module_timings(bytes, &tcl, &trcd, &trp, &tras);
+    decode_sdr_module_row_address_bits(bytes, &row_address_bits);
+    decode_sdr_module_col_address_bits(bytes, &col_address_bits);
+    decode_sdr_module_number_of_rows(bytes, &rows);
+    decode_sdr_module_data_with(bytes, &data_width);
+    decode_sdr_module_interface_signal_levels(bytes, &signal_level);
+    decode_sdr_module_configuration_type(bytes, &module_config_type);
+    decode_sdr_module_refresh_type(bytes, &refresh_type);
+    decode_sdr_module_refresh_rate(bytes, &refresh_rate);
+
+    /* TODO:
+       - RAS to CAS delay
+       - Supported CAS latencies
+       - Supported CS latencies
+       - Supported WE latencies
+       - Cycle Time / Access time
+       - SDRAM module attributes
+       - SDRAM device attributes
+       - Row densities
+       - Other misc stuff
+     */
+
+    return g_strdup_printf("[Module Information]\n"
+			   "Module type=SDR\n"
+			   "SPD revision=%d\n"
+			   "Row address bits=%s\n"
+			   "Column address bits=%s\n"
+			   "Number of rows=%d\n"
+			   "Data width=%d bits\n"
+			   "Interface signal levels=%s\n"
+			   "Configuration type=%s\n"
+			   "Refresh=%s (%s)\n"
+			   "[Timings]\n"
+			   "tCL=%.2f\n"
+			   "tRCD=%.2f\n"
+			   "tRP=%.2f\n"
+			   "tRAS=%.2f\n",
+			   bytes[62],
+			   row_address_bits, col_address_bits, rows,
+			   data_width, signal_level, module_config_type,
+			   refresh_type, refresh_rate, tcl, trcd, trp, tras);
+}
+
+static void decode_ddr_module_speed(unsigned char *bytes, float *ddrclk, int *pcclk)
+{
+    float temp, clk;
+    int tbits, pc;
+
+    temp = (bytes[9] >> 4) + (bytes[9] & 0xf) * 0.1;
+    clk = 2 * (1000 / temp);
+    tbits = (bytes[7] * 256) + bytes[6];
+
+    if (bytes[11] == 2 || bytes[11] == 1) {
+	tbits -= 8;
+    }
+
+    pc = clk * tbits / 8;
+    if (pc % 100 > 50) {
+	pc += 100;
+    }
+    pc -= pc % 100;
+
+    if (ddrclk)
+	*ddrclk = (int) clk;
+
+    if (pcclk)
+	*pcclk = pc;
+}
+
+static void decode_ddr_module_size(unsigned char *bytes, int *size)
+{
+    int i, k;
+
+    i = (bytes[3] & 0x0f) + (bytes[4] & 0x0f) - 17;
+    k = (bytes[5] <= 8 && bytes[17] <= 8) ? bytes[5] * bytes[17] : 0;
+
+    if (i > 0 && i <= 12 && k > 0) {
+	if (size) {
+	    *size = (1 << i) * k;
+	}
+    } else {
+	if (size) {
+	    *size = -1;
+	}
+    }
+}
+
+static void *decode_ddr_module_timings(unsigned char *bytes, float *tcl, float *trcd, float *trp, float *tras)
+{
+    float ctime;
+    float highest_cas = 0;
+    int i;
+
+    for (i = 0; i < 7; i++) {
+	if (bytes[18] & (1 << i)) {
+	    highest_cas = 1 + i * 0.5f;
+	}
+    }
+
+    ctime = (bytes[9] >> 4) + (bytes[9] & 0xf) * 0.1;
+
+    if (trcd) {
+	*trcd = (bytes[29] >> 2) + ((bytes[29] & 3) * 0.25);
+	*trcd = ceil(*trcd / ctime);
+    }
+
+    if (trp) {
+	*trp = (bytes[27] >> 2) + ((bytes[27] & 3) * 0.25);
+	*trp = ceil(*trp / ctime);
+    }
+
+    if (tras) {
+	*tras = bytes[30];
+	*tras = ceil(*tras / ctime);
+    }
+
+    if (tcl) {
+	*tcl = highest_cas;
+    }
+}
+
+static gchar *decode_ddr_sdram(unsigned char *bytes, int *size)
+{
+    float ddr_clock;
+    float tcl, trcd, trp, tras;
+    int pc_speed;
+
+    decode_ddr_module_speed(bytes, &ddr_clock, &pc_speed);
+    decode_ddr_module_size(bytes, size);
+    decode_ddr_module_timings(bytes, &tcl, &trcd, &trp, &tras);
+
+    return g_strdup_printf("[Module Information]\n"
+			   "Module type=DDR %.2fMHz (PC%d)\n"
+			   "SPD revision=%d.%d\n"
+			   "[Timings]\n"
+			   "tCL=%.2f\n"
+			   "tRCD=%.2f\n"
+			   "tRP=%.2f\n"
+			   "tRAS=%.2f\n", ddr_clock, pc_speed, bytes[62] >> 4, bytes[62] & 0xf, tcl, trcd, trp, tras);
+}
+
+static float decode_ddr2_module_ctime(unsigned char byte)
+{
+    float ctime;
+
+    ctime = (byte >> 4);
+    byte &= 0xf;
+
+    if (byte <= 9) {
+	ctime += byte * 0.1;
+    } else if (byte == 10) {
+	ctime += 0.25;
+    } else if (byte == 11) {
+	ctime += 0.33;
+    } else if (byte == 12) {
+	ctime += 0.66;
+    } else if (byte == 13) {
+	ctime += 0.75;
+    }
+
+    return ctime;
+}
+
+static void decode_ddr2_module_speed(unsigned char *bytes, float *ddr_clock, int *pc2_speed)
+{
+    float ctime;
+    float ddrclk;
+    int tbits, pcclk;
+
+    ctime = decode_ddr2_module_ctime(bytes[9]);
+    ddrclk = 2 * (1000 / ctime);
+
+    tbits = (bytes[7] * 256) + bytes[6];
+    if (bytes[11] & 0x03) {
+	tbits -= 8;
+    }
+
+    pcclk = ddrclk * tbits / 8;
+    pcclk -= pcclk % 100;
+
+    if (ddr_clock) {
+	*ddr_clock = (int) ddrclk;
+    }
+    if (pc2_speed) {
+	*pc2_speed = pcclk;
+    }
+}
+
+static void decode_ddr2_module_size(unsigned char *bytes, int *size)
+{
+    int i, k;
+
+    i = (bytes[3] & 0x0f) + (bytes[4] & 0x0f) - 17;
+    k = ((bytes[5] & 0x7) + 1) * bytes[17];
+
+    if (i > 0 && i <= 12 && k > 0) {
+	if (*size) {
+	    *size = ((1 << i) * k);
+	}
+    } else {
+	if (*size) {
+	    *size = 0;
+	}
+    }
+}
+
+static void decode_ddr2_module_timings(unsigned char *bytes, float *trcd, float *trp, float *tras, float *tcl)
+{
+    float ctime;
+    float highest_cas = 0;
+    int i;
+
+    for (i = 0; i < 7; i++) {
+	if (bytes[18] & (1 << i)) {
+	    highest_cas = i;
+	}
+    }
+
+    ctime = decode_ddr2_module_ctime(bytes[9]);
+
+    if (trcd) {
+	*trcd = ceil(((bytes[29] >> 2) + ((bytes[29] & 3) * 0.25)) / ctime);
+    }
+
+    if (trp) {
+	*trp = ceil(((bytes[27] >> 2) + ((bytes[27] & 3) * 0.25)) / ctime);
+    }
+
+    if (tras) {
+	*tras = ceil(bytes[30] / ctime);
+    }
+
+    if (tcl) {
+	*tcl = highest_cas;
+    }
+}
+
+static gchar *decode_ddr2_sdram(unsigned char *bytes, int *size)
+{
+    float ddr_clock;
+    float trcd, trp, tras, tcl;
+    int pc2_speed;
+
+    decode_ddr2_module_speed(bytes, &ddr_clock, &pc2_speed);
+    decode_ddr2_module_size(bytes, size);
+    decode_ddr2_module_timings(bytes, &trcd, &trp, &tras, &tcl);
+
+    return g_strdup_printf("[Module Information]\n"
+			   "Module type=DDR2 %.2f MHz (PC2-%d)\n"
+			   "SPD revision=%d.%d\n"
+			   "[Timings]\n"
+			   "tCL=%.2f\n"
+			   "tRCD=%.2f\n"
+			   "tRP=%.2f\n"
+			   "tRAS=%.2f\n", ddr_clock, pc2_speed, bytes[62] >> 4, bytes[62] & 0xf, tcl, trcd, trp, tras);
+}
+
+static void decode_ddr3_module_speed(unsigned char *bytes, float *ddr_clock, int *pc3_speed)
+{
+    float ctime;
+    float ddrclk;
+    int tbits, pcclk;
+    float mtb = 0.125;
+
+    if (bytes[10] == 1 && bytes[11] == 8)
+	mtb = 0.125;
+    if (bytes[10] == 1 && bytes[11] == 15)
+	mtb = 0.0625;
+    ctime = mtb * bytes[12];
+
+    ddrclk = 2 * (1000 / ctime);
+
+    tbits = 64;
+    switch (bytes[8]) {
+    case 1:
+	tbits = 16;
+	break;
+    case 4:
+	tbits = 32;
+	break;
+    case 3:
+    case 0xb:
+	tbits = 64;
+	break;
+    }
+
+    pcclk = ddrclk * tbits / 8;
+    pcclk -= pcclk % 100;
+
+    if (ddr_clock) {
+	*ddr_clock = (int) ddrclk;
+    }
+    if (pc3_speed) {
+	*pc3_speed = pcclk;
+    }
+}
+
+static void decode_ddr3_module_size(unsigned char *bytes, int *size)
+{
+    *size = 512 << bytes[4];
+}
+
+static void decode_ddr3_module_timings(unsigned char *bytes, float *trcd, float *trp, float *tras, float *tcl)
+{
+    float ctime;
+    float highest_cas = 0;
+    int i;
+    float mtb = 0.125;
+
+    if (bytes[10] == 1 && bytes[11] == 8)
+	mtb = 0.125;
+    if (bytes[10] == 1 && bytes[11] == 15)
+	mtb = 0.0625;
+    ctime = mtb * bytes[12];
+
+    switch (bytes[14]) {
+    case 6:
+	highest_cas = 5;
+	break;
+    case 4:
+	highest_cas = 6;
+	break;
+    case 0xc:
+	highest_cas = 7;
+	break;
+    case 0x1e:
+	highest_cas = 8;
+	break;
+    }
+    if (trcd) {
+	*trcd = bytes[18] * mtb;
+    }
+
+    if (trp) {
+	*trp = bytes[20] * mtb;
+    }
+
+    if (tras) {
+	*tras = (bytes[22] + bytes[21] & 0xf) * mtb;
+    }
+
+    if (tcl) {
+	*tcl = highest_cas;
+    }
+}
+
+static void decode_ddr3_module_type(unsigned char *bytes, const char **type)
+{
+    switch (bytes[3]) {
+    case 0x00:
+        *type = "Undefined";
+        break;
+    case 0x01:
+        *type = "RDIMM (Registered Long DIMM)";
+        break;
+    case 0x02:
+        *type = "UDIMM (Unbuffered Long DIMM)";
+        break;
+    case 0x03:
+        *type = "SODIMM (Small Outline DIMM)";
+        break;
+    default:
+        *type = "Unknown";
+    }
+}
+
+static gchar *decode_ddr3_sdram(unsigned char *bytes, int *size)
+{
+    float ddr_clock;
+    float trcd, trp, tras, tcl;
+    int pc3_speed;
+    const char *type;
+
+    decode_ddr3_module_speed(bytes, &ddr_clock, &pc3_speed);
+    decode_ddr3_module_size(bytes, size);
+    decode_ddr3_module_timings(bytes, &trcd, &trp, &tras, &tcl);
+    decode_ddr3_module_type(bytes, &type);
+
+    return g_strdup_printf("[Module Information]\n"
+			   "Module type=DDR3 %.2f MHz (PC3-%d)\n"
+			   "SPD revision=%d.%d\n"
+			   "Type=%s\n"
+			   "[Timings]\n"
+			   "tCL=%.2f\n"
+			   "tRCD=%.3fns\n"
+			   "tRP=%.3fns\n"
+			   "tRAS=%.3fns\n",
+			   ddr_clock, pc3_speed,
+			   bytes[1] >> 4, bytes[1] & 0xf,
+			   type,
+			   tcl,
+			   trcd,
+			   trp,
+			   tras);
+}
+
+static void decode_ddr3_part_number(unsigned char *bytes, char *part_number)
+{
+    int i;
+    if (part_number) {
+	for (i = 128; i <= 145; i++)
+	    *part_number++ = bytes[i];
+	*part_number = '\0';
+    }
+}
+
+static void decode_ddr3_manufacturer(unsigned char *bytes, char **manufacturer)
+{
+    char *out = "Unknown";
+
+  end:
+    if (manufacturer) {
+	*manufacturer = out;
+    }
+}
+
+static void decode_module_manufacturer(unsigned char *bytes, char **manufacturer)
+{
+    char *out = "Unknown";
+    unsigned char first;
+    int ai = 0;
+    int len = 8;
+    unsigned char *initial = bytes;
+
+    if (!spd_written(bytes, 8)) {
+	out = "Undefined";
+	goto end;
+    }
+
+    do {
+	ai++;
+    } while ((--len && (*bytes++ == 0x7f)));
+    first = *--bytes;
+
+    if (ai == 0) {
+	out = "Invalid";
+	goto end;
+    }
+
+    if (parity(first) != 1) {
+	out = "Invalid";
+	goto end;
+    }
+
+    out = (char *) vendors[ai - 1][(first & 0x7f) - 1];
+
+  end:
+    if (manufacturer) {
+	*manufacturer = out;
+    }
+}
+
+static void decode_module_part_number(unsigned char *bytes, char *part_number)
+{
+    if (part_number) {
+	bytes += 8 + 64;
+
+	while (*bytes++ && *bytes >= 32 && *bytes < 127) {
+	    *part_number++ = *bytes;
+	}
+	*part_number = '\0';
+    }
+}
+
+static int decode_ram_type(unsigned char *bytes)
+{
+    if (bytes[0] < 4) {
+	switch (bytes[2]) {
+	case 1:
+	    return DIRECT_RAMBUS;
+	case 17:
+	    return RAMBUS;
+	}
+    } else {
+	switch (bytes[2]) {
+	case 1:
+	    return FPM_DRAM;
+	case 2:
+	    return EDO;
+	case 3:
+	    return PIPELINED_NIBBLE;
+	case 4:
+	    return SDR_SDRAM;
+	case 5:
+	    return MULTIPLEXED_ROM;
+	case 6:
+	    return DDR_SGRAM;
+	case 7:
+	    return DDR_SDRAM;
+	case 8:
+	    return DDR2_SDRAM;
+	case 11:
+	    return DDR3_SDRAM;
+	}
+    }
+
+    return UNKNOWN;
+}
+
+static void read_spd(char *spd_path, int offset, size_t size, int use_sysfs, unsigned char *bytes_out)
+{
+    if (use_sysfs) {
+	FILE *spd;
+	gchar *temp_path;
+
+	temp_path = g_strdup_printf("%s/eeprom", spd_path);
+	if ((spd = fopen(temp_path, "rb"))) {
+	    fseek(spd, offset, SEEK_SET);
+	    fread(bytes_out, 1, size, spd);
+	    fclose(spd);
+	}
+
+	g_free(temp_path);
+    } else {
+	int i;
+
+	for (i = 0; i <= 3; i++) {
+	    FILE *spd;
+	    char *temp_path;
+
+	    temp_path = g_strdup_printf("%s/%02x", spd_path, offset + i * 16);
+	    if ((spd = fopen(temp_path, "rb"))) {
+		fread(bytes_out + i * 16, 1, 16, spd);
+		fclose(spd);
+	    }
+
+	    g_free(temp_path);
+	}
+    }
+}
+
+static gchar *decode_dimms(GSList * dimm_list, gboolean use_sysfs)
+{
+    GSList *dimm;
+    GString *output;
+    gint count = 0;
+
+    output = g_string_new("");
+
+    for (dimm = dimm_list; dimm; dimm = dimm->next, count++) {
+	gchar *spd_path = (gchar *) dimm->data;
+	gchar *manufacturer;
+	gchar *detailed_info;
+	gchar *moreinfo_key;
+	gchar part_number[32];
+	unsigned char bytes[256];
+	int module_size;
+	RamType ram_type;
+
+	shell_status_pulse();
+
+	read_spd(spd_path, 0, 256, use_sysfs, bytes);
+	ram_type = decode_ram_type(bytes);
+
+	switch (ram_type) {
+	case DDR2_SDRAM:
+	    detailed_info = decode_ddr2_sdram(bytes, &module_size);
+	    decode_module_part_number(bytes, part_number);
+	    decode_module_manufacturer(bytes + 64, &manufacturer);
+	    break;
+	case DDR3_SDRAM:
+	    detailed_info = decode_ddr3_sdram(bytes, &module_size);
+	    decode_ddr3_part_number(bytes, part_number);
+	    decode_ddr3_manufacturer(bytes, &manufacturer);
+	    break;
+	case DDR_SDRAM:
+	    detailed_info = decode_ddr_sdram(bytes, &module_size);
+	    decode_module_part_number(bytes, part_number);
+	    decode_module_manufacturer(bytes + 64, &manufacturer);
+	    break;
+	case SDR_SDRAM:
+	    detailed_info = decode_sdr_sdram(bytes, &module_size);
+	    decode_module_part_number(bytes, part_number);
+	    decode_module_manufacturer(bytes + 64, &manufacturer);
+	    break;
+	default:
+	    DEBUG("Unsupported EEPROM type: %s\n", ram_types[ram_type]);
+	    continue;
+	}
+
+
+
+	gchar *key = g_strdup_printf("MEM%d", count);
+	moreinfo_add_with_prefix("DEV", key, g_strdup(detailed_info));
+	g_free(key);
+	g_string_append_printf(output, "$MEM%d$%d=%s|%d MB|%s\n", count, count, part_number, module_size, manufacturer);
+
+	g_free(spd_path);
+	g_free(detailed_info);
+    }
+
+    return g_string_free(output, FALSE);
+}
+
+void scan_spd_do(void)
+{
+    GDir *dir = NULL;
+    GSList *dimm_list = NULL;
+    gboolean use_sysfs = FALSE;
+    gchar *dir_entry;
+    gchar *list;
+
+    if (g_file_test("/sys/bus/i2c/drivers/eeprom", G_FILE_TEST_EXISTS)) {
+	dir = g_dir_open("/sys/bus/i2c/drivers/eeprom", 0, NULL);
+	use_sysfs = TRUE;
+    } else if (g_file_test("/proc/sys/dev/sensors", G_FILE_TEST_EXISTS)) {
+	dir = g_dir_open("/proc/sys/dev/sensors", 0, NULL);
+    }
+
+    if (!dir) {
+	g_free(spd_info);
+	if (!g_file_test("/sys/module/eeprom", G_FILE_TEST_EXISTS)) {
+	    spd_info = g_strdup(_("[SPD]\n"
+                "Please load the eeprom module to obtain information about memory SPD=\n"
+                "[$ShellParam$]\n"
+                "ReloadInterval=500\n"));
+	} else {
+	    spd_info = g_strdup(_("[SPD]\n" "Reading memory SPD not supported on this system=\n"));
+	}
+
+	return;
+    }
+
+    while ((dir_entry = (char *) g_dir_read_name(dir))) {
+	if (use_sysfs && isdigit(dir_entry[0])) {
+	    dimm_list = g_slist_prepend(dimm_list, g_strdup_printf("/sys/bus/i2c/drivers/eeprom/%s", dir_entry));
+	} else if (g_str_has_prefix(dir_entry, "eeprom-")) {
+	    dimm_list = g_slist_prepend(dimm_list, g_strdup_printf("/proc/sys/dev/sensors/%s", dir_entry));
+	}
+    }
+
+    g_dir_close(dir);
+
+    list = decode_dimms(dimm_list, use_sysfs);
+    g_slist_free(dimm_list);
+
+    g_free(spd_info);
+    spd_info = g_strdup_printf("[%s]\n"
+                   "%s\n"
+                   "[$ShellParam$]\n"
+                   "ViewType=1\n"
+                   "ColumnTitle$TextValue=%s\n" /* Bank */
+                   "ColumnTitle$Extra1=%s\n" /* Size */
+                   "ColumnTitle$Extra2=%s\n" /* Manufacturer */
+                   "ColumnTitle$Value=%s\n" /* Model */
+                   "ShowColumnHeaders=true\n",
+                   _("SPD"), list,
+                   _("Bank"), _("Size"), _("Manufacturer"), _("Model") );
+    g_free(list);
+}
diff --git a/modules/devices/storage.c b/modules/devices/storage.c
new file mode 100644
index 0000000..0c39368
--- /dev/null
+++ b/modules/devices/storage.c
@@ -0,0 +1,371 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "hardinfo.h"
+#include "devices.h"
+
+gchar *storage_icons = NULL;
+
+/* SCSI support by Pascal F.Martin <pascalmartin@earthlink.net> */
+void
+__scan_scsi_devices(void)
+{
+    FILE *proc_scsi;
+    gchar buffer[256], *buf;
+    gint n = 0;
+    gint scsi_controller = 0;
+    gint scsi_channel = 0;
+    gint scsi_id = 0 ;
+    gint scsi_lun = 0;
+    gchar *vendor = NULL, *revision = NULL, *model = NULL;
+    gchar *scsi_storage_list;
+
+    /* remove old devices from global device table */
+    moreinfo_del_with_prefix("DEV:SCSI");
+
+    if (!g_file_test("/proc/scsi/scsi", G_FILE_TEST_EXISTS))
+	return;
+
+    scsi_storage_list = g_strdup(_("\n[SCSI Disks]\n"));
+
+    if ((proc_scsi = fopen("/proc/scsi/scsi", "r"))) {
+        while (fgets(buffer, 256, proc_scsi)) {
+            buf = g_strstrip(buffer);
+            if (!strncmp(buf, "Host: scsi", 10)) {
+                sscanf(buf,
+                       "Host: scsi%d Channel: %d Id: %d Lun: %d",
+                       &scsi_controller, &scsi_channel, &scsi_id, &scsi_lun);
+
+                n++;
+            } else if (!strncmp(buf, "Vendor: ", 8)) {
+                buf[17] = '\0';
+                buf[41] = '\0';
+                buf[53] = '\0';
+
+                vendor   = g_strdup(g_strstrip(buf + 8));
+                model    = g_strdup_printf("%s %s", vendor, g_strstrip(buf + 24));
+                revision = g_strdup(g_strstrip(buf + 46));
+            } else if (!strncmp(buf, "Type:   ", 8)) {
+                char *p;
+                gchar *type = NULL, *icon = NULL;
+
+                if (!(p = strstr(buf, "ANSI SCSI revision"))) {
+                    p = strstr(buf, "ANSI  SCSI revision");
+                }
+
+                if (p != NULL) {
+                    while (*(--p) == ' ');
+                    *(++p) = 0;
+
+                    static struct {
+                        char *type;
+                        char *label;
+                        char *icon;
+                    } type2icon[] = {
+                        { "Direct-Access", "Disk", "hdd"},
+                        { "Sequential-Access", "Tape", "tape"},
+                        { "Printer", "Printer", "lpr"},
+                        { "WORM", "CD-ROM", "cdrom"},
+                        { "CD-ROM", "CD-ROM", "cdrom"},
+                        { "Scanner", "Scanner", "scanner"},
+                        { "Flash Disk", "USB Flash Disk", "usbfldisk" },
+                        { NULL, "Generic", "scsi"}
+                    };
+                    int i;
+
+                    if (model && strstr(model, "Flash Disk")) {
+                      type = "Flash Disk";
+                      icon = "usbfldisk";
+                    } else {
+                      for (i = 0; type2icon[i].type != NULL; i++)
+                          if (g_str_equal(buf + 8, type2icon[i].type))
+                              break;
+
+                      type = type2icon[i].label;
+                      icon = type2icon[i].icon;
+                    }
+                }
+
+                gchar *devid = g_strdup_printf("SCSI%d", n);
+                scsi_storage_list = h_strdup_cprintf("$%s$%s=\n", scsi_storage_list, devid, model);
+                storage_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons, devid, model, icon);
+
+                gchar *strhash = g_strdup_printf(_("[Device Information]\n"
+                                                 "Model=%s\n"), model);
+
+                const gchar *url = vendor_get_url(model);
+                if (url) {
+                  strhash = h_strdup_cprintf(_("Vendor=%s (%s)\n"),
+                                             strhash,
+                                             vendor_get_name(model),
+                                             url);
+                } else {
+                  strhash = h_strdup_cprintf(_("Vendor=%s\n"),
+                                             strhash,
+                                             vendor_get_name(model));
+                }
+
+                strhash = h_strdup_cprintf(_("Type=%s\n"
+                                           "Revision=%s\n"
+                                           "[SCSI Controller]\n"
+                                           "Controller=scsi%d\n"
+                                           "Channel=%d\n"
+                                           "ID=%d\n" "LUN=%d\n"),
+                                           strhash,
+                                           type,
+                                           revision,
+                                           scsi_controller,
+                                           scsi_channel,
+                                           scsi_id,
+                                           scsi_lun);
+                moreinfo_add_with_prefix("DEV", devid, strhash);
+                g_free(devid);
+
+                g_free(model);
+                g_free(revision);
+                g_free(vendor);
+
+                scsi_controller = scsi_channel = scsi_id = scsi_lun = 0;
+            }
+        }
+        fclose(proc_scsi);
+    }
+
+    if (n) {
+      storage_list = h_strconcat(storage_list, scsi_storage_list, NULL);
+      g_free(scsi_storage_list);
+    }
+}
+
+void __scan_ide_devices(void)
+{
+    FILE *proc_ide;
+    gchar *device, iface, *model, *media, *pgeometry = NULL, *lgeometry = NULL;
+    gint n = 0, i = 0, cache, nn = 0;
+    gchar *capab = NULL, *speed = NULL, *driver = NULL, *ide_storage_list;
+
+    /* remove old devices from global device table */
+    moreinfo_del_with_prefix("DEV:IDE");
+
+    ide_storage_list = g_strdup(_("\n[IDE Disks]\n"));
+
+    iface = 'a';
+    for (i = 0; i <= 16; i++) {
+	device = g_strdup_printf("/proc/ide/hd%c/model", iface);
+	if (g_file_test(device, G_FILE_TEST_EXISTS)) {
+	    gchar buf[128];
+
+	    cache = 0;
+
+	    proc_ide = fopen(device, "r");
+	    if (!proc_ide)
+	        continue;
+
+	    (void) fgets(buf, 128, proc_ide);
+	    fclose(proc_ide);
+
+	    buf[strlen(buf) - 1] = 0;
+
+	    model = g_strdup(buf);
+
+	    g_free(device);
+
+	    device = g_strdup_printf("/proc/ide/hd%c/media", iface);
+	    proc_ide = fopen(device, "r");
+	    if (!proc_ide) {
+	        free(model);
+	        continue;
+            }
+
+	    (void) fgets(buf, 128, proc_ide);
+	    fclose(proc_ide);
+	    buf[strlen(buf) - 1] = 0;
+
+	    media = g_strdup(buf);
+	    if (g_str_equal(media, "cdrom")) {
+		/* obtain cd-rom drive information from cdrecord */
+		GTimer *timer;
+		gchar *tmp = g_strdup_printf("cdrecord dev=/dev/hd%c -prcap 2>/dev/stdout", iface);
+		FILE *prcap;
+
+		if ((prcap = popen(tmp, "r"))) {
+		    /* we need a timeout so cdrecord does not try to get information on cd drives
+		       with inserted media, which is not possible currently. half second should be
+		       enough. */
+		    timer = g_timer_new();
+		    g_timer_start(timer);
+
+		    while (fgets(buf, 128, prcap)
+			   && g_timer_elapsed(timer, NULL) < 0.5) {
+			if (g_str_has_prefix(buf, "  Does")) {
+			    if (g_str_has_suffix(buf, "media\n")
+				&& !strstr(buf, "speed")) {
+				gchar *media_type = g_strstrip(strstr(buf, "Does "));
+				gchar **ttmp = g_strsplit(media_type, " ", 0);
+
+				capab = h_strdup_cprintf("\nCan %s#%d=%s\n", capab, ttmp[1], ++nn, ttmp[2]);
+
+				g_strfreev(ttmp);
+			    } else if (strstr(buf, "Buffer-Underrun-Free")) {
+				capab =
+				    h_strdup_cprintf
+				    ("\nSupports BurnProof=%s\n", capab, strstr(buf, "Does not") ? "No" : "Yes");
+			    } else if (strstr(buf, "multi-session")) {
+				capab =
+				    h_strdup_cprintf
+				    ("\nCan read multi-session CDs=%s\n",
+				     capab, strstr(buf, "Does not") ? "No" : "Yes");
+			    } else if (strstr(buf, "audio CDs")) {
+				capab =
+				    h_strdup_cprintf
+				    ("\nCan play audio CDs=%s\n", capab, strstr(buf, "Does not") ? "No" : "Yes");
+			    } else if (strstr(buf, "PREVENT/ALLOW")) {
+				capab =
+				    h_strdup_cprintf
+				    ("\nCan lock media=%s\n", capab, strstr(buf, "Does not") ? "No" : "Yes");
+			    }
+			} else if ((strstr(buf, "read")
+				    || strstr(buf, "write"))
+				   && strstr(buf, "kB/s")) {
+			    speed =
+				g_strconcat(speed ? speed : "", strreplacechr(g_strstrip(buf), ":", '='), "\n", NULL);
+			} else if (strstr(buf, "Device seems to be")) {
+			    driver = g_strdup_printf(_("Driver=%s\n"), strchr(buf, ':') + 1);
+			}
+		    }
+
+		    pclose(prcap);
+		    g_timer_destroy(timer);
+		}
+
+		g_free(tmp);
+	    }
+	    g_free(device);
+
+	    device = g_strdup_printf("/proc/ide/hd%c/cache", iface);
+	    if (g_file_test(device, G_FILE_TEST_EXISTS)) {
+		proc_ide = fopen(device, "r");
+		if (proc_ide) {
+                    (void) fscanf(proc_ide, "%d", &cache);
+                    fclose(proc_ide);
+                } else {
+                    cache = 0;
+                }
+	    }
+	    g_free(device);
+
+	    device = g_strdup_printf("/proc/ide/hd%c/geometry", iface);
+	    if (g_file_test(device, G_FILE_TEST_EXISTS)) {
+		gchar *tmp;
+
+		proc_ide = fopen(device, "r");
+		if (proc_ide) {
+                    (void) fgets(buf, 64, proc_ide);
+                    for (tmp = buf; *tmp; tmp++) {
+                        if (*tmp >= '0' && *tmp <= '9')
+                            break;
+                    }
+
+                    pgeometry = g_strdup(g_strstrip(tmp));
+
+                    (void) fgets(buf, 64, proc_ide);
+                    for (tmp = buf; *tmp; tmp++) {
+                        if (*tmp >= '0' && *tmp <= '9')
+                            break;
+                    }
+                    lgeometry = g_strdup(g_strstrip(tmp));
+
+                    fclose(proc_ide);
+                } else {
+                    pgeometry = g_strdup("Unknown");
+                    lgeometry = g_strdup("Unknown");
+                }
+
+	    }
+	    g_free(device);
+
+	    n++;
+
+	    gchar *devid = g_strdup_printf("IDE%d", n);
+
+	    ide_storage_list = h_strdup_cprintf("$%s$%s=\n", ide_storage_list, devid, model);
+	    storage_icons =
+		h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons,
+				 devid, model, g_str_equal(media, "cdrom") ? "cdrom" : "hdd");
+
+	    gchar *strhash = g_strdup_printf(_("[Device Information]\n" "Model=%s\n"),
+					     model);
+
+	    const gchar *url = vendor_get_url(model);
+
+	    if (url) {
+		strhash = h_strdup_cprintf(_("Vendor=%s (%s)\n"), strhash, vendor_get_name(model), url);
+	    } else {
+		strhash = h_strdup_cprintf(_("Vendor=%s\n"), strhash, vendor_get_name(model));
+	    }
+
+	    strhash = h_strdup_cprintf(_("Device Name=hd%c\n"
+					 "Media=%s\n" "Cache=%dkb\n"), strhash, iface, media, cache);
+	    if (driver) {
+		strhash = h_strdup_cprintf("%s\n", strhash, driver);
+
+		g_free(driver);
+		driver = NULL;
+	    }
+
+	    if (pgeometry && lgeometry) {
+		strhash = h_strdup_cprintf(_("[Geometry]\n"
+					     "Physical=%s\n" "Logical=%s\n"), strhash, pgeometry, lgeometry);
+
+		g_free(pgeometry);
+		pgeometry = NULL;
+		g_free(lgeometry);
+		lgeometry = NULL;
+	    }
+
+	    if (capab) {
+		strhash = h_strdup_cprintf(_("[Capabilities]\n%s"), strhash, capab);
+
+		g_free(capab);
+		capab = NULL;
+	    }
+
+	    if (speed) {
+		strhash = h_strdup_cprintf(_("[Speeds]\n%s"), strhash, speed);
+
+		g_free(speed);
+		speed = NULL;
+	    }
+
+	    moreinfo_add_with_prefix("DEV", devid, strhash);
+	    g_free(devid);
+	    g_free(model);
+	} else {
+	    g_free(device);
+        }
+
+	iface++;
+    }
+
+    if (n) {
+	storage_list = h_strconcat(storage_list, ide_storage_list, NULL);
+	g_free(ide_storage_list);
+    }
+}
diff --git a/modules/devices/usb.c b/modules/devices/usb.c
new file mode 100644
index 0000000..9366c7c
--- /dev/null
+++ b/modules/devices/usb.c
@@ -0,0 +1,436 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2008 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+/*
+ * FIXME:
+ * - listing with sysfs does not generate device hierarchy
+ */
+
+#include <string.h>
+
+#include "hardinfo.h"
+#include "devices.h"
+
+gchar *usb_list = NULL;
+
+void __scan_usb_sysfs_add_device(gchar * endpoint, int n)
+{
+    gchar *manufacturer, *product, *mxpwr, *tmp, *strhash;
+    gint bus, classid, vendor, prodid;
+    gfloat version, speed;
+
+    classid = h_sysfs_read_int(endpoint, "bDeviceClass");
+    vendor = h_sysfs_read_int(endpoint, "idVendor");
+    prodid = h_sysfs_read_int(endpoint, "idProduct");
+    bus = h_sysfs_read_int(endpoint, "busnum");
+    speed = h_sysfs_read_float(endpoint, "speed");
+    version = h_sysfs_read_float(endpoint, "version");
+
+    if (!(mxpwr = h_sysfs_read_string(endpoint, "bMaxPower"))) {
+    	mxpwr = g_strdup_printf("%d %s", 0 , _("mA") );
+    }
+
+    if (!(manufacturer = h_sysfs_read_string(endpoint, "manufacturer"))) {
+    	manufacturer = g_strdup(_("(Unknown)"));
+    }
+
+    if (!(product = h_sysfs_read_string(endpoint, "product"))) {
+        if (classid == 9) {
+            product = g_strdup_printf(_(/*/%.2f is version*/ "USB %.2f Hub"), version);
+        } else {
+            product = g_strdup_printf(_("Unknown USB %.2f Device (class %d)"), version, classid);
+        }
+    }
+
+    const gchar *v_url = vendor_get_url(manufacturer);
+    const gchar *v_name = vendor_get_name(manufacturer);
+    gchar *v_str;
+    if (v_url != NULL) {
+        v_str = g_strdup_printf("%s (%s)", v_name, v_url);
+    } else {
+        v_str = g_strdup_printf("%s", manufacturer);
+    }
+
+    tmp = g_strdup_printf("USB%d", n);
+    usb_list = h_strdup_cprintf("$%s$%s=\n", usb_list, tmp, product);
+
+    strhash = g_strdup_printf("[%s]\n"
+             /* Product */      "%s=%s\n"
+             /* Manufacturer */ "%s=%s\n"
+             /* Speed */        "%s=%.2f %s\n"
+             /* Max Current */  "%s=%s\n"
+                  "[%s]\n"
+             /* USB Version */  "%s=%.2f\n"
+             /* Class */        "%s=0x%x\n"
+             /* Vendor */       "%s=0x%x\n"
+             /* Product ID */   "%s=0x%x\n"
+             /* Bus */          "%s=%d\n",
+                  _("Device Information"),
+                  _("Product"), product,
+                  _("Manufacturer"), v_str,
+                  _("Speed"), speed, _("Mbit/s"),
+                  _("Max Current"), mxpwr,
+                  _("Misc"),
+                  _("USB Version"), version,
+                  _("Class"), classid,
+                  _("Vendor ID"), vendor,
+                  _("Product ID"), prodid,
+                  _("Bus"), bus);
+
+    moreinfo_add_with_prefix("DEV", tmp, strhash);
+    g_free(tmp);
+    g_free(v_str);
+    g_free(manufacturer);
+    g_free(product);
+    g_free(mxpwr);
+}
+
+gboolean __scan_usb_sysfs(void)
+{
+    GDir *sysfs;
+    gchar *filename;
+    const gchar *sysfs_path = "/sys/class/usb_endpoint";
+    gint usb_device_number = 0;
+
+    if (!(sysfs = g_dir_open(sysfs_path, 0, NULL))) {
+	return FALSE;
+    }
+
+    if (usb_list) {
+       moreinfo_del_with_prefix("DEV:USB");
+	g_free(usb_list);
+    }
+    usb_list = g_strdup_printf("[%s]\n", _("USB Devices"));
+
+    while ((filename = (gchar *) g_dir_read_name(sysfs))) {
+	gchar *endpoint =
+	    g_build_filename(sysfs_path, filename, "device", NULL);
+	gchar *temp;
+
+	temp = g_build_filename(endpoint, "idVendor", NULL);
+	if (g_file_test(temp, G_FILE_TEST_EXISTS)) {
+	    __scan_usb_sysfs_add_device(endpoint, ++usb_device_number);
+	}
+
+	g_free(temp);
+	g_free(endpoint);
+    }
+
+    g_dir_close(sysfs);
+
+    return usb_device_number > 0;
+}
+
+gboolean __scan_usb_procfs(void)
+{
+    FILE *dev;
+    gchar buffer[128];
+    gchar *tmp, *manuf = NULL, *product = NULL, *mxpwr = NULL;
+    gint bus = 0, level = 0, port = 0, classid = 0, trash;
+    gint vendor = 0, prodid = 0;
+    gfloat ver = 0.0f, rev = 0.0f, speed = 0.0f;
+    int n = 0;
+
+    dev = fopen("/proc/bus/usb/devices", "r");
+    if (!dev)
+	return 0;
+
+    if (usb_list) {
+	moreinfo_del_with_prefix("DEV:USB");
+	g_free(usb_list);
+    }
+    usb_list = g_strdup_printf("[%s]\n", _("USB Devices"));
+
+    while (fgets(buffer, 128, dev)) {
+	tmp = buffer;
+
+	switch (*tmp) {
+	case 'T':
+	    sscanf(tmp,
+		   "T:  Bus=%d Lev=%d Prnt=%d Port=%d Cnt=%d Dev#=%d Spd=%f",
+		   &bus, &level, &trash, &port, &trash, &trash, &speed);
+	    break;
+	case 'D':
+	    sscanf(tmp, "D:  Ver=%f Cls=%x", &ver, &classid);
+	    break;
+	case 'P':
+	    sscanf(tmp, "P:  Vendor=%x ProdID=%x Rev=%f", &vendor, &prodid, &rev);
+	    break;
+	case 'S':
+	    if (strstr(tmp, "Manufacturer=")) {
+		manuf = g_strdup(strchr(tmp, '=') + 1);
+		remove_linefeed(manuf);
+	    } else if (strstr(tmp, "Product=")) {
+		product = g_strdup(strchr(tmp, '=') + 1);
+		remove_linefeed(product);
+	    }
+	    break;
+	case 'C':
+	    mxpwr = strstr(buffer, "MxPwr=") + 6;
+
+	    tmp = g_strdup_printf("USB%d", ++n);
+
+	    if (product && *product == '\0') {
+		g_free(product);
+		if (classid == 9) {
+		    product = g_strdup_printf(_("USB %.2f Hub"), ver);
+		} else {
+		    product = g_strdup_printf(_("Unknown USB %.2f Device (class %d)"), ver, classid);
+		}
+	    }
+
+        if (classid == 9) {	/* hub */
+            usb_list = h_strdup_cprintf("[%s#%d]\n", usb_list, product, n);
+        } else {		/* everything else */
+            usb_list = h_strdup_cprintf("$%s$%s=\n", usb_list, tmp, product);
+
+        EMPIFNULL(manuf);
+        const gchar *v_url = vendor_get_url(manuf);
+        const gchar *v_name = vendor_get_name(manuf);
+        gchar *v_str = NULL;
+        if (strlen(manuf)) {
+            if (v_url != NULL)
+                v_str = g_strdup_printf("%s (%s)", v_name, v_url);
+            else
+                v_str = g_strdup_printf("%s", manuf);
+        }
+        UNKIFNULL(v_str);
+        UNKIFNULL(product);
+
+        gchar *strhash = g_strdup_printf("[%s]\n" "%s=%s\n" "%s=%s\n",
+                        _("Device Information"),
+                        _("Product"), product,
+                        _("Manufacturer"), v_str);
+
+        strhash = h_strdup_cprintf("[%s #%d]\n"
+                  /* Speed */       "%s=%.2f %s\n"
+                  /* Max Current */ "%s=%s\n"
+                       "[%s]\n"
+                  /* USB Version */ "%s=%.2f\n"
+                  /* Revision */    "%s=%.2f\n"
+                  /* Class */       "%s=0x%x\n"
+                  /* Vendor */      "%s=0x%x\n"
+                  /* Product ID */  "%s=0x%x\n"
+                  /* Bus */         "%s=%d\n"
+                  /* Level */       "%s=%d\n",
+                       strhash,
+                       _("Port"), port,
+                       _("Speed"), speed, _("Mbit/s"),
+                       _("Max Current"), mxpwr,
+                       _("Misc"),
+                       _("USB Version"), ver,
+                       _("Revision"), rev,
+                       _("Class"), classid,
+                       _("Vendor ID"), vendor,
+                       _("Product ID"), prodid,
+                       _("Bus"), bus,
+                       _("Level"), level);
+
+        moreinfo_add_with_prefix("DEV", tmp, strhash);
+        g_free(v_str);
+        g_free(tmp);
+        }
+
+	    g_free(manuf);
+	    g_free(product);
+	    manuf = NULL;
+	    product = NULL;
+	    port = classid = 0;
+	}
+    }
+
+    fclose(dev);
+
+    return n > 0;
+}
+
+
+void __scan_usb_lsusb_add_device(char *buffer, int bufsize, FILE * lsusb, int usb_device_number)
+{
+    gint bus, device, vendor_id, product_id;
+    gchar *version = NULL, *product = NULL, *vendor = NULL, *dev_class = NULL, *int_class = NULL;
+    gchar *max_power = NULL, *name = NULL;
+    gchar *tmp, *strhash;
+    long position = 0;
+
+    g_strstrip(buffer);
+    sscanf(buffer, "Bus %d Device %d: ID %x:%x", &bus, &device, &vendor_id, &product_id);
+    name = g_strdup(buffer + 33);
+
+    for (fgets(buffer, bufsize, lsusb); position >= 0 && fgets(buffer, bufsize, lsusb); position = ftell(lsusb)) {
+	g_strstrip(buffer);
+
+	if (g_str_has_prefix(buffer, "idVendor")) {
+	    g_free(vendor);
+	    vendor = g_strdup(buffer + 26);
+	} else if (g_str_has_prefix(buffer, "idProduct")) {
+	    g_free(product);
+	    product = g_strdup(buffer + 26);
+	} else if (g_str_has_prefix(buffer, "MaxPower")) {
+	    g_free(max_power);
+	    max_power = g_strdup(buffer + 9);
+	} else if (g_str_has_prefix(buffer, "bcdUSB")) {
+	    g_free(version);
+	    version = g_strdup(buffer + 7);
+	} else if (g_str_has_prefix(buffer, "bDeviceClass")) {
+	    g_free(dev_class);
+	    dev_class = g_strdup(buffer + 14);
+	} else if (g_str_has_prefix(buffer, "bInterfaceClass")) {
+	    g_free(int_class);
+	    int_class = g_strdup(buffer + 16);
+	} else if (g_str_has_prefix(buffer, "Bus ")) {
+	    /* device separator */
+	    fseek(lsusb, position, SEEK_SET);
+	    break;
+	}
+    }
+
+    if (dev_class && strstr(dev_class, "0 (Defined at Interface level)")) {
+        g_free(dev_class);
+        if (int_class) {
+            dev_class = int_class;
+        } else {
+            dev_class = g_strdup(_("(Unknown)"));
+        }
+    } else
+    dev_class = g_strdup(_("(Unknown)"));
+
+    tmp = g_strdup_printf("USB%d", usb_device_number);
+    usb_list = h_strdup_cprintf("$%s$%s=\n", usb_list, tmp, name);
+
+    const gchar *v_url = vendor_get_url(vendor);
+    const gchar *v_name = vendor_get_name(vendor);
+    gchar *v_str;
+    if (v_url != NULL) {
+        v_str = g_strdup_printf("%s (%s)", v_name, v_url);
+    } else {
+        v_str = g_strdup_printf("%s", g_strstrip(vendor) );
+    }
+
+    if (max_power != NULL) {
+        int mA = atoi(g_strstrip(max_power));
+        gchar *trent_steel = g_strdup_printf("%d %s", mA, _("mA"));
+        g_free(max_power);
+        max_power = trent_steel;
+    }
+
+    UNKIFNULL(product);
+    UNKIFNULL(v_str);
+    UNKIFNULL(max_power);
+    UNKIFNULL(version);
+    UNKIFNULL(dev_class);
+
+    strhash = g_strdup_printf("[%s]\n"
+             /* Product */      "%s=%s\n"
+             /* Manufacturer */ "%s=%s\n"
+             /* Max Current */  "%s=%s\n"
+                            "[%s]\n"
+             /* USB Version */ "%s=%s\n"
+             /* Class */       "%s=%s\n"
+             /* Vendor ID */   "%s=0x%x\n"
+             /* Product ID */  "%s=0x%x\n"
+             /* Bus */         "%s=%d\n",
+                _("Device Information"),
+                _("Product"), g_strstrip(product),
+                _("Vendor"), v_str,
+                _("Max Current"), g_strstrip(max_power),
+                _("Misc"),
+                _("USB Version"), g_strstrip(version),
+                _("Class"), g_strstrip(dev_class),
+                _("Vendor ID"), vendor_id,
+                _("Product ID"), product_id,
+                _("Bus"), bus);
+
+    moreinfo_add_with_prefix("DEV", tmp, strhash);
+    g_free(v_str);
+    g_free(vendor);
+    g_free(product);
+    g_free(max_power);
+    g_free(dev_class);
+    g_free(version);
+    g_free(tmp);
+    g_free(name);
+}
+
+gboolean __scan_usb_lsusb(void)
+{
+    static gchar *lsusb_path = NULL;
+    int usb_device_number = 0;
+    FILE *lsusb;
+    FILE *temp_lsusb;
+    char buffer[512], *temp;
+
+    if (!lsusb_path) {
+        if (!(lsusb_path = find_program("lsusb"))) {
+            DEBUG("lsusb not found");
+
+            return FALSE;
+        }
+    }
+
+    temp = g_strdup_printf("%s -v | tr '[]' '()'", lsusb_path);
+    if (!(lsusb = popen(temp, "r"))) {
+        DEBUG("cannot run %s", lsusb_path);
+
+        g_free(temp);
+        return FALSE;
+    }
+
+    temp_lsusb = tmpfile();
+    if (!temp_lsusb) {
+        DEBUG("cannot create temporary file for lsusb");
+        pclose(lsusb);
+	 g_free(temp);
+        return FALSE;
+    }
+
+    while (fgets(buffer, sizeof(buffer), lsusb)) {
+        fputs(buffer, temp_lsusb);
+    }
+
+    pclose(lsusb);
+
+    // rewind file so we can read from it
+    fseek(temp_lsusb, 0, SEEK_SET);
+
+    g_free(temp);
+
+    if (usb_list) {
+       moreinfo_del_with_prefix("DEV:USB");
+        g_free(usb_list);
+    }
+    usb_list = g_strdup_printf("[%s]\n", _("USB Devices"));
+
+    while (fgets(buffer, sizeof(buffer), temp_lsusb)) {
+        if (g_str_has_prefix(buffer, "Bus ")) {
+           __scan_usb_lsusb_add_device(buffer, sizeof(buffer), temp_lsusb, ++usb_device_number);
+        }
+    }
+
+    fclose(temp_lsusb);
+
+    return usb_device_number > 0;
+}
+
+void __scan_usb(void)
+{
+    if (!__scan_usb_procfs()) {
+        if (!__scan_usb_sysfs()) {
+             __scan_usb_lsusb();
+        }
+    }
+}
diff --git a/modules/devices/x86/processor.c b/modules/devices/x86/processor.c
new file mode 100644
index 0000000..f1c2b6e
--- /dev/null
+++ b/modules/devices/x86/processor.c
@@ -0,0 +1,747 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+
+#include "x86_data.h"
+#include "x86_data.c"
+
+/*
+ * This function is partly based on x86cpucaps
+ * by Osamu Kayasono <jacobi@jcom.home.ne.jp>
+ */
+void get_processor_strfamily(Processor * processor)
+{
+    gint family = processor->family;
+    gint model = processor->model;
+
+    if (g_str_equal(processor->vendor_id, "GenuineIntel")) {
+	if (family == 4) {
+	    processor->strmodel = g_strdup("i486 series");
+	} else if (family == 5) {
+	    if (model < 4) {
+		processor->strmodel = g_strdup("Pentium Classic");
+	    } else {
+		processor->strmodel = g_strdup("Pentium MMX");
+	    }
+	} else if (family == 6) {
+	    if (model <= 1) {
+		processor->strmodel = g_strdup("Pentium Pro");
+	    } else if (model < 7) {
+		processor->strmodel = g_strdup("Pentium II/Pentium II Xeon/Celeron");
+	    } else if (model == 9) {
+		processor->strmodel = g_strdup("Pentium M");
+	    } else {
+		processor->strmodel = g_strdup("Pentium III/Pentium III Xeon/Celeron/Core Duo/Core Duo 2");
+	    }
+	} else if (family > 6) {
+	    processor->strmodel = g_strdup("Pentium 4");
+	} else {
+	    processor->strmodel = g_strdup("i386 class");
+	}
+    } else if (g_str_equal(processor->vendor_id, "AuthenticAMD")) {
+	if (family == 4) {
+	    if (model <= 9) {
+		processor->strmodel = g_strdup("AMD i80486 series");
+	    } else {
+		processor->strmodel = g_strdup("AMD 5x86");
+	    }
+	} else if (family == 5) {
+	    if (model <= 3) {
+		processor->strmodel = g_strdup("AMD K5");
+	    } else if (model <= 7) {
+		processor->strmodel = g_strdup("AMD K6");
+	    } else if (model == 8) {
+		processor->strmodel = g_strdup("AMD K6-2");
+	    } else if (model == 9) {
+		processor->strmodel = g_strdup("AMD K6-III");
+	    } else {
+		processor->strmodel = g_strdup("AMD K6-2+/III+");
+	    }
+	} else if (family == 6) {
+	    if (model == 1) {
+		processor->strmodel = g_strdup("AMD Athlon (K7)");
+	    } else if (model == 2) {
+		processor->strmodel = g_strdup("AMD Athlon (K75)");
+	    } else if (model == 3) {
+		processor->strmodel = g_strdup("AMD Duron (Spitfire)");
+	    } else if (model == 4) {
+		processor->strmodel = g_strdup("AMD Athlon (Thunderbird)");
+	    } else if (model == 6) {
+		processor->strmodel = g_strdup("AMD Athlon XP/MP/4 (Palomino)");
+	    } else if (model == 7) {
+		processor->strmodel = g_strdup("AMD Duron (Morgan)");
+	    } else if (model == 8) {
+		processor->strmodel = g_strdup("AMD Athlon XP/MP (Thoroughbred)");
+	    } else if (model == 10) {
+		processor->strmodel = g_strdup("AMD Athlon XP/MP (Barton)");
+	    } else {
+		processor->strmodel = g_strdup("AMD Athlon (unknown)");
+	    }
+	} else if (family > 6) {
+	    processor->strmodel = g_strdup("AMD Opteron/Athlon64/FX");
+	} else {
+	    processor->strmodel = g_strdup("AMD i386 class");
+	}
+    } else if (g_str_equal(processor->vendor_id, "CyrixInstead")) {
+	if (family == 4) {
+	    processor->strmodel = g_strdup("Cyrix 5x86");
+	} else if (family == 5) {
+	    processor->strmodel = g_strdup("Cyrix M1 (6x86)");
+	} else if (family == 6) {
+	    if (model == 0) {
+		processor->strmodel = g_strdup("Cyrix M2 (6x86MX)");
+	    } else if (model <= 5) {
+		processor->strmodel = g_strdup("VIA Cyrix III (M2 core)");
+	    } else if (model == 6) {
+		processor->strmodel = g_strdup("VIA Cyrix III (WinChip C5A)");
+	    } else if (model == 7) {
+		processor->strmodel = g_strdup("VIA Cyrix III (WinChip C5B/C)");
+	    } else {
+		processor->strmodel = g_strdup("VIA Cyrix III (WinChip C5C-T)");
+	    }
+	} else {
+	    processor->strmodel = g_strdup("Cyrix i386 class");
+	}
+    } else if (g_str_equal(processor->vendor_id, "CentaurHauls")) {
+	if (family == 5) {
+	    if (model <= 4) {
+		processor->strmodel = g_strdup("Centaur WinChip C6");
+	    } else if (model <= 8) {
+		processor->strmodel = g_strdup("Centaur WinChip 2");
+	    } else {
+		processor->strmodel = g_strdup("Centaur WinChip 2A");
+	    }
+	} else {
+	    processor->strmodel = g_strdup("Centaur i386 class");
+	}
+    } else if (g_str_equal(processor->vendor_id, "GenuineTMx86")) {
+	processor->strmodel = g_strdup("Transmeta Crusoe TM3x00/5x00");
+    } else {
+	processor->strmodel = g_strdup("Unknown");
+    }
+}
+
+static gchar *__cache_get_info_as_string(Processor *processor)
+{
+    gchar *result = g_strdup("");
+    GSList *cache_list;
+    ProcessorCache *cache;
+
+    if (!processor->cache) {
+        return g_strdup(_("Cache information not available=\n"));
+    }
+
+    for (cache_list = processor->cache; cache_list; cache_list = cache_list->next) {
+        cache = (ProcessorCache *)cache_list->data;
+
+        result = h_strdup_cprintf(_("Level %d (%s)=%d-way set-associative, %d sets, %dKB size\n"),
+                                  result,
+                                  cache->level,
+                                  C_("cache-type", cache->type),
+                                  cache->ways_of_associativity,
+                                  cache->number_of_sets,
+                                  cache->size);
+    }
+
+    return result;
+}
+
+/* This is not used directly, but creates translatable strings for
+ * the type string returned from /sys/.../cache */
+static const char* cache_types[] = {
+    NC_("cache-type", /*/cache type, as appears in: Level 1 (Data)*/ "Data"),
+    NC_("cache-type", /*/cache type, as appears in: Level 1 (Instruction)*/ "Instruction"),
+    NC_("cache-type", /*/cache type, as appears in: Level 2 (Unified)*/ "Unified")
+};
+
+static void __cache_obtain_info(Processor *processor)
+{
+    ProcessorCache *cache;
+    gchar *endpoint, *entry, *index;
+    gchar *uref = NULL;
+    gint i;
+    gint processor_number = processor->id;
+
+    endpoint = g_strdup_printf("/sys/devices/system/cpu/cpu%d/cache", processor_number);
+
+    for (i = 0; ; i++) {
+      cache = g_new0(ProcessorCache, 1);
+
+      index = g_strdup_printf("index%d/", i);
+
+      entry = g_strconcat(index, "type", NULL);
+      cache->type = h_sysfs_read_string(endpoint, entry);
+      g_free(entry);
+
+      if (!cache->type) {
+        g_free(cache);
+        g_free(index);
+        goto fail;
+      }
+
+      entry = g_strconcat(index, "level", NULL);
+      cache->level = h_sysfs_read_int(endpoint, entry);
+      g_free(entry);
+
+      entry = g_strconcat(index, "number_of_sets", NULL);
+      cache->number_of_sets = h_sysfs_read_int(endpoint, entry);
+      g_free(entry);
+
+      entry = g_strconcat(index, "physical_line_partition", NULL);
+      cache->physical_line_partition = h_sysfs_read_int(endpoint, entry);
+      g_free(entry);
+
+      entry = g_strconcat(index, "size", NULL);
+      cache->size = h_sysfs_read_int(endpoint, entry);
+      g_free(entry);
+
+      entry = g_strconcat(index, "ways_of_associativity", NULL);
+      cache->ways_of_associativity = h_sysfs_read_int(endpoint, entry);
+      g_free(entry);
+
+      /* unique cache references: id is nice, but share_cpu_list can be
+       * used if it is not available. */
+      entry = g_strconcat(index, "id", NULL);
+      uref = h_sysfs_read_string(endpoint, entry);
+      g_free(entry);
+      if (uref != NULL && *uref != 0 )
+        cache->uid = atoi(uref);
+      else
+        cache->uid = -1;
+      g_free(uref);
+      entry = g_strconcat(index, "shared_cpu_list", NULL);
+      cache->shared_cpu_list = h_sysfs_read_string(endpoint, entry);
+      g_free(entry);
+
+      /* reacharound */
+      entry = g_strconcat(index, "../../topology/physical_package_id", NULL);
+      cache->phy_sock = h_sysfs_read_int(endpoint, entry);
+      g_free(entry);
+
+      g_free(index);
+
+      processor->cache = g_slist_append(processor->cache, cache);
+    }
+
+fail:
+    g_free(endpoint);
+}
+
+#define khzint_to_mhzdouble(k) (((double)k)/1000)
+#define cmp_clocks_test(f) if (a->f < b->f) return -1; if (a->f > b->f) return 1;
+
+static gint cmp_cpufreq_data(cpufreq_data *a, cpufreq_data *b) {
+        gint i = 0;
+        i = g_strcmp0(a->shared_list, b->shared_list); if (i!=0) return i;
+        cmp_clocks_test(cpukhz_max);
+        cmp_clocks_test(cpukhz_min);
+        return 0;
+}
+
+static gint cmp_cpufreq_data_ignore_affected(cpufreq_data *a, cpufreq_data *b) {
+        gint i = 0;
+        cmp_clocks_test(cpukhz_max);
+        cmp_clocks_test(cpukhz_min);
+        return 0;
+}
+
+gchar *clocks_summary(GSList * processors)
+{
+    gchar *ret = g_strdup_printf("[%s]\n", _("Clocks"));
+    GSList *all_clocks = NULL, *uniq_clocks = NULL;
+    GSList *tmp, *l;
+    Processor *p;
+    cpufreq_data *c, *cur = NULL;
+    gint cur_count = 0, i = 0;
+
+    /* create list of all clock references */
+    for (l = processors; l; l = l->next) {
+        p = (Processor*)l->data;
+        if (p->cpufreq) {
+            all_clocks = g_slist_prepend(all_clocks, p->cpufreq);
+        }
+    }
+
+    if (g_slist_length(all_clocks) == 0) {
+        ret = h_strdup_cprintf("%s=\n", ret, _("(Not Available)") );
+        g_slist_free(all_clocks);
+        return ret;
+    }
+
+    /* ignore duplicate references */
+    all_clocks = g_slist_sort(all_clocks, (GCompareFunc)cmp_cpufreq_data);
+    for (l = all_clocks; l; l = l->next) {
+        c = (cpufreq_data*)l->data;
+        if (!cur) {
+            cur = c;
+        } else {
+            if (cmp_cpufreq_data(cur, c) != 0) {
+                uniq_clocks = g_slist_prepend(uniq_clocks, cur);
+                cur = c;
+            }
+        }
+    }
+    uniq_clocks = g_slist_prepend(uniq_clocks, cur);
+    uniq_clocks = g_slist_reverse(uniq_clocks);
+    cur = 0, cur_count = 0;
+
+    /* count and list clocks */
+    for (l = uniq_clocks; l; l = l->next) {
+        c = (cpufreq_data*)l->data;
+        if (!cur) {
+            cur = c;
+            cur_count = 1;
+        } else {
+            if (cmp_cpufreq_data_ignore_affected(cur, c) != 0) {
+                ret = h_strdup_cprintf(_("%.2f-%.2f %s=%dx\n"),
+                                ret,
+                                khzint_to_mhzdouble(cur->cpukhz_min),
+                                khzint_to_mhzdouble(cur->cpukhz_max),
+                                _("MHz"),
+                                cur_count);
+                cur = c;
+                cur_count = 1;
+            } else {
+                cur_count++;
+            }
+        }
+    }
+    ret = h_strdup_cprintf(_("%.2f-%.2f %s=%dx\n"),
+                    ret,
+                    khzint_to_mhzdouble(cur->cpukhz_min),
+                    khzint_to_mhzdouble(cur->cpukhz_max),
+                    _("MHz"),
+                    cur_count);
+
+    g_slist_free(all_clocks);
+    g_slist_free(uniq_clocks);
+    return ret;
+}
+
+#define cmp_cache_test(f) if (a->f < b->f) return -1; if (a->f > b->f) return 1;
+
+static gint cmp_cache(ProcessorCache *a, ProcessorCache *b) {
+        gint i = 0;
+        cmp_cache_test(phy_sock);
+        i = g_strcmp0(a->type, b->type); if (i!=0) return i;
+        cmp_cache_test(level);
+        cmp_cache_test(size);
+        cmp_cache_test(uid); /* uid is unique among caches with the same (type, level) */
+        if (a->uid == -1) {
+            /* if id wasn't available, use shared_cpu_list as a unique ref */
+            i = g_strcmp0(a->shared_cpu_list, b->shared_cpu_list); if (i!=0)
+            return i;
+        }
+        return 0;
+}
+
+static gint cmp_cache_ignore_id(ProcessorCache *a, ProcessorCache *b) {
+        gint i = 0;
+        cmp_cache_test(phy_sock);
+        i = g_strcmp0(a->type, b->type); if (i!=0) return i;
+        cmp_cache_test(level);
+        cmp_cache_test(size);
+        return 0;
+}
+
+gchar *caches_summary(GSList * processors)
+{
+    gchar *ret = g_strdup_printf("[%s]\n", _("Caches"));
+    GSList *all_cache = NULL, *uniq_cache = NULL;
+    GSList *tmp, *l;
+    Processor *p;
+    ProcessorCache *c, *cur = NULL;
+    gint cur_count = 0, i = 0;
+
+    /* create list of all cache references */
+    for (l = processors; l; l = l->next) {
+        p = (Processor*)l->data;
+        if (p->cache) {
+            tmp = g_slist_copy(p->cache);
+            if (all_cache) {
+                all_cache = g_slist_concat(all_cache, tmp);
+            } else {
+                all_cache = tmp;
+            }
+        }
+    }
+
+    if (g_slist_length(all_cache) == 0) {
+        ret = h_strdup_cprintf("%s=\n", ret, _("(Not Available)") );
+        g_slist_free(all_cache);
+        return ret;
+    }
+
+    /* ignore duplicate references */
+    all_cache = g_slist_sort(all_cache, (GCompareFunc)cmp_cache);
+    for (l = all_cache; l; l = l->next) {
+        c = (ProcessorCache*)l->data;
+        if (!cur) {
+            cur = c;
+        } else {
+            if (cmp_cache(cur, c) != 0) {
+                uniq_cache = g_slist_prepend(uniq_cache, cur);
+                cur = c;
+            }
+        }
+    }
+    uniq_cache = g_slist_prepend(uniq_cache, cur);
+    uniq_cache = g_slist_reverse(uniq_cache);
+    cur = 0, cur_count = 0;
+
+    /* count and list caches */
+    for (l = uniq_cache; l; l = l->next) {
+        c = (ProcessorCache*)l->data;
+        if (!cur) {
+            cur = c;
+            cur_count = 1;
+        } else {
+            if (cmp_cache_ignore_id(cur, c) != 0) {
+                ret = h_strdup_cprintf(_("Level %d (%s)#%d=%dx %dKB (%dKB), %d-way set-associative, %d sets\n"),
+                                      ret,
+                                      cur->level,
+                                      C_("cache-type", cur->type),
+                                      cur->phy_sock,
+                                      cur_count,
+                                      cur->size,
+                                      cur->size * cur_count,
+                                      cur->ways_of_associativity,
+                                      cur->number_of_sets);
+                cur = c;
+                cur_count = 1;
+            } else {
+                cur_count++;
+            }
+        }
+    }
+    ret = h_strdup_cprintf(_("Level %d (%s)#%d=%dx %dKB (%dKB), %d-way set-associative, %d sets\n"),
+                          ret,
+                          cur->level,
+                          C_("cache-type", cur->type),
+                          cur->phy_sock,
+                          cur_count,
+                          cur->size,
+                          cur->size * cur_count,
+                          cur->ways_of_associativity,
+                          cur->number_of_sets);
+
+    g_slist_free(all_cache);
+    g_slist_free(uniq_cache);
+    return ret;
+}
+
+#define PROC_SCAN_READ_BUFFER_SIZE 896
+GSList *processor_scan(void)
+{
+    GSList *procs = NULL, *l = NULL;
+    Processor *processor = NULL;
+    FILE *cpuinfo;
+    gchar buffer[PROC_SCAN_READ_BUFFER_SIZE];
+
+    cpuinfo = fopen(PROC_CPUINFO, "r");
+    if (!cpuinfo)
+        return NULL;
+
+    while (fgets(buffer, PROC_SCAN_READ_BUFFER_SIZE, cpuinfo)) {
+        int rlen = strlen(buffer);
+        if (rlen >= PROC_SCAN_READ_BUFFER_SIZE - 1) {
+            fprintf(stderr, "Warning: truncated a line (probably flags list) longer than %d bytes while reading %s.\n", PROC_SCAN_READ_BUFFER_SIZE, PROC_CPUINFO);
+        }
+        gchar **tmp = g_strsplit(buffer, ":", 2);
+        if (!tmp[1] || !tmp[0]) {
+            g_strfreev(tmp);
+            continue;
+        }
+
+        tmp[0] = g_strstrip(tmp[0]);
+        tmp[1] = g_strstrip(tmp[1]);
+
+        if (g_str_has_prefix(tmp[0], "processor")) {
+            /* finish previous */
+            if (processor)
+                procs = g_slist_append(procs, processor);
+
+            /* start next */
+            processor = g_new0(Processor, 1);
+            processor->id = atol(tmp[1]);
+            g_strfreev(tmp);
+            continue;
+        }
+
+        if (processor) {
+            get_str("model name", processor->model_name);
+            get_str("vendor_id", processor->vendor_id);
+            get_str("flags", processor->flags);
+            get_str("bugs", processor->bugs);
+            get_str("power management", processor->pm);
+            get_str("microcode", processor->microcode);
+            get_int("cache size", processor->cache_size);
+            get_float("cpu MHz", processor->cpu_mhz);
+            get_float("bogomips", processor->bogomips);
+
+            get_str("fpu", processor->has_fpu);
+
+            get_str("fdiv_bug", processor->bug_fdiv);
+            get_str("hlt_bug", processor->bug_hlt);
+            get_str("f00f_bug", processor->bug_f00f);
+            get_str("coma_bug", processor->bug_coma);
+            /* sep_bug? */
+
+            get_int("model", processor->model);
+            get_int("cpu family", processor->family);
+            get_int("stepping", processor->stepping);
+        }
+        g_strfreev(tmp);
+    }
+
+    fclose(cpuinfo);
+
+    /* finish last */
+    if (processor)
+        procs = g_slist_append(procs, processor);
+
+    for (l = procs; l; l = l->next) {
+        processor = (Processor *) l->data;
+
+        STRIFNULL(processor->microcode, _("(Not Available)") );
+
+        get_processor_strfamily(processor);
+        __cache_obtain_info(processor);
+
+#define NULLIFNOTYES(f) if (processor->f) if (strcmp(processor->f, "yes") != 0) { g_free(processor->f); processor->f = NULL; }
+        NULLIFNOTYES(bug_fdiv);
+        NULLIFNOTYES(bug_hlt);
+        NULLIFNOTYES(bug_f00f);
+        NULLIFNOTYES(bug_coma);
+
+        if (processor->bugs == NULL || g_strcmp0(processor->bugs, "") == 0) {
+            g_free(processor->bugs);
+            /* make bugs list on old kernels that don't offer one */
+            processor->bugs = g_strdup_printf("%s%s%s%s%s%s%s%s%s%s",
+                    /* the oldest bug workarounds indicated in /proc/cpuinfo */
+                    processor->bug_fdiv ? " fdiv" : "",
+                    processor->bug_hlt  ? " _hlt" : "",
+                    processor->bug_f00f ? " f00f" : "",
+                    processor->bug_coma ? " coma" : "",
+                    /* these bug workarounds were reported as "features" in older kernels */
+                    processor_has_flag(processor->flags, "fxsave_leak")     ? " fxsave_leak" : "",
+                    processor_has_flag(processor->flags, "clflush_monitor") ? " clflush_monitor" : "",
+                    processor_has_flag(processor->flags, "11ap")            ? " 11ap" : "",
+                    processor_has_flag(processor->flags, "tlb_mmatch")      ? " tlb_mmatch" : "",
+                    processor_has_flag(processor->flags, "apic_c1e")        ? " apic_c1e" : "",
+                    ""); /* just to make adding lines easier */
+            g_strchug(processor->bugs);
+        }
+
+        if (processor->pm == NULL || g_strcmp0(processor->pm, "") == 0) {
+            g_free(processor->pm);
+            /* make power management list on old kernels that don't offer one */
+            processor->pm = g_strdup_printf("%s%s",
+                    /* "hw_pstate" -> "hwpstate" */
+                    processor_has_flag(processor->flags, "hw_pstate") ? " hwpstate" : "",
+                    ""); /* just to make adding lines easier */
+            g_strchug(processor->pm);
+        }
+
+        /* topo & freq */
+        processor->cpufreq = cpufreq_new(processor->id);
+        processor->cputopo = cputopo_new(processor->id);
+
+        if (processor->cpufreq->cpukhz_max)
+            processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+    }
+
+    return procs;
+}
+
+gchar *processor_get_capabilities_from_flags(gchar *strflags, gchar *lookup_prefix)
+{
+    gchar **flags, **old;
+    gchar tmp_flag[64] = "";
+    const gchar *meaning;
+    gchar *tmp = NULL;
+    gint j = 0, i = 0;
+
+    flags = g_strsplit(strflags, " ", 0);
+    old = flags;
+
+    while (flags[j]) {
+        if ( sscanf(flags[j], "[%d]", &i) ) {
+            /* Some flags are indexes, like [13], and that looks like
+             * a new section to hardinfo shell */
+            tmp = h_strdup_cprintf("(%s%d)=\n", tmp,
+                (lookup_prefix) ? lookup_prefix : "",
+                i );
+        } else {
+            sprintf(tmp_flag, "%s%s", lookup_prefix, flags[j]);
+            meaning = x86_flag_meaning(tmp_flag);
+
+            if (meaning) {
+                tmp = h_strdup_cprintf("%s=%s\n", tmp, flags[j], meaning);
+            } else {
+                tmp = h_strdup_cprintf("%s=\n", tmp, flags[j]);
+            }
+        }
+        j++;
+    }
+    if (tmp == NULL || g_strcmp0(tmp, "") == 0)
+        tmp = g_strdup_printf("%s=%s\n", "empty", _("Empty List"));
+
+    g_strfreev(old);
+    return tmp;
+}
+
+gchar *processor_get_detailed_info(Processor * processor)
+{
+    gchar *tmp_flags, *tmp_bugs, *tmp_pm, *tmp_cpufreq, *tmp_topology, *ret, *cache_info;
+
+    tmp_flags = processor_get_capabilities_from_flags(processor->flags, "");
+    tmp_bugs = processor_get_capabilities_from_flags(processor->bugs, "bug:");
+    tmp_pm = processor_get_capabilities_from_flags(processor->pm, "pm:");
+    cache_info = __cache_get_info_as_string(processor);
+
+    tmp_topology = cputopo_section_str(processor->cputopo);
+    tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+    ret = g_strdup_printf("[%s]\n"
+                       "%s=%s\n"
+                       "%s=%d, %d, %d (%s)\n" /* family, model, stepping (decoded name) */
+                       "%s=%s\n"      /* vendor */
+                       "%s=%s\n"      /* microcode */
+                       "[%s]\n"       /* configuration */
+                       "%s=%d %s\n"   /* cache size (from cpuinfo) */
+                       "%s=%.2f %s\n" /* frequency */
+                       "%s=%.2f\n"    /* bogomips */
+                       "%s=%s\n"      /* byte order */
+                       "%s"     /* topology */
+                       "%s"     /* frequency scaling */
+                       "[%s]\n" /* cache */
+                       "%s\n"
+                       "[%s]\n" /* pm */
+                       "%s"
+                       "[%s]\n" /* bugs */
+                       "%s"
+                       "[%s]\n" /* flags */
+                       "%s",
+                   _("Processor"),
+                   _("Model Name"), processor->model_name,
+                   _("Family, model, stepping"),
+                   processor->family,
+                   processor->model,
+                   processor->stepping,
+                   processor->strmodel,
+                   _("Vendor"), vendor_get_name(processor->vendor_id),
+                   _("Microcode Version"), processor->microcode,
+                   _("Configuration"),
+                   _("Cache Size"), processor->cache_size, _("kb"),
+                   _("Frequency"), processor->cpu_mhz, _("MHz"),
+                   _("BogoMips"), processor->bogomips,
+                   _("Byte Order"), byte_order_str(),
+                   tmp_topology,
+                   tmp_cpufreq,
+                   _("Cache"), cache_info,
+                   _("Power Management"), tmp_pm,
+                   _("Bug Workarounds"), tmp_bugs,
+                   _("Capabilities"), tmp_flags );
+    g_free(tmp_flags);
+    g_free(tmp_bugs);
+    g_free(tmp_pm);
+    g_free(cache_info);
+    g_free(tmp_cpufreq);
+    g_free(tmp_topology);
+    return ret;
+}
+
+gchar *processor_name(GSList * processors) {
+    return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+    return processor_describe_default(processors);
+}
+
+gchar *processor_meta(GSList * processors) {
+    gchar *meta_cpu_name = processor_name(processors);
+    gchar *meta_cpu_desc = processor_describe(processors);
+    gchar *meta_freq_desc = processor_frequency_desc(processors);
+    gchar *meta_clocks = clocks_summary(processors);
+    gchar *meta_caches = caches_summary(processors);
+    gchar *ret = NULL;
+    UNKIFNULL(meta_cpu_desc);
+    ret = g_strdup_printf("[%s]\n"
+                        "%s=%s\n"
+                        "%s=%s\n"
+                        "%s=%s\n"
+                        "%s"
+                        "%s",
+                        _("Package Information"),
+                        _("Name"), meta_cpu_name,
+                        _("Topology"), meta_cpu_desc,
+                        _("Logical CPU Config"), meta_freq_desc,
+                        meta_clocks,
+                        meta_caches);
+    g_free(meta_cpu_desc);
+    g_free(meta_freq_desc);
+    g_free(meta_clocks);
+    g_free(meta_caches);
+    return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
+{
+    Processor *processor;
+    gchar *ret, *tmp, *hashkey;
+    gchar *meta; /* becomes owned by more_info? no need to free? */
+    GSList *l;
+
+    tmp = g_strdup_printf("$CPU_META$%s=\n", _("Package Information") );
+
+    meta = processor_meta(processors);
+    moreinfo_add_with_prefix("DEV", "CPU_META", meta);
+
+    for (l = processors; l; l = l->next) {
+        processor = (Processor *) l->data;
+
+        tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s|%d:%d|%d\n",
+                  tmp, processor->id,
+                  processor->model_name,
+                  processor->cpu_mhz, _("MHz"),
+                  processor->cputopo->socket_id,
+                  processor->cputopo->core_id,
+                  processor->cputopo->id );
+
+        hashkey = g_strdup_printf("CPU%d", processor->id);
+        moreinfo_add_with_prefix("DEV", hashkey,
+                processor_get_detailed_info(processor));
+        g_free(hashkey);
+    }
+
+    ret = g_strdup_printf("[$ShellParam$]\n"
+                  "ViewType=1\n"
+                  "ColumnTitle$Extra1=%s\n"
+                  "ColumnTitle$Extra2=%s\n"
+                  "[Processors]\n"
+                  "%s", _("Socket:Core"), _("Thread" /*TODO: +s*/), tmp);
+    g_free(tmp);
+
+    return ret;
+}
+
diff --git a/modules/devices/x86/x86_data.c b/modules/devices/x86/x86_data.c
new file mode 100644
index 0000000..c052f4e
--- /dev/null
+++ b/modules/devices/x86/x86_data.c
@@ -0,0 +1,348 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * Copyright (C) 2017  Burt P. <pburt0@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "x86_data.h"
+
+#ifndef C_
+#define C_(Ctx, String) String
+#endif
+#ifndef NC_
+#define NC_(Ctx, String) String
+#endif
+
+/* sources:
+ *   https://unix.stackexchange.com/a/43540
+ *   https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/tree/arch/x86/include/asm/cpufeatures.h?id=refs/tags/v4.9
+ *   hardinfo: modules/devices/x86/processor.c
+ */
+static struct {
+    char *name, *meaning;
+} tab_flag_meaning[] = {
+/* Intel-defined CPU features, CPUID level 0x00000001 (edx)
+ * See also Wikipedia and table 2-27 in Intel Advanced Vector Extensions Programming Reference */
+    { "fpu",     NC_("x86-flag", /*/flag:fpu*/  "Onboard FPU (floating point support)") },
+    { "vme",     NC_("x86-flag", /*/flag:vme*/  "Virtual 8086 mode enhancements") },
+    { "de",      NC_("x86-flag", /*/flag:de*/  "Debugging Extensions (CR4.DE)") },
+    { "pse",     NC_("x86-flag", /*/flag:pse*/  "Page Size Extensions (4MB memory pages)") },
+    { "tsc",     NC_("x86-flag", /*/flag:tsc*/  "Time Stamp Counter (RDTSC)") },
+    { "msr",     NC_("x86-flag", /*/flag:msr*/  "Model-Specific Registers (RDMSR, WRMSR)") },
+    { "pae",     NC_("x86-flag", /*/flag:pae*/  "Physical Address Extensions (support for more than 4GB of RAM)") },
+    { "mce",     NC_("x86-flag", /*/flag:mce*/  "Machine Check Exception") },
+    { "cx8",     NC_("x86-flag", /*/flag:cx8*/  "CMPXCHG8 instruction (64-bit compare-and-swap)") },
+    { "apic",    NC_("x86-flag", /*/flag:apic*/  "Onboard APIC") },
+    { "sep",     NC_("x86-flag", /*/flag:sep*/  "SYSENTER/SYSEXIT") },
+    { "mtrr",    NC_("x86-flag", /*/flag:mtrr*/  "Memory Type Range Registers") },
+    { "pge",     NC_("x86-flag", /*/flag:pge*/  "Page Global Enable (global bit in PDEs and PTEs)") },
+    { "mca",     NC_("x86-flag", /*/flag:mca*/  "Machine Check Architecture") },
+    { "cmov",    NC_("x86-flag", /*/flag:cmov*/  "CMOV instructions (conditional move) (also FCMOV)") },
+    { "pat",     NC_("x86-flag", /*/flag:pat*/  "Page Attribute Table") },
+    { "pse36",   NC_("x86-flag", /*/flag:pse36*/  "36-bit PSEs (huge pages)") },
+    { "pn",      NC_("x86-flag", /*/flag:pn*/  "Processor serial number") },
+    { "clflush", NC_("x86-flag", /*/flag:clflush*/  "Cache Line Flush instruction") },
+    { "dts",     NC_("x86-flag", /*/flag:dts*/  "Debug Store (buffer for debugging and profiling instructions), or alternately: digital thermal sensor") },
+    { "acpi",    NC_("x86-flag", /*/flag:acpi*/  "ACPI via MSR (temperature monitoring and clock speed modulation)") },
+    { "mmx",     NC_("x86-flag", /*/flag:mmx*/  "Multimedia Extensions") },
+    { "fxsr",    NC_("x86-flag", /*/flag:fxsr*/  "FXSAVE/FXRSTOR, CR4.OSFXSR") },
+    { "sse",     NC_("x86-flag", /*/flag:sse*/  "Intel SSE vector instructions") },
+    { "sse2",    NC_("x86-flag", /*/flag:sse2*/  "SSE2") },
+    { "ss",      NC_("x86-flag", /*/flag:ss*/  "CPU self snoop") },
+    { "ht",      NC_("x86-flag", /*/flag:ht*/  "Hyper-Threading") },
+    { "tm",      NC_("x86-flag", /*/flag:tm*/  "Automatic clock control (Thermal Monitor)") },
+    { "ia64",    NC_("x86-flag", /*/flag:ia64*/  "Intel Itanium Architecture 64-bit (not to be confused with Intel's 64-bit x86 architecture with flag x86-64 or \"AMD64\" bit indicated by flag lm)") },
+    { "pbe",     NC_("x86-flag", /*/flag:pbe*/  "Pending Break Enable (PBE# pin) wakeup support") },
+/* AMD-defined CPU features, CPUID level 0x80000001
+ * See also Wikipedia and table 2-23 in Intel Advanced Vector Extensions Programming Reference */
+    { "syscall",  NC_("x86-flag", /*/flag:syscall*/  "SYSCALL (Fast System Call) and SYSRET (Return From Fast System Call)") },
+    { "mp",       NC_("x86-flag", /*/flag:mp*/  "Multiprocessing Capable.") },
+    { "nx",       NC_("x86-flag", /*/flag:nx*/  "Execute Disable") },
+    { "mmxext",   NC_("x86-flag", /*/flag:mmxext*/  "AMD MMX extensions") },
+    { "fxsr_opt", NC_("x86-flag", /*/flag:fxsr_opt*/  "FXSAVE/FXRSTOR optimizations") },
+    { "pdpe1gb",  NC_("x86-flag", /*/flag:pdpe1gb*/  "One GB pages (allows hugepagesz=1G)") },
+    { "rdtscp",   NC_("x86-flag", /*/flag:rdtscp*/  "Read Time-Stamp Counter and Processor ID") },
+    { "lm",       NC_("x86-flag", /*/flag:lm*/  "Long Mode (x86-64: amd64, also known as Intel 64, i.e. 64-bit capable)") },
+    { "3dnow",    NC_("x86-flag", /*/flag:3dnow*/  "3DNow! (AMD vector instructions, competing with Intel's SSE1)") },
+    { "3dnowext", NC_("x86-flag", /*/flag:3dnowext*/  "AMD 3DNow! extensions") },
+/* Transmeta-defined CPU features, CPUID level 0x80860001 */
+    { "recovery", NC_("x86-flag", /*/flag:recovery*/  "CPU in recovery mode") },
+    { "longrun",  NC_("x86-flag", /*/flag:longrun*/  "Longrun power control") },
+    { "lrti",     NC_("x86-flag", /*/flag:lrti*/  "LongRun table interface") },
+/* Other features, Linux-defined mapping */
+    { "cxmmx",        NC_("x86-flag", /*/flag:cxmmx*/  "Cyrix MMX extensions") },
+    { "k6_mtrr",      NC_("x86-flag", /*/flag:k6_mtrr*/  "AMD K6 nonstandard MTRRs") },
+    { "cyrix_arr",    NC_("x86-flag", /*/flag:cyrix_arr*/  "Cyrix ARRs (= MTRRs)") },
+    { "centaur_mcr",  NC_("x86-flag", /*/flag:centaur_mcr*/  "Centaur MCRs (= MTRRs)") },
+    { "constant_tsc", NC_("x86-flag", /*/flag:constant_tsc*/  "TSC ticks at a constant rate") },
+    { "up",           NC_("x86-flag", /*/flag:up*/  "SMP kernel running on UP") },
+    { "art",          NC_("x86-flag", /*/flag:art*/  "Always-Running Timer") },
+    { "arch_perfmon", NC_("x86-flag", /*/flag:arch_perfmon*/  "Intel Architectural PerfMon") },
+    { "pebs",         NC_("x86-flag", /*/flag:pebs*/  "Precise-Event Based Sampling") },
+    { "bts",          NC_("x86-flag", /*/flag:bts*/  "Branch Trace Store") },
+    { "rep_good",     NC_("x86-flag", /*/flag:rep_good*/  "rep microcode works well") },
+    { "acc_power",    NC_("x86-flag", /*/flag:acc_power*/  "AMD accumulated power mechanism") },
+    { "nopl",         NC_("x86-flag", /*/flag:nopl*/  "The NOPL (0F 1F) instructions") },
+    { "xtopology",    NC_("x86-flag", /*/flag:xtopology*/  "cpu topology enum extensions") },
+    { "tsc_reliable", NC_("x86-flag", /*/flag:tsc_reliable*/  "TSC is known to be reliable") },
+    { "nonstop_tsc",  NC_("x86-flag", /*/flag:nonstop_tsc*/  "TSC does not stop in C states") },
+    { "extd_apicid",  NC_("x86-flag", /*/flag:extd_apicid*/  "has extended APICID (8 bits)") },
+    { "amd_dcm",      NC_("x86-flag", /*/flag:amd_dcm*/  "multi-node processor") },
+    { "aperfmperf",   NC_("x86-flag", /*/flag:aperfmperf*/  "APERFMPERF") },
+    { "eagerfpu",     NC_("x86-flag", /*/flag:eagerfpu*/  "Non lazy FPU restore") },
+    { "nonstop_tsc_s3", NC_("x86-flag", /*/flag:nonstop_tsc_s3*/  "TSC doesn't stop in S3 state") },
+    { "mce_recovery",   NC_("x86-flag", /*/flag:mce_recovery*/  "CPU has recoverable machine checks") },
+/* Intel-defined CPU features, CPUID level 0x00000001 (ecx)
+ * See also Wikipedia and table 2-26 in Intel Advanced Vector Extensions Programming Reference */
+    { "pni",       NC_("x86-flag", /*/flag:pni*/  "SSE-3 (\"Prescott New Instructions\")") },
+    { "pclmulqdq", NC_("x86-flag", /*/flag:pclmulqdq*/  "Perform a Carry-Less Multiplication of Quadword instruction - accelerator for GCM)") },
+    { "dtes64",    NC_("x86-flag", /*/flag:dtes64*/  "64-bit Debug Store") },
+    { "monitor",   NC_("x86-flag", /*/flag:monitor*/  "Monitor/Mwait support (Intel SSE3 supplements)") },
+    { "ds_cpl",    NC_("x86-flag", /*/flag:ds_cpl*/  "CPL Qual. Debug Store") },
+    { "vmx",       NC_("x86-flag", /*/flag:vmx*/  "Hardware virtualization, Intel VMX") },
+    { "smx",       NC_("x86-flag", /*/flag:smx*/  "Safer mode TXT (TPM support)") },
+    { "est",       NC_("x86-flag", /*/flag:est*/  "Enhanced SpeedStep") },
+    { "tm2",       NC_("x86-flag", /*/flag:tm2*/  "Thermal Monitor 2") },
+    { "ssse3",     NC_("x86-flag", /*/flag:ssse3*/  "Supplemental SSE-3") },
+    { "cid",       NC_("x86-flag", /*/flag:cid*/  "Context ID") },
+    { "sdbg",      NC_("x86-flag", /*/flag:sdbg*/  "silicon debug") },
+    { "fma",       NC_("x86-flag", /*/flag:fma*/  "Fused multiply-add") },
+    { "cx16",      NC_("x86-flag", /*/flag:cx16*/  "CMPXCHG16B") },
+    { "xtpr",      NC_("x86-flag", /*/flag:xtpr*/  "Send Task Priority Messages") },
+    { "pdcm",      NC_("x86-flag", /*/flag:pdcm*/  "Performance Capabilities") },
+    { "pcid",      NC_("x86-flag", /*/flag:pcid*/  "Process Context Identifiers") },
+    { "dca",       NC_("x86-flag", /*/flag:dca*/  "Direct Cache Access") },
+    { "sse4_1",    NC_("x86-flag", /*/flag:sse4_1*/  "SSE-4.1") },
+    { "sse4_2",    NC_("x86-flag", /*/flag:sse4_2*/  "SSE-4.2") },
+    { "x2apic",    NC_("x86-flag", /*/flag:x2apic*/  "x2APIC") },
+    { "movbe",     NC_("x86-flag", /*/flag:movbe*/  "Move Data After Swapping Bytes instruction") },
+    { "popcnt",    NC_("x86-flag", /*/flag:popcnt*/  "Return the Count of Number of Bits Set to 1 instruction (Hamming weight, i.e. bit count)") },
+    { "tsc_deadline_timer", NC_("x86-flag", /*/flag:tsc_deadline_timer*/  "Tsc deadline timer") },
+    { "aes/aes-ni",  NC_("x86-flag", /*/flag:aes/aes-ni*/  "Advanced Encryption Standard (New Instructions)") },
+    { "xsave",       NC_("x86-flag", /*/flag:xsave*/  "Save Processor Extended States: also provides XGETBY,XRSTOR,XSETBY") },
+    { "avx",         NC_("x86-flag", /*/flag:avx*/  "Advanced Vector Extensions") },
+    { "f16c",        NC_("x86-flag", /*/flag:f16c*/  "16-bit fp conversions (CVT16)") },
+    { "rdrand",      NC_("x86-flag", /*/flag:rdrand*/  "Read Random Number from hardware random number generator instruction") },
+    { "hypervisor",  NC_("x86-flag", /*/flag:hypervisor*/  "Running on a hypervisor") },
+/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001 */
+    { "rng",     NC_("x86-flag", /*/flag:rng*/  "Random Number Generator present (xstore)") },
+    { "rng_en",  NC_("x86-flag", /*/flag:rng_en*/  "Random Number Generator enabled") },
+    { "ace",     NC_("x86-flag", /*/flag:ace*/  "on-CPU crypto (xcrypt)") },
+    { "ace_en",  NC_("x86-flag", /*/flag:ace_en*/  "on-CPU crypto enabled") },
+    { "ace2",    NC_("x86-flag", /*/flag:ace2*/  "Advanced Cryptography Engine v2") },
+    { "ace2_en", NC_("x86-flag", /*/flag:ace2_en*/  "ACE v2 enabled") },
+    { "phe",     NC_("x86-flag", /*/flag:phe*/  "PadLock Hash Engine") },
+    { "phe_en",  NC_("x86-flag", /*/flag:phe_en*/  "PHE enabled") },
+    { "pmm",     NC_("x86-flag", /*/flag:pmm*/  "PadLock Montgomery Multiplier") },
+    { "pmm_en",  NC_("x86-flag", /*/flag:pmm_en*/  "PMM enabled") },
+/* More extended AMD flags: CPUID level 0x80000001, ecx */
+    { "lahf_lm",       NC_("x86-flag", /*/flag:lahf_lm*/  "Load AH from Flags (LAHF) and Store AH into Flags (SAHF) in long mode") },
+    { "cmp_legacy",    NC_("x86-flag", /*/flag:cmp_legacy*/  "If yes HyperThreading not valid") },
+    { "svm",           NC_("x86-flag", /*/flag:svm*/  "\"Secure virtual machine\": AMD-V") },
+    { "extapic",       NC_("x86-flag", /*/flag:extapic*/  "Extended APIC space") },
+    { "cr8_legacy",    NC_("x86-flag", /*/flag:cr8_legacy*/  "CR8 in 32-bit mode") },
+    { "abm",           NC_("x86-flag", /*/flag:abm*/  "Advanced Bit Manipulation") },
+    { "sse4a",         NC_("x86-flag", /*/flag:sse4a*/  "SSE-4A") },
+    { "misalignsse",   NC_("x86-flag", /*/flag:misalignsse*/  "indicates if a general-protection exception (#GP) is generated when some legacy SSE instructions operate on unaligned data. Also depends on CR0 and Alignment Checking bit") },
+    { "3dnowprefetch", NC_("x86-flag", /*/flag:3dnowprefetch*/  "3DNow prefetch instructions") },
+    { "osvw",          NC_("x86-flag", /*/flag:osvw*/  "indicates OS Visible Workaround, which allows the OS to work around processor errata.") },
+    { "ibs",           NC_("x86-flag", /*/flag:ibs*/  "Instruction Based Sampling") },
+    { "xop",           NC_("x86-flag", /*/flag:xop*/  "extended AVX instructions") },
+    { "skinit",        NC_("x86-flag", /*/flag:skinit*/  "SKINIT/STGI instructions") },
+    { "wdt",           NC_("x86-flag", /*/flag:wdt*/  "Watchdog timer") },
+    { "lwp",           NC_("x86-flag", /*/flag:lwp*/  "Light Weight Profiling") },
+    { "fma4",          NC_("x86-flag", /*/flag:fma4*/  "4 operands MAC instructions") },
+    { "tce",           NC_("x86-flag", /*/flag:tce*/  "translation cache extension") },
+    { "nodeid_msr",    NC_("x86-flag", /*/flag:nodeid_msr*/  "NodeId MSR") },
+    { "tbm",           NC_("x86-flag", /*/flag:tbm*/  "Trailing Bit Manipulation") },
+    { "topoext",       NC_("x86-flag", /*/flag:topoext*/  "Topology Extensions CPUID leafs") },
+    { "perfctr_core",  NC_("x86-flag", /*/flag:perfctr_core*/  "Core Performance Counter Extensions") },
+    { "perfctr_nb",    NC_("x86-flag", /*/flag:perfctr_nb*/  "NB Performance Counter Extensions") },
+    { "bpext",         NC_("x86-flag", /*/flag:bpext*/  "data breakpoint extension") },
+    { "ptsc",          NC_("x86-flag", /*/flag:ptsc*/  "performance time-stamp counter") },
+    { "perfctr_l2",    NC_("x86-flag", /*/flag:perfctr_l2*/  "L2 Performance Counter Extensions") },
+    { "mwaitx",        NC_("x86-flag", /*/flag:mwaitx*/  "MWAIT extension (MONITORX/MWAITX)") },
+/* Auxiliary flags: Linux defined - For features scattered in various CPUID levels */
+    { "cpb",           NC_("x86-flag", /*/flag:cpb*/  "AMD Core Performance Boost") },
+    { "epb",           NC_("x86-flag", /*/flag:epb*/  "IA32_ENERGY_PERF_BIAS support") },
+    { "hw_pstate",     NC_("x86-flag", /*/flag:hw_pstate*/  "AMD HW-PState") },
+    { "proc_feedback", NC_("x86-flag", /*/flag:proc_feedback*/  "AMD ProcFeedbackInterface") },
+    { "intel_pt",      NC_("x86-flag", /*/flag:intel_pt*/  "Intel Processor Tracing") },
+/* Virtualization flags: Linux defined */
+    { "tpr_shadow",   NC_("x86-flag", /*/flag:tpr_shadow*/  "Intel TPR Shadow") },
+    { "vnmi",         NC_("x86-flag", /*/flag:vnmi*/  "Intel Virtual NMI") },
+    { "flexpriority", NC_("x86-flag", /*/flag:flexpriority*/  "Intel FlexPriority") },
+    { "ept",          NC_("x86-flag", /*/flag:ept*/  "Intel Extended Page Table") },
+    { "vpid",         NC_("x86-flag", /*/flag:vpid*/  "Intel Virtual Processor ID") },
+    { "vmmcall",      NC_("x86-flag", /*/flag:vmmcall*/  "prefer VMMCALL to VMCALL") },
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx) */
+    { "fsgsbase",   NC_("x86-flag", /*/flag:fsgsbase*/  "{RD/WR}{FS/GS}BASE instructions") },
+    { "tsc_adjust", NC_("x86-flag", /*/flag:tsc_adjust*/  "TSC adjustment MSR") },
+    { "bmi1",       NC_("x86-flag", /*/flag:bmi1*/  "1st group bit manipulation extensions") },
+    { "hle",        NC_("x86-flag", /*/flag:hle*/  "Hardware Lock Elision") },
+    { "avx2",       NC_("x86-flag", /*/flag:avx2*/  "AVX2 instructions") },
+    { "smep",       NC_("x86-flag", /*/flag:smep*/  "Supervisor Mode Execution Protection") },
+    { "bmi2",       NC_("x86-flag", /*/flag:bmi2*/  "2nd group bit manipulation extensions") },
+    { "erms",       NC_("x86-flag", /*/flag:erms*/  "Enhanced REP MOVSB/STOSB") },
+    { "invpcid",    NC_("x86-flag", /*/flag:invpcid*/  "Invalidate Processor Context ID") },
+    { "rtm",        NC_("x86-flag", /*/flag:rtm*/  "Restricted Transactional Memory") },
+    { "cqm",        NC_("x86-flag", /*/flag:cqm*/  "Cache QoS Monitoring") },
+    { "mpx",        NC_("x86-flag", /*/flag:mpx*/  "Memory Protection Extension") },
+    { "avx512f",    NC_("x86-flag", /*/flag:avx512f*/  "AVX-512 foundation") },
+    { "avx512dq",   NC_("x86-flag", /*/flag:avx512dq*/  "AVX-512 Double/Quad instructions") },
+    { "rdseed",     NC_("x86-flag", /*/flag:rdseed*/  "The RDSEED instruction") },
+    { "adx",        NC_("x86-flag", /*/flag:adx*/  "The ADCX and ADOX instructions") },
+    { "smap",       NC_("x86-flag", /*/flag:smap*/  "Supervisor Mode Access Prevention") },
+    { "clflushopt", NC_("x86-flag", /*/flag:clflushopt*/  "CLFLUSHOPT instruction") },
+    { "clwb",       NC_("x86-flag", /*/flag:clwb*/  "CLWB instruction") },
+    { "avx512pf",   NC_("x86-flag", /*/flag:avx512pf*/  "AVX-512 Prefetch") },
+    { "avx512er",   NC_("x86-flag", /*/flag:avx512er*/  "AVX-512 Exponential and Reciprocal") },
+    { "avx512cd",   NC_("x86-flag", /*/flag:avx512cd*/  "AVX-512 Conflict Detection") },
+    { "sha_ni",     NC_("x86-flag", /*/flag:sha_ni*/  "SHA1/SHA256 Instruction Extensions") },
+    { "avx512bw",   NC_("x86-flag", /*/flag:avx512bw*/  "AVX-512 Byte/Word instructions") },
+    { "avx512vl",   NC_("x86-flag", /*/flag:avx512vl*/  "AVX-512 128/256 Vector Length extensions") },
+/* Extended state features, CPUID level 0x0000000d:1 (eax) */
+    { "xsaveopt",   NC_("x86-flag", /*/flag:xsaveopt*/  "Optimized XSAVE") },
+    { "xsavec",     NC_("x86-flag", /*/flag:xsavec*/  "XSAVEC") },
+    { "xgetbv1",    NC_("x86-flag", /*/flag:xgetbv1*/  "XGETBV with ECX = 1") },
+    { "xsaves",     NC_("x86-flag", /*/flag:xsaves*/  "XSAVES/XRSTORS") },
+/* Intel-defined CPU QoS sub-leaf, CPUID level 0x0000000F:0 (edx) */
+    { "cqm_llc",    NC_("x86-flag", /*/flag:cqm_llc*/  "LLC QoS") },
+/* Intel-defined CPU QoS sub-leaf, CPUID level 0x0000000F:1 (edx) */
+    { "cqm_occup_llc",  NC_("x86-flag", /*/flag:cqm_occup_llc*/  "LLC occupancy monitoring") },
+    { "cqm_mbm_total",  NC_("x86-flag", /*/flag:cqm_mbm_total*/  "LLC total MBM monitoring") },
+    { "cqm_mbm_local",  NC_("x86-flag", /*/flag:cqm_mbm_local*/  "LLC local MBM monitoring") },
+/* AMD-defined CPU features, CPUID level 0x80000008 (ebx) */
+    { "clzero",         NC_("x86-flag", /*/flag:clzero*/  "CLZERO instruction") },
+    { "irperf",         NC_("x86-flag", /*/flag:irperf*/  "instructions retired performance counter") },
+/* Thermal and Power Management leaf, CPUID level 0x00000006 (eax) */
+    { "dtherm",         NC_("x86-flag", /*/flag:dtherm*/  "digital thermal sensor") }, /* formerly dts */
+    { "ida",            NC_("x86-flag", /*/flag:ida*/  "Intel Dynamic Acceleration") },
+    { "arat",           NC_("x86-flag", /*/flag:arat*/  "Always Running APIC Timer") },
+    { "pln",            NC_("x86-flag", /*/flag:pln*/  "Intel Power Limit Notification") },
+    { "pts",            NC_("x86-flag", /*/flag:pts*/  "Intel Package Thermal Status") },
+    { "hwp",            NC_("x86-flag", /*/flag:hwp*/  "Intel Hardware P-states") },
+    { "hwp_notify",     NC_("x86-flag", /*/flag:hwp_notify*/  "HWP notification") },
+    { "hwp_act_window", NC_("x86-flag", /*/flag:hwp_act_window*/  "HWP Activity Window") },
+    { "hwp_epp",        NC_("x86-flag", /*/flag:hwp_epp*/  "HWP Energy Performance Preference") },
+    { "hwp_pkg_req",    NC_("x86-flag", /*/flag:hwp_pkg_req*/  "HWP package-level request") },
+/* AMD SVM Feature Identification, CPUID level 0x8000000a (edx) */
+    { "npt",            NC_("x86-flag", /*/flag:npt*/  "AMD Nested Page Table support") },
+    { "lbrv",           NC_("x86-flag", /*/flag:lbrv*/  "AMD LBR Virtualization support") },
+    { "svm_lock",       NC_("x86-flag", /*/flag:svm_lock*/  "AMD SVM locking MSR") },
+    { "nrip_save",      NC_("x86-flag", /*/flag:nrip_save*/  "AMD SVM next_rip save") },
+    { "tsc_scale",      NC_("x86-flag", /*/flag:tsc_scale*/  "AMD TSC scaling support") },
+    { "vmcb_clean",     NC_("x86-flag", /*/flag:vmcb_clean*/  "AMD VMCB clean bits support") },
+    { "flushbyasid",    NC_("x86-flag", /*/flag:flushbyasid*/  "AMD flush-by-ASID support") },
+    { "decodeassists",  NC_("x86-flag", /*/flag:decodeassists*/  "AMD Decode Assists support") },
+    { "pausefilter",    NC_("x86-flag", /*/flag:pausefilter*/  "AMD filtered pause intercept") },
+    { "pfthreshold",    NC_("x86-flag", /*/flag:pfthreshold*/  "AMD pause filter threshold") },
+    { "avic",           NC_("x86-flag", /*/flag:avic*/  "Virtual Interrupt Controller") },
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx) */
+    { "pku",            NC_("x86-flag", /*/flag:pku*/  "Protection Keys for Userspace") },
+    { "ospke",          NC_("x86-flag", /*/flag:ospke*/  "OS Protection Keys Enable") },
+/* AMD-defined CPU features, CPUID level 0x80000007 (ebx) */
+    { "overflow_recov", NC_("x86-flag", /*/flag:overflow_recov*/  "MCA overflow recovery support") },
+    { "succor",         NC_("x86-flag", /*/flag:succor*/  "uncorrectable error containment and recovery") },
+    { "smca",           NC_("x86-flag", /*/flag:smca*/  "Scalable MCA") },
+
+/* bug workarounds */
+    { "bug:f00f",       NC_("x86-flag", /*/bug:f00f*/  "Intel F00F bug")    },
+    { "bug:fdiv",       NC_("x86-flag", /*/bug:fdiv*/  "FPU FDIV")          },
+    { "bug:coma",       NC_("x86-flag", /*/bug:coma*/  "Cyrix 6x86 coma")   },
+    { "bug:tlb_mmatch", NC_("x86-flag", /*/bug:tlb_mmatch*/  "AMD Erratum 383")   },
+    { "bug:apic_c1e",   NC_("x86-flag", /*/bug:apic_c1e*/  "AMD Erratum 400")   },
+    { "bug:11ap",       NC_("x86-flag", /*/bug:11ap*/  "Bad local APIC aka 11AP")  },
+    { "bug:fxsave_leak",      NC_("x86-flag", /*/bug:fxsave_leak*/  "FXSAVE leaks FOP/FIP/FOP") },
+    { "bug:clflush_monitor",  NC_("x86-flag", /*/bug:clflush_monitor*/  "AAI65, CLFLUSH required before MONITOR") },
+    { "bug:sysret_ss_attrs",  NC_("x86-flag", /*/bug:sysret_ss_attrs*/  "SYSRET doesn't fix up SS attrs") },
+    { "bug:espfix",       NC_("x86-flag", /*/bug:espfix*/  "IRET to 16-bit SS corrupts ESP/RSP high bits") },
+    { "bug:null_seg",     NC_("x86-flag", /*/bug:null_seg*/  "Nulling a selector preserves the base") },         /* see: detect_null_seg_behavior() */
+    { "bug:swapgs_fence", NC_("x86-flag", /*/bug:swapgs_fence*/  "SWAPGS without input dep on GS") },
+    { "bug:monitor",      NC_("x86-flag", /*/bug:monitor*/  "IPI required to wake up remote CPU") },
+    { "bug:amd_e400",     NC_("x86-flag", /*/bug:amd_e400*/  "AMD Erratum 400") },
+    { "bug:cpu_insecure",     NC_("x86-flag", /*/bug:cpu_insecure & bug:cpu_meltdown*/  "CPU is affected by meltdown attack and needs kernel page table isolation") },
+    { "bug:cpu_meltdown",     NC_("x86-flag", /*/bug:cpu_insecure & bug:cpu_meltdown*/  "CPU is affected by meltdown attack and needs kernel page table isolation") },
+    { "bug:spectre_v1",     NC_("x86-flag", /*/bug:spectre_v1*/  "CPU is affected by Spectre variant 1 attack with conditional branches") },
+    { "bug:spectre_v2",     NC_("x86-flag", /*/bug:spectre_v2*/  "CPU is affected by Spectre variant 2 attack with indirect branches") },
+/* power management
+ * ... from arch/x86/kernel/cpu/powerflags.h */
+    { "pm:ts",            NC_("x86-flag", /*/flag:pm:ts*/  "temperature sensor")     },
+    { "pm:fid",           NC_("x86-flag", /*/flag:pm:fid*/  "frequency id control")   },
+    { "pm:vid",           NC_("x86-flag", /*/flag:pm:vid*/  "voltage id control")     },
+    { "pm:ttp",           NC_("x86-flag", /*/flag:pm:ttp*/  "thermal trip")           },
+    { "pm:tm",            NC_("x86-flag", /*/flag:pm:tm*/  "hardware thermal control")   },
+    { "pm:stc",           NC_("x86-flag", /*/flag:pm:stc*/  "software thermal control")   },
+    { "pm:100mhzsteps",   NC_("x86-flag", /*/flag:pm:100mhzsteps*/  "100 MHz multiplier control") },
+    { "pm:hwpstate",      NC_("x86-flag", /*/flag:pm:hwpstate*/  "hardware P-state control")   },
+    { "pm:cpb",           NC_("x86-flag", /*/flag:pm:cpb*/  "core performance boost")     },
+    { "pm:eff_freq_ro",   NC_("x86-flag", /*/flag:pm:eff_freq_ro*/  "Readonly aperf/mperf")       },
+    { "pm:proc_feedback", NC_("x86-flag", /*/flag:pm:proc_feedback*/  "processor feedback interface") },
+    { "pm:acc_power",     NC_("x86-flag", /*/flag:pm:acc_power*/  "accumulated power mechanism")  },
+    { NULL, NULL},
+};
+
+static char all_flags[4096] = "";
+
+#define APPEND_FLAG(f) strcat(all_flags, f); strcat(all_flags, " ");
+const char *x86_flag_list() {
+    int i = 0, built = 0;
+    built = strlen(all_flags);
+    if (!built) {
+        while(tab_flag_meaning[i].name != NULL) {
+            APPEND_FLAG(tab_flag_meaning[i].name);
+            i++;
+        }
+    }
+    return all_flags;
+}
+
+const char *x86_flag_meaning(const char *flag) {
+    int i = 0;
+    if (flag)
+    while(tab_flag_meaning[i].name != NULL) {
+        if (strcmp(tab_flag_meaning[i].name, flag) == 0) {
+            if (tab_flag_meaning[i].meaning != NULL)
+                return C_("x86-flag", tab_flag_meaning[i].meaning);
+            else return NULL;
+        }
+        i++;
+    }
+    return NULL;
+}
+
+static void x86_flag_find_dups(void) {
+    int t, i;
+
+    t = 0;
+    while(tab_flag_meaning[t].name != NULL) {
+        i = t+1;
+        while(tab_flag_meaning[i].name != NULL) {
+            if (strcmp(tab_flag_meaning[t].name, tab_flag_meaning[i].name) == 0) {
+                printf("x86-flag duplicate definition: %s\n ... %d: %s\n ... %d: %s\n",
+                    tab_flag_meaning[i].name,
+                    t, tab_flag_meaning[t].meaning,
+                    i, tab_flag_meaning[i].meaning);
+            }
+            i++;
+        }
+        t++;
+    }
+}
diff --git a/modules/devices/x86/x86_data.h b/modules/devices/x86/x86_data.h
new file mode 100644
index 0000000..66a4c80
--- /dev/null
+++ b/modules/devices/x86/x86_data.h
@@ -0,0 +1,28 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * Copyright (C) 2017  Burt P. <pburt0@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef _X86DATA_H_
+#define _X86DATA_H_
+
+/* cpu flags from /proc/cpuinfo */
+const char *x86_flag_list(void);                 /* list of all known flags */
+const char *x86_flag_meaning(const char *flag);  /* lookup flag meaning */
+
+#endif
diff --git a/modules/network.c b/modules/network.c
new file mode 100644
index 0000000..f27a159
--- /dev/null
+++ b/modules/network.c
@@ -0,0 +1,441 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2008 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <config.h>
+#include <time.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include <sys/stat.h>
+
+#include <sys/socket.h>
+#include <netdb.h>
+
+#include <hardinfo.h>
+#include <iconcache.h>
+#include <shell.h>
+
+#include <vendor.h>
+
+#include "network.h"
+
+/* Callbacks */
+gchar *callback_network();
+gchar *callback_route();
+gchar *callback_dns();
+gchar *callback_connections();
+gchar *callback_shares();
+gchar *callback_arp();
+gchar *callback_statistics();
+
+/* Scan callbacks */
+void scan_network(gboolean reload);
+void scan_route(gboolean reload);
+void scan_dns(gboolean reload);
+void scan_connections(gboolean reload);
+void scan_shares(gboolean reload);
+void scan_arp(gboolean reload);
+void scan_statistics(gboolean reload);
+
+static ModuleEntry entries[] = {
+    {N_("Interfaces"), "network-interface.png", callback_network, scan_network, MODULE_FLAG_NONE},
+    {N_("IP Connections"), "network-connections.png", callback_connections, scan_connections, MODULE_FLAG_NONE},
+    {N_("Routing Table"), "network.png", callback_route, scan_route, MODULE_FLAG_NONE},
+    {N_("ARP Table"), "module.png", callback_arp, scan_arp, MODULE_FLAG_NONE},
+    {N_("DNS Servers"), "dns.png", callback_dns, scan_dns, MODULE_FLAG_NONE},
+    {N_("Statistics"), "network-statistics.png", callback_statistics, scan_statistics, MODULE_FLAG_NONE},
+    {N_("Shared Directories"), "shares.png", callback_shares, scan_shares, MODULE_FLAG_NONE},
+    {NULL},
+};
+
+void scan_shares(gboolean reload)
+{
+    SCAN_START();
+    scan_samba();
+    scan_nfs_shared_directories();
+    SCAN_END();
+}
+
+static gchar *__statistics = NULL;
+void scan_statistics(gboolean reload)
+{
+    FILE *netstat;
+    gchar buffer[256];
+    gchar *netstat_path;
+    int line = 0;
+
+    SCAN_START();
+
+    g_free(__statistics);
+    __statistics = g_strdup("");
+
+    if ((netstat_path = find_program("netstat"))) {
+      gchar *command_line = g_strdup_printf("%s -s", netstat_path);
+
+      if ((netstat = popen(command_line, "r"))) {
+        while (fgets(buffer, 256, netstat)) {
+          if (!isspace(buffer[0]) && strchr(buffer, ':')) {
+            gchar *tmp;
+
+            tmp = g_ascii_strup(strend(buffer, ':'), -1);
+
+            __statistics = h_strdup_cprintf("[%s]\n",
+                                            __statistics,
+                                            tmp);
+            g_free(tmp);
+
+          } else {
+            gchar *tmp = buffer;
+
+            while (*tmp && isspace(*tmp)) tmp++;
+
+            __statistics = h_strdup_cprintf("<b> </b>#%d=%s\n",
+                                            __statistics,
+                                            line++, tmp);
+          }
+        }
+
+        pclose(netstat);
+      }
+
+      g_free(command_line);
+      g_free(netstat_path);
+    }
+
+    SCAN_END();
+}
+
+static gchar *__nameservers = NULL;
+void scan_dns(gboolean reload)
+{
+    FILE *resolv;
+    gchar buffer[256];
+
+    SCAN_START();
+
+    g_free(__nameservers);
+    __nameservers = g_strdup("");
+
+    if ((resolv = fopen("/etc/resolv.conf", "r"))) {
+      while (fgets(buffer, 256, resolv)) {
+        if (g_str_has_prefix(buffer, "nameserver")) {
+          gchar *ip;
+          struct sockaddr_in sa;
+          char hbuf[NI_MAXHOST];
+
+          ip = g_strstrip(buffer + sizeof("nameserver"));
+
+          sa.sin_family = AF_INET;
+          sa.sin_addr.s_addr = inet_addr(ip);
+
+          if (getnameinfo((struct sockaddr *)&sa, sizeof(sa), hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD)) {
+              __nameservers = h_strdup_cprintf("%s=\n",
+                                               __nameservers,
+                                               ip);
+          } else {
+              __nameservers = h_strdup_cprintf("%s=%s\n",
+                                               __nameservers,
+                                               ip, hbuf);
+
+          }
+
+          shell_status_pulse();
+        }
+      }
+      fclose(resolv);
+    }
+
+    SCAN_END();
+}
+
+void scan_network(gboolean reload)
+{
+    SCAN_START();
+    scan_net_interfaces();
+    SCAN_END();
+}
+
+static gchar *__routing_table = NULL;
+void scan_route(gboolean reload)
+{
+    FILE *route;
+    gchar buffer[256];
+    gchar *route_path;
+
+    SCAN_START();
+
+    g_free(__routing_table);
+    __routing_table = g_strdup("");
+
+    if ((route_path = find_program("route"))) {
+      gchar *command_line = g_strdup_printf("%s -n", route_path);
+
+      if ((route = popen(command_line, "r"))) {
+        /* eat first two lines */
+        (void)fgets(buffer, 256, route);
+        (void)fgets(buffer, 256, route);
+
+        while (fgets(buffer, 256, route)) {
+          buffer[15] = '\0';
+          buffer[31] = '\0';
+          buffer[47] = '\0';
+          buffer[53] = '\0';
+
+          __routing_table = h_strdup_cprintf("%s / %s=%s|%s|%s\n",
+                                             __routing_table,
+                                             g_strstrip(buffer), g_strstrip(buffer + 16),
+                                             g_strstrip(buffer + 72),
+                                             g_strstrip(buffer + 48),
+                                             g_strstrip(buffer + 32));
+        }
+
+        pclose(route);
+      }
+
+      g_free(command_line);
+      g_free(route_path);
+    }
+
+    SCAN_END();
+}
+
+static gchar *__arp_table = NULL;
+void scan_arp(gboolean reload)
+{
+    FILE *arp;
+    gchar buffer[256];
+
+    SCAN_START();
+
+    g_free(__arp_table);
+    __arp_table = g_strdup("");
+
+    if ((arp = fopen("/proc/net/arp", "r"))) {
+      /* eat first line */
+      (void)fgets(buffer, 256, arp);
+
+      while (fgets(buffer, 256, arp)) {
+        buffer[15] = '\0';
+        buffer[58] = '\0';
+
+        __arp_table = h_strdup_cprintf("%s=%s|%s\n",
+                                       __arp_table,
+                                       g_strstrip(buffer),
+                                       g_strstrip(buffer + 72),
+                                       g_strstrip(buffer + 41));
+      }
+
+      fclose(arp);
+    }
+
+    SCAN_END();
+}
+
+static gchar *__connections = NULL;
+void scan_connections(gboolean reload)
+{
+    FILE *netstat;
+    gchar buffer[256];
+    gchar *netstat_path;
+
+    SCAN_START();
+
+    g_free(__connections);
+    __connections = g_strdup("");
+
+    if ((netstat_path = find_program("netstat"))) {
+      gchar *command_line = g_strdup_printf("%s -an", netstat_path);
+
+      if ((netstat = popen("netstat -an", "r"))) {
+        while (fgets(buffer, 256, netstat)) {
+          buffer[6] = '\0';
+          buffer[43] = '\0';
+          buffer[67] = '\0';
+
+          if (g_str_has_prefix(buffer, "tcp") || g_str_has_prefix(buffer, "udp")) {
+            __connections = h_strdup_cprintf("%s=%s|%s|%s\n",
+                                             __connections,
+                                             g_strstrip(buffer + 20),	/* local address */
+                                             g_strstrip(buffer),		/* protocol */
+                                             g_strstrip(buffer + 44),	/* foreign address */
+                                             g_strstrip(buffer + 68));	/* state */
+          }
+        }
+
+        pclose(netstat);
+      }
+
+      g_free(command_line);
+      g_free(netstat_path);
+    }
+
+    SCAN_END();
+}
+
+gchar *callback_arp()
+{
+    return g_strdup_printf("[%s]\n"
+                           "%s\n"
+                           "[$ShellParam$]\n"
+                           "ReloadInterval=3000\n"
+                           "ColumnTitle$TextValue=%s\n" /* IP Address */
+                           "ColumnTitle$Value=%s\n" /* Interface */
+                           "ColumnTitle$Extra1=%s\n" /* MAC Address */
+                           "ShowColumnHeaders=true\n",
+                           _("ARP Table"), __arp_table,
+                           _("IP Address"), _("Interface"), _("MAC Address") );
+}
+
+gchar *callback_shares()
+{
+    return g_strdup_printf("[%s]\n"
+                "%s\n"
+                "[%s]\n"
+                "%s",
+                _("SAMBA"), smb_shares_list,
+                _("NFS"), nfs_shares_list);
+}
+
+gchar *callback_dns()
+{
+    return g_strdup_printf("[%s]\n"
+                           "%s\n"
+                           "[$ShellParam$]\n"
+                           "ColumnTitle$TextValue=%s\n" /* IP Address */
+                           "ColumnTitle$Value=%s\n" /* Name */
+                           "ShowColumnHeaders=true\n",
+                           _("Name Servers"), __nameservers,
+                           _("IP Address"), _("Name") );
+}
+
+gchar *callback_connections()
+{
+    return g_strdup_printf("[%s]\n"
+                           "%s\n"
+                           "[$ShellParam$]\n"
+                           "ReloadInterval=3000\n"
+                           "ColumnTitle$TextValue=%s\n" /* Local Address */
+                           "ColumnTitle$Value=%s\n" /* Protocol */
+                           "ColumnTitle$Extra1=%s\n" /* Foreign Address */
+                           "ColumnTitle$Extra2=%s\n" /* State */
+                           "ShowColumnHeaders=true\n",
+                           _("Connections"), __connections,
+                           _("Local Address"), _("Protocol"), _("Foreign Address"), _("State") );
+}
+
+gchar *callback_network()
+{
+    return g_strdup_printf("%s\n"
+               "[$ShellParam$]\n"
+               "ReloadInterval=3000\n"
+               "ViewType=1\n"
+               "ColumnTitle$TextValue=%s\n" /* Interface */
+               "ColumnTitle$Value=%s\n" /* IP Address */
+               "ColumnTitle$Extra1=%s\n" /* Sent */
+               "ColumnTitle$Extra2=%s\n" /* Received */
+               "ShowColumnHeaders=true\n"
+               "%s",
+               network_interfaces,
+               _("Interface"), _("IP Address"), _("Sent"), _("Received"),
+               network_icons);
+}
+
+gchar *callback_route()
+{
+    return g_strdup_printf("[%s]\n"
+                           "%s\n"
+                           "[$ShellParam$]\n"
+                           "ViewType=0\n"
+                           "ReloadInterval=3000\n"
+                           "ColumnTitle$TextValue=%s\n" /* Destination / Gateway */
+                           "ColumnTitle$Value=%s\n" /* Interface */
+                           "ColumnTitle$Extra1=%s\n" /* Flags */
+                           "ColumnTitle$Extra2=%s\n" /* Mask */
+                           "ShowColumnHeaders=true\n",
+                           _("IP routing table"), __routing_table,
+                           _("Destination/Gateway"), _("Interface"), _("Flags"), _("Mask") );
+}
+
+gchar *callback_statistics()
+{
+    return g_strdup_printf("%s\n"
+                           "[$ShellParam$]\n"
+                           "ReloadInterval=3000\n",
+                            __statistics);
+}
+
+gchar *hi_more_info(gchar * entry)
+{
+    gchar *info = moreinfo_lookup_with_prefix("NET", entry);
+
+    if (info)
+	return g_strdup(info);
+
+    return g_strdup_printf("[%s]", entry);
+}
+
+ModuleEntry *hi_module_get_entries(void)
+{
+    return entries;
+}
+
+gchar *hi_module_get_name(void)
+{
+    return g_strdup(_("Network"));
+}
+
+guchar hi_module_get_weight(void)
+{
+    return 160;
+}
+
+void hi_module_init(void)
+{
+}
+
+void hi_module_deinit(void)
+{
+    moreinfo_del_with_prefix("NET");
+
+    g_free(smb_shares_list);
+    g_free(nfs_shares_list);
+    g_free(network_interfaces);
+    g_free(network_icons);
+
+    g_free(__statistics);
+    g_free(__nameservers);
+    g_free(__arp_table);
+    g_free(__routing_table);
+    g_free(__connections);
+}
+
+ModuleAbout *hi_module_get_about(void)
+{
+    static ModuleAbout ma[] = {
+	{
+	 .author = "Leandro A. F. Pereira",
+	 .description = N_("Gathers information about this computer's network connection"),
+	 .version = VERSION,
+	 .license = "GNU GPL version 2"}
+    };
+
+    return ma;
+}
diff --git a/modules/network/net.c b/modules/network/net.c
new file mode 100644
index 0000000..a75cf8b
--- /dev/null
+++ b/modules/network/net.c
@@ -0,0 +1,494 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2008 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+/*
+ * Wireless Extension Example
+ * http://www.krugle.org/examples/p-OZYzuisV6gyQIaTu/iwconfig.c
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <linux/sockios.h>
+
+#include <arpa/inet.h>
+
+#ifdef HAS_LINUX_WE
+#include <linux/if.h>
+#include <linux/wireless.h>
+#else
+#include <net/if.h>
+#endif  /* HAS_LINUX_WE */
+
+#include "hardinfo.h"
+#include "network.h"
+
+gchar *network_interfaces = NULL, *network_icons = NULL;
+
+typedef struct _NetInfo NetInfo;
+struct _NetInfo {
+    char name[16];
+    int mtu;
+    unsigned char mac[8];
+    char ip[16];
+    char mask[16];
+    char broadcast[16];
+
+#ifdef HAS_LINUX_WE
+    char wi_essid[IW_ESSID_MAX_SIZE + 1];
+    int  wi_rate;
+    int  wi_mode, wi_status;
+    gboolean wi_has_txpower;
+    struct iw_param wi_txpower;
+    int  wi_quality_level, wi_signal_level, wi_noise_level;
+    gboolean is_wireless;
+#endif
+};
+
+#ifdef HAS_LINUX_WE
+const gchar *wi_operation_modes[] = {
+    NC_("wi-op-mode", "Auto"),
+    NC_("wi-op-mode", "Ad-Hoc"),
+    NC_("wi-op-mode", "Managed"),
+    NC_("wi-op-mode", "Master"),
+    NC_("wi-op-mode", "Repeater"),
+    NC_("wi-op-mode", "Secondary"),
+    NC_("wi-op-mode", "(Unknown)")
+};
+
+void get_wireless_info(int fd, NetInfo *netinfo)
+{
+  FILE *wrls;
+  char wbuf[256];
+  struct iwreq wi_req;
+  int r, trash;
+
+  netinfo->is_wireless = FALSE;
+
+  if ((wrls = fopen("/proc/net/wireless", "r"))) {
+      while (fgets(wbuf, 256, wrls)) {
+          if (strchr(wbuf, ':') && strstr(wbuf, netinfo->name)) {
+              gchar *buf1 = wbuf;
+
+              netinfo->is_wireless = TRUE;
+
+              buf1 = strchr(buf1, ':') + 1;
+
+              if (strchr(buf1, '.')) {
+                  sscanf(buf1, "%d %d. %d. %d %d %d %d %d %d %d",
+                         &(netinfo->wi_status),
+                         &(netinfo->wi_quality_level),
+                         &(netinfo->wi_signal_level),
+                         &(netinfo->wi_noise_level),
+                         &trash, &trash, &trash, &trash, &trash, &trash);
+              } else {
+                  sscanf(buf1, "%d %d %d %d %d %d %d %d %d %d",
+                         &(netinfo->wi_status),
+                         &(netinfo->wi_quality_level),
+                         &(netinfo->wi_signal_level),
+                         &(netinfo->wi_noise_level),
+                         &trash, &trash, &trash, &trash, &trash,
+                         &trash);
+              }
+
+              break;
+          }
+      }
+      fclose(wrls);
+  }
+
+  if (!netinfo->is_wireless)
+    return;
+
+  strncpy(wi_req.ifr_name, netinfo->name, 16);
+
+  /* obtain essid */
+  wi_req.u.essid.pointer = netinfo->wi_essid;
+  wi_req.u.essid.length  = IW_ESSID_MAX_SIZE + 1;
+  wi_req.u.essid.flags   = 0;
+
+  if (ioctl(fd, SIOCGIWESSID, &wi_req) < 0) {
+    strcpy(netinfo->wi_essid, "");
+  } else {
+    netinfo->wi_essid[wi_req.u.essid.length] = '\0';
+  }
+
+  /* obtain bit rate */
+  if (ioctl(fd, SIOCGIWRATE, &wi_req) < 0) {
+    netinfo->wi_rate = 0;
+  } else {
+    netinfo->wi_rate = wi_req.u.bitrate.value;
+  }
+
+  /* obtain operation mode */
+  if (ioctl(fd, SIOCGIWMODE, &wi_req) < 0) {
+    netinfo->wi_mode = 0;
+  } else {
+    if (wi_req.u.mode >= 0 && wi_req.u.mode < 6) {
+      netinfo->wi_mode = wi_req.u.mode;
+    } else {
+      netinfo->wi_mode = 6;
+    }
+  }
+
+#if WIRELESS_EXT >= 10
+  /* obtain txpower */
+  if (ioctl(fd, SIOCGIWTXPOW, &wi_req) < 0) {
+    netinfo->wi_has_txpower = FALSE;
+  } else {
+    netinfo->wi_has_txpower = TRUE;
+
+    memcpy(&netinfo->wi_txpower, &wi_req.u.txpower, sizeof(struct iw_param));
+  }
+#else
+  netinfo->wi_has_txpower = FALSE;
+#endif  /* WIRELESS_EXT >= 10 */
+}
+#endif /* HAS_LINUX_WE */
+
+void get_net_info(char *if_name, NetInfo * netinfo)
+{
+    struct ifreq ifr;
+    int fd;
+
+    fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+
+    /* IPv4 */
+    ifr.ifr_addr.sa_family = AF_INET;
+    strncpy(netinfo->name, if_name, sizeof(netinfo->name));
+
+    /* MTU */
+    strcpy(ifr.ifr_name, if_name);
+    if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) {
+    netinfo->mtu = 0;
+    } else {
+    netinfo->mtu = ifr.ifr_mtu;
+    }
+
+    /* HW Address */
+    strcpy(ifr.ifr_name, if_name);
+    if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
+    memset(netinfo->mac, 0, 8);
+    } else {
+    memcpy(netinfo->mac, ifr.ifr_ifru.ifru_hwaddr.sa_data, 8);
+    }
+
+    /* IP Address */
+    strcpy(ifr.ifr_name, if_name);
+    if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
+    netinfo->ip[0] = 0;
+    } else {
+    snprintf(netinfo->ip, sizeof(netinfo->ip), "%s",
+        inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->
+              sin_addr));
+    }
+
+    /* Mask Address */
+    strcpy(ifr.ifr_name, if_name);
+    if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0) {
+    netinfo->mask[0] = 0;
+    } else {
+    snprintf(netinfo->mask, sizeof(netinfo->mask), "%s",
+        inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->
+              sin_addr));
+    }
+
+    /* Broadcast Address */
+    strcpy(ifr.ifr_name, if_name);
+    if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0) {
+    netinfo->broadcast[0] = 0;
+    } else {
+    snprintf(netinfo->broadcast, sizeof(netinfo->broadcast), "%s",
+        inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->
+              sin_addr));
+    }
+
+#ifdef HAS_LINUX_WE
+    get_wireless_info(fd, netinfo);
+#endif
+
+    shutdown(fd, 0);
+    close(fd);
+}
+
+static struct {
+    char *type;
+    char *label;
+    char *icon;
+} netdev2type[] = {
+    /* Classic */
+    { "eth", NC_("net-if-type", "Ethernet"), "network-interface" },
+    { "lo", NC_("net-if-type", "Loopback"), "network" },
+    { "ppp", NC_("net-if-type", "Point-to-Point"), "modem" },
+    { "ath", NC_("net-if-type", "Wireless"), "wireless" },
+    { "wlan", NC_("net-if-type", "Wireless"), "wireless" },
+    { "ra", NC_("net-if-type", "Wireless"), "wireless" },
+    { "wmaster", NC_("net-if-type", "Wireless"), "wireless" },
+    { "tun", NC_("net-if-type", "Virtual Point-to-Point (TUN)"), "network" },
+    { "tap", NC_("net-if-type", "Ethernet (TAP)"), "network" },
+    { "plip", NC_("net-if-type", "Parallel Line Internet Protocol"), "network" },
+    { "irlan", NC_("net-if-type", "Infrared"), "network" },
+    { "slip", NC_("net-if-type", "Serial Line Internet Protocol"), "network" },
+    { "isdn", NC_("net-if-type", "Integrated Services Digital Network"), "modem" },
+    { "sit", NC_("net-if-type", "IPv6-over-IPv4 Tunnel"), "network" },
+    { "vmnet8", NC_("net-if-type", "VMWare Virtual Network Interface (NAT)"), "computer" },
+    { "vmnet", NC_("net-if-type", "VMWare Virtual Network Interface"), "computer" },
+    { "pan", NC_("net-if-type", "Personal Area Network (PAN)"), "bluetooth" },
+    { "bnep", NC_("net-if-type", "Bluetooth"), "bluetooth" },
+    { "br", NC_("net-if-type", "Bridge Interface"), "network" },
+    { "ham", NC_("net-if-type", "Hamachi Virtual Personal Network"), "network"},
+    { "net", NC_("net-if-type", "Ethernet"), "network-interface" },
+    { "ifb", NC_("net-if-type", "Intermediate Functional Block"), "network" },
+    { "gre", NC_("net-if-type", "GRE Network Tunnel"), "network" },
+    { "msh", NC_("net-if-type", "Mesh Network"), "wireless" },
+    { "wmaster", NC_("net-if-type", "Wireless Master Interface"), "wireless" },
+    { "vboxnet", NC_("net-if-type", "VirtualBox Virtual Network Interface"), "network" },
+
+    /* Predictable network interface device names (systemd) */
+    { "en", NC_("net-if-type", "Ethernet"), "network-interface" },
+    { "sl", NC_("net-if-type", "Serial Line Internet Protocol"), "network" },
+    { "wl", NC_("net-if-type", "Wireless"), "wireless" },
+    { "ww", NC_("net-if-type", "Wireless (WAN)"), "wireless" },
+
+    { NULL, NC_("net-if-type", "(Unknown)"), "network" },
+};
+
+static void net_get_iface_type(gchar * name, gchar ** type, gchar ** icon, NetInfo *ni)
+{
+    int i;
+
+#ifdef HAS_LINUX_WE
+    if (ni->is_wireless) {
+        *type = "Wireless"; /* translated when used */
+        *icon = "wireless";
+
+        return;
+    }
+#endif
+
+    for (i = 0; netdev2type[i].type; i++) {
+    if (g_str_has_prefix(name, netdev2type[i].type))
+        break;
+    }
+
+    *type = netdev2type[i].label; /* translated when used */
+    *icon = netdev2type[i].icon;
+}
+
+static gboolean
+remove_net_devices(gpointer key, gpointer value, gpointer data)
+{
+    return g_str_has_prefix(key, "NET");
+}
+
+#ifdef HAS_LINUX_WE
+const char *wifi_bars(int signal, int noise)
+{
+    signal = -signal;
+
+    if (signal > 80)
+        return "▰▰▰▰▰";
+    if (signal > 55)
+        return "▰▰▰▰▱";
+    if (signal > 30)
+        return "▰▰▰▱▱";
+    if (signal > 15)
+        return "▰▰▱▱▱";
+    if (signal > 5)
+        return "▰▱▱▱▱";
+    return "▱▱▱▱▱";
+}
+#endif
+
+static void scan_net_interfaces_24(void)
+{
+    FILE *proc_net;
+    NetInfo ni;
+    gchar buffer[256];
+    gchar *devid, *detailed;
+    gdouble recv_bytes;
+    gdouble recv_errors;
+    gdouble recv_packets;
+
+    gdouble trans_bytes;
+    gdouble trans_errors;
+    gdouble trans_packets;
+
+    if (!g_file_test("/proc/net/dev", G_FILE_TEST_EXISTS)) {
+    if (network_interfaces) {
+        g_free(network_interfaces);
+        network_interfaces = g_strdup_printf("[%s]]\n%s=\n",
+            _("Network Interfaces"), _("None Found") );
+    }
+
+    return;
+    }
+
+    g_free(network_interfaces);
+
+    g_free(network_icons);
+
+    network_interfaces = g_strdup_printf("[%s]\n", _("Network Interfaces"));
+    network_icons = g_strdup("");
+
+    proc_net = fopen("/proc/net/dev", "r");
+    if (!proc_net)
+        return;
+
+    while (fgets(buffer, 256, proc_net)) {
+    if (strchr(buffer, ':')) {
+        gint trash;
+        gchar ifacename[16];
+        gchar *buf = buffer;
+        gchar *iface_type, *iface_icon;
+        gint i;
+
+        buf = g_strstrip(buf);
+
+        memset(ifacename, 0, 16);
+
+        for (i = 0; buffer[i] != ':' && i < 16; i++) {
+        ifacename[i] = buffer[i];
+        }
+
+        buf = strchr(buf, ':') + 1;
+
+        /* iface: bytes packets errs drop fifo frame compressed multicast */
+        sscanf(buf, "%lf %lf %lf %d %d %d %d %d %lf %lf %lf",
+           &recv_bytes, &recv_packets,
+           &recv_errors, &trash, &trash, &trash, &trash,
+           &trash, &trans_bytes, &trans_packets, &trans_errors);
+
+        gdouble recv_mb = recv_bytes / 1048576.0;
+        gdouble trans_mb = trans_bytes / 1048576.0;
+
+        get_net_info(ifacename, &ni);
+
+        devid = g_strdup_printf("NET%s", ifacename);
+
+        network_interfaces =
+        h_strdup_cprintf
+        ("$%s$%s=%s|%.2lf%s|%.2lf%s\n",
+         network_interfaces, devid, ifacename, ni.ip[0] ? ni.ip : "",
+         trans_mb, _("MiB"), recv_mb, _("MiB"));
+        net_get_iface_type(ifacename, &iface_type, &iface_icon, &ni);
+
+        network_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n",
+                         network_icons, devid,
+                         ifacename, iface_icon);
+
+        detailed = g_strdup_printf("[%s]\n"
+                       "%s=%s\n" /* Interface Type */
+                       "%s=%02x:%02x:%02x:%02x:%02x:%02x\n" /* MAC */
+                       "%s=%d\n" /* MTU */
+                       "[%s]\n" /*Transfer Details*/
+                       "%s=%.0lf (%.2f%s)\n" /* Bytes Received */
+                       "%s=%.0lf (%.2f%s)\n" /* Bytes Sent */,
+                       _("Network Adapter Properties"),
+                       _("Interface Type"), C_("net-if-type", iface_type),
+                       _("Hardware Address (MAC)"),
+                       ni.mac[0], ni.mac[1],
+                       ni.mac[2], ni.mac[3],
+                       ni.mac[4], ni.mac[5],
+                       _("MTU"), ni.mtu,
+                       _("Transfer Details"),
+                       _("Bytes Received"), recv_bytes, recv_mb, _("MiB"),
+                       _("Bytes Sent"), trans_bytes, trans_mb, _("MiB"));
+
+#ifdef HAS_LINUX_WE
+        if (ni.is_wireless) {
+            gchar *txpower;
+
+            if (ni.wi_has_txpower) {
+                gint mw, dbm;
+
+                if (ni.wi_txpower.flags & IW_TXPOW_MWATT) {
+                    mw = ni.wi_txpower.value;
+                    dbm = (int) ceil(10.0 * log10((double) ni.wi_txpower.value));
+                } else {
+                    dbm = ni.wi_txpower.value;
+                    mw = (int) floor(pow(10.0, ((double) dbm / 10.0)));
+                }
+
+                txpower = g_strdup_printf("%d%s (%d%s)", dbm, _("dBm"), mw, _("mW"));
+            } else {
+                txpower = g_strdup(_("(Unknown)"));
+            }
+
+            detailed = h_strdup_cprintf("\n[%s]\n"
+                "%s=%s\n" /* Network Name (SSID) */
+                "%s=%d%s\n" /* Bit Rate */
+                "%s=%s\n" /* Transmission Power */
+                "%s=%s\n" /* Mode */
+                "%s=%d\n" /* Status */
+                "%s=%d\n" /* Link Quality */
+                "%s=%d %s / %d %s (%s)\n",
+                detailed,
+                _("Wireless Properties"),
+                _("Network Name (SSID)"), ni.wi_essid,
+                _("Bit Rate"), ni.wi_rate / 1000000, _("Mb/s"),
+                _("Transmission Power"), txpower,
+                _("Mode"), C_("wi-op-mode", wi_operation_modes[ni.wi_mode]),
+                _("Status"), ni.wi_status,
+                _("Link Quality"), ni.wi_quality_level,
+                _("Signal / Noise"),
+                    ni.wi_signal_level, _("dBm"),
+                    ni.wi_noise_level, _("dBm"),
+                wifi_bars(ni.wi_signal_level, ni.wi_noise_level));
+
+            g_free(txpower);
+        }
+#endif
+
+        if (ni.ip[0] || ni.mask[0] || ni.broadcast[0]) {
+        detailed =
+            h_strdup_cprintf("\n[%s]\n"
+                     "%s=%s\n"
+                     "%s=%s\n"
+                     "%s=%s\n", detailed,
+                     _("Internet Protocol (IPv4)"),
+                     _("IP Address"), ni.ip[0] ? ni.ip : _("(Not set)"),
+                     _("Mask"), ni.mask[0] ? ni.mask : _("(Not set)"),
+                     _("Broadcast Address"),
+                        ni.broadcast[0] ? ni.broadcast : _("(Not set)") );
+        }
+
+        moreinfo_add_with_prefix("NET", devid, detailed);
+        g_free(devid);
+    }
+    }
+    fclose(proc_net);
+}
+
+void scan_net_interfaces(void)
+{
+    /* FIXME: See if we're running Linux 2.6 and if /sys is mounted, then use
+       that instead of /proc/net/dev */
+
+    /* remove old devices from global device table */
+    moreinfo_del_with_prefix("NET");
+
+    scan_net_interfaces_24();
+}
diff --git a/modules/network/nfs.c b/modules/network/nfs.c
new file mode 100644
index 0000000..54bbfe0
--- /dev/null
+++ b/modules/network/nfs.c
@@ -0,0 +1,59 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "hardinfo.h"
+#include "network.h"
+
+gchar *nfs_shares_list = NULL;
+
+void
+scan_nfs_shared_directories(void)
+{
+    FILE *exports;
+    gint count = 0;
+    gchar buf[512];
+    
+    g_free(nfs_shares_list);
+
+    nfs_shares_list = g_strdup("");
+    
+    if ((exports = fopen("/etc/exports", "r"))) {
+        while (fgets(buf, 512, exports)) {
+            if (buf[0] != '/')
+                continue;
+            
+            strend(buf, ' ');
+            strend(buf, '\t');
+
+            nfs_shares_list = h_strdup_cprintf("%s=\n", 
+                                               nfs_shares_list, buf);
+            count++;
+        }
+
+        fclose(exports);
+    }
+
+    if (!count) {
+        g_free(nfs_shares_list);
+        
+        nfs_shares_list = g_strdup("No NFS exports=\n");
+    }
+}
+
diff --git a/modules/network/samba.c b/modules/network/samba.c
new file mode 100644
index 0000000..7e8dc46
--- /dev/null
+++ b/modules/network/samba.c
@@ -0,0 +1,126 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "hardinfo.h"
+#include "network.h"
+
+gchar *smb_shares_list = NULL;
+
+void scan_samba_from_string(gchar *str, gsize length);
+void scan_samba_usershares(void);
+
+void
+scan_samba(void)
+{
+    gchar *str;
+    gsize length;
+
+    if (smb_shares_list) {
+        g_free(smb_shares_list);
+        smb_shares_list = g_strdup("");
+    }
+
+    if (g_file_get_contents("/etc/samba/smb.conf",
+                            &str, &length, NULL)) {
+        shell_status_update("Scanning SAMBA shares...");
+        scan_samba_from_string(str, length);
+        g_free(str);
+    }
+
+    scan_samba_usershares();
+}
+
+void
+scan_samba_usershares(void)
+{
+    FILE *usershare_list;
+    gboolean spawned;
+    int status;
+    gchar *out, *err, *p, *next_nl;
+    gchar *usershare, *cmdline;
+    gsize length;
+
+    spawned = g_spawn_command_line_sync("net usershare list",
+            &out, &err, &status, NULL);
+
+    if (spawned && status == 0 && out != NULL) {
+        shell_status_update("Scanning SAMBA user shares...");
+        p = out;
+        while(next_nl = strchr(p, '\n')) {
+            cmdline = g_strdup_printf("net usershare info '%s'",
+                                      strend(p, '\n'));
+            if (g_spawn_command_line_sync(cmdline,
+                        &usershare, NULL, NULL, NULL)) {
+                length = strlen(usershare);
+                scan_samba_from_string(usershare, length);
+                g_free(usershare);
+            }
+            g_free(cmdline);
+
+            shell_status_pulse();
+            p = next_nl + 1;
+        }
+        g_free(out);
+        g_free(err);
+    }
+}
+
+void
+scan_samba_from_string(gchar *str, gsize length)
+{
+    GKeyFile *keyfile;
+    GError *error = NULL;
+    gchar **groups;
+    gint i = 0;
+
+    keyfile = g_key_file_new();
+
+    gchar *_smbconf = str;
+    for (; *_smbconf; _smbconf++)
+        if (*_smbconf == ';') *_smbconf = '\0';
+
+    if (!g_key_file_load_from_data(keyfile, str, length, 0, &error)) {
+        smb_shares_list = g_strdup("Cannot parse smb.conf=\n");
+        if (error)
+            g_error_free(error);
+        goto cleanup;
+    }
+
+    groups = g_key_file_get_groups(keyfile, NULL);
+    while (groups[i]) {
+        shell_status_pulse();
+
+        if (g_key_file_has_key(keyfile, groups[i], "path", NULL)) {
+            gchar *path = g_key_file_get_string(keyfile, groups[i], "path", NULL);
+            smb_shares_list = h_strdup_cprintf("%s=%s\n",
+                                               smb_shares_list,
+                                               groups[i], path);
+            g_free(path);
+        }
+
+        i++;
+    }
+
+    g_strfreev(groups);
+
+  cleanup:
+    g_key_file_free(keyfile);
+}
+
diff --git a/pixmaps/about-modules.png b/pixmaps/about-modules.png
new file mode 100644
index 0000000..9808644
Binary files /dev/null and b/pixmaps/about-modules.png differ
diff --git a/pixmaps/audio.png b/pixmaps/audio.png
new file mode 100644
index 0000000..cc0d9ec
Binary files /dev/null and b/pixmaps/audio.png differ
diff --git a/pixmaps/battery.png b/pixmaps/battery.png
new file mode 100644
index 0000000..172c238
Binary files /dev/null and b/pixmaps/battery.png differ
diff --git a/pixmaps/benchmark.png b/pixmaps/benchmark.png
new file mode 100644
index 0000000..b807f11
Binary files /dev/null and b/pixmaps/benchmark.png differ
diff --git a/pixmaps/blowfish.png b/pixmaps/blowfish.png
new file mode 100644
index 0000000..54a9ba8
Binary files /dev/null and b/pixmaps/blowfish.png differ
diff --git a/pixmaps/bluetooth.png b/pixmaps/bluetooth.png
new file mode 100644
index 0000000..4621658
Binary files /dev/null and b/pixmaps/bluetooth.png differ
diff --git a/pixmaps/boot.png b/pixmaps/boot.png
new file mode 100644
index 0000000..1151e48
Binary files /dev/null and b/pixmaps/boot.png differ
diff --git a/pixmaps/cdrom.png b/pixmaps/cdrom.png
new file mode 100644
index 0000000..52a2397
Binary files /dev/null and b/pixmaps/cdrom.png differ
diff --git a/pixmaps/close.png b/pixmaps/close.png
new file mode 100644
index 0000000..7d702c5
Binary files /dev/null and b/pixmaps/close.png differ
diff --git a/pixmaps/compress.png b/pixmaps/compress.png
new file mode 100644
index 0000000..1c4530b
Binary files /dev/null and b/pixmaps/compress.png differ
diff --git a/pixmaps/computer.png b/pixmaps/computer.png
new file mode 100644
index 0000000..b00cb15
Binary files /dev/null and b/pixmaps/computer.png differ
diff --git a/pixmaps/cryptohash.png b/pixmaps/cryptohash.png
new file mode 100644
index 0000000..b62f29e
Binary files /dev/null and b/pixmaps/cryptohash.png differ
diff --git a/pixmaps/dev_removable.png b/pixmaps/dev_removable.png
new file mode 100644
index 0000000..d6c91e4
Binary files /dev/null and b/pixmaps/dev_removable.png differ
diff --git a/pixmaps/devel.png b/pixmaps/devel.png
new file mode 100644
index 0000000..8aeebd6
Binary files /dev/null and b/pixmaps/devel.png differ
diff --git a/pixmaps/devices.png b/pixmaps/devices.png
new file mode 100644
index 0000000..c21504c
Binary files /dev/null and b/pixmaps/devices.png differ
diff --git a/pixmaps/dialog-error.png b/pixmaps/dialog-error.png
new file mode 100644
index 0000000..7d6aaf6
Binary files /dev/null and b/pixmaps/dialog-error.png differ
diff --git a/pixmaps/dialog-information.png b/pixmaps/dialog-information.png
new file mode 100644
index 0000000..83b6993
Binary files /dev/null and b/pixmaps/dialog-information.png differ
diff --git a/pixmaps/dialog-warning.png b/pixmaps/dialog-warning.png
new file mode 100644
index 0000000..d5c4be4
Binary files /dev/null and b/pixmaps/dialog-warning.png differ
diff --git a/pixmaps/dns.png b/pixmaps/dns.png
new file mode 100644
index 0000000..44dbb3f
Binary files /dev/null and b/pixmaps/dns.png differ
diff --git a/pixmaps/environment.png b/pixmaps/environment.png
new file mode 100644
index 0000000..2f58075
Binary files /dev/null and b/pixmaps/environment.png differ
diff --git a/pixmaps/face-grin.png b/pixmaps/face-grin.png
new file mode 100644
index 0000000..cc45e7c
Binary files /dev/null and b/pixmaps/face-grin.png differ
diff --git a/pixmaps/fft.png b/pixmaps/fft.png
new file mode 100644
index 0000000..ed16da1
Binary files /dev/null and b/pixmaps/fft.png differ
diff --git a/pixmaps/file-roller.png b/pixmaps/file-roller.png
new file mode 100644
index 0000000..5c17e91
Binary files /dev/null and b/pixmaps/file-roller.png differ
diff --git a/pixmaps/hdd.png b/pixmaps/hdd.png
new file mode 100644
index 0000000..d035034
Binary files /dev/null and b/pixmaps/hdd.png differ
diff --git a/pixmaps/home.png b/pixmaps/home.png
new file mode 100644
index 0000000..74a83d0
Binary files /dev/null and b/pixmaps/home.png differ
diff --git a/pixmaps/inputdevices.png b/pixmaps/inputdevices.png
new file mode 100644
index 0000000..aea0f1d
Binary files /dev/null and b/pixmaps/inputdevices.png differ
diff --git a/pixmaps/internet.png b/pixmaps/internet.png
new file mode 100644
index 0000000..ca76ef6
Binary files /dev/null and b/pixmaps/internet.png differ
diff --git a/pixmaps/joystick.png b/pixmaps/joystick.png
new file mode 100644
index 0000000..368b179
Binary files /dev/null and b/pixmaps/joystick.png differ
diff --git a/pixmaps/keyboard.png b/pixmaps/keyboard.png
new file mode 100644
index 0000000..9d0eecf
Binary files /dev/null and b/pixmaps/keyboard.png differ
diff --git a/pixmaps/language.png b/pixmaps/language.png
new file mode 100644
index 0000000..495a94b
Binary files /dev/null and b/pixmaps/language.png differ
diff --git a/pixmaps/logo.png b/pixmaps/logo.png
new file mode 100644
index 0000000..9d0484a
Binary files /dev/null and b/pixmaps/logo.png differ
diff --git a/pixmaps/logo.xcf b/pixmaps/logo.xcf
new file mode 100644
index 0000000..e429525
Binary files /dev/null and b/pixmaps/logo.xcf differ
diff --git a/pixmaps/memory.png b/pixmaps/memory.png
new file mode 100644
index 0000000..25ffba9
Binary files /dev/null and b/pixmaps/memory.png differ
diff --git a/pixmaps/modem.png b/pixmaps/modem.png
new file mode 100644
index 0000000..450e403
Binary files /dev/null and b/pixmaps/modem.png differ
diff --git a/pixmaps/module.png b/pixmaps/module.png
new file mode 100644
index 0000000..7c389a2
Binary files /dev/null and b/pixmaps/module.png differ
diff --git a/pixmaps/monitor.png b/pixmaps/monitor.png
new file mode 100644
index 0000000..fbe38d6
Binary files /dev/null and b/pixmaps/monitor.png differ
diff --git a/pixmaps/mouse.png b/pixmaps/mouse.png
new file mode 100644
index 0000000..8baa74d
Binary files /dev/null and b/pixmaps/mouse.png differ
diff --git a/pixmaps/nautilus.png b/pixmaps/nautilus.png
new file mode 100644
index 0000000..2eac917
Binary files /dev/null and b/pixmaps/nautilus.png differ
diff --git a/pixmaps/network-connections.png b/pixmaps/network-connections.png
new file mode 100644
index 0000000..0e9124a
Binary files /dev/null and b/pixmaps/network-connections.png differ
diff --git a/pixmaps/network-interface.png b/pixmaps/network-interface.png
new file mode 100644
index 0000000..0a765eb
Binary files /dev/null and b/pixmaps/network-interface.png differ
diff --git a/pixmaps/network-statistics.png b/pixmaps/network-statistics.png
new file mode 100644
index 0000000..e9c6a8b
Binary files /dev/null and b/pixmaps/network-statistics.png differ
diff --git a/pixmaps/network.png b/pixmaps/network.png
new file mode 100644
index 0000000..5f95ba3
Binary files /dev/null and b/pixmaps/network.png differ
diff --git a/pixmaps/nqueens.png b/pixmaps/nqueens.png
new file mode 100644
index 0000000..e33e857
Binary files /dev/null and b/pixmaps/nqueens.png differ
diff --git a/pixmaps/os.png b/pixmaps/os.png
new file mode 100644
index 0000000..2c07199
Binary files /dev/null and b/pixmaps/os.png differ
diff --git a/pixmaps/pcmcia.png b/pixmaps/pcmcia.png
new file mode 100644
index 0000000..2baac66
Binary files /dev/null and b/pixmaps/pcmcia.png differ
diff --git a/pixmaps/printer.png b/pixmaps/printer.png
new file mode 100644
index 0000000..20861df
Binary files /dev/null and b/pixmaps/printer.png differ
diff --git a/pixmaps/processor.png b/pixmaps/processor.png
new file mode 100644
index 0000000..b5dfa01
Binary files /dev/null and b/pixmaps/processor.png differ
diff --git a/pixmaps/raytrace.png b/pixmaps/raytrace.png
new file mode 100644
index 0000000..9340a29
Binary files /dev/null and b/pixmaps/raytrace.png differ
diff --git a/pixmaps/report-large.png b/pixmaps/report-large.png
new file mode 100644
index 0000000..d2dcafb
Binary files /dev/null and b/pixmaps/report-large.png differ
diff --git a/pixmaps/report.png b/pixmaps/report.png
new file mode 100644
index 0000000..40d5fc8
Binary files /dev/null and b/pixmaps/report.png differ
diff --git a/pixmaps/resources.png b/pixmaps/resources.png
new file mode 100644
index 0000000..c23587b
Binary files /dev/null and b/pixmaps/resources.png differ
diff --git a/pixmaps/server-large.png b/pixmaps/server-large.png
new file mode 100644
index 0000000..9879971
Binary files /dev/null and b/pixmaps/server-large.png differ
diff --git a/pixmaps/server.png b/pixmaps/server.png
new file mode 100644
index 0000000..3f7b69b
Binary files /dev/null and b/pixmaps/server.png differ
diff --git a/pixmaps/shares.png b/pixmaps/shares.png
new file mode 100644
index 0000000..a05befe
Binary files /dev/null and b/pixmaps/shares.png differ
diff --git a/pixmaps/summary.png b/pixmaps/summary.png
new file mode 100644
index 0000000..8451f99
Binary files /dev/null and b/pixmaps/summary.png differ
diff --git a/pixmaps/syncmanager-small.png b/pixmaps/syncmanager-small.png
new file mode 100644
index 0000000..2a52261
Binary files /dev/null and b/pixmaps/syncmanager-small.png differ
diff --git a/pixmaps/syncmanager.png b/pixmaps/syncmanager.png
new file mode 100644
index 0000000..46da641
Binary files /dev/null and b/pixmaps/syncmanager.png differ
diff --git a/pixmaps/therm.png b/pixmaps/therm.png
new file mode 100644
index 0000000..8db7a2c
Binary files /dev/null and b/pixmaps/therm.png differ
diff --git a/pixmaps/usb.png b/pixmaps/usb.png
new file mode 100644
index 0000000..d35176a
Binary files /dev/null and b/pixmaps/usb.png differ
diff --git a/pixmaps/usbfldisk.png b/pixmaps/usbfldisk.png
new file mode 100644
index 0000000..c6a2d0c
Binary files /dev/null and b/pixmaps/usbfldisk.png differ
diff --git a/pixmaps/users.png b/pixmaps/users.png
new file mode 100644
index 0000000..bf3cabb
Binary files /dev/null and b/pixmaps/users.png differ
diff --git a/pixmaps/wireless.png b/pixmaps/wireless.png
new file mode 100644
index 0000000..c5a5bf9
Binary files /dev/null and b/pixmaps/wireless.png differ
diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt
new file mode 100644
index 0000000..95dbdfe
--- /dev/null
+++ b/po/CMakeLists.txt
@@ -0,0 +1,3 @@
+include(Translations)
+add_translations_directory("hardinfo")
+add_translations_catalog("hardinfo" ../shell/ ../modules/ ../hardinfo/ ../remote/ ../help-viewer/ )
\ No newline at end of file
diff --git a/po/HOWTO.txt b/po/HOWTO.txt
new file mode 100644
index 0000000..afe9a8c
--- /dev/null
+++ b/po/HOWTO.txt
@@ -0,0 +1,9 @@
+Translators
+===========
+
+IF POSSIBLE, run `bash updatepo.sh` in the po/ directory before begining.
+This will regenerate hardinfo.pot and update all the .po files.
+NOTHING IS LOST if this isn't done, but it prevents wasting time translating
+strings that have changed, or are no longer used.
+
+DO NOT use `make pot`!
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 0000000..623b5e0
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,4402 @@
+# German translations for PACKAGE package
+# German translation for PACKAGE.
+# Copyright (C) 2016 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Alexander Münch <git@thehacker.biz>, 2016.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2017-08-14 22:23-0500\n"
+"PO-Revision-Date: 2016-06-10 12:11+0200\n"
+"Last-Translator: Alexander Münch <git@thehacker.biz>\n"
+"Language-Team: German\n"
+"Language: de\n"
+"X-Poedit-Basepath: ../\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.8.7.1\n"
+
+#. / %d will be latest year of copyright
+#: hardinfo/hardinfo.c:49
+#, c-format
+msgid ""
+"Copyright (C) 2003-%d Leandro A. F. Pereira. See COPYING for details.\n"
+"\n"
+msgstr ""
+
+#: hardinfo/hardinfo.c:51
+#, c-format
+msgid ""
+"Compile-time options:\n"
+"  Release version:   %s (%s)\n"
+"  BinReloc enabled:  %s\n"
+"  Data prefix:       %s\n"
+"  Library prefix:    %s\n"
+"  Compiled for:      %s\n"
+msgstr ""
+
+#: hardinfo/hardinfo.c:57 hardinfo/hardinfo.c:58 modules/computer.c:605
+#: modules/devices/inputdevices.c:128 modules/devices/pci.c:112
+#: modules/devices/printers.c:138
+msgid "Yes"
+msgstr "Ja"
+
+#: hardinfo/hardinfo.c:58 modules/computer.c:605 modules/devices/pci.c:112
+#: modules/devices/printers.c:138
+msgid "No"
+msgstr "Nein"
+
+#: hardinfo/hardinfo.c:69
+#, c-format
+msgid ""
+"Failed to find runtime data.\n"
+"\n"
+"• Is HardInfo correctly installed?\n"
+"• See if %s and %s exists and you have read permission."
+msgstr ""
+
+#: hardinfo/hardinfo.c:76
+#, c-format
+msgid ""
+"Modules:\n"
+"%-20s %-15s %-12s\n"
+msgstr ""
+
+#: hardinfo/hardinfo.c:77
+msgid "File Name"
+msgstr ""
+
+#: hardinfo/hardinfo.c:77 modules/computer.c:534 modules/computer.c:562
+#: modules/computer.c:630 modules/computer/languages.c:104
+#: modules/computer/modules.c:146 modules/devices/arm/processor.c:336
+#: modules/devices/ia64/processor.c:160 modules/devices/inputdevices.c:116
+#: modules/devices/pci.c:215 modules/devices/sh/processor.c:84
+#: modules/devices/x86/processor.c:455 modules/network.c:326
+msgid "Name"
+msgstr "Name"
+
+#: hardinfo/hardinfo.c:77 modules/computer.c:296 modules/computer.c:505
+#: modules/computer.c:507 modules/computer.c:595 modules/computer.c:603
+#: modules/devices/inputdevices.c:121
+msgid "Version"
+msgstr ""
+
+#: hardinfo/hardinfo.c:124
+#, c-format
+msgid "Unknown benchmark ``%s'' or libbenchmark.so not loaded"
+msgstr ""
+
+#: hardinfo/hardinfo.c:152
+msgid "Don't know what to do. Exiting."
+msgstr ""
+
+#: hardinfo/util.c:104 modules/computer/uptime.c:53
+#, c-format
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] "%d Tag"
+msgstr[1] "%d Tage"
+
+#: hardinfo/util.c:105 modules/computer/uptime.c:54
+#, c-format
+msgid "%d hour"
+msgid_plural "%d hours"
+msgstr[0] "%d Stunde"
+msgstr[1] "%d Stunden"
+
+#: hardinfo/util.c:106 modules/computer/uptime.c:55
+#, c-format
+msgid "%d minute"
+msgid_plural "%d minutes"
+msgstr[0] "%d Minute"
+msgstr[1] "%d Minuten"
+
+#: hardinfo/util.c:107
+#, c-format
+msgid "%d second"
+msgid_plural "%d seconds"
+msgstr[0] "%d Sekunde"
+msgstr[1] "%d Sekunden"
+
+#: hardinfo/util.c:128
+#, c-format
+msgid "%.1f B"
+msgstr "%.1f Byte(s)"
+
+#: hardinfo/util.c:130
+#, c-format
+msgid "%.1f KiB"
+msgstr "%.1f KiB"
+
+#: hardinfo/util.c:132
+#, c-format
+msgid "%.1f MiB"
+msgstr "%.1f MiB"
+
+#: hardinfo/util.c:134
+#, c-format
+msgid "%.1f GiB"
+msgstr "%.1f GiB"
+
+#: hardinfo/util.c:136
+#, c-format
+msgid "%.1f TiB"
+msgstr "%.1f TiB"
+
+#: hardinfo/util.c:138
+#, c-format
+msgid "%.1f PiB"
+msgstr "%.1f PiB"
+
+#: hardinfo/util.c:361
+msgid "Error"
+msgstr "Fehler"
+
+#: hardinfo/util.c:361 hardinfo/util.c:377
+msgid "Warning"
+msgstr "Warnung"
+
+#: hardinfo/util.c:376
+msgid "Fatal Error"
+msgstr "Kritischer Fehler"
+
+#: hardinfo/util.c:401
+msgid "creates a report and prints to standard output"
+msgstr ""
+
+#: hardinfo/util.c:407
+msgid "chooses a report format (text, html)"
+msgstr ""
+
+#: hardinfo/util.c:413
+msgid "run benchmark; requires benchmark.so to be loaded"
+msgstr ""
+
+#: hardinfo/util.c:419
+msgid "lists modules"
+msgstr ""
+
+#: hardinfo/util.c:425
+msgid "specify module to load"
+msgstr ""
+
+#: hardinfo/util.c:431
+msgid "automatically load module dependencies"
+msgstr ""
+
+#: hardinfo/util.c:438
+msgid "run in XML-RPC server mode"
+msgstr ""
+
+#: hardinfo/util.c:445
+msgid "shows program version and quit"
+msgstr ""
+
+#: hardinfo/util.c:450
+msgid "- System Profiler and Benchmark tool"
+msgstr "- System-Profiler und Benchmark-Werkzeug"
+
+#: hardinfo/util.c:460
+#, c-format
+msgid ""
+"Unrecognized arguments.\n"
+"Try ``%s --help'' for more information.\n"
+msgstr ""
+
+#: hardinfo/util.c:526
+#, c-format
+msgid "Couldn't find a Web browser to open URL %s."
+msgstr "Konnte keinen Web-Browser finden, um die URL %s zu öffnen."
+
+#: hardinfo/util.c:875
+#, c-format
+msgid "Module \"%s\" depends on module \"%s\", load it?"
+msgstr ""
+
+#: hardinfo/util.c:898
+#, c-format
+msgid "Module \"%s\" depends on module \"%s\"."
+msgstr ""
+
+#: hardinfo/util.c:943
+#, c-format
+msgid "No module could be loaded. Check permissions on \"%s\" and try again."
+msgstr ""
+
+#: hardinfo/util.c:947
+msgid ""
+"No module could be loaded. Please use hardinfo -l to list all available "
+"modules and try again with a valid module list."
+msgstr ""
+
+#: hardinfo/util.c:1024
+#, c-format
+msgid "Scanning: %s..."
+msgstr ""
+
+#: hardinfo/util.c:1034 shell/shell.c:301 shell/shell.c:760 shell/shell.c:1795
+#: modules/benchmark.c:449 modules/benchmark.c:457
+msgid "Done."
+msgstr "Fertig."
+
+#: shell/callbacks.c:117
+#, c-format
+msgid "%s Module"
+msgstr ""
+
+#: shell/callbacks.c:128
+#, c-format
+msgid ""
+"Written by %s\n"
+"Licensed under %s"
+msgstr ""
+"Programmiert von %s\n"
+"Lizenziert unter %s"
+
+#: shell/callbacks.c:142
+#, c-format
+msgid "No about information is associated with the %s module."
+msgstr ""
+
+#: shell/callbacks.c:158
+msgid "Author:"
+msgstr ""
+
+#: shell/callbacks.c:161
+msgid "Contributors:"
+msgstr "Mitwirkende:"
+
+#: shell/callbacks.c:166
+msgid "Based on work by:"
+msgstr ""
+
+#: shell/callbacks.c:167
+msgid "MD5 implementation by Colin Plumb (see md5.c for details)"
+msgstr ""
+
+#: shell/callbacks.c:168
+msgid "SHA1 implementation by Steve Reid (see sha1.c for details)"
+msgstr ""
+
+#: shell/callbacks.c:169
+msgid "Blowfish implementation by Paul Kocher (see blowfich.c for details)"
+msgstr ""
+
+#: shell/callbacks.c:170
+msgid "Raytracing benchmark by John Walker (see fbench.c for details)"
+msgstr ""
+
+#: shell/callbacks.c:171
+msgid "FFT benchmark by Scott Robert Ladd (see fftbench.c for details)"
+msgstr ""
+
+#: shell/callbacks.c:172
+msgid "Some code partly based on x86cpucaps by Osamu Kayasono"
+msgstr ""
+
+#: shell/callbacks.c:173
+msgid "Vendor list based on GtkSysInfo by Pissens Sebastien"
+msgstr ""
+
+#: shell/callbacks.c:174
+msgid "DMI support based on code by Stewart Adam"
+msgstr ""
+
+#: shell/callbacks.c:175
+msgid "SCSI support based on code by Pascal F. Martin"
+msgstr ""
+
+#: shell/callbacks.c:180
+msgid "Tango Project"
+msgstr ""
+
+#: shell/callbacks.c:181
+msgid "The GNOME Project"
+msgstr ""
+
+#: shell/callbacks.c:182
+msgid "VMWare, Inc. (USB icon from VMWare Workstation 6)"
+msgstr ""
+
+#: shell/callbacks.c:200
+msgid "System information and benchmark tool"
+msgstr "System-Informationen und Benchmark-Werkzeug"
+
+#: shell/callbacks.c:205
+msgid ""
+"HardInfo is free software; you can redistribute it and/or modify it under "
+"the terms of the GNU General Public License as published by the Free "
+"Software Foundation, version 2.\n"
+"\n"
+"This program is distributed in the hope that it will be useful, but WITHOUT "
+"ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
+"FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for "
+"more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License along with "
+"this program; if not, write to the Free Software Foundation, Inc., 51 "
+"Franklin St, Fifth Floor, Boston, MA  02110-1301 USA"
+msgstr ""
+
+#: shell/callbacks.c:220
+msgid "translator-credits"
+msgstr ""
+
+#: shell/menu.c:35
+msgid "_Information"
+msgstr "_Informationen"
+
+#: shell/menu.c:36
+msgid "_Remote"
+msgstr ""
+
+#: shell/menu.c:37
+msgid "_View"
+msgstr "_Ansicht"
+
+#: shell/menu.c:38
+msgid "_Help"
+msgstr "_Hilfe"
+
+#: shell/menu.c:39
+msgid "About _Modules"
+msgstr "Über _Module"
+
+#: shell/menu.c:43
+msgid "Generate _Report"
+msgstr "_Bericht generieren"
+
+#: shell/menu.c:48
+msgid "_Network Updater..."
+msgstr "_Netzwerk-Updater…"
+
+#: shell/menu.c:53
+msgid "_Open..."
+msgstr ""
+
+#: shell/menu.c:58
+msgid "_Copy to Clipboard"
+msgstr "In die Zwischenablage _kopieren"
+
+#: shell/menu.c:59
+msgid "Copy to clipboard"
+msgstr "In die Zwischenablage kopieren"
+
+#: shell/menu.c:63
+msgid "_Refresh"
+msgstr "_Aktualisieren"
+
+#: shell/menu.c:68
+msgid "_Open HardInfo Web Site"
+msgstr "HardInfo-_Webseite öffnen"
+
+#: shell/menu.c:73
+msgid "_Report bug"
+msgstr "Fehler _melden"
+
+#: shell/menu.c:78
+msgid "_About HardInfo"
+msgstr "_Über HardInfo"
+
+#: shell/menu.c:79
+msgid "Displays program version information"
+msgstr ""
+
+#: shell/menu.c:83
+msgid "_Quit"
+msgstr "_Beenden"
+
+#: shell/menu.c:90
+msgid "_Side Pane"
+msgstr "_Seitenleiste"
+
+#: shell/menu.c:91
+msgid "Toggles side pane visibility"
+msgstr ""
+
+#: shell/menu.c:94
+msgid "_Toolbar"
+msgstr "_Symbolleiste"
+
+#: shell/report.c:494 shell/report.c:502
+msgid "Save File"
+msgstr "Datei speichern"
+
+#: shell/report.c:629
+msgid "Cannot create ReportContext. Programming bug?"
+msgstr ""
+
+#: shell/report.c:648
+msgid "Open the report with your web browser?"
+msgstr "Den Bericht in deinem Webbrowser öffnen?"
+
+#: shell/report.c:682
+msgid "Generating report..."
+msgstr "Generiere Bericht…"
+
+#: shell/report.c:692
+msgid "Report saved."
+msgstr "Bericht gespeichert."
+
+#: shell/report.c:694
+msgid "Error while creating the report."
+msgstr "Fehler beim Erzeugen des Berichts."
+
+#: shell/report.c:796
+msgid "Generate Report"
+msgstr "Bericht generieren"
+
+#: shell/report.c:821
+msgid ""
+"<big><b>Generate Report</b></big>\n"
+"Please choose the information that you wish to view in your report:"
+msgstr ""
+"<big><b>Bericht generieren</b></big>\n"
+"Bitte wähle die Informationen, die du in deinen Bereich einbeziehen möchtest:"
+
+#: shell/report.c:893
+msgid "Select _None"
+msgstr "_Nichts auswählen"
+
+#: shell/report.c:904
+msgid "Select _All"
+msgstr "_Alles auswählen"
+
+#: shell/report.c:929 shell/syncmanager.c:748
+msgid "_Cancel"
+msgstr ""
+
+#: shell/report.c:939
+msgid "_Generate"
+msgstr "_Generieren"
+
+#: shell/shell.c:402
+#, c-format
+msgid "%s - System Information"
+msgstr "%s - System-Informationen"
+
+#: shell/shell.c:407
+msgid "System Information"
+msgstr "System-Informationen"
+
+#: shell/shell.c:747
+msgid "Loading modules..."
+msgstr ""
+
+#: shell/shell.c:1660
+#, c-format
+msgid "<b>%s → Summary</b>"
+msgstr "<b>%s → Zusammenfassung</b>"
+
+#: shell/shell.c:1769
+msgid "Updating..."
+msgstr "Aktualisiere…"
+
+#: shell/syncmanager.c:69
+msgid ""
+"<big><b>Synchronize with Central Database</b></big>\n"
+"The following information may be synchronized with the HardInfo central "
+"database."
+msgstr ""
+"<big><b>Synchronisieren mit zentraler Datenbank</b></big>\n"
+"Die folgenden Informationen können mit der zentralen HardInfo-Datenbank "
+"synchronisiert werden."
+
+#: shell/syncmanager.c:72
+msgid ""
+"<big><b>Synchronizing</b></big>\n"
+"This may take some time."
+msgstr ""
+"<big><b>Synchronisiere</b></big>\n"
+"Dies kann kurz dauern."
+
+#: shell/syncmanager.c:132
+msgid ""
+"HardInfo was compiled without libsoup support. (Network Updater requires it.)"
+msgstr ""
+
+#: shell/syncmanager.c:161 shell/syncmanager.c:189
+#, c-format
+msgid "%s (error #%d)"
+msgstr "%s (Fehlercode #%d)"
+
+#: shell/syncmanager.c:170 shell/syncmanager.c:198
+msgid "Could not parse XML-RPC response"
+msgstr ""
+
+#: shell/syncmanager.c:280
+#, c-format
+msgid ""
+"Server says it supports API version %d, but this version of HardInfo only "
+"supports API version %d."
+msgstr ""
+
+#: shell/syncmanager.c:375
+msgid "Contacting HardInfo Central Database"
+msgstr "Kontaktiere zentrale HardInfo-Datenbank"
+
+#: shell/syncmanager.c:376
+msgid "Cleaning up"
+msgstr "Aufräumen"
+
+#: shell/syncmanager.c:493
+msgid "(canceled)"
+msgstr "(abgebrochen)"
+
+#: shell/syncmanager.c:510
+msgid "(failed)"
+msgstr "(gescheitert)"
+
+#: shell/syncmanager.c:521
+#, c-format
+msgid ""
+"Failed while performing \"%s\". Please file a bug report if this problem "
+"persists. (Use the Help→Report bug option.)\n"
+"\n"
+"Details: %s"
+msgstr ""
+
+#: shell/syncmanager.c:530
+#, c-format
+msgid ""
+"Failed while performing \"%s\". Please file a bug report if this problem "
+"persists. (Use the Help→Report bug option.)"
+msgstr ""
+
+#: shell/syncmanager.c:658
+msgid "Network Updater"
+msgstr "Netzwerk-Updater"
+
+#: shell/syncmanager.c:757
+msgid "_Synchronize"
+msgstr "_Synchronisieren"
+
+#: modules/benchmark.c:52
+msgid "CPU Blowfish"
+msgstr "CPU Blowfish"
+
+#: modules/benchmark.c:53
+msgid "CPU CryptoHash"
+msgstr "CPU Crypto-Hash"
+
+#: modules/benchmark.c:54
+msgid "CPU Fibonacci"
+msgstr "CPU Fibonacci"
+
+#: modules/benchmark.c:55
+msgid "CPU N-Queens"
+msgstr "CPU Damenproblem"
+
+#: modules/benchmark.c:56
+msgid "CPU Zlib"
+msgstr ""
+
+#: modules/benchmark.c:57
+msgid "FPU FFT"
+msgstr "FPU FFT"
+
+#: modules/benchmark.c:58
+msgid "FPU Raytracing"
+msgstr "FPU Raytracing"
+
+#: modules/benchmark.c:60
+msgid "GPU Drawing"
+msgstr "GPU Zeichnen"
+
+#: modules/benchmark.c:239 modules/benchmark.c:255
+msgid "CPU Config"
+msgstr ""
+
+#: modules/benchmark.c:239 modules/benchmark.c:255
+msgid "Results"
+msgstr "Ergebnisse"
+
+#: modules/benchmark.c:239 modules/benchmark.c:255 modules/computer.c:751
+#: modules/devices/sparc/processor.c:75
+msgid "CPU"
+msgstr ""
+
+#: modules/benchmark.c:381
+#, c-format
+msgid "Benchmarking: <b>%s</b>."
+msgstr "Benchmarke: <b>%s</b>."
+
+#: modules/benchmark.c:395
+msgid "Benchmarking. Please do not move your mouse or press any keys."
+msgstr "Benchmarke. Bitte bewege den Mauszeiger nicht und drücke keine Tasten."
+
+#: modules/benchmark.c:399
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#: modules/benchmark.c:536
+msgid "Results in MiB/second. Higher is better."
+msgstr "Ergebnisse in MiB/Sekunde. Höhere Werte sind besser."
+
+#: modules/benchmark.c:540
+msgid "Results in HIMarks. Higher is better."
+msgstr "Ergebnisse in HIMarks. Höhere Werte sind besser."
+
+#: modules/benchmark.c:547
+msgid "Results in seconds. Lower is better."
+msgstr "Ergebnisse in Sekunden. Niedrigere Werte sind besser."
+
+#: modules/benchmark.c:555
+msgid "Benchmarks"
+msgstr "Benchmarks"
+
+#: modules/benchmark.c:573
+msgid "Perform tasks and compare with other systems"
+msgstr "Erledigt Aufgaben und vergleicht die Ergebnisse mit anderen Systemen"
+
+#: modules/benchmark.c:663
+msgid "Send benchmark results"
+msgstr "Übermittle Benchmark-Ergebnisse"
+
+#: modules/benchmark.c:668
+msgid "Receive benchmark results"
+msgstr "Lade Benchmark-Ergebnisse"
+
+#: modules/computer/alsa.c:26 modules/computer.c:489
+msgid "Audio Devices"
+msgstr "Audio-Geräte"
+
+#: modules/computer/alsa.c:34
+msgid "Audio Adapter"
+msgstr ""
+
+#: modules/computer/boots.c:33 modules/computer.c:73 modules/computer.c:546
+msgid "Boots"
+msgstr "Systemstarts"
+
+#: modules/computer.c:70
+msgid "Summary"
+msgstr "Zusammenfassung"
+
+#: modules/computer.c:71 modules/computer.c:476 modules/computer.c:750
+msgid "Operating System"
+msgstr "Betriebssystem"
+
+#: modules/computer.c:72
+msgid "Kernel Modules"
+msgstr "Kernel-Module"
+
+#: modules/computer.c:74
+msgid "Languages"
+msgstr "Sprachen"
+
+#: modules/computer.c:75
+msgid "Filesystems"
+msgstr "Dateisysteme"
+
+#: modules/computer.c:76 modules/computer.c:481 modules/computer.c:590
+msgid "Display"
+msgstr "Anzeige"
+
+#: modules/computer.c:77 modules/computer/environment.c:32
+msgid "Environment Variables"
+msgstr "Umgebungsvariablen"
+
+#: modules/computer.c:79
+msgid "Development"
+msgstr "Entwicklung"
+
+#: modules/computer.c:81 modules/computer.c:617
+msgid "Users"
+msgstr "Benutzer"
+
+#: modules/computer.c:82
+msgid "Groups"
+msgstr "Gruppen"
+
+#: modules/computer.c:104 modules/computer.c:473 modules/devices.c:96
+#: modules/devices/pci.c:149
+msgid "Memory"
+msgstr "Hauptspeicher"
+
+#: modules/computer.c:106
+#, c-format
+msgid "%dMB (%dMB used)"
+msgstr ""
+
+#: modules/computer.c:108 modules/computer.c:520
+msgid "Uptime"
+msgstr ""
+
+#: modules/computer.c:110 modules/computer.c:478
+msgid "Date/Time"
+msgstr ""
+
+#: modules/computer.c:115 modules/computer.c:521
+msgid "Load Average"
+msgstr ""
+
+#: modules/computer.c:117 modules/computer.c:522
+msgid "Available entropy in /dev/random"
+msgstr ""
+
+#: modules/computer.c:203
+msgid "Scripting Languages"
+msgstr "Script-Sprachen"
+
+#: modules/computer.c:204
+msgid "Gambas3 (gbr3)"
+msgstr ""
+
+#: modules/computer.c:205
+msgid "Python"
+msgstr ""
+
+#: modules/computer.c:206
+msgid "Python2"
+msgstr ""
+
+#: modules/computer.c:207
+msgid "Python3"
+msgstr ""
+
+#: modules/computer.c:208
+msgid "Perl"
+msgstr "Perl"
+
+#: modules/computer.c:209
+msgid "Perl6 (VM)"
+msgstr ""
+
+#: modules/computer.c:210
+msgid "Perl6"
+msgstr ""
+
+#: modules/computer.c:211
+msgid "PHP"
+msgstr "PHP"
+
+#: modules/computer.c:212
+msgid "Ruby"
+msgstr "Ruby"
+
+#: modules/computer.c:213
+msgid "Bash"
+msgstr "Bash"
+
+#: modules/computer.c:214
+msgid "Compilers"
+msgstr "Compiler"
+
+#: modules/computer.c:215
+msgid "C (GCC)"
+msgstr "C (GCC)"
+
+#: modules/computer.c:216
+msgid "C (Clang)"
+msgstr "C (Clang)"
+
+#: modules/computer.c:217
+msgid "D (dmd)"
+msgstr "D (dmd)"
+
+#: modules/computer.c:218
+msgid "Gambas3 (gbc3)"
+msgstr ""
+
+#: modules/computer.c:219
+msgid "Java"
+msgstr "Java"
+
+#: modules/computer.c:220
+msgid "CSharp (Mono, old)"
+msgstr "CSharp (Mono, old)"
+
+#: modules/computer.c:221
+msgid "CSharp (Mono)"
+msgstr "CSharp (Mono)"
+
+#: modules/computer.c:222
+msgid "Vala"
+msgstr "Vala"
+
+#: modules/computer.c:223
+msgid "Haskell (GHC)"
+msgstr "Haskell (GHC)"
+
+#: modules/computer.c:224
+msgid "FreePascal"
+msgstr "FreePascal"
+
+#: modules/computer.c:225
+msgid "Go"
+msgstr ""
+
+#: modules/computer.c:226
+msgid "Tools"
+msgstr "Werkzeug-Programme"
+
+#: modules/computer.c:227
+msgid "make"
+msgstr "make"
+
+#: modules/computer.c:228
+msgid "GDB"
+msgstr "GDB"
+
+#: modules/computer.c:229
+msgid "strace"
+msgstr "strace"
+
+#: modules/computer.c:230
+msgid "valgrind"
+msgstr "valgrind"
+
+#: modules/computer.c:231
+msgid "QMake"
+msgstr "QMake"
+
+#: modules/computer.c:232
+msgid "CMake"
+msgstr ""
+
+#: modules/computer.c:233
+msgid "Gambas3 IDE"
+msgstr ""
+
+#: modules/computer.c:274
+msgid "Not found"
+msgstr "Nicht gefunden"
+
+#: modules/computer.c:279
+#, c-format
+msgid "Detecting version: %s"
+msgstr ""
+
+#: modules/computer.c:296
+msgid "Program"
+msgstr "Programm"
+
+#: modules/computer.c:308
+msgid "Invalid chassis type (0)"
+msgstr ""
+
+#: modules/computer.c:309 modules/computer.c:310
+msgid "Unknown chassis type"
+msgstr ""
+
+#: modules/computer.c:311
+msgid "Desktop"
+msgstr ""
+
+#: modules/computer.c:312
+msgid "Low-profile Desktop"
+msgstr ""
+
+#: modules/computer.c:313
+msgid "Pizza Box"
+msgstr ""
+
+#: modules/computer.c:314
+msgid "Mini Tower"
+msgstr ""
+
+#: modules/computer.c:315
+msgid "Tower"
+msgstr ""
+
+#: modules/computer.c:316
+msgid "Portable"
+msgstr ""
+
+#: modules/computer.c:317 modules/computer.c:341 modules/computer.c:350
+#: modules/computer.c:372
+msgid "Laptop"
+msgstr ""
+
+#: modules/computer.c:318
+msgid "Notebook"
+msgstr ""
+
+#: modules/computer.c:319
+msgid "Handheld"
+msgstr ""
+
+#: modules/computer.c:320
+msgid "Docking Station"
+msgstr ""
+
+#: modules/computer.c:321
+msgid "All-in-one"
+msgstr ""
+
+#: modules/computer.c:322
+msgid "Subnotebook"
+msgstr ""
+
+#: modules/computer.c:323
+msgid "Space-saving"
+msgstr ""
+
+#: modules/computer.c:324
+msgid "Lunch Box"
+msgstr ""
+
+#: modules/computer.c:325
+msgid "Main Server Chassis"
+msgstr ""
+
+#: modules/computer.c:326
+msgid "Expansion Chassis"
+msgstr ""
+
+#: modules/computer.c:327
+msgid "Sub Chassis"
+msgstr ""
+
+#: modules/computer.c:328
+msgid "Bus Expansion Chassis"
+msgstr ""
+
+#: modules/computer.c:329
+msgid "Peripheral Chassis"
+msgstr ""
+
+#: modules/computer.c:330
+msgid "RAID Chassis"
+msgstr ""
+
+#: modules/computer.c:331
+msgid "Rack Mount Chassis"
+msgstr ""
+
+#: modules/computer.c:332
+msgid "Sealed-case PC"
+msgstr ""
+
+#. /proc/apm
+#. FIXME: use dmidecode if available to get chassis type
+#: modules/computer.c:386
+msgid "Unknown physical machine type"
+msgstr ""
+
+#: modules/computer.c:470 modules/computer.c:709
+msgid "Computer"
+msgstr "Computer"
+
+#: modules/computer.c:471 modules/devices/alpha/processor.c:87
+#: modules/devices/arm/processor.c:236 modules/devices.c:95
+#: modules/devices/ia64/processor.c:159 modules/devices/m68k/processor.c:83
+#: modules/devices/mips/processor.c:74 modules/devices/parisc/processor.c:154
+#: modules/devices/ppc/processor.c:157 modules/devices/riscv/processor.c:181
+#: modules/devices/s390/processor.c:131 modules/devices/sh/processor.c:83
+#: modules/devices/sparc/processor.c:74 modules/devices/x86/processor.c:409
+msgid "Processor"
+msgstr "Prozessor"
+
+#: modules/computer.c:474
+msgid "Machine Type"
+msgstr "Maschinen-Typ"
+
+#: modules/computer.c:477 modules/computer.c:514
+msgid "User Name"
+msgstr "Benutzername"
+
+#: modules/computer.c:482 modules/computer.c:591
+msgid "Resolution"
+msgstr "Auflösung"
+
+#: modules/computer.c:483 modules/computer.c:592
+#, c-format
+msgid "%dx%d pixels"
+msgstr ""
+
+#: modules/computer.c:485
+msgid "OpenGL Renderer"
+msgstr "OpenGL-Renderer"
+
+#: modules/computer.c:486
+msgid "X11 Vendor"
+msgstr "X11-Hersteller"
+
+#: modules/computer.c:491 modules/devices.c:102
+msgid "Input Devices"
+msgstr "Eingabegeräte"
+
+#: modules/computer.c:493 modules/computer.c:752 modules/devices.c:99
+msgid "Printers"
+msgstr "Drucker"
+
+#: modules/computer.c:495 modules/computer.c:752 modules/devices.c:103
+msgid "Storage"
+msgstr "Speicher"
+
+#: modules/computer.c:506
+msgid "Kernel"
+msgstr ""
+
+#: modules/computer.c:508
+msgid "C Library"
+msgstr "C-Library"
+
+#: modules/computer.c:509
+msgid "Distribution"
+msgstr ""
+
+#: modules/computer.c:512
+msgid "Current Session"
+msgstr "Aktuelle Sitzung"
+
+#: modules/computer.c:513
+msgid "Computer Name"
+msgstr "Computername"
+
+#: modules/computer.c:515 modules/computer/languages.c:108
+msgid "Language"
+msgstr "Sprache"
+
+#: modules/computer.c:516 modules/computer/users.c:50
+msgid "Home Directory"
+msgstr "Stammverzeichnis"
+
+#: modules/computer.c:519 modules/devices/usb.c:87 modules/devices/usb.c:234
+#: modules/devices/usb.c:351
+msgid "Misc"
+msgstr "Verschiedenes"
+
+#: modules/computer.c:532
+msgid "Loaded Modules"
+msgstr "Geladene Module"
+
+#: modules/computer.c:535 modules/computer/modules.c:145
+#: modules/computer/modules.c:147 modules/devices/arm/processor.c:337
+#: modules/devices.c:559 modules/devices/x86/processor.c:456
+msgid "Description"
+msgstr "Beschreibung"
+
+#: modules/computer.c:548
+msgid "Date & Time"
+msgstr "Datum & Uhrzeit"
+
+#: modules/computer.c:549
+msgid "Kernel Version"
+msgstr "Kernel-Version"
+
+#: modules/computer.c:559
+msgid "Available Languages"
+msgstr ""
+
+#: modules/computer.c:561
+msgid "Language Code"
+msgstr "Sprach-Code"
+
+#: modules/computer.c:573
+msgid "Mounted File Systems"
+msgstr ""
+
+#: modules/computer.c:575 modules/computer/filesystem.c:85
+msgid "Mount Point"
+msgstr "Mount-Punkt"
+
+#: modules/computer.c:576
+msgid "Usage"
+msgstr "Verwendung"
+
+#: modules/computer.c:577
+msgid "Device"
+msgstr "Gerät"
+
+#: modules/computer.c:594 modules/computer.c:601
+#: modules/devices/ia64/processor.c:161 modules/devices/inputdevices.c:119
+#: modules/devices/pci.c:225 modules/devices/usb.c:349
+#: modules/devices/x86/processor.c:416
+msgid "Vendor"
+msgstr "Hersteller"
+
+#: modules/computer.c:598
+msgid "Monitors"
+msgstr "Bildschirme"
+
+#: modules/computer.c:600
+msgid "OpenGL"
+msgstr ""
+
+#: modules/computer.c:602
+msgid "Renderer"
+msgstr ""
+
+#: modules/computer.c:604
+msgid "Direct Rendering"
+msgstr "Direct-Rendering"
+
+#: modules/computer.c:608
+msgid "Extensions"
+msgstr "Erweiterungen"
+
+#: modules/computer.c:628
+msgid "Group"
+msgstr ""
+
+#: modules/computer.c:631 modules/computer/users.c:49
+msgid "Group ID"
+msgstr "Gruppen-ID"
+
+#: modules/computer.c:751
+msgid "RAM"
+msgstr ""
+
+#: modules/computer.c:751 modules/devices/devicetree/pmac_data.c:82
+msgid "Motherboard"
+msgstr ""
+
+#: modules/computer.c:751
+msgid "Graphics"
+msgstr ""
+
+#: modules/computer.c:752
+msgid "Audio"
+msgstr ""
+
+#: modules/computer.c:807
+msgid "Gathers high-level computer information"
+msgstr "Sammelt high-level Computer-Informationen"
+
+#: modules/computer/display.c:122
+#, c-format
+msgid "Monitor %d=%dx%d pixels\n"
+msgstr "Bildschirm %d=%dx%d Pixel\n"
+
+#: modules/computer/filesystem.c:83
+msgid "Filesystem"
+msgstr ""
+
+#: modules/computer/filesystem.c:84
+msgid "Mounted As"
+msgstr ""
+
+#: modules/computer/filesystem.c:84
+msgid "Read-Write"
+msgstr ""
+
+#: modules/computer/filesystem.c:84
+msgid "Read-Only"
+msgstr ""
+
+#: modules/computer/filesystem.c:86 modules/devices/spd-decode.c:1510
+msgid "Size"
+msgstr ""
+
+#: modules/computer/filesystem.c:87
+msgid "Used"
+msgstr ""
+
+#: modules/computer/filesystem.c:88
+msgid "Available"
+msgstr ""
+
+#: modules/computer/languages.c:103
+msgid "Locale Information"
+msgstr ""
+
+#: modules/computer/languages.c:105
+msgid "Source"
+msgstr ""
+
+#: modules/computer/languages.c:106
+msgid "Address"
+msgstr ""
+
+#: modules/computer/languages.c:107
+msgid "E-mail"
+msgstr ""
+
+#: modules/computer/languages.c:109
+msgid "Territory"
+msgstr ""
+
+#: modules/computer/languages.c:110 modules/devices/arm/processor.c:250
+#: modules/devices/ia64/processor.c:166 modules/devices/ppc/processor.c:159
+#: modules/devices/usb.c:236
+msgid "Revision"
+msgstr ""
+
+#: modules/computer/languages.c:111
+msgid "Date"
+msgstr ""
+
+#: modules/computer/languages.c:112
+msgid "Codeset"
+msgstr ""
+
+#: modules/computer/loadavg.c:64
+msgid "Couldn't obtain load average"
+msgstr ""
+
+#: modules/computer/modules.c:125 modules/computer/modules.c:126
+#: modules/computer/modules.c:127 modules/computer/modules.c:128
+#: modules/computer/modules.c:129
+msgid "(Not available)"
+msgstr ""
+
+#: modules/computer/modules.c:142
+msgid "Module Information"
+msgstr ""
+
+#: modules/computer/modules.c:143
+msgid "Path"
+msgstr ""
+
+#: modules/computer/modules.c:144
+msgid "Used Memory"
+msgstr ""
+
+#: modules/computer/modules.c:144
+msgid "KiB"
+msgstr ""
+
+#: modules/computer/modules.c:148
+msgid "Version Magic"
+msgstr ""
+
+#: modules/computer/modules.c:149
+msgid "Copyright"
+msgstr ""
+
+#: modules/computer/modules.c:150
+msgid "Author"
+msgstr ""
+
+#: modules/computer/modules.c:151
+msgid "License"
+msgstr ""
+
+#: modules/computer/modules.c:158
+msgid "Dependencies"
+msgstr ""
+
+#: modules/computer/os.c:35 modules/computer/os.c:36 modules/computer/os.c:37
+#: modules/computer/os.c:38
+msgid "GNU C Library"
+msgstr ""
+
+#: modules/computer/os.c:39
+msgid "uClibc or uClibc-ng"
+msgstr ""
+
+#: modules/computer/os.c:40
+msgid "diet libc"
+msgstr ""
+
+#: modules/computer/os.c:78 modules/computer/os.c:234 modules/computer/os.c:359
+#: modules/devices.c:333 modules/devices.c:387 modules/devices/printers.c:99
+#: modules/devices/printers.c:106 modules/devices/printers.c:116
+#: modules/devices/printers.c:131 modules/devices/printers.c:140
+#: modules/devices/printers.c:243
+msgid "Unknown"
+msgstr ""
+
+#: modules/computer/os.c:112 modules/computer/os.c:115
+msgid "GNOME Shell "
+msgstr ""
+
+#: modules/computer/os.c:123 modules/computer/os.c:126
+msgid "Version: "
+msgstr ""
+
+#: modules/computer/os.c:157
+#, c-format
+msgid "Unknown (Window Manager: %s)"
+msgstr ""
+
+#. /{desktop environment} on {session type}
+#: modules/computer/os.c:168
+#, c-format
+msgid "%s on %s"
+msgstr ""
+
+#: modules/computer/os.c:232
+msgid "Terminal"
+msgstr ""
+
+#. /bits of entropy for rng (0)
+#: modules/computer/os.c:241
+msgid "(None or not available)"
+msgstr ""
+
+#. /bits of entropy for rng (low/poor value)
+#: modules/computer/os.c:242
+#, c-format
+msgid "%d bits (low)"
+msgstr ""
+
+#. /bits of entropy for rng (medium value)
+#: modules/computer/os.c:243
+#, c-format
+msgid "%d bits (medium)"
+msgstr ""
+
+#. /bits of entropy for rng (high/good value)
+#: modules/computer/os.c:244
+#, c-format
+msgid "%d bits (healthy)"
+msgstr ""
+
+#: modules/computer/os.c:279 modules/devices/usb.c:48 modules/devices/usb.c:307
+#: modules/devices/usb.c:310 modules/network/net.c:442 includes/cpu_util.h:11
+msgid "(Unknown)"
+msgstr ""
+
+#: modules/computer/users.c:47
+msgid "User Information"
+msgstr ""
+
+#: modules/computer/users.c:48
+msgid "User ID"
+msgstr ""
+
+#: modules/computer/users.c:51
+msgid "Default Shell"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:88 modules/devices/devicetree.c:141
+#: modules/devices/devicetree.c:176 modules/devices/devicetree/pmac_data.c:80
+#: modules/devices/ia64/processor.c:165 modules/devices/m68k/processor.c:84
+#: modules/devices/mips/processor.c:75 modules/devices/parisc/processor.c:155
+#: modules/devices/ppc/processor.c:158 modules/devices/riscv/processor.c:182
+#: modules/devices/s390/processor.c:132 modules/devices/spd-decode.c:1510
+msgid "Model"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:89
+msgid "Platform String"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:90 modules/devices/arm/processor.c:240
+#: modules/devices/ia64/processor.c:167 modules/devices/m68k/processor.c:87
+#: modules/devices/mips/processor.c:77 modules/devices/parisc/processor.c:158
+#: modules/devices/pci.c:108 modules/devices/ppc/processor.c:160
+#: modules/devices/riscv/processor.c:186 modules/devices/sh/processor.c:87
+#: modules/devices/x86/processor.c:420
+msgid "Frequency"
+msgstr "Taktfrequenz"
+
+#: modules/devices/alpha/processor.c:90 modules/devices/arm/processor.c:240
+#: modules/devices/arm/processor.c:365 modules/devices.c:299
+#: modules/devices.c:307 modules/devices.c:335
+#: modules/devices/ia64/processor.c:167 modules/devices/ia64/processor.c:196
+#: modules/devices/m68k/processor.c:87 modules/devices/mips/processor.c:77
+#: modules/devices/parisc/processor.c:158
+#: modules/devices/parisc/processor.c:191 modules/devices/pci.c:108
+#: modules/devices/ppc/processor.c:160 modules/devices/ppc/processor.c:187
+#: modules/devices/riscv/processor.c:186 modules/devices/riscv/processor.c:214
+#: modules/devices/s390/processor.c:160 modules/devices/sh/processor.c:87
+#: modules/devices/sh/processor.c:88 modules/devices/sh/processor.c:89
+#: modules/devices/x86/processor.c:420 modules/devices/x86/processor.c:479
+msgid "MHz"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:91 modules/devices/arm/processor.c:241
+#: modules/devices/ia64/processor.c:168 modules/devices/m68k/processor.c:88
+#: modules/devices/mips/processor.c:78 modules/devices/parisc/processor.c:159
+#: modules/devices/ppc/processor.c:161 modules/devices/s390/processor.c:134
+#: modules/devices/sh/processor.c:90 modules/devices/x86/processor.c:421
+msgid "BogoMips"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:92 modules/devices/arm/processor.c:242
+#: modules/devices/ia64/processor.c:169 modules/devices/m68k/processor.c:89
+#: modules/devices/mips/processor.c:79 modules/devices/parisc/processor.c:160
+#: modules/devices/ppc/processor.c:162 modules/devices/riscv/processor.c:187
+#: modules/devices/s390/processor.c:135 modules/devices/sh/processor.c:91
+#: modules/devices/sparc/processor.c:77 modules/devices/x86/processor.c:422
+msgid "Byte Order"
+msgstr "Byte-Reihenfolge"
+
+#. /hw_cap
+#. /flag:swp
+#: modules/devices/arm/arm_data.c:42
+msgctxt "arm-flag"
+msgid "SWP instruction (atomic read-modify-write)"
+msgstr ""
+
+#. /flag:half
+#: modules/devices/arm/arm_data.c:43
+msgctxt "arm-flag"
+msgid "Half-word loads and stores"
+msgstr ""
+
+#. /flag:thumb
+#: modules/devices/arm/arm_data.c:44
+msgctxt "arm-flag"
+msgid "Thumb (16-bit instruction set)"
+msgstr ""
+
+#. /flag:26bit
+#: modules/devices/arm/arm_data.c:45
+msgctxt "arm-flag"
+msgid "26-Bit Model (Processor status register folded into program counter)"
+msgstr ""
+
+#. /flag:fastmult
+#: modules/devices/arm/arm_data.c:46
+msgctxt "arm-flag"
+msgid "32x32->64-bit multiplication"
+msgstr ""
+
+#. /flag:fpa
+#: modules/devices/arm/arm_data.c:47
+msgctxt "arm-flag"
+msgid "Floating point accelerator"
+msgstr ""
+
+#. /flag:vfp
+#: modules/devices/arm/arm_data.c:48
+msgctxt "arm-flag"
+msgid "VFP (early SIMD vector floating point instructions)"
+msgstr ""
+
+#. /flag:edsp
+#: modules/devices/arm/arm_data.c:49
+msgctxt "arm-flag"
+msgid "DSP extensions (the 'e' variant of the ARM9 CPUs, and all others above)"
+msgstr ""
+
+#. /flag:java
+#: modules/devices/arm/arm_data.c:50
+msgctxt "arm-flag"
+msgid "Jazelle (Java bytecode accelerator)"
+msgstr ""
+
+#. /flag:iwmmxt
+#: modules/devices/arm/arm_data.c:51
+msgctxt "arm-flag"
+msgid "SIMD instructions similar to Intel MMX"
+msgstr ""
+
+#. /flag:crunch
+#: modules/devices/arm/arm_data.c:52
+msgctxt "arm-flag"
+msgid "MaverickCrunch coprocessor (if kernel support enabled)"
+msgstr ""
+
+#. /flag:thumbee
+#: modules/devices/arm/arm_data.c:53
+msgctxt "arm-flag"
+msgid "ThumbEE"
+msgstr ""
+
+#. /flag:neon
+#: modules/devices/arm/arm_data.c:54
+msgctxt "arm-flag"
+msgid "Advanced SIMD/NEON on AArch32"
+msgstr ""
+
+#. /flag:evtstrm
+#: modules/devices/arm/arm_data.c:55
+msgctxt "arm-flag"
+msgid "Kernel event stream using generic architected timer"
+msgstr ""
+
+#. /flag:vfpv3
+#: modules/devices/arm/arm_data.c:56
+msgctxt "arm-flag"
+msgid "VFP version 3"
+msgstr ""
+
+#. /flag:vfpv3d16
+#: modules/devices/arm/arm_data.c:57
+msgctxt "arm-flag"
+msgid "VFP version 3 with 16 D-registers"
+msgstr ""
+
+#. /flag:vfpv4
+#: modules/devices/arm/arm_data.c:58
+msgctxt "arm-flag"
+msgid "VFP version 4 with fast context switching"
+msgstr ""
+
+#. /flag:vfpd32
+#: modules/devices/arm/arm_data.c:59
+msgctxt "arm-flag"
+msgid "VFP with 32 D-registers"
+msgstr ""
+
+#. /flag:tls
+#: modules/devices/arm/arm_data.c:60
+msgctxt "arm-flag"
+msgid "TLS register"
+msgstr ""
+
+#. /flag:idiva
+#: modules/devices/arm/arm_data.c:61
+msgctxt "arm-flag"
+msgid "SDIV and UDIV hardware division in ARM mode"
+msgstr ""
+
+#. /flag:idivt
+#: modules/devices/arm/arm_data.c:62
+msgctxt "arm-flag"
+msgid "SDIV and UDIV hardware division in Thumb mode"
+msgstr ""
+
+#. /flag:lpae
+#: modules/devices/arm/arm_data.c:63
+msgctxt "arm-flag"
+msgid "40-bit Large Physical Address Extension"
+msgstr ""
+
+#. /hw_cap2
+#. /flag:pmull
+#: modules/devices/arm/arm_data.c:65
+msgctxt "arm-flag"
+msgid "64x64->128-bit F2m multiplication (arch>8)"
+msgstr ""
+
+#. /flag:aes
+#: modules/devices/arm/arm_data.c:66
+msgctxt "arm-flag"
+msgid "Crypto:AES (arch>8)"
+msgstr ""
+
+#. /flag:sha1
+#: modules/devices/arm/arm_data.c:67
+msgctxt "arm-flag"
+msgid "Crypto:SHA1 (arch>8)"
+msgstr ""
+
+#. /flag:sha2
+#: modules/devices/arm/arm_data.c:68
+msgctxt "arm-flag"
+msgid "Crypto:SHA2 (arch>8)"
+msgstr ""
+
+#. /flag:crc32
+#: modules/devices/arm/arm_data.c:69
+msgctxt "arm-flag"
+msgid "CRC32 checksum instructions (arch>8)"
+msgstr ""
+
+#. /flag:asimd
+#: modules/devices/arm/arm_data.c:72
+msgctxt "arm-flag"
+msgid "Advanced SIMD/NEON on AArch64 (arch>8)"
+msgstr ""
+
+#: modules/devices/arm/processor.c:142
+msgid "ARM Processor"
+msgstr "ARM Prozessor"
+
+#: modules/devices/arm/processor.c:200 modules/devices/riscv/processor.c:147
+#: modules/devices/x86/processor.c:371
+msgid "Empty List"
+msgstr ""
+
+#: modules/devices/arm/processor.c:237
+msgid "Linux Name"
+msgstr ""
+
+#: modules/devices/arm/processor.c:238
+msgid "Decoded Name"
+msgstr ""
+
+#: modules/devices/arm/processor.c:239 modules/network/net.c:458
+msgid "Mode"
+msgstr ""
+
+#: modules/devices/arm/processor.c:245
+msgid "ARM"
+msgstr ""
+
+#: modules/devices/arm/processor.c:246
+msgid "Implementer"
+msgstr ""
+
+#: modules/devices/arm/processor.c:247
+msgid "Part"
+msgstr ""
+
+#: modules/devices/arm/processor.c:248 modules/devices/ia64/processor.c:162
+#: modules/devices/parisc/processor.c:156 modules/devices/riscv/processor.c:183
+msgid "Architecture"
+msgstr ""
+
+#: modules/devices/arm/processor.c:249
+msgid "Variant"
+msgstr ""
+
+#: modules/devices/arm/processor.c:251 modules/devices/riscv/processor.c:190
+#: modules/devices/sparc/processor.c:78 modules/devices/x86/processor.c:428
+msgid "Capabilities"
+msgstr "Fähigkeiten"
+
+#: modules/devices/arm/processor.c:335
+msgid "SOC/Package"
+msgstr ""
+
+#: modules/devices/arm/processor.c:338 modules/devices/cpu_util.c:222
+msgid "Topology"
+msgstr ""
+
+#: modules/devices/arm/processor.c:339
+msgid "Clocks"
+msgstr ""
+
+#: modules/devices/arm/processor.c:354
+msgid "SOC/Package Information"
+msgstr ""
+
+#: modules/devices/battery.c:181
+#, c-format
+msgid ""
+"\n"
+"[Battery: %s]\n"
+"State=%s (load: %s)\n"
+"Capacity=%s / %s (%.2f%%)\n"
+"Battery Technology=%s (%s)\n"
+"Manufacturer=%s\n"
+"Model Number=%s\n"
+"Serial Number=%s\n"
+msgstr ""
+"\n"
+"[Akku: %s]\n"
+"Status=%s (load: %s)\n"
+"Kapazität=%s / %s (%.2f%%)\n"
+"Akku-Technologie=%s (%s)\n"
+"Hersteller=%s\n"
+"Modellnummer=%s\n"
+"Seriennummer=%s\n"
+
+#: modules/devices/battery.c:258
+#, c-format
+msgid ""
+"\n"
+"[Battery: %s]\n"
+"State=%s\n"
+"Capacity=%s / %s\n"
+"Battery Technology=%s\n"
+"Manufacturer=%s\n"
+"Model Number=%s\n"
+"Serial Number=%s\n"
+msgstr ""
+"\n"
+"[Akku: %s]\n"
+"Status=%s\n"
+"Kapazität=%s / %s\n"
+"Akku-Technologie=%s\n"
+"Hersteller=%s\n"
+"Modellnummer=%s\n"
+"Seriennummer=%s\n"
+
+#: modules/devices/battery.c:346
+#, fuzzy, c-format
+msgid ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Remaining Charge=%s of %s\n"
+"Using=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+msgstr ""
+"\n"
+"[Akku (APM)]\n"
+"Ladung=%d%%\n"
+"Verbleibende Ladung=%s von %s\n"
+"Using=%s\n"
+"APM Driver-Version=%s\n"
+"APM BIOS-Version=%s\n"
+
+#: modules/devices/battery.c:358
+#, fuzzy, c-format
+msgid ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Using=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+msgstr ""
+"\n"
+"[Akku (APM)]\n"
+"Ladung=%d%%\n"
+"Using=%s\n"
+"APM Driver-Version=%s\n"
+"APM BIOS-Version=%s\n"
+
+#: modules/devices/battery.c:385
+msgid ""
+"[No batteries]\n"
+"No batteries found on this system=\n"
+msgstr ""
+"[Keine Akkus]\n"
+"Keine Akkus in diesem System gefunden=\n"
+
+#: modules/devices.c:97
+msgid "PCI Devices"
+msgstr "PCI-Geräte"
+
+#: modules/devices.c:98 modules/devices/usb.c:117 modules/devices/usb.c:156
+#: modules/devices/usb.c:415
+msgid "USB Devices"
+msgstr "USB-Geräte"
+
+#: modules/devices.c:100
+msgid "Battery"
+msgstr "Akku"
+
+#: modules/devices.c:101
+msgid "Sensors"
+msgstr "Sensoren"
+
+#: modules/devices.c:105
+msgid "DMI"
+msgstr "DMI"
+
+#: modules/devices.c:106
+msgid "Memory SPD"
+msgstr "Hauptspeicher (SPD)"
+
+#: modules/devices.c:111
+msgid "Device Tree"
+msgstr ""
+
+#: modules/devices.c:113
+msgid "Resources"
+msgstr "Ressourcen"
+
+#: modules/devices.c:151
+#, c-format
+msgid "%d physical processor"
+msgid_plural "%d physical processors"
+msgstr[0] ""
+msgstr[1] ""
+
+#: modules/devices.c:152
+#, c-format
+msgid "%d core"
+msgid_plural "%d cores"
+msgstr[0] ""
+msgstr[1] ""
+
+#: modules/devices.c:153
+#, c-format
+msgid "%d thread"
+msgid_plural "%d threads"
+msgstr[0] ""
+msgstr[1] ""
+
+#. /NP procs; NC cores; NT threads
+#: modules/devices.c:154
+#, c-format
+msgid "%s; %s; %s"
+msgstr ""
+
+#: modules/devices.c:372
+msgid " (model unknown)"
+msgstr " (unbekanntes Modell)"
+
+#: modules/devices.c:374
+msgid " (vendor unknown)"
+msgstr " (unbekannter Hersteller)"
+
+#: modules/devices.c:559
+msgid "Field"
+msgstr ""
+
+#: modules/devices.c:559 modules/devices.c:591
+msgid "Value"
+msgstr ""
+
+#: modules/devices.c:591
+msgid "Sensor"
+msgstr ""
+
+#: modules/devices.c:591 modules/devices/inputdevices.c:117
+msgid "Type"
+msgstr ""
+
+#: modules/devices.c:637
+msgid "Devices"
+msgstr "Geräte"
+
+#: modules/devices.c:649
+msgid "Update PCI ID listing"
+msgstr ""
+
+#: modules/devices.c:661
+msgid "Update CPU feature database"
+msgstr ""
+
+#: modules/devices.c:689
+msgid "Gathers information about hardware devices"
+msgstr "Sammelt Informationen über die Hardware-Geräte"
+
+#: modules/devices.c:708
+msgid "Resource information requires superuser privileges"
+msgstr ""
+
+#: modules/devices/cpu_util.c:30
+msgid "Little Endian"
+msgstr ""
+
+#: modules/devices/cpu_util.c:32
+msgid "Big Endian"
+msgstr ""
+
+#: modules/devices/cpu_util.c:178 modules/devices/cpu_util.c:189
+msgid "Frequency Scaling"
+msgstr ""
+
+#: modules/devices/cpu_util.c:179
+msgid "Minimum"
+msgstr ""
+
+#: modules/devices/cpu_util.c:179 modules/devices/cpu_util.c:180
+#: modules/devices/cpu_util.c:181
+msgid "kHz"
+msgstr ""
+
+#: modules/devices/cpu_util.c:180
+msgid "Maximum"
+msgstr ""
+
+#: modules/devices/cpu_util.c:181
+msgid "Current"
+msgstr ""
+
+#: modules/devices/cpu_util.c:182
+msgid "Transition Latency"
+msgstr ""
+
+#: modules/devices/cpu_util.c:182
+msgid "ns"
+msgstr ""
+
+#: modules/devices/cpu_util.c:183
+msgid "Governor"
+msgstr ""
+
+#: modules/devices/cpu_util.c:184 modules/devices/cpu_util.c:190
+msgid "Driver"
+msgstr "Treiber"
+
+#: modules/devices/cpu_util.c:196 modules/devices/x86/processor.c:297
+msgid "(Not Available)"
+msgstr ""
+
+#: modules/devices/cpu_util.c:204 modules/devices/cpu_util.c:206
+msgid "Socket"
+msgstr ""
+
+#: modules/devices/cpu_util.c:209 modules/devices/cpu_util.c:211
+msgid "Core"
+msgstr ""
+
+#: modules/devices/cpu_util.c:214
+msgid "Book"
+msgstr ""
+
+#: modules/devices/cpu_util.c:216
+msgid "Drawer"
+msgstr ""
+
+#: modules/devices/cpu_util.c:223
+msgid "ID"
+msgstr ""
+
+#: modules/devices/devicetree.c:47
+msgid "Properties"
+msgstr ""
+
+#: modules/devices/devicetree.c:48
+msgid "Children"
+msgstr ""
+
+#: modules/devices/devicetree.c:84
+msgid "Node"
+msgstr ""
+
+#: modules/devices/devicetree.c:85
+msgid "Node Path"
+msgstr ""
+
+#: modules/devices/devicetree.c:86
+msgid "Alias"
+msgstr ""
+
+#: modules/devices/devicetree.c:86 modules/devices/devicetree.c:87
+msgid "(None)"
+msgstr ""
+
+#: modules/devices/devicetree.c:87
+msgid "Symbol"
+msgstr ""
+
+#: modules/devices/devicetree.c:132 modules/devices/devicetree/pmac_data.c:79
+msgid "Platform"
+msgstr ""
+
+#: modules/devices/devicetree.c:133 modules/devices/devicetree.c:178
+msgid "Compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:134
+msgid "GPU-compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:140
+msgid "Raspberry Pi or Compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:142 modules/devices/devicetree.c:160
+#: modules/devices/devicetree.c:177 modules/devices/devicetree/rpi_data.c:160
+msgid "Serial Number"
+msgstr ""
+
+#: modules/devices/devicetree.c:143 modules/devices/devicetree/rpi_data.c:157
+msgid "RCode"
+msgstr ""
+
+#: modules/devices/devicetree.c:143
+msgid "No revision code available; unable to lookup model details."
+msgstr ""
+
+#: modules/devices/devicetree.c:159
+msgid "More"
+msgstr ""
+
+#: modules/devices/devicetree.c:175
+msgid "Board"
+msgstr ""
+
+#: modules/devices/devicetree.c:234
+msgid "Messages"
+msgstr ""
+
+#: modules/devices/devicetree/dt_util.c:1013
+msgid "phandle Map"
+msgstr ""
+
+#: modules/devices/devicetree/dt_util.c:1014
+msgid "Alias Map"
+msgstr ""
+
+#: modules/devices/devicetree/dt_util.c:1015
+msgid "Symbol Map"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:78
+msgid "Apple Power Macintosh"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:81 modules/devices/sh/processor.c:85
+msgid "Machine"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:83
+msgid "Detected as"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:84
+msgid "PMAC Flags"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:85
+msgid "L2 Cache"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:86
+msgid "PMAC Generation"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:152
+#: modules/devices/devicetree/rpi_data.c:153
+msgid "Raspberry Pi"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:153
+msgid "Board Name"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:154
+msgid "PCB Revision"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:155
+msgid "Introduction"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:156 modules/devices/spd-decode.c:1510
+#: modules/devices/usb.c:84 modules/devices/usb.c:217
+msgid "Manufacturer"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:158
+msgid "SOC (spec)"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:159
+msgid "Memory (spec)"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgid "Permanent overvolt bit"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgctxt "rpi-ov-bit"
+msgid "Set"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgctxt "rpi-ov-bit"
+msgid "Not set"
+msgstr ""
+
+#: modules/devices/devmemory.c:93
+msgid "Total Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:94
+msgid "Free Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:95
+msgid "Cached Swap"
+msgstr ""
+
+#: modules/devices/devmemory.c:96
+msgid "High Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:97
+msgid "Free High Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:98
+msgid "Low Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:99
+msgid "Free Low Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:100
+msgid "Virtual Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:101
+msgid "Free Virtual Memory"
+msgstr ""
+
+#: modules/devices/dmi.c:188
+msgid "(Not available; Perhaps try running HardInfo as root.)"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:108
+msgid "IA64 Processor"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:163
+msgid "Architecture Revision"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:164 modules/devices/sh/processor.c:86
+msgid "Family"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:170
+msgid "CPU regs"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:171
+msgid "Features"
+msgstr "Funktionen"
+
+#: modules/devices/inputdevices.c:115 modules/devices/pci.c:214
+#: modules/devices/usb.c:82 modules/devices/usb.c:215 modules/devices/usb.c:347
+msgid "Device Information"
+msgstr ""
+
+#: modules/devices/inputdevices.c:118 modules/devices/usb.c:92
+#: modules/devices/usb.c:240 modules/devices/usb.c:356
+msgid "Bus"
+msgstr ""
+
+#: modules/devices/inputdevices.c:120 modules/devices/usb.c:83
+#: modules/devices/usb.c:216 modules/devices/usb.c:348
+msgid "Product"
+msgstr ""
+
+#: modules/devices/inputdevices.c:124
+msgid "Connected to"
+msgstr ""
+
+#: modules/devices/inputdevices.c:128
+msgid "InfraRed port"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:85 modules/devices/riscv/processor.c:185
+msgid "MMU"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:86 modules/devices/sparc/processor.c:76
+msgid "FPU"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:90
+msgid "Calibration"
+msgstr ""
+
+#: modules/devices/mips/processor.c:76
+msgid "System Type"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:107
+msgid "PA-RISC Processor"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:157
+msgid "System"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:161
+msgid "HVersion"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:162
+msgid "SVersion"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:163 modules/devices/x86/processor.c:425
+msgid "Cache"
+msgstr ""
+
+#: modules/devices/pci.c:106
+msgid "IRQ"
+msgstr ""
+
+#: modules/devices/pci.c:110
+msgid "Latency"
+msgstr ""
+
+#: modules/devices/pci.c:112
+msgid "Bus Master"
+msgstr ""
+
+#: modules/devices/pci.c:118
+msgid "Kernel modules"
+msgstr ""
+
+#: modules/devices/pci.c:124
+#, c-format
+msgid "%s=%s (%s)\n"
+msgstr ""
+
+#: modules/devices/pci.c:126
+msgid "OEM Vendor"
+msgstr ""
+
+#: modules/devices/pci.c:153
+msgid "prefetchable"
+msgstr ""
+
+#: modules/devices/pci.c:154
+msgid "non-prefetchable"
+msgstr ""
+
+#: modules/devices/pci.c:163
+msgid "I/O ports at"
+msgstr ""
+
+#: modules/devices/pci.c:216 modules/devices/usb.c:89 modules/devices/usb.c:237
+#: modules/devices/usb.c:353
+msgid "Class"
+msgstr ""
+
+#: modules/devices/pci.c:217
+msgid "Domain"
+msgstr ""
+
+#: modules/devices/pci.c:218
+msgid "Bus, device, function"
+msgstr ""
+
+#: modules/devices/pci.c:243
+msgid "No PCI devices found"
+msgstr ""
+
+#: modules/devices/ppc/processor.c:117
+msgid "POWER Processor"
+msgstr "POWER Prozessor"
+
+#: modules/devices/printers.c:81
+msgid "⚬ Can do black and white printing=\n"
+msgstr "⚬ Kann schwarz/weiß drucken=\n"
+
+#: modules/devices/printers.c:83
+msgid "⚬ Can do color printing=\n"
+msgstr "⚬ Kann farbig drucken=\n"
+
+#: modules/devices/printers.c:85
+msgid "⚬ Can do duplexing=\n"
+msgstr "⚬ Kann zweiseitig drucken (Duplexdruck)=\n"
+
+#: modules/devices/printers.c:87
+msgid "⚬ Can do staple output=\n"
+msgstr "⚬ Kann Ausdrucke stapeln=\n"
+
+#: modules/devices/printers.c:89
+msgid "⚬ Can do copies=\n"
+msgstr "⚬ Kann kopieren=\n"
+
+#: modules/devices/printers.c:91
+msgid "⚬ Can collate copies=\n"
+msgstr "⚬ Kann Ausdruck sortieren=\n"
+
+#: modules/devices/printers.c:93
+msgid "⚬ Printer is rejecting jobs=\n"
+msgstr "⚬ Drucker weist Aufträge zurück=\n"
+
+#: modules/devices/printers.c:95
+msgid "⚬ Printer was automatically discovered and added=\n"
+msgstr "⚬ Drucker wurde automatisch entdeckt und hinzugefügt=\n"
+
+#: modules/devices/printers.c:110
+msgid "Idle"
+msgstr ""
+
+#: modules/devices/printers.c:112
+msgid "Printing a Job"
+msgstr ""
+
+#: modules/devices/printers.c:114
+msgid "Stopped"
+msgstr ""
+
+#: modules/devices/printers.c:190
+msgid ""
+"[Printers]\n"
+"No suitable CUPS library found="
+msgstr ""
+"[Drucker]\n"
+"Keine passende CUPS-Bibliothek gefunden="
+
+#: modules/devices/printers.c:200
+msgid "[Printers (CUPS)]\n"
+msgstr "[Drucker (CUPS)]\n"
+
+#: modules/devices/printers.c:263
+msgid ""
+"[Printers]\n"
+"No printers found=\n"
+msgstr ""
+"[Printers]\n"
+"Keine Drucker gefunden=\n"
+
+#: modules/devices/riscv/processor.c:107
+msgid "RISC-V Processor"
+msgstr ""
+
+#: modules/devices/riscv/processor.c:184
+msgid "uarch"
+msgstr ""
+
+#. /ext:RV32
+#: modules/devices/riscv/riscv_data.c:37
+msgctxt "rv-ext"
+msgid "RISC-V 32-bit"
+msgstr ""
+
+#. /ext:RV64
+#: modules/devices/riscv/riscv_data.c:38
+msgctxt "rv-ext"
+msgid "RISC-V 64-bit"
+msgstr ""
+
+#. /ext:RV128
+#: modules/devices/riscv/riscv_data.c:39
+msgctxt "rv-ext"
+msgid "RISC-V 128-bit"
+msgstr ""
+
+#. /ext:E
+#: modules/devices/riscv/riscv_data.c:40
+msgctxt "rv-ext"
+msgid "Base embedded integer instructions (15 registers)"
+msgstr ""
+
+#. /ext:I
+#: modules/devices/riscv/riscv_data.c:41
+msgctxt "rv-ext"
+msgid "Base integer instructions (31 registers)"
+msgstr ""
+
+#. /ext:M
+#: modules/devices/riscv/riscv_data.c:42
+msgctxt "rv-ext"
+msgid "Hardware integer multiply and divide"
+msgstr ""
+
+#. /ext:A
+#: modules/devices/riscv/riscv_data.c:43
+msgctxt "rv-ext"
+msgid "Atomic memory operations"
+msgstr ""
+
+#. /ext:C
+#: modules/devices/riscv/riscv_data.c:44
+msgctxt "rv-ext"
+msgid "Compressed 16-bit instructions"
+msgstr ""
+
+#. /ext:F
+#: modules/devices/riscv/riscv_data.c:45
+msgctxt "rv-ext"
+msgid "Floating-point instructions, single-precision"
+msgstr ""
+
+#. /ext:D
+#: modules/devices/riscv/riscv_data.c:46
+msgctxt "rv-ext"
+msgid "Floating-point instructions, double-precision"
+msgstr ""
+
+#. /ext:Q
+#: modules/devices/riscv/riscv_data.c:47
+msgctxt "rv-ext"
+msgid "Floating-point instructions, quad-precision"
+msgstr ""
+
+#. /ext:B
+#: modules/devices/riscv/riscv_data.c:48
+msgctxt "rv-ext"
+msgid "Bit manipulation instructions"
+msgstr ""
+
+#. /ext:V
+#: modules/devices/riscv/riscv_data.c:49
+msgctxt "rv-ext"
+msgid "Vector operations"
+msgstr ""
+
+#. /ext:T
+#: modules/devices/riscv/riscv_data.c:50
+msgctxt "rv-ext"
+msgid "Transactional memory"
+msgstr ""
+
+#. /ext:P
+#: modules/devices/riscv/riscv_data.c:51
+msgctxt "rv-ext"
+msgid "Packed SIMD instructions"
+msgstr ""
+
+#. /ext:L
+#: modules/devices/riscv/riscv_data.c:52
+msgctxt "rv-ext"
+msgid "Decimal floating-point instructions"
+msgstr ""
+
+#. /ext:J
+#: modules/devices/riscv/riscv_data.c:53
+msgctxt "rv-ext"
+msgid "Dynamically translated languages"
+msgstr ""
+
+#. /ext:N
+#: modules/devices/riscv/riscv_data.c:54
+msgctxt "rv-ext"
+msgid "User-level interrupts"
+msgstr ""
+
+#: modules/devices/s390/processor.c:92
+msgid "S390 Processor"
+msgstr ""
+
+#: modules/devices/s390/processor.c:133
+msgid "ID String"
+msgstr ""
+
+#: modules/devices/sh/processor.c:55
+msgid "SuperH Processor"
+msgstr ""
+
+#: modules/devices/sh/processor.c:88
+msgid "Bus Frequency"
+msgstr ""
+
+#: modules/devices/sh/processor.c:89
+msgid "Module Frequency"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1475
+msgid ""
+"[SPD]\n"
+"Please load the eeprom module to obtain information about memory SPD=\n"
+"[$ShellParam$]\n"
+"ReloadInterval=500\n"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1480
+msgid ""
+"[SPD]\n"
+"Reading memory SPD not supported on this system=\n"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1509
+msgid "SPD"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1510
+msgid "Bank"
+msgstr ""
+
+#: modules/devices/storage.c:46
+msgid ""
+"\n"
+"[SCSI Disks]\n"
+msgstr ""
+"\n"
+"[SCSI-Geräte]\n"
+
+#: modules/devices/storage.c:110 modules/devices/storage.c:313
+#, c-format
+msgid ""
+"[Device Information]\n"
+"Model=%s\n"
+msgstr ""
+"[Geräte-Informationen]\n"
+"Modell=%s\n"
+
+#: modules/devices/storage.c:115 modules/devices/storage.c:319
+#, c-format
+msgid "Vendor=%s (%s)\n"
+msgstr "Hersteller=%s (%s)\n"
+
+#: modules/devices/storage.c:120 modules/devices/storage.c:321
+#, c-format
+msgid "Vendor=%s\n"
+msgstr "Hersteller=%s\n"
+
+#: modules/devices/storage.c:125
+#, c-format
+msgid ""
+"Type=%s\n"
+"Revision=%s\n"
+"[SCSI Controller]\n"
+"Controller=scsi%d\n"
+"Channel=%d\n"
+"ID=%d\n"
+"LUN=%d\n"
+msgstr ""
+
+#: modules/devices/storage.c:167
+msgid ""
+"\n"
+"[IDE Disks]\n"
+msgstr ""
+"\n"
+"[IDE-Geräte]\n"
+
+#: modules/devices/storage.c:250
+#, c-format
+msgid "Driver=%s\n"
+msgstr "Treiber=%s\n"
+
+#: modules/devices/storage.c:324
+#, c-format
+msgid ""
+"Device Name=hd%c\n"
+"Media=%s\n"
+"Cache=%dkb\n"
+msgstr ""
+
+#: modules/devices/storage.c:334
+#, c-format
+msgid ""
+"[Geometry]\n"
+"Physical=%s\n"
+"Logical=%s\n"
+msgstr ""
+"[Geometrie]\n"
+"Physikalisch=%s\n"
+"Logisch=%s\n"
+
+#: modules/devices/storage.c:344
+#, c-format
+msgid ""
+"[Capabilities]\n"
+"%s"
+msgstr ""
+"[Fähigkeiten]\n"
+"%s"
+
+#: modules/devices/storage.c:351
+#, c-format
+msgid ""
+"[Speeds]\n"
+"%s"
+msgstr ""
+"[Geschwindigkeiten]\n"
+"%s"
+
+#: modules/devices/usb.c:44 modules/devices/usb.c:326
+msgid "mA"
+msgstr ""
+
+#. /%.2f is version
+#: modules/devices/usb.c:53 modules/devices/usb.c:190
+#, c-format
+msgid "USB %.2f Hub"
+msgstr ""
+
+#: modules/devices/usb.c:55 modules/devices/usb.c:192
+#, c-format
+msgid "Unknown USB %.2f Device (class %d)"
+msgstr ""
+
+#: modules/devices/usb.c:85 modules/devices/usb.c:232
+msgid "Speed"
+msgstr ""
+
+#: modules/devices/usb.c:85 modules/devices/usb.c:232
+msgid "Mbit/s"
+msgstr ""
+
+#: modules/devices/usb.c:86 modules/devices/usb.c:233 modules/devices/usb.c:350
+msgid "Max Current"
+msgstr ""
+
+#: modules/devices/usb.c:88 modules/devices/usb.c:235 modules/devices/usb.c:352
+msgid "USB Version"
+msgstr ""
+
+#: modules/devices/usb.c:90 modules/devices/usb.c:238 modules/devices/usb.c:354
+msgid "Vendor ID"
+msgstr ""
+
+#: modules/devices/usb.c:91 modules/devices/usb.c:239 modules/devices/usb.c:355
+msgid "Product ID"
+msgstr ""
+
+#: modules/devices/usb.c:231
+msgid "Port"
+msgstr ""
+
+#: modules/devices/usb.c:241
+msgid "Level"
+msgstr ""
+
+#: modules/devices/x86/processor.c:149
+msgid "Cache information not available=\n"
+msgstr ""
+
+#: modules/devices/x86/processor.c:155
+#, c-format
+msgid "Level %d (%s)=%d-way set-associative, %d sets, %dKB size\n"
+msgstr ""
+
+#. /cache type, as appears in: Level 1 (Data)
+#: modules/devices/x86/processor.c:170
+msgctxt "cache-type"
+msgid "Data"
+msgstr ""
+
+#. /cache type, as appears in: Level 1 (Instruction)
+#: modules/devices/x86/processor.c:171
+msgctxt "cache-type"
+msgid "Instruction"
+msgstr ""
+
+#. /cache type, as appears in: Level 2 (Unified)
+#: modules/devices/x86/processor.c:172
+msgctxt "cache-type"
+msgid "Unified"
+msgstr ""
+
+#: modules/devices/x86/processor.c:410
+msgid "Model Name"
+msgstr ""
+
+#: modules/devices/x86/processor.c:411
+msgid "Family, model, stepping"
+msgstr "Familie, Modell, Stufung"
+
+#: modules/devices/x86/processor.c:417
+msgid "Microcode Version"
+msgstr ""
+
+#: modules/devices/x86/processor.c:418
+msgid "Configuration"
+msgstr "Konfiguration"
+
+#: modules/devices/x86/processor.c:419
+msgid "Cache Size"
+msgstr "Cache-Größe"
+
+#: modules/devices/x86/processor.c:419
+msgid "kb"
+msgstr ""
+
+#: modules/devices/x86/processor.c:426
+msgid "Power Management"
+msgstr ""
+
+#: modules/devices/x86/processor.c:427
+msgid "Bug Workarounds"
+msgstr ""
+
+#: modules/devices/x86/processor.c:454 modules/devices/x86/processor.c:468
+msgid "Package Information"
+msgstr ""
+
+#. /flag:fpu
+#: modules/devices/x86/x86_data.c:43
+msgctxt "x86-flag"
+msgid "Onboard FPU (floating point support)"
+msgstr ""
+
+#. /flag:vme
+#: modules/devices/x86/x86_data.c:44
+msgctxt "x86-flag"
+msgid "Virtual 8086 mode enhancements"
+msgstr ""
+
+#. /flag:de
+#: modules/devices/x86/x86_data.c:45
+msgctxt "x86-flag"
+msgid "Debugging Extensions (CR4.DE)"
+msgstr ""
+
+#. /flag:pse
+#: modules/devices/x86/x86_data.c:46
+msgctxt "x86-flag"
+msgid "Page Size Extensions (4MB memory pages)"
+msgstr ""
+
+#. /flag:tsc
+#: modules/devices/x86/x86_data.c:47
+msgctxt "x86-flag"
+msgid "Time Stamp Counter (RDTSC)"
+msgstr ""
+
+#. /flag:msr
+#: modules/devices/x86/x86_data.c:48
+msgctxt "x86-flag"
+msgid "Model-Specific Registers (RDMSR, WRMSR)"
+msgstr ""
+
+#. /flag:pae
+#: modules/devices/x86/x86_data.c:49
+msgctxt "x86-flag"
+msgid "Physical Address Extensions (support for more than 4GB of RAM)"
+msgstr ""
+
+#. /flag:mce
+#: modules/devices/x86/x86_data.c:50
+msgctxt "x86-flag"
+msgid "Machine Check Exception"
+msgstr ""
+
+#. /flag:cx8
+#: modules/devices/x86/x86_data.c:51
+msgctxt "x86-flag"
+msgid "CMPXCHG8 instruction (64-bit compare-and-swap)"
+msgstr ""
+
+#. /flag:apic
+#: modules/devices/x86/x86_data.c:52
+msgctxt "x86-flag"
+msgid "Onboard APIC"
+msgstr ""
+
+#. /flag:sep
+#: modules/devices/x86/x86_data.c:53
+msgctxt "x86-flag"
+msgid "SYSENTER/SYSEXIT"
+msgstr ""
+
+#. /flag:mtrr
+#: modules/devices/x86/x86_data.c:54
+msgctxt "x86-flag"
+msgid "Memory Type Range Registers"
+msgstr ""
+
+#. /flag:pge
+#: modules/devices/x86/x86_data.c:55
+msgctxt "x86-flag"
+msgid "Page Global Enable (global bit in PDEs and PTEs)"
+msgstr ""
+
+#. /flag:mca
+#: modules/devices/x86/x86_data.c:56
+msgctxt "x86-flag"
+msgid "Machine Check Architecture"
+msgstr ""
+
+#. /flag:cmov
+#: modules/devices/x86/x86_data.c:57
+msgctxt "x86-flag"
+msgid "CMOV instructions (conditional move) (also FCMOV)"
+msgstr ""
+
+#. /flag:pat
+#: modules/devices/x86/x86_data.c:58
+msgctxt "x86-flag"
+msgid "Page Attribute Table"
+msgstr ""
+
+#. /flag:pse36
+#: modules/devices/x86/x86_data.c:59
+msgctxt "x86-flag"
+msgid "36-bit PSEs (huge pages)"
+msgstr ""
+
+#. /flag:pn
+#: modules/devices/x86/x86_data.c:60
+msgctxt "x86-flag"
+msgid "Processor serial number"
+msgstr ""
+
+#. /flag:clflush
+#: modules/devices/x86/x86_data.c:61
+msgctxt "x86-flag"
+msgid "Cache Line Flush instruction"
+msgstr ""
+
+#. /flag:dts
+#: modules/devices/x86/x86_data.c:62
+msgctxt "x86-flag"
+msgid ""
+"Debug Store (buffer for debugging and profiling instructions), or "
+"alternately: digital thermal sensor"
+msgstr ""
+
+#. /flag:acpi
+#: modules/devices/x86/x86_data.c:63
+msgctxt "x86-flag"
+msgid "ACPI via MSR (temperature monitoring and clock speed modulation)"
+msgstr ""
+
+#. /flag:mmx
+#: modules/devices/x86/x86_data.c:64
+msgctxt "x86-flag"
+msgid "Multimedia Extensions"
+msgstr ""
+
+#. /flag:fxsr
+#: modules/devices/x86/x86_data.c:65
+msgctxt "x86-flag"
+msgid "FXSAVE/FXRSTOR, CR4.OSFXSR"
+msgstr ""
+
+#. /flag:sse
+#: modules/devices/x86/x86_data.c:66
+msgctxt "x86-flag"
+msgid "Intel SSE vector instructions"
+msgstr ""
+
+#. /flag:sse2
+#: modules/devices/x86/x86_data.c:67
+msgctxt "x86-flag"
+msgid "SSE2"
+msgstr ""
+
+#. /flag:ss
+#: modules/devices/x86/x86_data.c:68
+msgctxt "x86-flag"
+msgid "CPU self snoop"
+msgstr ""
+
+#. /flag:ht
+#: modules/devices/x86/x86_data.c:69
+msgctxt "x86-flag"
+msgid "Hyper-Threading"
+msgstr ""
+
+#. /flag:tm
+#: modules/devices/x86/x86_data.c:70
+msgctxt "x86-flag"
+msgid "Automatic clock control (Thermal Monitor)"
+msgstr ""
+
+#. /flag:ia64
+#: modules/devices/x86/x86_data.c:71
+msgctxt "x86-flag"
+msgid ""
+"Intel Itanium Architecture 64-bit (not to be confused with Intel's 64-bit "
+"x86 architecture with flag x86-64 or \"AMD64\" bit indicated by flag lm)"
+msgstr ""
+
+#. /flag:pbe
+#: modules/devices/x86/x86_data.c:72
+msgctxt "x86-flag"
+msgid "Pending Break Enable (PBE# pin) wakeup support"
+msgstr ""
+
+#. /flag:syscall
+#: modules/devices/x86/x86_data.c:75
+msgctxt "x86-flag"
+msgid "SYSCALL (Fast System Call) and SYSRET (Return From Fast System Call)"
+msgstr ""
+
+#. /flag:mp
+#: modules/devices/x86/x86_data.c:76
+msgctxt "x86-flag"
+msgid "Multiprocessing Capable."
+msgstr ""
+
+#. /flag:nx
+#: modules/devices/x86/x86_data.c:77
+msgctxt "x86-flag"
+msgid "Execute Disable"
+msgstr ""
+
+#. /flag:mmxext
+#: modules/devices/x86/x86_data.c:78
+msgctxt "x86-flag"
+msgid "AMD MMX extensions"
+msgstr ""
+
+#. /flag:fxsr_opt
+#: modules/devices/x86/x86_data.c:79
+msgctxt "x86-flag"
+msgid "FXSAVE/FXRSTOR optimizations"
+msgstr ""
+
+#. /flag:pdpe1gb
+#: modules/devices/x86/x86_data.c:80
+msgctxt "x86-flag"
+msgid "One GB pages (allows hugepagesz=1G)"
+msgstr ""
+
+#. /flag:rdtscp
+#: modules/devices/x86/x86_data.c:81
+msgctxt "x86-flag"
+msgid "Read Time-Stamp Counter and Processor ID"
+msgstr ""
+
+#. /flag:lm
+#: modules/devices/x86/x86_data.c:82
+msgctxt "x86-flag"
+msgid "Long Mode (x86-64: amd64, also known as Intel 64, i.e. 64-bit capable)"
+msgstr ""
+
+#. /flag:3dnow
+#: modules/devices/x86/x86_data.c:83
+msgctxt "x86-flag"
+msgid "3DNow! (AMD vector instructions, competing with Intel's SSE1)"
+msgstr ""
+
+#. /flag:3dnowext
+#: modules/devices/x86/x86_data.c:84
+msgctxt "x86-flag"
+msgid "AMD 3DNow! extensions"
+msgstr ""
+
+#. /flag:recovery
+#: modules/devices/x86/x86_data.c:86
+msgctxt "x86-flag"
+msgid "CPU in recovery mode"
+msgstr ""
+
+#. /flag:longrun
+#: modules/devices/x86/x86_data.c:87
+msgctxt "x86-flag"
+msgid "Longrun power control"
+msgstr ""
+
+#. /flag:lrti
+#: modules/devices/x86/x86_data.c:88
+msgctxt "x86-flag"
+msgid "LongRun table interface"
+msgstr ""
+
+#. /flag:cxmmx
+#: modules/devices/x86/x86_data.c:90
+msgctxt "x86-flag"
+msgid "Cyrix MMX extensions"
+msgstr ""
+
+#. /flag:k6_mtrr
+#: modules/devices/x86/x86_data.c:91
+msgctxt "x86-flag"
+msgid "AMD K6 nonstandard MTRRs"
+msgstr ""
+
+#. /flag:cyrix_arr
+#: modules/devices/x86/x86_data.c:92
+msgctxt "x86-flag"
+msgid "Cyrix ARRs (= MTRRs)"
+msgstr ""
+
+#. /flag:centaur_mcr
+#: modules/devices/x86/x86_data.c:93
+msgctxt "x86-flag"
+msgid "Centaur MCRs (= MTRRs)"
+msgstr ""
+
+#. /flag:constant_tsc
+#: modules/devices/x86/x86_data.c:94
+msgctxt "x86-flag"
+msgid "TSC ticks at a constant rate"
+msgstr ""
+
+#. /flag:up
+#: modules/devices/x86/x86_data.c:95
+msgctxt "x86-flag"
+msgid "SMP kernel running on UP"
+msgstr ""
+
+#. /flag:art
+#: modules/devices/x86/x86_data.c:96
+msgctxt "x86-flag"
+msgid "Always-Running Timer"
+msgstr ""
+
+#. /flag:arch_perfmon
+#: modules/devices/x86/x86_data.c:97
+msgctxt "x86-flag"
+msgid "Intel Architectural PerfMon"
+msgstr ""
+
+#. /flag:pebs
+#: modules/devices/x86/x86_data.c:98
+msgctxt "x86-flag"
+msgid "Precise-Event Based Sampling"
+msgstr ""
+
+#. /flag:bts
+#: modules/devices/x86/x86_data.c:99
+msgctxt "x86-flag"
+msgid "Branch Trace Store"
+msgstr ""
+
+#. /flag:rep_good
+#: modules/devices/x86/x86_data.c:100
+msgctxt "x86-flag"
+msgid "rep microcode works well"
+msgstr ""
+
+#. /flag:acc_power
+#: modules/devices/x86/x86_data.c:101
+msgctxt "x86-flag"
+msgid "AMD accumulated power mechanism"
+msgstr ""
+
+#. /flag:nopl
+#: modules/devices/x86/x86_data.c:102
+msgctxt "x86-flag"
+msgid "The NOPL (0F 1F) instructions"
+msgstr ""
+
+#. /flag:xtopology
+#: modules/devices/x86/x86_data.c:103
+msgctxt "x86-flag"
+msgid "cpu topology enum extensions"
+msgstr ""
+
+#. /flag:tsc_reliable
+#: modules/devices/x86/x86_data.c:104
+msgctxt "x86-flag"
+msgid "TSC is known to be reliable"
+msgstr ""
+
+#. /flag:nonstop_tsc
+#: modules/devices/x86/x86_data.c:105
+msgctxt "x86-flag"
+msgid "TSC does not stop in C states"
+msgstr ""
+
+#. /flag:extd_apicid
+#: modules/devices/x86/x86_data.c:106
+msgctxt "x86-flag"
+msgid "has extended APICID (8 bits)"
+msgstr ""
+
+#. /flag:amd_dcm
+#: modules/devices/x86/x86_data.c:107
+msgctxt "x86-flag"
+msgid "multi-node processor"
+msgstr ""
+
+#. /flag:aperfmperf
+#: modules/devices/x86/x86_data.c:108
+msgctxt "x86-flag"
+msgid "APERFMPERF"
+msgstr ""
+
+#. /flag:eagerfpu
+#: modules/devices/x86/x86_data.c:109
+msgctxt "x86-flag"
+msgid "Non lazy FPU restore"
+msgstr ""
+
+#. /flag:nonstop_tsc_s3
+#: modules/devices/x86/x86_data.c:110
+msgctxt "x86-flag"
+msgid "TSC doesn't stop in S3 state"
+msgstr ""
+
+#. /flag:mce_recovery
+#: modules/devices/x86/x86_data.c:111
+msgctxt "x86-flag"
+msgid "CPU has recoverable machine checks"
+msgstr ""
+
+#. /flag:pni
+#: modules/devices/x86/x86_data.c:114
+msgctxt "x86-flag"
+msgid "SSE-3 (\"Prescott New Instructions\")"
+msgstr ""
+
+#. /flag:pclmulqdq
+#: modules/devices/x86/x86_data.c:115
+msgctxt "x86-flag"
+msgid ""
+"Perform a Carry-Less Multiplication of Quadword instruction - accelerator "
+"for GCM)"
+msgstr ""
+
+#. /flag:dtes64
+#: modules/devices/x86/x86_data.c:116
+msgctxt "x86-flag"
+msgid "64-bit Debug Store"
+msgstr ""
+
+#. /flag:monitor
+#: modules/devices/x86/x86_data.c:117
+msgctxt "x86-flag"
+msgid "Monitor/Mwait support (Intel SSE3 supplements)"
+msgstr ""
+
+#. /flag:ds_cpl
+#: modules/devices/x86/x86_data.c:118
+msgctxt "x86-flag"
+msgid "CPL Qual. Debug Store"
+msgstr ""
+
+#. /flag:vmx
+#: modules/devices/x86/x86_data.c:119
+msgctxt "x86-flag"
+msgid "Hardware virtualization, Intel VMX"
+msgstr ""
+
+#. /flag:smx
+#: modules/devices/x86/x86_data.c:120
+msgctxt "x86-flag"
+msgid "Safer mode TXT (TPM support)"
+msgstr ""
+
+#. /flag:est
+#: modules/devices/x86/x86_data.c:121
+msgctxt "x86-flag"
+msgid "Enhanced SpeedStep"
+msgstr ""
+
+#. /flag:tm2
+#: modules/devices/x86/x86_data.c:122
+msgctxt "x86-flag"
+msgid "Thermal Monitor 2"
+msgstr ""
+
+#. /flag:ssse3
+#: modules/devices/x86/x86_data.c:123
+msgctxt "x86-flag"
+msgid "Supplemental SSE-3"
+msgstr ""
+
+#. /flag:cid
+#: modules/devices/x86/x86_data.c:124
+msgctxt "x86-flag"
+msgid "Context ID"
+msgstr ""
+
+#. /flag:sdbg
+#: modules/devices/x86/x86_data.c:125
+msgctxt "x86-flag"
+msgid "silicon debug"
+msgstr ""
+
+#. /flag:fma
+#: modules/devices/x86/x86_data.c:126
+msgctxt "x86-flag"
+msgid "Fused multiply-add"
+msgstr ""
+
+#. /flag:cx16
+#: modules/devices/x86/x86_data.c:127
+msgctxt "x86-flag"
+msgid "CMPXCHG16B"
+msgstr ""
+
+#. /flag:xtpr
+#: modules/devices/x86/x86_data.c:128
+msgctxt "x86-flag"
+msgid "Send Task Priority Messages"
+msgstr ""
+
+#. /flag:pdcm
+#: modules/devices/x86/x86_data.c:129
+msgctxt "x86-flag"
+msgid "Performance Capabilities"
+msgstr ""
+
+#. /flag:pcid
+#: modules/devices/x86/x86_data.c:130
+msgctxt "x86-flag"
+msgid "Process Context Identifiers"
+msgstr ""
+
+#. /flag:dca
+#: modules/devices/x86/x86_data.c:131
+msgctxt "x86-flag"
+msgid "Direct Cache Access"
+msgstr ""
+
+#. /flag:sse4_1
+#: modules/devices/x86/x86_data.c:132
+msgctxt "x86-flag"
+msgid "SSE-4.1"
+msgstr ""
+
+#. /flag:sse4_2
+#: modules/devices/x86/x86_data.c:133
+msgctxt "x86-flag"
+msgid "SSE-4.2"
+msgstr ""
+
+#. /flag:x2apic
+#: modules/devices/x86/x86_data.c:134
+msgctxt "x86-flag"
+msgid "x2APIC"
+msgstr ""
+
+#. /flag:movbe
+#: modules/devices/x86/x86_data.c:135
+msgctxt "x86-flag"
+msgid "Move Data After Swapping Bytes instruction"
+msgstr ""
+
+#. /flag:popcnt
+#: modules/devices/x86/x86_data.c:136
+msgctxt "x86-flag"
+msgid ""
+"Return the Count of Number of Bits Set to 1 instruction (Hamming weight, i."
+"e. bit count)"
+msgstr ""
+
+#. /flag:tsc_deadline_timer
+#: modules/devices/x86/x86_data.c:137
+msgctxt "x86-flag"
+msgid "Tsc deadline timer"
+msgstr ""
+
+#. /flag:aes/aes-ni
+#: modules/devices/x86/x86_data.c:138
+msgctxt "x86-flag"
+msgid "Advanced Encryption Standard (New Instructions)"
+msgstr ""
+
+#. /flag:xsave
+#: modules/devices/x86/x86_data.c:139
+msgctxt "x86-flag"
+msgid "Save Processor Extended States: also provides XGETBY,XRSTOR,XSETBY"
+msgstr ""
+
+#. /flag:avx
+#: modules/devices/x86/x86_data.c:140
+msgctxt "x86-flag"
+msgid "Advanced Vector Extensions"
+msgstr ""
+
+#. /flag:f16c
+#: modules/devices/x86/x86_data.c:141
+msgctxt "x86-flag"
+msgid "16-bit fp conversions (CVT16)"
+msgstr ""
+
+#. /flag:rdrand
+#: modules/devices/x86/x86_data.c:142
+msgctxt "x86-flag"
+msgid "Read Random Number from hardware random number generator instruction"
+msgstr ""
+
+#. /flag:hypervisor
+#: modules/devices/x86/x86_data.c:143
+msgctxt "x86-flag"
+msgid "Running on a hypervisor"
+msgstr ""
+
+#. /Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001
+#. /flag:rng
+#: modules/devices/x86/x86_data.c:145
+msgctxt "x86-flag"
+msgid "Random Number Generator present (xstore)"
+msgstr ""
+
+#. /flag:rng_en
+#: modules/devices/x86/x86_data.c:146
+msgctxt "x86-flag"
+msgid "Random Number Generator enabled"
+msgstr ""
+
+#. /flag:ace
+#: modules/devices/x86/x86_data.c:147
+msgctxt "x86-flag"
+msgid "on-CPU crypto (xcrypt)"
+msgstr ""
+
+#. /flag:ace_en
+#: modules/devices/x86/x86_data.c:148
+msgctxt "x86-flag"
+msgid "on-CPU crypto enabled"
+msgstr ""
+
+#. /flag:ace2
+#: modules/devices/x86/x86_data.c:149
+msgctxt "x86-flag"
+msgid "Advanced Cryptography Engine v2"
+msgstr ""
+
+#. /flag:ace2_en
+#: modules/devices/x86/x86_data.c:150
+msgctxt "x86-flag"
+msgid "ACE v2 enabled"
+msgstr ""
+
+#. /flag:phe
+#: modules/devices/x86/x86_data.c:151
+msgctxt "x86-flag"
+msgid "PadLock Hash Engine"
+msgstr ""
+
+#. /flag:phe_en
+#: modules/devices/x86/x86_data.c:152
+msgctxt "x86-flag"
+msgid "PHE enabled"
+msgstr ""
+
+#. /flag:pmm
+#: modules/devices/x86/x86_data.c:153
+msgctxt "x86-flag"
+msgid "PadLock Montgomery Multiplier"
+msgstr ""
+
+#. /flag:pmm_en
+#: modules/devices/x86/x86_data.c:154
+msgctxt "x86-flag"
+msgid "PMM enabled"
+msgstr ""
+
+#. /flag:lahf_lm
+#: modules/devices/x86/x86_data.c:156
+msgctxt "x86-flag"
+msgid "Load AH from Flags (LAHF) and Store AH into Flags (SAHF) in long mode"
+msgstr ""
+
+#. /flag:cmp_legacy
+#: modules/devices/x86/x86_data.c:157
+msgctxt "x86-flag"
+msgid "If yes HyperThreading not valid"
+msgstr ""
+
+#. /flag:svm
+#: modules/devices/x86/x86_data.c:158
+msgctxt "x86-flag"
+msgid "\"Secure virtual machine\": AMD-V"
+msgstr ""
+
+#. /flag:extapic
+#: modules/devices/x86/x86_data.c:159
+msgctxt "x86-flag"
+msgid "Extended APIC space"
+msgstr ""
+
+#. /flag:cr8_legacy
+#: modules/devices/x86/x86_data.c:160
+msgctxt "x86-flag"
+msgid "CR8 in 32-bit mode"
+msgstr ""
+
+#. /flag:abm
+#: modules/devices/x86/x86_data.c:161
+msgctxt "x86-flag"
+msgid "Advanced Bit Manipulation"
+msgstr ""
+
+#. /flag:sse4a
+#: modules/devices/x86/x86_data.c:162
+msgctxt "x86-flag"
+msgid "SSE-4A"
+msgstr ""
+
+#. /flag:misalignsse
+#: modules/devices/x86/x86_data.c:163
+msgctxt "x86-flag"
+msgid ""
+"indicates if a general-protection exception (#GP) is generated when some "
+"legacy SSE instructions operate on unaligned data. Also depends on CR0 and "
+"Alignment Checking bit"
+msgstr ""
+
+#. /flag:3dnowprefetch
+#: modules/devices/x86/x86_data.c:164
+msgctxt "x86-flag"
+msgid "3DNow prefetch instructions"
+msgstr ""
+
+#. /flag:osvw
+#: modules/devices/x86/x86_data.c:165
+msgctxt "x86-flag"
+msgid ""
+"indicates OS Visible Workaround, which allows the OS to work around "
+"processor errata."
+msgstr ""
+
+#. /flag:ibs
+#: modules/devices/x86/x86_data.c:166
+msgctxt "x86-flag"
+msgid "Instruction Based Sampling"
+msgstr ""
+
+#. /flag:xop
+#: modules/devices/x86/x86_data.c:167
+msgctxt "x86-flag"
+msgid "extended AVX instructions"
+msgstr ""
+
+#. /flag:skinit
+#: modules/devices/x86/x86_data.c:168
+msgctxt "x86-flag"
+msgid "SKINIT/STGI instructions"
+msgstr ""
+
+#. /flag:wdt
+#: modules/devices/x86/x86_data.c:169
+msgctxt "x86-flag"
+msgid "Watchdog timer"
+msgstr ""
+
+#. /flag:lwp
+#: modules/devices/x86/x86_data.c:170
+msgctxt "x86-flag"
+msgid "Light Weight Profiling"
+msgstr ""
+
+#. /flag:fma4
+#: modules/devices/x86/x86_data.c:171
+msgctxt "x86-flag"
+msgid "4 operands MAC instructions"
+msgstr ""
+
+#. /flag:tce
+#: modules/devices/x86/x86_data.c:172
+msgctxt "x86-flag"
+msgid "translation cache extension"
+msgstr ""
+
+#. /flag:nodeid_msr
+#: modules/devices/x86/x86_data.c:173
+msgctxt "x86-flag"
+msgid "NodeId MSR"
+msgstr ""
+
+#. /flag:tbm
+#: modules/devices/x86/x86_data.c:174
+msgctxt "x86-flag"
+msgid "Trailing Bit Manipulation"
+msgstr ""
+
+#. /flag:topoext
+#: modules/devices/x86/x86_data.c:175
+msgctxt "x86-flag"
+msgid "Topology Extensions CPUID leafs"
+msgstr ""
+
+#. /flag:perfctr_core
+#: modules/devices/x86/x86_data.c:176
+msgctxt "x86-flag"
+msgid "Core Performance Counter Extensions"
+msgstr ""
+
+#. /flag:perfctr_nb
+#: modules/devices/x86/x86_data.c:177
+msgctxt "x86-flag"
+msgid "NB Performance Counter Extensions"
+msgstr ""
+
+#. /flag:bpext
+#: modules/devices/x86/x86_data.c:178
+msgctxt "x86-flag"
+msgid "data breakpoint extension"
+msgstr ""
+
+#. /flag:ptsc
+#: modules/devices/x86/x86_data.c:179
+msgctxt "x86-flag"
+msgid "performance time-stamp counter"
+msgstr ""
+
+#. /flag:perfctr_l2
+#: modules/devices/x86/x86_data.c:180
+msgctxt "x86-flag"
+msgid "L2 Performance Counter Extensions"
+msgstr ""
+
+#. /flag:mwaitx
+#: modules/devices/x86/x86_data.c:181
+msgctxt "x86-flag"
+msgid "MWAIT extension (MONITORX/MWAITX)"
+msgstr ""
+
+#. /flag:cpb
+#: modules/devices/x86/x86_data.c:183
+msgctxt "x86-flag"
+msgid "AMD Core Performance Boost"
+msgstr ""
+
+#. /flag:epb
+#: modules/devices/x86/x86_data.c:184
+msgctxt "x86-flag"
+msgid "IA32_ENERGY_PERF_BIAS support"
+msgstr ""
+
+#. /flag:hw_pstate
+#: modules/devices/x86/x86_data.c:185
+msgctxt "x86-flag"
+msgid "AMD HW-PState"
+msgstr ""
+
+#. /flag:proc_feedback
+#: modules/devices/x86/x86_data.c:186
+msgctxt "x86-flag"
+msgid "AMD ProcFeedbackInterface"
+msgstr ""
+
+#. /flag:intel_pt
+#: modules/devices/x86/x86_data.c:187
+msgctxt "x86-flag"
+msgid "Intel Processor Tracing"
+msgstr ""
+
+#. /flag:tpr_shadow
+#: modules/devices/x86/x86_data.c:189
+msgctxt "x86-flag"
+msgid "Intel TPR Shadow"
+msgstr ""
+
+#. /flag:vnmi
+#: modules/devices/x86/x86_data.c:190
+msgctxt "x86-flag"
+msgid "Intel Virtual NMI"
+msgstr ""
+
+#. /flag:flexpriority
+#: modules/devices/x86/x86_data.c:191
+msgctxt "x86-flag"
+msgid "Intel FlexPriority"
+msgstr ""
+
+#. /flag:ept
+#: modules/devices/x86/x86_data.c:192
+msgctxt "x86-flag"
+msgid "Intel Extended Page Table"
+msgstr ""
+
+#. /flag:vpid
+#: modules/devices/x86/x86_data.c:193
+msgctxt "x86-flag"
+msgid "Intel Virtual Processor ID"
+msgstr ""
+
+#. /flag:vmmcall
+#: modules/devices/x86/x86_data.c:194
+msgctxt "x86-flag"
+msgid "prefer VMMCALL to VMCALL"
+msgstr ""
+
+#. /flag:fsgsbase
+#: modules/devices/x86/x86_data.c:196
+msgctxt "x86-flag"
+msgid "{RD/WR}{FS/GS}BASE instructions"
+msgstr ""
+
+#. /flag:tsc_adjust
+#: modules/devices/x86/x86_data.c:197
+msgctxt "x86-flag"
+msgid "TSC adjustment MSR"
+msgstr ""
+
+#. /flag:bmi1
+#: modules/devices/x86/x86_data.c:198
+msgctxt "x86-flag"
+msgid "1st group bit manipulation extensions"
+msgstr ""
+
+#. /flag:hle
+#: modules/devices/x86/x86_data.c:199
+msgctxt "x86-flag"
+msgid "Hardware Lock Elision"
+msgstr ""
+
+#. /flag:avx2
+#: modules/devices/x86/x86_data.c:200
+msgctxt "x86-flag"
+msgid "AVX2 instructions"
+msgstr ""
+
+#. /flag:smep
+#: modules/devices/x86/x86_data.c:201
+msgctxt "x86-flag"
+msgid "Supervisor Mode Execution Protection"
+msgstr ""
+
+#. /flag:bmi2
+#: modules/devices/x86/x86_data.c:202
+msgctxt "x86-flag"
+msgid "2nd group bit manipulation extensions"
+msgstr ""
+
+#. /flag:erms
+#: modules/devices/x86/x86_data.c:203
+msgctxt "x86-flag"
+msgid "Enhanced REP MOVSB/STOSB"
+msgstr ""
+
+#. /flag:invpcid
+#: modules/devices/x86/x86_data.c:204
+msgctxt "x86-flag"
+msgid "Invalidate Processor Context ID"
+msgstr ""
+
+#. /flag:rtm
+#: modules/devices/x86/x86_data.c:205
+msgctxt "x86-flag"
+msgid "Restricted Transactional Memory"
+msgstr ""
+
+#. /flag:cqm
+#: modules/devices/x86/x86_data.c:206
+msgctxt "x86-flag"
+msgid "Cache QoS Monitoring"
+msgstr ""
+
+#. /flag:mpx
+#: modules/devices/x86/x86_data.c:207
+msgctxt "x86-flag"
+msgid "Memory Protection Extension"
+msgstr ""
+
+#. /flag:avx512f
+#: modules/devices/x86/x86_data.c:208
+msgctxt "x86-flag"
+msgid "AVX-512 foundation"
+msgstr ""
+
+#. /flag:avx512dq
+#: modules/devices/x86/x86_data.c:209
+msgctxt "x86-flag"
+msgid "AVX-512 Double/Quad instructions"
+msgstr ""
+
+#. /flag:rdseed
+#: modules/devices/x86/x86_data.c:210
+msgctxt "x86-flag"
+msgid "The RDSEED instruction"
+msgstr ""
+
+#. /flag:adx
+#: modules/devices/x86/x86_data.c:211
+msgctxt "x86-flag"
+msgid "The ADCX and ADOX instructions"
+msgstr ""
+
+#. /flag:smap
+#: modules/devices/x86/x86_data.c:212
+msgctxt "x86-flag"
+msgid "Supervisor Mode Access Prevention"
+msgstr ""
+
+#. /flag:clflushopt
+#: modules/devices/x86/x86_data.c:213
+msgctxt "x86-flag"
+msgid "CLFLUSHOPT instruction"
+msgstr ""
+
+#. /flag:clwb
+#: modules/devices/x86/x86_data.c:214
+msgctxt "x86-flag"
+msgid "CLWB instruction"
+msgstr ""
+
+#. /flag:avx512pf
+#: modules/devices/x86/x86_data.c:215
+msgctxt "x86-flag"
+msgid "AVX-512 Prefetch"
+msgstr ""
+
+#. /flag:avx512er
+#: modules/devices/x86/x86_data.c:216
+msgctxt "x86-flag"
+msgid "AVX-512 Exponential and Reciprocal"
+msgstr ""
+
+#. /flag:avx512cd
+#: modules/devices/x86/x86_data.c:217
+msgctxt "x86-flag"
+msgid "AVX-512 Conflict Detection"
+msgstr ""
+
+#. /flag:sha_ni
+#: modules/devices/x86/x86_data.c:218
+msgctxt "x86-flag"
+msgid "SHA1/SHA256 Instruction Extensions"
+msgstr ""
+
+#. /flag:avx512bw
+#: modules/devices/x86/x86_data.c:219
+msgctxt "x86-flag"
+msgid "AVX-512 Byte/Word instructions"
+msgstr ""
+
+#. /flag:avx512vl
+#: modules/devices/x86/x86_data.c:220
+msgctxt "x86-flag"
+msgid "AVX-512 128/256 Vector Length extensions"
+msgstr ""
+
+#. /flag:xsaveopt
+#: modules/devices/x86/x86_data.c:222
+msgctxt "x86-flag"
+msgid "Optimized XSAVE"
+msgstr ""
+
+#. /flag:xsavec
+#: modules/devices/x86/x86_data.c:223
+msgctxt "x86-flag"
+msgid "XSAVEC"
+msgstr ""
+
+#. /flag:xgetbv1
+#: modules/devices/x86/x86_data.c:224
+msgctxt "x86-flag"
+msgid "XGETBV with ECX = 1"
+msgstr ""
+
+#. /flag:xsaves
+#: modules/devices/x86/x86_data.c:225
+msgctxt "x86-flag"
+msgid "XSAVES/XRSTORS"
+msgstr ""
+
+#. /flag:cqm_llc
+#: modules/devices/x86/x86_data.c:227
+msgctxt "x86-flag"
+msgid "LLC QoS"
+msgstr ""
+
+#. /flag:cqm_occup_llc
+#: modules/devices/x86/x86_data.c:229
+msgctxt "x86-flag"
+msgid "LLC occupancy monitoring"
+msgstr ""
+
+#. /flag:cqm_mbm_total
+#: modules/devices/x86/x86_data.c:230
+msgctxt "x86-flag"
+msgid "LLC total MBM monitoring"
+msgstr ""
+
+#. /flag:cqm_mbm_local
+#: modules/devices/x86/x86_data.c:231
+msgctxt "x86-flag"
+msgid "LLC local MBM monitoring"
+msgstr ""
+
+#. /flag:clzero
+#: modules/devices/x86/x86_data.c:233
+msgctxt "x86-flag"
+msgid "CLZERO instruction"
+msgstr ""
+
+#. /flag:irperf
+#: modules/devices/x86/x86_data.c:234
+msgctxt "x86-flag"
+msgid "instructions retired performance counter"
+msgstr ""
+
+#. /flag:dtherm
+#: modules/devices/x86/x86_data.c:236
+msgctxt "x86-flag"
+msgid "digital thermal sensor"
+msgstr ""
+
+#. /flag:ida
+#: modules/devices/x86/x86_data.c:237
+msgctxt "x86-flag"
+msgid "Intel Dynamic Acceleration"
+msgstr ""
+
+#. /flag:arat
+#: modules/devices/x86/x86_data.c:238
+msgctxt "x86-flag"
+msgid "Always Running APIC Timer"
+msgstr ""
+
+#. /flag:pln
+#: modules/devices/x86/x86_data.c:239
+msgctxt "x86-flag"
+msgid "Intel Power Limit Notification"
+msgstr ""
+
+#. /flag:pts
+#: modules/devices/x86/x86_data.c:240
+msgctxt "x86-flag"
+msgid "Intel Package Thermal Status"
+msgstr ""
+
+#. /flag:hwp
+#: modules/devices/x86/x86_data.c:241
+msgctxt "x86-flag"
+msgid "Intel Hardware P-states"
+msgstr ""
+
+#. /flag:hwp_notify
+#: modules/devices/x86/x86_data.c:242
+msgctxt "x86-flag"
+msgid "HWP notification"
+msgstr ""
+
+#. /flag:hwp_act_window
+#: modules/devices/x86/x86_data.c:243
+msgctxt "x86-flag"
+msgid "HWP Activity Window"
+msgstr ""
+
+#. /flag:hwp_epp
+#: modules/devices/x86/x86_data.c:244
+msgctxt "x86-flag"
+msgid "HWP Energy Performance Preference"
+msgstr ""
+
+#. /flag:hwp_pkg_req
+#: modules/devices/x86/x86_data.c:245
+msgctxt "x86-flag"
+msgid "HWP package-level request"
+msgstr ""
+
+#. /flag:npt
+#: modules/devices/x86/x86_data.c:247
+msgctxt "x86-flag"
+msgid "AMD Nested Page Table support"
+msgstr ""
+
+#. /flag:lbrv
+#: modules/devices/x86/x86_data.c:248
+msgctxt "x86-flag"
+msgid "AMD LBR Virtualization support"
+msgstr ""
+
+#. /flag:svm_lock
+#: modules/devices/x86/x86_data.c:249
+msgctxt "x86-flag"
+msgid "AMD SVM locking MSR"
+msgstr ""
+
+#. /flag:nrip_save
+#: modules/devices/x86/x86_data.c:250
+msgctxt "x86-flag"
+msgid "AMD SVM next_rip save"
+msgstr ""
+
+#. /flag:tsc_scale
+#: modules/devices/x86/x86_data.c:251
+msgctxt "x86-flag"
+msgid "AMD TSC scaling support"
+msgstr ""
+
+#. /flag:vmcb_clean
+#: modules/devices/x86/x86_data.c:252
+msgctxt "x86-flag"
+msgid "AMD VMCB clean bits support"
+msgstr ""
+
+#. /flag:flushbyasid
+#: modules/devices/x86/x86_data.c:253
+msgctxt "x86-flag"
+msgid "AMD flush-by-ASID support"
+msgstr ""
+
+#. /flag:decodeassists
+#: modules/devices/x86/x86_data.c:254
+msgctxt "x86-flag"
+msgid "AMD Decode Assists support"
+msgstr ""
+
+#. /flag:pausefilter
+#: modules/devices/x86/x86_data.c:255
+msgctxt "x86-flag"
+msgid "AMD filtered pause intercept"
+msgstr ""
+
+#. /flag:pfthreshold
+#: modules/devices/x86/x86_data.c:256
+msgctxt "x86-flag"
+msgid "AMD pause filter threshold"
+msgstr ""
+
+#. /flag:avic
+#: modules/devices/x86/x86_data.c:257
+msgctxt "x86-flag"
+msgid "Virtual Interrupt Controller"
+msgstr ""
+
+#. /flag:pku
+#: modules/devices/x86/x86_data.c:259
+msgctxt "x86-flag"
+msgid "Protection Keys for Userspace"
+msgstr ""
+
+#. /flag:ospke
+#: modules/devices/x86/x86_data.c:260
+msgctxt "x86-flag"
+msgid "OS Protection Keys Enable"
+msgstr ""
+
+#. /flag:overflow_recov
+#: modules/devices/x86/x86_data.c:262
+msgctxt "x86-flag"
+msgid "MCA overflow recovery support"
+msgstr ""
+
+#. /flag:succor
+#: modules/devices/x86/x86_data.c:263
+msgctxt "x86-flag"
+msgid "uncorrectable error containment and recovery"
+msgstr ""
+
+#. /flag:smca
+#: modules/devices/x86/x86_data.c:264
+msgctxt "x86-flag"
+msgid "Scalable MCA"
+msgstr ""
+
+#. /bug:f00f
+#: modules/devices/x86/x86_data.c:267
+msgctxt "x86-flag"
+msgid "Intel F00F bug"
+msgstr ""
+
+#. /bug:fdiv
+#: modules/devices/x86/x86_data.c:268
+msgctxt "x86-flag"
+msgid "FPU FDIV"
+msgstr ""
+
+#. /bug:coma
+#: modules/devices/x86/x86_data.c:269
+msgctxt "x86-flag"
+msgid "Cyrix 6x86 coma"
+msgstr ""
+
+#. /bug:tlb_mmatch
+#: modules/devices/x86/x86_data.c:270
+msgctxt "x86-flag"
+msgid "AMD Erratum 383"
+msgstr ""
+
+#. /bug:apic_c1e
+#. /bug:amd_e400
+#: modules/devices/x86/x86_data.c:271 modules/devices/x86/x86_data.c:280
+msgctxt "x86-flag"
+msgid "AMD Erratum 400"
+msgstr ""
+
+#. /bug:11ap
+#: modules/devices/x86/x86_data.c:272
+msgctxt "x86-flag"
+msgid "Bad local APIC aka 11AP"
+msgstr ""
+
+#. /bug:fxsave_leak
+#: modules/devices/x86/x86_data.c:273
+msgctxt "x86-flag"
+msgid "FXSAVE leaks FOP/FIP/FOP"
+msgstr ""
+
+#. /bug:clflush_monitor
+#: modules/devices/x86/x86_data.c:274
+msgctxt "x86-flag"
+msgid "AAI65, CLFLUSH required before MONITOR"
+msgstr ""
+
+#. /bug:sysret_ss_attrs
+#: modules/devices/x86/x86_data.c:275
+msgctxt "x86-flag"
+msgid "SYSRET doesn't fix up SS attrs"
+msgstr ""
+
+#. /bug:espfix
+#: modules/devices/x86/x86_data.c:276
+msgctxt "x86-flag"
+msgid "IRET to 16-bit SS corrupts ESP/RSP high bits"
+msgstr ""
+
+#. /bug:null_seg
+#: modules/devices/x86/x86_data.c:277
+msgctxt "x86-flag"
+msgid "Nulling a selector preserves the base"
+msgstr ""
+
+#. /bug:swapgs_fence
+#: modules/devices/x86/x86_data.c:278
+msgctxt "x86-flag"
+msgid "SWAPGS without input dep on GS"
+msgstr ""
+
+#. /bug:monitor
+#: modules/devices/x86/x86_data.c:279
+msgctxt "x86-flag"
+msgid "IPI required to wake up remote CPU"
+msgstr ""
+
+#. /x86/kernel/cpu/powerflags.h
+#. /flag:pm:ts
+#: modules/devices/x86/x86_data.c:283
+msgctxt "x86-flag"
+msgid "temperature sensor"
+msgstr ""
+
+#. /flag:pm:fid
+#: modules/devices/x86/x86_data.c:284
+msgctxt "x86-flag"
+msgid "frequency id control"
+msgstr ""
+
+#. /flag:pm:vid
+#: modules/devices/x86/x86_data.c:285
+msgctxt "x86-flag"
+msgid "voltage id control"
+msgstr ""
+
+#. /flag:pm:ttp
+#: modules/devices/x86/x86_data.c:286
+msgctxt "x86-flag"
+msgid "thermal trip"
+msgstr ""
+
+#. /flag:pm:tm
+#: modules/devices/x86/x86_data.c:287
+msgctxt "x86-flag"
+msgid "hardware thermal control"
+msgstr ""
+
+#. /flag:pm:stc
+#: modules/devices/x86/x86_data.c:288
+msgctxt "x86-flag"
+msgid "software thermal control"
+msgstr ""
+
+#. /flag:pm:100mhzsteps
+#: modules/devices/x86/x86_data.c:289
+msgctxt "x86-flag"
+msgid "100 MHz multiplier control"
+msgstr ""
+
+#. /flag:pm:hwpstate
+#: modules/devices/x86/x86_data.c:290
+msgctxt "x86-flag"
+msgid "hardware P-state control"
+msgstr ""
+
+#. /flag:pm:cpb
+#: modules/devices/x86/x86_data.c:291
+msgctxt "x86-flag"
+msgid "core performance boost"
+msgstr ""
+
+#. /flag:pm:eff_freq_ro
+#: modules/devices/x86/x86_data.c:292
+msgctxt "x86-flag"
+msgid "Readonly aperf/mperf"
+msgstr ""
+
+#. /flag:pm:proc_feedback
+#: modules/devices/x86/x86_data.c:293
+msgctxt "x86-flag"
+msgid "processor feedback interface"
+msgstr ""
+
+#. /flag:pm:acc_power
+#: modules/devices/x86/x86_data.c:294
+msgctxt "x86-flag"
+msgid "accumulated power mechanism"
+msgstr ""
+
+#: modules/network.c:59
+msgid "Interfaces"
+msgstr "Schnittstellen"
+
+#: modules/network.c:60
+msgid "IP Connections"
+msgstr "IP-Verbindungen"
+
+#: modules/network.c:61
+msgid "Routing Table"
+msgstr "Routing-Tabelle"
+
+#: modules/network.c:62 modules/network.c:303
+msgid "ARP Table"
+msgstr "ARP-Tabelle"
+
+#: modules/network.c:63
+msgid "DNS Servers"
+msgstr "DNS-Server"
+
+#: modules/network.c:64
+msgid "Statistics"
+msgstr "Statistiken"
+
+#: modules/network.c:65
+msgid "Shared Directories"
+msgstr "Freigegebene Verzeichnisse"
+
+#: modules/network.c:304 modules/network.c:326 modules/network.c:357
+#: modules/network/net.c:477
+msgid "IP Address"
+msgstr "IP-Adresse"
+
+#: modules/network.c:304 modules/network.c:357 modules/network.c:374
+msgid "Interface"
+msgstr "Schnittstelle"
+
+#: modules/network.c:304
+msgid "MAC Address"
+msgstr "MAC-Adresse"
+
+#: modules/network.c:313
+msgid "SAMBA"
+msgstr ""
+
+#: modules/network.c:314
+msgid "NFS"
+msgstr ""
+
+#: modules/network.c:325
+msgid "Name Servers"
+msgstr "DNS-Server"
+
+#: modules/network.c:340
+msgid "Connections"
+msgstr ""
+
+#: modules/network.c:341
+msgid "Local Address"
+msgstr "Lokale Adresse"
+
+#: modules/network.c:341
+msgid "Protocol"
+msgstr "Protokoll"
+
+#: modules/network.c:341
+msgid "Foreign Address"
+msgstr "Fremde Adresse"
+
+#: modules/network.c:341
+msgid "State"
+msgstr "Status"
+
+#: modules/network.c:357
+msgid "Sent"
+msgstr "Gesendet"
+
+#: modules/network.c:357
+msgid "Received"
+msgstr "Empfangen"
+
+#: modules/network.c:373
+msgid "IP routing table"
+msgstr ""
+
+#: modules/network.c:374
+msgid "Destination/Gateway"
+msgstr "Ziel/Vorgaberoute"
+
+#: modules/network.c:374
+msgid "Flags"
+msgstr ""
+
+#: modules/network.c:374 modules/network/net.c:478
+msgid "Mask"
+msgstr "Netz-Maske"
+
+#: modules/network.c:402
+msgid "Network"
+msgstr "Netzwerk"
+
+#: modules/network.c:435
+msgid "Gathers information about this computer's network connection"
+msgstr "Sammelt Informationen über die Netzwerk-Verbindung dieses Computers"
+
+#: modules/network/net.c:72
+msgctxt "wi-op-mode"
+msgid "Auto"
+msgstr ""
+
+#: modules/network/net.c:73
+msgctxt "wi-op-mode"
+msgid "Ad-Hoc"
+msgstr ""
+
+#: modules/network/net.c:74
+msgctxt "wi-op-mode"
+msgid "Managed"
+msgstr ""
+
+#: modules/network/net.c:75
+msgctxt "wi-op-mode"
+msgid "Master"
+msgstr ""
+
+#: modules/network/net.c:76
+msgctxt "wi-op-mode"
+msgid "Repeater"
+msgstr ""
+
+#: modules/network/net.c:77
+msgctxt "wi-op-mode"
+msgid "Secondary"
+msgstr ""
+
+#: modules/network/net.c:78
+msgctxt "wi-op-mode"
+msgid "(Unknown)"
+msgstr ""
+
+#: modules/network/net.c:242 modules/network/net.c:262
+#: modules/network/net.c:270
+msgctxt "net-if-type"
+msgid "Ethernet"
+msgstr ""
+
+#: modules/network/net.c:243
+msgctxt "net-if-type"
+msgid "Loopback"
+msgstr ""
+
+#: modules/network/net.c:244
+msgctxt "net-if-type"
+msgid "Point-to-Point"
+msgstr ""
+
+#: modules/network/net.c:245 modules/network/net.c:246
+#: modules/network/net.c:247 modules/network/net.c:248
+#: modules/network/net.c:272
+msgctxt "net-if-type"
+msgid "Wireless"
+msgstr ""
+
+#: modules/network/net.c:249
+msgctxt "net-if-type"
+msgid "Virtual Point-to-Point (TUN)"
+msgstr ""
+
+#: modules/network/net.c:250
+msgctxt "net-if-type"
+msgid "Ethernet (TAP)"
+msgstr ""
+
+#: modules/network/net.c:251
+msgctxt "net-if-type"
+msgid "Parallel Line Internet Protocol"
+msgstr ""
+
+#: modules/network/net.c:252
+msgctxt "net-if-type"
+msgid "Infrared"
+msgstr ""
+
+#: modules/network/net.c:253 modules/network/net.c:271
+msgctxt "net-if-type"
+msgid "Serial Line Internet Protocol"
+msgstr ""
+
+#: modules/network/net.c:254
+msgctxt "net-if-type"
+msgid "Integrated Services Digital Network"
+msgstr ""
+
+#: modules/network/net.c:255
+msgctxt "net-if-type"
+msgid "IPv6-over-IPv4 Tunnel"
+msgstr ""
+
+#: modules/network/net.c:256
+msgctxt "net-if-type"
+msgid "VMWare Virtual Network Interface (NAT)"
+msgstr ""
+
+#: modules/network/net.c:257
+msgctxt "net-if-type"
+msgid "VMWare Virtual Network Interface"
+msgstr ""
+
+#: modules/network/net.c:258
+msgctxt "net-if-type"
+msgid "Personal Area Network (PAN)"
+msgstr ""
+
+#: modules/network/net.c:259
+msgctxt "net-if-type"
+msgid "Bluetooth"
+msgstr ""
+
+#: modules/network/net.c:260
+msgctxt "net-if-type"
+msgid "Bridge Interface"
+msgstr ""
+
+#: modules/network/net.c:261
+msgctxt "net-if-type"
+msgid "Hamachi Virtual Personal Network"
+msgstr ""
+
+#: modules/network/net.c:263
+msgctxt "net-if-type"
+msgid "Intermediate Functional Block"
+msgstr ""
+
+#: modules/network/net.c:264
+msgctxt "net-if-type"
+msgid "GRE Network Tunnel"
+msgstr ""
+
+#: modules/network/net.c:265
+msgctxt "net-if-type"
+msgid "Mesh Network"
+msgstr ""
+
+#: modules/network/net.c:266
+msgctxt "net-if-type"
+msgid "Wireless Master Interface"
+msgstr ""
+
+#: modules/network/net.c:267
+msgctxt "net-if-type"
+msgid "VirtualBox Virtual Network Interface"
+msgstr ""
+
+#: modules/network/net.c:273
+msgctxt "net-if-type"
+msgid "Wireless (WAN)"
+msgstr ""
+
+#: modules/network/net.c:275
+msgctxt "net-if-type"
+msgid "(Unknown)"
+msgstr ""
+
+#: modules/network/net.c:348 modules/network/net.c:358
+msgid "Network Interfaces"
+msgstr ""
+
+#: modules/network/net.c:348
+msgid "None Found"
+msgstr ""
+
+#: modules/network/net.c:400 modules/network/net.c:422
+#: modules/network/net.c:423
+msgid "MiB"
+msgstr ""
+
+#: modules/network/net.c:414
+msgid "Network Adapter Properties"
+msgstr ""
+
+#: modules/network/net.c:415
+msgid "Interface Type"
+msgstr ""
+
+#: modules/network/net.c:416
+msgid "Hardware Address (MAC)"
+msgstr ""
+
+#: modules/network/net.c:420
+msgid "MTU"
+msgstr ""
+
+#: modules/network/net.c:421
+msgid "Transfer Details"
+msgstr ""
+
+#: modules/network/net.c:422
+msgid "Bytes Received"
+msgstr ""
+
+#: modules/network/net.c:423
+msgid "Bytes Sent"
+msgstr ""
+
+#: modules/network/net.c:440 modules/network/net.c:462
+#: modules/network/net.c:463
+msgid "dBm"
+msgstr ""
+
+#: modules/network/net.c:440
+msgid "mW"
+msgstr ""
+
+#: modules/network/net.c:454
+msgid "Wireless Properties"
+msgstr ""
+
+#: modules/network/net.c:455
+msgid "Network Name (SSID)"
+msgstr ""
+
+#: modules/network/net.c:456
+msgid "Bit Rate"
+msgstr ""
+
+#: modules/network/net.c:456
+msgid "Mb/s"
+msgstr ""
+
+#: modules/network/net.c:457
+msgid "Transmission Power"
+msgstr ""
+
+#: modules/network/net.c:459
+msgid "Status"
+msgstr ""
+
+#: modules/network/net.c:460
+msgid "Link Quality"
+msgstr ""
+
+#: modules/network/net.c:461
+msgid "Signal / Noise"
+msgstr ""
+
+#: modules/network/net.c:476
+msgid "Internet Protocol (IPv4)"
+msgstr ""
+
+#: modules/network/net.c:477 modules/network/net.c:478
+#: modules/network/net.c:480
+msgid "(Not set)"
+msgstr ""
+
+#: modules/network/net.c:479
+msgid "Broadcast Address"
+msgstr ""
+
+#~ msgid "CPU Clock"
+#~ msgstr "CPU-Takt"
+
+#~ msgid "Desktop Environment"
+#~ msgstr "Desktop-Umgebung"
+
+#~ msgid "%s$CPU%d$%s=%.2fMHz\n"
+#~ msgstr "%s$CPU%d$%s=%.2fMHz\n"
diff --git a/po/es.po b/po/es.po
new file mode 100644
index 0000000..ddef4a7
--- /dev/null
+++ b/po/es.po
@@ -0,0 +1,4467 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: hardinfo\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2017-08-14 22:23-0500\n"
+"PO-Revision-Date: 2017-08-04 00:00-0430\n"
+"Last-Translator: PICCORO Lenz McKAY <mckaygerhard@gmail.com>\n"
+"Language-Team: Fernando López <soportelihuen@linti.unlp.edu.ar>\n"
+"Language: es\n"
+"X-Poedit-Basepath: ../\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Spanish\n"
+
+#. / %d will be latest year of copyright
+#: hardinfo/hardinfo.c:49
+#, c-format
+msgid ""
+"Copyright (C) 2003-%d Leandro A. F. Pereira. See COPYING for details.\n"
+"\n"
+msgstr ""
+"Copyright (C) 2003-%d Leandro A. F. Pereira. Vea COPYING para más detalles.\n"
+"\n"
+
+#: hardinfo/hardinfo.c:51
+#, c-format
+msgid ""
+"Compile-time options:\n"
+"  Release version:   %s (%s)\n"
+"  BinReloc enabled:  %s\n"
+"  Data prefix:       %s\n"
+"  Library prefix:    %s\n"
+"  Compiled for:      %s\n"
+msgstr ""
+"Opciones de compilado:\n"
+"  \"Release\" versión:      %s (%s)\n"
+"  BinReloc habilitado:    %s\n"
+"  Prefijo de datos:       %s\n"
+"  Prefijo de bibliotecas: %s\n"
+"  Compilado en:           %s\n"
+
+#: hardinfo/hardinfo.c:57 hardinfo/hardinfo.c:58 modules/computer.c:605
+#: modules/devices/inputdevices.c:128 modules/devices/pci.c:112
+#: modules/devices/printers.c:138
+msgid "Yes"
+msgstr "Sí"
+
+#: hardinfo/hardinfo.c:58 modules/computer.c:605 modules/devices/pci.c:112
+#: modules/devices/printers.c:138
+msgid "No"
+msgstr "_No"
+
+#: hardinfo/hardinfo.c:69
+#, c-format
+msgid ""
+"Failed to find runtime data.\n"
+"\n"
+"• Is HardInfo correctly installed?\n"
+"• See if %s and %s exists and you have read permission."
+msgstr ""
+"Falló en encontrar datos del programa.\n"
+"\n"
+"• ¿HardInfo está correctamente instalado?\n"
+"• Vea si %s y %s existen y tenga accesos para lectura."
+
+#: hardinfo/hardinfo.c:76
+#, c-format
+msgid ""
+"Modules:\n"
+"%-20s %-15s %-12s\n"
+msgstr ""
+"Módulos:\n"
+"%-20s %-15s %-12s\n"
+
+#: hardinfo/hardinfo.c:77
+msgid "File Name"
+msgstr "Nombre de archivo"
+
+#: hardinfo/hardinfo.c:77 modules/computer.c:534 modules/computer.c:562
+#: modules/computer.c:630 modules/computer/languages.c:104
+#: modules/computer/modules.c:146 modules/devices/arm/processor.c:336
+#: modules/devices/ia64/processor.c:160 modules/devices/inputdevices.c:116
+#: modules/devices/pci.c:215 modules/devices/sh/processor.c:84
+#: modules/devices/x86/processor.c:455 modules/network.c:326
+msgid "Name"
+msgstr "Nombre"
+
+#: hardinfo/hardinfo.c:77 modules/computer.c:296 modules/computer.c:505
+#: modules/computer.c:507 modules/computer.c:595 modules/computer.c:603
+#: modules/devices/inputdevices.c:121
+msgid "Version"
+msgstr "Versión"
+
+#: hardinfo/hardinfo.c:124
+#, c-format
+msgid "Unknown benchmark ``%s'' or libbenchmark.so not loaded"
+msgstr "Benchmark desconocido ``%s'' o no se cargó libbenchmark.so"
+
+#: hardinfo/hardinfo.c:152
+msgid "Don't know what to do. Exiting."
+msgstr "No se puede determinar que hacer. Saliendo."
+
+#: hardinfo/util.c:104 modules/computer/uptime.c:53
+#, c-format
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] "%d día"
+msgstr[1] "%d días"
+
+#: hardinfo/util.c:105 modules/computer/uptime.c:54
+#, c-format
+msgid "%d hour"
+msgid_plural "%d hours"
+msgstr[0] "%d hora"
+msgstr[1] "%d horas"
+
+#: hardinfo/util.c:106 modules/computer/uptime.c:55
+#, c-format
+msgid "%d minute"
+msgid_plural "%d minutes"
+msgstr[0] "%d minuto"
+msgstr[1] "%d minutos"
+
+#: hardinfo/util.c:107
+#, c-format
+msgid "%d second"
+msgid_plural "%d seconds"
+msgstr[0] "%d segundo"
+msgstr[1] "%d segundos"
+
+#: hardinfo/util.c:128
+#, c-format
+msgid "%.1f B"
+msgstr "%.1f B"
+
+#: hardinfo/util.c:130
+#, c-format
+msgid "%.1f KiB"
+msgstr "%.1f KiB"
+
+#: hardinfo/util.c:132
+#, c-format
+msgid "%.1f MiB"
+msgstr "%.1f MiB"
+
+#: hardinfo/util.c:134
+#, c-format
+msgid "%.1f GiB"
+msgstr "%.1f GiB"
+
+#: hardinfo/util.c:136
+#, c-format
+msgid "%.1f TiB"
+msgstr "%.1f TiB"
+
+#: hardinfo/util.c:138
+#, c-format
+msgid "%.1f PiB"
+msgstr "%.1f PiB"
+
+#: hardinfo/util.c:361
+msgid "Error"
+msgstr "Error"
+
+#: hardinfo/util.c:361 hardinfo/util.c:377
+msgid "Warning"
+msgstr "Advertencia"
+
+#: hardinfo/util.c:376
+msgid "Fatal Error"
+msgstr "Error fatal"
+
+#: hardinfo/util.c:401
+msgid "creates a report and prints to standard output"
+msgstr "crea un reporte y lo imprime en la salida estándar"
+
+#: hardinfo/util.c:407
+msgid "chooses a report format (text, html)"
+msgstr "elige un formato para el reporte (texto, html)"
+
+#: hardinfo/util.c:413
+msgid "run benchmark; requires benchmark.so to be loaded"
+msgstr "correr benchmark; requiere benchmark.so para ser cargado"
+
+#: hardinfo/util.c:419
+msgid "lists modules"
+msgstr "lista los módulos"
+
+#: hardinfo/util.c:425
+msgid "specify module to load"
+msgstr "especificar módulo a cargar"
+
+#: hardinfo/util.c:431
+msgid "automatically load module dependencies"
+msgstr "cargar automáticamente las dependencias de los módulos"
+
+#: hardinfo/util.c:438
+msgid "run in XML-RPC server mode"
+msgstr "correr en modo servidor XML-RPC"
+
+#: hardinfo/util.c:445
+msgid "shows program version and quit"
+msgstr "muestra la versión del programa y sale"
+
+#: hardinfo/util.c:450
+msgid "- System Profiler and Benchmark tool"
+msgstr "- Analizador de sistema y herramienta de benchmark"
+
+#: hardinfo/util.c:460
+#, c-format
+msgid ""
+"Unrecognized arguments.\n"
+"Try ``%s --help'' for more information.\n"
+msgstr ""
+"Argumentos no reconocidos.\n"
+"Intente ``%s --help'' para más información.\n"
+
+#: hardinfo/util.c:526
+#, c-format
+msgid "Couldn't find a Web browser to open URL %s."
+msgstr "No se pudo encontrar un navegador Web para abrir la URL %s."
+
+#: hardinfo/util.c:875
+#, c-format
+msgid "Module \"%s\" depends on module \"%s\", load it?"
+msgstr "El módulo \"%s\" depende del módulo \"%s\", ¿desea cargarlo?"
+
+#: hardinfo/util.c:898
+#, c-format
+msgid "Module \"%s\" depends on module \"%s\"."
+msgstr "El módulo \"%s\" depende del módulo \"%s\"."
+
+#: hardinfo/util.c:943
+#, c-format
+msgid "No module could be loaded. Check permissions on \"%s\" and try again."
+msgstr ""
+"No se puede cargar ningún módulo. Verifique los permisos en \"%s\" y pruebe "
+"de nuevo."
+
+#: hardinfo/util.c:947
+msgid ""
+"No module could be loaded. Please use hardinfo -l to list all available "
+"modules and try again with a valid module list."
+msgstr ""
+"No se pudo cargar ningún módulo. Por favor use hardinfo -l para listar "
+"todoslos módulos disponibles e intente de nuevo con una lista válida de "
+"módulos."
+
+#: hardinfo/util.c:1024
+#, c-format
+msgid "Scanning: %s..."
+msgstr "Escaneando: %s..."
+
+#: hardinfo/util.c:1034 shell/shell.c:301 shell/shell.c:760 shell/shell.c:1795
+#: modules/benchmark.c:449 modules/benchmark.c:457
+msgid "Done."
+msgstr "Hecho."
+
+#: shell/callbacks.c:117
+#, c-format
+msgid "%s Module"
+msgstr "%s módulo"
+
+#: shell/callbacks.c:128
+#, c-format
+msgid ""
+"Written by %s\n"
+"Licensed under %s"
+msgstr ""
+"Escrito por %s\n"
+"Licencia bajo %s"
+
+#: shell/callbacks.c:142
+#, c-format
+msgid "No about information is associated with the %s module."
+msgstr "No hay información \"acerca de\" asociada al módulo %s."
+
+#: shell/callbacks.c:158
+msgid "Author:"
+msgstr "Autor:"
+
+#: shell/callbacks.c:161
+msgid "Contributors:"
+msgstr "Contribuyentes:"
+
+#: shell/callbacks.c:166
+msgid "Based on work by:"
+msgstr "Basado en el trabajo de:"
+
+#: shell/callbacks.c:167
+msgid "MD5 implementation by Colin Plumb (see md5.c for details)"
+msgstr "Implementación de MD5 por Colin Plumb (ver md5.c para detalles)"
+
+#: shell/callbacks.c:168
+msgid "SHA1 implementation by Steve Reid (see sha1.c for details)"
+msgstr "Implementación de SHA1 por Steve Reid (ver sha1.c para detalles)"
+
+#: shell/callbacks.c:169
+msgid "Blowfish implementation by Paul Kocher (see blowfich.c for details)"
+msgstr ""
+"Implementación de Blowfish por Paul Kocher (ver blowfich.c para detalles)"
+
+#: shell/callbacks.c:170
+msgid "Raytracing benchmark by John Walker (see fbench.c for details)"
+msgstr ""
+"Benchmark de trazado de rayos por John Walker (ver fbench.c para detalles)"
+
+#: shell/callbacks.c:171
+msgid "FFT benchmark by Scott Robert Ladd (see fftbench.c for details)"
+msgstr "Benchmark  de FFT por Scott Robert Ladd (ver fftbench.c para detalles)"
+
+#: shell/callbacks.c:172
+msgid "Some code partly based on x86cpucaps by Osamu Kayasono"
+msgstr "Parte del código parcialmente basado en x86cpucaps por Osamu Kayasono"
+
+#: shell/callbacks.c:173
+msgid "Vendor list based on GtkSysInfo by Pissens Sebastien"
+msgstr "Lista de proveedores basada en GtkSysInfo por Pissens Sebastien"
+
+#: shell/callbacks.c:174
+msgid "DMI support based on code by Stewart Adam"
+msgstr "Soporte DMI basado en código de Stewart Adam"
+
+#: shell/callbacks.c:175
+msgid "SCSI support based on code by Pascal F. Martin"
+msgstr "Soporte SCSI basado en código de Pascal F. Martin"
+
+#: shell/callbacks.c:180
+msgid "Tango Project"
+msgstr "Proyecto Tango"
+
+#: shell/callbacks.c:181
+msgid "The GNOME Project"
+msgstr "El proyecto GNOME"
+
+#: shell/callbacks.c:182
+msgid "VMWare, Inc. (USB icon from VMWare Workstation 6)"
+msgstr "VMWare, Inc. (icono USB de VMWare Workstation 6)"
+
+#: shell/callbacks.c:200
+msgid "System information and benchmark tool"
+msgstr "Herramienta de Informacion y Pruebas del Sistema"
+
+#: shell/callbacks.c:205
+msgid ""
+"HardInfo is free software; you can redistribute it and/or modify it under "
+"the terms of the GNU General Public License as published by the Free "
+"Software Foundation, version 2.\n"
+"\n"
+"This program is distributed in the hope that it will be useful, but WITHOUT "
+"ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
+"FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for "
+"more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License along with "
+"this program; if not, write to the Free Software Foundation, Inc., 51 "
+"Franklin St, Fifth Floor, Boston, MA  02110-1301 USA"
+msgstr ""
+
+#: shell/callbacks.c:220
+msgid "translator-credits"
+msgstr ""
+
+#: shell/menu.c:35
+msgid "_Information"
+msgstr "_Información"
+
+#: shell/menu.c:36
+msgid "_Remote"
+msgstr "_Remoto"
+
+#: shell/menu.c:37
+msgid "_View"
+msgstr "_Ver"
+
+#: shell/menu.c:38
+msgid "_Help"
+msgstr "_Ayuda"
+
+#: shell/menu.c:39
+msgid "About _Modules"
+msgstr "Acerca de los _módulos"
+
+#: shell/menu.c:43
+msgid "Generate _Report"
+msgstr "Generar _reporte"
+
+#: shell/menu.c:48
+msgid "_Network Updater..."
+msgstr "_Actualizador por red..."
+
+#: shell/menu.c:53
+msgid "_Open..."
+msgstr "_Abrir..."
+
+#: shell/menu.c:58
+msgid "_Copy to Clipboard"
+msgstr "_Copiar al portapapeles"
+
+#: shell/menu.c:59
+msgid "Copy to clipboard"
+msgstr "Copiar al portapapeles"
+
+#: shell/menu.c:63
+msgid "_Refresh"
+msgstr "_Refrescar"
+
+#: shell/menu.c:68
+msgid "_Open HardInfo Web Site"
+msgstr "_Abrir sitio web de Hardinfo"
+
+#: shell/menu.c:73
+msgid "_Report bug"
+msgstr "_Reportar un error"
+
+#: shell/menu.c:78
+msgid "_About HardInfo"
+msgstr "_Acerca de Hardinfo"
+
+#: shell/menu.c:79
+msgid "Displays program version information"
+msgstr "Muestra la información de versión del programa"
+
+#: shell/menu.c:83
+msgid "_Quit"
+msgstr "_Salir"
+
+#: shell/menu.c:90
+msgid "_Side Pane"
+msgstr "_Panel lateral"
+
+#: shell/menu.c:91
+msgid "Toggles side pane visibility"
+msgstr "Cambia la visibilidad del panel lateral"
+
+#: shell/menu.c:94
+msgid "_Toolbar"
+msgstr "_Barra de herramientas"
+
+#: shell/report.c:494 shell/report.c:502
+msgid "Save File"
+msgstr "Guardar archivo"
+
+#: shell/report.c:629
+msgid "Cannot create ReportContext. Programming bug?"
+msgstr "No se puede crear ReportContext. ¿Error del programa?"
+
+#: shell/report.c:648
+msgid "Open the report with your web browser?"
+msgstr "¿Abrir el reporte en el navegador web?"
+
+#: shell/report.c:682
+msgid "Generating report..."
+msgstr "Generando reporte..."
+
+#: shell/report.c:692
+msgid "Report saved."
+msgstr "Reporte guardado."
+
+#: shell/report.c:694
+msgid "Error while creating the report."
+msgstr "Error creando el reporte."
+
+#: shell/report.c:796
+msgid "Generate Report"
+msgstr "Generar reporte"
+
+#: shell/report.c:821
+msgid ""
+"<big><b>Generate Report</b></big>\n"
+"Please choose the information that you wish to view in your report:"
+msgstr ""
+"<big><b>Generar reporte</b></big>\n"
+"Por favor elija la información que desea ver en el reporte:"
+
+#: shell/report.c:893
+msgid "Select _None"
+msgstr "_Deseleccionar todo"
+
+#: shell/report.c:904
+msgid "Select _All"
+msgstr "_Seleccionar todo"
+
+#: shell/report.c:929 shell/syncmanager.c:748
+msgid "_Cancel"
+msgstr "_Cancelar"
+
+#: shell/report.c:939
+msgid "_Generate"
+msgstr "_Generar"
+
+#: shell/shell.c:402
+#, c-format
+msgid "%s - System Information"
+msgstr "%s - Información del sistema"
+
+#: shell/shell.c:407
+msgid "System Information"
+msgstr "Información del sistema"
+
+#: shell/shell.c:747
+msgid "Loading modules..."
+msgstr "Cargando módulos..."
+
+#: shell/shell.c:1660
+#, c-format
+msgid "<b>%s → Summary</b>"
+msgstr "<b>%s → Resumen</b>"
+
+#: shell/shell.c:1769
+msgid "Updating..."
+msgstr "Actualizando..."
+
+#: shell/syncmanager.c:69
+msgid ""
+"<big><b>Synchronize with Central Database</b></big>\n"
+"The following information may be synchronized with the HardInfo central "
+"database."
+msgstr ""
+"<big><b>Sincronizar con base de datos central</b></big>\n"
+"La siguiente información puede ser sincronizada con la base de datos central "
+"de Hardinfo."
+
+#: shell/syncmanager.c:72
+msgid ""
+"<big><b>Synchronizing</b></big>\n"
+"This may take some time."
+msgstr ""
+"<big><b>Sincronizando</b></big>\n"
+"Esto puede tomar algún tiempo."
+
+#: shell/syncmanager.c:132
+msgid ""
+"HardInfo was compiled without libsoup support. (Network Updater requires it.)"
+msgstr ""
+"HardInfo fue compilado sin soporte libsoup. (El actualizador por red lo "
+"requiere.)"
+
+#: shell/syncmanager.c:161 shell/syncmanager.c:189
+#, c-format
+msgid "%s (error #%d)"
+msgstr "%s (error #%d)"
+
+#: shell/syncmanager.c:170 shell/syncmanager.c:198
+msgid "Could not parse XML-RPC response"
+msgstr "No se pudo procesar la respuesta XML-RPC"
+
+#: shell/syncmanager.c:280
+#, c-format
+msgid ""
+"Server says it supports API version %d, but this version of HardInfo only "
+"supports API version %d."
+msgstr ""
+"El servidor dice que soporta la versión de la API %d, pero esta versión de "
+"HardInfo solo soporta la versión de la API %d."
+
+#: shell/syncmanager.c:375
+msgid "Contacting HardInfo Central Database"
+msgstr "Contactando base de datos central de Hardinfo"
+
+#: shell/syncmanager.c:376
+msgid "Cleaning up"
+msgstr "Limpiando"
+
+#: shell/syncmanager.c:493
+msgid "(canceled)"
+msgstr "(cancelado)"
+
+#: shell/syncmanager.c:510
+msgid "(failed)"
+msgstr "(falló)"
+
+#: shell/syncmanager.c:521
+#, c-format
+msgid ""
+"Failed while performing \"%s\". Please file a bug report if this problem "
+"persists. (Use the Help→Report bug option.)\n"
+"\n"
+"Details: %s"
+msgstr ""
+"Falló realizando \"%s\". Por favor reporte el error si este problema "
+"persiste. (Use la opción Ayuda→Reportar error.)\n"
+"\n"
+"Detalles: %s"
+
+#: shell/syncmanager.c:530
+#, c-format
+msgid ""
+"Failed while performing \"%s\". Please file a bug report if this problem "
+"persists. (Use the Help→Report bug option.)"
+msgstr ""
+"Falló realizando \"%s\". Por favor reporte el error si este problema "
+"persiste. (Use la opción Ayuda→Reportar error.)"
+
+#: shell/syncmanager.c:658
+msgid "Network Updater"
+msgstr "Actualizador por red"
+
+#: shell/syncmanager.c:757
+msgid "_Synchronize"
+msgstr "_Sincronizar"
+
+#: modules/benchmark.c:52
+msgid "CPU Blowfish"
+msgstr ""
+
+#: modules/benchmark.c:53
+msgid "CPU CryptoHash"
+msgstr ""
+
+#: modules/benchmark.c:54
+msgid "CPU Fibonacci"
+msgstr ""
+
+#: modules/benchmark.c:55
+msgid "CPU N-Queens"
+msgstr "CPU N-Reinas"
+
+#: modules/benchmark.c:56
+msgid "CPU Zlib"
+msgstr "CPU Zlib"
+
+#: modules/benchmark.c:57
+msgid "FPU FFT"
+msgstr "FPU FFT"
+
+#: modules/benchmark.c:58
+msgid "FPU Raytracing"
+msgstr "FPU trazado de rayos"
+
+#: modules/benchmark.c:60
+msgid "GPU Drawing"
+msgstr "GPU dibujado"
+
+#: modules/benchmark.c:239 modules/benchmark.c:255
+msgid "CPU Config"
+msgstr ""
+
+#: modules/benchmark.c:239 modules/benchmark.c:255
+msgid "Results"
+msgstr "Resultados"
+
+#: modules/benchmark.c:239 modules/benchmark.c:255 modules/computer.c:751
+#: modules/devices/sparc/processor.c:75
+msgid "CPU"
+msgstr "CPU"
+
+#: modules/benchmark.c:381
+#, c-format
+msgid "Benchmarking: <b>%s</b>."
+msgstr "Ejecutando benchmark: <b>%s</b>."
+
+#: modules/benchmark.c:395
+msgid "Benchmarking. Please do not move your mouse or press any keys."
+msgstr "Ejecutando benchmarks. Por favor no mueva el mouse ni use el teclado."
+
+#: modules/benchmark.c:399
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: modules/benchmark.c:536
+msgid "Results in MiB/second. Higher is better."
+msgstr "Resultados en MiB/segundo. Más alto es mejor."
+
+#: modules/benchmark.c:540
+msgid "Results in HIMarks. Higher is better."
+msgstr "Resultados en HIMarks. Más alto es mejor."
+
+#: modules/benchmark.c:547
+msgid "Results in seconds. Lower is better."
+msgstr "Resultados en segundos. Más bajo es mejor."
+
+#: modules/benchmark.c:555
+msgid "Benchmarks"
+msgstr "Benchmarks"
+
+#: modules/benchmark.c:573
+msgid "Perform tasks and compare with other systems"
+msgstr "Realizar tareas y comparar con otros sistemas"
+
+#: modules/benchmark.c:663
+msgid "Send benchmark results"
+msgstr "Enviar resultados de los benchmark"
+
+#: modules/benchmark.c:668
+msgid "Receive benchmark results"
+msgstr "Recibir resultados de los benchmark"
+
+#: modules/computer/alsa.c:26 modules/computer.c:489
+msgid "Audio Devices"
+msgstr "Dispositivos de audio"
+
+#: modules/computer/alsa.c:34
+msgid "Audio Adapter"
+msgstr "Adaptador de audio"
+
+#: modules/computer/boots.c:33 modules/computer.c:73 modules/computer.c:546
+msgid "Boots"
+msgstr "Arranques"
+
+#: modules/computer.c:70
+msgid "Summary"
+msgstr "Resumen"
+
+#: modules/computer.c:71 modules/computer.c:476 modules/computer.c:750
+msgid "Operating System"
+msgstr "Sistema operativo"
+
+#: modules/computer.c:72
+msgid "Kernel Modules"
+msgstr "Módulos del kernel"
+
+#: modules/computer.c:74
+msgid "Languages"
+msgstr "Idiomas"
+
+#: modules/computer.c:75
+msgid "Filesystems"
+msgstr "Sistemas de archivos"
+
+#: modules/computer.c:76 modules/computer.c:481 modules/computer.c:590
+msgid "Display"
+msgstr "Pantalla"
+
+#: modules/computer.c:77 modules/computer/environment.c:32
+msgid "Environment Variables"
+msgstr "Variables de entorno"
+
+#: modules/computer.c:79
+msgid "Development"
+msgstr "Desarrollo"
+
+#: modules/computer.c:81 modules/computer.c:617
+msgid "Users"
+msgstr "Usuarios"
+
+#: modules/computer.c:82
+msgid "Groups"
+msgstr "Grupos"
+
+#: modules/computer.c:104 modules/computer.c:473 modules/devices.c:96
+#: modules/devices/pci.c:149
+msgid "Memory"
+msgstr "Memoria"
+
+#: modules/computer.c:106
+#, c-format
+msgid "%dMB (%dMB used)"
+msgstr "%dMB (%dMB usados)"
+
+#: modules/computer.c:108 modules/computer.c:520
+msgid "Uptime"
+msgstr "Activo"
+
+#: modules/computer.c:110 modules/computer.c:478
+msgid "Date/Time"
+msgstr "Fecha/Hora"
+
+#: modules/computer.c:115 modules/computer.c:521
+msgid "Load Average"
+msgstr "Promedio de carga"
+
+#: modules/computer.c:117 modules/computer.c:522
+msgid "Available entropy in /dev/random"
+msgstr "Entropía disponible en /dev/random"
+
+#: modules/computer.c:203
+msgid "Scripting Languages"
+msgstr "Lenguajes de scripting"
+
+#: modules/computer.c:204
+msgid "Gambas3 (gbr3)"
+msgstr ""
+
+#: modules/computer.c:205
+msgid "Python"
+msgstr ""
+
+#: modules/computer.c:206
+msgid "Python2"
+msgstr ""
+
+#: modules/computer.c:207
+msgid "Python3"
+msgstr ""
+
+#: modules/computer.c:208
+msgid "Perl"
+msgstr ""
+
+#: modules/computer.c:209
+msgid "Perl6 (VM)"
+msgstr ""
+
+#: modules/computer.c:210
+msgid "Perl6"
+msgstr ""
+
+#: modules/computer.c:211
+msgid "PHP"
+msgstr ""
+
+#: modules/computer.c:212
+msgid "Ruby"
+msgstr ""
+
+#: modules/computer.c:213
+msgid "Bash"
+msgstr ""
+
+#: modules/computer.c:214
+msgid "Compilers"
+msgstr "Compiladores"
+
+#: modules/computer.c:215
+msgid "C (GCC)"
+msgstr ""
+
+#: modules/computer.c:216
+msgid "C (Clang)"
+msgstr ""
+
+#: modules/computer.c:217
+msgid "D (dmd)"
+msgstr ""
+
+#: modules/computer.c:218
+msgid "Gambas3 (gbc3)"
+msgstr ""
+
+#: modules/computer.c:219
+msgid "Java"
+msgstr ""
+
+#: modules/computer.c:220
+msgid "CSharp (Mono, old)"
+msgstr "CSharp (Mono, antiguo)"
+
+#: modules/computer.c:221
+msgid "CSharp (Mono)"
+msgstr ""
+
+#: modules/computer.c:222
+msgid "Vala"
+msgstr ""
+
+#: modules/computer.c:223
+msgid "Haskell (GHC)"
+msgstr ""
+
+#: modules/computer.c:224
+msgid "FreePascal"
+msgstr ""
+
+#: modules/computer.c:225
+msgid "Go"
+msgstr ""
+
+#: modules/computer.c:226
+msgid "Tools"
+msgstr "Herramientas"
+
+#: modules/computer.c:227
+msgid "make"
+msgstr ""
+
+#: modules/computer.c:228
+msgid "GDB"
+msgstr ""
+
+#: modules/computer.c:229
+msgid "strace"
+msgstr ""
+
+#: modules/computer.c:230
+msgid "valgrind"
+msgstr ""
+
+#: modules/computer.c:231
+msgid "QMake"
+msgstr ""
+
+#: modules/computer.c:232
+msgid "CMake"
+msgstr ""
+
+#: modules/computer.c:233
+msgid "Gambas3 IDE"
+msgstr ""
+
+#: modules/computer.c:274
+msgid "Not found"
+msgstr "No encontrado"
+
+#: modules/computer.c:279
+#, c-format
+msgid "Detecting version: %s"
+msgstr "Detectando versión: %s"
+
+#: modules/computer.c:296
+msgid "Program"
+msgstr "Programa"
+
+#: modules/computer.c:308
+msgid "Invalid chassis type (0)"
+msgstr "Clasificación maquina invalida (0)"
+
+#: modules/computer.c:309 modules/computer.c:310
+msgid "Unknown chassis type"
+msgstr "Clasificación mauqina desconocida"
+
+#: modules/computer.c:311
+msgid "Desktop"
+msgstr "PC Escritorio"
+
+#: modules/computer.c:312
+msgid "Low-profile Desktop"
+msgstr "PC economico"
+
+#: modules/computer.c:313
+msgid "Pizza Box"
+msgstr "PC caja pizza"
+
+#: modules/computer.c:314
+msgid "Mini Tower"
+msgstr "Torre mediana"
+
+#: modules/computer.c:315
+msgid "Tower"
+msgstr "Torreta"
+
+#: modules/computer.c:316
+msgid "Portable"
+msgstr "Portable"
+
+#: modules/computer.c:317 modules/computer.c:341 modules/computer.c:350
+#: modules/computer.c:372
+msgid "Laptop"
+msgstr "Portatil"
+
+#: modules/computer.c:318
+msgid "Notebook"
+msgstr "Mini portatil"
+
+#: modules/computer.c:319
+msgid "Handheld"
+msgstr "Mini bolsillo"
+
+#: modules/computer.c:320
+msgid "Docking Station"
+msgstr "Estacion fija"
+
+#: modules/computer.c:321
+msgid "All-in-one"
+msgstr "All in one"
+
+#: modules/computer.c:322
+msgid "Subnotebook"
+msgstr "Subportátil"
+
+#: modules/computer.c:323
+msgid "Space-saving"
+msgstr "PC Espacio-pequeño"
+
+#: modules/computer.c:324
+msgid "Lunch Box"
+msgstr "PC caja"
+
+#: modules/computer.c:325
+msgid "Main Server Chassis"
+msgstr "Servidor principal"
+
+#: modules/computer.c:326
+msgid "Expansion Chassis"
+msgstr "Servidor expansion"
+
+#: modules/computer.c:327
+msgid "Sub Chassis"
+msgstr "Sub servidor"
+
+#: modules/computer.c:328
+msgid "Bus Expansion Chassis"
+msgstr "Expansion de bus acoplable"
+
+#: modules/computer.c:329
+msgid "Peripheral Chassis"
+msgstr "Periferico acoplable"
+
+#: modules/computer.c:330
+msgid "RAID Chassis"
+msgstr "RAID acoplable"
+
+#: modules/computer.c:331
+msgid "Rack Mount Chassis"
+msgstr "Rack de montaje acoplable"
+
+#: modules/computer.c:332
+msgid "Sealed-case PC"
+msgstr "PC sellada"
+
+#. /proc/apm
+#. FIXME: use dmidecode if available to get chassis type
+#: modules/computer.c:386
+msgid "Unknown physical machine type"
+msgstr "Equipo fisico no catalogado"
+
+#: modules/computer.c:470 modules/computer.c:709
+msgid "Computer"
+msgstr "Equipo"
+
+#: modules/computer.c:471 modules/devices/alpha/processor.c:87
+#: modules/devices/arm/processor.c:236 modules/devices.c:95
+#: modules/devices/ia64/processor.c:159 modules/devices/m68k/processor.c:83
+#: modules/devices/mips/processor.c:74 modules/devices/parisc/processor.c:154
+#: modules/devices/ppc/processor.c:157 modules/devices/riscv/processor.c:181
+#: modules/devices/s390/processor.c:131 modules/devices/sh/processor.c:83
+#: modules/devices/sparc/processor.c:74 modules/devices/x86/processor.c:409
+msgid "Processor"
+msgstr "Procesador"
+
+#: modules/computer.c:474
+msgid "Machine Type"
+msgstr "Tipo de equipo"
+
+#: modules/computer.c:477 modules/computer.c:514
+msgid "User Name"
+msgstr "Nombre de usuario"
+
+#: modules/computer.c:482 modules/computer.c:591
+msgid "Resolution"
+msgstr "Resolución"
+
+#: modules/computer.c:483 modules/computer.c:592
+#, c-format
+msgid "%dx%d pixels"
+msgstr ""
+
+#: modules/computer.c:485
+msgid "OpenGL Renderer"
+msgstr "Renderizador OpenGL"
+
+#: modules/computer.c:486
+msgid "X11 Vendor"
+msgstr "Proveedor X11"
+
+#: modules/computer.c:491 modules/devices.c:102
+msgid "Input Devices"
+msgstr "Dispositivos de entrada"
+
+#: modules/computer.c:493 modules/computer.c:752 modules/devices.c:99
+msgid "Printers"
+msgstr "Impresoras"
+
+#: modules/computer.c:495 modules/computer.c:752 modules/devices.c:103
+msgid "Storage"
+msgstr "Almacenamiento"
+
+#: modules/computer.c:506
+msgid "Kernel"
+msgstr "Núcleo"
+
+#: modules/computer.c:508
+msgid "C Library"
+msgstr "Biblioteca C"
+
+#: modules/computer.c:509
+msgid "Distribution"
+msgstr "Distribución"
+
+#: modules/computer.c:512
+msgid "Current Session"
+msgstr "Sesión actual"
+
+#: modules/computer.c:513
+msgid "Computer Name"
+msgstr "Nombre del equipo"
+
+#: modules/computer.c:515 modules/computer/languages.c:108
+msgid "Language"
+msgstr "Idioma"
+
+#: modules/computer.c:516 modules/computer/users.c:50
+msgid "Home Directory"
+msgstr "Directorio personal"
+
+#: modules/computer.c:519 modules/devices/usb.c:87 modules/devices/usb.c:234
+#: modules/devices/usb.c:351
+msgid "Misc"
+msgstr "Otras"
+
+#: modules/computer.c:532
+msgid "Loaded Modules"
+msgstr "Módulos cargados"
+
+#: modules/computer.c:535 modules/computer/modules.c:145
+#: modules/computer/modules.c:147 modules/devices/arm/processor.c:337
+#: modules/devices.c:559 modules/devices/x86/processor.c:456
+msgid "Description"
+msgstr "Descripción"
+
+#: modules/computer.c:548
+msgid "Date & Time"
+msgstr "Fecha y hora"
+
+#: modules/computer.c:549
+msgid "Kernel Version"
+msgstr "Versión del núcleo"
+
+#: modules/computer.c:559
+msgid "Available Languages"
+msgstr "Idiomas disponibles"
+
+#: modules/computer.c:561
+msgid "Language Code"
+msgstr "Código del idioma"
+
+#: modules/computer.c:573
+msgid "Mounted File Systems"
+msgstr "Sistemas de archivos montados"
+
+#: modules/computer.c:575 modules/computer/filesystem.c:85
+msgid "Mount Point"
+msgstr "Punto de montaje"
+
+#: modules/computer.c:576
+msgid "Usage"
+msgstr "Uso"
+
+#: modules/computer.c:577
+msgid "Device"
+msgstr "Dispositivo"
+
+#: modules/computer.c:594 modules/computer.c:601
+#: modules/devices/ia64/processor.c:161 modules/devices/inputdevices.c:119
+#: modules/devices/pci.c:225 modules/devices/usb.c:349
+#: modules/devices/x86/processor.c:416
+msgid "Vendor"
+msgstr "Proveedor"
+
+#: modules/computer.c:598
+msgid "Monitors"
+msgstr "Monitores"
+
+#: modules/computer.c:600
+msgid "OpenGL"
+msgstr "OpenGL (3D)"
+
+#: modules/computer.c:602
+msgid "Renderer"
+msgstr "Renderizador"
+
+#: modules/computer.c:604
+msgid "Direct Rendering"
+msgstr "Renderizado Directo"
+
+#: modules/computer.c:608
+msgid "Extensions"
+msgstr "Extensiones"
+
+#: modules/computer.c:628
+msgid "Group"
+msgstr ""
+
+#: modules/computer.c:631 modules/computer/users.c:49
+msgid "Group ID"
+msgstr "ID del grupo"
+
+#: modules/computer.c:751
+msgid "RAM"
+msgstr "RAM"
+
+#: modules/computer.c:751 modules/devices/devicetree/pmac_data.c:82
+msgid "Motherboard"
+msgstr "Tarjeta madre"
+
+#: modules/computer.c:751
+msgid "Graphics"
+msgstr "Graficos"
+
+#: modules/computer.c:752
+msgid "Audio"
+msgstr "Audio"
+
+#: modules/computer.c:807
+msgid "Gathers high-level computer information"
+msgstr "Obtiene información del equipo de alto nivel"
+
+#: modules/computer/display.c:122
+#, c-format
+msgid "Monitor %d=%dx%d pixels\n"
+msgstr "Monitor %d=%dx%d pixels\n"
+
+#: modules/computer/filesystem.c:83
+msgid "Filesystem"
+msgstr "Sistemas de ficheros"
+
+#: modules/computer/filesystem.c:84
+msgid "Mounted As"
+msgstr "Montado como"
+
+#: modules/computer/filesystem.c:84
+msgid "Read-Write"
+msgstr "Lectura-escritura"
+
+#: modules/computer/filesystem.c:84
+msgid "Read-Only"
+msgstr "Solo-lectura"
+
+#: modules/computer/filesystem.c:86 modules/devices/spd-decode.c:1510
+msgid "Size"
+msgstr "Tamaño"
+
+#: modules/computer/filesystem.c:87
+msgid "Used"
+msgstr "Usado"
+
+#: modules/computer/filesystem.c:88
+msgid "Available"
+msgstr "Disponible"
+
+#: modules/computer/languages.c:103
+msgid "Locale Information"
+msgstr ""
+
+#: modules/computer/languages.c:105
+msgid "Source"
+msgstr ""
+
+#: modules/computer/languages.c:106
+msgid "Address"
+msgstr ""
+
+#: modules/computer/languages.c:107
+msgid "E-mail"
+msgstr ""
+
+#: modules/computer/languages.c:109
+msgid "Territory"
+msgstr ""
+
+#: modules/computer/languages.c:110 modules/devices/arm/processor.c:250
+#: modules/devices/ia64/processor.c:166 modules/devices/ppc/processor.c:159
+#: modules/devices/usb.c:236
+msgid "Revision"
+msgstr "Revision"
+
+#: modules/computer/languages.c:111
+msgid "Date"
+msgstr ""
+
+#: modules/computer/languages.c:112
+msgid "Codeset"
+msgstr ""
+
+#: modules/computer/loadavg.c:64
+msgid "Couldn't obtain load average"
+msgstr "No se pudo obtener estadisticas"
+
+#: modules/computer/modules.c:125 modules/computer/modules.c:126
+#: modules/computer/modules.c:127 modules/computer/modules.c:128
+#: modules/computer/modules.c:129
+msgid "(Not available)"
+msgstr ""
+
+#: modules/computer/modules.c:142
+msgid "Module Information"
+msgstr ""
+
+#: modules/computer/modules.c:143
+msgid "Path"
+msgstr ""
+
+#: modules/computer/modules.c:144
+msgid "Used Memory"
+msgstr ""
+
+#: modules/computer/modules.c:144
+msgid "KiB"
+msgstr ""
+
+#: modules/computer/modules.c:148
+msgid "Version Magic"
+msgstr ""
+
+#: modules/computer/modules.c:149
+msgid "Copyright"
+msgstr ""
+
+#: modules/computer/modules.c:150
+msgid "Author"
+msgstr ""
+
+#: modules/computer/modules.c:151
+msgid "License"
+msgstr ""
+
+#: modules/computer/modules.c:158
+msgid "Dependencies"
+msgstr ""
+
+#: modules/computer/os.c:35 modules/computer/os.c:36 modules/computer/os.c:37
+#: modules/computer/os.c:38
+msgid "GNU C Library"
+msgstr "Libreria C GNU"
+
+#: modules/computer/os.c:39
+msgid "uClibc or uClibc-ng"
+msgstr "Libreria uClibc/uClibc-ng"
+
+#: modules/computer/os.c:40
+msgid "diet libc"
+msgstr "Libreria diet libc"
+
+#: modules/computer/os.c:78 modules/computer/os.c:234 modules/computer/os.c:359
+#: modules/devices.c:333 modules/devices.c:387 modules/devices/printers.c:99
+#: modules/devices/printers.c:106 modules/devices/printers.c:116
+#: modules/devices/printers.c:131 modules/devices/printers.c:140
+#: modules/devices/printers.c:243
+msgid "Unknown"
+msgstr "Desconocido"
+
+#: modules/computer/os.c:112 modules/computer/os.c:115
+msgid "GNOME Shell "
+msgstr ""
+
+#: modules/computer/os.c:123 modules/computer/os.c:126
+msgid "Version: "
+msgstr "Versión"
+
+#: modules/computer/os.c:157
+#, c-format
+msgid "Unknown (Window Manager: %s)"
+msgstr "Desconocido (Gestor de ventanas: %s)"
+
+#. /{desktop environment} on {session type}
+#: modules/computer/os.c:168
+#, c-format
+msgid "%s on %s"
+msgstr "%s en %s"
+
+#: modules/computer/os.c:232
+msgid "Terminal"
+msgstr "Terminal"
+
+#. /bits of entropy for rng (0)
+#: modules/computer/os.c:241
+msgid "(None or not available)"
+msgstr "(Ninguno o no disponible)"
+
+#. /bits of entropy for rng (low/poor value)
+#: modules/computer/os.c:242
+#, c-format
+msgid "%d bits (low)"
+msgstr "%d bits (bajo)"
+
+#. /bits of entropy for rng (medium value)
+#: modules/computer/os.c:243
+#, c-format
+msgid "%d bits (medium)"
+msgstr "%d bits (promedio)"
+
+#. /bits of entropy for rng (high/good value)
+#: modules/computer/os.c:244
+#, c-format
+msgid "%d bits (healthy)"
+msgstr "%d bits (saludable)"
+
+#: modules/computer/os.c:279 modules/devices/usb.c:48 modules/devices/usb.c:307
+#: modules/devices/usb.c:310 modules/network/net.c:442 includes/cpu_util.h:11
+msgid "(Unknown)"
+msgstr "(desconocido)"
+
+#: modules/computer/users.c:47
+msgid "User Information"
+msgstr "Informacion de usuario"
+
+#: modules/computer/users.c:48
+msgid "User ID"
+msgstr "ID usuario"
+
+#: modules/computer/users.c:51
+msgid "Default Shell"
+msgstr "Shell principal"
+
+#: modules/devices/alpha/processor.c:88 modules/devices/devicetree.c:141
+#: modules/devices/devicetree.c:176 modules/devices/devicetree/pmac_data.c:80
+#: modules/devices/ia64/processor.c:165 modules/devices/m68k/processor.c:84
+#: modules/devices/mips/processor.c:75 modules/devices/parisc/processor.c:155
+#: modules/devices/ppc/processor.c:158 modules/devices/riscv/processor.c:182
+#: modules/devices/s390/processor.c:132 modules/devices/spd-decode.c:1510
+msgid "Model"
+msgstr "Modelo"
+
+#: modules/devices/alpha/processor.c:89
+msgid "Platform String"
+msgstr "Plataforma"
+
+#: modules/devices/alpha/processor.c:90 modules/devices/arm/processor.c:240
+#: modules/devices/ia64/processor.c:167 modules/devices/m68k/processor.c:87
+#: modules/devices/mips/processor.c:77 modules/devices/parisc/processor.c:158
+#: modules/devices/pci.c:108 modules/devices/ppc/processor.c:160
+#: modules/devices/riscv/processor.c:186 modules/devices/sh/processor.c:87
+#: modules/devices/x86/processor.c:420
+msgid "Frequency"
+msgstr "Frecuencia"
+
+#: modules/devices/alpha/processor.c:90 modules/devices/arm/processor.c:240
+#: modules/devices/arm/processor.c:365 modules/devices.c:299
+#: modules/devices.c:307 modules/devices.c:335
+#: modules/devices/ia64/processor.c:167 modules/devices/ia64/processor.c:196
+#: modules/devices/m68k/processor.c:87 modules/devices/mips/processor.c:77
+#: modules/devices/parisc/processor.c:158
+#: modules/devices/parisc/processor.c:191 modules/devices/pci.c:108
+#: modules/devices/ppc/processor.c:160 modules/devices/ppc/processor.c:187
+#: modules/devices/riscv/processor.c:186 modules/devices/riscv/processor.c:214
+#: modules/devices/s390/processor.c:160 modules/devices/sh/processor.c:87
+#: modules/devices/sh/processor.c:88 modules/devices/sh/processor.c:89
+#: modules/devices/x86/processor.c:420 modules/devices/x86/processor.c:479
+msgid "MHz"
+msgstr "MHz"
+
+#: modules/devices/alpha/processor.c:91 modules/devices/arm/processor.c:241
+#: modules/devices/ia64/processor.c:168 modules/devices/m68k/processor.c:88
+#: modules/devices/mips/processor.c:78 modules/devices/parisc/processor.c:159
+#: modules/devices/ppc/processor.c:161 modules/devices/s390/processor.c:134
+#: modules/devices/sh/processor.c:90 modules/devices/x86/processor.c:421
+msgid "BogoMips"
+msgstr "BogoMips"
+
+#: modules/devices/alpha/processor.c:92 modules/devices/arm/processor.c:242
+#: modules/devices/ia64/processor.c:169 modules/devices/m68k/processor.c:89
+#: modules/devices/mips/processor.c:79 modules/devices/parisc/processor.c:160
+#: modules/devices/ppc/processor.c:162 modules/devices/riscv/processor.c:187
+#: modules/devices/s390/processor.c:135 modules/devices/sh/processor.c:91
+#: modules/devices/sparc/processor.c:77 modules/devices/x86/processor.c:422
+msgid "Byte Order"
+msgstr "Orden Byte"
+
+#. /hw_cap
+#. /flag:swp
+#: modules/devices/arm/arm_data.c:42
+msgctxt "arm-flag"
+msgid "SWP instruction (atomic read-modify-write)"
+msgstr "SWP instruction (Atomicidad en leer-alterar-escribir)"
+
+#. /flag:half
+#: modules/devices/arm/arm_data.c:43
+msgctxt "arm-flag"
+msgid "Half-word loads and stores"
+msgstr "Half-word cargar y guardado"
+
+#. /flag:thumb
+#: modules/devices/arm/arm_data.c:44
+msgctxt "arm-flag"
+msgid "Thumb (16-bit instruction set)"
+msgstr "Thumb (set instrucciones de 16-bit)"
+
+#. /flag:26bit
+#: modules/devices/arm/arm_data.c:45
+msgctxt "arm-flag"
+msgid "26-Bit Model (Processor status register folded into program counter)"
+msgstr ""
+"26-Bit Model (Registros de estado de procesador en el contador de programa)"
+
+#. /flag:fastmult
+#: modules/devices/arm/arm_data.c:46
+msgctxt "arm-flag"
+msgid "32x32->64-bit multiplication"
+msgstr "32x32->64-bit multiplicador"
+
+#. /flag:fpa
+#: modules/devices/arm/arm_data.c:47
+msgctxt "arm-flag"
+msgid "Floating point accelerator"
+msgstr "Acelerador de punto flotante"
+
+#. /flag:vfp
+#: modules/devices/arm/arm_data.c:48
+msgctxt "arm-flag"
+msgid "VFP (early SIMD vector floating point instructions)"
+msgstr "VFP (vector SIMD temprano de instrucciones de punto flotante"
+
+#. /flag:edsp
+#: modules/devices/arm/arm_data.c:49
+msgctxt "arm-flag"
+msgid "DSP extensions (the 'e' variant of the ARM9 CPUs, and all others above)"
+msgstr "DSP (extensiones en el variante 'e' del ARM9 y otros mas nuevos)"
+
+#. /flag:java
+#: modules/devices/arm/arm_data.c:50
+msgctxt "arm-flag"
+msgid "Jazelle (Java bytecode accelerator)"
+msgstr "Jazelle (aceletador de bytecode Java)"
+
+#. /flag:iwmmxt
+#: modules/devices/arm/arm_data.c:51
+msgctxt "arm-flag"
+msgid "SIMD instructions similar to Intel MMX"
+msgstr "SIMD instrucciones similares a Intel MMX"
+
+#. /flag:crunch
+#: modules/devices/arm/arm_data.c:52
+msgctxt "arm-flag"
+msgid "MaverickCrunch coprocessor (if kernel support enabled)"
+msgstr "MaverickCrunch coprocessor (si esta habilitado en el kernel)"
+
+#. /flag:thumbee
+#: modules/devices/arm/arm_data.c:53
+msgctxt "arm-flag"
+msgid "ThumbEE"
+msgstr "thumbEE"
+
+#. /flag:neon
+#: modules/devices/arm/arm_data.c:54
+msgctxt "arm-flag"
+msgid "Advanced SIMD/NEON on AArch32"
+msgstr "SIMD/NEON avanzado en AArch32"
+
+#. /flag:evtstrm
+#: modules/devices/arm/arm_data.c:55
+msgctxt "arm-flag"
+msgid "Kernel event stream using generic architected timer"
+msgstr ""
+"Secuencia de eventos de kernel con temporizador de arquitectura genérico"
+
+#. /flag:vfpv3
+#: modules/devices/arm/arm_data.c:56
+msgctxt "arm-flag"
+msgid "VFP version 3"
+msgstr "VFP versión 3"
+
+#. /flag:vfpv3d16
+#: modules/devices/arm/arm_data.c:57
+msgctxt "arm-flag"
+msgid "VFP version 3 with 16 D-registers"
+msgstr "VFP versión 3 con 16 D-registros"
+
+#. /flag:vfpv4
+#: modules/devices/arm/arm_data.c:58
+msgctxt "arm-flag"
+msgid "VFP version 4 with fast context switching"
+msgstr "VFP versión 4 con rapido cambio de contexto"
+
+#. /flag:vfpd32
+#: modules/devices/arm/arm_data.c:59
+msgctxt "arm-flag"
+msgid "VFP with 32 D-registers"
+msgstr "VFP con 32 D-registros"
+
+#. /flag:tls
+#: modules/devices/arm/arm_data.c:60
+msgctxt "arm-flag"
+msgid "TLS register"
+msgstr "Registros TLS"
+
+#. /flag:idiva
+#: modules/devices/arm/arm_data.c:61
+msgctxt "arm-flag"
+msgid "SDIV and UDIV hardware division in ARM mode"
+msgstr "SDIV y UDIV divisores por hardware en modo ARM"
+
+#. /flag:idivt
+#: modules/devices/arm/arm_data.c:62
+msgctxt "arm-flag"
+msgid "SDIV and UDIV hardware division in Thumb mode"
+msgstr "SDIV y UDIV divisores por hardware en modo Thumb"
+
+#. /flag:lpae
+#: modules/devices/arm/arm_data.c:63
+msgctxt "arm-flag"
+msgid "40-bit Large Physical Address Extension"
+msgstr "40-bit Extencion de direcciones fisica larga"
+
+#. /hw_cap2
+#. /flag:pmull
+#: modules/devices/arm/arm_data.c:65
+msgctxt "arm-flag"
+msgid "64x64->128-bit F2m multiplication (arch>8)"
+msgstr ""
+
+#. /flag:aes
+#: modules/devices/arm/arm_data.c:66
+msgctxt "arm-flag"
+msgid "Crypto:AES (arch>8)"
+msgstr "Encriptamiento:AES (arch>8)"
+
+#. /flag:sha1
+#: modules/devices/arm/arm_data.c:67
+msgctxt "arm-flag"
+msgid "Crypto:SHA1 (arch>8)"
+msgstr "Encriptamiento:SHA1 (arch>8)"
+
+#. /flag:sha2
+#: modules/devices/arm/arm_data.c:68
+msgctxt "arm-flag"
+msgid "Crypto:SHA2 (arch>8)"
+msgstr "Encriptamiento:SHA2 (arch>8)"
+
+#. /flag:crc32
+#: modules/devices/arm/arm_data.c:69
+msgctxt "arm-flag"
+msgid "CRC32 checksum instructions (arch>8)"
+msgstr "Instrucciones CRC32 checksum (arch>8)"
+
+#. /flag:asimd
+#: modules/devices/arm/arm_data.c:72
+msgctxt "arm-flag"
+msgid "Advanced SIMD/NEON on AArch64 (arch>8)"
+msgstr "SIMD/NEON Avanzado en AArch64 (arch>8)"
+
+#: modules/devices/arm/processor.c:142
+msgid "ARM Processor"
+msgstr "Procesador ARM"
+
+#: modules/devices/arm/processor.c:200 modules/devices/riscv/processor.c:147
+#: modules/devices/x86/processor.c:371
+msgid "Empty List"
+msgstr "Lista vacia"
+
+#: modules/devices/arm/processor.c:237
+msgid "Linux Name"
+msgstr "Nombre Linux"
+
+#: modules/devices/arm/processor.c:238
+msgid "Decoded Name"
+msgstr "Nombre decodificado"
+
+#: modules/devices/arm/processor.c:239 modules/network/net.c:458
+msgid "Mode"
+msgstr "Modo"
+
+#: modules/devices/arm/processor.c:245
+msgid "ARM"
+msgstr "ARM"
+
+#: modules/devices/arm/processor.c:246
+msgid "Implementer"
+msgstr "Implementador"
+
+#: modules/devices/arm/processor.c:247
+msgid "Part"
+msgstr "Parte"
+
+#: modules/devices/arm/processor.c:248 modules/devices/ia64/processor.c:162
+#: modules/devices/parisc/processor.c:156 modules/devices/riscv/processor.c:183
+msgid "Architecture"
+msgstr "Arquitectura"
+
+#: modules/devices/arm/processor.c:249
+msgid "Variant"
+msgstr "Variante"
+
+#: modules/devices/arm/processor.c:251 modules/devices/riscv/processor.c:190
+#: modules/devices/sparc/processor.c:78 modules/devices/x86/processor.c:428
+msgid "Capabilities"
+msgstr "Capacidades"
+
+#: modules/devices/arm/processor.c:335
+msgid "SOC/Package"
+msgstr ""
+
+#: modules/devices/arm/processor.c:338 modules/devices/cpu_util.c:222
+msgid "Topology"
+msgstr "Topologia"
+
+#: modules/devices/arm/processor.c:339
+msgid "Clocks"
+msgstr ""
+
+#: modules/devices/arm/processor.c:354
+msgid "SOC/Package Information"
+msgstr ""
+
+#: modules/devices/battery.c:181
+#, c-format
+msgid ""
+"\n"
+"[Battery: %s]\n"
+"State=%s (load: %s)\n"
+"Capacity=%s / %s (%.2f%%)\n"
+"Battery Technology=%s (%s)\n"
+"Manufacturer=%s\n"
+"Model Number=%s\n"
+"Serial Number=%s\n"
+msgstr ""
+"\n"
+"[Batería: %s]\n"
+"Estado=%s (carga: %s)\n"
+"Capacidad=%s / %s (%.2f%%)\n"
+"Tecnología de la batería=%s (%s)\n"
+"Fabricante=%s\n"
+"Numero de modelo=%s\n"
+"Numero de serie=%s\n"
+
+#: modules/devices/battery.c:258
+#, c-format
+msgid ""
+"\n"
+"[Battery: %s]\n"
+"State=%s\n"
+"Capacity=%s / %s\n"
+"Battery Technology=%s\n"
+"Manufacturer=%s\n"
+"Model Number=%s\n"
+"Serial Number=%s\n"
+msgstr ""
+"\n"
+"[Bateria: %s]\n"
+"Estado=%s\n"
+"Capacidad=%s / %s\n"
+"Technologia de bateria=%s\n"
+"Manufacturador=%s\n"
+"Numero de modelo=%s\n"
+"Numero de serial=%s\n"
+
+#: modules/devices/battery.c:346
+#, c-format
+msgid ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Remaining Charge=%s of %s\n"
+"Using=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+msgstr ""
+"\n"
+"[Batería (APM)]\n"
+"Carga=%d%%\n"
+"Carga restante=%s of %s\n"
+"Usando=%s\n"
+"Versión del driver APM=%s\n"
+"APM BIOS version=%s\n"
+
+#: modules/devices/battery.c:358
+#, c-format
+msgid ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Using=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+msgstr ""
+"\n"
+"[Batería (APM)]\n"
+"Carga=%d%%\n"
+"Usando=%s\n"
+"Versión del driver APM=%s\n"
+"Versión del BIOS APM=%s\n"
+
+#: modules/devices/battery.c:385
+msgid ""
+"[No batteries]\n"
+"No batteries found on this system=\n"
+msgstr ""
+"[Sin baterías]\n"
+"No se encontraron baterías en este sistema=\n"
+
+#: modules/devices.c:97
+msgid "PCI Devices"
+msgstr "Dispositivos PCI"
+
+#: modules/devices.c:98 modules/devices/usb.c:117 modules/devices/usb.c:156
+#: modules/devices/usb.c:415
+msgid "USB Devices"
+msgstr "Dispositivos USB"
+
+#: modules/devices.c:100
+msgid "Battery"
+msgstr "Batería"
+
+#: modules/devices.c:101
+msgid "Sensors"
+msgstr "Sensores"
+
+#: modules/devices.c:105
+msgid "DMI"
+msgstr "DMI"
+
+#: modules/devices.c:106
+msgid "Memory SPD"
+msgstr "Memoria SPD"
+
+#: modules/devices.c:111
+msgid "Device Tree"
+msgstr "Arbol de dispositivos"
+
+#: modules/devices.c:113
+msgid "Resources"
+msgstr "Recursos"
+
+#: modules/devices.c:151
+#, c-format
+msgid "%d physical processor"
+msgid_plural "%d physical processors"
+msgstr[0] ""
+msgstr[1] ""
+
+#: modules/devices.c:152
+#, c-format
+msgid "%d core"
+msgid_plural "%d cores"
+msgstr[0] ""
+msgstr[1] ""
+
+#: modules/devices.c:153
+#, c-format
+msgid "%d thread"
+msgid_plural "%d threads"
+msgstr[0] ""
+msgstr[1] ""
+
+#. /NP procs; NC cores; NT threads
+#: modules/devices.c:154
+#, c-format
+msgid "%s; %s; %s"
+msgstr ""
+
+#: modules/devices.c:372
+msgid " (model unknown)"
+msgstr " (modelo desconocido)"
+
+#: modules/devices.c:374
+msgid " (vendor unknown)"
+msgstr " (proveedor desconocido)"
+
+#: modules/devices.c:559
+msgid "Field"
+msgstr "Campo"
+
+#: modules/devices.c:559 modules/devices.c:591
+msgid "Value"
+msgstr "Valor"
+
+#: modules/devices.c:591
+msgid "Sensor"
+msgstr "Sensor"
+
+#: modules/devices.c:591 modules/devices/inputdevices.c:117
+msgid "Type"
+msgstr "Tipo"
+
+#: modules/devices.c:637
+msgid "Devices"
+msgstr "Dispositivos"
+
+#: modules/devices.c:649
+msgid "Update PCI ID listing"
+msgstr "Actualizar listado de ids PCI"
+
+#: modules/devices.c:661
+msgid "Update CPU feature database"
+msgstr "Actualizar base de datos de características de CPU"
+
+#: modules/devices.c:689
+msgid "Gathers information about hardware devices"
+msgstr "Obtiene información acerca de los dispositivos de hardware"
+
+#: modules/devices.c:708
+msgid "Resource information requires superuser privileges"
+msgstr "Informacion de recursos require privilegios de superusuario"
+
+#: modules/devices/cpu_util.c:30
+msgid "Little Endian"
+msgstr "Little Endian"
+
+#: modules/devices/cpu_util.c:32
+msgid "Big Endian"
+msgstr "Big Endian"
+
+#: modules/devices/cpu_util.c:178 modules/devices/cpu_util.c:189
+msgid "Frequency Scaling"
+msgstr "Escalador de frecuencia"
+
+#: modules/devices/cpu_util.c:179
+msgid "Minimum"
+msgstr "Minimo"
+
+#: modules/devices/cpu_util.c:179 modules/devices/cpu_util.c:180
+#: modules/devices/cpu_util.c:181
+msgid "kHz"
+msgstr "Khz"
+
+#: modules/devices/cpu_util.c:180
+msgid "Maximum"
+msgstr "Maximo"
+
+#: modules/devices/cpu_util.c:181
+msgid "Current"
+msgstr "Actual"
+
+#: modules/devices/cpu_util.c:182
+msgid "Transition Latency"
+msgstr "Latencia de transicion"
+
+#: modules/devices/cpu_util.c:182
+msgid "ns"
+msgstr "ns"
+
+#: modules/devices/cpu_util.c:183
+msgid "Governor"
+msgstr "Gobernador"
+
+#: modules/devices/cpu_util.c:184 modules/devices/cpu_util.c:190
+msgid "Driver"
+msgstr "Manejador"
+
+#: modules/devices/cpu_util.c:196 modules/devices/x86/processor.c:297
+msgid "(Not Available)"
+msgstr "(no disponible)"
+
+#: modules/devices/cpu_util.c:204 modules/devices/cpu_util.c:206
+msgid "Socket"
+msgstr "Soket"
+
+#: modules/devices/cpu_util.c:209 modules/devices/cpu_util.c:211
+msgid "Core"
+msgstr "Core"
+
+#: modules/devices/cpu_util.c:214
+msgid "Book"
+msgstr "Asentamientos"
+
+#: modules/devices/cpu_util.c:216
+msgid "Drawer"
+msgstr "Dibujado"
+
+#: modules/devices/cpu_util.c:223
+msgid "ID"
+msgstr "ID"
+
+#: modules/devices/devicetree.c:47
+msgid "Properties"
+msgstr "Propiedades"
+
+#: modules/devices/devicetree.c:48
+msgid "Children"
+msgstr "Hijos"
+
+#: modules/devices/devicetree.c:84
+msgid "Node"
+msgstr "Nodo"
+
+#: modules/devices/devicetree.c:85
+msgid "Node Path"
+msgstr "Ruta nodo"
+
+#: modules/devices/devicetree.c:86
+msgid "Alias"
+msgstr "Alterno"
+
+#: modules/devices/devicetree.c:86 modules/devices/devicetree.c:87
+msgid "(None)"
+msgstr "(ninguno)"
+
+#: modules/devices/devicetree.c:87
+msgid "Symbol"
+msgstr "Simbolo"
+
+#: modules/devices/devicetree.c:132 modules/devices/devicetree/pmac_data.c:79
+msgid "Platform"
+msgstr "Plataforma"
+
+#: modules/devices/devicetree.c:133 modules/devices/devicetree.c:178
+msgid "Compatible"
+msgstr "Compatible"
+
+#: modules/devices/devicetree.c:134
+msgid "GPU-compatible"
+msgstr "GPU-compatble"
+
+#: modules/devices/devicetree.c:140
+msgid "Raspberry Pi or Compatible"
+msgstr "Raspberry Pi o similar"
+
+#: modules/devices/devicetree.c:142 modules/devices/devicetree.c:160
+#: modules/devices/devicetree.c:177 modules/devices/devicetree/rpi_data.c:160
+msgid "Serial Number"
+msgstr "Numero serial"
+
+#: modules/devices/devicetree.c:143 modules/devices/devicetree/rpi_data.c:157
+msgid "RCode"
+msgstr "Codigo R"
+
+#: modules/devices/devicetree.c:143
+msgid "No revision code available; unable to lookup model details."
+msgstr "No hay codigo de revision disponible, imposible obtener detalles"
+
+#: modules/devices/devicetree.c:159
+msgid "More"
+msgstr "Mas"
+
+#: modules/devices/devicetree.c:175
+msgid "Board"
+msgstr "Tarjeta"
+
+#: modules/devices/devicetree.c:234
+msgid "Messages"
+msgstr "Mensajes"
+
+#: modules/devices/devicetree/dt_util.c:1013
+msgid "phandle Map"
+msgstr "Mapa manejado"
+
+#: modules/devices/devicetree/dt_util.c:1014
+msgid "Alias Map"
+msgstr "Mapa alternativo"
+
+#: modules/devices/devicetree/dt_util.c:1015
+msgid "Symbol Map"
+msgstr "Mapa de simbolos"
+
+#: modules/devices/devicetree/pmac_data.c:78
+msgid "Apple Power Macintosh"
+msgstr "Power Macintosh de Apple"
+
+#: modules/devices/devicetree/pmac_data.c:81 modules/devices/sh/processor.c:85
+msgid "Machine"
+msgstr "Maquina"
+
+#: modules/devices/devicetree/pmac_data.c:83
+msgid "Detected as"
+msgstr "detectada como"
+
+#: modules/devices/devicetree/pmac_data.c:84
+msgid "PMAC Flags"
+msgstr "Semaforos PMAC"
+
+#: modules/devices/devicetree/pmac_data.c:85
+msgid "L2 Cache"
+msgstr "Cache L2"
+
+#: modules/devices/devicetree/pmac_data.c:86
+msgid "PMAC Generation"
+msgstr "PMAC generacion"
+
+#: modules/devices/devicetree/rpi_data.c:152
+#: modules/devices/devicetree/rpi_data.c:153
+msgid "Raspberry Pi"
+msgstr "Raspberry Pi"
+
+#: modules/devices/devicetree/rpi_data.c:153
+msgid "Board Name"
+msgstr "Nombre Tarjeta"
+
+#: modules/devices/devicetree/rpi_data.c:154
+msgid "PCB Revision"
+msgstr "Revision PCB"
+
+#: modules/devices/devicetree/rpi_data.c:155
+msgid "Introduction"
+msgstr "Introducido"
+
+#: modules/devices/devicetree/rpi_data.c:156 modules/devices/spd-decode.c:1510
+#: modules/devices/usb.c:84 modules/devices/usb.c:217
+msgid "Manufacturer"
+msgstr "Manufacturado"
+
+#: modules/devices/devicetree/rpi_data.c:158
+msgid "SOC (spec)"
+msgstr "SOC (specif)"
+
+#: modules/devices/devicetree/rpi_data.c:159
+msgid "Memory (spec)"
+msgstr "Memoria (specif)"
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgid "Permanent overvolt bit"
+msgstr "Bit de sobrevoltage permanente"
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgctxt "rpi-ov-bit"
+msgid "Set"
+msgstr "Asignado"
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgctxt "rpi-ov-bit"
+msgid "Not set"
+msgstr "Sin ajustar"
+
+#: modules/devices/devmemory.c:93
+msgid "Total Memory"
+msgstr "Memoria total"
+
+#: modules/devices/devmemory.c:94
+msgid "Free Memory"
+msgstr "Memoria Libre"
+
+#: modules/devices/devmemory.c:95
+msgid "Cached Swap"
+msgstr "Intercambio"
+
+#: modules/devices/devmemory.c:96
+msgid "High Memory"
+msgstr "Memoria alta"
+
+#: modules/devices/devmemory.c:97
+msgid "Free High Memory"
+msgstr "Memoria alta libre"
+
+#: modules/devices/devmemory.c:98
+msgid "Low Memory"
+msgstr "Memoria base"
+
+#: modules/devices/devmemory.c:99
+msgid "Free Low Memory"
+msgstr "Memoria base libre"
+
+#: modules/devices/devmemory.c:100
+msgid "Virtual Memory"
+msgstr "Memoria virtual"
+
+#: modules/devices/devmemory.c:101
+msgid "Free Virtual Memory"
+msgstr "Memoria virtual libre"
+
+#: modules/devices/dmi.c:188
+msgid "(Not available; Perhaps try running HardInfo as root.)"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:108
+msgid "IA64 Processor"
+msgstr "Procesador IA64"
+
+#: modules/devices/ia64/processor.c:163
+msgid "Architecture Revision"
+msgstr "Revision arquitectura"
+
+#: modules/devices/ia64/processor.c:164 modules/devices/sh/processor.c:86
+msgid "Family"
+msgstr "Familia"
+
+#: modules/devices/ia64/processor.c:170
+msgid "CPU regs"
+msgstr "Registros"
+
+#: modules/devices/ia64/processor.c:171
+msgid "Features"
+msgstr "Capacidades"
+
+#: modules/devices/inputdevices.c:115 modules/devices/pci.c:214
+#: modules/devices/usb.c:82 modules/devices/usb.c:215 modules/devices/usb.c:347
+msgid "Device Information"
+msgstr ""
+
+#: modules/devices/inputdevices.c:118 modules/devices/usb.c:92
+#: modules/devices/usb.c:240 modules/devices/usb.c:356
+msgid "Bus"
+msgstr ""
+
+#: modules/devices/inputdevices.c:120 modules/devices/usb.c:83
+#: modules/devices/usb.c:216 modules/devices/usb.c:348
+msgid "Product"
+msgstr ""
+
+#: modules/devices/inputdevices.c:124
+msgid "Connected to"
+msgstr ""
+
+#: modules/devices/inputdevices.c:128
+msgid "InfraRed port"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:85 modules/devices/riscv/processor.c:185
+msgid "MMU"
+msgstr "MMU"
+
+#: modules/devices/m68k/processor.c:86 modules/devices/sparc/processor.c:76
+msgid "FPU"
+msgstr "FPU"
+
+#: modules/devices/m68k/processor.c:90
+msgid "Calibration"
+msgstr "Calibracion"
+
+#: modules/devices/mips/processor.c:76
+msgid "System Type"
+msgstr "Tipo sistema"
+
+#: modules/devices/parisc/processor.c:107
+msgid "PA-RISC Processor"
+msgstr "Procesador PA-RISC"
+
+#: modules/devices/parisc/processor.c:157
+msgid "System"
+msgstr "Sistema"
+
+#: modules/devices/parisc/processor.c:161
+msgid "HVersion"
+msgstr "HVersion"
+
+#: modules/devices/parisc/processor.c:162
+msgid "SVersion"
+msgstr "SVersion"
+
+#: modules/devices/parisc/processor.c:163 modules/devices/x86/processor.c:425
+msgid "Cache"
+msgstr "Cache"
+
+#: modules/devices/pci.c:106
+msgid "IRQ"
+msgstr ""
+
+#: modules/devices/pci.c:110
+msgid "Latency"
+msgstr ""
+
+#: modules/devices/pci.c:112
+msgid "Bus Master"
+msgstr ""
+
+#: modules/devices/pci.c:118
+msgid "Kernel modules"
+msgstr ""
+
+#: modules/devices/pci.c:124
+#, c-format
+msgid "%s=%s (%s)\n"
+msgstr ""
+
+#: modules/devices/pci.c:126
+msgid "OEM Vendor"
+msgstr ""
+
+#: modules/devices/pci.c:153
+msgid "prefetchable"
+msgstr ""
+
+#: modules/devices/pci.c:154
+msgid "non-prefetchable"
+msgstr ""
+
+#: modules/devices/pci.c:163
+msgid "I/O ports at"
+msgstr ""
+
+#: modules/devices/pci.c:216 modules/devices/usb.c:89 modules/devices/usb.c:237
+#: modules/devices/usb.c:353
+msgid "Class"
+msgstr ""
+
+#: modules/devices/pci.c:217
+msgid "Domain"
+msgstr ""
+
+#: modules/devices/pci.c:218
+msgid "Bus, device, function"
+msgstr ""
+
+#: modules/devices/pci.c:243
+msgid "No PCI devices found"
+msgstr ""
+
+#: modules/devices/ppc/processor.c:117
+msgid "POWER Processor"
+msgstr "Procesador POWER"
+
+#: modules/devices/printers.c:81
+msgid "⚬ Can do black and white printing=\n"
+msgstr "⚬ Puede imprimir en blanco y negro=\n"
+
+#: modules/devices/printers.c:83
+msgid "⚬ Can do color printing=\n"
+msgstr "⚬ Puede imprimir en color=\n"
+
+#: modules/devices/printers.c:85
+msgid "⚬ Can do duplexing=\n"
+msgstr "⚬ Can do duplexing=\n"
+
+#: modules/devices/printers.c:87
+msgid "⚬ Can do staple output=\n"
+msgstr "⚬ Puede engrapar la salida=\n"
+
+#: modules/devices/printers.c:89
+msgid "⚬ Can do copies=\n"
+msgstr "⚬ Puede hacer copias=\n"
+
+#: modules/devices/printers.c:91
+msgid "⚬ Can collate copies=\n"
+msgstr "⚬ Puede compaginar copias=\n"
+
+#: modules/devices/printers.c:93
+msgid "⚬ Printer is rejecting jobs=\n"
+msgstr "⚬ La impresora está rechazando trabajos=\n"
+
+#: modules/devices/printers.c:95
+msgid "⚬ Printer was automatically discovered and added=\n"
+msgstr "⚬ La impresora fue encontrada automáticamente y agregada=\n"
+
+#: modules/devices/printers.c:110
+msgid "Idle"
+msgstr "Ocioso"
+
+#: modules/devices/printers.c:112
+msgid "Printing a Job"
+msgstr "Imprimiendo un trabajo"
+
+#: modules/devices/printers.c:114
+msgid "Stopped"
+msgstr "Detenido"
+
+#: modules/devices/printers.c:190
+msgid ""
+"[Printers]\n"
+"No suitable CUPS library found="
+msgstr ""
+"[Impresoras]\n"
+"No se encontró ninguna biblioteca CUPS usable="
+
+#: modules/devices/printers.c:200
+msgid "[Printers (CUPS)]\n"
+msgstr "[Impresoras (CUPS)]\n"
+
+#: modules/devices/printers.c:263
+msgid ""
+"[Printers]\n"
+"No printers found=\n"
+msgstr ""
+"[Impresoras]\n"
+"No se encontraron impresoras=\n"
+
+#: modules/devices/riscv/processor.c:107
+msgid "RISC-V Processor"
+msgstr "Procesador RISC-V"
+
+#: modules/devices/riscv/processor.c:184
+msgid "uarch"
+msgstr "uarch"
+
+#. /ext:RV32
+#: modules/devices/riscv/riscv_data.c:37
+msgctxt "rv-ext"
+msgid "RISC-V 32-bit"
+msgstr "RISC-V 32-bit"
+
+#. /ext:RV64
+#: modules/devices/riscv/riscv_data.c:38
+msgctxt "rv-ext"
+msgid "RISC-V 64-bit"
+msgstr "RISC-V 64-bit"
+
+#. /ext:RV128
+#: modules/devices/riscv/riscv_data.c:39
+msgctxt "rv-ext"
+msgid "RISC-V 128-bit"
+msgstr "RISC-V 128-bit"
+
+#. /ext:E
+#: modules/devices/riscv/riscv_data.c:40
+msgctxt "rv-ext"
+msgid "Base embedded integer instructions (15 registers)"
+msgstr "Instrucciones de enteros embebidas base (15 registros)"
+
+#. /ext:I
+#: modules/devices/riscv/riscv_data.c:41
+msgctxt "rv-ext"
+msgid "Base integer instructions (31 registers)"
+msgstr "Instrucciones de enteros base (31 registros)"
+
+#. /ext:M
+#: modules/devices/riscv/riscv_data.c:42
+msgctxt "rv-ext"
+msgid "Hardware integer multiply and divide"
+msgstr "Multiplicador y divisor de enteros por hardware"
+
+#. /ext:A
+#: modules/devices/riscv/riscv_data.c:43
+msgctxt "rv-ext"
+msgid "Atomic memory operations"
+msgstr "Operaciones de memoria unificadas"
+
+#. /ext:C
+#: modules/devices/riscv/riscv_data.c:44
+msgctxt "rv-ext"
+msgid "Compressed 16-bit instructions"
+msgstr "Intrucciones compresion 16-bit"
+
+#. /ext:F
+#: modules/devices/riscv/riscv_data.c:45
+msgctxt "rv-ext"
+msgid "Floating-point instructions, single-precision"
+msgstr "Instrucciones punto-flotante, precision simple"
+
+#. /ext:D
+#: modules/devices/riscv/riscv_data.c:46
+msgctxt "rv-ext"
+msgid "Floating-point instructions, double-precision"
+msgstr "Instrucciones punto-flotante, precision doble"
+
+#. /ext:Q
+#: modules/devices/riscv/riscv_data.c:47
+msgctxt "rv-ext"
+msgid "Floating-point instructions, quad-precision"
+msgstr "Instrucciones punto-flotante, precision cuadruple"
+
+#. /ext:B
+#: modules/devices/riscv/riscv_data.c:48
+msgctxt "rv-ext"
+msgid "Bit manipulation instructions"
+msgstr "Instrucciones de manipulacion de bit"
+
+#. /ext:V
+#: modules/devices/riscv/riscv_data.c:49
+msgctxt "rv-ext"
+msgid "Vector operations"
+msgstr "Operaciones de Vector"
+
+#. /ext:T
+#: modules/devices/riscv/riscv_data.c:50
+msgctxt "rv-ext"
+msgid "Transactional memory"
+msgstr "Memoria transaccional"
+
+#. /ext:P
+#: modules/devices/riscv/riscv_data.c:51
+msgctxt "rv-ext"
+msgid "Packed SIMD instructions"
+msgstr "Instrucciones SIMD empaquetadas"
+
+#. /ext:L
+#: modules/devices/riscv/riscv_data.c:52
+msgctxt "rv-ext"
+msgid "Decimal floating-point instructions"
+msgstr "Instrucciones punto-flotante decimales"
+
+#. /ext:J
+#: modules/devices/riscv/riscv_data.c:53
+msgctxt "rv-ext"
+msgid "Dynamically translated languages"
+msgstr "Traduccion de lenguajes dinamicamente"
+
+#. /ext:N
+#: modules/devices/riscv/riscv_data.c:54
+msgctxt "rv-ext"
+msgid "User-level interrupts"
+msgstr "Interrupciones de nivel de usuario"
+
+#: modules/devices/s390/processor.c:92
+msgid "S390 Processor"
+msgstr "Procesador S390"
+
+#: modules/devices/s390/processor.c:133
+msgid "ID String"
+msgstr "ID String"
+
+#: modules/devices/sh/processor.c:55
+msgid "SuperH Processor"
+msgstr "Procesador SuperH"
+
+#: modules/devices/sh/processor.c:88
+msgid "Bus Frequency"
+msgstr "Frecuencya de Bus"
+
+#: modules/devices/sh/processor.c:89
+msgid "Module Frequency"
+msgstr "Frecuencia modular"
+
+#: modules/devices/spd-decode.c:1475
+msgid ""
+"[SPD]\n"
+"Please load the eeprom module to obtain information about memory SPD=\n"
+"[$ShellParam$]\n"
+"ReloadInterval=500\n"
+msgstr ""
+"[SPD]\n"
+"Por favor carge el modulo eeprom para obtener informacion de memorias SPD=\n"
+"[$ShellParam$]\n"
+"ReloadInterval=500\n"
+
+#: modules/devices/spd-decode.c:1480
+msgid ""
+"[SPD]\n"
+"Reading memory SPD not supported on this system=\n"
+msgstr ""
+"[SPD]\n"
+"Lectura de memorias no soportado en este sistema=\n"
+
+#: modules/devices/spd-decode.c:1509
+msgid "SPD"
+msgstr "SPD"
+
+#: modules/devices/spd-decode.c:1510
+msgid "Bank"
+msgstr "Ranura"
+
+#: modules/devices/storage.c:46
+msgid ""
+"\n"
+"[SCSI Disks]\n"
+msgstr ""
+"\n"
+"[Discos SCSI]\n"
+
+#: modules/devices/storage.c:110 modules/devices/storage.c:313
+#, c-format
+msgid ""
+"[Device Information]\n"
+"Model=%s\n"
+msgstr ""
+"[Información de dispositivo]\n"
+"Modelo=%s\n"
+
+#: modules/devices/storage.c:115 modules/devices/storage.c:319
+#, c-format
+msgid "Vendor=%s (%s)\n"
+msgstr "Proveedor=%s (%s)\n"
+
+#: modules/devices/storage.c:120 modules/devices/storage.c:321
+#, c-format
+msgid "Vendor=%s\n"
+msgstr "Proveedor=%s\n"
+
+#: modules/devices/storage.c:125
+#, c-format
+msgid ""
+"Type=%s\n"
+"Revision=%s\n"
+"[SCSI Controller]\n"
+"Controller=scsi%d\n"
+"Channel=%d\n"
+"ID=%d\n"
+"LUN=%d\n"
+msgstr ""
+"Tipo=%s\n"
+"Revisión=%s\n"
+"[Controladora SCSI]\n"
+"Controladora=scsi%d\n"
+"Canal=%d\n"
+"ID=%d\n"
+"LUN=%d\n"
+
+#: modules/devices/storage.c:167
+msgid ""
+"\n"
+"[IDE Disks]\n"
+msgstr ""
+"\n"
+"[Discos IDE]\n"
+
+#: modules/devices/storage.c:250
+#, c-format
+msgid "Driver=%s\n"
+msgstr "Driver=%s\n"
+
+#: modules/devices/storage.c:324
+#, c-format
+msgid ""
+"Device Name=hd%c\n"
+"Media=%s\n"
+"Cache=%dkb\n"
+msgstr ""
+"Nombre del dispositivo=hd%c\n"
+"Medio=%s\n"
+"Cache=%dkb\n"
+
+#: modules/devices/storage.c:334
+#, c-format
+msgid ""
+"[Geometry]\n"
+"Physical=%s\n"
+"Logical=%s\n"
+msgstr ""
+"[Geometría]\n"
+"Física=%s\n"
+"Lógica=%s\n"
+
+#: modules/devices/storage.c:344
+#, c-format
+msgid ""
+"[Capabilities]\n"
+"%s"
+msgstr ""
+"[Capacidades]\n"
+"%s"
+
+#: modules/devices/storage.c:351
+#, c-format
+msgid ""
+"[Speeds]\n"
+"%s"
+msgstr ""
+"[Velocidades]\n"
+"%s"
+
+#: modules/devices/usb.c:44 modules/devices/usb.c:326
+msgid "mA"
+msgstr ""
+
+#. /%.2f is version
+#: modules/devices/usb.c:53 modules/devices/usb.c:190
+#, c-format
+msgid "USB %.2f Hub"
+msgstr ""
+
+#: modules/devices/usb.c:55 modules/devices/usb.c:192
+#, c-format
+msgid "Unknown USB %.2f Device (class %d)"
+msgstr ""
+
+#: modules/devices/usb.c:85 modules/devices/usb.c:232
+msgid "Speed"
+msgstr ""
+
+#: modules/devices/usb.c:85 modules/devices/usb.c:232
+msgid "Mbit/s"
+msgstr ""
+
+#: modules/devices/usb.c:86 modules/devices/usb.c:233 modules/devices/usb.c:350
+msgid "Max Current"
+msgstr ""
+
+#: modules/devices/usb.c:88 modules/devices/usb.c:235 modules/devices/usb.c:352
+msgid "USB Version"
+msgstr ""
+
+#: modules/devices/usb.c:90 modules/devices/usb.c:238 modules/devices/usb.c:354
+msgid "Vendor ID"
+msgstr ""
+
+#: modules/devices/usb.c:91 modules/devices/usb.c:239 modules/devices/usb.c:355
+msgid "Product ID"
+msgstr ""
+
+#: modules/devices/usb.c:231
+msgid "Port"
+msgstr ""
+
+#: modules/devices/usb.c:241
+msgid "Level"
+msgstr ""
+
+#: modules/devices/x86/processor.c:149
+msgid "Cache information not available=\n"
+msgstr "Informacion de cache no disponible=\n"
+
+#: modules/devices/x86/processor.c:155
+#, c-format
+msgid "Level %d (%s)=%d-way set-associative, %d sets, %dKB size\n"
+msgstr "Nivel %d (%s)=%d-way set-associative, %d sets, %dKB tamaño\n"
+
+#. /cache type, as appears in: Level 1 (Data)
+#: modules/devices/x86/processor.c:170
+msgctxt "cache-type"
+msgid "Data"
+msgstr "Datos"
+
+#. /cache type, as appears in: Level 1 (Instruction)
+#: modules/devices/x86/processor.c:171
+msgctxt "cache-type"
+msgid "Instruction"
+msgstr "Instruccion"
+
+#. /cache type, as appears in: Level 2 (Unified)
+#: modules/devices/x86/processor.c:172
+msgctxt "cache-type"
+msgid "Unified"
+msgstr "Unificado"
+
+#: modules/devices/x86/processor.c:410
+msgid "Model Name"
+msgstr "Nombre Modelo"
+
+#: modules/devices/x86/processor.c:411
+msgid "Family, model, stepping"
+msgstr "Familia, modelo, escalado"
+
+#: modules/devices/x86/processor.c:417
+msgid "Microcode Version"
+msgstr ""
+
+#: modules/devices/x86/processor.c:418
+msgid "Configuration"
+msgstr "Configuracion"
+
+#: modules/devices/x86/processor.c:419
+msgid "Cache Size"
+msgstr "Tamaño cache"
+
+#: modules/devices/x86/processor.c:419
+msgid "kb"
+msgstr "kb"
+
+#: modules/devices/x86/processor.c:426
+msgid "Power Management"
+msgstr "Manejador energia"
+
+#: modules/devices/x86/processor.c:427
+msgid "Bug Workarounds"
+msgstr "Manejo de errores"
+
+#: modules/devices/x86/processor.c:454 modules/devices/x86/processor.c:468
+msgid "Package Information"
+msgstr ""
+
+#. /flag:fpu
+#: modules/devices/x86/x86_data.c:43
+msgctxt "x86-flag"
+msgid "Onboard FPU (floating point support)"
+msgstr "FPÜ embebido (soporte punto flotante)"
+
+#. /flag:vme
+#: modules/devices/x86/x86_data.c:44
+msgctxt "x86-flag"
+msgid "Virtual 8086 mode enhancements"
+msgstr "Virtual 8086 modo ampliado"
+
+#. /flag:de
+#: modules/devices/x86/x86_data.c:45
+msgctxt "x86-flag"
+msgid "Debugging Extensions (CR4.DE)"
+msgstr "Extensiuones depurado (CR4.DE)"
+
+#. /flag:pse
+#: modules/devices/x86/x86_data.c:46
+msgctxt "x86-flag"
+msgid "Page Size Extensions (4MB memory pages)"
+msgstr "Extensiones de pagina (paginas de 4MB memoria)"
+
+#. /flag:tsc
+#: modules/devices/x86/x86_data.c:47
+msgctxt "x86-flag"
+msgid "Time Stamp Counter (RDTSC)"
+msgstr "contador de estampa de tiempo (RDTSC)"
+
+#. /flag:msr
+#: modules/devices/x86/x86_data.c:48
+msgctxt "x86-flag"
+msgid "Model-Specific Registers (RDMSR, WRMSR)"
+msgstr "Registros de modelo-especificos (RDMSR, WRMSR)"
+
+#. /flag:pae
+#: modules/devices/x86/x86_data.c:49
+msgctxt "x86-flag"
+msgid "Physical Address Extensions (support for more than 4GB of RAM)"
+msgstr "Extension de direcciones fisicas (soporte de mas de 4GB de RAM)"
+
+#. /flag:mce
+#: modules/devices/x86/x86_data.c:50
+msgctxt "x86-flag"
+msgid "Machine Check Exception"
+msgstr "Excepciones de revision de maquina"
+
+#. /flag:cx8
+#: modules/devices/x86/x86_data.c:51
+msgctxt "x86-flag"
+msgid "CMPXCHG8 instruction (64-bit compare-and-swap)"
+msgstr "Instrucciones CMPXCHG8 (64-bit compare-and-swap)"
+
+#. /flag:apic
+#: modules/devices/x86/x86_data.c:52
+msgctxt "x86-flag"
+msgid "Onboard APIC"
+msgstr "APIC embebida"
+
+#. /flag:sep
+#: modules/devices/x86/x86_data.c:53
+msgctxt "x86-flag"
+msgid "SYSENTER/SYSEXIT"
+msgstr "SYSENTER/SYSEXIT"
+
+#. /flag:mtrr
+#: modules/devices/x86/x86_data.c:54
+msgctxt "x86-flag"
+msgid "Memory Type Range Registers"
+msgstr "Registros de rango de tipo de Memoria"
+
+#. /flag:pge
+#: modules/devices/x86/x86_data.c:55
+msgctxt "x86-flag"
+msgid "Page Global Enable (global bit in PDEs and PTEs)"
+msgstr "Habilitador de pagina global (global bit in PDEs and PTEs)"
+
+#. /flag:mca
+#: modules/devices/x86/x86_data.c:56
+msgctxt "x86-flag"
+msgid "Machine Check Architecture"
+msgstr "Revisor de arquitectura de maquina"
+
+#. /flag:cmov
+#: modules/devices/x86/x86_data.c:57
+msgctxt "x86-flag"
+msgid "CMOV instructions (conditional move) (also FCMOV)"
+msgstr "Instrucciones CMOV (mover condicionalmente) (tambien FCMOV)"
+
+#. /flag:pat
+#: modules/devices/x86/x86_data.c:58
+msgctxt "x86-flag"
+msgid "Page Attribute Table"
+msgstr "Tabla de atributos de pagina"
+
+#. /flag:pse36
+#: modules/devices/x86/x86_data.c:59
+msgctxt "x86-flag"
+msgid "36-bit PSEs (huge pages)"
+msgstr "36-bit PSEs (huge pages)"
+
+#. /flag:pn
+#: modules/devices/x86/x86_data.c:60
+msgctxt "x86-flag"
+msgid "Processor serial number"
+msgstr "Numero serial de prosesador"
+
+#. /flag:clflush
+#: modules/devices/x86/x86_data.c:61
+msgctxt "x86-flag"
+msgid "Cache Line Flush instruction"
+msgstr "Cache Line Flush instruction"
+
+#. /flag:dts
+#: modules/devices/x86/x86_data.c:62
+msgctxt "x86-flag"
+msgid ""
+"Debug Store (buffer for debugging and profiling instructions), or "
+"alternately: digital thermal sensor"
+msgstr ""
+"Guardado de depurado (buffer para depurado y pruebas de instrucciones), o "
+"alternativamente: sensor de temperatura digital"
+
+#. /flag:acpi
+#: modules/devices/x86/x86_data.c:63
+msgctxt "x86-flag"
+msgid "ACPI via MSR (temperature monitoring and clock speed modulation)"
+msgstr ""
+"ACPI via MSR (monitor de temperatura y reloj de modulacion de velocidad)"
+
+#. /flag:mmx
+#: modules/devices/x86/x86_data.c:64
+msgctxt "x86-flag"
+msgid "Multimedia Extensions"
+msgstr "Extensiones multimedia"
+
+#. /flag:fxsr
+#: modules/devices/x86/x86_data.c:65
+msgctxt "x86-flag"
+msgid "FXSAVE/FXRSTOR, CR4.OSFXSR"
+msgstr "FXSAVE/FXRSTOR, CR4.OSFXSR"
+
+#. /flag:sse
+#: modules/devices/x86/x86_data.c:66
+msgctxt "x86-flag"
+msgid "Intel SSE vector instructions"
+msgstr "Intel SSE instrucciones de vectorizado"
+
+#. /flag:sse2
+#: modules/devices/x86/x86_data.c:67
+msgctxt "x86-flag"
+msgid "SSE2"
+msgstr "SSE2"
+
+#. /flag:ss
+#: modules/devices/x86/x86_data.c:68
+msgctxt "x86-flag"
+msgid "CPU self snoop"
+msgstr "CPU self snoop"
+
+#. /flag:ht
+#: modules/devices/x86/x86_data.c:69
+msgctxt "x86-flag"
+msgid "Hyper-Threading"
+msgstr "Hyper-Threading"
+
+#. /flag:tm
+#: modules/devices/x86/x86_data.c:70
+msgctxt "x86-flag"
+msgid "Automatic clock control (Thermal Monitor)"
+msgstr "control automatico de reloj (Monitor de temperatura)"
+
+#. /flag:ia64
+#: modules/devices/x86/x86_data.c:71
+msgctxt "x86-flag"
+msgid ""
+"Intel Itanium Architecture 64-bit (not to be confused with Intel's 64-bit "
+"x86 architecture with flag x86-64 or \"AMD64\" bit indicated by flag lm)"
+msgstr ""
+"Intel Itanium Arquitectura 64-bit (no confundir con el 64-bit Intel de "
+"architecture x86 con el flag x86-64 o bit \"AMD64\" indicado por flag lm)"
+
+#. /flag:pbe
+#: modules/devices/x86/x86_data.c:72
+msgctxt "x86-flag"
+msgid "Pending Break Enable (PBE# pin) wakeup support"
+msgstr "Pending Break Enable (PBE# pin) despertado"
+
+#. /flag:syscall
+#: modules/devices/x86/x86_data.c:75
+msgctxt "x86-flag"
+msgid "SYSCALL (Fast System Call) and SYSRET (Return From Fast System Call)"
+msgstr "SYSCALL (Fast System Call) and SYSRET (Return From Fast System Call)"
+
+#. /flag:mp
+#: modules/devices/x86/x86_data.c:76
+msgctxt "x86-flag"
+msgid "Multiprocessing Capable."
+msgstr "Capacidades multiprocesos"
+
+#. /flag:nx
+#: modules/devices/x86/x86_data.c:77
+msgctxt "x86-flag"
+msgid "Execute Disable"
+msgstr "Execute Disable"
+
+#. /flag:mmxext
+#: modules/devices/x86/x86_data.c:78
+msgctxt "x86-flag"
+msgid "AMD MMX extensions"
+msgstr "Extensiones AMD MMX"
+
+#. /flag:fxsr_opt
+#: modules/devices/x86/x86_data.c:79
+msgctxt "x86-flag"
+msgid "FXSAVE/FXRSTOR optimizations"
+msgstr "Optimizaciones FXSAVE/FXRSTOR"
+
+#. /flag:pdpe1gb
+#: modules/devices/x86/x86_data.c:80
+msgctxt "x86-flag"
+msgid "One GB pages (allows hugepagesz=1G)"
+msgstr "Paginas One GB (permite hugepagesz=1G)"
+
+#. /flag:rdtscp
+#: modules/devices/x86/x86_data.c:81
+msgctxt "x86-flag"
+msgid "Read Time-Stamp Counter and Processor ID"
+msgstr "Read Time-Stamp Counter and Processor ID"
+
+#. /flag:lm
+#: modules/devices/x86/x86_data.c:82
+msgctxt "x86-flag"
+msgid "Long Mode (x86-64: amd64, also known as Intel 64, i.e. 64-bit capable)"
+msgstr ""
+"Modo Largo (x86-64: amd64, conocido como Intel 64, ejem. compatible 64-bit)"
+
+#. /flag:3dnow
+#: modules/devices/x86/x86_data.c:83
+msgctxt "x86-flag"
+msgid "3DNow! (AMD vector instructions, competing with Intel's SSE1)"
+msgstr ""
+"3DNow! (AMD instrucciones de vectorizado, competidor de las Intel SSE1)"
+
+#. /flag:3dnowext
+#: modules/devices/x86/x86_data.c:84
+msgctxt "x86-flag"
+msgid "AMD 3DNow! extensions"
+msgstr "AMD 3DNow! extensions"
+
+#. /flag:recovery
+#: modules/devices/x86/x86_data.c:86
+msgctxt "x86-flag"
+msgid "CPU in recovery mode"
+msgstr "CPU en modo recuperacion"
+
+#. /flag:longrun
+#: modules/devices/x86/x86_data.c:87
+msgctxt "x86-flag"
+msgid "Longrun power control"
+msgstr "control energia Longrun"
+
+#. /flag:lrti
+#: modules/devices/x86/x86_data.c:88
+msgctxt "x86-flag"
+msgid "LongRun table interface"
+msgstr "Interfaz de tabla LongRun"
+
+#. /flag:cxmmx
+#: modules/devices/x86/x86_data.c:90
+msgctxt "x86-flag"
+msgid "Cyrix MMX extensions"
+msgstr "Cyrix MMX extensions"
+
+#. /flag:k6_mtrr
+#: modules/devices/x86/x86_data.c:91
+msgctxt "x86-flag"
+msgid "AMD K6 nonstandard MTRRs"
+msgstr "AMD K6 nonstandard MTRRs"
+
+#. /flag:cyrix_arr
+#: modules/devices/x86/x86_data.c:92
+msgctxt "x86-flag"
+msgid "Cyrix ARRs (= MTRRs)"
+msgstr "Cyrix ARRs (= MTRRs)"
+
+#. /flag:centaur_mcr
+#: modules/devices/x86/x86_data.c:93
+msgctxt "x86-flag"
+msgid "Centaur MCRs (= MTRRs)"
+msgstr "Centaur MCRs (= MTRRs)"
+
+#. /flag:constant_tsc
+#: modules/devices/x86/x86_data.c:94
+msgctxt "x86-flag"
+msgid "TSC ticks at a constant rate"
+msgstr "TSC ticks a una velocidad constante"
+
+#. /flag:up
+#: modules/devices/x86/x86_data.c:95
+msgctxt "x86-flag"
+msgid "SMP kernel running on UP"
+msgstr "Kernel SMP ejecutandose"
+
+#. /flag:art
+#: modules/devices/x86/x86_data.c:96
+msgctxt "x86-flag"
+msgid "Always-Running Timer"
+msgstr "Timer Siempre-ejecutandose"
+
+#. /flag:arch_perfmon
+#: modules/devices/x86/x86_data.c:97
+msgctxt "x86-flag"
+msgid "Intel Architectural PerfMon"
+msgstr "Arquitectura Intel PerfMon"
+
+#. /flag:pebs
+#: modules/devices/x86/x86_data.c:98
+msgctxt "x86-flag"
+msgid "Precise-Event Based Sampling"
+msgstr ""
+
+#. /flag:bts
+#: modules/devices/x86/x86_data.c:99
+msgctxt "x86-flag"
+msgid "Branch Trace Store"
+msgstr ""
+
+#. /flag:rep_good
+#: modules/devices/x86/x86_data.c:100
+msgctxt "x86-flag"
+msgid "rep microcode works well"
+msgstr "rep microcode trabaja bien"
+
+#. /flag:acc_power
+#: modules/devices/x86/x86_data.c:101
+msgctxt "x86-flag"
+msgid "AMD accumulated power mechanism"
+msgstr "AMD mecanismo de energia acumulada"
+
+#. /flag:nopl
+#: modules/devices/x86/x86_data.c:102
+msgctxt "x86-flag"
+msgid "The NOPL (0F 1F) instructions"
+msgstr "Instrucciones NOPL (0F 1F)"
+
+#. /flag:xtopology
+#: modules/devices/x86/x86_data.c:103
+msgctxt "x86-flag"
+msgid "cpu topology enum extensions"
+msgstr "extensiones de enumaracion de cpu"
+
+#. /flag:tsc_reliable
+#: modules/devices/x86/x86_data.c:104
+msgctxt "x86-flag"
+msgid "TSC is known to be reliable"
+msgstr "TSC esta en modo confiable"
+
+#. /flag:nonstop_tsc
+#: modules/devices/x86/x86_data.c:105
+msgctxt "x86-flag"
+msgid "TSC does not stop in C states"
+msgstr "TSC no se detiene en estado C"
+
+#. /flag:extd_apicid
+#: modules/devices/x86/x86_data.c:106
+msgctxt "x86-flag"
+msgid "has extended APICID (8 bits)"
+msgstr "tiene extenciones APICID (8 bits)"
+
+#. /flag:amd_dcm
+#: modules/devices/x86/x86_data.c:107
+msgctxt "x86-flag"
+msgid "multi-node processor"
+msgstr "procesador muti-nodo"
+
+#. /flag:aperfmperf
+#: modules/devices/x86/x86_data.c:108
+msgctxt "x86-flag"
+msgid "APERFMPERF"
+msgstr "APERFMPERF"
+
+#. /flag:eagerfpu
+#: modules/devices/x86/x86_data.c:109
+msgctxt "x86-flag"
+msgid "Non lazy FPU restore"
+msgstr "FPU restauracion tardia"
+
+#. /flag:nonstop_tsc_s3
+#: modules/devices/x86/x86_data.c:110
+msgctxt "x86-flag"
+msgid "TSC doesn't stop in S3 state"
+msgstr "TSC no se detiene en estado S3"
+
+#. /flag:mce_recovery
+#: modules/devices/x86/x86_data.c:111
+msgctxt "x86-flag"
+msgid "CPU has recoverable machine checks"
+msgstr "CPU tiene corroborador de maquina recuperable"
+
+#. /flag:pni
+#: modules/devices/x86/x86_data.c:114
+msgctxt "x86-flag"
+msgid "SSE-3 (\"Prescott New Instructions\")"
+msgstr "SSE-3 (\"Nuevas Instrucciones Prescott\")"
+
+#. /flag:pclmulqdq
+#: modules/devices/x86/x86_data.c:115
+msgctxt "x86-flag"
+msgid ""
+"Perform a Carry-Less Multiplication of Quadword instruction - accelerator "
+"for GCM)"
+msgstr ""
+"Realizar una Multiplicación Vaga de la instrucción - aceleracion Quadword "
+"para GCM)"
+
+#. /flag:dtes64
+#: modules/devices/x86/x86_data.c:116
+msgctxt "x86-flag"
+msgid "64-bit Debug Store"
+msgstr "Almacenamiento de depuracion 64-bit"
+
+#. /flag:monitor
+#: modules/devices/x86/x86_data.c:117
+msgctxt "x86-flag"
+msgid "Monitor/Mwait support (Intel SSE3 supplements)"
+msgstr "Soporte Monitor/Mwait (suplementos Intel SSE3"
+
+#. /flag:ds_cpl
+#: modules/devices/x86/x86_data.c:118
+msgctxt "x86-flag"
+msgid "CPL Qual. Debug Store"
+msgstr "CPL Qual. Debug Store"
+
+#. /flag:vmx
+#: modules/devices/x86/x86_data.c:119
+msgctxt "x86-flag"
+msgid "Hardware virtualization, Intel VMX"
+msgstr "Virtualizacion de hardware, Intel VMX"
+
+#. /flag:smx
+#: modules/devices/x86/x86_data.c:120
+msgctxt "x86-flag"
+msgid "Safer mode TXT (TPM support)"
+msgstr "Mode asegurado TXT (soporte TPM)"
+
+#. /flag:est
+#: modules/devices/x86/x86_data.c:121
+msgctxt "x86-flag"
+msgid "Enhanced SpeedStep"
+msgstr "SpeedStep ampliado"
+
+#. /flag:tm2
+#: modules/devices/x86/x86_data.c:122
+msgctxt "x86-flag"
+msgid "Thermal Monitor 2"
+msgstr "Monitor termico 2"
+
+#. /flag:ssse3
+#: modules/devices/x86/x86_data.c:123
+msgctxt "x86-flag"
+msgid "Supplemental SSE-3"
+msgstr "Suplemento SSE-3"
+
+#. /flag:cid
+#: modules/devices/x86/x86_data.c:124
+msgctxt "x86-flag"
+msgid "Context ID"
+msgstr "Contexto ID"
+
+#. /flag:sdbg
+#: modules/devices/x86/x86_data.c:125
+msgctxt "x86-flag"
+msgid "silicon debug"
+msgstr "depurador silicon"
+
+#. /flag:fma
+#: modules/devices/x86/x86_data.c:126
+msgctxt "x86-flag"
+msgid "Fused multiply-add"
+msgstr ""
+
+#. /flag:cx16
+#: modules/devices/x86/x86_data.c:127
+msgctxt "x86-flag"
+msgid "CMPXCHG16B"
+msgstr "CMPXCHG16B"
+
+#. /flag:xtpr
+#: modules/devices/x86/x86_data.c:128
+msgctxt "x86-flag"
+msgid "Send Task Priority Messages"
+msgstr "Enviador de Mesajes de Prioridad de Tareas"
+
+#. /flag:pdcm
+#: modules/devices/x86/x86_data.c:129
+msgctxt "x86-flag"
+msgid "Performance Capabilities"
+msgstr "Capacidades de Rendimiento"
+
+#. /flag:pcid
+#: modules/devices/x86/x86_data.c:130
+msgctxt "x86-flag"
+msgid "Process Context Identifiers"
+msgstr "Identificador de contexto de proceso"
+
+#. /flag:dca
+#: modules/devices/x86/x86_data.c:131
+msgctxt "x86-flag"
+msgid "Direct Cache Access"
+msgstr "Acceso Directo de Cache"
+
+#. /flag:sse4_1
+#: modules/devices/x86/x86_data.c:132
+msgctxt "x86-flag"
+msgid "SSE-4.1"
+msgstr "SSE-4.1"
+
+#. /flag:sse4_2
+#: modules/devices/x86/x86_data.c:133
+msgctxt "x86-flag"
+msgid "SSE-4.2"
+msgstr "SSE-4.2"
+
+#. /flag:x2apic
+#: modules/devices/x86/x86_data.c:134
+msgctxt "x86-flag"
+msgid "x2APIC"
+msgstr "x2APIC"
+
+#. /flag:movbe
+#: modules/devices/x86/x86_data.c:135
+msgctxt "x86-flag"
+msgid "Move Data After Swapping Bytes instruction"
+msgstr ""
+
+#. /flag:popcnt
+#: modules/devices/x86/x86_data.c:136
+msgctxt "x86-flag"
+msgid ""
+"Return the Count of Number of Bits Set to 1 instruction (Hamming weight, i."
+"e. bit count)"
+msgstr ""
+"Devuelve la cuenta de número de bits establecida en 1 instrucción (Hamming "
+"weight, ex. cuenta bit)"
+
+#. /flag:tsc_deadline_timer
+#: modules/devices/x86/x86_data.c:137
+msgctxt "x86-flag"
+msgid "Tsc deadline timer"
+msgstr "Tsc deadline timer"
+
+#. /flag:aes/aes-ni
+#: modules/devices/x86/x86_data.c:138
+msgctxt "x86-flag"
+msgid "Advanced Encryption Standard (New Instructions)"
+msgstr "Estándar de cifrado avanzado (nuevas instrucciones)"
+
+#. /flag:xsave
+#: modules/devices/x86/x86_data.c:139
+msgctxt "x86-flag"
+msgid "Save Processor Extended States: also provides XGETBY,XRSTOR,XSETBY"
+msgstr ""
+"Save Processor Extended States: también proporciona XGETBY, XRSTOR, XSETBY"
+
+#. /flag:avx
+#: modules/devices/x86/x86_data.c:140
+msgctxt "x86-flag"
+msgid "Advanced Vector Extensions"
+msgstr ""
+
+#. /flag:f16c
+#: modules/devices/x86/x86_data.c:141
+msgctxt "x86-flag"
+msgid "16-bit fp conversions (CVT16)"
+msgstr "conversiones fp 16-bit (CVT16)"
+
+#. /flag:rdrand
+#: modules/devices/x86/x86_data.c:142
+msgctxt "x86-flag"
+msgid "Read Random Number from hardware random number generator instruction"
+msgstr ""
+"Lector de Numeros Aleatorios desde generador de instruccion de aleatorios de "
+"Hardware"
+
+#. /flag:hypervisor
+#: modules/devices/x86/x86_data.c:143
+msgctxt "x86-flag"
+msgid "Running on a hypervisor"
+msgstr "Corriendo en un hipervisor"
+
+#. /Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001
+#. /flag:rng
+#: modules/devices/x86/x86_data.c:145
+msgctxt "x86-flag"
+msgid "Random Number Generator present (xstore)"
+msgstr "Generador de numeros aleatorios presente (xstore)"
+
+#. /flag:rng_en
+#: modules/devices/x86/x86_data.c:146
+msgctxt "x86-flag"
+msgid "Random Number Generator enabled"
+msgstr "Generador de numeros aleatorios activo"
+
+#. /flag:ace
+#: modules/devices/x86/x86_data.c:147
+msgctxt "x86-flag"
+msgid "on-CPU crypto (xcrypt)"
+msgstr "encriptacion en-CPU (xcrypt)"
+
+#. /flag:ace_en
+#: modules/devices/x86/x86_data.c:148
+msgctxt "x86-flag"
+msgid "on-CPU crypto enabled"
+msgstr "encriptacion en-CPU activada"
+
+#. /flag:ace2
+#: modules/devices/x86/x86_data.c:149
+msgctxt "x86-flag"
+msgid "Advanced Cryptography Engine v2"
+msgstr "Manejador Encriptamiento Avanzado v2"
+
+#. /flag:ace2_en
+#: modules/devices/x86/x86_data.c:150
+msgctxt "x86-flag"
+msgid "ACE v2 enabled"
+msgstr "ACE v2 presente"
+
+#. /flag:phe
+#: modules/devices/x86/x86_data.c:151
+msgctxt "x86-flag"
+msgid "PadLock Hash Engine"
+msgstr "Manejador PadLock Hash"
+
+#. /flag:phe_en
+#: modules/devices/x86/x86_data.c:152
+msgctxt "x86-flag"
+msgid "PHE enabled"
+msgstr "PHE presente"
+
+#. /flag:pmm
+#: modules/devices/x86/x86_data.c:153
+msgctxt "x86-flag"
+msgid "PadLock Montgomery Multiplier"
+msgstr "PadLock Montgomery Multiplier"
+
+#. /flag:pmm_en
+#: modules/devices/x86/x86_data.c:154
+msgctxt "x86-flag"
+msgid "PMM enabled"
+msgstr "PMM presente"
+
+#. /flag:lahf_lm
+#: modules/devices/x86/x86_data.c:156
+msgctxt "x86-flag"
+msgid "Load AH from Flags (LAHF) and Store AH into Flags (SAHF) in long mode"
+msgstr "Carga AH desde Flags (LAHF) y almacena AH en Flags (SAHF) en modo long"
+
+#. /flag:cmp_legacy
+#: modules/devices/x86/x86_data.c:157
+msgctxt "x86-flag"
+msgid "If yes HyperThreading not valid"
+msgstr "Si yes/si HyperThreading no valido"
+
+#. /flag:svm
+#: modules/devices/x86/x86_data.c:158
+msgctxt "x86-flag"
+msgid "\"Secure virtual machine\": AMD-V"
+msgstr "\"Maquina Virtual Segura\": AMD-V"
+
+#. /flag:extapic
+#: modules/devices/x86/x86_data.c:159
+msgctxt "x86-flag"
+msgid "Extended APIC space"
+msgstr "Espacio APIC Extendida"
+
+#. /flag:cr8_legacy
+#: modules/devices/x86/x86_data.c:160
+msgctxt "x86-flag"
+msgid "CR8 in 32-bit mode"
+msgstr "CR8 en modo 32-bit"
+
+#. /flag:abm
+#: modules/devices/x86/x86_data.c:161
+msgctxt "x86-flag"
+msgid "Advanced Bit Manipulation"
+msgstr "Advanced Bit Manipulation"
+
+#. /flag:sse4a
+#: modules/devices/x86/x86_data.c:162
+msgctxt "x86-flag"
+msgid "SSE-4A"
+msgstr "SSE-4A"
+
+#. /flag:misalignsse
+#: modules/devices/x86/x86_data.c:163
+msgctxt "x86-flag"
+msgid ""
+"indicates if a general-protection exception (#GP) is generated when some "
+"legacy SSE instructions operate on unaligned data. Also depends on CR0 and "
+"Alignment Checking bit"
+msgstr ""
+"Indica si se genera una excepción de protección general (#GP) cuando algunas "
+"instrucciones heredadas de SSE funcionan con datos no alineados. También "
+"depende de CR0 y Alignment Checking bit"
+
+#. /flag:3dnowprefetch
+#: modules/devices/x86/x86_data.c:164
+msgctxt "x86-flag"
+msgid "3DNow prefetch instructions"
+msgstr "Instrucciones 3DNow prefetch"
+
+#. /flag:osvw
+#: modules/devices/x86/x86_data.c:165
+msgctxt "x86-flag"
+msgid ""
+"indicates OS Visible Workaround, which allows the OS to work around "
+"processor errata."
+msgstr ""
+"indica medidas visibles al OS, que permitan que el OS pueda manejar erratas "
+"del procesador"
+
+#. /flag:ibs
+#: modules/devices/x86/x86_data.c:166
+msgctxt "x86-flag"
+msgid "Instruction Based Sampling"
+msgstr "Instruction Based Sampling"
+
+#. /flag:xop
+#: modules/devices/x86/x86_data.c:167
+msgctxt "x86-flag"
+msgid "extended AVX instructions"
+msgstr "Instrucciones AVX extendidas"
+
+#. /flag:skinit
+#: modules/devices/x86/x86_data.c:168
+msgctxt "x86-flag"
+msgid "SKINIT/STGI instructions"
+msgstr "Instrucciones SKINIT/STGI"
+
+#. /flag:wdt
+#: modules/devices/x86/x86_data.c:169
+msgctxt "x86-flag"
+msgid "Watchdog timer"
+msgstr ""
+
+#. /flag:lwp
+#: modules/devices/x86/x86_data.c:170
+msgctxt "x86-flag"
+msgid "Light Weight Profiling"
+msgstr ""
+
+#. /flag:fma4
+#: modules/devices/x86/x86_data.c:171
+msgctxt "x86-flag"
+msgid "4 operands MAC instructions"
+msgstr ""
+
+#. /flag:tce
+#: modules/devices/x86/x86_data.c:172
+msgctxt "x86-flag"
+msgid "translation cache extension"
+msgstr ""
+
+#. /flag:nodeid_msr
+#: modules/devices/x86/x86_data.c:173
+msgctxt "x86-flag"
+msgid "NodeId MSR"
+msgstr ""
+
+#. /flag:tbm
+#: modules/devices/x86/x86_data.c:174
+msgctxt "x86-flag"
+msgid "Trailing Bit Manipulation"
+msgstr ""
+
+#. /flag:topoext
+#: modules/devices/x86/x86_data.c:175
+msgctxt "x86-flag"
+msgid "Topology Extensions CPUID leafs"
+msgstr ""
+
+#. /flag:perfctr_core
+#: modules/devices/x86/x86_data.c:176
+msgctxt "x86-flag"
+msgid "Core Performance Counter Extensions"
+msgstr ""
+
+#. /flag:perfctr_nb
+#: modules/devices/x86/x86_data.c:177
+msgctxt "x86-flag"
+msgid "NB Performance Counter Extensions"
+msgstr ""
+
+#. /flag:bpext
+#: modules/devices/x86/x86_data.c:178
+msgctxt "x86-flag"
+msgid "data breakpoint extension"
+msgstr ""
+
+#. /flag:ptsc
+#: modules/devices/x86/x86_data.c:179
+msgctxt "x86-flag"
+msgid "performance time-stamp counter"
+msgstr ""
+
+#. /flag:perfctr_l2
+#: modules/devices/x86/x86_data.c:180
+msgctxt "x86-flag"
+msgid "L2 Performance Counter Extensions"
+msgstr ""
+
+#. /flag:mwaitx
+#: modules/devices/x86/x86_data.c:181
+msgctxt "x86-flag"
+msgid "MWAIT extension (MONITORX/MWAITX)"
+msgstr ""
+
+#. /flag:cpb
+#: modules/devices/x86/x86_data.c:183
+msgctxt "x86-flag"
+msgid "AMD Core Performance Boost"
+msgstr ""
+
+#. /flag:epb
+#: modules/devices/x86/x86_data.c:184
+msgctxt "x86-flag"
+msgid "IA32_ENERGY_PERF_BIAS support"
+msgstr ""
+
+#. /flag:hw_pstate
+#: modules/devices/x86/x86_data.c:185
+msgctxt "x86-flag"
+msgid "AMD HW-PState"
+msgstr ""
+
+#. /flag:proc_feedback
+#: modules/devices/x86/x86_data.c:186
+msgctxt "x86-flag"
+msgid "AMD ProcFeedbackInterface"
+msgstr ""
+
+#. /flag:intel_pt
+#: modules/devices/x86/x86_data.c:187
+msgctxt "x86-flag"
+msgid "Intel Processor Tracing"
+msgstr ""
+
+#. /flag:tpr_shadow
+#: modules/devices/x86/x86_data.c:189
+msgctxt "x86-flag"
+msgid "Intel TPR Shadow"
+msgstr ""
+
+#. /flag:vnmi
+#: modules/devices/x86/x86_data.c:190
+msgctxt "x86-flag"
+msgid "Intel Virtual NMI"
+msgstr ""
+
+#. /flag:flexpriority
+#: modules/devices/x86/x86_data.c:191
+msgctxt "x86-flag"
+msgid "Intel FlexPriority"
+msgstr ""
+
+#. /flag:ept
+#: modules/devices/x86/x86_data.c:192
+msgctxt "x86-flag"
+msgid "Intel Extended Page Table"
+msgstr ""
+
+#. /flag:vpid
+#: modules/devices/x86/x86_data.c:193
+msgctxt "x86-flag"
+msgid "Intel Virtual Processor ID"
+msgstr ""
+
+#. /flag:vmmcall
+#: modules/devices/x86/x86_data.c:194
+msgctxt "x86-flag"
+msgid "prefer VMMCALL to VMCALL"
+msgstr ""
+
+#. /flag:fsgsbase
+#: modules/devices/x86/x86_data.c:196
+msgctxt "x86-flag"
+msgid "{RD/WR}{FS/GS}BASE instructions"
+msgstr ""
+
+#. /flag:tsc_adjust
+#: modules/devices/x86/x86_data.c:197
+msgctxt "x86-flag"
+msgid "TSC adjustment MSR"
+msgstr ""
+
+#. /flag:bmi1
+#: modules/devices/x86/x86_data.c:198
+msgctxt "x86-flag"
+msgid "1st group bit manipulation extensions"
+msgstr ""
+
+#. /flag:hle
+#: modules/devices/x86/x86_data.c:199
+msgctxt "x86-flag"
+msgid "Hardware Lock Elision"
+msgstr ""
+
+#. /flag:avx2
+#: modules/devices/x86/x86_data.c:200
+msgctxt "x86-flag"
+msgid "AVX2 instructions"
+msgstr "Instrucciones AVX2"
+
+#. /flag:smep
+#: modules/devices/x86/x86_data.c:201
+msgctxt "x86-flag"
+msgid "Supervisor Mode Execution Protection"
+msgstr ""
+
+#. /flag:bmi2
+#: modules/devices/x86/x86_data.c:202
+msgctxt "x86-flag"
+msgid "2nd group bit manipulation extensions"
+msgstr ""
+
+#. /flag:erms
+#: modules/devices/x86/x86_data.c:203
+msgctxt "x86-flag"
+msgid "Enhanced REP MOVSB/STOSB"
+msgstr ""
+
+#. /flag:invpcid
+#: modules/devices/x86/x86_data.c:204
+msgctxt "x86-flag"
+msgid "Invalidate Processor Context ID"
+msgstr ""
+
+#. /flag:rtm
+#: modules/devices/x86/x86_data.c:205
+msgctxt "x86-flag"
+msgid "Restricted Transactional Memory"
+msgstr ""
+
+#. /flag:cqm
+#: modules/devices/x86/x86_data.c:206
+msgctxt "x86-flag"
+msgid "Cache QoS Monitoring"
+msgstr ""
+
+#. /flag:mpx
+#: modules/devices/x86/x86_data.c:207
+msgctxt "x86-flag"
+msgid "Memory Protection Extension"
+msgstr ""
+
+#. /flag:avx512f
+#: modules/devices/x86/x86_data.c:208
+msgctxt "x86-flag"
+msgid "AVX-512 foundation"
+msgstr ""
+
+#. /flag:avx512dq
+#: modules/devices/x86/x86_data.c:209
+msgctxt "x86-flag"
+msgid "AVX-512 Double/Quad instructions"
+msgstr ""
+
+#. /flag:rdseed
+#: modules/devices/x86/x86_data.c:210
+msgctxt "x86-flag"
+msgid "The RDSEED instruction"
+msgstr ""
+
+#. /flag:adx
+#: modules/devices/x86/x86_data.c:211
+msgctxt "x86-flag"
+msgid "The ADCX and ADOX instructions"
+msgstr ""
+
+#. /flag:smap
+#: modules/devices/x86/x86_data.c:212
+msgctxt "x86-flag"
+msgid "Supervisor Mode Access Prevention"
+msgstr ""
+
+#. /flag:clflushopt
+#: modules/devices/x86/x86_data.c:213
+msgctxt "x86-flag"
+msgid "CLFLUSHOPT instruction"
+msgstr ""
+
+#. /flag:clwb
+#: modules/devices/x86/x86_data.c:214
+msgctxt "x86-flag"
+msgid "CLWB instruction"
+msgstr ""
+
+#. /flag:avx512pf
+#: modules/devices/x86/x86_data.c:215
+msgctxt "x86-flag"
+msgid "AVX-512 Prefetch"
+msgstr ""
+
+#. /flag:avx512er
+#: modules/devices/x86/x86_data.c:216
+msgctxt "x86-flag"
+msgid "AVX-512 Exponential and Reciprocal"
+msgstr ""
+
+#. /flag:avx512cd
+#: modules/devices/x86/x86_data.c:217
+msgctxt "x86-flag"
+msgid "AVX-512 Conflict Detection"
+msgstr ""
+
+#. /flag:sha_ni
+#: modules/devices/x86/x86_data.c:218
+msgctxt "x86-flag"
+msgid "SHA1/SHA256 Instruction Extensions"
+msgstr ""
+
+#. /flag:avx512bw
+#: modules/devices/x86/x86_data.c:219
+msgctxt "x86-flag"
+msgid "AVX-512 Byte/Word instructions"
+msgstr ""
+
+#. /flag:avx512vl
+#: modules/devices/x86/x86_data.c:220
+msgctxt "x86-flag"
+msgid "AVX-512 128/256 Vector Length extensions"
+msgstr ""
+
+#. /flag:xsaveopt
+#: modules/devices/x86/x86_data.c:222
+msgctxt "x86-flag"
+msgid "Optimized XSAVE"
+msgstr ""
+
+#. /flag:xsavec
+#: modules/devices/x86/x86_data.c:223
+msgctxt "x86-flag"
+msgid "XSAVEC"
+msgstr ""
+
+#. /flag:xgetbv1
+#: modules/devices/x86/x86_data.c:224
+msgctxt "x86-flag"
+msgid "XGETBV with ECX = 1"
+msgstr ""
+
+#. /flag:xsaves
+#: modules/devices/x86/x86_data.c:225
+msgctxt "x86-flag"
+msgid "XSAVES/XRSTORS"
+msgstr ""
+
+#. /flag:cqm_llc
+#: modules/devices/x86/x86_data.c:227
+msgctxt "x86-flag"
+msgid "LLC QoS"
+msgstr ""
+
+#. /flag:cqm_occup_llc
+#: modules/devices/x86/x86_data.c:229
+msgctxt "x86-flag"
+msgid "LLC occupancy monitoring"
+msgstr ""
+
+#. /flag:cqm_mbm_total
+#: modules/devices/x86/x86_data.c:230
+msgctxt "x86-flag"
+msgid "LLC total MBM monitoring"
+msgstr ""
+
+#. /flag:cqm_mbm_local
+#: modules/devices/x86/x86_data.c:231
+msgctxt "x86-flag"
+msgid "LLC local MBM monitoring"
+msgstr ""
+
+#. /flag:clzero
+#: modules/devices/x86/x86_data.c:233
+msgctxt "x86-flag"
+msgid "CLZERO instruction"
+msgstr ""
+
+#. /flag:irperf
+#: modules/devices/x86/x86_data.c:234
+msgctxt "x86-flag"
+msgid "instructions retired performance counter"
+msgstr ""
+
+#. /flag:dtherm
+#: modules/devices/x86/x86_data.c:236
+msgctxt "x86-flag"
+msgid "digital thermal sensor"
+msgstr ""
+
+#. /flag:ida
+#: modules/devices/x86/x86_data.c:237
+msgctxt "x86-flag"
+msgid "Intel Dynamic Acceleration"
+msgstr ""
+
+#. /flag:arat
+#: modules/devices/x86/x86_data.c:238
+msgctxt "x86-flag"
+msgid "Always Running APIC Timer"
+msgstr ""
+
+#. /flag:pln
+#: modules/devices/x86/x86_data.c:239
+msgctxt "x86-flag"
+msgid "Intel Power Limit Notification"
+msgstr ""
+
+#. /flag:pts
+#: modules/devices/x86/x86_data.c:240
+msgctxt "x86-flag"
+msgid "Intel Package Thermal Status"
+msgstr ""
+
+#. /flag:hwp
+#: modules/devices/x86/x86_data.c:241
+msgctxt "x86-flag"
+msgid "Intel Hardware P-states"
+msgstr ""
+
+#. /flag:hwp_notify
+#: modules/devices/x86/x86_data.c:242
+msgctxt "x86-flag"
+msgid "HWP notification"
+msgstr ""
+
+#. /flag:hwp_act_window
+#: modules/devices/x86/x86_data.c:243
+msgctxt "x86-flag"
+msgid "HWP Activity Window"
+msgstr ""
+
+#. /flag:hwp_epp
+#: modules/devices/x86/x86_data.c:244
+msgctxt "x86-flag"
+msgid "HWP Energy Performance Preference"
+msgstr ""
+
+#. /flag:hwp_pkg_req
+#: modules/devices/x86/x86_data.c:245
+msgctxt "x86-flag"
+msgid "HWP package-level request"
+msgstr ""
+
+#. /flag:npt
+#: modules/devices/x86/x86_data.c:247
+msgctxt "x86-flag"
+msgid "AMD Nested Page Table support"
+msgstr ""
+
+#. /flag:lbrv
+#: modules/devices/x86/x86_data.c:248
+msgctxt "x86-flag"
+msgid "AMD LBR Virtualization support"
+msgstr ""
+
+#. /flag:svm_lock
+#: modules/devices/x86/x86_data.c:249
+msgctxt "x86-flag"
+msgid "AMD SVM locking MSR"
+msgstr ""
+
+#. /flag:nrip_save
+#: modules/devices/x86/x86_data.c:250
+msgctxt "x86-flag"
+msgid "AMD SVM next_rip save"
+msgstr ""
+
+#. /flag:tsc_scale
+#: modules/devices/x86/x86_data.c:251
+msgctxt "x86-flag"
+msgid "AMD TSC scaling support"
+msgstr ""
+
+#. /flag:vmcb_clean
+#: modules/devices/x86/x86_data.c:252
+msgctxt "x86-flag"
+msgid "AMD VMCB clean bits support"
+msgstr ""
+
+#. /flag:flushbyasid
+#: modules/devices/x86/x86_data.c:253
+msgctxt "x86-flag"
+msgid "AMD flush-by-ASID support"
+msgstr ""
+
+#. /flag:decodeassists
+#: modules/devices/x86/x86_data.c:254
+msgctxt "x86-flag"
+msgid "AMD Decode Assists support"
+msgstr ""
+
+#. /flag:pausefilter
+#: modules/devices/x86/x86_data.c:255
+msgctxt "x86-flag"
+msgid "AMD filtered pause intercept"
+msgstr ""
+
+#. /flag:pfthreshold
+#: modules/devices/x86/x86_data.c:256
+msgctxt "x86-flag"
+msgid "AMD pause filter threshold"
+msgstr ""
+
+#. /flag:avic
+#: modules/devices/x86/x86_data.c:257
+msgctxt "x86-flag"
+msgid "Virtual Interrupt Controller"
+msgstr ""
+
+#. /flag:pku
+#: modules/devices/x86/x86_data.c:259
+msgctxt "x86-flag"
+msgid "Protection Keys for Userspace"
+msgstr ""
+
+#. /flag:ospke
+#: modules/devices/x86/x86_data.c:260
+msgctxt "x86-flag"
+msgid "OS Protection Keys Enable"
+msgstr ""
+
+#. /flag:overflow_recov
+#: modules/devices/x86/x86_data.c:262
+msgctxt "x86-flag"
+msgid "MCA overflow recovery support"
+msgstr ""
+
+#. /flag:succor
+#: modules/devices/x86/x86_data.c:263
+msgctxt "x86-flag"
+msgid "uncorrectable error containment and recovery"
+msgstr ""
+
+#. /flag:smca
+#: modules/devices/x86/x86_data.c:264
+msgctxt "x86-flag"
+msgid "Scalable MCA"
+msgstr ""
+
+#. /bug:f00f
+#: modules/devices/x86/x86_data.c:267
+msgctxt "x86-flag"
+msgid "Intel F00F bug"
+msgstr ""
+
+#. /bug:fdiv
+#: modules/devices/x86/x86_data.c:268
+msgctxt "x86-flag"
+msgid "FPU FDIV"
+msgstr ""
+
+#. /bug:coma
+#: modules/devices/x86/x86_data.c:269
+msgctxt "x86-flag"
+msgid "Cyrix 6x86 coma"
+msgstr ""
+
+#. /bug:tlb_mmatch
+#: modules/devices/x86/x86_data.c:270
+msgctxt "x86-flag"
+msgid "AMD Erratum 383"
+msgstr ""
+
+#. /bug:apic_c1e
+#. /bug:amd_e400
+#: modules/devices/x86/x86_data.c:271 modules/devices/x86/x86_data.c:280
+msgctxt "x86-flag"
+msgid "AMD Erratum 400"
+msgstr ""
+
+#. /bug:11ap
+#: modules/devices/x86/x86_data.c:272
+msgctxt "x86-flag"
+msgid "Bad local APIC aka 11AP"
+msgstr ""
+
+#. /bug:fxsave_leak
+#: modules/devices/x86/x86_data.c:273
+msgctxt "x86-flag"
+msgid "FXSAVE leaks FOP/FIP/FOP"
+msgstr ""
+
+#. /bug:clflush_monitor
+#: modules/devices/x86/x86_data.c:274
+msgctxt "x86-flag"
+msgid "AAI65, CLFLUSH required before MONITOR"
+msgstr ""
+
+#. /bug:sysret_ss_attrs
+#: modules/devices/x86/x86_data.c:275
+msgctxt "x86-flag"
+msgid "SYSRET doesn't fix up SS attrs"
+msgstr ""
+
+#. /bug:espfix
+#: modules/devices/x86/x86_data.c:276
+msgctxt "x86-flag"
+msgid "IRET to 16-bit SS corrupts ESP/RSP high bits"
+msgstr ""
+
+#. /bug:null_seg
+#: modules/devices/x86/x86_data.c:277
+msgctxt "x86-flag"
+msgid "Nulling a selector preserves the base"
+msgstr ""
+
+#. /bug:swapgs_fence
+#: modules/devices/x86/x86_data.c:278
+msgctxt "x86-flag"
+msgid "SWAPGS without input dep on GS"
+msgstr ""
+
+#. /bug:monitor
+#: modules/devices/x86/x86_data.c:279
+msgctxt "x86-flag"
+msgid "IPI required to wake up remote CPU"
+msgstr ""
+
+#. /x86/kernel/cpu/powerflags.h
+#. /flag:pm:ts
+#: modules/devices/x86/x86_data.c:283
+msgctxt "x86-flag"
+msgid "temperature sensor"
+msgstr "sensor de temparatura"
+
+#. /flag:pm:fid
+#: modules/devices/x86/x86_data.c:284
+msgctxt "x86-flag"
+msgid "frequency id control"
+msgstr "id de control frecuencia"
+
+#. /flag:pm:vid
+#: modules/devices/x86/x86_data.c:285
+msgctxt "x86-flag"
+msgid "voltage id control"
+msgstr "id control voltage"
+
+#. /flag:pm:ttp
+#: modules/devices/x86/x86_data.c:286
+msgctxt "x86-flag"
+msgid "thermal trip"
+msgstr "limite termico"
+
+#. /flag:pm:tm
+#: modules/devices/x86/x86_data.c:287
+msgctxt "x86-flag"
+msgid "hardware thermal control"
+msgstr "control terminco por hardware"
+
+#. /flag:pm:stc
+#: modules/devices/x86/x86_data.c:288
+msgctxt "x86-flag"
+msgid "software thermal control"
+msgstr "control terminco por software"
+
+#. /flag:pm:100mhzsteps
+#: modules/devices/x86/x86_data.c:289
+msgctxt "x86-flag"
+msgid "100 MHz multiplier control"
+msgstr "control multiplicador 100MHz"
+
+#. /flag:pm:hwpstate
+#: modules/devices/x86/x86_data.c:290
+msgctxt "x86-flag"
+msgid "hardware P-state control"
+msgstr "control hardware de P-state"
+
+#. /flag:pm:cpb
+#: modules/devices/x86/x86_data.c:291
+msgctxt "x86-flag"
+msgid "core performance boost"
+msgstr "Impulso de rendimiento básico"
+
+#. /flag:pm:eff_freq_ro
+#: modules/devices/x86/x86_data.c:292
+msgctxt "x86-flag"
+msgid "Readonly aperf/mperf"
+msgstr ""
+
+#. /flag:pm:proc_feedback
+#: modules/devices/x86/x86_data.c:293
+msgctxt "x86-flag"
+msgid "processor feedback interface"
+msgstr "interfez de retroalimentacion de procesador"
+
+#. /flag:pm:acc_power
+#: modules/devices/x86/x86_data.c:294
+msgctxt "x86-flag"
+msgid "accumulated power mechanism"
+msgstr "mecanismo de energia acumulada"
+
+#: modules/network.c:59
+msgid "Interfaces"
+msgstr "Interfaces"
+
+#: modules/network.c:60
+msgid "IP Connections"
+msgstr "Conexiones IP"
+
+#: modules/network.c:61
+msgid "Routing Table"
+msgstr "Tabla de ruteo"
+
+#: modules/network.c:62 modules/network.c:303
+msgid "ARP Table"
+msgstr "Tabla ARP"
+
+#: modules/network.c:63
+msgid "DNS Servers"
+msgstr "Servidores DNS"
+
+#: modules/network.c:64
+msgid "Statistics"
+msgstr "Estadísticas"
+
+#: modules/network.c:65
+msgid "Shared Directories"
+msgstr "Directorios compartidos"
+
+#: modules/network.c:304 modules/network.c:326 modules/network.c:357
+#: modules/network/net.c:477
+msgid "IP Address"
+msgstr "Dirección IP"
+
+#: modules/network.c:304 modules/network.c:357 modules/network.c:374
+msgid "Interface"
+msgstr "Interfaz"
+
+#: modules/network.c:304
+msgid "MAC Address"
+msgstr "Dirección MAC"
+
+#: modules/network.c:313
+msgid "SAMBA"
+msgstr "SAMBA"
+
+#: modules/network.c:314
+msgid "NFS"
+msgstr "NFS"
+
+#: modules/network.c:325
+msgid "Name Servers"
+msgstr "Servidores de nombres"
+
+#: modules/network.c:340
+msgid "Connections"
+msgstr "Conexiones"
+
+#: modules/network.c:341
+msgid "Local Address"
+msgstr "Direccion local"
+
+#: modules/network.c:341
+msgid "Protocol"
+msgstr "Protocolo"
+
+#: modules/network.c:341
+msgid "Foreign Address"
+msgstr "Direccion enlazada"
+
+#: modules/network.c:341
+msgid "State"
+msgstr "Estado"
+
+#: modules/network.c:357
+msgid "Sent"
+msgstr "Enviado"
+
+#: modules/network.c:357
+msgid "Received"
+msgstr "Recibido"
+
+#: modules/network.c:373
+msgid "IP routing table"
+msgstr "Tabla de ruteo IP"
+
+#: modules/network.c:374
+msgid "Destination/Gateway"
+msgstr "Destino/Puerta de enlace"
+
+#: modules/network.c:374
+msgid "Flags"
+msgstr "Marcas"
+
+#: modules/network.c:374 modules/network/net.c:478
+msgid "Mask"
+msgstr "Máscara"
+
+#: modules/network.c:402
+msgid "Network"
+msgstr "Red"
+
+#: modules/network.c:435
+msgid "Gathers information about this computer's network connection"
+msgstr "Obtiene información sobre la conexión de red de esta computadora"
+
+#: modules/network/net.c:72
+msgctxt "wi-op-mode"
+msgid "Auto"
+msgstr "Auto"
+
+#: modules/network/net.c:73
+msgctxt "wi-op-mode"
+msgid "Ad-Hoc"
+msgstr "Ad-Hoc"
+
+#: modules/network/net.c:74
+msgctxt "wi-op-mode"
+msgid "Managed"
+msgstr "Manejada"
+
+#: modules/network/net.c:75
+msgctxt "wi-op-mode"
+msgid "Master"
+msgstr "Maestra"
+
+#: modules/network/net.c:76
+msgctxt "wi-op-mode"
+msgid "Repeater"
+msgstr "Repetidor"
+
+#: modules/network/net.c:77
+msgctxt "wi-op-mode"
+msgid "Secondary"
+msgstr "Secundaria"
+
+#: modules/network/net.c:78
+msgctxt "wi-op-mode"
+msgid "(Unknown)"
+msgstr "(desconocido)"
+
+#: modules/network/net.c:242 modules/network/net.c:262
+#: modules/network/net.c:270
+msgctxt "net-if-type"
+msgid "Ethernet"
+msgstr "Ethernet"
+
+#: modules/network/net.c:243
+msgctxt "net-if-type"
+msgid "Loopback"
+msgstr "Loopback"
+
+#: modules/network/net.c:244
+msgctxt "net-if-type"
+msgid "Point-to-Point"
+msgstr "Punto-a-Punto"
+
+#: modules/network/net.c:245 modules/network/net.c:246
+#: modules/network/net.c:247 modules/network/net.c:248
+#: modules/network/net.c:272
+msgctxt "net-if-type"
+msgid "Wireless"
+msgstr "Inalambrica"
+
+#: modules/network/net.c:249
+msgctxt "net-if-type"
+msgid "Virtual Point-to-Point (TUN)"
+msgstr "Virtual Punto-a-Punto (TUN)"
+
+#: modules/network/net.c:250
+msgctxt "net-if-type"
+msgid "Ethernet (TAP)"
+msgstr "Ethernet (TAP)"
+
+#: modules/network/net.c:251
+msgctxt "net-if-type"
+msgid "Parallel Line Internet Protocol"
+msgstr "Protocolo Linea Intenet Paralela"
+
+#: modules/network/net.c:252
+msgctxt "net-if-type"
+msgid "Infrared"
+msgstr "Infraroja"
+
+#: modules/network/net.c:253 modules/network/net.c:271
+msgctxt "net-if-type"
+msgid "Serial Line Internet Protocol"
+msgstr "Protocolo Internel Linea Serial"
+
+#: modules/network/net.c:254
+msgctxt "net-if-type"
+msgid "Integrated Services Digital Network"
+msgstr "Red de servicio digital (ISDN)"
+
+#: modules/network/net.c:255
+msgctxt "net-if-type"
+msgid "IPv6-over-IPv4 Tunnel"
+msgstr "Tunel IPv6-sobre-IPv4"
+
+#: modules/network/net.c:256
+msgctxt "net-if-type"
+msgid "VMWare Virtual Network Interface (NAT)"
+msgstr "Interfaz Red virtual VMWare (NAT)"
+
+#: modules/network/net.c:257
+msgctxt "net-if-type"
+msgid "VMWare Virtual Network Interface"
+msgstr "Interfaz Red virtual VMWare"
+
+#: modules/network/net.c:258
+msgctxt "net-if-type"
+msgid "Personal Area Network (PAN)"
+msgstr "Red de Area Personal (PAN)"
+
+#: modules/network/net.c:259
+msgctxt "net-if-type"
+msgid "Bluetooth"
+msgstr "Bluetooth"
+
+#: modules/network/net.c:260
+msgctxt "net-if-type"
+msgid "Bridge Interface"
+msgstr "Interfaz Puente"
+
+#: modules/network/net.c:261
+msgctxt "net-if-type"
+msgid "Hamachi Virtual Personal Network"
+msgstr "Red Virtual Personal Hamachi"
+
+#: modules/network/net.c:263
+msgctxt "net-if-type"
+msgid "Intermediate Functional Block"
+msgstr "Bloque funcional Intermediario"
+
+#: modules/network/net.c:264
+msgctxt "net-if-type"
+msgid "GRE Network Tunnel"
+msgstr "Tunel Red GRE"
+
+#: modules/network/net.c:265
+msgctxt "net-if-type"
+msgid "Mesh Network"
+msgstr "Red de malla"
+
+#: modules/network/net.c:266
+msgctxt "net-if-type"
+msgid "Wireless Master Interface"
+msgstr "Interfaz Maestra Inalambrica"
+
+#: modules/network/net.c:267
+msgctxt "net-if-type"
+msgid "VirtualBox Virtual Network Interface"
+msgstr "Interfaz Red Virtual VirtualBox"
+
+#: modules/network/net.c:273
+msgctxt "net-if-type"
+msgid "Wireless (WAN)"
+msgstr "Inalambrica (WAN)"
+
+#: modules/network/net.c:275
+msgctxt "net-if-type"
+msgid "(Unknown)"
+msgstr "(desconocida)"
+
+#: modules/network/net.c:348 modules/network/net.c:358
+msgid "Network Interfaces"
+msgstr "Interfaces de Red"
+
+#: modules/network/net.c:348
+msgid "None Found"
+msgstr "Ninguna encontrada"
+
+#: modules/network/net.c:400 modules/network/net.c:422
+#: modules/network/net.c:423
+msgid "MiB"
+msgstr "MiB"
+
+#: modules/network/net.c:414
+msgid "Network Adapter Properties"
+msgstr "Propiedades de adaptador"
+
+#: modules/network/net.c:415
+msgid "Interface Type"
+msgstr "Tipo interfaz"
+
+#: modules/network/net.c:416
+msgid "Hardware Address (MAC)"
+msgstr "Direccion fisica"
+
+#: modules/network/net.c:420
+msgid "MTU"
+msgstr "MTU"
+
+#: modules/network/net.c:421
+msgid "Transfer Details"
+msgstr "Detalles de transferencias"
+
+#: modules/network/net.c:422
+msgid "Bytes Received"
+msgstr "Bytes Recividos"
+
+#: modules/network/net.c:423
+msgid "Bytes Sent"
+msgstr "Bytes Enviados"
+
+#: modules/network/net.c:440 modules/network/net.c:462
+#: modules/network/net.c:463
+msgid "dBm"
+msgstr "dBm"
+
+#: modules/network/net.c:440
+msgid "mW"
+msgstr "mW"
+
+#: modules/network/net.c:454
+msgid "Wireless Properties"
+msgstr "Propiedades de Inalambrica"
+
+#: modules/network/net.c:455
+msgid "Network Name (SSID)"
+msgstr "Nombre de red (SSID)"
+
+#: modules/network/net.c:456
+msgid "Bit Rate"
+msgstr "Velocidad de bits"
+
+#: modules/network/net.c:456
+msgid "Mb/s"
+msgstr "Mb/s"
+
+#: modules/network/net.c:457
+msgid "Transmission Power"
+msgstr "Intensidad transmision"
+
+#: modules/network/net.c:459
+msgid "Status"
+msgstr "Estado"
+
+#: modules/network/net.c:460
+msgid "Link Quality"
+msgstr "Calidad enlace"
+
+#: modules/network/net.c:461
+msgid "Signal / Noise"
+msgstr "Señal / Ruido"
+
+#: modules/network/net.c:476
+msgid "Internet Protocol (IPv4)"
+msgstr "Protocolo Internet (IPv4)"
+
+#: modules/network/net.c:477 modules/network/net.c:478
+#: modules/network/net.c:480
+msgid "(Not set)"
+msgstr "(sin asignar)"
+
+#: modules/network/net.c:479
+msgid "Broadcast Address"
+msgstr "Dirección de Difusión"
+
+#~ msgid "pixels"
+#~ msgstr "pixeles"
+
+#~ msgid "Desktop Environment"
+#~ msgstr "Entorno de escritorio"
diff --git a/po/fr.po b/po/fr.po
new file mode 100644
index 0000000..627e528
--- /dev/null
+++ b/po/fr.po
@@ -0,0 +1,4429 @@
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Yo L <http://kreizenn-dafar.org>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: hardinfo\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2017-08-14 22:23-0500\n"
+"PO-Revision-Date: 2014-09-03\n"
+"Last-Translator: yolateng0 @olala22000\n"
+"Language-Team: LeFlood\n"
+"Language: fr\n"
+"X-Poedit-Basepath: ../\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+"X-Generator: Poedit 1.5.4\n"
+
+#. / %d will be latest year of copyright
+#: hardinfo/hardinfo.c:49
+#, c-format
+msgid ""
+"Copyright (C) 2003-%d Leandro A. F. Pereira. See COPYING for details.\n"
+"\n"
+msgstr ""
+"Copyright (C) 2003-%d Leandro A. F. Pereira. voir COPYING pour les details.\n"
+"\n"
+
+#: hardinfo/hardinfo.c:51
+#, c-format
+msgid ""
+"Compile-time options:\n"
+"  Release version:   %s (%s)\n"
+"  BinReloc enabled:  %s\n"
+"  Data prefix:       %s\n"
+"  Library prefix:    %s\n"
+"  Compiled for:      %s\n"
+msgstr ""
+"Compile-time options:\n"
+" \"Release\" version: %s (%s)\n"
+" BinReloc activé:   %s\n"
+" Data prefix:       %s\n"
+" Library prefix:    %s\n"
+" Compilation:       %s\n"
+
+#: hardinfo/hardinfo.c:57 hardinfo/hardinfo.c:58 modules/computer.c:605
+#: modules/devices/inputdevices.c:128 modules/devices/pci.c:112
+#: modules/devices/printers.c:138
+msgid "Yes"
+msgstr "Oui"
+
+#: hardinfo/hardinfo.c:58 modules/computer.c:605 modules/devices/pci.c:112
+#: modules/devices/printers.c:138
+msgid "No"
+msgstr "Non"
+
+#: hardinfo/hardinfo.c:69
+#, c-format
+msgid ""
+"Failed to find runtime data.\n"
+"\n"
+"• Is HardInfo correctly installed?\n"
+"• See if %s and %s exists and you have read permission."
+msgstr ""
+"Impossible de trouver les données d'exécution.\n"
+"\n"
+"• Est ce que HardInfo est correctement installé?\n"
+"• Voir si %s et %s existes et que vous avez bien les privilèges."
+
+#: hardinfo/hardinfo.c:76
+#, c-format
+msgid ""
+"Modules:\n"
+"%-20s %-15s %-12s\n"
+msgstr ""
+
+#: hardinfo/hardinfo.c:77
+msgid "File Name"
+msgstr "Nom du fichier"
+
+#: hardinfo/hardinfo.c:77 modules/computer.c:534 modules/computer.c:562
+#: modules/computer.c:630 modules/computer/languages.c:104
+#: modules/computer/modules.c:146 modules/devices/arm/processor.c:336
+#: modules/devices/ia64/processor.c:160 modules/devices/inputdevices.c:116
+#: modules/devices/pci.c:215 modules/devices/sh/processor.c:84
+#: modules/devices/x86/processor.c:455 modules/network.c:326
+msgid "Name"
+msgstr "Nom"
+
+#: hardinfo/hardinfo.c:77 modules/computer.c:296 modules/computer.c:505
+#: modules/computer.c:507 modules/computer.c:595 modules/computer.c:603
+#: modules/devices/inputdevices.c:121
+msgid "Version"
+msgstr "Version"
+
+#: hardinfo/hardinfo.c:124
+#, c-format
+msgid "Unknown benchmark ``%s'' or libbenchmark.so not loaded"
+msgstr "Benchmark inconnu ``%s'' ou libbenchmark.so non chargé"
+
+#: hardinfo/hardinfo.c:152
+msgid "Don't know what to do. Exiting."
+msgstr "Que faire. Sortie."
+
+#: hardinfo/util.c:104 modules/computer/uptime.c:53
+#, c-format
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] "%d jour"
+msgstr[1] "%d jours"
+
+#: hardinfo/util.c:105 modules/computer/uptime.c:54
+#, c-format
+msgid "%d hour"
+msgid_plural "%d hours"
+msgstr[0] "%d heure"
+msgstr[1] "%d heures"
+
+#: hardinfo/util.c:106 modules/computer/uptime.c:55
+#, c-format
+msgid "%d minute"
+msgid_plural "%d minutes"
+msgstr[0] "%d minute"
+msgstr[1] "%d minutes"
+
+#: hardinfo/util.c:107
+#, c-format
+msgid "%d second"
+msgid_plural "%d seconds"
+msgstr[0] "%d seconde"
+msgstr[1] "%d secondes"
+
+#: hardinfo/util.c:128
+#, c-format
+msgid "%.1f B"
+msgstr "%.1f B"
+
+#: hardinfo/util.c:130
+#, c-format
+msgid "%.1f KiB"
+msgstr "%.1f KiB"
+
+#: hardinfo/util.c:132
+#, c-format
+msgid "%.1f MiB"
+msgstr "%.1f MiB"
+
+#: hardinfo/util.c:134
+#, c-format
+msgid "%.1f GiB"
+msgstr "%.1f GiB"
+
+#: hardinfo/util.c:136
+#, c-format
+msgid "%.1f TiB"
+msgstr ""
+
+#: hardinfo/util.c:138
+#, c-format
+msgid "%.1f PiB"
+msgstr ""
+
+#: hardinfo/util.c:361
+msgid "Error"
+msgstr "Erreur"
+
+#: hardinfo/util.c:361 hardinfo/util.c:377
+msgid "Warning"
+msgstr "Attention"
+
+#: hardinfo/util.c:376
+msgid "Fatal Error"
+msgstr "Erreur Fatale"
+
+#: hardinfo/util.c:401
+msgid "creates a report and prints to standard output"
+msgstr "crée un rapport et imprime sur la sortie standard"
+
+#: hardinfo/util.c:407
+msgid "chooses a report format (text, html)"
+msgstr "choisir un format de rapport (texte, html)"
+
+#: hardinfo/util.c:413
+msgid "run benchmark; requires benchmark.so to be loaded"
+msgstr "Envoyé le benchmark; nécessite benchmark.so"
+
+#: hardinfo/util.c:419
+msgid "lists modules"
+msgstr "Listes des modules"
+
+#: hardinfo/util.c:425
+msgid "specify module to load"
+msgstr "spécifie les modules à charger"
+
+#: hardinfo/util.c:431
+msgid "automatically load module dependencies"
+msgstr "charger automatiquement les dépendances entre modules"
+
+#: hardinfo/util.c:438
+msgid "run in XML-RPC server mode"
+msgstr "fonctionner en mode serveur XML-RPC"
+
+#: hardinfo/util.c:445
+msgid "shows program version and quit"
+msgstr "Affiche la version du programme et quitter"
+
+#: hardinfo/util.c:450
+msgid "- System Profiler and Benchmark tool"
+msgstr "- Profil du Systeme et outil d'évaluation Benchmark"
+
+#: hardinfo/util.c:460
+#, c-format
+msgid ""
+"Unrecognized arguments.\n"
+"Try ``%s --help'' for more information.\n"
+msgstr ""
+"commandes inconnues.\n"
+"taper ``%s --help'' pour plus d'informations.\n"
+
+#: hardinfo/util.c:526
+#, c-format
+msgid "Couldn't find a Web browser to open URL %s."
+msgstr "Impossible de trouver un navigateur Web pour ouvrir l'URL %s."
+
+#: hardinfo/util.c:875
+#, c-format
+msgid "Module \"%s\" depends on module \"%s\", load it?"
+msgstr "Module \"%s\" depends du module \"%s\", le charger?"
+
+#: hardinfo/util.c:898
+#, c-format
+msgid "Module \"%s\" depends on module \"%s\"."
+msgstr "Module \"%s\" depends du module \"%s\"."
+
+#: hardinfo/util.c:943
+#, c-format
+msgid "No module could be loaded. Check permissions on \"%s\" and try again."
+msgstr ""
+"Aucun module peut être chargé. Vérifiez les permissions sur \"%s\" et "
+"essayez à nouveau."
+
+#: hardinfo/util.c:947
+msgid ""
+"No module could be loaded. Please use hardinfo -l to list all available "
+"modules and try again with a valid module list."
+msgstr ""
+"Aucun module peut être chargé. S'il vous plaît utiliser hardinfo -l pour "
+"répertorier tous les modules disponibles et essayez à nouveau avec une liste "
+"de modules valides."
+
+#: hardinfo/util.c:1024
+#, c-format
+msgid "Scanning: %s..."
+msgstr "Scanne: %s..."
+
+#: hardinfo/util.c:1034 shell/shell.c:301 shell/shell.c:760 shell/shell.c:1795
+#: modules/benchmark.c:449 modules/benchmark.c:457
+msgid "Done."
+msgstr "Réalisé."
+
+#: shell/callbacks.c:117
+#, c-format
+msgid "%s Module"
+msgstr "%s Module"
+
+#: shell/callbacks.c:128
+#, c-format
+msgid ""
+"Written by %s\n"
+"Licensed under %s"
+msgstr ""
+"Ecrit par %s\n"
+"Sous Licence %s"
+
+#: shell/callbacks.c:142
+#, c-format
+msgid "No about information is associated with the %s module."
+msgstr "Pas d'information associée au module %s."
+
+#: shell/callbacks.c:158
+msgid "Author:"
+msgstr "Auteur:"
+
+#: shell/callbacks.c:161
+msgid "Contributors:"
+msgstr "Contributeurs:"
+
+#: shell/callbacks.c:166
+msgid "Based on work by:"
+msgstr "Basé sur le travail de:"
+
+#: shell/callbacks.c:167
+msgid "MD5 implementation by Colin Plumb (see md5.c for details)"
+msgstr "Implémentation  MD5 par Colin Plumb (voir md5.c pour les détails)"
+
+#: shell/callbacks.c:168
+msgid "SHA1 implementation by Steve Reid (see sha1.c for details)"
+msgstr "implémentation  SHA1 par Steve Reid (voir sha1.c pour les détails)"
+
+#: shell/callbacks.c:169
+msgid "Blowfish implementation by Paul Kocher (see blowfich.c for details)"
+msgstr ""
+"Implémentation Blowfish par Paul Kocher (voir blowchih.c pour de plus amples "
+"détails"
+
+#: shell/callbacks.c:170
+msgid "Raytracing benchmark by John Walker (see fbench.c for details)"
+msgstr ""
+"Raytracing benchmark par John Walker (voir fbench.c pour de plus amples "
+"détails)"
+
+#: shell/callbacks.c:171
+msgid "FFT benchmark by Scott Robert Ladd (see fftbench.c for details)"
+msgstr "FFT benchmark par Scott Robert Ladd (voir fftbench.c pour les détails)"
+
+#: shell/callbacks.c:172
+msgid "Some code partly based on x86cpucaps by Osamu Kayasono"
+msgstr "Une partie du code est basé sur x86cpucaps par Osamu Kayasono"
+
+#: shell/callbacks.c:173
+msgid "Vendor list based on GtkSysInfo by Pissens Sebastien"
+msgstr "La liste des fabricants est basée sur GtkSysInfo par Pissens Sebastien"
+
+#: shell/callbacks.c:174
+msgid "DMI support based on code by Stewart Adam"
+msgstr "Les supports DMI sont basés sur le code de Stewart Adam"
+
+#: shell/callbacks.c:175
+msgid "SCSI support based on code by Pascal F. Martin"
+msgstr "Les supports SCSI sont basés sur le code de Pascal F. Martin"
+
+#: shell/callbacks.c:180
+msgid "Tango Project"
+msgstr "Projet Tango"
+
+#: shell/callbacks.c:181
+msgid "The GNOME Project"
+msgstr "Le Projet Gnome"
+
+#: shell/callbacks.c:182
+msgid "VMWare, Inc. (USB icon from VMWare Workstation 6)"
+msgstr "VMWare, Inc. (USB icône sur VMWare Workstation 6)"
+
+#: shell/callbacks.c:200
+msgid "System information and benchmark tool"
+msgstr "Information du systeme et outil d'évaluation"
+
+#: shell/callbacks.c:205
+msgid ""
+"HardInfo is free software; you can redistribute it and/or modify it under "
+"the terms of the GNU General Public License as published by the Free "
+"Software Foundation, version 2.\n"
+"\n"
+"This program is distributed in the hope that it will be useful, but WITHOUT "
+"ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
+"FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for "
+"more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License along with "
+"this program; if not, write to the Free Software Foundation, Inc., 51 "
+"Franklin St, Fifth Floor, Boston, MA  02110-1301 USA"
+msgstr ""
+
+#: shell/callbacks.c:220
+msgid "translator-credits"
+msgstr ""
+
+#: shell/menu.c:35
+msgid "_Information"
+msgstr "_Information"
+
+#: shell/menu.c:36
+msgid "_Remote"
+msgstr "_Périphériques distants"
+
+#: shell/menu.c:37
+msgid "_View"
+msgstr "_Voir"
+
+#: shell/menu.c:38
+msgid "_Help"
+msgstr "_Aide"
+
+#: shell/menu.c:39
+msgid "About _Modules"
+msgstr "A propos des _modules"
+
+#: shell/menu.c:43
+msgid "Generate _Report"
+msgstr "Générer _Rapport"
+
+#: shell/menu.c:48
+msgid "_Network Updater..."
+msgstr "_Mise à jour des données"
+
+#: shell/menu.c:53
+msgid "_Open..."
+msgstr "_Ouvrir..."
+
+#: shell/menu.c:58
+msgid "_Copy to Clipboard"
+msgstr "_Copier dans le presse-papier"
+
+#: shell/menu.c:59
+msgid "Copy to clipboard"
+msgstr "Copie dans le presse-papier"
+
+#: shell/menu.c:63
+msgid "_Refresh"
+msgstr "_Rafraichir"
+
+#: shell/menu.c:68
+msgid "_Open HardInfo Web Site"
+msgstr "_HardInfo Site Web"
+
+#: shell/menu.c:73
+msgid "_Report bug"
+msgstr "_Rapporter un bug"
+
+#: shell/menu.c:78
+msgid "_About HardInfo"
+msgstr "_A Propos de HardInfo"
+
+#: shell/menu.c:79
+msgid "Displays program version information"
+msgstr "Affiche les informations de version du programme"
+
+#: shell/menu.c:83
+msgid "_Quit"
+msgstr "_Quitter"
+
+#: shell/menu.c:90
+msgid "_Side Pane"
+msgstr "_Volet latéral"
+
+#: shell/menu.c:91
+msgid "Toggles side pane visibility"
+msgstr "Basculer visibilité du panneau latéral "
+
+#: shell/menu.c:94
+msgid "_Toolbar"
+msgstr "_Barre d'outils"
+
+#: shell/report.c:494 shell/report.c:502
+msgid "Save File"
+msgstr "Sauvegarder le fichier"
+
+#: shell/report.c:629
+msgid "Cannot create ReportContext. Programming bug?"
+msgstr "Impossible de créer un rapport général. Bug?"
+
+#: shell/report.c:648
+msgid "Open the report with your web browser?"
+msgstr "Ouvrez le rapport avec votre navigateur Web?"
+
+#: shell/report.c:682
+msgid "Generating report..."
+msgstr "Création du rapport..."
+
+#: shell/report.c:692
+msgid "Report saved."
+msgstr "Rapport sauvegardé"
+
+#: shell/report.c:694
+msgid "Error while creating the report."
+msgstr "Erreur lors de la création du rapport."
+
+#: shell/report.c:796
+msgid "Generate Report"
+msgstr "Réalisation du Rapport"
+
+#: shell/report.c:821
+msgid ""
+"<big><b>Generate Report</b></big>\n"
+"Please choose the information that you wish to view in your report:"
+msgstr ""
+"<big> <b> Générer un rapport </b> </big> \n"
+" S'il vous plaît choisissez les informations que vous souhaitez afficher "
+"dans votre rapport:"
+
+#: shell/report.c:893
+msgid "Select _None"
+msgstr "Désélectionner _Tout"
+
+#: shell/report.c:904
+msgid "Select _All"
+msgstr "Sélectionner _Tout"
+
+#: shell/report.c:929 shell/syncmanager.c:748
+msgid "_Cancel"
+msgstr ""
+
+#: shell/report.c:939
+msgid "_Generate"
+msgstr "_Création"
+
+#: shell/shell.c:402
+#, c-format
+msgid "%s - System Information"
+msgstr "%s - Informations du Système"
+
+#: shell/shell.c:407
+msgid "System Information"
+msgstr "Informations du Système"
+
+#: shell/shell.c:747
+msgid "Loading modules..."
+msgstr "Chargement des modules..."
+
+#: shell/shell.c:1660
+#, c-format
+msgid "<b>%s → Summary</b>"
+msgstr "<b>%s → Résumé</b>"
+
+#: shell/shell.c:1769
+msgid "Updating..."
+msgstr "Mise à jour..."
+
+#: shell/syncmanager.c:69
+msgid ""
+"<big><b>Synchronize with Central Database</b></big>\n"
+"The following information may be synchronized with the HardInfo central "
+"database."
+msgstr ""
+"<big><b>Synchroniser avec la base de données centrale</b></big>\n"
+"Les informations suivantes seront synchronisées avec la base de données de "
+"HardInfo."
+
+#: shell/syncmanager.c:72
+msgid ""
+"<big><b>Synchronizing</b></big>\n"
+"This may take some time."
+msgstr ""
+"<big><b>Synchronisation</b></big>\n"
+"Cela peut prendre un certain temps."
+
+#: shell/syncmanager.c:132
+msgid ""
+"HardInfo was compiled without libsoup support. (Network Updater requires it.)"
+msgstr ""
+"HARDiNFO a été compilé sans le support libsoup. (Mise à jour des données "
+"l'exige.)"
+
+#: shell/syncmanager.c:161 shell/syncmanager.c:189
+#, c-format
+msgid "%s (error #%d)"
+msgstr "%s (erreur #%d)"
+
+#: shell/syncmanager.c:170 shell/syncmanager.c:198
+msgid "Could not parse XML-RPC response"
+msgstr "Impossible d'analyser la réponse XML-RPC"
+
+#: shell/syncmanager.c:280
+#, c-format
+msgid ""
+"Server says it supports API version %d, but this version of HardInfo only "
+"supports API version %d."
+msgstr ""
+"Le serveur dit qu'il supporte la version de l'API %d, mais cette version de "
+"HARDiNFO supporte seulement le support version de l'API %d."
+
+#: shell/syncmanager.c:375
+msgid "Contacting HardInfo Central Database"
+msgstr "En contact avec la base de données centrale du site HARDiNFO"
+
+#: shell/syncmanager.c:376
+msgid "Cleaning up"
+msgstr "Nettoyage"
+
+#: shell/syncmanager.c:493
+msgid "(canceled)"
+msgstr "(annuler)"
+
+#: shell/syncmanager.c:510
+msgid "(failed)"
+msgstr "(echec)"
+
+#: shell/syncmanager.c:521
+#, c-format
+msgid ""
+"Failed while performing \"%s\". Please file a bug report if this problem "
+"persists. (Use the Help→Report bug option.)\n"
+"\n"
+"Details: %s"
+msgstr ""
+"Échec lors de l'exécution de \"%s\". S'il vous plaît remplissez un rapport "
+"de bug si ce problème persiste. (Utilisez l'option Aide → Rapport de Bug.)\n"
+"\n"
+"Détails: %s"
+
+#: shell/syncmanager.c:530
+#, c-format
+msgid ""
+"Failed while performing \"%s\". Please file a bug report if this problem "
+"persists. (Use the Help→Report bug option.)"
+msgstr ""
+"Échec lors de l'exécution de \"%s\". S'il vous plaît remplissez un rapport "
+"de bug si ce problème persiste. (Utilisez l'option Aide → Rapport de Bug.)"
+
+#: shell/syncmanager.c:658
+msgid "Network Updater"
+msgstr "Mises à jour"
+
+#: shell/syncmanager.c:757
+msgid "_Synchronize"
+msgstr "_Synchronisation"
+
+#: modules/benchmark.c:52
+msgid "CPU Blowfish"
+msgstr "Test CPU Blowfish"
+
+#: modules/benchmark.c:53
+msgid "CPU CryptoHash"
+msgstr "Test CPU CryptoHash"
+
+#: modules/benchmark.c:54
+msgid "CPU Fibonacci"
+msgstr "Test CPU Fibonacci "
+
+#: modules/benchmark.c:55
+msgid "CPU N-Queens"
+msgstr "Test CPU N-Queens"
+
+#: modules/benchmark.c:56
+msgid "CPU Zlib"
+msgstr ""
+
+#: modules/benchmark.c:57
+msgid "FPU FFT"
+msgstr "Test FPU FFT"
+
+#: modules/benchmark.c:58
+msgid "FPU Raytracing"
+msgstr "Test FPU Raytracing"
+
+#: modules/benchmark.c:60
+msgid "GPU Drawing"
+msgstr "Test GPU Drawing"
+
+#: modules/benchmark.c:239 modules/benchmark.c:255
+msgid "CPU Config"
+msgstr ""
+
+#: modules/benchmark.c:239 modules/benchmark.c:255
+msgid "Results"
+msgstr ""
+
+#: modules/benchmark.c:239 modules/benchmark.c:255 modules/computer.c:751
+#: modules/devices/sparc/processor.c:75
+msgid "CPU"
+msgstr ""
+
+#: modules/benchmark.c:381
+#, c-format
+msgid "Benchmarking: <b>%s</b>."
+msgstr "Benchmarking: <b>%s</b>."
+
+#: modules/benchmark.c:395
+msgid "Benchmarking. Please do not move your mouse or press any keys."
+msgstr ""
+"Benchmarking. S'il vous plaît ne pas déplacer votre souris ou appuyer sur "
+"les touches"
+
+#: modules/benchmark.c:399
+msgid "Cancel"
+msgstr "Annuler"
+
+#: modules/benchmark.c:536
+msgid "Results in MiB/second. Higher is better."
+msgstr "Résultats en MiB/seconde. Plus c'est élevé meilleur c'est."
+
+#: modules/benchmark.c:540
+msgid "Results in HIMarks. Higher is better."
+msgstr "Résultats en HIMarks. Plus c'est élevé meilleur c'est."
+
+#: modules/benchmark.c:547
+msgid "Results in seconds. Lower is better."
+msgstr "Résultats en secondes. Plus c'est bas meilleur c'est."
+
+#: modules/benchmark.c:555
+msgid "Benchmarks"
+msgstr "Benchmarks"
+
+#: modules/benchmark.c:573
+msgid "Perform tasks and compare with other systems"
+msgstr "Effectuer des tâches et les comparer avec d'autres systèmes"
+
+#: modules/benchmark.c:663
+msgid "Send benchmark results"
+msgstr "Envoyer vos résultats de référence"
+
+#: modules/benchmark.c:668
+msgid "Receive benchmark results"
+msgstr "Recevoir les résultats de benchmark"
+
+#: modules/computer/alsa.c:26 modules/computer.c:489
+msgid "Audio Devices"
+msgstr ""
+
+#: modules/computer/alsa.c:34
+msgid "Audio Adapter"
+msgstr "Adapteur Audio"
+
+#: modules/computer/boots.c:33 modules/computer.c:73 modules/computer.c:546
+msgid "Boots"
+msgstr "Boots"
+
+#: modules/computer.c:70
+msgid "Summary"
+msgstr "Résumé"
+
+#: modules/computer.c:71 modules/computer.c:476 modules/computer.c:750
+msgid "Operating System"
+msgstr "Systeme d'exploitation"
+
+#: modules/computer.c:72
+msgid "Kernel Modules"
+msgstr "Modules du kernel"
+
+#: modules/computer.c:74
+msgid "Languages"
+msgstr "Langues"
+
+#: modules/computer.c:75
+msgid "Filesystems"
+msgstr "Fichiers Systeme"
+
+#: modules/computer.c:76 modules/computer.c:481 modules/computer.c:590
+msgid "Display"
+msgstr "Affichage"
+
+#: modules/computer.c:77 modules/computer/environment.c:32
+msgid "Environment Variables"
+msgstr "Variables d'environnement"
+
+#: modules/computer.c:79
+msgid "Development"
+msgstr "Developpement"
+
+#: modules/computer.c:81 modules/computer.c:617
+msgid "Users"
+msgstr "Utilisateurs"
+
+#: modules/computer.c:82
+msgid "Groups"
+msgstr "Groupes"
+
+#: modules/computer.c:104 modules/computer.c:473 modules/devices.c:96
+#: modules/devices/pci.c:149
+msgid "Memory"
+msgstr "Mémoire"
+
+#: modules/computer.c:106
+#, c-format
+msgid "%dMB (%dMB used)"
+msgstr "%dMB (%dMB utilisé)"
+
+#: modules/computer.c:108 modules/computer.c:520
+msgid "Uptime"
+msgstr "durée de fonctionnent"
+
+#: modules/computer.c:110 modules/computer.c:478
+msgid "Date/Time"
+msgstr "Date/Heure"
+
+#: modules/computer.c:115 modules/computer.c:521
+msgid "Load Average"
+msgstr ""
+
+#: modules/computer.c:117 modules/computer.c:522
+msgid "Available entropy in /dev/random"
+msgstr ""
+
+#: modules/computer.c:203
+msgid "Scripting Languages"
+msgstr "Type de script"
+
+#: modules/computer.c:204
+msgid "Gambas3 (gbr3)"
+msgstr ""
+
+#: modules/computer.c:205
+msgid "Python"
+msgstr ""
+
+#: modules/computer.c:206
+msgid "Python2"
+msgstr ""
+
+#: modules/computer.c:207
+msgid "Python3"
+msgstr ""
+
+#: modules/computer.c:208
+msgid "Perl"
+msgstr "Perl"
+
+#: modules/computer.c:209
+msgid "Perl6 (VM)"
+msgstr ""
+
+#: modules/computer.c:210
+msgid "Perl6"
+msgstr ""
+
+#: modules/computer.c:211
+msgid "PHP"
+msgstr "PHP"
+
+#: modules/computer.c:212
+msgid "Ruby"
+msgstr "Ruby"
+
+#: modules/computer.c:213
+msgid "Bash"
+msgstr "Bash"
+
+#: modules/computer.c:214
+msgid "Compilers"
+msgstr "Compilateurs"
+
+#: modules/computer.c:215
+msgid "C (GCC)"
+msgstr "C (GCC)"
+
+#: modules/computer.c:216
+msgid "C (Clang)"
+msgstr ""
+
+#: modules/computer.c:217
+msgid "D (dmd)"
+msgstr ""
+
+#: modules/computer.c:218
+msgid "Gambas3 (gbc3)"
+msgstr ""
+
+#: modules/computer.c:219
+msgid "Java"
+msgstr "Java"
+
+#: modules/computer.c:220
+msgid "CSharp (Mono, old)"
+msgstr "CSharp (Mono, old)"
+
+#: modules/computer.c:221
+msgid "CSharp (Mono)"
+msgstr "CSharp (Mono)"
+
+#: modules/computer.c:222
+msgid "Vala"
+msgstr "Vala"
+
+#: modules/computer.c:223
+msgid "Haskell (GHC)"
+msgstr "Haskell (GHC)"
+
+#: modules/computer.c:224
+msgid "FreePascal"
+msgstr "FreePascal"
+
+#: modules/computer.c:225
+msgid "Go"
+msgstr ""
+
+#: modules/computer.c:226
+msgid "Tools"
+msgstr "Outils"
+
+#: modules/computer.c:227
+msgid "make"
+msgstr ""
+
+#: modules/computer.c:228
+msgid "GDB"
+msgstr ""
+
+#: modules/computer.c:229
+msgid "strace"
+msgstr ""
+
+#: modules/computer.c:230
+msgid "valgrind"
+msgstr ""
+
+#: modules/computer.c:231
+msgid "QMake"
+msgstr ""
+
+#: modules/computer.c:232
+msgid "CMake"
+msgstr ""
+
+#: modules/computer.c:233
+msgid "Gambas3 IDE"
+msgstr ""
+
+#: modules/computer.c:274
+msgid "Not found"
+msgstr "Non trouvé"
+
+#: modules/computer.c:279
+#, c-format
+msgid "Detecting version: %s"
+msgstr "Version détectée: %s"
+
+#: modules/computer.c:296
+msgid "Program"
+msgstr "Programme"
+
+#: modules/computer.c:308
+msgid "Invalid chassis type (0)"
+msgstr ""
+
+#: modules/computer.c:309 modules/computer.c:310
+msgid "Unknown chassis type"
+msgstr ""
+
+#: modules/computer.c:311
+msgid "Desktop"
+msgstr ""
+
+#: modules/computer.c:312
+msgid "Low-profile Desktop"
+msgstr ""
+
+#: modules/computer.c:313
+msgid "Pizza Box"
+msgstr ""
+
+#: modules/computer.c:314
+msgid "Mini Tower"
+msgstr ""
+
+#: modules/computer.c:315
+msgid "Tower"
+msgstr ""
+
+#: modules/computer.c:316
+msgid "Portable"
+msgstr ""
+
+#: modules/computer.c:317 modules/computer.c:341 modules/computer.c:350
+#: modules/computer.c:372
+msgid "Laptop"
+msgstr ""
+
+#: modules/computer.c:318
+msgid "Notebook"
+msgstr ""
+
+#: modules/computer.c:319
+msgid "Handheld"
+msgstr ""
+
+#: modules/computer.c:320
+msgid "Docking Station"
+msgstr ""
+
+#: modules/computer.c:321
+msgid "All-in-one"
+msgstr ""
+
+#: modules/computer.c:322
+msgid "Subnotebook"
+msgstr ""
+
+#: modules/computer.c:323
+msgid "Space-saving"
+msgstr ""
+
+#: modules/computer.c:324
+msgid "Lunch Box"
+msgstr ""
+
+#: modules/computer.c:325
+msgid "Main Server Chassis"
+msgstr ""
+
+#: modules/computer.c:326
+msgid "Expansion Chassis"
+msgstr ""
+
+#: modules/computer.c:327
+msgid "Sub Chassis"
+msgstr ""
+
+#: modules/computer.c:328
+msgid "Bus Expansion Chassis"
+msgstr ""
+
+#: modules/computer.c:329
+msgid "Peripheral Chassis"
+msgstr ""
+
+#: modules/computer.c:330
+msgid "RAID Chassis"
+msgstr ""
+
+#: modules/computer.c:331
+msgid "Rack Mount Chassis"
+msgstr ""
+
+#: modules/computer.c:332
+msgid "Sealed-case PC"
+msgstr ""
+
+#. /proc/apm
+#. FIXME: use dmidecode if available to get chassis type
+#: modules/computer.c:386
+msgid "Unknown physical machine type"
+msgstr ""
+
+#: modules/computer.c:470 modules/computer.c:709
+msgid "Computer"
+msgstr "Ordinateur"
+
+#: modules/computer.c:471 modules/devices/alpha/processor.c:87
+#: modules/devices/arm/processor.c:236 modules/devices.c:95
+#: modules/devices/ia64/processor.c:159 modules/devices/m68k/processor.c:83
+#: modules/devices/mips/processor.c:74 modules/devices/parisc/processor.c:154
+#: modules/devices/ppc/processor.c:157 modules/devices/riscv/processor.c:181
+#: modules/devices/s390/processor.c:131 modules/devices/sh/processor.c:83
+#: modules/devices/sparc/processor.c:74 modules/devices/x86/processor.c:409
+msgid "Processor"
+msgstr "Processeur"
+
+#: modules/computer.c:474
+msgid "Machine Type"
+msgstr ""
+
+#: modules/computer.c:477 modules/computer.c:514
+msgid "User Name"
+msgstr "Utilisateur"
+
+#: modules/computer.c:482 modules/computer.c:591
+msgid "Resolution"
+msgstr "Résolution"
+
+#: modules/computer.c:483 modules/computer.c:592
+#, c-format
+msgid "%dx%d pixels"
+msgstr ""
+
+#: modules/computer.c:485
+msgid "OpenGL Renderer"
+msgstr ""
+
+#: modules/computer.c:486
+msgid "X11 Vendor"
+msgstr ""
+
+#: modules/computer.c:491 modules/devices.c:102
+msgid "Input Devices"
+msgstr "Périphériques d'entrée"
+
+#: modules/computer.c:493 modules/computer.c:752 modules/devices.c:99
+msgid "Printers"
+msgstr "Imprimantes"
+
+#: modules/computer.c:495 modules/computer.c:752 modules/devices.c:103
+msgid "Storage"
+msgstr "Stockage"
+
+#: modules/computer.c:506
+msgid "Kernel"
+msgstr ""
+
+#: modules/computer.c:508
+msgid "C Library"
+msgstr ""
+
+#: modules/computer.c:509
+msgid "Distribution"
+msgstr ""
+
+#: modules/computer.c:512
+msgid "Current Session"
+msgstr ""
+
+#: modules/computer.c:513
+msgid "Computer Name"
+msgstr "Ordinateur"
+
+#: modules/computer.c:515 modules/computer/languages.c:108
+msgid "Language"
+msgstr ""
+
+#: modules/computer.c:516 modules/computer/users.c:50
+msgid "Home Directory"
+msgstr "Dossier Home"
+
+#: modules/computer.c:519 modules/devices/usb.c:87 modules/devices/usb.c:234
+#: modules/devices/usb.c:351
+msgid "Misc"
+msgstr ""
+
+#: modules/computer.c:532
+msgid "Loaded Modules"
+msgstr ""
+
+#: modules/computer.c:535 modules/computer/modules.c:145
+#: modules/computer/modules.c:147 modules/devices/arm/processor.c:337
+#: modules/devices.c:559 modules/devices/x86/processor.c:456
+msgid "Description"
+msgstr ""
+
+#: modules/computer.c:548
+msgid "Date & Time"
+msgstr ""
+
+#: modules/computer.c:549
+msgid "Kernel Version"
+msgstr ""
+
+#: modules/computer.c:559
+msgid "Available Languages"
+msgstr ""
+
+#: modules/computer.c:561
+msgid "Language Code"
+msgstr "Type Code"
+
+#: modules/computer.c:573
+msgid "Mounted File Systems"
+msgstr ""
+
+#: modules/computer.c:575 modules/computer/filesystem.c:85
+msgid "Mount Point"
+msgstr "Point de montage"
+
+#: modules/computer.c:576
+msgid "Usage"
+msgstr ""
+
+#: modules/computer.c:577
+msgid "Device"
+msgstr "Périphérique"
+
+#: modules/computer.c:594 modules/computer.c:601
+#: modules/devices/ia64/processor.c:161 modules/devices/inputdevices.c:119
+#: modules/devices/pci.c:225 modules/devices/usb.c:349
+#: modules/devices/x86/processor.c:416
+msgid "Vendor"
+msgstr "Fabricant"
+
+#: modules/computer.c:598
+msgid "Monitors"
+msgstr ""
+
+#: modules/computer.c:600
+msgid "OpenGL"
+msgstr ""
+
+#: modules/computer.c:602
+msgid "Renderer"
+msgstr ""
+
+#: modules/computer.c:604
+msgid "Direct Rendering"
+msgstr ""
+
+#: modules/computer.c:608
+msgid "Extensions"
+msgstr ""
+
+#: modules/computer.c:628
+msgid "Group"
+msgstr ""
+
+#: modules/computer.c:631 modules/computer/users.c:49
+msgid "Group ID"
+msgstr ""
+
+#: modules/computer.c:751
+msgid "RAM"
+msgstr ""
+
+#: modules/computer.c:751 modules/devices/devicetree/pmac_data.c:82
+msgid "Motherboard"
+msgstr ""
+
+#: modules/computer.c:751
+msgid "Graphics"
+msgstr ""
+
+#: modules/computer.c:752
+msgid "Audio"
+msgstr ""
+
+#: modules/computer.c:807
+msgid "Gathers high-level computer information"
+msgstr "Collecte des informations de l'ordinateur"
+
+#: modules/computer/display.c:122
+#, c-format
+msgid "Monitor %d=%dx%d pixels\n"
+msgstr "Moniteur %d=%dx%d pixels\n"
+
+#: modules/computer/filesystem.c:83
+msgid "Filesystem"
+msgstr ""
+
+#: modules/computer/filesystem.c:84
+msgid "Mounted As"
+msgstr ""
+
+#: modules/computer/filesystem.c:84
+msgid "Read-Write"
+msgstr ""
+
+#: modules/computer/filesystem.c:84
+msgid "Read-Only"
+msgstr ""
+
+#: modules/computer/filesystem.c:86 modules/devices/spd-decode.c:1510
+msgid "Size"
+msgstr ""
+
+#: modules/computer/filesystem.c:87
+msgid "Used"
+msgstr ""
+
+#: modules/computer/filesystem.c:88
+msgid "Available"
+msgstr ""
+
+#: modules/computer/languages.c:103
+msgid "Locale Information"
+msgstr ""
+
+#: modules/computer/languages.c:105
+msgid "Source"
+msgstr ""
+
+#: modules/computer/languages.c:106
+msgid "Address"
+msgstr ""
+
+#: modules/computer/languages.c:107
+msgid "E-mail"
+msgstr ""
+
+#: modules/computer/languages.c:109
+msgid "Territory"
+msgstr ""
+
+#: modules/computer/languages.c:110 modules/devices/arm/processor.c:250
+#: modules/devices/ia64/processor.c:166 modules/devices/ppc/processor.c:159
+#: modules/devices/usb.c:236
+msgid "Revision"
+msgstr ""
+
+#: modules/computer/languages.c:111
+msgid "Date"
+msgstr ""
+
+#: modules/computer/languages.c:112
+msgid "Codeset"
+msgstr ""
+
+#: modules/computer/loadavg.c:64
+msgid "Couldn't obtain load average"
+msgstr ""
+
+#: modules/computer/modules.c:125 modules/computer/modules.c:126
+#: modules/computer/modules.c:127 modules/computer/modules.c:128
+#: modules/computer/modules.c:129
+msgid "(Not available)"
+msgstr ""
+
+#: modules/computer/modules.c:142
+msgid "Module Information"
+msgstr ""
+
+#: modules/computer/modules.c:143
+msgid "Path"
+msgstr ""
+
+#: modules/computer/modules.c:144
+msgid "Used Memory"
+msgstr ""
+
+#: modules/computer/modules.c:144
+msgid "KiB"
+msgstr ""
+
+#: modules/computer/modules.c:148
+msgid "Version Magic"
+msgstr ""
+
+#: modules/computer/modules.c:149
+msgid "Copyright"
+msgstr ""
+
+#: modules/computer/modules.c:150
+msgid "Author"
+msgstr ""
+
+#: modules/computer/modules.c:151
+msgid "License"
+msgstr ""
+
+#: modules/computer/modules.c:158
+msgid "Dependencies"
+msgstr ""
+
+#: modules/computer/os.c:35 modules/computer/os.c:36 modules/computer/os.c:37
+#: modules/computer/os.c:38
+msgid "GNU C Library"
+msgstr ""
+
+#: modules/computer/os.c:39
+msgid "uClibc or uClibc-ng"
+msgstr ""
+
+#: modules/computer/os.c:40
+msgid "diet libc"
+msgstr ""
+
+#: modules/computer/os.c:78 modules/computer/os.c:234 modules/computer/os.c:359
+#: modules/devices.c:333 modules/devices.c:387 modules/devices/printers.c:99
+#: modules/devices/printers.c:106 modules/devices/printers.c:116
+#: modules/devices/printers.c:131 modules/devices/printers.c:140
+#: modules/devices/printers.c:243
+msgid "Unknown"
+msgstr "Inconnu"
+
+#: modules/computer/os.c:112 modules/computer/os.c:115
+msgid "GNOME Shell "
+msgstr ""
+
+#: modules/computer/os.c:123 modules/computer/os.c:126
+msgid "Version: "
+msgstr ""
+
+#: modules/computer/os.c:157
+#, c-format
+msgid "Unknown (Window Manager: %s)"
+msgstr "Unknown (gestionnaire de fenêtres: %s)"
+
+#. /{desktop environment} on {session type}
+#: modules/computer/os.c:168
+#, c-format
+msgid "%s on %s"
+msgstr ""
+
+#: modules/computer/os.c:232
+msgid "Terminal"
+msgstr "Terminal"
+
+#. /bits of entropy for rng (0)
+#: modules/computer/os.c:241
+msgid "(None or not available)"
+msgstr ""
+
+#. /bits of entropy for rng (low/poor value)
+#: modules/computer/os.c:242
+#, c-format
+msgid "%d bits (low)"
+msgstr ""
+
+#. /bits of entropy for rng (medium value)
+#: modules/computer/os.c:243
+#, c-format
+msgid "%d bits (medium)"
+msgstr ""
+
+#. /bits of entropy for rng (high/good value)
+#: modules/computer/os.c:244
+#, c-format
+msgid "%d bits (healthy)"
+msgstr ""
+
+#: modules/computer/os.c:279 modules/devices/usb.c:48 modules/devices/usb.c:307
+#: modules/devices/usb.c:310 modules/network/net.c:442 includes/cpu_util.h:11
+msgid "(Unknown)"
+msgstr ""
+
+#: modules/computer/users.c:47
+msgid "User Information"
+msgstr ""
+
+#: modules/computer/users.c:48
+msgid "User ID"
+msgstr ""
+
+#: modules/computer/users.c:51
+msgid "Default Shell"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:88 modules/devices/devicetree.c:141
+#: modules/devices/devicetree.c:176 modules/devices/devicetree/pmac_data.c:80
+#: modules/devices/ia64/processor.c:165 modules/devices/m68k/processor.c:84
+#: modules/devices/mips/processor.c:75 modules/devices/parisc/processor.c:155
+#: modules/devices/ppc/processor.c:158 modules/devices/riscv/processor.c:182
+#: modules/devices/s390/processor.c:132 modules/devices/spd-decode.c:1510
+msgid "Model"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:89
+msgid "Platform String"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:90 modules/devices/arm/processor.c:240
+#: modules/devices/ia64/processor.c:167 modules/devices/m68k/processor.c:87
+#: modules/devices/mips/processor.c:77 modules/devices/parisc/processor.c:158
+#: modules/devices/pci.c:108 modules/devices/ppc/processor.c:160
+#: modules/devices/riscv/processor.c:186 modules/devices/sh/processor.c:87
+#: modules/devices/x86/processor.c:420
+msgid "Frequency"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:90 modules/devices/arm/processor.c:240
+#: modules/devices/arm/processor.c:365 modules/devices.c:299
+#: modules/devices.c:307 modules/devices.c:335
+#: modules/devices/ia64/processor.c:167 modules/devices/ia64/processor.c:196
+#: modules/devices/m68k/processor.c:87 modules/devices/mips/processor.c:77
+#: modules/devices/parisc/processor.c:158
+#: modules/devices/parisc/processor.c:191 modules/devices/pci.c:108
+#: modules/devices/ppc/processor.c:160 modules/devices/ppc/processor.c:187
+#: modules/devices/riscv/processor.c:186 modules/devices/riscv/processor.c:214
+#: modules/devices/s390/processor.c:160 modules/devices/sh/processor.c:87
+#: modules/devices/sh/processor.c:88 modules/devices/sh/processor.c:89
+#: modules/devices/x86/processor.c:420 modules/devices/x86/processor.c:479
+msgid "MHz"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:91 modules/devices/arm/processor.c:241
+#: modules/devices/ia64/processor.c:168 modules/devices/m68k/processor.c:88
+#: modules/devices/mips/processor.c:78 modules/devices/parisc/processor.c:159
+#: modules/devices/ppc/processor.c:161 modules/devices/s390/processor.c:134
+#: modules/devices/sh/processor.c:90 modules/devices/x86/processor.c:421
+msgid "BogoMips"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:92 modules/devices/arm/processor.c:242
+#: modules/devices/ia64/processor.c:169 modules/devices/m68k/processor.c:89
+#: modules/devices/mips/processor.c:79 modules/devices/parisc/processor.c:160
+#: modules/devices/ppc/processor.c:162 modules/devices/riscv/processor.c:187
+#: modules/devices/s390/processor.c:135 modules/devices/sh/processor.c:91
+#: modules/devices/sparc/processor.c:77 modules/devices/x86/processor.c:422
+msgid "Byte Order"
+msgstr ""
+
+#. /hw_cap
+#. /flag:swp
+#: modules/devices/arm/arm_data.c:42
+msgctxt "arm-flag"
+msgid "SWP instruction (atomic read-modify-write)"
+msgstr ""
+
+#. /flag:half
+#: modules/devices/arm/arm_data.c:43
+msgctxt "arm-flag"
+msgid "Half-word loads and stores"
+msgstr ""
+
+#. /flag:thumb
+#: modules/devices/arm/arm_data.c:44
+msgctxt "arm-flag"
+msgid "Thumb (16-bit instruction set)"
+msgstr ""
+
+#. /flag:26bit
+#: modules/devices/arm/arm_data.c:45
+msgctxt "arm-flag"
+msgid "26-Bit Model (Processor status register folded into program counter)"
+msgstr ""
+
+#. /flag:fastmult
+#: modules/devices/arm/arm_data.c:46
+msgctxt "arm-flag"
+msgid "32x32->64-bit multiplication"
+msgstr ""
+
+#. /flag:fpa
+#: modules/devices/arm/arm_data.c:47
+msgctxt "arm-flag"
+msgid "Floating point accelerator"
+msgstr ""
+
+#. /flag:vfp
+#: modules/devices/arm/arm_data.c:48
+msgctxt "arm-flag"
+msgid "VFP (early SIMD vector floating point instructions)"
+msgstr ""
+
+#. /flag:edsp
+#: modules/devices/arm/arm_data.c:49
+msgctxt "arm-flag"
+msgid "DSP extensions (the 'e' variant of the ARM9 CPUs, and all others above)"
+msgstr ""
+
+#. /flag:java
+#: modules/devices/arm/arm_data.c:50
+msgctxt "arm-flag"
+msgid "Jazelle (Java bytecode accelerator)"
+msgstr ""
+
+#. /flag:iwmmxt
+#: modules/devices/arm/arm_data.c:51
+msgctxt "arm-flag"
+msgid "SIMD instructions similar to Intel MMX"
+msgstr ""
+
+#. /flag:crunch
+#: modules/devices/arm/arm_data.c:52
+msgctxt "arm-flag"
+msgid "MaverickCrunch coprocessor (if kernel support enabled)"
+msgstr ""
+
+#. /flag:thumbee
+#: modules/devices/arm/arm_data.c:53
+msgctxt "arm-flag"
+msgid "ThumbEE"
+msgstr ""
+
+#. /flag:neon
+#: modules/devices/arm/arm_data.c:54
+msgctxt "arm-flag"
+msgid "Advanced SIMD/NEON on AArch32"
+msgstr ""
+
+#. /flag:evtstrm
+#: modules/devices/arm/arm_data.c:55
+msgctxt "arm-flag"
+msgid "Kernel event stream using generic architected timer"
+msgstr ""
+
+#. /flag:vfpv3
+#: modules/devices/arm/arm_data.c:56
+msgctxt "arm-flag"
+msgid "VFP version 3"
+msgstr ""
+
+#. /flag:vfpv3d16
+#: modules/devices/arm/arm_data.c:57
+msgctxt "arm-flag"
+msgid "VFP version 3 with 16 D-registers"
+msgstr ""
+
+#. /flag:vfpv4
+#: modules/devices/arm/arm_data.c:58
+msgctxt "arm-flag"
+msgid "VFP version 4 with fast context switching"
+msgstr ""
+
+#. /flag:vfpd32
+#: modules/devices/arm/arm_data.c:59
+msgctxt "arm-flag"
+msgid "VFP with 32 D-registers"
+msgstr ""
+
+#. /flag:tls
+#: modules/devices/arm/arm_data.c:60
+msgctxt "arm-flag"
+msgid "TLS register"
+msgstr ""
+
+#. /flag:idiva
+#: modules/devices/arm/arm_data.c:61
+msgctxt "arm-flag"
+msgid "SDIV and UDIV hardware division in ARM mode"
+msgstr ""
+
+#. /flag:idivt
+#: modules/devices/arm/arm_data.c:62
+msgctxt "arm-flag"
+msgid "SDIV and UDIV hardware division in Thumb mode"
+msgstr ""
+
+#. /flag:lpae
+#: modules/devices/arm/arm_data.c:63
+msgctxt "arm-flag"
+msgid "40-bit Large Physical Address Extension"
+msgstr ""
+
+#. /hw_cap2
+#. /flag:pmull
+#: modules/devices/arm/arm_data.c:65
+msgctxt "arm-flag"
+msgid "64x64->128-bit F2m multiplication (arch>8)"
+msgstr ""
+
+#. /flag:aes
+#: modules/devices/arm/arm_data.c:66
+msgctxt "arm-flag"
+msgid "Crypto:AES (arch>8)"
+msgstr ""
+
+#. /flag:sha1
+#: modules/devices/arm/arm_data.c:67
+msgctxt "arm-flag"
+msgid "Crypto:SHA1 (arch>8)"
+msgstr ""
+
+#. /flag:sha2
+#: modules/devices/arm/arm_data.c:68
+msgctxt "arm-flag"
+msgid "Crypto:SHA2 (arch>8)"
+msgstr ""
+
+#. /flag:crc32
+#: modules/devices/arm/arm_data.c:69
+msgctxt "arm-flag"
+msgid "CRC32 checksum instructions (arch>8)"
+msgstr ""
+
+#. /flag:asimd
+#: modules/devices/arm/arm_data.c:72
+msgctxt "arm-flag"
+msgid "Advanced SIMD/NEON on AArch64 (arch>8)"
+msgstr ""
+
+#: modules/devices/arm/processor.c:142
+msgid "ARM Processor"
+msgstr ""
+
+#: modules/devices/arm/processor.c:200 modules/devices/riscv/processor.c:147
+#: modules/devices/x86/processor.c:371
+msgid "Empty List"
+msgstr ""
+
+#: modules/devices/arm/processor.c:237
+msgid "Linux Name"
+msgstr ""
+
+#: modules/devices/arm/processor.c:238
+msgid "Decoded Name"
+msgstr ""
+
+#: modules/devices/arm/processor.c:239 modules/network/net.c:458
+msgid "Mode"
+msgstr ""
+
+#: modules/devices/arm/processor.c:245
+msgid "ARM"
+msgstr ""
+
+#: modules/devices/arm/processor.c:246
+msgid "Implementer"
+msgstr ""
+
+#: modules/devices/arm/processor.c:247
+msgid "Part"
+msgstr ""
+
+#: modules/devices/arm/processor.c:248 modules/devices/ia64/processor.c:162
+#: modules/devices/parisc/processor.c:156 modules/devices/riscv/processor.c:183
+msgid "Architecture"
+msgstr ""
+
+#: modules/devices/arm/processor.c:249
+msgid "Variant"
+msgstr ""
+
+#: modules/devices/arm/processor.c:251 modules/devices/riscv/processor.c:190
+#: modules/devices/sparc/processor.c:78 modules/devices/x86/processor.c:428
+msgid "Capabilities"
+msgstr ""
+
+#: modules/devices/arm/processor.c:335
+msgid "SOC/Package"
+msgstr ""
+
+#: modules/devices/arm/processor.c:338 modules/devices/cpu_util.c:222
+msgid "Topology"
+msgstr ""
+
+#: modules/devices/arm/processor.c:339
+msgid "Clocks"
+msgstr ""
+
+#: modules/devices/arm/processor.c:354
+msgid "SOC/Package Information"
+msgstr ""
+
+#: modules/devices/battery.c:181
+#, c-format
+msgid ""
+"\n"
+"[Battery: %s]\n"
+"State=%s (load: %s)\n"
+"Capacity=%s / %s (%.2f%%)\n"
+"Battery Technology=%s (%s)\n"
+"Manufacturer=%s\n"
+"Model Number=%s\n"
+"Serial Number=%s\n"
+msgstr ""
+"\n"
+"[Battery: %s]\n"
+"Etat=%s (load: %s)\n"
+"Capacité=%s / %s (%.2f%%)\n"
+"Technologie=%s (%s)\n"
+"Fabriquant=%s\n"
+"Modele=%s\n"
+"Numéro de série=%s\n"
+
+#: modules/devices/battery.c:258
+#, c-format
+msgid ""
+"\n"
+"[Battery: %s]\n"
+"State=%s\n"
+"Capacity=%s / %s\n"
+"Battery Technology=%s\n"
+"Manufacturer=%s\n"
+"Model Number=%s\n"
+"Serial Number=%s\n"
+msgstr ""
+
+#: modules/devices/battery.c:346
+#, c-format
+msgid ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Remaining Charge=%s of %s\n"
+"Using=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+msgstr ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Charge restante=%s of %s\n"
+"Etat=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+
+#: modules/devices/battery.c:358
+#, c-format
+msgid ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Using=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+msgstr ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Etat=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+
+#: modules/devices/battery.c:385
+msgid ""
+"[No batteries]\n"
+"No batteries found on this system=\n"
+msgstr ""
+"[Aucune batterie]\n"
+"Aucune batterie trouvée sur ce système=\n"
+
+#: modules/devices.c:97
+msgid "PCI Devices"
+msgstr "Périphériques PCI"
+
+#: modules/devices.c:98 modules/devices/usb.c:117 modules/devices/usb.c:156
+#: modules/devices/usb.c:415
+msgid "USB Devices"
+msgstr "Périphériques USB"
+
+#: modules/devices.c:100
+msgid "Battery"
+msgstr "Batterie"
+
+#: modules/devices.c:101
+msgid "Sensors"
+msgstr "Capteurs"
+
+#: modules/devices.c:105
+msgid "DMI"
+msgstr "DMI"
+
+#: modules/devices.c:106
+msgid "Memory SPD"
+msgstr "Mémoire SPD"
+
+#: modules/devices.c:111
+msgid "Device Tree"
+msgstr ""
+
+#: modules/devices.c:113
+msgid "Resources"
+msgstr "Ressources"
+
+#: modules/devices.c:151
+#, c-format
+msgid "%d physical processor"
+msgid_plural "%d physical processors"
+msgstr[0] ""
+msgstr[1] ""
+
+#: modules/devices.c:152
+#, c-format
+msgid "%d core"
+msgid_plural "%d cores"
+msgstr[0] ""
+msgstr[1] ""
+
+#: modules/devices.c:153
+#, c-format
+msgid "%d thread"
+msgid_plural "%d threads"
+msgstr[0] ""
+msgstr[1] ""
+
+#. /NP procs; NC cores; NT threads
+#: modules/devices.c:154
+#, c-format
+msgid "%s; %s; %s"
+msgstr ""
+
+#: modules/devices.c:372
+msgid " (model unknown)"
+msgstr " (modèle inconnu)"
+
+#: modules/devices.c:374
+msgid " (vendor unknown)"
+msgstr " (Fabricant inconnu)"
+
+#: modules/devices.c:559
+msgid "Field"
+msgstr ""
+
+#: modules/devices.c:559 modules/devices.c:591
+msgid "Value"
+msgstr ""
+
+#: modules/devices.c:591
+msgid "Sensor"
+msgstr ""
+
+#: modules/devices.c:591 modules/devices/inputdevices.c:117
+msgid "Type"
+msgstr ""
+
+#: modules/devices.c:637
+msgid "Devices"
+msgstr "Périphériques"
+
+#: modules/devices.c:649
+msgid "Update PCI ID listing"
+msgstr "Mise à jour de la liste ID PCI "
+
+#: modules/devices.c:661
+msgid "Update CPU feature database"
+msgstr "Mise à jour des bases de données caractéristiques CPU"
+
+#: modules/devices.c:689
+msgid "Gathers information about hardware devices"
+msgstr "Collecte des informations des périphériques"
+
+#: modules/devices.c:708
+msgid "Resource information requires superuser privileges"
+msgstr ""
+
+#: modules/devices/cpu_util.c:30
+msgid "Little Endian"
+msgstr ""
+
+#: modules/devices/cpu_util.c:32
+msgid "Big Endian"
+msgstr ""
+
+#: modules/devices/cpu_util.c:178 modules/devices/cpu_util.c:189
+msgid "Frequency Scaling"
+msgstr ""
+
+#: modules/devices/cpu_util.c:179
+msgid "Minimum"
+msgstr ""
+
+#: modules/devices/cpu_util.c:179 modules/devices/cpu_util.c:180
+#: modules/devices/cpu_util.c:181
+msgid "kHz"
+msgstr ""
+
+#: modules/devices/cpu_util.c:180
+msgid "Maximum"
+msgstr ""
+
+#: modules/devices/cpu_util.c:181
+msgid "Current"
+msgstr ""
+
+#: modules/devices/cpu_util.c:182
+msgid "Transition Latency"
+msgstr ""
+
+#: modules/devices/cpu_util.c:182
+msgid "ns"
+msgstr ""
+
+#: modules/devices/cpu_util.c:183
+msgid "Governor"
+msgstr ""
+
+#: modules/devices/cpu_util.c:184 modules/devices/cpu_util.c:190
+msgid "Driver"
+msgstr ""
+
+#: modules/devices/cpu_util.c:196 modules/devices/x86/processor.c:297
+msgid "(Not Available)"
+msgstr ""
+
+#: modules/devices/cpu_util.c:204 modules/devices/cpu_util.c:206
+msgid "Socket"
+msgstr ""
+
+#: modules/devices/cpu_util.c:209 modules/devices/cpu_util.c:211
+msgid "Core"
+msgstr ""
+
+#: modules/devices/cpu_util.c:214
+msgid "Book"
+msgstr ""
+
+#: modules/devices/cpu_util.c:216
+msgid "Drawer"
+msgstr ""
+
+#: modules/devices/cpu_util.c:223
+msgid "ID"
+msgstr ""
+
+#: modules/devices/devicetree.c:47
+msgid "Properties"
+msgstr ""
+
+#: modules/devices/devicetree.c:48
+msgid "Children"
+msgstr ""
+
+#: modules/devices/devicetree.c:84
+msgid "Node"
+msgstr ""
+
+#: modules/devices/devicetree.c:85
+msgid "Node Path"
+msgstr ""
+
+#: modules/devices/devicetree.c:86
+msgid "Alias"
+msgstr ""
+
+#: modules/devices/devicetree.c:86 modules/devices/devicetree.c:87
+msgid "(None)"
+msgstr ""
+
+#: modules/devices/devicetree.c:87
+msgid "Symbol"
+msgstr ""
+
+#: modules/devices/devicetree.c:132 modules/devices/devicetree/pmac_data.c:79
+msgid "Platform"
+msgstr ""
+
+#: modules/devices/devicetree.c:133 modules/devices/devicetree.c:178
+msgid "Compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:134
+msgid "GPU-compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:140
+msgid "Raspberry Pi or Compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:142 modules/devices/devicetree.c:160
+#: modules/devices/devicetree.c:177 modules/devices/devicetree/rpi_data.c:160
+msgid "Serial Number"
+msgstr ""
+
+#: modules/devices/devicetree.c:143 modules/devices/devicetree/rpi_data.c:157
+msgid "RCode"
+msgstr ""
+
+#: modules/devices/devicetree.c:143
+msgid "No revision code available; unable to lookup model details."
+msgstr ""
+
+#: modules/devices/devicetree.c:159
+msgid "More"
+msgstr ""
+
+#: modules/devices/devicetree.c:175
+msgid "Board"
+msgstr ""
+
+#: modules/devices/devicetree.c:234
+msgid "Messages"
+msgstr ""
+
+#: modules/devices/devicetree/dt_util.c:1013
+msgid "phandle Map"
+msgstr ""
+
+#: modules/devices/devicetree/dt_util.c:1014
+msgid "Alias Map"
+msgstr ""
+
+#: modules/devices/devicetree/dt_util.c:1015
+msgid "Symbol Map"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:78
+msgid "Apple Power Macintosh"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:81 modules/devices/sh/processor.c:85
+msgid "Machine"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:83
+msgid "Detected as"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:84
+msgid "PMAC Flags"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:85
+msgid "L2 Cache"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:86
+msgid "PMAC Generation"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:152
+#: modules/devices/devicetree/rpi_data.c:153
+msgid "Raspberry Pi"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:153
+msgid "Board Name"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:154
+msgid "PCB Revision"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:155
+msgid "Introduction"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:156 modules/devices/spd-decode.c:1510
+#: modules/devices/usb.c:84 modules/devices/usb.c:217
+msgid "Manufacturer"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:158
+msgid "SOC (spec)"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:159
+msgid "Memory (spec)"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgid "Permanent overvolt bit"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgctxt "rpi-ov-bit"
+msgid "Set"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgctxt "rpi-ov-bit"
+msgid "Not set"
+msgstr ""
+
+#: modules/devices/devmemory.c:93
+msgid "Total Memory"
+msgstr "Mémoire totale"
+
+#: modules/devices/devmemory.c:94
+msgid "Free Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:95
+msgid "Cached Swap"
+msgstr ""
+
+#: modules/devices/devmemory.c:96
+msgid "High Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:97
+msgid "Free High Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:98
+msgid "Low Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:99
+msgid "Free Low Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:100
+msgid "Virtual Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:101
+msgid "Free Virtual Memory"
+msgstr ""
+
+#: modules/devices/dmi.c:188
+msgid "(Not available; Perhaps try running HardInfo as root.)"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:108
+msgid "IA64 Processor"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:163
+msgid "Architecture Revision"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:164 modules/devices/sh/processor.c:86
+msgid "Family"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:170
+msgid "CPU regs"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:171
+msgid "Features"
+msgstr ""
+
+#: modules/devices/inputdevices.c:115 modules/devices/pci.c:214
+#: modules/devices/usb.c:82 modules/devices/usb.c:215 modules/devices/usb.c:347
+msgid "Device Information"
+msgstr ""
+
+#: modules/devices/inputdevices.c:118 modules/devices/usb.c:92
+#: modules/devices/usb.c:240 modules/devices/usb.c:356
+msgid "Bus"
+msgstr ""
+
+#: modules/devices/inputdevices.c:120 modules/devices/usb.c:83
+#: modules/devices/usb.c:216 modules/devices/usb.c:348
+msgid "Product"
+msgstr ""
+
+#: modules/devices/inputdevices.c:124
+msgid "Connected to"
+msgstr ""
+
+#: modules/devices/inputdevices.c:128
+msgid "InfraRed port"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:85 modules/devices/riscv/processor.c:185
+msgid "MMU"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:86 modules/devices/sparc/processor.c:76
+msgid "FPU"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:90
+msgid "Calibration"
+msgstr ""
+
+#: modules/devices/mips/processor.c:76
+msgid "System Type"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:107
+msgid "PA-RISC Processor"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:157
+msgid "System"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:161
+msgid "HVersion"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:162
+msgid "SVersion"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:163 modules/devices/x86/processor.c:425
+msgid "Cache"
+msgstr ""
+
+#: modules/devices/pci.c:106
+msgid "IRQ"
+msgstr ""
+
+#: modules/devices/pci.c:110
+msgid "Latency"
+msgstr ""
+
+#: modules/devices/pci.c:112
+msgid "Bus Master"
+msgstr ""
+
+#: modules/devices/pci.c:118
+msgid "Kernel modules"
+msgstr ""
+
+#: modules/devices/pci.c:124
+#, c-format
+msgid "%s=%s (%s)\n"
+msgstr ""
+
+#: modules/devices/pci.c:126
+msgid "OEM Vendor"
+msgstr ""
+
+#: modules/devices/pci.c:153
+msgid "prefetchable"
+msgstr ""
+
+#: modules/devices/pci.c:154
+msgid "non-prefetchable"
+msgstr ""
+
+#: modules/devices/pci.c:163
+msgid "I/O ports at"
+msgstr ""
+
+#: modules/devices/pci.c:216 modules/devices/usb.c:89 modules/devices/usb.c:237
+#: modules/devices/usb.c:353
+msgid "Class"
+msgstr ""
+
+#: modules/devices/pci.c:217
+msgid "Domain"
+msgstr ""
+
+#: modules/devices/pci.c:218
+msgid "Bus, device, function"
+msgstr ""
+
+#: modules/devices/pci.c:243
+msgid "No PCI devices found"
+msgstr ""
+
+#: modules/devices/ppc/processor.c:117
+msgid "POWER Processor"
+msgstr ""
+
+#: modules/devices/printers.c:81
+msgid "⚬ Can do black and white printing=\n"
+msgstr "⚬ Impression en noir et blanc =\n"
+
+#: modules/devices/printers.c:83
+msgid "⚬ Can do color printing=\n"
+msgstr "⚬ Imprimer en couleur=\n"
+
+#: modules/devices/printers.c:85
+msgid "⚬ Can do duplexing=\n"
+msgstr "⚬ Imprimer recto verso=\n"
+
+#: modules/devices/printers.c:87
+msgid "⚬ Can do staple output=\n"
+msgstr "⚬ Agrafer les feuilles imprimées=\n"
+
+#: modules/devices/printers.c:89
+msgid "⚬ Can do copies=\n"
+msgstr "⚬ Réaliser copies=\n"
+
+#: modules/devices/printers.c:91
+msgid "⚬ Can collate copies=\n"
+msgstr "⚬ Assembler des copies=\n"
+
+#: modules/devices/printers.c:93
+msgid "⚬ Printer is rejecting jobs=\n"
+msgstr "⚬ Imprimante rejette cette tâche=\n"
+
+#: modules/devices/printers.c:95
+msgid "⚬ Printer was automatically discovered and added=\n"
+msgstr "⚬ Imprimante a été automatiquement détecté et ajouté=\n"
+
+#: modules/devices/printers.c:110
+msgid "Idle"
+msgstr "Inoccupé"
+
+#: modules/devices/printers.c:112
+msgid "Printing a Job"
+msgstr "Impression"
+
+#: modules/devices/printers.c:114
+msgid "Stopped"
+msgstr "Arrêt"
+
+#: modules/devices/printers.c:190
+msgid ""
+"[Printers]\n"
+"No suitable CUPS library found="
+msgstr ""
+"[Printers]\n"
+"Aucune suite de librairie CUPS trouvée="
+
+#: modules/devices/printers.c:200
+msgid "[Printers (CUPS)]\n"
+msgstr "[Printers (CUPS)]\n"
+
+#: modules/devices/printers.c:263
+msgid ""
+"[Printers]\n"
+"No printers found=\n"
+msgstr ""
+"[Printers]\n"
+"Aucune imprimante trouvée=\n"
+
+#: modules/devices/riscv/processor.c:107
+msgid "RISC-V Processor"
+msgstr ""
+
+#: modules/devices/riscv/processor.c:184
+msgid "uarch"
+msgstr ""
+
+#. /ext:RV32
+#: modules/devices/riscv/riscv_data.c:37
+msgctxt "rv-ext"
+msgid "RISC-V 32-bit"
+msgstr ""
+
+#. /ext:RV64
+#: modules/devices/riscv/riscv_data.c:38
+msgctxt "rv-ext"
+msgid "RISC-V 64-bit"
+msgstr ""
+
+#. /ext:RV128
+#: modules/devices/riscv/riscv_data.c:39
+msgctxt "rv-ext"
+msgid "RISC-V 128-bit"
+msgstr ""
+
+#. /ext:E
+#: modules/devices/riscv/riscv_data.c:40
+msgctxt "rv-ext"
+msgid "Base embedded integer instructions (15 registers)"
+msgstr ""
+
+#. /ext:I
+#: modules/devices/riscv/riscv_data.c:41
+msgctxt "rv-ext"
+msgid "Base integer instructions (31 registers)"
+msgstr ""
+
+#. /ext:M
+#: modules/devices/riscv/riscv_data.c:42
+msgctxt "rv-ext"
+msgid "Hardware integer multiply and divide"
+msgstr ""
+
+#. /ext:A
+#: modules/devices/riscv/riscv_data.c:43
+msgctxt "rv-ext"
+msgid "Atomic memory operations"
+msgstr ""
+
+#. /ext:C
+#: modules/devices/riscv/riscv_data.c:44
+msgctxt "rv-ext"
+msgid "Compressed 16-bit instructions"
+msgstr ""
+
+#. /ext:F
+#: modules/devices/riscv/riscv_data.c:45
+msgctxt "rv-ext"
+msgid "Floating-point instructions, single-precision"
+msgstr ""
+
+#. /ext:D
+#: modules/devices/riscv/riscv_data.c:46
+msgctxt "rv-ext"
+msgid "Floating-point instructions, double-precision"
+msgstr ""
+
+#. /ext:Q
+#: modules/devices/riscv/riscv_data.c:47
+msgctxt "rv-ext"
+msgid "Floating-point instructions, quad-precision"
+msgstr ""
+
+#. /ext:B
+#: modules/devices/riscv/riscv_data.c:48
+msgctxt "rv-ext"
+msgid "Bit manipulation instructions"
+msgstr ""
+
+#. /ext:V
+#: modules/devices/riscv/riscv_data.c:49
+msgctxt "rv-ext"
+msgid "Vector operations"
+msgstr ""
+
+#. /ext:T
+#: modules/devices/riscv/riscv_data.c:50
+msgctxt "rv-ext"
+msgid "Transactional memory"
+msgstr ""
+
+#. /ext:P
+#: modules/devices/riscv/riscv_data.c:51
+msgctxt "rv-ext"
+msgid "Packed SIMD instructions"
+msgstr ""
+
+#. /ext:L
+#: modules/devices/riscv/riscv_data.c:52
+msgctxt "rv-ext"
+msgid "Decimal floating-point instructions"
+msgstr ""
+
+#. /ext:J
+#: modules/devices/riscv/riscv_data.c:53
+msgctxt "rv-ext"
+msgid "Dynamically translated languages"
+msgstr ""
+
+#. /ext:N
+#: modules/devices/riscv/riscv_data.c:54
+msgctxt "rv-ext"
+msgid "User-level interrupts"
+msgstr ""
+
+#: modules/devices/s390/processor.c:92
+msgid "S390 Processor"
+msgstr ""
+
+#: modules/devices/s390/processor.c:133
+msgid "ID String"
+msgstr ""
+
+#: modules/devices/sh/processor.c:55
+msgid "SuperH Processor"
+msgstr ""
+
+#: modules/devices/sh/processor.c:88
+msgid "Bus Frequency"
+msgstr ""
+
+#: modules/devices/sh/processor.c:89
+msgid "Module Frequency"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1475
+msgid ""
+"[SPD]\n"
+"Please load the eeprom module to obtain information about memory SPD=\n"
+"[$ShellParam$]\n"
+"ReloadInterval=500\n"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1480
+msgid ""
+"[SPD]\n"
+"Reading memory SPD not supported on this system=\n"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1509
+msgid "SPD"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1510
+msgid "Bank"
+msgstr ""
+
+#: modules/devices/storage.c:46
+msgid ""
+"\n"
+"[SCSI Disks]\n"
+msgstr ""
+"\n"
+"[SCSI Disks]\n"
+
+#: modules/devices/storage.c:110 modules/devices/storage.c:313
+#, c-format
+msgid ""
+"[Device Information]\n"
+"Model=%s\n"
+msgstr ""
+"[Device Information]\n"
+"Modele=%s\n"
+
+#: modules/devices/storage.c:115 modules/devices/storage.c:319
+#, c-format
+msgid "Vendor=%s (%s)\n"
+msgstr "Vendeur=%s (%s)\n"
+
+#: modules/devices/storage.c:120 modules/devices/storage.c:321
+#, c-format
+msgid "Vendor=%s\n"
+msgstr "Vendeur=%s\n"
+
+#: modules/devices/storage.c:125
+#, c-format
+msgid ""
+"Type=%s\n"
+"Revision=%s\n"
+"[SCSI Controller]\n"
+"Controller=scsi%d\n"
+"Channel=%d\n"
+"ID=%d\n"
+"LUN=%d\n"
+msgstr ""
+"Type=%s\n"
+"Revision=%s\n"
+"[SCSI Controller]\n"
+"Controleur=scsi%d\n"
+"Channel=%d\n"
+"ID=%d\n"
+"LUN=%d\n"
+
+#: modules/devices/storage.c:167
+msgid ""
+"\n"
+"[IDE Disks]\n"
+msgstr ""
+"\n"
+"[IDE Disks]\n"
+
+#: modules/devices/storage.c:250
+#, c-format
+msgid "Driver=%s\n"
+msgstr "Driver=%s\n"
+
+#: modules/devices/storage.c:324
+#, c-format
+msgid ""
+"Device Name=hd%c\n"
+"Media=%s\n"
+"Cache=%dkb\n"
+msgstr ""
+
+#: modules/devices/storage.c:334
+#, c-format
+msgid ""
+"[Geometry]\n"
+"Physical=%s\n"
+"Logical=%s\n"
+msgstr ""
+"[Geometry]\n"
+"Physique=%s\n"
+"Logique=%s\n"
+
+#: modules/devices/storage.c:344
+#, c-format
+msgid ""
+"[Capabilities]\n"
+"%s"
+msgstr ""
+"[Capabilities]\n"
+"%s"
+
+#: modules/devices/storage.c:351
+#, c-format
+msgid ""
+"[Speeds]\n"
+"%s"
+msgstr ""
+"[Speeds]\n"
+"%s"
+
+#: modules/devices/usb.c:44 modules/devices/usb.c:326
+msgid "mA"
+msgstr ""
+
+#. /%.2f is version
+#: modules/devices/usb.c:53 modules/devices/usb.c:190
+#, c-format
+msgid "USB %.2f Hub"
+msgstr ""
+
+#: modules/devices/usb.c:55 modules/devices/usb.c:192
+#, c-format
+msgid "Unknown USB %.2f Device (class %d)"
+msgstr ""
+
+#: modules/devices/usb.c:85 modules/devices/usb.c:232
+msgid "Speed"
+msgstr ""
+
+#: modules/devices/usb.c:85 modules/devices/usb.c:232
+msgid "Mbit/s"
+msgstr ""
+
+#: modules/devices/usb.c:86 modules/devices/usb.c:233 modules/devices/usb.c:350
+msgid "Max Current"
+msgstr ""
+
+#: modules/devices/usb.c:88 modules/devices/usb.c:235 modules/devices/usb.c:352
+msgid "USB Version"
+msgstr ""
+
+#: modules/devices/usb.c:90 modules/devices/usb.c:238 modules/devices/usb.c:354
+msgid "Vendor ID"
+msgstr ""
+
+#: modules/devices/usb.c:91 modules/devices/usb.c:239 modules/devices/usb.c:355
+msgid "Product ID"
+msgstr ""
+
+#: modules/devices/usb.c:231
+msgid "Port"
+msgstr ""
+
+#: modules/devices/usb.c:241
+msgid "Level"
+msgstr ""
+
+#: modules/devices/x86/processor.c:149
+msgid "Cache information not available=\n"
+msgstr ""
+
+#: modules/devices/x86/processor.c:155
+#, c-format
+msgid "Level %d (%s)=%d-way set-associative, %d sets, %dKB size\n"
+msgstr ""
+
+#. /cache type, as appears in: Level 1 (Data)
+#: modules/devices/x86/processor.c:170
+msgctxt "cache-type"
+msgid "Data"
+msgstr ""
+
+#. /cache type, as appears in: Level 1 (Instruction)
+#: modules/devices/x86/processor.c:171
+msgctxt "cache-type"
+msgid "Instruction"
+msgstr ""
+
+#. /cache type, as appears in: Level 2 (Unified)
+#: modules/devices/x86/processor.c:172
+msgctxt "cache-type"
+msgid "Unified"
+msgstr ""
+
+#: modules/devices/x86/processor.c:410
+msgid "Model Name"
+msgstr ""
+
+#: modules/devices/x86/processor.c:411
+msgid "Family, model, stepping"
+msgstr ""
+
+#: modules/devices/x86/processor.c:417
+msgid "Microcode Version"
+msgstr ""
+
+#: modules/devices/x86/processor.c:418
+msgid "Configuration"
+msgstr ""
+
+#: modules/devices/x86/processor.c:419
+msgid "Cache Size"
+msgstr ""
+
+#: modules/devices/x86/processor.c:419
+msgid "kb"
+msgstr ""
+
+#: modules/devices/x86/processor.c:426
+msgid "Power Management"
+msgstr ""
+
+#: modules/devices/x86/processor.c:427
+msgid "Bug Workarounds"
+msgstr ""
+
+#: modules/devices/x86/processor.c:454 modules/devices/x86/processor.c:468
+msgid "Package Information"
+msgstr ""
+
+#. /flag:fpu
+#: modules/devices/x86/x86_data.c:43
+msgctxt "x86-flag"
+msgid "Onboard FPU (floating point support)"
+msgstr ""
+
+#. /flag:vme
+#: modules/devices/x86/x86_data.c:44
+msgctxt "x86-flag"
+msgid "Virtual 8086 mode enhancements"
+msgstr ""
+
+#. /flag:de
+#: modules/devices/x86/x86_data.c:45
+msgctxt "x86-flag"
+msgid "Debugging Extensions (CR4.DE)"
+msgstr ""
+
+#. /flag:pse
+#: modules/devices/x86/x86_data.c:46
+msgctxt "x86-flag"
+msgid "Page Size Extensions (4MB memory pages)"
+msgstr ""
+
+#. /flag:tsc
+#: modules/devices/x86/x86_data.c:47
+msgctxt "x86-flag"
+msgid "Time Stamp Counter (RDTSC)"
+msgstr ""
+
+#. /flag:msr
+#: modules/devices/x86/x86_data.c:48
+msgctxt "x86-flag"
+msgid "Model-Specific Registers (RDMSR, WRMSR)"
+msgstr ""
+
+#. /flag:pae
+#: modules/devices/x86/x86_data.c:49
+msgctxt "x86-flag"
+msgid "Physical Address Extensions (support for more than 4GB of RAM)"
+msgstr ""
+
+#. /flag:mce
+#: modules/devices/x86/x86_data.c:50
+msgctxt "x86-flag"
+msgid "Machine Check Exception"
+msgstr ""
+
+#. /flag:cx8
+#: modules/devices/x86/x86_data.c:51
+msgctxt "x86-flag"
+msgid "CMPXCHG8 instruction (64-bit compare-and-swap)"
+msgstr ""
+
+#. /flag:apic
+#: modules/devices/x86/x86_data.c:52
+msgctxt "x86-flag"
+msgid "Onboard APIC"
+msgstr ""
+
+#. /flag:sep
+#: modules/devices/x86/x86_data.c:53
+msgctxt "x86-flag"
+msgid "SYSENTER/SYSEXIT"
+msgstr ""
+
+#. /flag:mtrr
+#: modules/devices/x86/x86_data.c:54
+msgctxt "x86-flag"
+msgid "Memory Type Range Registers"
+msgstr ""
+
+#. /flag:pge
+#: modules/devices/x86/x86_data.c:55
+msgctxt "x86-flag"
+msgid "Page Global Enable (global bit in PDEs and PTEs)"
+msgstr ""
+
+#. /flag:mca
+#: modules/devices/x86/x86_data.c:56
+msgctxt "x86-flag"
+msgid "Machine Check Architecture"
+msgstr ""
+
+#. /flag:cmov
+#: modules/devices/x86/x86_data.c:57
+msgctxt "x86-flag"
+msgid "CMOV instructions (conditional move) (also FCMOV)"
+msgstr ""
+
+#. /flag:pat
+#: modules/devices/x86/x86_data.c:58
+msgctxt "x86-flag"
+msgid "Page Attribute Table"
+msgstr ""
+
+#. /flag:pse36
+#: modules/devices/x86/x86_data.c:59
+msgctxt "x86-flag"
+msgid "36-bit PSEs (huge pages)"
+msgstr ""
+
+#. /flag:pn
+#: modules/devices/x86/x86_data.c:60
+msgctxt "x86-flag"
+msgid "Processor serial number"
+msgstr ""
+
+#. /flag:clflush
+#: modules/devices/x86/x86_data.c:61
+msgctxt "x86-flag"
+msgid "Cache Line Flush instruction"
+msgstr ""
+
+#. /flag:dts
+#: modules/devices/x86/x86_data.c:62
+msgctxt "x86-flag"
+msgid ""
+"Debug Store (buffer for debugging and profiling instructions), or "
+"alternately: digital thermal sensor"
+msgstr ""
+
+#. /flag:acpi
+#: modules/devices/x86/x86_data.c:63
+msgctxt "x86-flag"
+msgid "ACPI via MSR (temperature monitoring and clock speed modulation)"
+msgstr ""
+
+#. /flag:mmx
+#: modules/devices/x86/x86_data.c:64
+msgctxt "x86-flag"
+msgid "Multimedia Extensions"
+msgstr ""
+
+#. /flag:fxsr
+#: modules/devices/x86/x86_data.c:65
+msgctxt "x86-flag"
+msgid "FXSAVE/FXRSTOR, CR4.OSFXSR"
+msgstr ""
+
+#. /flag:sse
+#: modules/devices/x86/x86_data.c:66
+msgctxt "x86-flag"
+msgid "Intel SSE vector instructions"
+msgstr ""
+
+#. /flag:sse2
+#: modules/devices/x86/x86_data.c:67
+msgctxt "x86-flag"
+msgid "SSE2"
+msgstr ""
+
+#. /flag:ss
+#: modules/devices/x86/x86_data.c:68
+msgctxt "x86-flag"
+msgid "CPU self snoop"
+msgstr ""
+
+#. /flag:ht
+#: modules/devices/x86/x86_data.c:69
+msgctxt "x86-flag"
+msgid "Hyper-Threading"
+msgstr ""
+
+#. /flag:tm
+#: modules/devices/x86/x86_data.c:70
+msgctxt "x86-flag"
+msgid "Automatic clock control (Thermal Monitor)"
+msgstr ""
+
+#. /flag:ia64
+#: modules/devices/x86/x86_data.c:71
+msgctxt "x86-flag"
+msgid ""
+"Intel Itanium Architecture 64-bit (not to be confused with Intel's 64-bit "
+"x86 architecture with flag x86-64 or \"AMD64\" bit indicated by flag lm)"
+msgstr ""
+
+#. /flag:pbe
+#: modules/devices/x86/x86_data.c:72
+msgctxt "x86-flag"
+msgid "Pending Break Enable (PBE# pin) wakeup support"
+msgstr ""
+
+#. /flag:syscall
+#: modules/devices/x86/x86_data.c:75
+msgctxt "x86-flag"
+msgid "SYSCALL (Fast System Call) and SYSRET (Return From Fast System Call)"
+msgstr ""
+
+#. /flag:mp
+#: modules/devices/x86/x86_data.c:76
+msgctxt "x86-flag"
+msgid "Multiprocessing Capable."
+msgstr ""
+
+#. /flag:nx
+#: modules/devices/x86/x86_data.c:77
+msgctxt "x86-flag"
+msgid "Execute Disable"
+msgstr ""
+
+#. /flag:mmxext
+#: modules/devices/x86/x86_data.c:78
+msgctxt "x86-flag"
+msgid "AMD MMX extensions"
+msgstr ""
+
+#. /flag:fxsr_opt
+#: modules/devices/x86/x86_data.c:79
+msgctxt "x86-flag"
+msgid "FXSAVE/FXRSTOR optimizations"
+msgstr ""
+
+#. /flag:pdpe1gb
+#: modules/devices/x86/x86_data.c:80
+msgctxt "x86-flag"
+msgid "One GB pages (allows hugepagesz=1G)"
+msgstr ""
+
+#. /flag:rdtscp
+#: modules/devices/x86/x86_data.c:81
+msgctxt "x86-flag"
+msgid "Read Time-Stamp Counter and Processor ID"
+msgstr ""
+
+#. /flag:lm
+#: modules/devices/x86/x86_data.c:82
+msgctxt "x86-flag"
+msgid "Long Mode (x86-64: amd64, also known as Intel 64, i.e. 64-bit capable)"
+msgstr ""
+
+#. /flag:3dnow
+#: modules/devices/x86/x86_data.c:83
+msgctxt "x86-flag"
+msgid "3DNow! (AMD vector instructions, competing with Intel's SSE1)"
+msgstr ""
+
+#. /flag:3dnowext
+#: modules/devices/x86/x86_data.c:84
+msgctxt "x86-flag"
+msgid "AMD 3DNow! extensions"
+msgstr ""
+
+#. /flag:recovery
+#: modules/devices/x86/x86_data.c:86
+msgctxt "x86-flag"
+msgid "CPU in recovery mode"
+msgstr ""
+
+#. /flag:longrun
+#: modules/devices/x86/x86_data.c:87
+msgctxt "x86-flag"
+msgid "Longrun power control"
+msgstr ""
+
+#. /flag:lrti
+#: modules/devices/x86/x86_data.c:88
+msgctxt "x86-flag"
+msgid "LongRun table interface"
+msgstr ""
+
+#. /flag:cxmmx
+#: modules/devices/x86/x86_data.c:90
+msgctxt "x86-flag"
+msgid "Cyrix MMX extensions"
+msgstr ""
+
+#. /flag:k6_mtrr
+#: modules/devices/x86/x86_data.c:91
+msgctxt "x86-flag"
+msgid "AMD K6 nonstandard MTRRs"
+msgstr ""
+
+#. /flag:cyrix_arr
+#: modules/devices/x86/x86_data.c:92
+msgctxt "x86-flag"
+msgid "Cyrix ARRs (= MTRRs)"
+msgstr ""
+
+#. /flag:centaur_mcr
+#: modules/devices/x86/x86_data.c:93
+msgctxt "x86-flag"
+msgid "Centaur MCRs (= MTRRs)"
+msgstr ""
+
+#. /flag:constant_tsc
+#: modules/devices/x86/x86_data.c:94
+msgctxt "x86-flag"
+msgid "TSC ticks at a constant rate"
+msgstr ""
+
+#. /flag:up
+#: modules/devices/x86/x86_data.c:95
+msgctxt "x86-flag"
+msgid "SMP kernel running on UP"
+msgstr ""
+
+#. /flag:art
+#: modules/devices/x86/x86_data.c:96
+msgctxt "x86-flag"
+msgid "Always-Running Timer"
+msgstr ""
+
+#. /flag:arch_perfmon
+#: modules/devices/x86/x86_data.c:97
+msgctxt "x86-flag"
+msgid "Intel Architectural PerfMon"
+msgstr ""
+
+#. /flag:pebs
+#: modules/devices/x86/x86_data.c:98
+msgctxt "x86-flag"
+msgid "Precise-Event Based Sampling"
+msgstr ""
+
+#. /flag:bts
+#: modules/devices/x86/x86_data.c:99
+msgctxt "x86-flag"
+msgid "Branch Trace Store"
+msgstr ""
+
+#. /flag:rep_good
+#: modules/devices/x86/x86_data.c:100
+msgctxt "x86-flag"
+msgid "rep microcode works well"
+msgstr ""
+
+#. /flag:acc_power
+#: modules/devices/x86/x86_data.c:101
+msgctxt "x86-flag"
+msgid "AMD accumulated power mechanism"
+msgstr ""
+
+#. /flag:nopl
+#: modules/devices/x86/x86_data.c:102
+msgctxt "x86-flag"
+msgid "The NOPL (0F 1F) instructions"
+msgstr ""
+
+#. /flag:xtopology
+#: modules/devices/x86/x86_data.c:103
+msgctxt "x86-flag"
+msgid "cpu topology enum extensions"
+msgstr ""
+
+#. /flag:tsc_reliable
+#: modules/devices/x86/x86_data.c:104
+msgctxt "x86-flag"
+msgid "TSC is known to be reliable"
+msgstr ""
+
+#. /flag:nonstop_tsc
+#: modules/devices/x86/x86_data.c:105
+msgctxt "x86-flag"
+msgid "TSC does not stop in C states"
+msgstr ""
+
+#. /flag:extd_apicid
+#: modules/devices/x86/x86_data.c:106
+msgctxt "x86-flag"
+msgid "has extended APICID (8 bits)"
+msgstr ""
+
+#. /flag:amd_dcm
+#: modules/devices/x86/x86_data.c:107
+msgctxt "x86-flag"
+msgid "multi-node processor"
+msgstr ""
+
+#. /flag:aperfmperf
+#: modules/devices/x86/x86_data.c:108
+msgctxt "x86-flag"
+msgid "APERFMPERF"
+msgstr ""
+
+#. /flag:eagerfpu
+#: modules/devices/x86/x86_data.c:109
+msgctxt "x86-flag"
+msgid "Non lazy FPU restore"
+msgstr ""
+
+#. /flag:nonstop_tsc_s3
+#: modules/devices/x86/x86_data.c:110
+msgctxt "x86-flag"
+msgid "TSC doesn't stop in S3 state"
+msgstr ""
+
+#. /flag:mce_recovery
+#: modules/devices/x86/x86_data.c:111
+msgctxt "x86-flag"
+msgid "CPU has recoverable machine checks"
+msgstr ""
+
+#. /flag:pni
+#: modules/devices/x86/x86_data.c:114
+msgctxt "x86-flag"
+msgid "SSE-3 (\"Prescott New Instructions\")"
+msgstr ""
+
+#. /flag:pclmulqdq
+#: modules/devices/x86/x86_data.c:115
+msgctxt "x86-flag"
+msgid ""
+"Perform a Carry-Less Multiplication of Quadword instruction - accelerator "
+"for GCM)"
+msgstr ""
+
+#. /flag:dtes64
+#: modules/devices/x86/x86_data.c:116
+msgctxt "x86-flag"
+msgid "64-bit Debug Store"
+msgstr ""
+
+#. /flag:monitor
+#: modules/devices/x86/x86_data.c:117
+msgctxt "x86-flag"
+msgid "Monitor/Mwait support (Intel SSE3 supplements)"
+msgstr ""
+
+#. /flag:ds_cpl
+#: modules/devices/x86/x86_data.c:118
+msgctxt "x86-flag"
+msgid "CPL Qual. Debug Store"
+msgstr ""
+
+#. /flag:vmx
+#: modules/devices/x86/x86_data.c:119
+msgctxt "x86-flag"
+msgid "Hardware virtualization, Intel VMX"
+msgstr ""
+
+#. /flag:smx
+#: modules/devices/x86/x86_data.c:120
+msgctxt "x86-flag"
+msgid "Safer mode TXT (TPM support)"
+msgstr ""
+
+#. /flag:est
+#: modules/devices/x86/x86_data.c:121
+msgctxt "x86-flag"
+msgid "Enhanced SpeedStep"
+msgstr ""
+
+#. /flag:tm2
+#: modules/devices/x86/x86_data.c:122
+msgctxt "x86-flag"
+msgid "Thermal Monitor 2"
+msgstr ""
+
+#. /flag:ssse3
+#: modules/devices/x86/x86_data.c:123
+msgctxt "x86-flag"
+msgid "Supplemental SSE-3"
+msgstr ""
+
+#. /flag:cid
+#: modules/devices/x86/x86_data.c:124
+msgctxt "x86-flag"
+msgid "Context ID"
+msgstr ""
+
+#. /flag:sdbg
+#: modules/devices/x86/x86_data.c:125
+msgctxt "x86-flag"
+msgid "silicon debug"
+msgstr ""
+
+#. /flag:fma
+#: modules/devices/x86/x86_data.c:126
+msgctxt "x86-flag"
+msgid "Fused multiply-add"
+msgstr ""
+
+#. /flag:cx16
+#: modules/devices/x86/x86_data.c:127
+msgctxt "x86-flag"
+msgid "CMPXCHG16B"
+msgstr ""
+
+#. /flag:xtpr
+#: modules/devices/x86/x86_data.c:128
+msgctxt "x86-flag"
+msgid "Send Task Priority Messages"
+msgstr ""
+
+#. /flag:pdcm
+#: modules/devices/x86/x86_data.c:129
+msgctxt "x86-flag"
+msgid "Performance Capabilities"
+msgstr ""
+
+#. /flag:pcid
+#: modules/devices/x86/x86_data.c:130
+msgctxt "x86-flag"
+msgid "Process Context Identifiers"
+msgstr ""
+
+#. /flag:dca
+#: modules/devices/x86/x86_data.c:131
+msgctxt "x86-flag"
+msgid "Direct Cache Access"
+msgstr ""
+
+#. /flag:sse4_1
+#: modules/devices/x86/x86_data.c:132
+msgctxt "x86-flag"
+msgid "SSE-4.1"
+msgstr ""
+
+#. /flag:sse4_2
+#: modules/devices/x86/x86_data.c:133
+msgctxt "x86-flag"
+msgid "SSE-4.2"
+msgstr ""
+
+#. /flag:x2apic
+#: modules/devices/x86/x86_data.c:134
+msgctxt "x86-flag"
+msgid "x2APIC"
+msgstr ""
+
+#. /flag:movbe
+#: modules/devices/x86/x86_data.c:135
+msgctxt "x86-flag"
+msgid "Move Data After Swapping Bytes instruction"
+msgstr ""
+
+#. /flag:popcnt
+#: modules/devices/x86/x86_data.c:136
+msgctxt "x86-flag"
+msgid ""
+"Return the Count of Number of Bits Set to 1 instruction (Hamming weight, i."
+"e. bit count)"
+msgstr ""
+
+#. /flag:tsc_deadline_timer
+#: modules/devices/x86/x86_data.c:137
+msgctxt "x86-flag"
+msgid "Tsc deadline timer"
+msgstr ""
+
+#. /flag:aes/aes-ni
+#: modules/devices/x86/x86_data.c:138
+msgctxt "x86-flag"
+msgid "Advanced Encryption Standard (New Instructions)"
+msgstr ""
+
+#. /flag:xsave
+#: modules/devices/x86/x86_data.c:139
+msgctxt "x86-flag"
+msgid "Save Processor Extended States: also provides XGETBY,XRSTOR,XSETBY"
+msgstr ""
+
+#. /flag:avx
+#: modules/devices/x86/x86_data.c:140
+msgctxt "x86-flag"
+msgid "Advanced Vector Extensions"
+msgstr ""
+
+#. /flag:f16c
+#: modules/devices/x86/x86_data.c:141
+msgctxt "x86-flag"
+msgid "16-bit fp conversions (CVT16)"
+msgstr ""
+
+#. /flag:rdrand
+#: modules/devices/x86/x86_data.c:142
+msgctxt "x86-flag"
+msgid "Read Random Number from hardware random number generator instruction"
+msgstr ""
+
+#. /flag:hypervisor
+#: modules/devices/x86/x86_data.c:143
+msgctxt "x86-flag"
+msgid "Running on a hypervisor"
+msgstr ""
+
+#. /Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001
+#. /flag:rng
+#: modules/devices/x86/x86_data.c:145
+msgctxt "x86-flag"
+msgid "Random Number Generator present (xstore)"
+msgstr ""
+
+#. /flag:rng_en
+#: modules/devices/x86/x86_data.c:146
+msgctxt "x86-flag"
+msgid "Random Number Generator enabled"
+msgstr ""
+
+#. /flag:ace
+#: modules/devices/x86/x86_data.c:147
+msgctxt "x86-flag"
+msgid "on-CPU crypto (xcrypt)"
+msgstr ""
+
+#. /flag:ace_en
+#: modules/devices/x86/x86_data.c:148
+msgctxt "x86-flag"
+msgid "on-CPU crypto enabled"
+msgstr ""
+
+#. /flag:ace2
+#: modules/devices/x86/x86_data.c:149
+msgctxt "x86-flag"
+msgid "Advanced Cryptography Engine v2"
+msgstr ""
+
+#. /flag:ace2_en
+#: modules/devices/x86/x86_data.c:150
+msgctxt "x86-flag"
+msgid "ACE v2 enabled"
+msgstr ""
+
+#. /flag:phe
+#: modules/devices/x86/x86_data.c:151
+msgctxt "x86-flag"
+msgid "PadLock Hash Engine"
+msgstr ""
+
+#. /flag:phe_en
+#: modules/devices/x86/x86_data.c:152
+msgctxt "x86-flag"
+msgid "PHE enabled"
+msgstr ""
+
+#. /flag:pmm
+#: modules/devices/x86/x86_data.c:153
+msgctxt "x86-flag"
+msgid "PadLock Montgomery Multiplier"
+msgstr ""
+
+#. /flag:pmm_en
+#: modules/devices/x86/x86_data.c:154
+msgctxt "x86-flag"
+msgid "PMM enabled"
+msgstr ""
+
+#. /flag:lahf_lm
+#: modules/devices/x86/x86_data.c:156
+msgctxt "x86-flag"
+msgid "Load AH from Flags (LAHF) and Store AH into Flags (SAHF) in long mode"
+msgstr ""
+
+#. /flag:cmp_legacy
+#: modules/devices/x86/x86_data.c:157
+msgctxt "x86-flag"
+msgid "If yes HyperThreading not valid"
+msgstr ""
+
+#. /flag:svm
+#: modules/devices/x86/x86_data.c:158
+msgctxt "x86-flag"
+msgid "\"Secure virtual machine\": AMD-V"
+msgstr ""
+
+#. /flag:extapic
+#: modules/devices/x86/x86_data.c:159
+msgctxt "x86-flag"
+msgid "Extended APIC space"
+msgstr ""
+
+#. /flag:cr8_legacy
+#: modules/devices/x86/x86_data.c:160
+msgctxt "x86-flag"
+msgid "CR8 in 32-bit mode"
+msgstr ""
+
+#. /flag:abm
+#: modules/devices/x86/x86_data.c:161
+msgctxt "x86-flag"
+msgid "Advanced Bit Manipulation"
+msgstr ""
+
+#. /flag:sse4a
+#: modules/devices/x86/x86_data.c:162
+msgctxt "x86-flag"
+msgid "SSE-4A"
+msgstr ""
+
+#. /flag:misalignsse
+#: modules/devices/x86/x86_data.c:163
+msgctxt "x86-flag"
+msgid ""
+"indicates if a general-protection exception (#GP) is generated when some "
+"legacy SSE instructions operate on unaligned data. Also depends on CR0 and "
+"Alignment Checking bit"
+msgstr ""
+
+#. /flag:3dnowprefetch
+#: modules/devices/x86/x86_data.c:164
+msgctxt "x86-flag"
+msgid "3DNow prefetch instructions"
+msgstr ""
+
+#. /flag:osvw
+#: modules/devices/x86/x86_data.c:165
+msgctxt "x86-flag"
+msgid ""
+"indicates OS Visible Workaround, which allows the OS to work around "
+"processor errata."
+msgstr ""
+
+#. /flag:ibs
+#: modules/devices/x86/x86_data.c:166
+msgctxt "x86-flag"
+msgid "Instruction Based Sampling"
+msgstr ""
+
+#. /flag:xop
+#: modules/devices/x86/x86_data.c:167
+msgctxt "x86-flag"
+msgid "extended AVX instructions"
+msgstr ""
+
+#. /flag:skinit
+#: modules/devices/x86/x86_data.c:168
+msgctxt "x86-flag"
+msgid "SKINIT/STGI instructions"
+msgstr ""
+
+#. /flag:wdt
+#: modules/devices/x86/x86_data.c:169
+msgctxt "x86-flag"
+msgid "Watchdog timer"
+msgstr ""
+
+#. /flag:lwp
+#: modules/devices/x86/x86_data.c:170
+msgctxt "x86-flag"
+msgid "Light Weight Profiling"
+msgstr ""
+
+#. /flag:fma4
+#: modules/devices/x86/x86_data.c:171
+msgctxt "x86-flag"
+msgid "4 operands MAC instructions"
+msgstr ""
+
+#. /flag:tce
+#: modules/devices/x86/x86_data.c:172
+msgctxt "x86-flag"
+msgid "translation cache extension"
+msgstr ""
+
+#. /flag:nodeid_msr
+#: modules/devices/x86/x86_data.c:173
+msgctxt "x86-flag"
+msgid "NodeId MSR"
+msgstr ""
+
+#. /flag:tbm
+#: modules/devices/x86/x86_data.c:174
+msgctxt "x86-flag"
+msgid "Trailing Bit Manipulation"
+msgstr ""
+
+#. /flag:topoext
+#: modules/devices/x86/x86_data.c:175
+msgctxt "x86-flag"
+msgid "Topology Extensions CPUID leafs"
+msgstr ""
+
+#. /flag:perfctr_core
+#: modules/devices/x86/x86_data.c:176
+msgctxt "x86-flag"
+msgid "Core Performance Counter Extensions"
+msgstr ""
+
+#. /flag:perfctr_nb
+#: modules/devices/x86/x86_data.c:177
+msgctxt "x86-flag"
+msgid "NB Performance Counter Extensions"
+msgstr ""
+
+#. /flag:bpext
+#: modules/devices/x86/x86_data.c:178
+msgctxt "x86-flag"
+msgid "data breakpoint extension"
+msgstr ""
+
+#. /flag:ptsc
+#: modules/devices/x86/x86_data.c:179
+msgctxt "x86-flag"
+msgid "performance time-stamp counter"
+msgstr ""
+
+#. /flag:perfctr_l2
+#: modules/devices/x86/x86_data.c:180
+msgctxt "x86-flag"
+msgid "L2 Performance Counter Extensions"
+msgstr ""
+
+#. /flag:mwaitx
+#: modules/devices/x86/x86_data.c:181
+msgctxt "x86-flag"
+msgid "MWAIT extension (MONITORX/MWAITX)"
+msgstr ""
+
+#. /flag:cpb
+#: modules/devices/x86/x86_data.c:183
+msgctxt "x86-flag"
+msgid "AMD Core Performance Boost"
+msgstr ""
+
+#. /flag:epb
+#: modules/devices/x86/x86_data.c:184
+msgctxt "x86-flag"
+msgid "IA32_ENERGY_PERF_BIAS support"
+msgstr ""
+
+#. /flag:hw_pstate
+#: modules/devices/x86/x86_data.c:185
+msgctxt "x86-flag"
+msgid "AMD HW-PState"
+msgstr ""
+
+#. /flag:proc_feedback
+#: modules/devices/x86/x86_data.c:186
+msgctxt "x86-flag"
+msgid "AMD ProcFeedbackInterface"
+msgstr ""
+
+#. /flag:intel_pt
+#: modules/devices/x86/x86_data.c:187
+msgctxt "x86-flag"
+msgid "Intel Processor Tracing"
+msgstr ""
+
+#. /flag:tpr_shadow
+#: modules/devices/x86/x86_data.c:189
+msgctxt "x86-flag"
+msgid "Intel TPR Shadow"
+msgstr ""
+
+#. /flag:vnmi
+#: modules/devices/x86/x86_data.c:190
+msgctxt "x86-flag"
+msgid "Intel Virtual NMI"
+msgstr ""
+
+#. /flag:flexpriority
+#: modules/devices/x86/x86_data.c:191
+msgctxt "x86-flag"
+msgid "Intel FlexPriority"
+msgstr ""
+
+#. /flag:ept
+#: modules/devices/x86/x86_data.c:192
+msgctxt "x86-flag"
+msgid "Intel Extended Page Table"
+msgstr ""
+
+#. /flag:vpid
+#: modules/devices/x86/x86_data.c:193
+msgctxt "x86-flag"
+msgid "Intel Virtual Processor ID"
+msgstr ""
+
+#. /flag:vmmcall
+#: modules/devices/x86/x86_data.c:194
+msgctxt "x86-flag"
+msgid "prefer VMMCALL to VMCALL"
+msgstr ""
+
+#. /flag:fsgsbase
+#: modules/devices/x86/x86_data.c:196
+msgctxt "x86-flag"
+msgid "{RD/WR}{FS/GS}BASE instructions"
+msgstr ""
+
+#. /flag:tsc_adjust
+#: modules/devices/x86/x86_data.c:197
+msgctxt "x86-flag"
+msgid "TSC adjustment MSR"
+msgstr ""
+
+#. /flag:bmi1
+#: modules/devices/x86/x86_data.c:198
+msgctxt "x86-flag"
+msgid "1st group bit manipulation extensions"
+msgstr ""
+
+#. /flag:hle
+#: modules/devices/x86/x86_data.c:199
+msgctxt "x86-flag"
+msgid "Hardware Lock Elision"
+msgstr ""
+
+#. /flag:avx2
+#: modules/devices/x86/x86_data.c:200
+msgctxt "x86-flag"
+msgid "AVX2 instructions"
+msgstr ""
+
+#. /flag:smep
+#: modules/devices/x86/x86_data.c:201
+msgctxt "x86-flag"
+msgid "Supervisor Mode Execution Protection"
+msgstr ""
+
+#. /flag:bmi2
+#: modules/devices/x86/x86_data.c:202
+msgctxt "x86-flag"
+msgid "2nd group bit manipulation extensions"
+msgstr ""
+
+#. /flag:erms
+#: modules/devices/x86/x86_data.c:203
+msgctxt "x86-flag"
+msgid "Enhanced REP MOVSB/STOSB"
+msgstr ""
+
+#. /flag:invpcid
+#: modules/devices/x86/x86_data.c:204
+msgctxt "x86-flag"
+msgid "Invalidate Processor Context ID"
+msgstr ""
+
+#. /flag:rtm
+#: modules/devices/x86/x86_data.c:205
+msgctxt "x86-flag"
+msgid "Restricted Transactional Memory"
+msgstr ""
+
+#. /flag:cqm
+#: modules/devices/x86/x86_data.c:206
+msgctxt "x86-flag"
+msgid "Cache QoS Monitoring"
+msgstr ""
+
+#. /flag:mpx
+#: modules/devices/x86/x86_data.c:207
+msgctxt "x86-flag"
+msgid "Memory Protection Extension"
+msgstr ""
+
+#. /flag:avx512f
+#: modules/devices/x86/x86_data.c:208
+msgctxt "x86-flag"
+msgid "AVX-512 foundation"
+msgstr ""
+
+#. /flag:avx512dq
+#: modules/devices/x86/x86_data.c:209
+msgctxt "x86-flag"
+msgid "AVX-512 Double/Quad instructions"
+msgstr ""
+
+#. /flag:rdseed
+#: modules/devices/x86/x86_data.c:210
+msgctxt "x86-flag"
+msgid "The RDSEED instruction"
+msgstr ""
+
+#. /flag:adx
+#: modules/devices/x86/x86_data.c:211
+msgctxt "x86-flag"
+msgid "The ADCX and ADOX instructions"
+msgstr ""
+
+#. /flag:smap
+#: modules/devices/x86/x86_data.c:212
+msgctxt "x86-flag"
+msgid "Supervisor Mode Access Prevention"
+msgstr ""
+
+#. /flag:clflushopt
+#: modules/devices/x86/x86_data.c:213
+msgctxt "x86-flag"
+msgid "CLFLUSHOPT instruction"
+msgstr ""
+
+#. /flag:clwb
+#: modules/devices/x86/x86_data.c:214
+msgctxt "x86-flag"
+msgid "CLWB instruction"
+msgstr ""
+
+#. /flag:avx512pf
+#: modules/devices/x86/x86_data.c:215
+msgctxt "x86-flag"
+msgid "AVX-512 Prefetch"
+msgstr ""
+
+#. /flag:avx512er
+#: modules/devices/x86/x86_data.c:216
+msgctxt "x86-flag"
+msgid "AVX-512 Exponential and Reciprocal"
+msgstr ""
+
+#. /flag:avx512cd
+#: modules/devices/x86/x86_data.c:217
+msgctxt "x86-flag"
+msgid "AVX-512 Conflict Detection"
+msgstr ""
+
+#. /flag:sha_ni
+#: modules/devices/x86/x86_data.c:218
+msgctxt "x86-flag"
+msgid "SHA1/SHA256 Instruction Extensions"
+msgstr ""
+
+#. /flag:avx512bw
+#: modules/devices/x86/x86_data.c:219
+msgctxt "x86-flag"
+msgid "AVX-512 Byte/Word instructions"
+msgstr ""
+
+#. /flag:avx512vl
+#: modules/devices/x86/x86_data.c:220
+msgctxt "x86-flag"
+msgid "AVX-512 128/256 Vector Length extensions"
+msgstr ""
+
+#. /flag:xsaveopt
+#: modules/devices/x86/x86_data.c:222
+msgctxt "x86-flag"
+msgid "Optimized XSAVE"
+msgstr ""
+
+#. /flag:xsavec
+#: modules/devices/x86/x86_data.c:223
+msgctxt "x86-flag"
+msgid "XSAVEC"
+msgstr ""
+
+#. /flag:xgetbv1
+#: modules/devices/x86/x86_data.c:224
+msgctxt "x86-flag"
+msgid "XGETBV with ECX = 1"
+msgstr ""
+
+#. /flag:xsaves
+#: modules/devices/x86/x86_data.c:225
+msgctxt "x86-flag"
+msgid "XSAVES/XRSTORS"
+msgstr ""
+
+#. /flag:cqm_llc
+#: modules/devices/x86/x86_data.c:227
+msgctxt "x86-flag"
+msgid "LLC QoS"
+msgstr ""
+
+#. /flag:cqm_occup_llc
+#: modules/devices/x86/x86_data.c:229
+msgctxt "x86-flag"
+msgid "LLC occupancy monitoring"
+msgstr ""
+
+#. /flag:cqm_mbm_total
+#: modules/devices/x86/x86_data.c:230
+msgctxt "x86-flag"
+msgid "LLC total MBM monitoring"
+msgstr ""
+
+#. /flag:cqm_mbm_local
+#: modules/devices/x86/x86_data.c:231
+msgctxt "x86-flag"
+msgid "LLC local MBM monitoring"
+msgstr ""
+
+#. /flag:clzero
+#: modules/devices/x86/x86_data.c:233
+msgctxt "x86-flag"
+msgid "CLZERO instruction"
+msgstr ""
+
+#. /flag:irperf
+#: modules/devices/x86/x86_data.c:234
+msgctxt "x86-flag"
+msgid "instructions retired performance counter"
+msgstr ""
+
+#. /flag:dtherm
+#: modules/devices/x86/x86_data.c:236
+msgctxt "x86-flag"
+msgid "digital thermal sensor"
+msgstr ""
+
+#. /flag:ida
+#: modules/devices/x86/x86_data.c:237
+msgctxt "x86-flag"
+msgid "Intel Dynamic Acceleration"
+msgstr ""
+
+#. /flag:arat
+#: modules/devices/x86/x86_data.c:238
+msgctxt "x86-flag"
+msgid "Always Running APIC Timer"
+msgstr ""
+
+#. /flag:pln
+#: modules/devices/x86/x86_data.c:239
+msgctxt "x86-flag"
+msgid "Intel Power Limit Notification"
+msgstr ""
+
+#. /flag:pts
+#: modules/devices/x86/x86_data.c:240
+msgctxt "x86-flag"
+msgid "Intel Package Thermal Status"
+msgstr ""
+
+#. /flag:hwp
+#: modules/devices/x86/x86_data.c:241
+msgctxt "x86-flag"
+msgid "Intel Hardware P-states"
+msgstr ""
+
+#. /flag:hwp_notify
+#: modules/devices/x86/x86_data.c:242
+msgctxt "x86-flag"
+msgid "HWP notification"
+msgstr ""
+
+#. /flag:hwp_act_window
+#: modules/devices/x86/x86_data.c:243
+msgctxt "x86-flag"
+msgid "HWP Activity Window"
+msgstr ""
+
+#. /flag:hwp_epp
+#: modules/devices/x86/x86_data.c:244
+msgctxt "x86-flag"
+msgid "HWP Energy Performance Preference"
+msgstr ""
+
+#. /flag:hwp_pkg_req
+#: modules/devices/x86/x86_data.c:245
+msgctxt "x86-flag"
+msgid "HWP package-level request"
+msgstr ""
+
+#. /flag:npt
+#: modules/devices/x86/x86_data.c:247
+msgctxt "x86-flag"
+msgid "AMD Nested Page Table support"
+msgstr ""
+
+#. /flag:lbrv
+#: modules/devices/x86/x86_data.c:248
+msgctxt "x86-flag"
+msgid "AMD LBR Virtualization support"
+msgstr ""
+
+#. /flag:svm_lock
+#: modules/devices/x86/x86_data.c:249
+msgctxt "x86-flag"
+msgid "AMD SVM locking MSR"
+msgstr ""
+
+#. /flag:nrip_save
+#: modules/devices/x86/x86_data.c:250
+msgctxt "x86-flag"
+msgid "AMD SVM next_rip save"
+msgstr ""
+
+#. /flag:tsc_scale
+#: modules/devices/x86/x86_data.c:251
+msgctxt "x86-flag"
+msgid "AMD TSC scaling support"
+msgstr ""
+
+#. /flag:vmcb_clean
+#: modules/devices/x86/x86_data.c:252
+msgctxt "x86-flag"
+msgid "AMD VMCB clean bits support"
+msgstr ""
+
+#. /flag:flushbyasid
+#: modules/devices/x86/x86_data.c:253
+msgctxt "x86-flag"
+msgid "AMD flush-by-ASID support"
+msgstr ""
+
+#. /flag:decodeassists
+#: modules/devices/x86/x86_data.c:254
+msgctxt "x86-flag"
+msgid "AMD Decode Assists support"
+msgstr ""
+
+#. /flag:pausefilter
+#: modules/devices/x86/x86_data.c:255
+msgctxt "x86-flag"
+msgid "AMD filtered pause intercept"
+msgstr ""
+
+#. /flag:pfthreshold
+#: modules/devices/x86/x86_data.c:256
+msgctxt "x86-flag"
+msgid "AMD pause filter threshold"
+msgstr ""
+
+#. /flag:avic
+#: modules/devices/x86/x86_data.c:257
+msgctxt "x86-flag"
+msgid "Virtual Interrupt Controller"
+msgstr ""
+
+#. /flag:pku
+#: modules/devices/x86/x86_data.c:259
+msgctxt "x86-flag"
+msgid "Protection Keys for Userspace"
+msgstr ""
+
+#. /flag:ospke
+#: modules/devices/x86/x86_data.c:260
+msgctxt "x86-flag"
+msgid "OS Protection Keys Enable"
+msgstr ""
+
+#. /flag:overflow_recov
+#: modules/devices/x86/x86_data.c:262
+msgctxt "x86-flag"
+msgid "MCA overflow recovery support"
+msgstr ""
+
+#. /flag:succor
+#: modules/devices/x86/x86_data.c:263
+msgctxt "x86-flag"
+msgid "uncorrectable error containment and recovery"
+msgstr ""
+
+#. /flag:smca
+#: modules/devices/x86/x86_data.c:264
+msgctxt "x86-flag"
+msgid "Scalable MCA"
+msgstr ""
+
+#. /bug:f00f
+#: modules/devices/x86/x86_data.c:267
+msgctxt "x86-flag"
+msgid "Intel F00F bug"
+msgstr ""
+
+#. /bug:fdiv
+#: modules/devices/x86/x86_data.c:268
+msgctxt "x86-flag"
+msgid "FPU FDIV"
+msgstr ""
+
+#. /bug:coma
+#: modules/devices/x86/x86_data.c:269
+msgctxt "x86-flag"
+msgid "Cyrix 6x86 coma"
+msgstr ""
+
+#. /bug:tlb_mmatch
+#: modules/devices/x86/x86_data.c:270
+msgctxt "x86-flag"
+msgid "AMD Erratum 383"
+msgstr ""
+
+#. /bug:apic_c1e
+#. /bug:amd_e400
+#: modules/devices/x86/x86_data.c:271 modules/devices/x86/x86_data.c:280
+msgctxt "x86-flag"
+msgid "AMD Erratum 400"
+msgstr ""
+
+#. /bug:11ap
+#: modules/devices/x86/x86_data.c:272
+msgctxt "x86-flag"
+msgid "Bad local APIC aka 11AP"
+msgstr ""
+
+#. /bug:fxsave_leak
+#: modules/devices/x86/x86_data.c:273
+msgctxt "x86-flag"
+msgid "FXSAVE leaks FOP/FIP/FOP"
+msgstr ""
+
+#. /bug:clflush_monitor
+#: modules/devices/x86/x86_data.c:274
+msgctxt "x86-flag"
+msgid "AAI65, CLFLUSH required before MONITOR"
+msgstr ""
+
+#. /bug:sysret_ss_attrs
+#: modules/devices/x86/x86_data.c:275
+msgctxt "x86-flag"
+msgid "SYSRET doesn't fix up SS attrs"
+msgstr ""
+
+#. /bug:espfix
+#: modules/devices/x86/x86_data.c:276
+msgctxt "x86-flag"
+msgid "IRET to 16-bit SS corrupts ESP/RSP high bits"
+msgstr ""
+
+#. /bug:null_seg
+#: modules/devices/x86/x86_data.c:277
+msgctxt "x86-flag"
+msgid "Nulling a selector preserves the base"
+msgstr ""
+
+#. /bug:swapgs_fence
+#: modules/devices/x86/x86_data.c:278
+msgctxt "x86-flag"
+msgid "SWAPGS without input dep on GS"
+msgstr ""
+
+#. /bug:monitor
+#: modules/devices/x86/x86_data.c:279
+msgctxt "x86-flag"
+msgid "IPI required to wake up remote CPU"
+msgstr ""
+
+#. /x86/kernel/cpu/powerflags.h
+#. /flag:pm:ts
+#: modules/devices/x86/x86_data.c:283
+msgctxt "x86-flag"
+msgid "temperature sensor"
+msgstr ""
+
+#. /flag:pm:fid
+#: modules/devices/x86/x86_data.c:284
+msgctxt "x86-flag"
+msgid "frequency id control"
+msgstr ""
+
+#. /flag:pm:vid
+#: modules/devices/x86/x86_data.c:285
+msgctxt "x86-flag"
+msgid "voltage id control"
+msgstr ""
+
+#. /flag:pm:ttp
+#: modules/devices/x86/x86_data.c:286
+msgctxt "x86-flag"
+msgid "thermal trip"
+msgstr ""
+
+#. /flag:pm:tm
+#: modules/devices/x86/x86_data.c:287
+msgctxt "x86-flag"
+msgid "hardware thermal control"
+msgstr ""
+
+#. /flag:pm:stc
+#: modules/devices/x86/x86_data.c:288
+msgctxt "x86-flag"
+msgid "software thermal control"
+msgstr ""
+
+#. /flag:pm:100mhzsteps
+#: modules/devices/x86/x86_data.c:289
+msgctxt "x86-flag"
+msgid "100 MHz multiplier control"
+msgstr ""
+
+#. /flag:pm:hwpstate
+#: modules/devices/x86/x86_data.c:290
+msgctxt "x86-flag"
+msgid "hardware P-state control"
+msgstr ""
+
+#. /flag:pm:cpb
+#: modules/devices/x86/x86_data.c:291
+msgctxt "x86-flag"
+msgid "core performance boost"
+msgstr ""
+
+#. /flag:pm:eff_freq_ro
+#: modules/devices/x86/x86_data.c:292
+msgctxt "x86-flag"
+msgid "Readonly aperf/mperf"
+msgstr ""
+
+#. /flag:pm:proc_feedback
+#: modules/devices/x86/x86_data.c:293
+msgctxt "x86-flag"
+msgid "processor feedback interface"
+msgstr ""
+
+#. /flag:pm:acc_power
+#: modules/devices/x86/x86_data.c:294
+msgctxt "x86-flag"
+msgid "accumulated power mechanism"
+msgstr ""
+
+#: modules/network.c:59
+msgid "Interfaces"
+msgstr "Interfaces"
+
+#: modules/network.c:60
+msgid "IP Connections"
+msgstr "Connections IP"
+
+#: modules/network.c:61
+msgid "Routing Table"
+msgstr "Table de Routage"
+
+#: modules/network.c:62 modules/network.c:303
+msgid "ARP Table"
+msgstr "Table ARP"
+
+#: modules/network.c:63
+msgid "DNS Servers"
+msgstr "Serveurs DNS"
+
+#: modules/network.c:64
+msgid "Statistics"
+msgstr "Statistiques"
+
+#: modules/network.c:65
+msgid "Shared Directories"
+msgstr "Dossiers d'interopérabilités"
+
+#: modules/network.c:304 modules/network.c:326 modules/network.c:357
+#: modules/network/net.c:477
+msgid "IP Address"
+msgstr "Addresse IP"
+
+#: modules/network.c:304 modules/network.c:357 modules/network.c:374
+msgid "Interface"
+msgstr ""
+
+#: modules/network.c:304
+msgid "MAC Address"
+msgstr ""
+
+#: modules/network.c:313
+msgid "SAMBA"
+msgstr ""
+
+#: modules/network.c:314
+msgid "NFS"
+msgstr ""
+
+#: modules/network.c:325
+msgid "Name Servers"
+msgstr ""
+
+#: modules/network.c:340
+msgid "Connections"
+msgstr ""
+
+#: modules/network.c:341
+msgid "Local Address"
+msgstr ""
+
+#: modules/network.c:341
+msgid "Protocol"
+msgstr ""
+
+#: modules/network.c:341
+msgid "Foreign Address"
+msgstr ""
+
+#: modules/network.c:341
+msgid "State"
+msgstr ""
+
+#: modules/network.c:357
+msgid "Sent"
+msgstr "Envoyé"
+
+#: modules/network.c:357
+msgid "Received"
+msgstr "Reçue"
+
+#: modules/network.c:373
+msgid "IP routing table"
+msgstr ""
+
+#: modules/network.c:374
+msgid "Destination/Gateway"
+msgstr ""
+
+#: modules/network.c:374
+msgid "Flags"
+msgstr ""
+
+#: modules/network.c:374 modules/network/net.c:478
+msgid "Mask"
+msgstr ""
+
+#: modules/network.c:402
+msgid "Network"
+msgstr "Réseau"
+
+#: modules/network.c:435
+msgid "Gathers information about this computer's network connection"
+msgstr "Collecte des informations sur les connexions réseau de cet ordinateur"
+
+#: modules/network/net.c:72
+msgctxt "wi-op-mode"
+msgid "Auto"
+msgstr ""
+
+#: modules/network/net.c:73
+msgctxt "wi-op-mode"
+msgid "Ad-Hoc"
+msgstr ""
+
+#: modules/network/net.c:74
+msgctxt "wi-op-mode"
+msgid "Managed"
+msgstr ""
+
+#: modules/network/net.c:75
+msgctxt "wi-op-mode"
+msgid "Master"
+msgstr ""
+
+#: modules/network/net.c:76
+msgctxt "wi-op-mode"
+msgid "Repeater"
+msgstr ""
+
+#: modules/network/net.c:77
+msgctxt "wi-op-mode"
+msgid "Secondary"
+msgstr ""
+
+#: modules/network/net.c:78
+msgctxt "wi-op-mode"
+msgid "(Unknown)"
+msgstr ""
+
+#: modules/network/net.c:242 modules/network/net.c:262
+#: modules/network/net.c:270
+msgctxt "net-if-type"
+msgid "Ethernet"
+msgstr ""
+
+#: modules/network/net.c:243
+msgctxt "net-if-type"
+msgid "Loopback"
+msgstr ""
+
+#: modules/network/net.c:244
+msgctxt "net-if-type"
+msgid "Point-to-Point"
+msgstr ""
+
+#: modules/network/net.c:245 modules/network/net.c:246
+#: modules/network/net.c:247 modules/network/net.c:248
+#: modules/network/net.c:272
+msgctxt "net-if-type"
+msgid "Wireless"
+msgstr ""
+
+#: modules/network/net.c:249
+msgctxt "net-if-type"
+msgid "Virtual Point-to-Point (TUN)"
+msgstr ""
+
+#: modules/network/net.c:250
+msgctxt "net-if-type"
+msgid "Ethernet (TAP)"
+msgstr ""
+
+#: modules/network/net.c:251
+msgctxt "net-if-type"
+msgid "Parallel Line Internet Protocol"
+msgstr ""
+
+#: modules/network/net.c:252
+msgctxt "net-if-type"
+msgid "Infrared"
+msgstr ""
+
+#: modules/network/net.c:253 modules/network/net.c:271
+msgctxt "net-if-type"
+msgid "Serial Line Internet Protocol"
+msgstr ""
+
+#: modules/network/net.c:254
+msgctxt "net-if-type"
+msgid "Integrated Services Digital Network"
+msgstr ""
+
+#: modules/network/net.c:255
+msgctxt "net-if-type"
+msgid "IPv6-over-IPv4 Tunnel"
+msgstr ""
+
+#: modules/network/net.c:256
+msgctxt "net-if-type"
+msgid "VMWare Virtual Network Interface (NAT)"
+msgstr ""
+
+#: modules/network/net.c:257
+msgctxt "net-if-type"
+msgid "VMWare Virtual Network Interface"
+msgstr ""
+
+#: modules/network/net.c:258
+msgctxt "net-if-type"
+msgid "Personal Area Network (PAN)"
+msgstr ""
+
+#: modules/network/net.c:259
+msgctxt "net-if-type"
+msgid "Bluetooth"
+msgstr ""
+
+#: modules/network/net.c:260
+msgctxt "net-if-type"
+msgid "Bridge Interface"
+msgstr ""
+
+#: modules/network/net.c:261
+msgctxt "net-if-type"
+msgid "Hamachi Virtual Personal Network"
+msgstr ""
+
+#: modules/network/net.c:263
+msgctxt "net-if-type"
+msgid "Intermediate Functional Block"
+msgstr ""
+
+#: modules/network/net.c:264
+msgctxt "net-if-type"
+msgid "GRE Network Tunnel"
+msgstr ""
+
+#: modules/network/net.c:265
+msgctxt "net-if-type"
+msgid "Mesh Network"
+msgstr ""
+
+#: modules/network/net.c:266
+msgctxt "net-if-type"
+msgid "Wireless Master Interface"
+msgstr ""
+
+#: modules/network/net.c:267
+msgctxt "net-if-type"
+msgid "VirtualBox Virtual Network Interface"
+msgstr ""
+
+#: modules/network/net.c:273
+msgctxt "net-if-type"
+msgid "Wireless (WAN)"
+msgstr ""
+
+#: modules/network/net.c:275
+msgctxt "net-if-type"
+msgid "(Unknown)"
+msgstr ""
+
+#: modules/network/net.c:348 modules/network/net.c:358
+msgid "Network Interfaces"
+msgstr ""
+
+#: modules/network/net.c:348
+msgid "None Found"
+msgstr ""
+
+#: modules/network/net.c:400 modules/network/net.c:422
+#: modules/network/net.c:423
+msgid "MiB"
+msgstr ""
+
+#: modules/network/net.c:414
+msgid "Network Adapter Properties"
+msgstr ""
+
+#: modules/network/net.c:415
+msgid "Interface Type"
+msgstr ""
+
+#: modules/network/net.c:416
+msgid "Hardware Address (MAC)"
+msgstr ""
+
+#: modules/network/net.c:420
+msgid "MTU"
+msgstr ""
+
+#: modules/network/net.c:421
+msgid "Transfer Details"
+msgstr ""
+
+#: modules/network/net.c:422
+msgid "Bytes Received"
+msgstr ""
+
+#: modules/network/net.c:423
+msgid "Bytes Sent"
+msgstr ""
+
+#: modules/network/net.c:440 modules/network/net.c:462
+#: modules/network/net.c:463
+msgid "dBm"
+msgstr ""
+
+#: modules/network/net.c:440
+msgid "mW"
+msgstr ""
+
+#: modules/network/net.c:454
+msgid "Wireless Properties"
+msgstr ""
+
+#: modules/network/net.c:455
+msgid "Network Name (SSID)"
+msgstr ""
+
+#: modules/network/net.c:456
+msgid "Bit Rate"
+msgstr ""
+
+#: modules/network/net.c:456
+msgid "Mb/s"
+msgstr ""
+
+#: modules/network/net.c:457
+msgid "Transmission Power"
+msgstr ""
+
+#: modules/network/net.c:459
+msgid "Status"
+msgstr ""
+
+#: modules/network/net.c:460
+msgid "Link Quality"
+msgstr ""
+
+#: modules/network/net.c:461
+msgid "Signal / Noise"
+msgstr ""
+
+#: modules/network/net.c:476
+msgid "Internet Protocol (IPv4)"
+msgstr ""
+
+#: modules/network/net.c:477 modules/network/net.c:478
+#: modules/network/net.c:480
+msgid "(Not set)"
+msgstr ""
+
+#: modules/network/net.c:479
+msgid "Broadcast Address"
+msgstr ""
+
+#~ msgid "Desktop Environment"
+#~ msgstr "Environnement de bureau"
diff --git a/po/hardinfo.pot b/po/hardinfo.pot
new file mode 100644
index 0000000..a2d37c6
--- /dev/null
+++ b/po/hardinfo.pot
@@ -0,0 +1,4334 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2017-08-14 22:23-0500\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#. / %d will be latest year of copyright
+#: hardinfo/hardinfo.c:49
+#, c-format
+msgid ""
+"Copyright (C) 2003-%d Leandro A. F. Pereira. See COPYING for details.\n"
+"\n"
+msgstr ""
+
+#: hardinfo/hardinfo.c:51
+#, c-format
+msgid ""
+"Compile-time options:\n"
+"  Release version:   %s (%s)\n"
+"  BinReloc enabled:  %s\n"
+"  Data prefix:       %s\n"
+"  Library prefix:    %s\n"
+"  Compiled for:      %s\n"
+msgstr ""
+
+#: hardinfo/hardinfo.c:57 hardinfo/hardinfo.c:58 modules/computer.c:605
+#: modules/devices/inputdevices.c:128 modules/devices/pci.c:112
+#: modules/devices/printers.c:138
+msgid "Yes"
+msgstr ""
+
+#: hardinfo/hardinfo.c:58 modules/computer.c:605 modules/devices/pci.c:112
+#: modules/devices/printers.c:138
+msgid "No"
+msgstr ""
+
+#: hardinfo/hardinfo.c:69
+#, c-format
+msgid ""
+"Failed to find runtime data.\n"
+"\n"
+"• Is HardInfo correctly installed?\n"
+"• See if %s and %s exists and you have read permission."
+msgstr ""
+
+#: hardinfo/hardinfo.c:76
+#, c-format
+msgid ""
+"Modules:\n"
+"%-20s %-15s %-12s\n"
+msgstr ""
+
+#: hardinfo/hardinfo.c:77
+msgid "File Name"
+msgstr ""
+
+#: hardinfo/hardinfo.c:77 modules/computer.c:534 modules/computer.c:562
+#: modules/computer.c:630 modules/computer/languages.c:104
+#: modules/computer/modules.c:146 modules/devices/arm/processor.c:336
+#: modules/devices/ia64/processor.c:160 modules/devices/inputdevices.c:116
+#: modules/devices/pci.c:215 modules/devices/sh/processor.c:84
+#: modules/devices/x86/processor.c:455 modules/network.c:326
+msgid "Name"
+msgstr ""
+
+#: hardinfo/hardinfo.c:77 modules/computer.c:296 modules/computer.c:505
+#: modules/computer.c:507 modules/computer.c:595 modules/computer.c:603
+#: modules/devices/inputdevices.c:121
+msgid "Version"
+msgstr ""
+
+#: hardinfo/hardinfo.c:124
+#, c-format
+msgid "Unknown benchmark ``%s'' or libbenchmark.so not loaded"
+msgstr ""
+
+#: hardinfo/hardinfo.c:152
+msgid "Don't know what to do. Exiting."
+msgstr ""
+
+#: hardinfo/util.c:104 modules/computer/uptime.c:53
+#, c-format
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
+#: hardinfo/util.c:105 modules/computer/uptime.c:54
+#, c-format
+msgid "%d hour"
+msgid_plural "%d hours"
+msgstr[0] ""
+msgstr[1] ""
+
+#: hardinfo/util.c:106 modules/computer/uptime.c:55
+#, c-format
+msgid "%d minute"
+msgid_plural "%d minutes"
+msgstr[0] ""
+msgstr[1] ""
+
+#: hardinfo/util.c:107
+#, c-format
+msgid "%d second"
+msgid_plural "%d seconds"
+msgstr[0] ""
+msgstr[1] ""
+
+#: hardinfo/util.c:128
+#, c-format
+msgid "%.1f B"
+msgstr ""
+
+#: hardinfo/util.c:130
+#, c-format
+msgid "%.1f KiB"
+msgstr ""
+
+#: hardinfo/util.c:132
+#, c-format
+msgid "%.1f MiB"
+msgstr ""
+
+#: hardinfo/util.c:134
+#, c-format
+msgid "%.1f GiB"
+msgstr ""
+
+#: hardinfo/util.c:136
+#, c-format
+msgid "%.1f TiB"
+msgstr ""
+
+#: hardinfo/util.c:138
+#, c-format
+msgid "%.1f PiB"
+msgstr ""
+
+#: hardinfo/util.c:361
+msgid "Error"
+msgstr ""
+
+#: hardinfo/util.c:361 hardinfo/util.c:377
+msgid "Warning"
+msgstr ""
+
+#: hardinfo/util.c:376
+msgid "Fatal Error"
+msgstr ""
+
+#: hardinfo/util.c:401
+msgid "creates a report and prints to standard output"
+msgstr ""
+
+#: hardinfo/util.c:407
+msgid "chooses a report format (text, html)"
+msgstr ""
+
+#: hardinfo/util.c:413
+msgid "run benchmark; requires benchmark.so to be loaded"
+msgstr ""
+
+#: hardinfo/util.c:419
+msgid "lists modules"
+msgstr ""
+
+#: hardinfo/util.c:425
+msgid "specify module to load"
+msgstr ""
+
+#: hardinfo/util.c:431
+msgid "automatically load module dependencies"
+msgstr ""
+
+#: hardinfo/util.c:438
+msgid "run in XML-RPC server mode"
+msgstr ""
+
+#: hardinfo/util.c:445
+msgid "shows program version and quit"
+msgstr ""
+
+#: hardinfo/util.c:450
+msgid "- System Profiler and Benchmark tool"
+msgstr ""
+
+#: hardinfo/util.c:460
+#, c-format
+msgid ""
+"Unrecognized arguments.\n"
+"Try ``%s --help'' for more information.\n"
+msgstr ""
+
+#: hardinfo/util.c:526
+#, c-format
+msgid "Couldn't find a Web browser to open URL %s."
+msgstr ""
+
+#: hardinfo/util.c:875
+#, c-format
+msgid "Module \"%s\" depends on module \"%s\", load it?"
+msgstr ""
+
+#: hardinfo/util.c:898
+#, c-format
+msgid "Module \"%s\" depends on module \"%s\"."
+msgstr ""
+
+#: hardinfo/util.c:943
+#, c-format
+msgid "No module could be loaded. Check permissions on \"%s\" and try again."
+msgstr ""
+
+#: hardinfo/util.c:947
+msgid ""
+"No module could be loaded. Please use hardinfo -l to list all available "
+"modules and try again with a valid module list."
+msgstr ""
+
+#: hardinfo/util.c:1024
+#, c-format
+msgid "Scanning: %s..."
+msgstr ""
+
+#: hardinfo/util.c:1034 shell/shell.c:301 shell/shell.c:760 shell/shell.c:1795
+#: modules/benchmark.c:449 modules/benchmark.c:457
+msgid "Done."
+msgstr ""
+
+#: shell/callbacks.c:117
+#, c-format
+msgid "%s Module"
+msgstr ""
+
+#: shell/callbacks.c:128
+#, c-format
+msgid ""
+"Written by %s\n"
+"Licensed under %s"
+msgstr ""
+
+#: shell/callbacks.c:142
+#, c-format
+msgid "No about information is associated with the %s module."
+msgstr ""
+
+#: shell/callbacks.c:158
+msgid "Author:"
+msgstr ""
+
+#: shell/callbacks.c:161
+msgid "Contributors:"
+msgstr ""
+
+#: shell/callbacks.c:166
+msgid "Based on work by:"
+msgstr ""
+
+#: shell/callbacks.c:167
+msgid "MD5 implementation by Colin Plumb (see md5.c for details)"
+msgstr ""
+
+#: shell/callbacks.c:168
+msgid "SHA1 implementation by Steve Reid (see sha1.c for details)"
+msgstr ""
+
+#: shell/callbacks.c:169
+msgid "Blowfish implementation by Paul Kocher (see blowfich.c for details)"
+msgstr ""
+
+#: shell/callbacks.c:170
+msgid "Raytracing benchmark by John Walker (see fbench.c for details)"
+msgstr ""
+
+#: shell/callbacks.c:171
+msgid "FFT benchmark by Scott Robert Ladd (see fftbench.c for details)"
+msgstr ""
+
+#: shell/callbacks.c:172
+msgid "Some code partly based on x86cpucaps by Osamu Kayasono"
+msgstr ""
+
+#: shell/callbacks.c:173
+msgid "Vendor list based on GtkSysInfo by Pissens Sebastien"
+msgstr ""
+
+#: shell/callbacks.c:174
+msgid "DMI support based on code by Stewart Adam"
+msgstr ""
+
+#: shell/callbacks.c:175
+msgid "SCSI support based on code by Pascal F. Martin"
+msgstr ""
+
+#: shell/callbacks.c:180
+msgid "Tango Project"
+msgstr ""
+
+#: shell/callbacks.c:181
+msgid "The GNOME Project"
+msgstr ""
+
+#: shell/callbacks.c:182
+msgid "VMWare, Inc. (USB icon from VMWare Workstation 6)"
+msgstr ""
+
+#: shell/callbacks.c:200
+msgid "System information and benchmark tool"
+msgstr ""
+
+#: shell/callbacks.c:205
+msgid ""
+"HardInfo is free software; you can redistribute it and/or modify it under "
+"the terms of the GNU General Public License as published by the Free "
+"Software Foundation, version 2.\n"
+"\n"
+"This program is distributed in the hope that it will be useful, but WITHOUT "
+"ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
+"FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for "
+"more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License along with "
+"this program; if not, write to the Free Software Foundation, Inc., 51 "
+"Franklin St, Fifth Floor, Boston, MA  02110-1301 USA"
+msgstr ""
+
+#: shell/callbacks.c:220
+msgid "translator-credits"
+msgstr ""
+
+#: shell/menu.c:35
+msgid "_Information"
+msgstr ""
+
+#: shell/menu.c:36
+msgid "_Remote"
+msgstr ""
+
+#: shell/menu.c:37
+msgid "_View"
+msgstr ""
+
+#: shell/menu.c:38
+msgid "_Help"
+msgstr ""
+
+#: shell/menu.c:39
+msgid "About _Modules"
+msgstr ""
+
+#: shell/menu.c:43
+msgid "Generate _Report"
+msgstr ""
+
+#: shell/menu.c:48
+msgid "_Network Updater..."
+msgstr ""
+
+#: shell/menu.c:53
+msgid "_Open..."
+msgstr ""
+
+#: shell/menu.c:58
+msgid "_Copy to Clipboard"
+msgstr ""
+
+#: shell/menu.c:59
+msgid "Copy to clipboard"
+msgstr ""
+
+#: shell/menu.c:63
+msgid "_Refresh"
+msgstr ""
+
+#: shell/menu.c:68
+msgid "_Open HardInfo Web Site"
+msgstr ""
+
+#: shell/menu.c:73
+msgid "_Report bug"
+msgstr ""
+
+#: shell/menu.c:78
+msgid "_About HardInfo"
+msgstr ""
+
+#: shell/menu.c:79
+msgid "Displays program version information"
+msgstr ""
+
+#: shell/menu.c:83
+msgid "_Quit"
+msgstr ""
+
+#: shell/menu.c:90
+msgid "_Side Pane"
+msgstr ""
+
+#: shell/menu.c:91
+msgid "Toggles side pane visibility"
+msgstr ""
+
+#: shell/menu.c:94
+msgid "_Toolbar"
+msgstr ""
+
+#: shell/report.c:494 shell/report.c:502
+msgid "Save File"
+msgstr ""
+
+#: shell/report.c:629
+msgid "Cannot create ReportContext. Programming bug?"
+msgstr ""
+
+#: shell/report.c:648
+msgid "Open the report with your web browser?"
+msgstr ""
+
+#: shell/report.c:682
+msgid "Generating report..."
+msgstr ""
+
+#: shell/report.c:692
+msgid "Report saved."
+msgstr ""
+
+#: shell/report.c:694
+msgid "Error while creating the report."
+msgstr ""
+
+#: shell/report.c:796
+msgid "Generate Report"
+msgstr ""
+
+#: shell/report.c:821
+msgid ""
+"<big><b>Generate Report</b></big>\n"
+"Please choose the information that you wish to view in your report:"
+msgstr ""
+
+#: shell/report.c:893
+msgid "Select _None"
+msgstr ""
+
+#: shell/report.c:904
+msgid "Select _All"
+msgstr ""
+
+#: shell/report.c:929 shell/syncmanager.c:748
+msgid "_Cancel"
+msgstr ""
+
+#: shell/report.c:939
+msgid "_Generate"
+msgstr ""
+
+#: shell/shell.c:402
+#, c-format
+msgid "%s - System Information"
+msgstr ""
+
+#: shell/shell.c:407
+msgid "System Information"
+msgstr ""
+
+#: shell/shell.c:747
+msgid "Loading modules..."
+msgstr ""
+
+#: shell/shell.c:1660
+#, c-format
+msgid "<b>%s → Summary</b>"
+msgstr ""
+
+#: shell/shell.c:1769
+msgid "Updating..."
+msgstr ""
+
+#: shell/syncmanager.c:69
+msgid ""
+"<big><b>Synchronize with Central Database</b></big>\n"
+"The following information may be synchronized with the HardInfo central "
+"database."
+msgstr ""
+
+#: shell/syncmanager.c:72
+msgid ""
+"<big><b>Synchronizing</b></big>\n"
+"This may take some time."
+msgstr ""
+
+#: shell/syncmanager.c:132
+msgid ""
+"HardInfo was compiled without libsoup support. (Network Updater requires it.)"
+msgstr ""
+
+#: shell/syncmanager.c:161 shell/syncmanager.c:189
+#, c-format
+msgid "%s (error #%d)"
+msgstr ""
+
+#: shell/syncmanager.c:170 shell/syncmanager.c:198
+msgid "Could not parse XML-RPC response"
+msgstr ""
+
+#: shell/syncmanager.c:280
+#, c-format
+msgid ""
+"Server says it supports API version %d, but this version of HardInfo only "
+"supports API version %d."
+msgstr ""
+
+#: shell/syncmanager.c:375
+msgid "Contacting HardInfo Central Database"
+msgstr ""
+
+#: shell/syncmanager.c:376
+msgid "Cleaning up"
+msgstr ""
+
+#: shell/syncmanager.c:493
+msgid "(canceled)"
+msgstr ""
+
+#: shell/syncmanager.c:510
+msgid "(failed)"
+msgstr ""
+
+#: shell/syncmanager.c:521
+#, c-format
+msgid ""
+"Failed while performing \"%s\". Please file a bug report if this problem "
+"persists. (Use the Help→Report bug option.)\n"
+"\n"
+"Details: %s"
+msgstr ""
+
+#: shell/syncmanager.c:530
+#, c-format
+msgid ""
+"Failed while performing \"%s\". Please file a bug report if this problem "
+"persists. (Use the Help→Report bug option.)"
+msgstr ""
+
+#: shell/syncmanager.c:658
+msgid "Network Updater"
+msgstr ""
+
+#: shell/syncmanager.c:757
+msgid "_Synchronize"
+msgstr ""
+
+#: modules/benchmark.c:52
+msgid "CPU Blowfish"
+msgstr ""
+
+#: modules/benchmark.c:53
+msgid "CPU CryptoHash"
+msgstr ""
+
+#: modules/benchmark.c:54
+msgid "CPU Fibonacci"
+msgstr ""
+
+#: modules/benchmark.c:55
+msgid "CPU N-Queens"
+msgstr ""
+
+#: modules/benchmark.c:56
+msgid "CPU Zlib"
+msgstr ""
+
+#: modules/benchmark.c:57
+msgid "FPU FFT"
+msgstr ""
+
+#: modules/benchmark.c:58
+msgid "FPU Raytracing"
+msgstr ""
+
+#: modules/benchmark.c:60
+msgid "GPU Drawing"
+msgstr ""
+
+#: modules/benchmark.c:239 modules/benchmark.c:255
+msgid "CPU Config"
+msgstr ""
+
+#: modules/benchmark.c:239 modules/benchmark.c:255
+msgid "Results"
+msgstr ""
+
+#: modules/benchmark.c:239 modules/benchmark.c:255 modules/computer.c:751
+#: modules/devices/sparc/processor.c:75
+msgid "CPU"
+msgstr ""
+
+#: modules/benchmark.c:381
+#, c-format
+msgid "Benchmarking: <b>%s</b>."
+msgstr ""
+
+#: modules/benchmark.c:395
+msgid "Benchmarking. Please do not move your mouse or press any keys."
+msgstr ""
+
+#: modules/benchmark.c:399
+msgid "Cancel"
+msgstr ""
+
+#: modules/benchmark.c:536
+msgid "Results in MiB/second. Higher is better."
+msgstr ""
+
+#: modules/benchmark.c:540
+msgid "Results in HIMarks. Higher is better."
+msgstr ""
+
+#: modules/benchmark.c:547
+msgid "Results in seconds. Lower is better."
+msgstr ""
+
+#: modules/benchmark.c:555
+msgid "Benchmarks"
+msgstr ""
+
+#: modules/benchmark.c:573
+msgid "Perform tasks and compare with other systems"
+msgstr ""
+
+#: modules/benchmark.c:663
+msgid "Send benchmark results"
+msgstr ""
+
+#: modules/benchmark.c:668
+msgid "Receive benchmark results"
+msgstr ""
+
+#: modules/computer/alsa.c:26 modules/computer.c:489
+msgid "Audio Devices"
+msgstr ""
+
+#: modules/computer/alsa.c:34
+msgid "Audio Adapter"
+msgstr ""
+
+#: modules/computer/boots.c:33 modules/computer.c:73 modules/computer.c:546
+msgid "Boots"
+msgstr ""
+
+#: modules/computer.c:70
+msgid "Summary"
+msgstr ""
+
+#: modules/computer.c:71 modules/computer.c:476 modules/computer.c:750
+msgid "Operating System"
+msgstr ""
+
+#: modules/computer.c:72
+msgid "Kernel Modules"
+msgstr ""
+
+#: modules/computer.c:74
+msgid "Languages"
+msgstr ""
+
+#: modules/computer.c:75
+msgid "Filesystems"
+msgstr ""
+
+#: modules/computer.c:76 modules/computer.c:481 modules/computer.c:590
+msgid "Display"
+msgstr ""
+
+#: modules/computer.c:77 modules/computer/environment.c:32
+msgid "Environment Variables"
+msgstr ""
+
+#: modules/computer.c:79
+msgid "Development"
+msgstr ""
+
+#: modules/computer.c:81 modules/computer.c:617
+msgid "Users"
+msgstr ""
+
+#: modules/computer.c:82
+msgid "Groups"
+msgstr ""
+
+#: modules/computer.c:104 modules/computer.c:473 modules/devices.c:96
+#: modules/devices/pci.c:149
+msgid "Memory"
+msgstr ""
+
+#: modules/computer.c:106
+#, c-format
+msgid "%dMB (%dMB used)"
+msgstr ""
+
+#: modules/computer.c:108 modules/computer.c:520
+msgid "Uptime"
+msgstr ""
+
+#: modules/computer.c:110 modules/computer.c:478
+msgid "Date/Time"
+msgstr ""
+
+#: modules/computer.c:115 modules/computer.c:521
+msgid "Load Average"
+msgstr ""
+
+#: modules/computer.c:117 modules/computer.c:522
+msgid "Available entropy in /dev/random"
+msgstr ""
+
+#: modules/computer.c:203
+msgid "Scripting Languages"
+msgstr ""
+
+#: modules/computer.c:204
+msgid "Gambas3 (gbr3)"
+msgstr ""
+
+#: modules/computer.c:205
+msgid "Python"
+msgstr ""
+
+#: modules/computer.c:206
+msgid "Python2"
+msgstr ""
+
+#: modules/computer.c:207
+msgid "Python3"
+msgstr ""
+
+#: modules/computer.c:208
+msgid "Perl"
+msgstr ""
+
+#: modules/computer.c:209
+msgid "Perl6 (VM)"
+msgstr ""
+
+#: modules/computer.c:210
+msgid "Perl6"
+msgstr ""
+
+#: modules/computer.c:211
+msgid "PHP"
+msgstr ""
+
+#: modules/computer.c:212
+msgid "Ruby"
+msgstr ""
+
+#: modules/computer.c:213
+msgid "Bash"
+msgstr ""
+
+#: modules/computer.c:214
+msgid "Compilers"
+msgstr ""
+
+#: modules/computer.c:215
+msgid "C (GCC)"
+msgstr ""
+
+#: modules/computer.c:216
+msgid "C (Clang)"
+msgstr ""
+
+#: modules/computer.c:217
+msgid "D (dmd)"
+msgstr ""
+
+#: modules/computer.c:218
+msgid "Gambas3 (gbc3)"
+msgstr ""
+
+#: modules/computer.c:219
+msgid "Java"
+msgstr ""
+
+#: modules/computer.c:220
+msgid "CSharp (Mono, old)"
+msgstr ""
+
+#: modules/computer.c:221
+msgid "CSharp (Mono)"
+msgstr ""
+
+#: modules/computer.c:222
+msgid "Vala"
+msgstr ""
+
+#: modules/computer.c:223
+msgid "Haskell (GHC)"
+msgstr ""
+
+#: modules/computer.c:224
+msgid "FreePascal"
+msgstr ""
+
+#: modules/computer.c:225
+msgid "Go"
+msgstr ""
+
+#: modules/computer.c:226
+msgid "Tools"
+msgstr ""
+
+#: modules/computer.c:227
+msgid "make"
+msgstr ""
+
+#: modules/computer.c:228
+msgid "GDB"
+msgstr ""
+
+#: modules/computer.c:229
+msgid "strace"
+msgstr ""
+
+#: modules/computer.c:230
+msgid "valgrind"
+msgstr ""
+
+#: modules/computer.c:231
+msgid "QMake"
+msgstr ""
+
+#: modules/computer.c:232
+msgid "CMake"
+msgstr ""
+
+#: modules/computer.c:233
+msgid "Gambas3 IDE"
+msgstr ""
+
+#: modules/computer.c:274
+msgid "Not found"
+msgstr ""
+
+#: modules/computer.c:279
+#, c-format
+msgid "Detecting version: %s"
+msgstr ""
+
+#: modules/computer.c:296
+msgid "Program"
+msgstr ""
+
+#: modules/computer.c:308
+msgid "Invalid chassis type (0)"
+msgstr ""
+
+#: modules/computer.c:309 modules/computer.c:310
+msgid "Unknown chassis type"
+msgstr ""
+
+#: modules/computer.c:311
+msgid "Desktop"
+msgstr ""
+
+#: modules/computer.c:312
+msgid "Low-profile Desktop"
+msgstr ""
+
+#: modules/computer.c:313
+msgid "Pizza Box"
+msgstr ""
+
+#: modules/computer.c:314
+msgid "Mini Tower"
+msgstr ""
+
+#: modules/computer.c:315
+msgid "Tower"
+msgstr ""
+
+#: modules/computer.c:316
+msgid "Portable"
+msgstr ""
+
+#: modules/computer.c:317 modules/computer.c:341 modules/computer.c:350
+#: modules/computer.c:372
+msgid "Laptop"
+msgstr ""
+
+#: modules/computer.c:318
+msgid "Notebook"
+msgstr ""
+
+#: modules/computer.c:319
+msgid "Handheld"
+msgstr ""
+
+#: modules/computer.c:320
+msgid "Docking Station"
+msgstr ""
+
+#: modules/computer.c:321
+msgid "All-in-one"
+msgstr ""
+
+#: modules/computer.c:322
+msgid "Subnotebook"
+msgstr ""
+
+#: modules/computer.c:323
+msgid "Space-saving"
+msgstr ""
+
+#: modules/computer.c:324
+msgid "Lunch Box"
+msgstr ""
+
+#: modules/computer.c:325
+msgid "Main Server Chassis"
+msgstr ""
+
+#: modules/computer.c:326
+msgid "Expansion Chassis"
+msgstr ""
+
+#: modules/computer.c:327
+msgid "Sub Chassis"
+msgstr ""
+
+#: modules/computer.c:328
+msgid "Bus Expansion Chassis"
+msgstr ""
+
+#: modules/computer.c:329
+msgid "Peripheral Chassis"
+msgstr ""
+
+#: modules/computer.c:330
+msgid "RAID Chassis"
+msgstr ""
+
+#: modules/computer.c:331
+msgid "Rack Mount Chassis"
+msgstr ""
+
+#: modules/computer.c:332
+msgid "Sealed-case PC"
+msgstr ""
+
+#. /proc/apm
+#. FIXME: use dmidecode if available to get chassis type
+#: modules/computer.c:386
+msgid "Unknown physical machine type"
+msgstr ""
+
+#: modules/computer.c:470 modules/computer.c:709
+msgid "Computer"
+msgstr ""
+
+#: modules/computer.c:471 modules/devices/alpha/processor.c:87
+#: modules/devices/arm/processor.c:236 modules/devices.c:95
+#: modules/devices/ia64/processor.c:159 modules/devices/m68k/processor.c:83
+#: modules/devices/mips/processor.c:74 modules/devices/parisc/processor.c:154
+#: modules/devices/ppc/processor.c:157 modules/devices/riscv/processor.c:181
+#: modules/devices/s390/processor.c:131 modules/devices/sh/processor.c:83
+#: modules/devices/sparc/processor.c:74 modules/devices/x86/processor.c:409
+msgid "Processor"
+msgstr ""
+
+#: modules/computer.c:474
+msgid "Machine Type"
+msgstr ""
+
+#: modules/computer.c:477 modules/computer.c:514
+msgid "User Name"
+msgstr ""
+
+#: modules/computer.c:482 modules/computer.c:591
+msgid "Resolution"
+msgstr ""
+
+#: modules/computer.c:483 modules/computer.c:592
+#, c-format
+msgid "%dx%d pixels"
+msgstr ""
+
+#: modules/computer.c:485
+msgid "OpenGL Renderer"
+msgstr ""
+
+#: modules/computer.c:486
+msgid "X11 Vendor"
+msgstr ""
+
+#: modules/computer.c:491 modules/devices.c:102
+msgid "Input Devices"
+msgstr ""
+
+#: modules/computer.c:493 modules/computer.c:752 modules/devices.c:99
+msgid "Printers"
+msgstr ""
+
+#: modules/computer.c:495 modules/computer.c:752 modules/devices.c:103
+msgid "Storage"
+msgstr ""
+
+#: modules/computer.c:506
+msgid "Kernel"
+msgstr ""
+
+#: modules/computer.c:508
+msgid "C Library"
+msgstr ""
+
+#: modules/computer.c:509
+msgid "Distribution"
+msgstr ""
+
+#: modules/computer.c:512
+msgid "Current Session"
+msgstr ""
+
+#: modules/computer.c:513
+msgid "Computer Name"
+msgstr ""
+
+#: modules/computer.c:515 modules/computer/languages.c:108
+msgid "Language"
+msgstr ""
+
+#: modules/computer.c:516 modules/computer/users.c:50
+msgid "Home Directory"
+msgstr ""
+
+#: modules/computer.c:519 modules/devices/usb.c:87 modules/devices/usb.c:234
+#: modules/devices/usb.c:351
+msgid "Misc"
+msgstr ""
+
+#: modules/computer.c:532
+msgid "Loaded Modules"
+msgstr ""
+
+#: modules/computer.c:535 modules/computer/modules.c:145
+#: modules/computer/modules.c:147 modules/devices/arm/processor.c:337
+#: modules/devices.c:559 modules/devices/x86/processor.c:456
+msgid "Description"
+msgstr ""
+
+#: modules/computer.c:548
+msgid "Date & Time"
+msgstr ""
+
+#: modules/computer.c:549
+msgid "Kernel Version"
+msgstr ""
+
+#: modules/computer.c:559
+msgid "Available Languages"
+msgstr ""
+
+#: modules/computer.c:561
+msgid "Language Code"
+msgstr ""
+
+#: modules/computer.c:573
+msgid "Mounted File Systems"
+msgstr ""
+
+#: modules/computer.c:575 modules/computer/filesystem.c:85
+msgid "Mount Point"
+msgstr ""
+
+#: modules/computer.c:576
+msgid "Usage"
+msgstr ""
+
+#: modules/computer.c:577
+msgid "Device"
+msgstr ""
+
+#: modules/computer.c:594 modules/computer.c:601
+#: modules/devices/ia64/processor.c:161 modules/devices/inputdevices.c:119
+#: modules/devices/pci.c:225 modules/devices/usb.c:349
+#: modules/devices/x86/processor.c:416
+msgid "Vendor"
+msgstr ""
+
+#: modules/computer.c:598
+msgid "Monitors"
+msgstr ""
+
+#: modules/computer.c:600
+msgid "OpenGL"
+msgstr ""
+
+#: modules/computer.c:602
+msgid "Renderer"
+msgstr ""
+
+#: modules/computer.c:604
+msgid "Direct Rendering"
+msgstr ""
+
+#: modules/computer.c:608
+msgid "Extensions"
+msgstr ""
+
+#: modules/computer.c:628
+msgid "Group"
+msgstr ""
+
+#: modules/computer.c:631 modules/computer/users.c:49
+msgid "Group ID"
+msgstr ""
+
+#: modules/computer.c:751
+msgid "RAM"
+msgstr ""
+
+#: modules/computer.c:751 modules/devices/devicetree/pmac_data.c:82
+msgid "Motherboard"
+msgstr ""
+
+#: modules/computer.c:751
+msgid "Graphics"
+msgstr ""
+
+#: modules/computer.c:752
+msgid "Audio"
+msgstr ""
+
+#: modules/computer.c:807
+msgid "Gathers high-level computer information"
+msgstr ""
+
+#: modules/computer/display.c:122
+#, c-format
+msgid "Monitor %d=%dx%d pixels\n"
+msgstr ""
+
+#: modules/computer/filesystem.c:83
+msgid "Filesystem"
+msgstr ""
+
+#: modules/computer/filesystem.c:84
+msgid "Mounted As"
+msgstr ""
+
+#: modules/computer/filesystem.c:84
+msgid "Read-Write"
+msgstr ""
+
+#: modules/computer/filesystem.c:84
+msgid "Read-Only"
+msgstr ""
+
+#: modules/computer/filesystem.c:86 modules/devices/spd-decode.c:1510
+msgid "Size"
+msgstr ""
+
+#: modules/computer/filesystem.c:87
+msgid "Used"
+msgstr ""
+
+#: modules/computer/filesystem.c:88
+msgid "Available"
+msgstr ""
+
+#: modules/computer/languages.c:103
+msgid "Locale Information"
+msgstr ""
+
+#: modules/computer/languages.c:105
+msgid "Source"
+msgstr ""
+
+#: modules/computer/languages.c:106
+msgid "Address"
+msgstr ""
+
+#: modules/computer/languages.c:107
+msgid "E-mail"
+msgstr ""
+
+#: modules/computer/languages.c:109
+msgid "Territory"
+msgstr ""
+
+#: modules/computer/languages.c:110 modules/devices/arm/processor.c:250
+#: modules/devices/ia64/processor.c:166 modules/devices/ppc/processor.c:159
+#: modules/devices/usb.c:236
+msgid "Revision"
+msgstr ""
+
+#: modules/computer/languages.c:111
+msgid "Date"
+msgstr ""
+
+#: modules/computer/languages.c:112
+msgid "Codeset"
+msgstr ""
+
+#: modules/computer/loadavg.c:64
+msgid "Couldn't obtain load average"
+msgstr ""
+
+#: modules/computer/modules.c:125 modules/computer/modules.c:126
+#: modules/computer/modules.c:127 modules/computer/modules.c:128
+#: modules/computer/modules.c:129
+msgid "(Not available)"
+msgstr ""
+
+#: modules/computer/modules.c:142
+msgid "Module Information"
+msgstr ""
+
+#: modules/computer/modules.c:143
+msgid "Path"
+msgstr ""
+
+#: modules/computer/modules.c:144
+msgid "Used Memory"
+msgstr ""
+
+#: modules/computer/modules.c:144
+msgid "KiB"
+msgstr ""
+
+#: modules/computer/modules.c:148
+msgid "Version Magic"
+msgstr ""
+
+#: modules/computer/modules.c:149
+msgid "Copyright"
+msgstr ""
+
+#: modules/computer/modules.c:150
+msgid "Author"
+msgstr ""
+
+#: modules/computer/modules.c:151
+msgid "License"
+msgstr ""
+
+#: modules/computer/modules.c:158
+msgid "Dependencies"
+msgstr ""
+
+#: modules/computer/os.c:35 modules/computer/os.c:36 modules/computer/os.c:37
+#: modules/computer/os.c:38
+msgid "GNU C Library"
+msgstr ""
+
+#: modules/computer/os.c:39
+msgid "uClibc or uClibc-ng"
+msgstr ""
+
+#: modules/computer/os.c:40
+msgid "diet libc"
+msgstr ""
+
+#: modules/computer/os.c:78 modules/computer/os.c:234 modules/computer/os.c:359
+#: modules/devices.c:333 modules/devices.c:387 modules/devices/printers.c:99
+#: modules/devices/printers.c:106 modules/devices/printers.c:116
+#: modules/devices/printers.c:131 modules/devices/printers.c:140
+#: modules/devices/printers.c:243
+msgid "Unknown"
+msgstr ""
+
+#: modules/computer/os.c:112 modules/computer/os.c:115
+msgid "GNOME Shell "
+msgstr ""
+
+#: modules/computer/os.c:123 modules/computer/os.c:126
+msgid "Version: "
+msgstr ""
+
+#: modules/computer/os.c:157
+#, c-format
+msgid "Unknown (Window Manager: %s)"
+msgstr ""
+
+#. /{desktop environment} on {session type}
+#: modules/computer/os.c:168
+#, c-format
+msgid "%s on %s"
+msgstr ""
+
+#: modules/computer/os.c:232
+msgid "Terminal"
+msgstr ""
+
+#. /bits of entropy for rng (0)
+#: modules/computer/os.c:241
+msgid "(None or not available)"
+msgstr ""
+
+#. /bits of entropy for rng (low/poor value)
+#: modules/computer/os.c:242
+#, c-format
+msgid "%d bits (low)"
+msgstr ""
+
+#. /bits of entropy for rng (medium value)
+#: modules/computer/os.c:243
+#, c-format
+msgid "%d bits (medium)"
+msgstr ""
+
+#. /bits of entropy for rng (high/good value)
+#: modules/computer/os.c:244
+#, c-format
+msgid "%d bits (healthy)"
+msgstr ""
+
+#: modules/computer/os.c:279 modules/devices/usb.c:48 modules/devices/usb.c:307
+#: modules/devices/usb.c:310 modules/network/net.c:442 includes/cpu_util.h:11
+msgid "(Unknown)"
+msgstr ""
+
+#: modules/computer/users.c:47
+msgid "User Information"
+msgstr ""
+
+#: modules/computer/users.c:48
+msgid "User ID"
+msgstr ""
+
+#: modules/computer/users.c:51
+msgid "Default Shell"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:88 modules/devices/devicetree.c:141
+#: modules/devices/devicetree.c:176 modules/devices/devicetree/pmac_data.c:80
+#: modules/devices/ia64/processor.c:165 modules/devices/m68k/processor.c:84
+#: modules/devices/mips/processor.c:75 modules/devices/parisc/processor.c:155
+#: modules/devices/ppc/processor.c:158 modules/devices/riscv/processor.c:182
+#: modules/devices/s390/processor.c:132 modules/devices/spd-decode.c:1510
+msgid "Model"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:89
+msgid "Platform String"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:90 modules/devices/arm/processor.c:240
+#: modules/devices/ia64/processor.c:167 modules/devices/m68k/processor.c:87
+#: modules/devices/mips/processor.c:77 modules/devices/parisc/processor.c:158
+#: modules/devices/pci.c:108 modules/devices/ppc/processor.c:160
+#: modules/devices/riscv/processor.c:186 modules/devices/sh/processor.c:87
+#: modules/devices/x86/processor.c:420
+msgid "Frequency"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:90 modules/devices/arm/processor.c:240
+#: modules/devices/arm/processor.c:365 modules/devices.c:299
+#: modules/devices.c:307 modules/devices.c:335
+#: modules/devices/ia64/processor.c:167 modules/devices/ia64/processor.c:196
+#: modules/devices/m68k/processor.c:87 modules/devices/mips/processor.c:77
+#: modules/devices/parisc/processor.c:158
+#: modules/devices/parisc/processor.c:191 modules/devices/pci.c:108
+#: modules/devices/ppc/processor.c:160 modules/devices/ppc/processor.c:187
+#: modules/devices/riscv/processor.c:186 modules/devices/riscv/processor.c:214
+#: modules/devices/s390/processor.c:160 modules/devices/sh/processor.c:87
+#: modules/devices/sh/processor.c:88 modules/devices/sh/processor.c:89
+#: modules/devices/x86/processor.c:420 modules/devices/x86/processor.c:479
+msgid "MHz"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:91 modules/devices/arm/processor.c:241
+#: modules/devices/ia64/processor.c:168 modules/devices/m68k/processor.c:88
+#: modules/devices/mips/processor.c:78 modules/devices/parisc/processor.c:159
+#: modules/devices/ppc/processor.c:161 modules/devices/s390/processor.c:134
+#: modules/devices/sh/processor.c:90 modules/devices/x86/processor.c:421
+msgid "BogoMips"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:92 modules/devices/arm/processor.c:242
+#: modules/devices/ia64/processor.c:169 modules/devices/m68k/processor.c:89
+#: modules/devices/mips/processor.c:79 modules/devices/parisc/processor.c:160
+#: modules/devices/ppc/processor.c:162 modules/devices/riscv/processor.c:187
+#: modules/devices/s390/processor.c:135 modules/devices/sh/processor.c:91
+#: modules/devices/sparc/processor.c:77 modules/devices/x86/processor.c:422
+msgid "Byte Order"
+msgstr ""
+
+#. /hw_cap
+#. /flag:swp
+#: modules/devices/arm/arm_data.c:42
+msgctxt "arm-flag"
+msgid "SWP instruction (atomic read-modify-write)"
+msgstr ""
+
+#. /flag:half
+#: modules/devices/arm/arm_data.c:43
+msgctxt "arm-flag"
+msgid "Half-word loads and stores"
+msgstr ""
+
+#. /flag:thumb
+#: modules/devices/arm/arm_data.c:44
+msgctxt "arm-flag"
+msgid "Thumb (16-bit instruction set)"
+msgstr ""
+
+#. /flag:26bit
+#: modules/devices/arm/arm_data.c:45
+msgctxt "arm-flag"
+msgid "26-Bit Model (Processor status register folded into program counter)"
+msgstr ""
+
+#. /flag:fastmult
+#: modules/devices/arm/arm_data.c:46
+msgctxt "arm-flag"
+msgid "32x32->64-bit multiplication"
+msgstr ""
+
+#. /flag:fpa
+#: modules/devices/arm/arm_data.c:47
+msgctxt "arm-flag"
+msgid "Floating point accelerator"
+msgstr ""
+
+#. /flag:vfp
+#: modules/devices/arm/arm_data.c:48
+msgctxt "arm-flag"
+msgid "VFP (early SIMD vector floating point instructions)"
+msgstr ""
+
+#. /flag:edsp
+#: modules/devices/arm/arm_data.c:49
+msgctxt "arm-flag"
+msgid "DSP extensions (the 'e' variant of the ARM9 CPUs, and all others above)"
+msgstr ""
+
+#. /flag:java
+#: modules/devices/arm/arm_data.c:50
+msgctxt "arm-flag"
+msgid "Jazelle (Java bytecode accelerator)"
+msgstr ""
+
+#. /flag:iwmmxt
+#: modules/devices/arm/arm_data.c:51
+msgctxt "arm-flag"
+msgid "SIMD instructions similar to Intel MMX"
+msgstr ""
+
+#. /flag:crunch
+#: modules/devices/arm/arm_data.c:52
+msgctxt "arm-flag"
+msgid "MaverickCrunch coprocessor (if kernel support enabled)"
+msgstr ""
+
+#. /flag:thumbee
+#: modules/devices/arm/arm_data.c:53
+msgctxt "arm-flag"
+msgid "ThumbEE"
+msgstr ""
+
+#. /flag:neon
+#: modules/devices/arm/arm_data.c:54
+msgctxt "arm-flag"
+msgid "Advanced SIMD/NEON on AArch32"
+msgstr ""
+
+#. /flag:evtstrm
+#: modules/devices/arm/arm_data.c:55
+msgctxt "arm-flag"
+msgid "Kernel event stream using generic architected timer"
+msgstr ""
+
+#. /flag:vfpv3
+#: modules/devices/arm/arm_data.c:56
+msgctxt "arm-flag"
+msgid "VFP version 3"
+msgstr ""
+
+#. /flag:vfpv3d16
+#: modules/devices/arm/arm_data.c:57
+msgctxt "arm-flag"
+msgid "VFP version 3 with 16 D-registers"
+msgstr ""
+
+#. /flag:vfpv4
+#: modules/devices/arm/arm_data.c:58
+msgctxt "arm-flag"
+msgid "VFP version 4 with fast context switching"
+msgstr ""
+
+#. /flag:vfpd32
+#: modules/devices/arm/arm_data.c:59
+msgctxt "arm-flag"
+msgid "VFP with 32 D-registers"
+msgstr ""
+
+#. /flag:tls
+#: modules/devices/arm/arm_data.c:60
+msgctxt "arm-flag"
+msgid "TLS register"
+msgstr ""
+
+#. /flag:idiva
+#: modules/devices/arm/arm_data.c:61
+msgctxt "arm-flag"
+msgid "SDIV and UDIV hardware division in ARM mode"
+msgstr ""
+
+#. /flag:idivt
+#: modules/devices/arm/arm_data.c:62
+msgctxt "arm-flag"
+msgid "SDIV and UDIV hardware division in Thumb mode"
+msgstr ""
+
+#. /flag:lpae
+#: modules/devices/arm/arm_data.c:63
+msgctxt "arm-flag"
+msgid "40-bit Large Physical Address Extension"
+msgstr ""
+
+#. /hw_cap2
+#. /flag:pmull
+#: modules/devices/arm/arm_data.c:65
+msgctxt "arm-flag"
+msgid "64x64->128-bit F2m multiplication (arch>8)"
+msgstr ""
+
+#. /flag:aes
+#: modules/devices/arm/arm_data.c:66
+msgctxt "arm-flag"
+msgid "Crypto:AES (arch>8)"
+msgstr ""
+
+#. /flag:sha1
+#: modules/devices/arm/arm_data.c:67
+msgctxt "arm-flag"
+msgid "Crypto:SHA1 (arch>8)"
+msgstr ""
+
+#. /flag:sha2
+#: modules/devices/arm/arm_data.c:68
+msgctxt "arm-flag"
+msgid "Crypto:SHA2 (arch>8)"
+msgstr ""
+
+#. /flag:crc32
+#: modules/devices/arm/arm_data.c:69
+msgctxt "arm-flag"
+msgid "CRC32 checksum instructions (arch>8)"
+msgstr ""
+
+#. /flag:asimd
+#: modules/devices/arm/arm_data.c:72
+msgctxt "arm-flag"
+msgid "Advanced SIMD/NEON on AArch64 (arch>8)"
+msgstr ""
+
+#: modules/devices/arm/processor.c:142
+msgid "ARM Processor"
+msgstr ""
+
+#: modules/devices/arm/processor.c:200 modules/devices/riscv/processor.c:147
+#: modules/devices/x86/processor.c:371
+msgid "Empty List"
+msgstr ""
+
+#: modules/devices/arm/processor.c:237
+msgid "Linux Name"
+msgstr ""
+
+#: modules/devices/arm/processor.c:238
+msgid "Decoded Name"
+msgstr ""
+
+#: modules/devices/arm/processor.c:239 modules/network/net.c:458
+msgid "Mode"
+msgstr ""
+
+#: modules/devices/arm/processor.c:245
+msgid "ARM"
+msgstr ""
+
+#: modules/devices/arm/processor.c:246
+msgid "Implementer"
+msgstr ""
+
+#: modules/devices/arm/processor.c:247
+msgid "Part"
+msgstr ""
+
+#: modules/devices/arm/processor.c:248 modules/devices/ia64/processor.c:162
+#: modules/devices/parisc/processor.c:156 modules/devices/riscv/processor.c:183
+msgid "Architecture"
+msgstr ""
+
+#: modules/devices/arm/processor.c:249
+msgid "Variant"
+msgstr ""
+
+#: modules/devices/arm/processor.c:251 modules/devices/riscv/processor.c:190
+#: modules/devices/sparc/processor.c:78 modules/devices/x86/processor.c:428
+msgid "Capabilities"
+msgstr ""
+
+#: modules/devices/arm/processor.c:335
+msgid "SOC/Package"
+msgstr ""
+
+#: modules/devices/arm/processor.c:338 modules/devices/cpu_util.c:222
+msgid "Topology"
+msgstr ""
+
+#: modules/devices/arm/processor.c:339
+msgid "Clocks"
+msgstr ""
+
+#: modules/devices/arm/processor.c:354
+msgid "SOC/Package Information"
+msgstr ""
+
+#: modules/devices/battery.c:181
+#, c-format
+msgid ""
+"\n"
+"[Battery: %s]\n"
+"State=%s (load: %s)\n"
+"Capacity=%s / %s (%.2f%%)\n"
+"Battery Technology=%s (%s)\n"
+"Manufacturer=%s\n"
+"Model Number=%s\n"
+"Serial Number=%s\n"
+msgstr ""
+
+#: modules/devices/battery.c:258
+#, c-format
+msgid ""
+"\n"
+"[Battery: %s]\n"
+"State=%s\n"
+"Capacity=%s / %s\n"
+"Battery Technology=%s\n"
+"Manufacturer=%s\n"
+"Model Number=%s\n"
+"Serial Number=%s\n"
+msgstr ""
+
+#: modules/devices/battery.c:346
+#, c-format
+msgid ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Remaining Charge=%s of %s\n"
+"Using=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+msgstr ""
+
+#: modules/devices/battery.c:358
+#, c-format
+msgid ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Using=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+msgstr ""
+
+#: modules/devices/battery.c:385
+msgid ""
+"[No batteries]\n"
+"No batteries found on this system=\n"
+msgstr ""
+
+#: modules/devices.c:97
+msgid "PCI Devices"
+msgstr ""
+
+#: modules/devices.c:98 modules/devices/usb.c:117 modules/devices/usb.c:156
+#: modules/devices/usb.c:415
+msgid "USB Devices"
+msgstr ""
+
+#: modules/devices.c:100
+msgid "Battery"
+msgstr ""
+
+#: modules/devices.c:101
+msgid "Sensors"
+msgstr ""
+
+#: modules/devices.c:105
+msgid "DMI"
+msgstr ""
+
+#: modules/devices.c:106
+msgid "Memory SPD"
+msgstr ""
+
+#: modules/devices.c:111
+msgid "Device Tree"
+msgstr ""
+
+#: modules/devices.c:113
+msgid "Resources"
+msgstr ""
+
+#: modules/devices.c:151
+#, c-format
+msgid "%d physical processor"
+msgid_plural "%d physical processors"
+msgstr[0] ""
+msgstr[1] ""
+
+#: modules/devices.c:152
+#, c-format
+msgid "%d core"
+msgid_plural "%d cores"
+msgstr[0] ""
+msgstr[1] ""
+
+#: modules/devices.c:153
+#, c-format
+msgid "%d thread"
+msgid_plural "%d threads"
+msgstr[0] ""
+msgstr[1] ""
+
+#. /NP procs; NC cores; NT threads
+#: modules/devices.c:154
+#, c-format
+msgid "%s; %s; %s"
+msgstr ""
+
+#: modules/devices.c:372
+msgid " (model unknown)"
+msgstr ""
+
+#: modules/devices.c:374
+msgid " (vendor unknown)"
+msgstr ""
+
+#: modules/devices.c:559
+msgid "Field"
+msgstr ""
+
+#: modules/devices.c:559 modules/devices.c:591
+msgid "Value"
+msgstr ""
+
+#: modules/devices.c:591
+msgid "Sensor"
+msgstr ""
+
+#: modules/devices.c:591 modules/devices/inputdevices.c:117
+msgid "Type"
+msgstr ""
+
+#: modules/devices.c:637
+msgid "Devices"
+msgstr ""
+
+#: modules/devices.c:649
+msgid "Update PCI ID listing"
+msgstr ""
+
+#: modules/devices.c:661
+msgid "Update CPU feature database"
+msgstr ""
+
+#: modules/devices.c:689
+msgid "Gathers information about hardware devices"
+msgstr ""
+
+#: modules/devices.c:708
+msgid "Resource information requires superuser privileges"
+msgstr ""
+
+#: modules/devices/cpu_util.c:30
+msgid "Little Endian"
+msgstr ""
+
+#: modules/devices/cpu_util.c:32
+msgid "Big Endian"
+msgstr ""
+
+#: modules/devices/cpu_util.c:178 modules/devices/cpu_util.c:189
+msgid "Frequency Scaling"
+msgstr ""
+
+#: modules/devices/cpu_util.c:179
+msgid "Minimum"
+msgstr ""
+
+#: modules/devices/cpu_util.c:179 modules/devices/cpu_util.c:180
+#: modules/devices/cpu_util.c:181
+msgid "kHz"
+msgstr ""
+
+#: modules/devices/cpu_util.c:180
+msgid "Maximum"
+msgstr ""
+
+#: modules/devices/cpu_util.c:181
+msgid "Current"
+msgstr ""
+
+#: modules/devices/cpu_util.c:182
+msgid "Transition Latency"
+msgstr ""
+
+#: modules/devices/cpu_util.c:182
+msgid "ns"
+msgstr ""
+
+#: modules/devices/cpu_util.c:183
+msgid "Governor"
+msgstr ""
+
+#: modules/devices/cpu_util.c:184 modules/devices/cpu_util.c:190
+msgid "Driver"
+msgstr ""
+
+#: modules/devices/cpu_util.c:196 modules/devices/x86/processor.c:297
+msgid "(Not Available)"
+msgstr ""
+
+#: modules/devices/cpu_util.c:204 modules/devices/cpu_util.c:206
+msgid "Socket"
+msgstr ""
+
+#: modules/devices/cpu_util.c:209 modules/devices/cpu_util.c:211
+msgid "Core"
+msgstr ""
+
+#: modules/devices/cpu_util.c:214
+msgid "Book"
+msgstr ""
+
+#: modules/devices/cpu_util.c:216
+msgid "Drawer"
+msgstr ""
+
+#: modules/devices/cpu_util.c:223
+msgid "ID"
+msgstr ""
+
+#: modules/devices/devicetree.c:47
+msgid "Properties"
+msgstr ""
+
+#: modules/devices/devicetree.c:48
+msgid "Children"
+msgstr ""
+
+#: modules/devices/devicetree.c:84
+msgid "Node"
+msgstr ""
+
+#: modules/devices/devicetree.c:85
+msgid "Node Path"
+msgstr ""
+
+#: modules/devices/devicetree.c:86
+msgid "Alias"
+msgstr ""
+
+#: modules/devices/devicetree.c:86 modules/devices/devicetree.c:87
+msgid "(None)"
+msgstr ""
+
+#: modules/devices/devicetree.c:87
+msgid "Symbol"
+msgstr ""
+
+#: modules/devices/devicetree.c:132 modules/devices/devicetree/pmac_data.c:79
+msgid "Platform"
+msgstr ""
+
+#: modules/devices/devicetree.c:133 modules/devices/devicetree.c:178
+msgid "Compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:134
+msgid "GPU-compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:140
+msgid "Raspberry Pi or Compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:142 modules/devices/devicetree.c:160
+#: modules/devices/devicetree.c:177 modules/devices/devicetree/rpi_data.c:160
+msgid "Serial Number"
+msgstr ""
+
+#: modules/devices/devicetree.c:143 modules/devices/devicetree/rpi_data.c:157
+msgid "RCode"
+msgstr ""
+
+#: modules/devices/devicetree.c:143
+msgid "No revision code available; unable to lookup model details."
+msgstr ""
+
+#: modules/devices/devicetree.c:159
+msgid "More"
+msgstr ""
+
+#: modules/devices/devicetree.c:175
+msgid "Board"
+msgstr ""
+
+#: modules/devices/devicetree.c:234
+msgid "Messages"
+msgstr ""
+
+#: modules/devices/devicetree/dt_util.c:1013
+msgid "phandle Map"
+msgstr ""
+
+#: modules/devices/devicetree/dt_util.c:1014
+msgid "Alias Map"
+msgstr ""
+
+#: modules/devices/devicetree/dt_util.c:1015
+msgid "Symbol Map"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:78
+msgid "Apple Power Macintosh"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:81 modules/devices/sh/processor.c:85
+msgid "Machine"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:83
+msgid "Detected as"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:84
+msgid "PMAC Flags"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:85
+msgid "L2 Cache"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:86
+msgid "PMAC Generation"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:152
+#: modules/devices/devicetree/rpi_data.c:153
+msgid "Raspberry Pi"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:153
+msgid "Board Name"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:154
+msgid "PCB Revision"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:155
+msgid "Introduction"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:156 modules/devices/spd-decode.c:1510
+#: modules/devices/usb.c:84 modules/devices/usb.c:217
+msgid "Manufacturer"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:158
+msgid "SOC (spec)"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:159
+msgid "Memory (spec)"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgid "Permanent overvolt bit"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgctxt "rpi-ov-bit"
+msgid "Set"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgctxt "rpi-ov-bit"
+msgid "Not set"
+msgstr ""
+
+#: modules/devices/devmemory.c:93
+msgid "Total Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:94
+msgid "Free Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:95
+msgid "Cached Swap"
+msgstr ""
+
+#: modules/devices/devmemory.c:96
+msgid "High Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:97
+msgid "Free High Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:98
+msgid "Low Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:99
+msgid "Free Low Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:100
+msgid "Virtual Memory"
+msgstr ""
+
+#: modules/devices/devmemory.c:101
+msgid "Free Virtual Memory"
+msgstr ""
+
+#: modules/devices/dmi.c:188
+msgid "(Not available; Perhaps try running HardInfo as root.)"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:108
+msgid "IA64 Processor"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:163
+msgid "Architecture Revision"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:164 modules/devices/sh/processor.c:86
+msgid "Family"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:170
+msgid "CPU regs"
+msgstr ""
+
+#: modules/devices/ia64/processor.c:171
+msgid "Features"
+msgstr ""
+
+#: modules/devices/inputdevices.c:115 modules/devices/pci.c:214
+#: modules/devices/usb.c:82 modules/devices/usb.c:215 modules/devices/usb.c:347
+msgid "Device Information"
+msgstr ""
+
+#: modules/devices/inputdevices.c:118 modules/devices/usb.c:92
+#: modules/devices/usb.c:240 modules/devices/usb.c:356
+msgid "Bus"
+msgstr ""
+
+#: modules/devices/inputdevices.c:120 modules/devices/usb.c:83
+#: modules/devices/usb.c:216 modules/devices/usb.c:348
+msgid "Product"
+msgstr ""
+
+#: modules/devices/inputdevices.c:124
+msgid "Connected to"
+msgstr ""
+
+#: modules/devices/inputdevices.c:128
+msgid "InfraRed port"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:85 modules/devices/riscv/processor.c:185
+msgid "MMU"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:86 modules/devices/sparc/processor.c:76
+msgid "FPU"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:90
+msgid "Calibration"
+msgstr ""
+
+#: modules/devices/mips/processor.c:76
+msgid "System Type"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:107
+msgid "PA-RISC Processor"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:157
+msgid "System"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:161
+msgid "HVersion"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:162
+msgid "SVersion"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:163 modules/devices/x86/processor.c:425
+msgid "Cache"
+msgstr ""
+
+#: modules/devices/pci.c:106
+msgid "IRQ"
+msgstr ""
+
+#: modules/devices/pci.c:110
+msgid "Latency"
+msgstr ""
+
+#: modules/devices/pci.c:112
+msgid "Bus Master"
+msgstr ""
+
+#: modules/devices/pci.c:118
+msgid "Kernel modules"
+msgstr ""
+
+#: modules/devices/pci.c:124
+#, c-format
+msgid "%s=%s (%s)\n"
+msgstr ""
+
+#: modules/devices/pci.c:126
+msgid "OEM Vendor"
+msgstr ""
+
+#: modules/devices/pci.c:153
+msgid "prefetchable"
+msgstr ""
+
+#: modules/devices/pci.c:154
+msgid "non-prefetchable"
+msgstr ""
+
+#: modules/devices/pci.c:163
+msgid "I/O ports at"
+msgstr ""
+
+#: modules/devices/pci.c:216 modules/devices/usb.c:89 modules/devices/usb.c:237
+#: modules/devices/usb.c:353
+msgid "Class"
+msgstr ""
+
+#: modules/devices/pci.c:217
+msgid "Domain"
+msgstr ""
+
+#: modules/devices/pci.c:218
+msgid "Bus, device, function"
+msgstr ""
+
+#: modules/devices/pci.c:243
+msgid "No PCI devices found"
+msgstr ""
+
+#: modules/devices/ppc/processor.c:117
+msgid "POWER Processor"
+msgstr ""
+
+#: modules/devices/printers.c:81
+msgid "⚬ Can do black and white printing=\n"
+msgstr ""
+
+#: modules/devices/printers.c:83
+msgid "⚬ Can do color printing=\n"
+msgstr ""
+
+#: modules/devices/printers.c:85
+msgid "⚬ Can do duplexing=\n"
+msgstr ""
+
+#: modules/devices/printers.c:87
+msgid "⚬ Can do staple output=\n"
+msgstr ""
+
+#: modules/devices/printers.c:89
+msgid "⚬ Can do copies=\n"
+msgstr ""
+
+#: modules/devices/printers.c:91
+msgid "⚬ Can collate copies=\n"
+msgstr ""
+
+#: modules/devices/printers.c:93
+msgid "⚬ Printer is rejecting jobs=\n"
+msgstr ""
+
+#: modules/devices/printers.c:95
+msgid "⚬ Printer was automatically discovered and added=\n"
+msgstr ""
+
+#: modules/devices/printers.c:110
+msgid "Idle"
+msgstr ""
+
+#: modules/devices/printers.c:112
+msgid "Printing a Job"
+msgstr ""
+
+#: modules/devices/printers.c:114
+msgid "Stopped"
+msgstr ""
+
+#: modules/devices/printers.c:190
+msgid ""
+"[Printers]\n"
+"No suitable CUPS library found="
+msgstr ""
+
+#: modules/devices/printers.c:200
+msgid "[Printers (CUPS)]\n"
+msgstr ""
+
+#: modules/devices/printers.c:263
+msgid ""
+"[Printers]\n"
+"No printers found=\n"
+msgstr ""
+
+#: modules/devices/riscv/processor.c:107
+msgid "RISC-V Processor"
+msgstr ""
+
+#: modules/devices/riscv/processor.c:184
+msgid "uarch"
+msgstr ""
+
+#. /ext:RV32
+#: modules/devices/riscv/riscv_data.c:37
+msgctxt "rv-ext"
+msgid "RISC-V 32-bit"
+msgstr ""
+
+#. /ext:RV64
+#: modules/devices/riscv/riscv_data.c:38
+msgctxt "rv-ext"
+msgid "RISC-V 64-bit"
+msgstr ""
+
+#. /ext:RV128
+#: modules/devices/riscv/riscv_data.c:39
+msgctxt "rv-ext"
+msgid "RISC-V 128-bit"
+msgstr ""
+
+#. /ext:E
+#: modules/devices/riscv/riscv_data.c:40
+msgctxt "rv-ext"
+msgid "Base embedded integer instructions (15 registers)"
+msgstr ""
+
+#. /ext:I
+#: modules/devices/riscv/riscv_data.c:41
+msgctxt "rv-ext"
+msgid "Base integer instructions (31 registers)"
+msgstr ""
+
+#. /ext:M
+#: modules/devices/riscv/riscv_data.c:42
+msgctxt "rv-ext"
+msgid "Hardware integer multiply and divide"
+msgstr ""
+
+#. /ext:A
+#: modules/devices/riscv/riscv_data.c:43
+msgctxt "rv-ext"
+msgid "Atomic memory operations"
+msgstr ""
+
+#. /ext:C
+#: modules/devices/riscv/riscv_data.c:44
+msgctxt "rv-ext"
+msgid "Compressed 16-bit instructions"
+msgstr ""
+
+#. /ext:F
+#: modules/devices/riscv/riscv_data.c:45
+msgctxt "rv-ext"
+msgid "Floating-point instructions, single-precision"
+msgstr ""
+
+#. /ext:D
+#: modules/devices/riscv/riscv_data.c:46
+msgctxt "rv-ext"
+msgid "Floating-point instructions, double-precision"
+msgstr ""
+
+#. /ext:Q
+#: modules/devices/riscv/riscv_data.c:47
+msgctxt "rv-ext"
+msgid "Floating-point instructions, quad-precision"
+msgstr ""
+
+#. /ext:B
+#: modules/devices/riscv/riscv_data.c:48
+msgctxt "rv-ext"
+msgid "Bit manipulation instructions"
+msgstr ""
+
+#. /ext:V
+#: modules/devices/riscv/riscv_data.c:49
+msgctxt "rv-ext"
+msgid "Vector operations"
+msgstr ""
+
+#. /ext:T
+#: modules/devices/riscv/riscv_data.c:50
+msgctxt "rv-ext"
+msgid "Transactional memory"
+msgstr ""
+
+#. /ext:P
+#: modules/devices/riscv/riscv_data.c:51
+msgctxt "rv-ext"
+msgid "Packed SIMD instructions"
+msgstr ""
+
+#. /ext:L
+#: modules/devices/riscv/riscv_data.c:52
+msgctxt "rv-ext"
+msgid "Decimal floating-point instructions"
+msgstr ""
+
+#. /ext:J
+#: modules/devices/riscv/riscv_data.c:53
+msgctxt "rv-ext"
+msgid "Dynamically translated languages"
+msgstr ""
+
+#. /ext:N
+#: modules/devices/riscv/riscv_data.c:54
+msgctxt "rv-ext"
+msgid "User-level interrupts"
+msgstr ""
+
+#: modules/devices/s390/processor.c:92
+msgid "S390 Processor"
+msgstr ""
+
+#: modules/devices/s390/processor.c:133
+msgid "ID String"
+msgstr ""
+
+#: modules/devices/sh/processor.c:55
+msgid "SuperH Processor"
+msgstr ""
+
+#: modules/devices/sh/processor.c:88
+msgid "Bus Frequency"
+msgstr ""
+
+#: modules/devices/sh/processor.c:89
+msgid "Module Frequency"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1475
+msgid ""
+"[SPD]\n"
+"Please load the eeprom module to obtain information about memory SPD=\n"
+"[$ShellParam$]\n"
+"ReloadInterval=500\n"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1480
+msgid ""
+"[SPD]\n"
+"Reading memory SPD not supported on this system=\n"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1509
+msgid "SPD"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1510
+msgid "Bank"
+msgstr ""
+
+#: modules/devices/storage.c:46
+msgid ""
+"\n"
+"[SCSI Disks]\n"
+msgstr ""
+
+#: modules/devices/storage.c:110 modules/devices/storage.c:313
+#, c-format
+msgid ""
+"[Device Information]\n"
+"Model=%s\n"
+msgstr ""
+
+#: modules/devices/storage.c:115 modules/devices/storage.c:319
+#, c-format
+msgid "Vendor=%s (%s)\n"
+msgstr ""
+
+#: modules/devices/storage.c:120 modules/devices/storage.c:321
+#, c-format
+msgid "Vendor=%s\n"
+msgstr ""
+
+#: modules/devices/storage.c:125
+#, c-format
+msgid ""
+"Type=%s\n"
+"Revision=%s\n"
+"[SCSI Controller]\n"
+"Controller=scsi%d\n"
+"Channel=%d\n"
+"ID=%d\n"
+"LUN=%d\n"
+msgstr ""
+
+#: modules/devices/storage.c:167
+msgid ""
+"\n"
+"[IDE Disks]\n"
+msgstr ""
+
+#: modules/devices/storage.c:250
+#, c-format
+msgid "Driver=%s\n"
+msgstr ""
+
+#: modules/devices/storage.c:324
+#, c-format
+msgid ""
+"Device Name=hd%c\n"
+"Media=%s\n"
+"Cache=%dkb\n"
+msgstr ""
+
+#: modules/devices/storage.c:334
+#, c-format
+msgid ""
+"[Geometry]\n"
+"Physical=%s\n"
+"Logical=%s\n"
+msgstr ""
+
+#: modules/devices/storage.c:344
+#, c-format
+msgid ""
+"[Capabilities]\n"
+"%s"
+msgstr ""
+
+#: modules/devices/storage.c:351
+#, c-format
+msgid ""
+"[Speeds]\n"
+"%s"
+msgstr ""
+
+#: modules/devices/usb.c:44 modules/devices/usb.c:326
+msgid "mA"
+msgstr ""
+
+#. /%.2f is version
+#: modules/devices/usb.c:53 modules/devices/usb.c:190
+#, c-format
+msgid "USB %.2f Hub"
+msgstr ""
+
+#: modules/devices/usb.c:55 modules/devices/usb.c:192
+#, c-format
+msgid "Unknown USB %.2f Device (class %d)"
+msgstr ""
+
+#: modules/devices/usb.c:85 modules/devices/usb.c:232
+msgid "Speed"
+msgstr ""
+
+#: modules/devices/usb.c:85 modules/devices/usb.c:232
+msgid "Mbit/s"
+msgstr ""
+
+#: modules/devices/usb.c:86 modules/devices/usb.c:233 modules/devices/usb.c:350
+msgid "Max Current"
+msgstr ""
+
+#: modules/devices/usb.c:88 modules/devices/usb.c:235 modules/devices/usb.c:352
+msgid "USB Version"
+msgstr ""
+
+#: modules/devices/usb.c:90 modules/devices/usb.c:238 modules/devices/usb.c:354
+msgid "Vendor ID"
+msgstr ""
+
+#: modules/devices/usb.c:91 modules/devices/usb.c:239 modules/devices/usb.c:355
+msgid "Product ID"
+msgstr ""
+
+#: modules/devices/usb.c:231
+msgid "Port"
+msgstr ""
+
+#: modules/devices/usb.c:241
+msgid "Level"
+msgstr ""
+
+#: modules/devices/x86/processor.c:149
+msgid "Cache information not available=\n"
+msgstr ""
+
+#: modules/devices/x86/processor.c:155
+#, c-format
+msgid "Level %d (%s)=%d-way set-associative, %d sets, %dKB size\n"
+msgstr ""
+
+#. /cache type, as appears in: Level 1 (Data)
+#: modules/devices/x86/processor.c:170
+msgctxt "cache-type"
+msgid "Data"
+msgstr ""
+
+#. /cache type, as appears in: Level 1 (Instruction)
+#: modules/devices/x86/processor.c:171
+msgctxt "cache-type"
+msgid "Instruction"
+msgstr ""
+
+#. /cache type, as appears in: Level 2 (Unified)
+#: modules/devices/x86/processor.c:172
+msgctxt "cache-type"
+msgid "Unified"
+msgstr ""
+
+#: modules/devices/x86/processor.c:410
+msgid "Model Name"
+msgstr ""
+
+#: modules/devices/x86/processor.c:411
+msgid "Family, model, stepping"
+msgstr ""
+
+#: modules/devices/x86/processor.c:417
+msgid "Microcode Version"
+msgstr ""
+
+#: modules/devices/x86/processor.c:418
+msgid "Configuration"
+msgstr ""
+
+#: modules/devices/x86/processor.c:419
+msgid "Cache Size"
+msgstr ""
+
+#: modules/devices/x86/processor.c:419
+msgid "kb"
+msgstr ""
+
+#: modules/devices/x86/processor.c:426
+msgid "Power Management"
+msgstr ""
+
+#: modules/devices/x86/processor.c:427
+msgid "Bug Workarounds"
+msgstr ""
+
+#: modules/devices/x86/processor.c:454 modules/devices/x86/processor.c:468
+msgid "Package Information"
+msgstr ""
+
+#. /flag:fpu
+#: modules/devices/x86/x86_data.c:43
+msgctxt "x86-flag"
+msgid "Onboard FPU (floating point support)"
+msgstr ""
+
+#. /flag:vme
+#: modules/devices/x86/x86_data.c:44
+msgctxt "x86-flag"
+msgid "Virtual 8086 mode enhancements"
+msgstr ""
+
+#. /flag:de
+#: modules/devices/x86/x86_data.c:45
+msgctxt "x86-flag"
+msgid "Debugging Extensions (CR4.DE)"
+msgstr ""
+
+#. /flag:pse
+#: modules/devices/x86/x86_data.c:46
+msgctxt "x86-flag"
+msgid "Page Size Extensions (4MB memory pages)"
+msgstr ""
+
+#. /flag:tsc
+#: modules/devices/x86/x86_data.c:47
+msgctxt "x86-flag"
+msgid "Time Stamp Counter (RDTSC)"
+msgstr ""
+
+#. /flag:msr
+#: modules/devices/x86/x86_data.c:48
+msgctxt "x86-flag"
+msgid "Model-Specific Registers (RDMSR, WRMSR)"
+msgstr ""
+
+#. /flag:pae
+#: modules/devices/x86/x86_data.c:49
+msgctxt "x86-flag"
+msgid "Physical Address Extensions (support for more than 4GB of RAM)"
+msgstr ""
+
+#. /flag:mce
+#: modules/devices/x86/x86_data.c:50
+msgctxt "x86-flag"
+msgid "Machine Check Exception"
+msgstr ""
+
+#. /flag:cx8
+#: modules/devices/x86/x86_data.c:51
+msgctxt "x86-flag"
+msgid "CMPXCHG8 instruction (64-bit compare-and-swap)"
+msgstr ""
+
+#. /flag:apic
+#: modules/devices/x86/x86_data.c:52
+msgctxt "x86-flag"
+msgid "Onboard APIC"
+msgstr ""
+
+#. /flag:sep
+#: modules/devices/x86/x86_data.c:53
+msgctxt "x86-flag"
+msgid "SYSENTER/SYSEXIT"
+msgstr ""
+
+#. /flag:mtrr
+#: modules/devices/x86/x86_data.c:54
+msgctxt "x86-flag"
+msgid "Memory Type Range Registers"
+msgstr ""
+
+#. /flag:pge
+#: modules/devices/x86/x86_data.c:55
+msgctxt "x86-flag"
+msgid "Page Global Enable (global bit in PDEs and PTEs)"
+msgstr ""
+
+#. /flag:mca
+#: modules/devices/x86/x86_data.c:56
+msgctxt "x86-flag"
+msgid "Machine Check Architecture"
+msgstr ""
+
+#. /flag:cmov
+#: modules/devices/x86/x86_data.c:57
+msgctxt "x86-flag"
+msgid "CMOV instructions (conditional move) (also FCMOV)"
+msgstr ""
+
+#. /flag:pat
+#: modules/devices/x86/x86_data.c:58
+msgctxt "x86-flag"
+msgid "Page Attribute Table"
+msgstr ""
+
+#. /flag:pse36
+#: modules/devices/x86/x86_data.c:59
+msgctxt "x86-flag"
+msgid "36-bit PSEs (huge pages)"
+msgstr ""
+
+#. /flag:pn
+#: modules/devices/x86/x86_data.c:60
+msgctxt "x86-flag"
+msgid "Processor serial number"
+msgstr ""
+
+#. /flag:clflush
+#: modules/devices/x86/x86_data.c:61
+msgctxt "x86-flag"
+msgid "Cache Line Flush instruction"
+msgstr ""
+
+#. /flag:dts
+#: modules/devices/x86/x86_data.c:62
+msgctxt "x86-flag"
+msgid ""
+"Debug Store (buffer for debugging and profiling instructions), or "
+"alternately: digital thermal sensor"
+msgstr ""
+
+#. /flag:acpi
+#: modules/devices/x86/x86_data.c:63
+msgctxt "x86-flag"
+msgid "ACPI via MSR (temperature monitoring and clock speed modulation)"
+msgstr ""
+
+#. /flag:mmx
+#: modules/devices/x86/x86_data.c:64
+msgctxt "x86-flag"
+msgid "Multimedia Extensions"
+msgstr ""
+
+#. /flag:fxsr
+#: modules/devices/x86/x86_data.c:65
+msgctxt "x86-flag"
+msgid "FXSAVE/FXRSTOR, CR4.OSFXSR"
+msgstr ""
+
+#. /flag:sse
+#: modules/devices/x86/x86_data.c:66
+msgctxt "x86-flag"
+msgid "Intel SSE vector instructions"
+msgstr ""
+
+#. /flag:sse2
+#: modules/devices/x86/x86_data.c:67
+msgctxt "x86-flag"
+msgid "SSE2"
+msgstr ""
+
+#. /flag:ss
+#: modules/devices/x86/x86_data.c:68
+msgctxt "x86-flag"
+msgid "CPU self snoop"
+msgstr ""
+
+#. /flag:ht
+#: modules/devices/x86/x86_data.c:69
+msgctxt "x86-flag"
+msgid "Hyper-Threading"
+msgstr ""
+
+#. /flag:tm
+#: modules/devices/x86/x86_data.c:70
+msgctxt "x86-flag"
+msgid "Automatic clock control (Thermal Monitor)"
+msgstr ""
+
+#. /flag:ia64
+#: modules/devices/x86/x86_data.c:71
+msgctxt "x86-flag"
+msgid ""
+"Intel Itanium Architecture 64-bit (not to be confused with Intel's 64-bit "
+"x86 architecture with flag x86-64 or \"AMD64\" bit indicated by flag lm)"
+msgstr ""
+
+#. /flag:pbe
+#: modules/devices/x86/x86_data.c:72
+msgctxt "x86-flag"
+msgid "Pending Break Enable (PBE# pin) wakeup support"
+msgstr ""
+
+#. /flag:syscall
+#: modules/devices/x86/x86_data.c:75
+msgctxt "x86-flag"
+msgid "SYSCALL (Fast System Call) and SYSRET (Return From Fast System Call)"
+msgstr ""
+
+#. /flag:mp
+#: modules/devices/x86/x86_data.c:76
+msgctxt "x86-flag"
+msgid "Multiprocessing Capable."
+msgstr ""
+
+#. /flag:nx
+#: modules/devices/x86/x86_data.c:77
+msgctxt "x86-flag"
+msgid "Execute Disable"
+msgstr ""
+
+#. /flag:mmxext
+#: modules/devices/x86/x86_data.c:78
+msgctxt "x86-flag"
+msgid "AMD MMX extensions"
+msgstr ""
+
+#. /flag:fxsr_opt
+#: modules/devices/x86/x86_data.c:79
+msgctxt "x86-flag"
+msgid "FXSAVE/FXRSTOR optimizations"
+msgstr ""
+
+#. /flag:pdpe1gb
+#: modules/devices/x86/x86_data.c:80
+msgctxt "x86-flag"
+msgid "One GB pages (allows hugepagesz=1G)"
+msgstr ""
+
+#. /flag:rdtscp
+#: modules/devices/x86/x86_data.c:81
+msgctxt "x86-flag"
+msgid "Read Time-Stamp Counter and Processor ID"
+msgstr ""
+
+#. /flag:lm
+#: modules/devices/x86/x86_data.c:82
+msgctxt "x86-flag"
+msgid "Long Mode (x86-64: amd64, also known as Intel 64, i.e. 64-bit capable)"
+msgstr ""
+
+#. /flag:3dnow
+#: modules/devices/x86/x86_data.c:83
+msgctxt "x86-flag"
+msgid "3DNow! (AMD vector instructions, competing with Intel's SSE1)"
+msgstr ""
+
+#. /flag:3dnowext
+#: modules/devices/x86/x86_data.c:84
+msgctxt "x86-flag"
+msgid "AMD 3DNow! extensions"
+msgstr ""
+
+#. /flag:recovery
+#: modules/devices/x86/x86_data.c:86
+msgctxt "x86-flag"
+msgid "CPU in recovery mode"
+msgstr ""
+
+#. /flag:longrun
+#: modules/devices/x86/x86_data.c:87
+msgctxt "x86-flag"
+msgid "Longrun power control"
+msgstr ""
+
+#. /flag:lrti
+#: modules/devices/x86/x86_data.c:88
+msgctxt "x86-flag"
+msgid "LongRun table interface"
+msgstr ""
+
+#. /flag:cxmmx
+#: modules/devices/x86/x86_data.c:90
+msgctxt "x86-flag"
+msgid "Cyrix MMX extensions"
+msgstr ""
+
+#. /flag:k6_mtrr
+#: modules/devices/x86/x86_data.c:91
+msgctxt "x86-flag"
+msgid "AMD K6 nonstandard MTRRs"
+msgstr ""
+
+#. /flag:cyrix_arr
+#: modules/devices/x86/x86_data.c:92
+msgctxt "x86-flag"
+msgid "Cyrix ARRs (= MTRRs)"
+msgstr ""
+
+#. /flag:centaur_mcr
+#: modules/devices/x86/x86_data.c:93
+msgctxt "x86-flag"
+msgid "Centaur MCRs (= MTRRs)"
+msgstr ""
+
+#. /flag:constant_tsc
+#: modules/devices/x86/x86_data.c:94
+msgctxt "x86-flag"
+msgid "TSC ticks at a constant rate"
+msgstr ""
+
+#. /flag:up
+#: modules/devices/x86/x86_data.c:95
+msgctxt "x86-flag"
+msgid "SMP kernel running on UP"
+msgstr ""
+
+#. /flag:art
+#: modules/devices/x86/x86_data.c:96
+msgctxt "x86-flag"
+msgid "Always-Running Timer"
+msgstr ""
+
+#. /flag:arch_perfmon
+#: modules/devices/x86/x86_data.c:97
+msgctxt "x86-flag"
+msgid "Intel Architectural PerfMon"
+msgstr ""
+
+#. /flag:pebs
+#: modules/devices/x86/x86_data.c:98
+msgctxt "x86-flag"
+msgid "Precise-Event Based Sampling"
+msgstr ""
+
+#. /flag:bts
+#: modules/devices/x86/x86_data.c:99
+msgctxt "x86-flag"
+msgid "Branch Trace Store"
+msgstr ""
+
+#. /flag:rep_good
+#: modules/devices/x86/x86_data.c:100
+msgctxt "x86-flag"
+msgid "rep microcode works well"
+msgstr ""
+
+#. /flag:acc_power
+#: modules/devices/x86/x86_data.c:101
+msgctxt "x86-flag"
+msgid "AMD accumulated power mechanism"
+msgstr ""
+
+#. /flag:nopl
+#: modules/devices/x86/x86_data.c:102
+msgctxt "x86-flag"
+msgid "The NOPL (0F 1F) instructions"
+msgstr ""
+
+#. /flag:xtopology
+#: modules/devices/x86/x86_data.c:103
+msgctxt "x86-flag"
+msgid "cpu topology enum extensions"
+msgstr ""
+
+#. /flag:tsc_reliable
+#: modules/devices/x86/x86_data.c:104
+msgctxt "x86-flag"
+msgid "TSC is known to be reliable"
+msgstr ""
+
+#. /flag:nonstop_tsc
+#: modules/devices/x86/x86_data.c:105
+msgctxt "x86-flag"
+msgid "TSC does not stop in C states"
+msgstr ""
+
+#. /flag:extd_apicid
+#: modules/devices/x86/x86_data.c:106
+msgctxt "x86-flag"
+msgid "has extended APICID (8 bits)"
+msgstr ""
+
+#. /flag:amd_dcm
+#: modules/devices/x86/x86_data.c:107
+msgctxt "x86-flag"
+msgid "multi-node processor"
+msgstr ""
+
+#. /flag:aperfmperf
+#: modules/devices/x86/x86_data.c:108
+msgctxt "x86-flag"
+msgid "APERFMPERF"
+msgstr ""
+
+#. /flag:eagerfpu
+#: modules/devices/x86/x86_data.c:109
+msgctxt "x86-flag"
+msgid "Non lazy FPU restore"
+msgstr ""
+
+#. /flag:nonstop_tsc_s3
+#: modules/devices/x86/x86_data.c:110
+msgctxt "x86-flag"
+msgid "TSC doesn't stop in S3 state"
+msgstr ""
+
+#. /flag:mce_recovery
+#: modules/devices/x86/x86_data.c:111
+msgctxt "x86-flag"
+msgid "CPU has recoverable machine checks"
+msgstr ""
+
+#. /flag:pni
+#: modules/devices/x86/x86_data.c:114
+msgctxt "x86-flag"
+msgid "SSE-3 (\"Prescott New Instructions\")"
+msgstr ""
+
+#. /flag:pclmulqdq
+#: modules/devices/x86/x86_data.c:115
+msgctxt "x86-flag"
+msgid ""
+"Perform a Carry-Less Multiplication of Quadword instruction - accelerator "
+"for GCM)"
+msgstr ""
+
+#. /flag:dtes64
+#: modules/devices/x86/x86_data.c:116
+msgctxt "x86-flag"
+msgid "64-bit Debug Store"
+msgstr ""
+
+#. /flag:monitor
+#: modules/devices/x86/x86_data.c:117
+msgctxt "x86-flag"
+msgid "Monitor/Mwait support (Intel SSE3 supplements)"
+msgstr ""
+
+#. /flag:ds_cpl
+#: modules/devices/x86/x86_data.c:118
+msgctxt "x86-flag"
+msgid "CPL Qual. Debug Store"
+msgstr ""
+
+#. /flag:vmx
+#: modules/devices/x86/x86_data.c:119
+msgctxt "x86-flag"
+msgid "Hardware virtualization, Intel VMX"
+msgstr ""
+
+#. /flag:smx
+#: modules/devices/x86/x86_data.c:120
+msgctxt "x86-flag"
+msgid "Safer mode TXT (TPM support)"
+msgstr ""
+
+#. /flag:est
+#: modules/devices/x86/x86_data.c:121
+msgctxt "x86-flag"
+msgid "Enhanced SpeedStep"
+msgstr ""
+
+#. /flag:tm2
+#: modules/devices/x86/x86_data.c:122
+msgctxt "x86-flag"
+msgid "Thermal Monitor 2"
+msgstr ""
+
+#. /flag:ssse3
+#: modules/devices/x86/x86_data.c:123
+msgctxt "x86-flag"
+msgid "Supplemental SSE-3"
+msgstr ""
+
+#. /flag:cid
+#: modules/devices/x86/x86_data.c:124
+msgctxt "x86-flag"
+msgid "Context ID"
+msgstr ""
+
+#. /flag:sdbg
+#: modules/devices/x86/x86_data.c:125
+msgctxt "x86-flag"
+msgid "silicon debug"
+msgstr ""
+
+#. /flag:fma
+#: modules/devices/x86/x86_data.c:126
+msgctxt "x86-flag"
+msgid "Fused multiply-add"
+msgstr ""
+
+#. /flag:cx16
+#: modules/devices/x86/x86_data.c:127
+msgctxt "x86-flag"
+msgid "CMPXCHG16B"
+msgstr ""
+
+#. /flag:xtpr
+#: modules/devices/x86/x86_data.c:128
+msgctxt "x86-flag"
+msgid "Send Task Priority Messages"
+msgstr ""
+
+#. /flag:pdcm
+#: modules/devices/x86/x86_data.c:129
+msgctxt "x86-flag"
+msgid "Performance Capabilities"
+msgstr ""
+
+#. /flag:pcid
+#: modules/devices/x86/x86_data.c:130
+msgctxt "x86-flag"
+msgid "Process Context Identifiers"
+msgstr ""
+
+#. /flag:dca
+#: modules/devices/x86/x86_data.c:131
+msgctxt "x86-flag"
+msgid "Direct Cache Access"
+msgstr ""
+
+#. /flag:sse4_1
+#: modules/devices/x86/x86_data.c:132
+msgctxt "x86-flag"
+msgid "SSE-4.1"
+msgstr ""
+
+#. /flag:sse4_2
+#: modules/devices/x86/x86_data.c:133
+msgctxt "x86-flag"
+msgid "SSE-4.2"
+msgstr ""
+
+#. /flag:x2apic
+#: modules/devices/x86/x86_data.c:134
+msgctxt "x86-flag"
+msgid "x2APIC"
+msgstr ""
+
+#. /flag:movbe
+#: modules/devices/x86/x86_data.c:135
+msgctxt "x86-flag"
+msgid "Move Data After Swapping Bytes instruction"
+msgstr ""
+
+#. /flag:popcnt
+#: modules/devices/x86/x86_data.c:136
+msgctxt "x86-flag"
+msgid ""
+"Return the Count of Number of Bits Set to 1 instruction (Hamming weight, i."
+"e. bit count)"
+msgstr ""
+
+#. /flag:tsc_deadline_timer
+#: modules/devices/x86/x86_data.c:137
+msgctxt "x86-flag"
+msgid "Tsc deadline timer"
+msgstr ""
+
+#. /flag:aes/aes-ni
+#: modules/devices/x86/x86_data.c:138
+msgctxt "x86-flag"
+msgid "Advanced Encryption Standard (New Instructions)"
+msgstr ""
+
+#. /flag:xsave
+#: modules/devices/x86/x86_data.c:139
+msgctxt "x86-flag"
+msgid "Save Processor Extended States: also provides XGETBY,XRSTOR,XSETBY"
+msgstr ""
+
+#. /flag:avx
+#: modules/devices/x86/x86_data.c:140
+msgctxt "x86-flag"
+msgid "Advanced Vector Extensions"
+msgstr ""
+
+#. /flag:f16c
+#: modules/devices/x86/x86_data.c:141
+msgctxt "x86-flag"
+msgid "16-bit fp conversions (CVT16)"
+msgstr ""
+
+#. /flag:rdrand
+#: modules/devices/x86/x86_data.c:142
+msgctxt "x86-flag"
+msgid "Read Random Number from hardware random number generator instruction"
+msgstr ""
+
+#. /flag:hypervisor
+#: modules/devices/x86/x86_data.c:143
+msgctxt "x86-flag"
+msgid "Running on a hypervisor"
+msgstr ""
+
+#. /Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001
+#. /flag:rng
+#: modules/devices/x86/x86_data.c:145
+msgctxt "x86-flag"
+msgid "Random Number Generator present (xstore)"
+msgstr ""
+
+#. /flag:rng_en
+#: modules/devices/x86/x86_data.c:146
+msgctxt "x86-flag"
+msgid "Random Number Generator enabled"
+msgstr ""
+
+#. /flag:ace
+#: modules/devices/x86/x86_data.c:147
+msgctxt "x86-flag"
+msgid "on-CPU crypto (xcrypt)"
+msgstr ""
+
+#. /flag:ace_en
+#: modules/devices/x86/x86_data.c:148
+msgctxt "x86-flag"
+msgid "on-CPU crypto enabled"
+msgstr ""
+
+#. /flag:ace2
+#: modules/devices/x86/x86_data.c:149
+msgctxt "x86-flag"
+msgid "Advanced Cryptography Engine v2"
+msgstr ""
+
+#. /flag:ace2_en
+#: modules/devices/x86/x86_data.c:150
+msgctxt "x86-flag"
+msgid "ACE v2 enabled"
+msgstr ""
+
+#. /flag:phe
+#: modules/devices/x86/x86_data.c:151
+msgctxt "x86-flag"
+msgid "PadLock Hash Engine"
+msgstr ""
+
+#. /flag:phe_en
+#: modules/devices/x86/x86_data.c:152
+msgctxt "x86-flag"
+msgid "PHE enabled"
+msgstr ""
+
+#. /flag:pmm
+#: modules/devices/x86/x86_data.c:153
+msgctxt "x86-flag"
+msgid "PadLock Montgomery Multiplier"
+msgstr ""
+
+#. /flag:pmm_en
+#: modules/devices/x86/x86_data.c:154
+msgctxt "x86-flag"
+msgid "PMM enabled"
+msgstr ""
+
+#. /flag:lahf_lm
+#: modules/devices/x86/x86_data.c:156
+msgctxt "x86-flag"
+msgid "Load AH from Flags (LAHF) and Store AH into Flags (SAHF) in long mode"
+msgstr ""
+
+#. /flag:cmp_legacy
+#: modules/devices/x86/x86_data.c:157
+msgctxt "x86-flag"
+msgid "If yes HyperThreading not valid"
+msgstr ""
+
+#. /flag:svm
+#: modules/devices/x86/x86_data.c:158
+msgctxt "x86-flag"
+msgid "\"Secure virtual machine\": AMD-V"
+msgstr ""
+
+#. /flag:extapic
+#: modules/devices/x86/x86_data.c:159
+msgctxt "x86-flag"
+msgid "Extended APIC space"
+msgstr ""
+
+#. /flag:cr8_legacy
+#: modules/devices/x86/x86_data.c:160
+msgctxt "x86-flag"
+msgid "CR8 in 32-bit mode"
+msgstr ""
+
+#. /flag:abm
+#: modules/devices/x86/x86_data.c:161
+msgctxt "x86-flag"
+msgid "Advanced Bit Manipulation"
+msgstr ""
+
+#. /flag:sse4a
+#: modules/devices/x86/x86_data.c:162
+msgctxt "x86-flag"
+msgid "SSE-4A"
+msgstr ""
+
+#. /flag:misalignsse
+#: modules/devices/x86/x86_data.c:163
+msgctxt "x86-flag"
+msgid ""
+"indicates if a general-protection exception (#GP) is generated when some "
+"legacy SSE instructions operate on unaligned data. Also depends on CR0 and "
+"Alignment Checking bit"
+msgstr ""
+
+#. /flag:3dnowprefetch
+#: modules/devices/x86/x86_data.c:164
+msgctxt "x86-flag"
+msgid "3DNow prefetch instructions"
+msgstr ""
+
+#. /flag:osvw
+#: modules/devices/x86/x86_data.c:165
+msgctxt "x86-flag"
+msgid ""
+"indicates OS Visible Workaround, which allows the OS to work around "
+"processor errata."
+msgstr ""
+
+#. /flag:ibs
+#: modules/devices/x86/x86_data.c:166
+msgctxt "x86-flag"
+msgid "Instruction Based Sampling"
+msgstr ""
+
+#. /flag:xop
+#: modules/devices/x86/x86_data.c:167
+msgctxt "x86-flag"
+msgid "extended AVX instructions"
+msgstr ""
+
+#. /flag:skinit
+#: modules/devices/x86/x86_data.c:168
+msgctxt "x86-flag"
+msgid "SKINIT/STGI instructions"
+msgstr ""
+
+#. /flag:wdt
+#: modules/devices/x86/x86_data.c:169
+msgctxt "x86-flag"
+msgid "Watchdog timer"
+msgstr ""
+
+#. /flag:lwp
+#: modules/devices/x86/x86_data.c:170
+msgctxt "x86-flag"
+msgid "Light Weight Profiling"
+msgstr ""
+
+#. /flag:fma4
+#: modules/devices/x86/x86_data.c:171
+msgctxt "x86-flag"
+msgid "4 operands MAC instructions"
+msgstr ""
+
+#. /flag:tce
+#: modules/devices/x86/x86_data.c:172
+msgctxt "x86-flag"
+msgid "translation cache extension"
+msgstr ""
+
+#. /flag:nodeid_msr
+#: modules/devices/x86/x86_data.c:173
+msgctxt "x86-flag"
+msgid "NodeId MSR"
+msgstr ""
+
+#. /flag:tbm
+#: modules/devices/x86/x86_data.c:174
+msgctxt "x86-flag"
+msgid "Trailing Bit Manipulation"
+msgstr ""
+
+#. /flag:topoext
+#: modules/devices/x86/x86_data.c:175
+msgctxt "x86-flag"
+msgid "Topology Extensions CPUID leafs"
+msgstr ""
+
+#. /flag:perfctr_core
+#: modules/devices/x86/x86_data.c:176
+msgctxt "x86-flag"
+msgid "Core Performance Counter Extensions"
+msgstr ""
+
+#. /flag:perfctr_nb
+#: modules/devices/x86/x86_data.c:177
+msgctxt "x86-flag"
+msgid "NB Performance Counter Extensions"
+msgstr ""
+
+#. /flag:bpext
+#: modules/devices/x86/x86_data.c:178
+msgctxt "x86-flag"
+msgid "data breakpoint extension"
+msgstr ""
+
+#. /flag:ptsc
+#: modules/devices/x86/x86_data.c:179
+msgctxt "x86-flag"
+msgid "performance time-stamp counter"
+msgstr ""
+
+#. /flag:perfctr_l2
+#: modules/devices/x86/x86_data.c:180
+msgctxt "x86-flag"
+msgid "L2 Performance Counter Extensions"
+msgstr ""
+
+#. /flag:mwaitx
+#: modules/devices/x86/x86_data.c:181
+msgctxt "x86-flag"
+msgid "MWAIT extension (MONITORX/MWAITX)"
+msgstr ""
+
+#. /flag:cpb
+#: modules/devices/x86/x86_data.c:183
+msgctxt "x86-flag"
+msgid "AMD Core Performance Boost"
+msgstr ""
+
+#. /flag:epb
+#: modules/devices/x86/x86_data.c:184
+msgctxt "x86-flag"
+msgid "IA32_ENERGY_PERF_BIAS support"
+msgstr ""
+
+#. /flag:hw_pstate
+#: modules/devices/x86/x86_data.c:185
+msgctxt "x86-flag"
+msgid "AMD HW-PState"
+msgstr ""
+
+#. /flag:proc_feedback
+#: modules/devices/x86/x86_data.c:186
+msgctxt "x86-flag"
+msgid "AMD ProcFeedbackInterface"
+msgstr ""
+
+#. /flag:intel_pt
+#: modules/devices/x86/x86_data.c:187
+msgctxt "x86-flag"
+msgid "Intel Processor Tracing"
+msgstr ""
+
+#. /flag:tpr_shadow
+#: modules/devices/x86/x86_data.c:189
+msgctxt "x86-flag"
+msgid "Intel TPR Shadow"
+msgstr ""
+
+#. /flag:vnmi
+#: modules/devices/x86/x86_data.c:190
+msgctxt "x86-flag"
+msgid "Intel Virtual NMI"
+msgstr ""
+
+#. /flag:flexpriority
+#: modules/devices/x86/x86_data.c:191
+msgctxt "x86-flag"
+msgid "Intel FlexPriority"
+msgstr ""
+
+#. /flag:ept
+#: modules/devices/x86/x86_data.c:192
+msgctxt "x86-flag"
+msgid "Intel Extended Page Table"
+msgstr ""
+
+#. /flag:vpid
+#: modules/devices/x86/x86_data.c:193
+msgctxt "x86-flag"
+msgid "Intel Virtual Processor ID"
+msgstr ""
+
+#. /flag:vmmcall
+#: modules/devices/x86/x86_data.c:194
+msgctxt "x86-flag"
+msgid "prefer VMMCALL to VMCALL"
+msgstr ""
+
+#. /flag:fsgsbase
+#: modules/devices/x86/x86_data.c:196
+msgctxt "x86-flag"
+msgid "{RD/WR}{FS/GS}BASE instructions"
+msgstr ""
+
+#. /flag:tsc_adjust
+#: modules/devices/x86/x86_data.c:197
+msgctxt "x86-flag"
+msgid "TSC adjustment MSR"
+msgstr ""
+
+#. /flag:bmi1
+#: modules/devices/x86/x86_data.c:198
+msgctxt "x86-flag"
+msgid "1st group bit manipulation extensions"
+msgstr ""
+
+#. /flag:hle
+#: modules/devices/x86/x86_data.c:199
+msgctxt "x86-flag"
+msgid "Hardware Lock Elision"
+msgstr ""
+
+#. /flag:avx2
+#: modules/devices/x86/x86_data.c:200
+msgctxt "x86-flag"
+msgid "AVX2 instructions"
+msgstr ""
+
+#. /flag:smep
+#: modules/devices/x86/x86_data.c:201
+msgctxt "x86-flag"
+msgid "Supervisor Mode Execution Protection"
+msgstr ""
+
+#. /flag:bmi2
+#: modules/devices/x86/x86_data.c:202
+msgctxt "x86-flag"
+msgid "2nd group bit manipulation extensions"
+msgstr ""
+
+#. /flag:erms
+#: modules/devices/x86/x86_data.c:203
+msgctxt "x86-flag"
+msgid "Enhanced REP MOVSB/STOSB"
+msgstr ""
+
+#. /flag:invpcid
+#: modules/devices/x86/x86_data.c:204
+msgctxt "x86-flag"
+msgid "Invalidate Processor Context ID"
+msgstr ""
+
+#. /flag:rtm
+#: modules/devices/x86/x86_data.c:205
+msgctxt "x86-flag"
+msgid "Restricted Transactional Memory"
+msgstr ""
+
+#. /flag:cqm
+#: modules/devices/x86/x86_data.c:206
+msgctxt "x86-flag"
+msgid "Cache QoS Monitoring"
+msgstr ""
+
+#. /flag:mpx
+#: modules/devices/x86/x86_data.c:207
+msgctxt "x86-flag"
+msgid "Memory Protection Extension"
+msgstr ""
+
+#. /flag:avx512f
+#: modules/devices/x86/x86_data.c:208
+msgctxt "x86-flag"
+msgid "AVX-512 foundation"
+msgstr ""
+
+#. /flag:avx512dq
+#: modules/devices/x86/x86_data.c:209
+msgctxt "x86-flag"
+msgid "AVX-512 Double/Quad instructions"
+msgstr ""
+
+#. /flag:rdseed
+#: modules/devices/x86/x86_data.c:210
+msgctxt "x86-flag"
+msgid "The RDSEED instruction"
+msgstr ""
+
+#. /flag:adx
+#: modules/devices/x86/x86_data.c:211
+msgctxt "x86-flag"
+msgid "The ADCX and ADOX instructions"
+msgstr ""
+
+#. /flag:smap
+#: modules/devices/x86/x86_data.c:212
+msgctxt "x86-flag"
+msgid "Supervisor Mode Access Prevention"
+msgstr ""
+
+#. /flag:clflushopt
+#: modules/devices/x86/x86_data.c:213
+msgctxt "x86-flag"
+msgid "CLFLUSHOPT instruction"
+msgstr ""
+
+#. /flag:clwb
+#: modules/devices/x86/x86_data.c:214
+msgctxt "x86-flag"
+msgid "CLWB instruction"
+msgstr ""
+
+#. /flag:avx512pf
+#: modules/devices/x86/x86_data.c:215
+msgctxt "x86-flag"
+msgid "AVX-512 Prefetch"
+msgstr ""
+
+#. /flag:avx512er
+#: modules/devices/x86/x86_data.c:216
+msgctxt "x86-flag"
+msgid "AVX-512 Exponential and Reciprocal"
+msgstr ""
+
+#. /flag:avx512cd
+#: modules/devices/x86/x86_data.c:217
+msgctxt "x86-flag"
+msgid "AVX-512 Conflict Detection"
+msgstr ""
+
+#. /flag:sha_ni
+#: modules/devices/x86/x86_data.c:218
+msgctxt "x86-flag"
+msgid "SHA1/SHA256 Instruction Extensions"
+msgstr ""
+
+#. /flag:avx512bw
+#: modules/devices/x86/x86_data.c:219
+msgctxt "x86-flag"
+msgid "AVX-512 Byte/Word instructions"
+msgstr ""
+
+#. /flag:avx512vl
+#: modules/devices/x86/x86_data.c:220
+msgctxt "x86-flag"
+msgid "AVX-512 128/256 Vector Length extensions"
+msgstr ""
+
+#. /flag:xsaveopt
+#: modules/devices/x86/x86_data.c:222
+msgctxt "x86-flag"
+msgid "Optimized XSAVE"
+msgstr ""
+
+#. /flag:xsavec
+#: modules/devices/x86/x86_data.c:223
+msgctxt "x86-flag"
+msgid "XSAVEC"
+msgstr ""
+
+#. /flag:xgetbv1
+#: modules/devices/x86/x86_data.c:224
+msgctxt "x86-flag"
+msgid "XGETBV with ECX = 1"
+msgstr ""
+
+#. /flag:xsaves
+#: modules/devices/x86/x86_data.c:225
+msgctxt "x86-flag"
+msgid "XSAVES/XRSTORS"
+msgstr ""
+
+#. /flag:cqm_llc
+#: modules/devices/x86/x86_data.c:227
+msgctxt "x86-flag"
+msgid "LLC QoS"
+msgstr ""
+
+#. /flag:cqm_occup_llc
+#: modules/devices/x86/x86_data.c:229
+msgctxt "x86-flag"
+msgid "LLC occupancy monitoring"
+msgstr ""
+
+#. /flag:cqm_mbm_total
+#: modules/devices/x86/x86_data.c:230
+msgctxt "x86-flag"
+msgid "LLC total MBM monitoring"
+msgstr ""
+
+#. /flag:cqm_mbm_local
+#: modules/devices/x86/x86_data.c:231
+msgctxt "x86-flag"
+msgid "LLC local MBM monitoring"
+msgstr ""
+
+#. /flag:clzero
+#: modules/devices/x86/x86_data.c:233
+msgctxt "x86-flag"
+msgid "CLZERO instruction"
+msgstr ""
+
+#. /flag:irperf
+#: modules/devices/x86/x86_data.c:234
+msgctxt "x86-flag"
+msgid "instructions retired performance counter"
+msgstr ""
+
+#. /flag:dtherm
+#: modules/devices/x86/x86_data.c:236
+msgctxt "x86-flag"
+msgid "digital thermal sensor"
+msgstr ""
+
+#. /flag:ida
+#: modules/devices/x86/x86_data.c:237
+msgctxt "x86-flag"
+msgid "Intel Dynamic Acceleration"
+msgstr ""
+
+#. /flag:arat
+#: modules/devices/x86/x86_data.c:238
+msgctxt "x86-flag"
+msgid "Always Running APIC Timer"
+msgstr ""
+
+#. /flag:pln
+#: modules/devices/x86/x86_data.c:239
+msgctxt "x86-flag"
+msgid "Intel Power Limit Notification"
+msgstr ""
+
+#. /flag:pts
+#: modules/devices/x86/x86_data.c:240
+msgctxt "x86-flag"
+msgid "Intel Package Thermal Status"
+msgstr ""
+
+#. /flag:hwp
+#: modules/devices/x86/x86_data.c:241
+msgctxt "x86-flag"
+msgid "Intel Hardware P-states"
+msgstr ""
+
+#. /flag:hwp_notify
+#: modules/devices/x86/x86_data.c:242
+msgctxt "x86-flag"
+msgid "HWP notification"
+msgstr ""
+
+#. /flag:hwp_act_window
+#: modules/devices/x86/x86_data.c:243
+msgctxt "x86-flag"
+msgid "HWP Activity Window"
+msgstr ""
+
+#. /flag:hwp_epp
+#: modules/devices/x86/x86_data.c:244
+msgctxt "x86-flag"
+msgid "HWP Energy Performance Preference"
+msgstr ""
+
+#. /flag:hwp_pkg_req
+#: modules/devices/x86/x86_data.c:245
+msgctxt "x86-flag"
+msgid "HWP package-level request"
+msgstr ""
+
+#. /flag:npt
+#: modules/devices/x86/x86_data.c:247
+msgctxt "x86-flag"
+msgid "AMD Nested Page Table support"
+msgstr ""
+
+#. /flag:lbrv
+#: modules/devices/x86/x86_data.c:248
+msgctxt "x86-flag"
+msgid "AMD LBR Virtualization support"
+msgstr ""
+
+#. /flag:svm_lock
+#: modules/devices/x86/x86_data.c:249
+msgctxt "x86-flag"
+msgid "AMD SVM locking MSR"
+msgstr ""
+
+#. /flag:nrip_save
+#: modules/devices/x86/x86_data.c:250
+msgctxt "x86-flag"
+msgid "AMD SVM next_rip save"
+msgstr ""
+
+#. /flag:tsc_scale
+#: modules/devices/x86/x86_data.c:251
+msgctxt "x86-flag"
+msgid "AMD TSC scaling support"
+msgstr ""
+
+#. /flag:vmcb_clean
+#: modules/devices/x86/x86_data.c:252
+msgctxt "x86-flag"
+msgid "AMD VMCB clean bits support"
+msgstr ""
+
+#. /flag:flushbyasid
+#: modules/devices/x86/x86_data.c:253
+msgctxt "x86-flag"
+msgid "AMD flush-by-ASID support"
+msgstr ""
+
+#. /flag:decodeassists
+#: modules/devices/x86/x86_data.c:254
+msgctxt "x86-flag"
+msgid "AMD Decode Assists support"
+msgstr ""
+
+#. /flag:pausefilter
+#: modules/devices/x86/x86_data.c:255
+msgctxt "x86-flag"
+msgid "AMD filtered pause intercept"
+msgstr ""
+
+#. /flag:pfthreshold
+#: modules/devices/x86/x86_data.c:256
+msgctxt "x86-flag"
+msgid "AMD pause filter threshold"
+msgstr ""
+
+#. /flag:avic
+#: modules/devices/x86/x86_data.c:257
+msgctxt "x86-flag"
+msgid "Virtual Interrupt Controller"
+msgstr ""
+
+#. /flag:pku
+#: modules/devices/x86/x86_data.c:259
+msgctxt "x86-flag"
+msgid "Protection Keys for Userspace"
+msgstr ""
+
+#. /flag:ospke
+#: modules/devices/x86/x86_data.c:260
+msgctxt "x86-flag"
+msgid "OS Protection Keys Enable"
+msgstr ""
+
+#. /flag:overflow_recov
+#: modules/devices/x86/x86_data.c:262
+msgctxt "x86-flag"
+msgid "MCA overflow recovery support"
+msgstr ""
+
+#. /flag:succor
+#: modules/devices/x86/x86_data.c:263
+msgctxt "x86-flag"
+msgid "uncorrectable error containment and recovery"
+msgstr ""
+
+#. /flag:smca
+#: modules/devices/x86/x86_data.c:264
+msgctxt "x86-flag"
+msgid "Scalable MCA"
+msgstr ""
+
+#. /bug:f00f
+#: modules/devices/x86/x86_data.c:267
+msgctxt "x86-flag"
+msgid "Intel F00F bug"
+msgstr ""
+
+#. /bug:fdiv
+#: modules/devices/x86/x86_data.c:268
+msgctxt "x86-flag"
+msgid "FPU FDIV"
+msgstr ""
+
+#. /bug:coma
+#: modules/devices/x86/x86_data.c:269
+msgctxt "x86-flag"
+msgid "Cyrix 6x86 coma"
+msgstr ""
+
+#. /bug:tlb_mmatch
+#: modules/devices/x86/x86_data.c:270
+msgctxt "x86-flag"
+msgid "AMD Erratum 383"
+msgstr ""
+
+#. /bug:apic_c1e
+#. /bug:amd_e400
+#: modules/devices/x86/x86_data.c:271 modules/devices/x86/x86_data.c:280
+msgctxt "x86-flag"
+msgid "AMD Erratum 400"
+msgstr ""
+
+#. /bug:11ap
+#: modules/devices/x86/x86_data.c:272
+msgctxt "x86-flag"
+msgid "Bad local APIC aka 11AP"
+msgstr ""
+
+#. /bug:fxsave_leak
+#: modules/devices/x86/x86_data.c:273
+msgctxt "x86-flag"
+msgid "FXSAVE leaks FOP/FIP/FOP"
+msgstr ""
+
+#. /bug:clflush_monitor
+#: modules/devices/x86/x86_data.c:274
+msgctxt "x86-flag"
+msgid "AAI65, CLFLUSH required before MONITOR"
+msgstr ""
+
+#. /bug:sysret_ss_attrs
+#: modules/devices/x86/x86_data.c:275
+msgctxt "x86-flag"
+msgid "SYSRET doesn't fix up SS attrs"
+msgstr ""
+
+#. /bug:espfix
+#: modules/devices/x86/x86_data.c:276
+msgctxt "x86-flag"
+msgid "IRET to 16-bit SS corrupts ESP/RSP high bits"
+msgstr ""
+
+#. /bug:null_seg
+#: modules/devices/x86/x86_data.c:277
+msgctxt "x86-flag"
+msgid "Nulling a selector preserves the base"
+msgstr ""
+
+#. /bug:swapgs_fence
+#: modules/devices/x86/x86_data.c:278
+msgctxt "x86-flag"
+msgid "SWAPGS without input dep on GS"
+msgstr ""
+
+#. /bug:monitor
+#: modules/devices/x86/x86_data.c:279
+msgctxt "x86-flag"
+msgid "IPI required to wake up remote CPU"
+msgstr ""
+
+#. /x86/kernel/cpu/powerflags.h
+#. /flag:pm:ts
+#: modules/devices/x86/x86_data.c:283
+msgctxt "x86-flag"
+msgid "temperature sensor"
+msgstr ""
+
+#. /flag:pm:fid
+#: modules/devices/x86/x86_data.c:284
+msgctxt "x86-flag"
+msgid "frequency id control"
+msgstr ""
+
+#. /flag:pm:vid
+#: modules/devices/x86/x86_data.c:285
+msgctxt "x86-flag"
+msgid "voltage id control"
+msgstr ""
+
+#. /flag:pm:ttp
+#: modules/devices/x86/x86_data.c:286
+msgctxt "x86-flag"
+msgid "thermal trip"
+msgstr ""
+
+#. /flag:pm:tm
+#: modules/devices/x86/x86_data.c:287
+msgctxt "x86-flag"
+msgid "hardware thermal control"
+msgstr ""
+
+#. /flag:pm:stc
+#: modules/devices/x86/x86_data.c:288
+msgctxt "x86-flag"
+msgid "software thermal control"
+msgstr ""
+
+#. /flag:pm:100mhzsteps
+#: modules/devices/x86/x86_data.c:289
+msgctxt "x86-flag"
+msgid "100 MHz multiplier control"
+msgstr ""
+
+#. /flag:pm:hwpstate
+#: modules/devices/x86/x86_data.c:290
+msgctxt "x86-flag"
+msgid "hardware P-state control"
+msgstr ""
+
+#. /flag:pm:cpb
+#: modules/devices/x86/x86_data.c:291
+msgctxt "x86-flag"
+msgid "core performance boost"
+msgstr ""
+
+#. /flag:pm:eff_freq_ro
+#: modules/devices/x86/x86_data.c:292
+msgctxt "x86-flag"
+msgid "Readonly aperf/mperf"
+msgstr ""
+
+#. /flag:pm:proc_feedback
+#: modules/devices/x86/x86_data.c:293
+msgctxt "x86-flag"
+msgid "processor feedback interface"
+msgstr ""
+
+#. /flag:pm:acc_power
+#: modules/devices/x86/x86_data.c:294
+msgctxt "x86-flag"
+msgid "accumulated power mechanism"
+msgstr ""
+
+#: modules/network.c:59
+msgid "Interfaces"
+msgstr ""
+
+#: modules/network.c:60
+msgid "IP Connections"
+msgstr ""
+
+#: modules/network.c:61
+msgid "Routing Table"
+msgstr ""
+
+#: modules/network.c:62 modules/network.c:303
+msgid "ARP Table"
+msgstr ""
+
+#: modules/network.c:63
+msgid "DNS Servers"
+msgstr ""
+
+#: modules/network.c:64
+msgid "Statistics"
+msgstr ""
+
+#: modules/network.c:65
+msgid "Shared Directories"
+msgstr ""
+
+#: modules/network.c:304 modules/network.c:326 modules/network.c:357
+#: modules/network/net.c:477
+msgid "IP Address"
+msgstr ""
+
+#: modules/network.c:304 modules/network.c:357 modules/network.c:374
+msgid "Interface"
+msgstr ""
+
+#: modules/network.c:304
+msgid "MAC Address"
+msgstr ""
+
+#: modules/network.c:313
+msgid "SAMBA"
+msgstr ""
+
+#: modules/network.c:314
+msgid "NFS"
+msgstr ""
+
+#: modules/network.c:325
+msgid "Name Servers"
+msgstr ""
+
+#: modules/network.c:340
+msgid "Connections"
+msgstr ""
+
+#: modules/network.c:341
+msgid "Local Address"
+msgstr ""
+
+#: modules/network.c:341
+msgid "Protocol"
+msgstr ""
+
+#: modules/network.c:341
+msgid "Foreign Address"
+msgstr ""
+
+#: modules/network.c:341
+msgid "State"
+msgstr ""
+
+#: modules/network.c:357
+msgid "Sent"
+msgstr ""
+
+#: modules/network.c:357
+msgid "Received"
+msgstr ""
+
+#: modules/network.c:373
+msgid "IP routing table"
+msgstr ""
+
+#: modules/network.c:374
+msgid "Destination/Gateway"
+msgstr ""
+
+#: modules/network.c:374
+msgid "Flags"
+msgstr ""
+
+#: modules/network.c:374 modules/network/net.c:478
+msgid "Mask"
+msgstr ""
+
+#: modules/network.c:402
+msgid "Network"
+msgstr ""
+
+#: modules/network.c:435
+msgid "Gathers information about this computer's network connection"
+msgstr ""
+
+#: modules/network/net.c:72
+msgctxt "wi-op-mode"
+msgid "Auto"
+msgstr ""
+
+#: modules/network/net.c:73
+msgctxt "wi-op-mode"
+msgid "Ad-Hoc"
+msgstr ""
+
+#: modules/network/net.c:74
+msgctxt "wi-op-mode"
+msgid "Managed"
+msgstr ""
+
+#: modules/network/net.c:75
+msgctxt "wi-op-mode"
+msgid "Master"
+msgstr ""
+
+#: modules/network/net.c:76
+msgctxt "wi-op-mode"
+msgid "Repeater"
+msgstr ""
+
+#: modules/network/net.c:77
+msgctxt "wi-op-mode"
+msgid "Secondary"
+msgstr ""
+
+#: modules/network/net.c:78
+msgctxt "wi-op-mode"
+msgid "(Unknown)"
+msgstr ""
+
+#: modules/network/net.c:242 modules/network/net.c:262
+#: modules/network/net.c:270
+msgctxt "net-if-type"
+msgid "Ethernet"
+msgstr ""
+
+#: modules/network/net.c:243
+msgctxt "net-if-type"
+msgid "Loopback"
+msgstr ""
+
+#: modules/network/net.c:244
+msgctxt "net-if-type"
+msgid "Point-to-Point"
+msgstr ""
+
+#: modules/network/net.c:245 modules/network/net.c:246
+#: modules/network/net.c:247 modules/network/net.c:248
+#: modules/network/net.c:272
+msgctxt "net-if-type"
+msgid "Wireless"
+msgstr ""
+
+#: modules/network/net.c:249
+msgctxt "net-if-type"
+msgid "Virtual Point-to-Point (TUN)"
+msgstr ""
+
+#: modules/network/net.c:250
+msgctxt "net-if-type"
+msgid "Ethernet (TAP)"
+msgstr ""
+
+#: modules/network/net.c:251
+msgctxt "net-if-type"
+msgid "Parallel Line Internet Protocol"
+msgstr ""
+
+#: modules/network/net.c:252
+msgctxt "net-if-type"
+msgid "Infrared"
+msgstr ""
+
+#: modules/network/net.c:253 modules/network/net.c:271
+msgctxt "net-if-type"
+msgid "Serial Line Internet Protocol"
+msgstr ""
+
+#: modules/network/net.c:254
+msgctxt "net-if-type"
+msgid "Integrated Services Digital Network"
+msgstr ""
+
+#: modules/network/net.c:255
+msgctxt "net-if-type"
+msgid "IPv6-over-IPv4 Tunnel"
+msgstr ""
+
+#: modules/network/net.c:256
+msgctxt "net-if-type"
+msgid "VMWare Virtual Network Interface (NAT)"
+msgstr ""
+
+#: modules/network/net.c:257
+msgctxt "net-if-type"
+msgid "VMWare Virtual Network Interface"
+msgstr ""
+
+#: modules/network/net.c:258
+msgctxt "net-if-type"
+msgid "Personal Area Network (PAN)"
+msgstr ""
+
+#: modules/network/net.c:259
+msgctxt "net-if-type"
+msgid "Bluetooth"
+msgstr ""
+
+#: modules/network/net.c:260
+msgctxt "net-if-type"
+msgid "Bridge Interface"
+msgstr ""
+
+#: modules/network/net.c:261
+msgctxt "net-if-type"
+msgid "Hamachi Virtual Personal Network"
+msgstr ""
+
+#: modules/network/net.c:263
+msgctxt "net-if-type"
+msgid "Intermediate Functional Block"
+msgstr ""
+
+#: modules/network/net.c:264
+msgctxt "net-if-type"
+msgid "GRE Network Tunnel"
+msgstr ""
+
+#: modules/network/net.c:265
+msgctxt "net-if-type"
+msgid "Mesh Network"
+msgstr ""
+
+#: modules/network/net.c:266
+msgctxt "net-if-type"
+msgid "Wireless Master Interface"
+msgstr ""
+
+#: modules/network/net.c:267
+msgctxt "net-if-type"
+msgid "VirtualBox Virtual Network Interface"
+msgstr ""
+
+#: modules/network/net.c:273
+msgctxt "net-if-type"
+msgid "Wireless (WAN)"
+msgstr ""
+
+#: modules/network/net.c:275
+msgctxt "net-if-type"
+msgid "(Unknown)"
+msgstr ""
+
+#: modules/network/net.c:348 modules/network/net.c:358
+msgid "Network Interfaces"
+msgstr ""
+
+#: modules/network/net.c:348
+msgid "None Found"
+msgstr ""
+
+#: modules/network/net.c:400 modules/network/net.c:422
+#: modules/network/net.c:423
+msgid "MiB"
+msgstr ""
+
+#: modules/network/net.c:414
+msgid "Network Adapter Properties"
+msgstr ""
+
+#: modules/network/net.c:415
+msgid "Interface Type"
+msgstr ""
+
+#: modules/network/net.c:416
+msgid "Hardware Address (MAC)"
+msgstr ""
+
+#: modules/network/net.c:420
+msgid "MTU"
+msgstr ""
+
+#: modules/network/net.c:421
+msgid "Transfer Details"
+msgstr ""
+
+#: modules/network/net.c:422
+msgid "Bytes Received"
+msgstr ""
+
+#: modules/network/net.c:423
+msgid "Bytes Sent"
+msgstr ""
+
+#: modules/network/net.c:440 modules/network/net.c:462
+#: modules/network/net.c:463
+msgid "dBm"
+msgstr ""
+
+#: modules/network/net.c:440
+msgid "mW"
+msgstr ""
+
+#: modules/network/net.c:454
+msgid "Wireless Properties"
+msgstr ""
+
+#: modules/network/net.c:455
+msgid "Network Name (SSID)"
+msgstr ""
+
+#: modules/network/net.c:456
+msgid "Bit Rate"
+msgstr ""
+
+#: modules/network/net.c:456
+msgid "Mb/s"
+msgstr ""
+
+#: modules/network/net.c:457
+msgid "Transmission Power"
+msgstr ""
+
+#: modules/network/net.c:459
+msgid "Status"
+msgstr ""
+
+#: modules/network/net.c:460
+msgid "Link Quality"
+msgstr ""
+
+#: modules/network/net.c:461
+msgid "Signal / Noise"
+msgstr ""
+
+#: modules/network/net.c:476
+msgid "Internet Protocol (IPv4)"
+msgstr ""
+
+#: modules/network/net.c:477 modules/network/net.c:478
+#: modules/network/net.c:480
+msgid "(Not set)"
+msgstr ""
+
+#: modules/network/net.c:479
+msgid "Broadcast Address"
+msgstr ""
diff --git a/po/ru.po b/po/ru.po
new file mode 100644
index 0000000..3cb4862
--- /dev/null
+++ b/po/ru.po
@@ -0,0 +1,4618 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: hardinfo\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2017-11-03 05:49+0300\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Sergey Rodin <rodin.s@rambler.ru>\n"
+"Language-Team: \n"
+"Language: ru_UA\n"
+"X-Poedit-Basepath: ../\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Russian\n"
+"X-Poedit-Country: UKRAINE\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+
+#: hardinfo/cpu_util.c:30
+msgid "Little Endian"
+msgstr ""
+
+#: hardinfo/cpu_util.c:32
+msgid "Big Endian"
+msgstr ""
+
+#: hardinfo/cpu_util.c:178 hardinfo/cpu_util.c:189
+msgid "Frequency Scaling"
+msgstr "Масштабирование частоты"
+
+#: hardinfo/cpu_util.c:179
+msgid "Minimum"
+msgstr "Минимальная"
+
+#: hardinfo/cpu_util.c:179 hardinfo/cpu_util.c:180 hardinfo/cpu_util.c:181
+msgid "kHz"
+msgstr "кГц"
+
+#: hardinfo/cpu_util.c:180
+msgid "Maximum"
+msgstr "Максимальная"
+
+#: hardinfo/cpu_util.c:181
+msgid "Current"
+msgstr "Текущая"
+
+#: hardinfo/cpu_util.c:182
+msgid "Transition Latency"
+msgstr "Задержка перехода"
+
+#: hardinfo/cpu_util.c:182
+msgid "ns"
+msgstr "нс"
+
+#: hardinfo/cpu_util.c:183
+msgid "Governor"
+msgstr "Регулятор"
+
+#: hardinfo/cpu_util.c:184 hardinfo/cpu_util.c:190
+msgid "Driver"
+msgstr "Драйвер"
+
+#: hardinfo/cpu_util.c:196 modules/devices/x86/processor.c:297
+msgid "(Not Available)"
+msgstr "(Недоступно)"
+
+#: hardinfo/cpu_util.c:204 hardinfo/cpu_util.c:206
+msgid "Socket"
+msgstr "Сокет"
+
+#: hardinfo/cpu_util.c:209 hardinfo/cpu_util.c:211
+msgid "Core"
+msgstr "Ядро"
+
+#: hardinfo/cpu_util.c:214
+msgid "Book"
+msgstr "Книга"
+
+#: hardinfo/cpu_util.c:216
+msgid "Drawer"
+msgstr "Трассировщик"
+
+#: hardinfo/cpu_util.c:222 modules/devices/arm/processor.c:356
+msgid "Topology"
+msgstr "Топология"
+
+#: hardinfo/cpu_util.c:223
+msgid "ID"
+msgstr ""
+
+#: hardinfo/dmi_util.c:114
+msgid "Invalid chassis type (0)"
+msgstr ""
+
+#: hardinfo/dmi_util.c:115 hardinfo/dmi_util.c:116
+msgid "Unknown chassis type"
+msgstr ""
+
+#: hardinfo/dmi_util.c:117
+msgid "Desktop"
+msgstr "Настольный компьютер"
+
+#: hardinfo/dmi_util.c:118
+msgid "Low-profile Desktop"
+msgstr "Низкопрофильный компьютер"
+
+#: hardinfo/dmi_util.c:119
+msgid "Pizza Box"
+msgstr ""
+
+#: hardinfo/dmi_util.c:120
+msgid "Mini Tower"
+msgstr ""
+
+#: hardinfo/dmi_util.c:121
+msgid "Tower"
+msgstr ""
+
+#: hardinfo/dmi_util.c:122
+msgid "Portable"
+msgstr "Портативный компьютер"
+
+#: hardinfo/dmi_util.c:123 modules/computer.c:326 modules/computer.c:335
+#: modules/computer.c:357
+msgid "Laptop"
+msgstr ""
+
+#: hardinfo/dmi_util.c:124
+msgid "Notebook"
+msgstr ""
+
+#: hardinfo/dmi_util.c:125
+msgid "Handheld"
+msgstr ""
+
+#: hardinfo/dmi_util.c:126
+msgid "Docking Station"
+msgstr ""
+
+#: hardinfo/dmi_util.c:127
+msgid "All-in-one"
+msgstr ""
+
+#: hardinfo/dmi_util.c:128
+msgid "Subnotebook"
+msgstr ""
+
+#: hardinfo/dmi_util.c:129
+msgid "Space-saving"
+msgstr ""
+
+#: hardinfo/dmi_util.c:130
+msgid "Lunch Box"
+msgstr ""
+
+#: hardinfo/dmi_util.c:131
+msgid "Main Server Chassis"
+msgstr ""
+
+#: hardinfo/dmi_util.c:132
+msgid "Expansion Chassis"
+msgstr ""
+
+#: hardinfo/dmi_util.c:133
+msgid "Sub Chassis"
+msgstr ""
+
+#: hardinfo/dmi_util.c:134
+msgid "Bus Expansion Chassis"
+msgstr ""
+
+#: hardinfo/dmi_util.c:135
+msgid "Peripheral Chassis"
+msgstr ""
+
+#: hardinfo/dmi_util.c:136
+msgid "RAID Chassis"
+msgstr ""
+
+#: hardinfo/dmi_util.c:137
+msgid "Rack Mount Chassis"
+msgstr ""
+
+#: hardinfo/dmi_util.c:138
+msgid "Sealed-case PC"
+msgstr ""
+
+#: hardinfo/dt_util.c:1013
+msgid "phandle Map"
+msgstr ""
+
+#: hardinfo/dt_util.c:1014
+msgid "Alias Map"
+msgstr ""
+
+#: hardinfo/dt_util.c:1015
+msgid "Symbol Map"
+msgstr ""
+
+#. / %d will be latest year of copyright
+#: hardinfo/hardinfo.c:49
+#, c-format
+msgid ""
+"Copyright (C) 2003-%d Leandro A. F. Pereira. See COPYING for details.\n"
+"\n"
+msgstr ""
+"Copyright (C) 2003-%d Leandro A. F. Pereira. Смотрите файл COPYING для более "
+"подробной информации.\n"
+"\n"
+
+#: hardinfo/hardinfo.c:51
+#, c-format
+msgid ""
+"Compile-time options:\n"
+"  Release version:   %s (%s)\n"
+"  BinReloc enabled:  %s\n"
+"  Data prefix:       %s\n"
+"  Library prefix:    %s\n"
+"  Compiled for:      %s\n"
+msgstr ""
+"Настройки компиляции:\n"
+"  Release version:    %s (%s)\n"
+"  BinReloc включен:   %s\n"
+"  Префикс данных:     %s\n"
+"  Префикс библиотеки: %s\n"
+"  Скомпилировано на:  %s\n"
+
+#: hardinfo/hardinfo.c:57 hardinfo/hardinfo.c:58 modules/computer.c:595
+#: modules/devices/inputdevices.c:128 modules/devices/pci.c:112
+#: modules/devices/printers.c:138
+msgid "Yes"
+msgstr "Да"
+
+#: hardinfo/hardinfo.c:58 modules/computer.c:595 modules/devices/pci.c:112
+#: modules/devices/printers.c:138
+msgid "No"
+msgstr "Нет"
+
+#: hardinfo/hardinfo.c:69
+#, c-format
+msgid ""
+"Failed to find runtime data.\n"
+"\n"
+"• Is HardInfo correctly installed?\n"
+"• See if %s and %s exists and you have read permission."
+msgstr ""
+"Не удалось найти данные среды выполнения.\n"
+"\n"
+"• Правильно ли установлен HardInfo?\n"
+"• Проверьте, существуют ли %s и %s и есть ли у вас право на чтение."
+
+#: hardinfo/hardinfo.c:76
+#, c-format
+msgid ""
+"Modules:\n"
+"%-20s %-15s %-12s\n"
+msgstr ""
+"Модули:\n"
+"%-20s %-15s %-12s\n"
+
+#: hardinfo/hardinfo.c:77
+msgid "File Name"
+msgstr "Имя файла"
+
+#: hardinfo/hardinfo.c:77 modules/computer.c:524 modules/computer.c:552
+#: modules/computer.c:620 modules/computer/languages.c:104
+#: modules/computer/modules.c:146 modules/devices/arm/processor.c:354
+#: modules/devices/dmi.c:37 modules/devices/dmi.c:46
+#: modules/devices/ia64/processor.c:160 modules/devices/inputdevices.c:116
+#: modules/devices/pci.c:215 modules/devices/sh/processor.c:84
+#: modules/devices/x86/processor.c:455 modules/network.c:326
+msgid "Name"
+msgstr "Название"
+
+#: hardinfo/hardinfo.c:77 modules/computer.c:300 modules/computer.c:495
+#: modules/computer.c:497 modules/computer.c:584 modules/computer.c:593
+#: modules/devices/dmi.c:40 modules/devices/dmi.c:44 modules/devices/dmi.c:48
+#: modules/devices/dmi.c:54 modules/devices/inputdevices.c:121
+msgid "Version"
+msgstr "Версия"
+
+#: hardinfo/hardinfo.c:124
+#, c-format
+msgid "Unknown benchmark ``%s'' or libbenchmark.so not loaded"
+msgstr "Тест ``%s'' неизвестен или библиотека libbenchmark.so не загружена"
+
+#: hardinfo/hardinfo.c:152
+msgid "Don't know what to do. Exiting."
+msgstr "Неизвестно, что делать. Выход."
+
+#: hardinfo/util.c:104 modules/computer/uptime.c:54
+#, c-format
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] "%d день"
+msgstr[1] "%d дня"
+msgstr[2] "%d дней"
+
+#: hardinfo/util.c:105 modules/computer/uptime.c:55
+#, c-format
+msgid "%d hour"
+msgid_plural "%d hours"
+msgstr[0] "%d час"
+msgstr[1] "%d часа"
+msgstr[2] "%d часов"
+
+#: hardinfo/util.c:106 modules/computer/uptime.c:56
+#, c-format
+msgid "%d minute"
+msgid_plural "%d minutes"
+msgstr[0] "%d минута"
+msgstr[1] "%d минуты"
+msgstr[2] "%d минут"
+
+#: hardinfo/util.c:107
+#, c-format
+msgid "%d second"
+msgid_plural "%d seconds"
+msgstr[0] "секунда"
+msgstr[1] "секунды"
+msgstr[2] "секунд"
+
+#: hardinfo/util.c:128
+#, c-format
+msgid "%.1f B"
+msgstr "%.1f Б"
+
+#: hardinfo/util.c:130
+#, c-format
+msgid "%.1f KiB"
+msgstr "%.1f КиБ"
+
+#: hardinfo/util.c:132
+#, c-format
+msgid "%.1f MiB"
+msgstr "%.1f МиБ"
+
+#: hardinfo/util.c:134
+#, c-format
+msgid "%.1f GiB"
+msgstr "%.1f ГиБ"
+
+#: hardinfo/util.c:136
+#, c-format
+msgid "%.1f TiB"
+msgstr "%.1f ТиБ"
+
+#: hardinfo/util.c:138
+#, c-format
+msgid "%.1f PiB"
+msgstr "%.1f ПиБ"
+
+#: hardinfo/util.c:361
+msgid "Error"
+msgstr "Ошибка"
+
+#: hardinfo/util.c:361 hardinfo/util.c:377
+msgid "Warning"
+msgstr "Предупреждение"
+
+#: hardinfo/util.c:376
+msgid "Fatal Error"
+msgstr "Фатальная ошибка"
+
+#: hardinfo/util.c:401
+msgid "creates a report and prints to standard output"
+msgstr "создаёт отчёт и выводит на стандартный вывод"
+
+#: hardinfo/util.c:407
+msgid "chooses a report format (text, html)"
+msgstr "выбирает формат отчёта (text, html)"
+
+#: hardinfo/util.c:413
+msgid "run benchmark; requires benchmark.so to be loaded"
+msgstr "запуск теста; требует, чтобы benchmark.so был загружен"
+
+#: hardinfo/util.c:419
+msgid "lists modules"
+msgstr "список модулей"
+
+#: hardinfo/util.c:425
+msgid "specify module to load"
+msgstr "укажите модуль для загрузки"
+
+#: hardinfo/util.c:431
+msgid "automatically load module dependencies"
+msgstr "автоматически загружает зависимости модулей"
+
+#: hardinfo/util.c:438
+msgid "run in XML-RPC server mode"
+msgstr "запуск в режиме сервера XML-RPC"
+
+#: hardinfo/util.c:445
+msgid "shows program version and quit"
+msgstr "показывает версию программы и выходит"
+
+#: hardinfo/util.c:450
+msgid "- System Profiler and Benchmark tool"
+msgstr "- Инструмент для тестирования и проверки свойств системы"
+
+#: hardinfo/util.c:460
+#, c-format
+msgid ""
+"Unrecognized arguments.\n"
+"Try ``%s --help'' for more information.\n"
+msgstr ""
+"Неизвестные аргументы.\n"
+"Используйте `%s --help' для справки.\n"
+
+#: hardinfo/util.c:526
+#, c-format
+msgid "Couldn't find a Web browser to open URL %s."
+msgstr "Не удаётся найти веб-браузер для открытия URL %s."
+
+#: hardinfo/util.c:875
+#, c-format
+msgid "Module \"%s\" depends on module \"%s\", load it?"
+msgstr "Модуль \"%s\" зависит от модуля \"%s\", загрузить его?"
+
+#: hardinfo/util.c:898
+#, c-format
+msgid "Module \"%s\" depends on module \"%s\"."
+msgstr "Модуль \"%s\" зависит от модуля \"%s\"."
+
+#: hardinfo/util.c:943
+#, c-format
+msgid "No module could be loaded. Check permissions on \"%s\" and try again."
+msgstr ""
+"Модули не могут быть загружены. Проверьте разрешения на \"%s\" и попробуйте "
+"снова."
+
+#: hardinfo/util.c:947
+msgid ""
+"No module could be loaded. Please use hardinfo -l to list all available "
+"modules and try again with a valid module list."
+msgstr ""
+"Не удается загрузить модули. Пожалуйста, используйте hardinfo -l для "
+"получения списка доступных модулей и попробуйте снова с правильным списком "
+"модулей."
+
+#: hardinfo/util.c:1024
+#, c-format
+msgid "Scanning: %s..."
+msgstr "Сканирование: %s..."
+
+#: hardinfo/util.c:1034 shell/shell.c:301 shell/shell.c:772 shell/shell.c:1850
+#: modules/benchmark.c:505 modules/benchmark.c:513
+msgid "Done."
+msgstr "Выполнено."
+
+#: shell/callbacks.c:128
+#, c-format
+msgid ""
+"Written by %s\n"
+"Licensed under %s"
+msgstr ""
+"Автор программы %s\n"
+"Лицензия %s"
+
+#: shell/callbacks.c:142
+#, c-format
+msgid "No about information is associated with the %s module."
+msgstr "Нет информации о модуле %s."
+
+#: shell/callbacks.c:158
+msgid "Author:"
+msgstr "Автор:"
+
+#: shell/callbacks.c:161
+msgid "Contributors:"
+msgstr "Участники:"
+
+#: shell/callbacks.c:166
+msgid "Based on work by:"
+msgstr "Основан на работах:"
+
+#: shell/callbacks.c:167
+msgid "MD5 implementation by Colin Plumb (see md5.c for details)"
+msgstr "Реализация MD5 от Colin Plumb (см. подробности в md5.c)"
+
+#: shell/callbacks.c:168
+msgid "SHA1 implementation by Steve Reid (see sha1.c for details)"
+msgstr "Реализация SHA1 от Steve Reid (см. подробности в sha1.c) "
+
+#: shell/callbacks.c:169
+msgid "Blowfish implementation by Paul Kocher (see blowfich.c for details)"
+msgstr "Реализация Blowfish от Paul Kocher (см. подробности в blowfich.c)"
+
+#: shell/callbacks.c:170
+msgid "Raytracing benchmark by John Walker (see fbench.c for details)"
+msgstr "Тест Raytracing от John Walker (см. подробности в fbench.c)"
+
+#: shell/callbacks.c:171
+msgid "FFT benchmark by Scott Robert Ladd (see fftbench.c for details)"
+msgstr "Тест FFT Скотта от Robert Ladd (см. подробности в fbench.c)"
+
+#: shell/callbacks.c:172
+msgid "Some code partly based on x86cpucaps by Osamu Kayasono"
+msgstr "Часть кода основана на x86cpucaps от Osamu Kayasono"
+
+#: shell/callbacks.c:173
+msgid "Vendor list based on GtkSysInfo by Pissens Sebastien"
+msgstr "Список поставщиков основан на GtkSysInfo от Pissens Sebastien"
+
+#: shell/callbacks.c:174
+msgid "DMI support based on code by Stewart Adam"
+msgstr "Поддержка DMI основана на коде от Stewart Adam"
+
+#: shell/callbacks.c:175
+msgid "SCSI support based on code by Pascal F. Martin"
+msgstr "Поддержка SCSI основана на коде от Pascal F. Martin"
+
+#: shell/callbacks.c:180
+msgid "Tango Project"
+msgstr "Проект Tango"
+
+#: shell/callbacks.c:181
+msgid "The GNOME Project"
+msgstr "Проект GNOME"
+
+#: shell/callbacks.c:182
+msgid "VMWare, Inc. (USB icon from VMWare Workstation 6)"
+msgstr "VMWare, Inc. (значок USB из VMWare Workstation 6)"
+
+#: shell/callbacks.c:200
+msgid "System information and benchmark tool"
+msgstr "Информация о системе и тестирование"
+
+#: shell/callbacks.c:205
+msgid ""
+"HardInfo is free software; you can redistribute it and/or modify it under "
+"the terms of the GNU General Public License as published by the Free "
+"Software Foundation, version 2.\n"
+"\n"
+"This program is distributed in the hope that it will be useful, but WITHOUT "
+"ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
+"FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for "
+"more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License along with "
+"this program; if not, write to the Free Software Foundation, Inc., 51 "
+"Franklin St, Fifth Floor, Boston, MA  02110-1301 USA"
+msgstr ""
+"HardInfo — это свободное программное обеспечение; вы можете распространять "
+"его и/или изменять под условиями Общей общественной лицензии GNU, которая "
+"была опубликована Фондом свободного программного обеспечения, версия 2.\n"
+"\n"
+"Эта программа распространятся в надежде, что она будет полезной, но БЕЗ "
+"КАКОЙ-ЛИБО ГАРАНТИИ; даже без предполагаемой гарантии ПРИГОДНОСТИ ДЛЯ "
+"КОНКРЕТНЫХ ЦЕЛЕЙ. См. подробности в Общественной лицензии GNU.\n"
+"\n"
+"Вы должны были получить копию Общественной лицензии GNU вместе с этой "
+"программой; если нет, пишите в Фонд свободного программного обеспечения, "
+"Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA"
+
+#: shell/callbacks.c:220
+msgid "translator-credits"
+msgstr ""
+
+#: shell/menu.c:35
+msgid "_Information"
+msgstr "_Информация"
+
+#: shell/menu.c:36
+msgid "_Remote"
+msgstr "_Удалённо"
+
+#: shell/menu.c:37
+msgid "_View"
+msgstr "_Вид"
+
+#: shell/menu.c:38
+msgid "_Help"
+msgstr "_Справка"
+
+#: shell/menu.c:39
+msgid "About _Modules"
+msgstr "О _модулях"
+
+#: shell/menu.c:43
+msgid "Generate _Report"
+msgstr "Создать _отчёт"
+
+#: shell/menu.c:48
+msgid "_Network Updater..."
+msgstr "_Обновление через сеть..."
+
+#: shell/menu.c:53
+msgid "_Open..."
+msgstr "_Открыть..."
+
+#: shell/menu.c:58
+msgid "_Copy to Clipboard"
+msgstr "_Копировать в буфер"
+
+#: shell/menu.c:59
+msgid "Copy to clipboard"
+msgstr "Копировать в буфер обмена"
+
+#: shell/menu.c:63
+msgid "_Refresh"
+msgstr "_Обновить"
+
+#: shell/menu.c:68
+msgid "_Open HardInfo Web Site"
+msgstr "_Открыть веб-сайт Hardinfo"
+
+#: shell/menu.c:73
+msgid "_Report bug"
+msgstr "_Сообщить об ошибке"
+
+#: shell/menu.c:78
+msgid "_About HardInfo"
+msgstr "_О HardInfo"
+
+#: shell/menu.c:79
+msgid "Displays program version information"
+msgstr "Показывает информацию о версии программы"
+
+#: shell/menu.c:83
+msgid "_Quit"
+msgstr "_Выход"
+
+#: shell/menu.c:90
+msgid "_Side Pane"
+msgstr "_Боковая панель"
+
+#: shell/menu.c:91
+msgid "Toggles side pane visibility"
+msgstr "Управляет боковой панелью"
+
+#: shell/menu.c:94
+msgid "_Toolbar"
+msgstr "_Панель инструментов"
+
+#: shell/report.c:494 shell/report.c:502
+msgid "Save File"
+msgstr "Сохранить файл"
+
+#: shell/report.c:497 shell/report.c:929 shell/syncmanager.c:748
+msgid "_Cancel"
+msgstr "_Отмена"
+
+#: shell/report.c:499
+msgid "_Save"
+msgstr "_Сохранить"
+
+#: shell/report.c:629
+msgid "Cannot create ReportContext. Programming bug?"
+msgstr "Не могу создать ReportContext. Ошибка программирования?"
+
+#: shell/report.c:648
+msgid "Open the report with your web browser?"
+msgstr "Открыть отчёт в веб-браузере?"
+
+#: shell/report.c:651
+msgid "_No"
+msgstr "_Нет"
+
+#: shell/report.c:652
+msgid "_Open"
+msgstr "_Открыть"
+
+#: shell/report.c:682
+msgid "Generating report..."
+msgstr "Создаётся отчёт..."
+
+#: shell/report.c:692
+msgid "Report saved."
+msgstr "Отчёт сохранён."
+
+#: shell/report.c:694
+msgid "Error while creating the report."
+msgstr "Ошибка во время создания отчёта."
+
+#: shell/report.c:796
+msgid "Generate Report"
+msgstr "Создать отчёт"
+
+#: shell/report.c:821
+msgid ""
+"<big><b>Generate Report</b></big>\n"
+"Please choose the information that you wish to view in your report:"
+msgstr ""
+"<big><b>Создать отчёт</b></big>\n"
+"Пожалуйста, выберите информацию для отображения в отчёте:"
+
+#: shell/report.c:893
+msgid "Select _None"
+msgstr "Выбор: нет"
+
+#: shell/report.c:904
+msgid "Select _All"
+msgstr "Выбор: все"
+
+#: shell/report.c:939
+msgid "_Generate"
+msgstr "_Сгенерировать"
+
+#: shell/shell.c:402
+#, c-format
+msgid "%s - System Information"
+msgstr "%s - Информация о системе"
+
+#: shell/shell.c:407
+msgid "System Information"
+msgstr "Информация о системе"
+
+#: shell/shell.c:759
+msgid "Loading modules..."
+msgstr "Загрузка модулей..."
+
+#: shell/shell.c:1715
+#, c-format
+msgid "<b>%s → Summary</b>"
+msgstr "<b>%s → </b>"
+
+#: shell/shell.c:1824
+msgid "Updating..."
+msgstr "Обновление..."
+
+#: shell/syncmanager.c:69
+msgid ""
+"<big><b>Synchronize with Central Database</b></big>\n"
+"The following information may be synchronized with the HardInfo central "
+"database."
+msgstr ""
+"<big><b>Синхронизировать с центральной базой данных</b></big>\n"
+"Следующая информация может быть синхронизирована с центральной базой данных "
+"HardInfo."
+
+#: shell/syncmanager.c:72
+msgid ""
+"<big><b>Synchronizing</b></big>\n"
+"This may take some time."
+msgstr ""
+"<big><b>Синхронизация</b></big>\n"
+"Это может занять какое-то время."
+
+#: shell/syncmanager.c:132
+msgid ""
+"HardInfo was compiled without libsoup support. (Network Updater requires it.)"
+msgstr ""
+"HardInfo был скомпилирован без поддержки библиотеки libsoup. (Нужна для "
+"сетевого обновления.)"
+
+#: shell/syncmanager.c:161 shell/syncmanager.c:189
+#, c-format
+msgid "%s (error #%d)"
+msgstr "%s (ошибка #%d)"
+
+#: shell/syncmanager.c:170 shell/syncmanager.c:198
+msgid "Could not parse XML-RPC response"
+msgstr "Не могу разобрать ответ XML-RPC"
+
+#: shell/syncmanager.c:280
+#, c-format
+msgid ""
+"Server says it supports API version %d, but this version of HardInfo only "
+"supports API version %d."
+msgstr ""
+"Сервер говорит, что поддерживает API версии %d, но эта версия HardInfo "
+"поддерживает API только версии %d."
+
+#: shell/syncmanager.c:375
+msgid "Contacting HardInfo Central Database"
+msgstr "Подключение к центральной базе данных Hardinfo"
+
+#: shell/syncmanager.c:376
+msgid "Cleaning up"
+msgstr "Очистка"
+
+#: shell/syncmanager.c:493
+msgid "(canceled)"
+msgstr "(отменен)"
+
+#: shell/syncmanager.c:510
+msgid "(failed)"
+msgstr "(ошибка)"
+
+#: shell/syncmanager.c:521
+#, c-format
+msgid ""
+"Failed while performing \"%s\". Please file a bug report if this problem "
+"persists. (Use the Help→Report bug option.)\n"
+"\n"
+"Details: %s"
+msgstr ""
+"Ошибка во время выполнения \"%s\". Если проблема будет повторяться, "
+"пожалуйста, сообщите об ошибке. (Используйте опцию в меню Справка.)\n"
+"\n"
+"Подробности: %s"
+
+#: shell/syncmanager.c:530
+#, c-format
+msgid ""
+"Failed while performing \"%s\". Please file a bug report if this problem "
+"persists. (Use the Help→Report bug option.)"
+msgstr ""
+"Ошибка во время выполнения \"%s\". Если проблема будет повторяться, "
+"пожалуйста, сообщите об ошибке. (Используйте опцию в меню Справка.)"
+
+#: shell/syncmanager.c:658
+msgid "Network Updater"
+msgstr "Сетевое обновление"
+
+#: shell/syncmanager.c:757
+msgid "_Synchronize"
+msgstr "_Синхронизировать"
+
+#. /or modify
+#. *    it under the terms of the GNU General Public License as published by
+#. *    the Free Software Foundation, version 2.
+#. *
+#. *    This program is distributed in the hope that it will be useful,
+#. *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#. *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#. *    GNU General Public License for more details.
+#. *
+#. *    You should have received a copy of the GNU General Public License
+#. *    along with this program; if not, write to the Free Software
+#. *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+#.
+#. / Used for an unknown value. Having it in only one place cleans up the .po line references
+#: modules/benchmark/bench_results.c:22 modules/computer/display.c:54
+#: modules/computer/display.c:56 modules/computer/display.c:58
+#: modules/computer/display.c:61 modules/computer/os.c:279
+#: modules/devices.c:387 modules/devices/usb.c:48 modules/devices/usb.c:307
+#: modules/devices/usb.c:310 modules/network/net.c:437 includes/cpu_util.h:11
+msgid "(Unknown)"
+msgstr "(Неизвестно)"
+
+#: modules/benchmark/bench_results.c:47 modules/benchmark/bench_results.c:298
+#: modules/devices/alpha/processor.c:90 modules/devices/arm/processor.c:240
+#: modules/devices/arm/processor.c:383 modules/devices.c:299
+#: modules/devices.c:307 modules/devices.c:335
+#: modules/devices/ia64/processor.c:167 modules/devices/ia64/processor.c:196
+#: modules/devices/m68k/processor.c:87 modules/devices/mips/processor.c:77
+#: modules/devices/parisc/processor.c:158
+#: modules/devices/parisc/processor.c:191 modules/devices/pci.c:108
+#: modules/devices/ppc/processor.c:160 modules/devices/ppc/processor.c:187
+#: modules/devices/riscv/processor.c:186 modules/devices/riscv/processor.c:214
+#: modules/devices/s390/processor.c:160 modules/devices/sh/processor.c:87
+#: modules/devices/sh/processor.c:88 modules/devices/sh/processor.c:89
+#: modules/devices/x86/processor.c:420 modules/devices/x86/processor.c:479
+msgid "MHz"
+msgstr "МГц"
+
+#: modules/benchmark/bench_results.c:347 modules/benchmark/bench_results.c:408
+msgid "kiB"
+msgstr "КиБ"
+
+#: modules/benchmark/bench_results.c:361 modules/benchmark/bench_results.c:395
+msgid "Benchmark Result"
+msgstr "Результат теста"
+
+#: modules/benchmark/bench_results.c:362 modules/benchmark/bench_results.c:398
+msgid "Threads"
+msgstr "Потоки"
+
+#: modules/benchmark/bench_results.c:363 modules/benchmark/bench_results.c:399
+msgid "Note"
+msgstr "Примечание"
+
+#: modules/benchmark/bench_results.c:364 modules/benchmark/bench_results.c:400
+msgid ""
+"This result is from an old version of HardInfo. Results might not be "
+"comparable to current version. Some details are missing."
+msgstr ""
+"Данный результат получен с использованием старой версии HardInfo.Он может "
+"быть несопоставим с результатом текущей версии, поскольку отсутствуют "
+"некоторые подробности."
+
+#: modules/benchmark/bench_results.c:365 modules/benchmark/bench_results.c:401
+#: modules/devices/devicetree/pmac_data.c:81 modules/devices/sh/processor.c:85
+msgid "Machine"
+msgstr "Машина"
+
+#: modules/benchmark/bench_results.c:366 modules/benchmark/bench_results.c:402
+#: modules/devices/devicetree.c:206 modules/devices/dmi.c:45
+msgid "Board"
+msgstr "Плата"
+
+#: modules/benchmark/bench_results.c:367 modules/benchmark/bench_results.c:403
+msgid "CPU Name"
+msgstr "Название процессора"
+
+#: modules/benchmark/bench_results.c:368 modules/benchmark/bench_results.c:404
+msgid "CPU Description"
+msgstr "Описание процессора"
+
+#: modules/benchmark/bench_results.c:369 modules/benchmark/bench_results.c:405
+#: modules/benchmark.c:288
+msgid "CPU Config"
+msgstr "Конфигурация процессора"
+
+#: modules/benchmark/bench_results.c:370 modules/benchmark/bench_results.c:406
+msgid "Threads Available"
+msgstr "Доступно потоков"
+
+#: modules/benchmark/bench_results.c:371 modules/benchmark/bench_results.c:407
+#: modules/computer.c:475
+msgid "OpenGL Renderer"
+msgstr "Рендер OpenGL"
+
+#: modules/benchmark/bench_results.c:372 modules/benchmark/bench_results.c:408
+#: modules/computer.c:108 modules/computer.c:464 modules/devices.c:96
+#: modules/devices/pci.c:149
+msgid "Memory"
+msgstr "Память"
+
+#: modules/benchmark/bench_results.c:396
+msgid "Benchmark"
+msgstr ""
+
+#: modules/benchmark/bench_results.c:397
+msgid "Result"
+msgstr ""
+
+#: modules/benchmark/bench_results.c:409
+msgid "Handles"
+msgstr ""
+
+#: modules/benchmark/bench_results.c:410
+msgid "mid"
+msgstr ""
+
+#: modules/benchmark/bench_results.c:411
+msgid "cfg_val"
+msgstr ""
+
+#: modules/benchmark.c:54
+msgid "CPU Blowfish"
+msgstr ""
+
+#: modules/benchmark.c:55
+msgid "CPU CryptoHash"
+msgstr ""
+
+#: modules/benchmark.c:56
+msgid "CPU Fibonacci"
+msgstr ""
+
+#: modules/benchmark.c:57
+msgid "CPU N-Queens"
+msgstr ""
+
+#: modules/benchmark.c:58
+msgid "CPU Zlib"
+msgstr ""
+
+#: modules/benchmark.c:59
+msgid "FPU FFT"
+msgstr ""
+
+#: modules/benchmark.c:60
+msgid "FPU Raytracing"
+msgstr ""
+
+#: modules/benchmark.c:62
+msgid "GPU Drawing"
+msgstr ""
+
+#: modules/benchmark.c:288
+msgid "Results"
+msgstr "Результаты"
+
+#: modules/benchmark.c:288 modules/computer.c:749
+#: modules/devices/sparc/processor.c:75
+msgid "CPU"
+msgstr "Процессор"
+
+#: modules/benchmark.c:415
+#, c-format
+msgid "Benchmarking: <b>%s</b>."
+msgstr "Тестирование: <b>%s</b>"
+
+#: modules/benchmark.c:434 modules/benchmark.c:454
+msgid "Cancel"
+msgstr "Отмена"
+
+#: modules/benchmark.c:438 modules/benchmark.c:450
+msgid "Benchmarking. Please do not move your mouse or press any keys."
+msgstr "Тестирование. Пожалуйста, не двигайте мышь и не нажимайте на кнопки."
+
+#: modules/benchmark.c:592
+msgid "Results in MiB/second. Higher is better."
+msgstr "Результаты в МиБ/сек. Чем выше, тем лучше."
+
+#: modules/benchmark.c:596
+msgid "Results in HIMarks. Higher is better."
+msgstr "Результаты в HIMarks. Чем выше, тем лучше."
+
+#: modules/benchmark.c:603
+msgid "Results in seconds. Lower is better."
+msgstr "Результат в секундах. Чем ниже, тем лучше."
+
+#: modules/benchmark.c:611
+msgid "Benchmarks"
+msgstr "Тесты"
+
+#: modules/benchmark.c:629
+msgid "Perform tasks and compare with other systems"
+msgstr "Выполняет задания и сравнивает с другими системами"
+
+#: modules/benchmark.c:719
+msgid "Send benchmark results"
+msgstr "Отправить результаты тестирования"
+
+#: modules/benchmark.c:724
+msgid "Receive benchmark results"
+msgstr "Принять результаты тестирования"
+
+#: modules/computer/alsa.c:26 modules/computer.c:479
+msgid "Audio Devices"
+msgstr "Аудио устройства"
+
+#: modules/computer/alsa.c:34
+msgid "Audio Adapter"
+msgstr "Звуковая карта"
+
+#: modules/computer.c:74
+msgid "Summary"
+msgstr "Общая информация"
+
+#: modules/computer.c:75 modules/computer.c:467 modules/computer.c:748
+msgid "Operating System"
+msgstr "Операционная система"
+
+#: modules/computer.c:76
+msgid "Kernel Modules"
+msgstr "Модули ядра"
+
+#: modules/computer.c:77 modules/computer.c:536
+msgid "Boots"
+msgstr "Загрузки"
+
+#: modules/computer.c:78
+msgid "Languages"
+msgstr "Языки"
+
+#: modules/computer.c:79
+msgid "Filesystems"
+msgstr "Файловые системы"
+
+#: modules/computer.c:80 modules/computer.c:472 modules/computer.c:580
+msgid "Display"
+msgstr "Дисплей"
+
+#: modules/computer.c:81 modules/computer/environment.c:32
+msgid "Environment Variables"
+msgstr "Переменные среды"
+
+#: modules/computer.c:83
+msgid "Development"
+msgstr "Разработка"
+
+#: modules/computer.c:85 modules/computer.c:607
+msgid "Users"
+msgstr "Пользователи"
+
+#: modules/computer.c:86
+msgid "Groups"
+msgstr "Группы"
+
+#: modules/computer.c:110
+#, c-format
+msgid "%dMB (%dMB used)"
+msgstr "%d Мб (%d Мб занято)"
+
+#: modules/computer.c:112 modules/computer.c:510
+msgid "Uptime"
+msgstr "Время работы"
+
+#: modules/computer.c:114 modules/computer.c:469
+msgid "Date/Time"
+msgstr "Дата/время"
+
+# Должно совпадать с таким-же полем в строке 430 computer.c
+#: modules/computer.c:119 modules/computer.c:511
+msgid "Load Average"
+msgstr "Средняя нагрузка"
+
+#: modules/computer.c:121 modules/computer.c:512
+msgid "Available entropy in /dev/random"
+msgstr "Доступная энтропия в /dev/random"
+
+#: modules/computer.c:207
+msgid "Scripting Languages"
+msgstr "Скриптовые языки"
+
+#: modules/computer.c:208
+msgid "Gambas3 (gbr3)"
+msgstr ""
+
+#: modules/computer.c:209
+msgid "Python"
+msgstr ""
+
+#: modules/computer.c:210
+msgid "Python2"
+msgstr ""
+
+#: modules/computer.c:211
+msgid "Python3"
+msgstr ""
+
+#: modules/computer.c:212
+msgid "Perl"
+msgstr ""
+
+#: modules/computer.c:213
+msgid "Perl6 (VM)"
+msgstr ""
+
+#: modules/computer.c:214
+msgid "Perl6"
+msgstr ""
+
+#: modules/computer.c:215
+msgid "PHP"
+msgstr ""
+
+#: modules/computer.c:216
+msgid "Ruby"
+msgstr ""
+
+#: modules/computer.c:217
+msgid "Bash"
+msgstr ""
+
+#: modules/computer.c:218
+msgid "Compilers"
+msgstr "Компиляторы"
+
+#: modules/computer.c:219
+msgid "C (GCC)"
+msgstr ""
+
+#: modules/computer.c:220
+msgid "C (Clang)"
+msgstr ""
+
+#: modules/computer.c:221
+msgid "D (dmd)"
+msgstr ""
+
+#: modules/computer.c:222
+msgid "Gambas3 (gbc3)"
+msgstr ""
+
+#: modules/computer.c:223
+#, fuzzy
+msgid "Java"
+msgstr "Язык программирования Java"
+
+#: modules/computer.c:224
+#, fuzzy
+msgid "CSharp (Mono, old)"
+msgstr "Найдена старая установка %s."
+
+#: modules/computer.c:225
+#, fuzzy
+msgid "CSharp (Mono)"
+msgstr "Моноширинный шрифт"
+
+#: modules/computer.c:226
+#, fuzzy
+msgid "Vala"
+msgstr "базы данных vala"
+
+#: modules/computer.c:227
+msgid "Haskell (GHC)"
+msgstr ""
+
+#: modules/computer.c:228
+msgid "FreePascal"
+msgstr ""
+
+#: modules/computer.c:229
+msgid "Go"
+msgstr ""
+
+#: modules/computer.c:230
+msgid "Tools"
+msgstr "Инструменты"
+
+#: modules/computer.c:231
+msgid "make"
+msgstr ""
+
+#: modules/computer.c:232
+msgid "GDB"
+msgstr ""
+
+#: modules/computer.c:233
+msgid "strace"
+msgstr ""
+
+#: modules/computer.c:234
+msgid "valgrind"
+msgstr ""
+
+#: modules/computer.c:235
+msgid "QMake"
+msgstr ""
+
+#: modules/computer.c:236
+msgid "CMake"
+msgstr ""
+
+#: modules/computer.c:237
+msgid "Gambas3 IDE"
+msgstr ""
+
+#: modules/computer.c:278
+msgid "Not found"
+msgstr "Не найдено"
+
+#: modules/computer.c:283
+#, c-format
+msgid "Detecting version: %s"
+msgstr "Определена версия: %s"
+
+#: modules/computer.c:300
+msgid "Program"
+msgstr "Программа"
+
+#: modules/computer.c:320
+msgid "Single-board computer"
+msgstr ""
+
+#. /proc/apm
+#: modules/computer.c:369
+msgid "Unknown physical machine type"
+msgstr ""
+
+#: modules/computer.c:389 modules/computer.c:390
+msgid "Virtual (VMware)"
+msgstr ""
+
+#: modules/computer.c:392 modules/computer.c:393 modules/computer.c:394
+#: modules/computer.c:395
+msgid "Virtual (QEMU)"
+msgstr ""
+
+#: modules/computer.c:397 modules/computer.c:398
+msgid "Virtual (Unknown)"
+msgstr ""
+
+#: modules/computer.c:400 modules/computer.c:401 modules/computer.c:402
+#: modules/computer.c:423
+msgid "Virtual (VirtualBox)"
+msgstr ""
+
+#: modules/computer.c:404 modules/computer.c:405 modules/computer.c:406
+#: modules/computer.c:417
+msgid "Virtual (Xen)"
+msgstr ""
+
+#: modules/computer.c:408
+msgid "Virtual (hypervisor present)"
+msgstr ""
+
+#: modules/computer.c:461 modules/computer.c:707
+msgid "Computer"
+msgstr "Компьютер"
+
+#: modules/computer.c:462 modules/devices/alpha/processor.c:87
+#: modules/devices/arm/processor.c:236 modules/devices.c:95
+#: modules/devices/ia64/processor.c:159 modules/devices/m68k/processor.c:83
+#: modules/devices/mips/processor.c:74 modules/devices/parisc/processor.c:154
+#: modules/devices/ppc/processor.c:157 modules/devices/riscv/processor.c:181
+#: modules/devices/s390/processor.c:131 modules/devices/sh/processor.c:83
+#: modules/devices/sparc/processor.c:74 modules/devices/x86/processor.c:409
+msgid "Processor"
+msgstr "Процессор"
+
+#: modules/computer.c:465
+msgid "Machine Type"
+msgstr "Тип машины"
+
+#: modules/computer.c:468 modules/computer.c:504
+msgid "User Name"
+msgstr "Пользователь"
+
+#: modules/computer.c:473 modules/computer.c:581
+msgid "Resolution"
+msgstr "Разрешение"
+
+#: modules/computer.c:473 modules/computer.c:581
+#, c-format
+msgid "%dx%d pixels"
+msgstr "%dx%d пикселей"
+
+#: modules/computer.c:476
+msgid "X11 Vendor"
+msgstr "Поставщик X11"
+
+#: modules/computer.c:481 modules/devices.c:102
+msgid "Input Devices"
+msgstr "Устройства ввода"
+
+#: modules/computer.c:496
+msgid "Kernel"
+msgstr "Ядро"
+
+#: modules/computer.c:498
+msgid "C Library"
+msgstr "Библиотека C"
+
+#: modules/computer.c:499
+msgid "Distribution"
+msgstr "Дистрибутив"
+
+#: modules/computer.c:502
+msgid "Current Session"
+msgstr "Текущая сессия"
+
+#: modules/computer.c:503
+msgid "Computer Name"
+msgstr "Имя компьютера"
+
+#: modules/computer.c:505 modules/computer/languages.c:108
+msgid "Language"
+msgstr "Язык"
+
+#: modules/computer.c:506 modules/computer/users.c:50
+msgid "Home Directory"
+msgstr "Домашний каталог"
+
+#: modules/computer.c:509 modules/devices/usb.c:87 modules/devices/usb.c:234
+#: modules/devices/usb.c:351
+msgid "Misc"
+msgstr "Разное"
+
+#: modules/computer.c:522
+msgid "Loaded Modules"
+msgstr ""
+
+#: modules/computer.c:525 modules/computer/modules.c:145
+#: modules/computer/modules.c:147 modules/devices/arm/processor.c:355
+#: modules/devices.c:572 modules/devices/x86/processor.c:456
+msgid "Description"
+msgstr "Описание"
+
+#: modules/computer.c:538
+msgid "Date & Time"
+msgstr "Дата и время"
+
+#: modules/computer.c:539
+msgid "Kernel Version"
+msgstr "Версия ядра"
+
+#: modules/computer.c:549
+msgid "Available Languages"
+msgstr ""
+
+#: modules/computer.c:551
+msgid "Language Code"
+msgstr "Код языка"
+
+#: modules/computer.c:563
+msgid "Mounted File Systems"
+msgstr ""
+
+#: modules/computer.c:565 modules/computer/filesystem.c:85
+msgid "Mount Point"
+msgstr "Точка монтирования"
+
+#: modules/computer.c:566
+msgid "Usage"
+msgstr "Использование"
+
+#: modules/computer.c:567
+msgid "Device"
+msgstr "Устройство"
+
+#: modules/computer.c:583 modules/computer.c:591 modules/devices/dmi.c:39
+#: modules/devices/dmi.c:43 modules/devices/dmi.c:47 modules/devices/dmi.c:52
+#: modules/devices/ia64/processor.c:161 modules/devices/inputdevices.c:119
+#: modules/devices/pci.c:225 modules/devices/usb.c:349
+#: modules/devices/x86/processor.c:416
+msgid "Vendor"
+msgstr "Производитель"
+
+#: modules/computer.c:585
+msgid "Current Display Name"
+msgstr "Имя текущего дисплея"
+
+#: modules/computer.c:588
+msgid "Monitors"
+msgstr "Монитор"
+
+#: modules/computer.c:590
+msgid "OpenGL"
+msgstr ""
+
+#: modules/computer.c:592
+msgid "Renderer"
+msgstr "Рендер"
+
+#: modules/computer.c:594
+msgid "Direct Rendering"
+msgstr "Графическое ускорение"
+
+#: modules/computer.c:598
+msgid "Extensions"
+msgstr "Расширения"
+
+#: modules/computer.c:618
+msgid "Group"
+msgstr ""
+
+#: modules/computer.c:621 modules/computer/users.c:49
+msgid "Group ID"
+msgstr "ID группы"
+
+#: modules/computer.c:749
+msgid "RAM"
+msgstr "Оперативная память"
+
+#: modules/computer.c:749 modules/devices/devicetree/pmac_data.c:82
+msgid "Motherboard"
+msgstr "Материнская плата"
+
+#: modules/computer.c:749
+msgid "Graphics"
+msgstr "Графика"
+
+#: modules/computer.c:750 modules/devices.c:103
+msgid "Storage"
+msgstr "Устройства хранения"
+
+#: modules/computer.c:750 modules/devices.c:99
+msgid "Printers"
+msgstr "Принтеры"
+
+#: modules/computer.c:750
+msgid "Audio"
+msgstr "Аудио"
+
+#: modules/computer.c:805
+msgid "Gathers high-level computer information"
+msgstr "Собирает высокоуровневую информацию о компьютере"
+
+#: modules/computer/display.c:125
+#, c-format
+msgid "Monitor %d=%dx%d pixels\n"
+msgstr "Монитор %d=%dx%d пикселей\n"
+
+#: modules/computer/filesystem.c:83
+msgid "Filesystem"
+msgstr "Файловая система"
+
+#: modules/computer/filesystem.c:84
+msgid "Mounted As"
+msgstr "Смонтировано"
+
+#: modules/computer/filesystem.c:84
+msgid "Read-Write"
+msgstr "Для чтения и записи"
+
+#: modules/computer/filesystem.c:84
+msgid "Read-Only"
+msgstr "Только для чтения"
+
+#: modules/computer/filesystem.c:86 modules/devices/spd-decode.c:1510
+msgid "Size"
+msgstr "Размер"
+
+#: modules/computer/filesystem.c:87
+msgid "Used"
+msgstr "Занято"
+
+#: modules/computer/filesystem.c:88
+msgid "Available"
+msgstr "Свободно"
+
+#: modules/computer/languages.c:103
+msgid "Locale Information"
+msgstr "Информация о языке"
+
+#: modules/computer/languages.c:105
+msgid "Source"
+msgstr "Источник"
+
+#: modules/computer/languages.c:106
+msgid "Address"
+msgstr "Адрес"
+
+#: modules/computer/languages.c:107
+msgid "E-mail"
+msgstr "Электронная почта"
+
+#: modules/computer/languages.c:109
+msgid "Territory"
+msgstr "Территория"
+
+#: modules/computer/languages.c:110 modules/devices/arm/processor.c:250
+#: modules/devices/ia64/processor.c:166 modules/devices/ppc/processor.c:159
+#: modules/devices/usb.c:236
+msgid "Revision"
+msgstr "Ревизия"
+
+#: modules/computer/languages.c:111 modules/devices/dmi.c:42
+msgid "Date"
+msgstr "Дата"
+
+#: modules/computer/languages.c:112
+msgid "Codeset"
+msgstr "Кодировка"
+
+#: modules/computer/loadavg.c:64
+msgid "Couldn't obtain load average"
+msgstr "Не удается установить среднюю загрузку"
+
+#: modules/computer/modules.c:125 modules/computer/modules.c:126
+#: modules/computer/modules.c:127 modules/computer/modules.c:128
+#: modules/computer/modules.c:129 modules/devices/dmi.c:115
+msgid "(Not available)"
+msgstr "(Недоступно)"
+
+#: modules/computer/modules.c:142
+msgid "Module Information"
+msgstr "Информация о модуле"
+
+#: modules/computer/modules.c:143
+msgid "Path"
+msgstr "Путь"
+
+#: modules/computer/modules.c:144
+msgid "Used Memory"
+msgstr "Обьем занимаемой памяти"
+
+#: modules/computer/modules.c:144 modules/devices/devmemory.c:72
+msgid "KiB"
+msgstr "КиБ"
+
+#: modules/computer/modules.c:148
+msgid "Version Magic"
+msgstr "Версия"
+
+#: modules/computer/modules.c:149
+msgid "Copyright"
+msgstr "Авторское право"
+
+#: modules/computer/modules.c:150
+msgid "Author"
+msgstr "Автор"
+
+#: modules/computer/modules.c:151
+msgid "License"
+msgstr "Лицензия"
+
+#: modules/computer/modules.c:158
+msgid "Dependencies"
+msgstr "Зависимости"
+
+#: modules/computer/os.c:35 modules/computer/os.c:36 modules/computer/os.c:37
+#: modules/computer/os.c:38
+msgid "GNU C Library"
+msgstr ""
+
+#: modules/computer/os.c:39
+msgid "uClibc or uClibc-ng"
+msgstr ""
+
+#: modules/computer/os.c:40
+msgid "diet libc"
+msgstr ""
+
+#: modules/computer/os.c:78 modules/computer/os.c:234 modules/computer/os.c:359
+#: modules/devices.c:333 modules/devices.c:400 modules/devices/printers.c:99
+#: modules/devices/printers.c:106 modules/devices/printers.c:116
+#: modules/devices/printers.c:131 modules/devices/printers.c:140
+#: modules/devices/printers.c:243
+msgid "Unknown"
+msgstr "Неизвестно"
+
+#: modules/computer/os.c:112 modules/computer/os.c:115
+msgid "GNOME Shell "
+msgstr ""
+
+#: modules/computer/os.c:123 modules/computer/os.c:126
+msgid "Version: "
+msgstr ""
+
+#: modules/computer/os.c:157
+#, c-format
+msgid "Unknown (Window Manager: %s)"
+msgstr "Неизвестно (Оконный менеджер: %s)"
+
+#. /{desktop environment} on {session type}
+#: modules/computer/os.c:168
+#, c-format
+msgid "%s on %s"
+msgstr "%s на %s"
+
+#: modules/computer/os.c:232
+msgid "Terminal"
+msgstr "Терминал"
+
+#. /bits of entropy for rng (0)
+#: modules/computer/os.c:241
+msgid "(None or not available)"
+msgstr "(Нет или недоступно)"
+
+#. /bits of entropy for rng (low/poor value)
+#: modules/computer/os.c:242
+#, c-format
+msgid "%d bits (low)"
+msgstr "%d бит (низкая)"
+
+#. /bits of entropy for rng (medium value)
+#: modules/computer/os.c:243
+#, c-format
+msgid "%d bits (medium)"
+msgstr "%d бит (средняя)"
+
+#. /bits of entropy for rng (high/good value)
+#: modules/computer/os.c:244
+#, c-format
+msgid "%d bits (healthy)"
+msgstr "%d бит (огромная)"
+
+#: modules/computer/users.c:47
+msgid "User Information"
+msgstr "Информация о пользователе"
+
+#: modules/computer/users.c:48
+msgid "User ID"
+msgstr "ID пользователя"
+
+#: modules/computer/users.c:51
+msgid "Default Shell"
+msgstr "Оболочка по умолчанию"
+
+#: modules/devices/alpha/processor.c:88 modules/devices/devicetree.c:161
+#: modules/devices/devicetree.c:207 modules/devices/devicetree/pmac_data.c:80
+#: modules/devices/ia64/processor.c:165 modules/devices/m68k/processor.c:84
+#: modules/devices/mips/processor.c:75 modules/devices/parisc/processor.c:155
+#: modules/devices/ppc/processor.c:158 modules/devices/riscv/processor.c:182
+#: modules/devices/s390/processor.c:132 modules/devices/spd-decode.c:1510
+msgid "Model"
+msgstr "Модель"
+
+#: modules/devices/alpha/processor.c:89
+msgid "Platform String"
+msgstr "Строка платформы"
+
+#: modules/devices/alpha/processor.c:90 modules/devices/arm/processor.c:240
+#: modules/devices/ia64/processor.c:167 modules/devices/m68k/processor.c:87
+#: modules/devices/mips/processor.c:77 modules/devices/parisc/processor.c:158
+#: modules/devices/pci.c:108 modules/devices/ppc/processor.c:160
+#: modules/devices/riscv/processor.c:186 modules/devices/sh/processor.c:87
+#: modules/devices/x86/processor.c:420
+msgid "Frequency"
+msgstr "Частота"
+
+#: modules/devices/alpha/processor.c:91 modules/devices/arm/processor.c:241
+#: modules/devices/ia64/processor.c:168 modules/devices/m68k/processor.c:88
+#: modules/devices/mips/processor.c:78 modules/devices/parisc/processor.c:159
+#: modules/devices/ppc/processor.c:161 modules/devices/s390/processor.c:134
+#: modules/devices/sh/processor.c:90 modules/devices/x86/processor.c:421
+msgid "BogoMips"
+msgstr ""
+
+#: modules/devices/alpha/processor.c:92 modules/devices/arm/processor.c:242
+#: modules/devices/ia64/processor.c:169 modules/devices/m68k/processor.c:89
+#: modules/devices/mips/processor.c:79 modules/devices/parisc/processor.c:160
+#: modules/devices/ppc/processor.c:162 modules/devices/riscv/processor.c:187
+#: modules/devices/s390/processor.c:135 modules/devices/sh/processor.c:91
+#: modules/devices/sparc/processor.c:77 modules/devices/x86/processor.c:422
+msgid "Byte Order"
+msgstr "Порядок байтов"
+
+#. /hw_cap
+#. /flag:swp
+#: modules/devices/arm/arm_data.c:42
+msgctxt "arm-flag"
+msgid "SWP instruction (atomic read-modify-write)"
+msgstr "Инструкция SWP (атомарное чтение-изменение-запись)"
+
+#. /flag:half
+#: modules/devices/arm/arm_data.c:43
+msgctxt "arm-flag"
+msgid "Half-word loads and stores"
+msgstr "Загрузка и хранение полуслова"
+
+#. /flag:thumb
+#: modules/devices/arm/arm_data.c:44
+msgctxt "arm-flag"
+msgid "Thumb (16-bit instruction set)"
+msgstr "Thumb (набор 16-битных инструкций)"
+
+#. /flag:26bit
+#: modules/devices/arm/arm_data.c:45
+msgctxt "arm-flag"
+msgid "26-Bit Model (Processor status register folded into program counter)"
+msgstr ""
+"26-битная модель (регистр статуса процессора вложен в счетчик программы)"
+
+#. /flag:fastmult
+#: modules/devices/arm/arm_data.c:46
+msgctxt "arm-flag"
+msgid "32x32->64-bit multiplication"
+msgstr "32x32->64-битное умножение"
+
+#. /flag:fpa
+#: modules/devices/arm/arm_data.c:47
+msgctxt "arm-flag"
+msgid "Floating point accelerator"
+msgstr "Ускоритель плавающей точки"
+
+#. /flag:vfp
+#: modules/devices/arm/arm_data.c:48
+msgctxt "arm-flag"
+msgid "VFP (early SIMD vector floating point instructions)"
+msgstr "VFP (ранний вектор SIMD инструкций плавающей точки)"
+
+#. /flag:edsp
+#: modules/devices/arm/arm_data.c:49
+msgctxt "arm-flag"
+msgid "DSP extensions (the 'e' variant of the ARM9 CPUs, and all others above)"
+msgstr "расширения DSP (вариант 'e' процессоров ARM9 и выше)"
+
+#. /flag:java
+#: modules/devices/arm/arm_data.c:50
+msgctxt "arm-flag"
+msgid "Jazelle (Java bytecode accelerator)"
+msgstr "Jazelle (ускоритель байт-кода Java)"
+
+#. /flag:iwmmxt
+#: modules/devices/arm/arm_data.c:51
+msgctxt "arm-flag"
+msgid "SIMD instructions similar to Intel MMX"
+msgstr "Инструкции SIMD, схожие с Intel MMX"
+
+#. /flag:crunch
+#: modules/devices/arm/arm_data.c:52
+msgctxt "arm-flag"
+msgid "MaverickCrunch coprocessor (if kernel support enabled)"
+msgstr "Сопроцессор MaverickCrunch (при наличии поддержки в ядре)"
+
+#. /flag:thumbee
+#: modules/devices/arm/arm_data.c:53
+msgctxt "arm-flag"
+msgid "ThumbEE"
+msgstr ""
+
+#. /flag:neon
+#: modules/devices/arm/arm_data.c:54
+msgctxt "arm-flag"
+msgid "Advanced SIMD/NEON on AArch32"
+msgstr "Дополнительный SIMD/NEON на AArch32"
+
+#. /flag:evtstrm
+#: modules/devices/arm/arm_data.c:55
+msgctxt "arm-flag"
+msgid "Kernel event stream using generic architected timer"
+msgstr "поток событий ядра с использованием общего архитектурного таймера"
+
+#. /flag:vfpv3
+#: modules/devices/arm/arm_data.c:56
+msgctxt "arm-flag"
+msgid "VFP version 3"
+msgstr "VFP версии 3"
+
+#. /flag:vfpv3d16
+#: modules/devices/arm/arm_data.c:57
+msgctxt "arm-flag"
+msgid "VFP version 3 with 16 D-registers"
+msgstr "VFP версии 3 с 16 D-регистрами"
+
+#. /flag:vfpv4
+#: modules/devices/arm/arm_data.c:58
+msgctxt "arm-flag"
+msgid "VFP version 4 with fast context switching"
+msgstr "VFP версии 4 с быстрым контекстным переключением"
+
+#. /flag:vfpd32
+#: modules/devices/arm/arm_data.c:59
+msgctxt "arm-flag"
+msgid "VFP with 32 D-registers"
+msgstr "VFP с 32 D-регистрами"
+
+#. /flag:tls
+#: modules/devices/arm/arm_data.c:60
+msgctxt "arm-flag"
+msgid "TLS register"
+msgstr "Регистр TLS"
+
+#. /flag:idiva
+#: modules/devices/arm/arm_data.c:61
+msgctxt "arm-flag"
+msgid "SDIV and UDIV hardware division in ARM mode"
+msgstr "Аппаратное разделение SDIV и UDIV в режиме ARM"
+
+#. /flag:idivt
+#: modules/devices/arm/arm_data.c:62
+msgctxt "arm-flag"
+msgid "SDIV and UDIV hardware division in Thumb mode"
+msgstr "Аппаратное разделение SDIV и UDIV в режиме Thumb"
+
+#. /flag:lpae
+#: modules/devices/arm/arm_data.c:63
+msgctxt "arm-flag"
+msgid "40-bit Large Physical Address Extension"
+msgstr "40-битное большое физическое адресное расширение"
+
+#. /hw_cap2
+#. /flag:pmull
+#: modules/devices/arm/arm_data.c:65
+msgctxt "arm-flag"
+msgid "64x64->128-bit F2m multiplication (arch>8)"
+msgstr "64x64->128-битное умножение F2m (arch>8)"
+
+#. /flag:aes
+#: modules/devices/arm/arm_data.c:66
+msgctxt "arm-flag"
+msgid "Crypto:AES (arch>8)"
+msgstr "Крипто:AES (arch>8)"
+
+#. /flag:sha1
+#: modules/devices/arm/arm_data.c:67
+msgctxt "arm-flag"
+msgid "Crypto:SHA1 (arch>8)"
+msgstr "Крипто:SHA1 (arch>8)"
+
+#. /flag:sha2
+#: modules/devices/arm/arm_data.c:68
+msgctxt "arm-flag"
+msgid "Crypto:SHA2 (arch>8)"
+msgstr "Крипто:SHA2 (arch>8)"
+
+#. /flag:crc32
+#: modules/devices/arm/arm_data.c:69
+msgctxt "arm-flag"
+msgid "CRC32 checksum instructions (arch>8)"
+msgstr "инструкции контрольной суммы CRC32 (arch>8)"
+
+#. /flag:asimd
+#: modules/devices/arm/arm_data.c:72
+msgctxt "arm-flag"
+msgid "Advanced SIMD/NEON on AArch64 (arch>8)"
+msgstr "Дополнительный SIMD/NEON на AArch64 (arch>8)"
+
+#: modules/devices/arm/processor.c:142
+msgid "ARM Processor"
+msgstr "Процессор ARM"
+
+#: modules/devices/arm/processor.c:200 modules/devices/riscv/processor.c:147
+#: modules/devices/x86/processor.c:371
+msgid "Empty List"
+msgstr "Пустой список"
+
+#: modules/devices/arm/processor.c:237
+msgid "Linux Name"
+msgstr "Имя Linux"
+
+#: modules/devices/arm/processor.c:238
+msgid "Decoded Name"
+msgstr "Декодированное имя"
+
+#: modules/devices/arm/processor.c:239 modules/network/net.c:453
+msgid "Mode"
+msgstr "Режим"
+
+#: modules/devices/arm/processor.c:245
+msgid "ARM"
+msgstr ""
+
+#: modules/devices/arm/processor.c:246
+msgid "Implementer"
+msgstr "Исполнитель"
+
+#: modules/devices/arm/processor.c:247
+msgid "Part"
+msgstr "Часть"
+
+#: modules/devices/arm/processor.c:248 modules/devices/ia64/processor.c:162
+#: modules/devices/parisc/processor.c:156 modules/devices/riscv/processor.c:183
+msgid "Architecture"
+msgstr "Архитектура"
+
+#: modules/devices/arm/processor.c:249
+msgid "Variant"
+msgstr "Вариант"
+
+#: modules/devices/arm/processor.c:251 modules/devices/riscv/processor.c:190
+#: modules/devices/sparc/processor.c:78 modules/devices/x86/processor.c:428
+msgid "Capabilities"
+msgstr "Возможности"
+
+#: modules/devices/arm/processor.c:353
+msgid "SOC/Package"
+msgstr ""
+
+#: modules/devices/arm/processor.c:357
+msgid "Clocks"
+msgstr ""
+
+#: modules/devices/arm/processor.c:372
+msgid "SOC/Package Information"
+msgstr ""
+
+#: modules/devices/battery.c:181
+#, c-format
+msgid ""
+"\n"
+"[Battery: %s]\n"
+"State=%s (load: %s)\n"
+"Capacity=%s / %s (%.2f%%)\n"
+"Battery Technology=%s (%s)\n"
+"Manufacturer=%s\n"
+"Model Number=%s\n"
+"Serial Number=%s\n"
+msgstr ""
+"\n"
+"[Батарея: %s]\n"
+"Состояние=%s (нагрузка: %s)\n"
+"Емкость=%s / %s (%.2f%%)\n"
+"Технология батареи=%s (%s)\n"
+"Изготовитель=%s\n"
+"Номер модели=%s\n"
+"Серийный номер=%s\n"
+
+#: modules/devices/battery.c:258
+#, c-format
+msgid ""
+"\n"
+"[Battery: %s]\n"
+"State=%s\n"
+"Capacity=%s / %s\n"
+"Battery Technology=%s\n"
+"Manufacturer=%s\n"
+"Model Number=%s\n"
+"Serial Number=%s\n"
+msgstr ""
+"\n"
+"[Батарея: %s]\n"
+"Состояние=%s\n"
+"Емкость=%s / %s\n"
+"Технология батареи=%s\n"
+"Производитель=%s\n"
+"Номер модели=%s\n"
+"Серийный номер=%s\n"
+
+#: modules/devices/battery.c:346
+#, c-format
+msgid ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Remaining Charge=%s of %s\n"
+"Using=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+msgstr ""
+"\n"
+"[Батарея (APM)]\n"
+"Заряд=%d%%\n"
+"Оставшийся заряд=%s из %s\n"
+"Используется=%s\n"
+"APM драйвер версии=%s\n"
+"APM BIOS версии=%s\n"
+
+#: modules/devices/battery.c:358
+#, c-format
+msgid ""
+"\n"
+"[Battery (APM)]\n"
+"Charge=%d%%\n"
+"Using=%s\n"
+"APM driver version=%s\n"
+"APM BIOS version=%s\n"
+msgstr ""
+"\n"
+"[Батарея (APM)]\n"
+"Заряд=%d%%\n"
+"Используется=%s\n"
+"APM драйвер версии=%s\n"
+"APM BIOS версии=%s\n"
+
+#: modules/devices/battery.c:385
+msgid ""
+"[No batteries]\n"
+"No batteries found on this system=\n"
+msgstr ""
+"[No batteries]\n"
+"Батареи не найдены на этой системе=\n"
+
+#: modules/devices.c:97
+msgid "PCI Devices"
+msgstr "Устройства PCI"
+
+#: modules/devices.c:98 modules/devices/usb.c:117 modules/devices/usb.c:156
+#: modules/devices/usb.c:416
+msgid "USB Devices"
+msgstr "Устройства USB"
+
+#: modules/devices.c:100
+msgid "Battery"
+msgstr "Батарея"
+
+#: modules/devices.c:101
+msgid "Sensors"
+msgstr "Сенсоры"
+
+#: modules/devices.c:105
+msgid "DMI"
+msgstr ""
+
+#: modules/devices.c:106
+msgid "Memory SPD"
+msgstr "Память SPD"
+
+#: modules/devices.c:111
+msgid "Device Tree"
+msgstr ""
+
+#: modules/devices.c:113
+msgid "Resources"
+msgstr "Ресурсы"
+
+#: modules/devices.c:151
+#, c-format
+msgid "%d physical processor"
+msgid_plural "%d physical processors"
+msgstr[0] "%d физический процессор"
+msgstr[1] "%d физических процессора"
+msgstr[2] "%d физических процессоров"
+
+#: modules/devices.c:152
+#, c-format
+msgid "%d core"
+msgid_plural "%d cores"
+msgstr[0] "%d ядро"
+msgstr[1] "%d ядра"
+msgstr[2] "%d ядер"
+
+#: modules/devices.c:153
+#, c-format
+msgid "%d thread"
+msgid_plural "%d threads"
+msgstr[0] "%d поток"
+msgstr[1] "%d потока"
+msgstr[2] "%d потоков"
+
+#. /NP procs; NC cores; NT threads
+#: modules/devices.c:154
+#, c-format
+msgid "%s; %s; %s"
+msgstr ""
+
+#: modules/devices.c:572
+msgid "Field"
+msgstr "Поле"
+
+#: modules/devices.c:572 modules/devices.c:604
+msgid "Value"
+msgstr "Значение"
+
+#: modules/devices.c:604
+msgid "Sensor"
+msgstr "Сенсор"
+
+#: modules/devices.c:604 modules/devices/dmi.c:53
+#: modules/devices/inputdevices.c:117
+msgid "Type"
+msgstr "Тип"
+
+#: modules/devices.c:650
+msgid "Devices"
+msgstr "Устройства"
+
+#: modules/devices.c:662
+msgid "Update PCI ID listing"
+msgstr "Обновить список PCI ID"
+
+#: modules/devices.c:674
+msgid "Update CPU feature database"
+msgstr "Обновить базу данных функций процессора"
+
+#: modules/devices.c:702
+msgid "Gathers information about hardware devices"
+msgstr "Собирает информацию об устройствах"
+
+#: modules/devices.c:721
+msgid "Resource information requires superuser privileges"
+msgstr "Для вывода информации о ресурсах нужны права администратора"
+
+#: modules/devices/devicetree.c:50
+msgid "Properties"
+msgstr ""
+
+#: modules/devices/devicetree.c:51
+msgid "Children"
+msgstr ""
+
+#: modules/devices/devicetree.c:87
+msgid "Node"
+msgstr ""
+
+#: modules/devices/devicetree.c:88
+msgid "Node Path"
+msgstr ""
+
+#: modules/devices/devicetree.c:89
+msgid "Alias"
+msgstr ""
+
+#: modules/devices/devicetree.c:89 modules/devices/devicetree.c:90
+msgid "(None)"
+msgstr ""
+
+#: modules/devices/devicetree.c:90
+msgid "Symbol"
+msgstr ""
+
+#: modules/devices/devicetree.c:143 modules/devices/devicetree/pmac_data.c:79
+msgid "Platform"
+msgstr ""
+
+#: modules/devices/devicetree.c:144 modules/devices/devicetree.c:209
+msgid "Compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:145
+msgid "GPU-compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:160
+msgid "Raspberry Pi or Compatible"
+msgstr ""
+
+#: modules/devices/devicetree.c:162 modules/devices/devicetree.c:189
+#: modules/devices/devicetree.c:208 modules/devices/devicetree/rpi_data.c:160
+#: modules/devices/dmi.c:49 modules/devices/dmi.c:55
+msgid "Serial Number"
+msgstr "Серийный номер"
+
+#: modules/devices/devicetree.c:163 modules/devices/devicetree/rpi_data.c:157
+msgid "RCode"
+msgstr ""
+
+#: modules/devices/devicetree.c:163
+msgid "No revision code available; unable to lookup model details."
+msgstr ""
+
+#: modules/devices/devicetree.c:188
+msgid "More"
+msgstr ""
+
+#: modules/devices/devicetree.c:268
+msgid "Messages"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:78
+msgid "Apple Power Macintosh"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:83
+msgid "Detected as"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:84
+msgid "PMAC Flags"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:85
+msgid "L2 Cache"
+msgstr ""
+
+#: modules/devices/devicetree/pmac_data.c:86
+msgid "PMAC Generation"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:152
+#: modules/devices/devicetree/rpi_data.c:153
+msgid "Raspberry Pi"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:153
+msgid "Board Name"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:154
+msgid "PCB Revision"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:155
+msgid "Introduction"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:156 modules/devices/spd-decode.c:1510
+#: modules/devices/usb.c:84 modules/devices/usb.c:217
+msgid "Manufacturer"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:158
+msgid "SOC (spec)"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:159
+msgid "Memory (spec)"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgid "Permanent overvolt bit"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgctxt "rpi-ov-bit"
+msgid "Set"
+msgstr ""
+
+#: modules/devices/devicetree/rpi_data.c:161
+msgctxt "rpi-ov-bit"
+msgid "Not set"
+msgstr ""
+
+#: modules/devices/devmemory.c:101
+msgid "Total Memory"
+msgstr "Общая память"
+
+#: modules/devices/devmemory.c:102
+msgid "Free Memory"
+msgstr "Свободная память"
+
+#: modules/devices/devmemory.c:103
+msgid "Cached Swap"
+msgstr "Кэш подкачки"
+
+#: modules/devices/devmemory.c:104
+msgid "High Memory"
+msgstr "Высокая память"
+
+#: modules/devices/devmemory.c:105
+msgid "Free High Memory"
+msgstr "Свободная высокая память"
+
+#: modules/devices/devmemory.c:106
+msgid "Low Memory"
+msgstr "Низкая память"
+
+#: modules/devices/devmemory.c:107
+msgid "Free Low Memory"
+msgstr "Свободная низкая память"
+
+#: modules/devices/devmemory.c:108
+msgid "Virtual Memory"
+msgstr "Виртуальная память"
+
+#: modules/devices/devmemory.c:109
+msgid "Free Virtual Memory"
+msgstr "Свободная виртуальная память"
+
+#: modules/devices/dmi.c:36 modules/devices/inputdevices.c:120
+#: modules/devices/usb.c:83 modules/devices/usb.c:216 modules/devices/usb.c:348
+msgid "Product"
+msgstr "Продукт"
+
+#: modules/devices/dmi.c:38 modules/devices/ia64/processor.c:164
+#: modules/devices/sh/processor.c:86
+msgid "Family"
+msgstr "Семейство"
+
+#: modules/devices/dmi.c:41
+msgid "BIOS"
+msgstr ""
+
+#: modules/devices/dmi.c:50 modules/devices/dmi.c:56
+msgid "Asset Tag"
+msgstr ""
+
+#: modules/devices/dmi.c:51
+msgid "Chassis"
+msgstr "Шасси"
+
+#: modules/devices/dmi.c:116
+msgid "(Not available; Perhaps try running HardInfo as root.)"
+msgstr "(Недоступно, попробуйте выполнить HardInfo с правами администратора.)"
+
+#: modules/devices/ia64/processor.c:108
+msgid "IA64 Processor"
+msgstr "Процессор IA64"
+
+#: modules/devices/ia64/processor.c:163
+msgid "Architecture Revision"
+msgstr "Ревизия архитектуры"
+
+#: modules/devices/ia64/processor.c:170
+msgid "CPU regs"
+msgstr "Регистры"
+
+#: modules/devices/ia64/processor.c:171
+msgid "Features"
+msgstr "Возможности"
+
+#: modules/devices/inputdevices.c:115 modules/devices/pci.c:214
+#: modules/devices/usb.c:82 modules/devices/usb.c:215 modules/devices/usb.c:347
+msgid "Device Information"
+msgstr "Информация об устройстве"
+
+#: modules/devices/inputdevices.c:118 modules/devices/usb.c:92
+#: modules/devices/usb.c:240 modules/devices/usb.c:356
+msgid "Bus"
+msgstr "Шина"
+
+#: modules/devices/inputdevices.c:124
+msgid "Connected to"
+msgstr "Подключен к"
+
+#: modules/devices/inputdevices.c:128
+msgid "InfraRed port"
+msgstr "Инфракрасный порт"
+
+#: modules/devices/m68k/processor.c:85 modules/devices/riscv/processor.c:185
+msgid "MMU"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:86 modules/devices/sparc/processor.c:76
+msgid "FPU"
+msgstr ""
+
+#: modules/devices/m68k/processor.c:90
+msgid "Calibration"
+msgstr "Калибровка"
+
+#: modules/devices/mips/processor.c:76
+msgid "System Type"
+msgstr "Тип системы"
+
+#: modules/devices/parisc/processor.c:107
+msgid "PA-RISC Processor"
+msgstr "Процессор PA-RISC"
+
+#: modules/devices/parisc/processor.c:157
+msgid "System"
+msgstr "Система"
+
+#: modules/devices/parisc/processor.c:161
+msgid "HVersion"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:162
+msgid "SVersion"
+msgstr ""
+
+#: modules/devices/parisc/processor.c:163 modules/devices/x86/processor.c:425
+msgid "Cache"
+msgstr "Кэш"
+
+#: modules/devices/pci.c:106
+msgid "IRQ"
+msgstr ""
+
+#: modules/devices/pci.c:110
+msgid "Latency"
+msgstr "Отклик"
+
+#: modules/devices/pci.c:112
+msgid "Bus Master"
+msgstr "Главная шина"
+
+#: modules/devices/pci.c:118
+msgid "Kernel modules"
+msgstr "Модули ядра"
+
+#: modules/devices/pci.c:124
+#, c-format
+msgid "%s=%s (%s)\n"
+msgstr ""
+
+#: modules/devices/pci.c:126
+msgid "OEM Vendor"
+msgstr "Производитель OEM"
+
+#: modules/devices/pci.c:153
+msgid "prefetchable"
+msgstr ""
+
+#: modules/devices/pci.c:154
+msgid "non-prefetchable"
+msgstr ""
+
+#: modules/devices/pci.c:163
+msgid "I/O ports at"
+msgstr "Порты ввода/вывода на"
+
+#: modules/devices/pci.c:216 modules/devices/usb.c:89 modules/devices/usb.c:237
+#: modules/devices/usb.c:353
+msgid "Class"
+msgstr "Класс"
+
+#: modules/devices/pci.c:217
+msgid "Domain"
+msgstr "Домен"
+
+#: modules/devices/pci.c:218
+msgid "Bus, device, function"
+msgstr "Шина, устройство, функция"
+
+#: modules/devices/pci.c:243
+msgid "No PCI devices found"
+msgstr "Устройства PCI не найдены"
+
+#: modules/devices/ppc/processor.c:117
+msgid "POWER Processor"
+msgstr "Процессор POWER"
+
+#: modules/devices/printers.c:81
+msgid "⚬ Can do black and white printing=\n"
+msgstr "⚬ Может печатать черно-белым=\n"
+
+#: modules/devices/printers.c:83
+msgid "⚬ Can do color printing=\n"
+msgstr "⚬ Может печатать цветным=\n"
+
+#: modules/devices/printers.c:85
+#, fuzzy
+msgid "⚬ Can do duplexing=\n"
+msgstr "Не исправлять:"
+
+#: modules/devices/printers.c:87
+#, fuzzy
+msgid "⚬ Can do staple output=\n"
+msgstr "Выходной файл не может быть переименован."
+
+#: modules/devices/printers.c:89
+msgid "⚬ Can do copies=\n"
+msgstr "⚬ Можно делать копии=\n"
+
+#: modules/devices/printers.c:91
+msgid "⚬ Can collate copies=\n"
+msgstr "⚬ Можно сравнивать копии=\n"
+
+#: modules/devices/printers.c:93
+msgid "⚬ Printer is rejecting jobs=\n"
+msgstr "⚬ Принтер отклоняет задачи=\n"
+
+#: modules/devices/printers.c:95
+msgid "⚬ Printer was automatically discovered and added=\n"
+msgstr "⚬ Принтер был автоматически найден и добавлен=\n"
+
+#: modules/devices/printers.c:110
+msgid "Idle"
+msgstr "Неактивен"
+
+#: modules/devices/printers.c:112
+msgid "Printing a Job"
+msgstr "Печатается задача"
+
+#: modules/devices/printers.c:114
+msgid "Stopped"
+msgstr "Остановлен"
+
+#: modules/devices/printers.c:190
+msgid ""
+"[Printers]\n"
+"No suitable CUPS library found="
+msgstr ""
+"[Принтеры]\n"
+"Подходящей библиотеки CUPS не найдено="
+
+#: modules/devices/printers.c:200
+msgid "[Printers (CUPS)]\n"
+msgstr "[Принтеры (CUPS)]\n"
+
+#: modules/devices/printers.c:263
+msgid ""
+"[Printers]\n"
+"No printers found=\n"
+msgstr ""
+"[Принтеры]\n"
+"Принтеры не найдены=\n"
+
+#: modules/devices/riscv/processor.c:107
+msgid "RISC-V Processor"
+msgstr "Процессор RISC-V"
+
+#: modules/devices/riscv/processor.c:184
+msgid "uarch"
+msgstr ""
+
+#. /ext:RV32
+#: modules/devices/riscv/riscv_data.c:37
+msgctxt "rv-ext"
+msgid "RISC-V 32-bit"
+msgstr "32-битная RISC-V"
+
+#. /ext:RV64
+#: modules/devices/riscv/riscv_data.c:38
+msgctxt "rv-ext"
+msgid "RISC-V 64-bit"
+msgstr "64-битная RISC-V"
+
+#. /ext:RV128
+#: modules/devices/riscv/riscv_data.c:39
+msgctxt "rv-ext"
+msgid "RISC-V 128-bit"
+msgstr "128-битная RISC-V"
+
+#. /ext:E
+#: modules/devices/riscv/riscv_data.c:40
+msgctxt "rv-ext"
+msgid "Base embedded integer instructions (15 registers)"
+msgstr "Базовые встроенные целочисленные инструкции (15 регистров)"
+
+#. /ext:I
+#: modules/devices/riscv/riscv_data.c:41
+msgctxt "rv-ext"
+msgid "Base integer instructions (31 registers)"
+msgstr "Базовые целочисленные инструкции (31 регистр)"
+
+#. /ext:M
+#: modules/devices/riscv/riscv_data.c:42
+msgctxt "rv-ext"
+msgid "Hardware integer multiply and divide"
+msgstr "Аппаратное умножение и деление целых чисел"
+
+#. /ext:A
+#: modules/devices/riscv/riscv_data.c:43
+msgctxt "rv-ext"
+msgid "Atomic memory operations"
+msgstr "Атомные операции с памятью"
+
+#. /ext:C
+#: modules/devices/riscv/riscv_data.c:44
+msgctxt "rv-ext"
+msgid "Compressed 16-bit instructions"
+msgstr "Сжатые 16-битные инструкции"
+
+#. /ext:F
+#: modules/devices/riscv/riscv_data.c:45
+msgctxt "rv-ext"
+msgid "Floating-point instructions, single-precision"
+msgstr "Инструкции с плавающей запятой, одинарной точности"
+
+#. /ext:D
+#: modules/devices/riscv/riscv_data.c:46
+msgctxt "rv-ext"
+msgid "Floating-point instructions, double-precision"
+msgstr "Инструкции с плавающей запятой, двойной точности"
+
+#. /ext:Q
+#: modules/devices/riscv/riscv_data.c:47
+msgctxt "rv-ext"
+msgid "Floating-point instructions, quad-precision"
+msgstr "Инструкции с плавающей запятой, четверной точности"
+
+#. /ext:B
+#: modules/devices/riscv/riscv_data.c:48
+msgctxt "rv-ext"
+msgid "Bit manipulation instructions"
+msgstr "Инструкции манипуляции битами"
+
+#. /ext:V
+#: modules/devices/riscv/riscv_data.c:49
+msgctxt "rv-ext"
+msgid "Vector operations"
+msgstr "Векторные операции"
+
+#. /ext:T
+#: modules/devices/riscv/riscv_data.c:50
+msgctxt "rv-ext"
+msgid "Transactional memory"
+msgstr "Переходная память"
+
+#. /ext:P
+#: modules/devices/riscv/riscv_data.c:51
+msgctxt "rv-ext"
+msgid "Packed SIMD instructions"
+msgstr "Сжатые инструкции SIMD"
+
+#. /ext:L
+#: modules/devices/riscv/riscv_data.c:52
+msgctxt "rv-ext"
+msgid "Decimal floating-point instructions"
+msgstr "Десятичные инструкции с плавающей запятой"
+
+#. /ext:J
+#: modules/devices/riscv/riscv_data.c:53
+msgctxt "rv-ext"
+msgid "Dynamically translated languages"
+msgstr "Языки с динамической трансляцией"
+
+#. /ext:N
+#: modules/devices/riscv/riscv_data.c:54
+msgctxt "rv-ext"
+msgid "User-level interrupts"
+msgstr "Прерывания пользовательского уровня"
+
+#: modules/devices/s390/processor.c:92
+msgid "S390 Processor"
+msgstr "Процессор S390"
+
+#: modules/devices/s390/processor.c:133
+msgid "ID String"
+msgstr "Строка ID"
+
+#: modules/devices/sh/processor.c:55
+msgid "SuperH Processor"
+msgstr "Процессор SuperH"
+
+#: modules/devices/sh/processor.c:88
+msgid "Bus Frequency"
+msgstr "Частота шины"
+
+#: modules/devices/sh/processor.c:89
+msgid "Module Frequency"
+msgstr "Частота модуля"
+
+#: modules/devices/spd-decode.c:1475
+msgid ""
+"[SPD]\n"
+"Please load the eeprom module to obtain information about memory SPD=\n"
+"[$ShellParam$]\n"
+"ReloadInterval=500\n"
+msgstr ""
+"[SPD]\n"
+"Пожалуйста, загрузите модуль eeprom для получения информации о памяти SPD=\n"
+"[$ShellParam$]\n"
+"ReloadInterval=500\n"
+
+#: modules/devices/spd-decode.c:1480
+msgid ""
+"[SPD]\n"
+"Reading memory SPD not supported on this system=\n"
+msgstr ""
+"[SPD]\n"
+"Чтение памяти SPD не поддерживается на данной системе=\n"
+
+#: modules/devices/spd-decode.c:1509
+msgid "SPD"
+msgstr ""
+
+#: modules/devices/spd-decode.c:1510
+msgid "Bank"
+msgstr ""
+
+#: modules/devices/storage.c:46
+msgid ""
+"\n"
+"[SCSI Disks]\n"
+msgstr ""
+"\n"
+"[SCSI диски]\n"
+
+#: modules/devices/storage.c:110 modules/devices/storage.c:313
+#, c-format
+msgid ""
+"[Device Information]\n"
+"Model=%s\n"
+msgstr ""
+"[Информация об устройстве]\n"
+"Модель=%s\n"
+
+#: modules/devices/storage.c:115 modules/devices/storage.c:319
+#, c-format
+msgid "Vendor=%s (%s)\n"
+msgstr "Изготовитель=%s (%s)\n"
+
+#: modules/devices/storage.c:120 modules/devices/storage.c:321
+#, c-format
+msgid "Vendor=%s\n"
+msgstr "Изготовитель=%s\n"
+
+#: modules/devices/storage.c:125
+#, c-format
+msgid ""
+"Type=%s\n"
+"Revision=%s\n"
+"[SCSI Controller]\n"
+"Controller=scsi%d\n"
+"Channel=%d\n"
+"ID=%d\n"
+"LUN=%d\n"
+msgstr ""
+"Тип=%s\n"
+"Ревизия=%s\n"
+"[SCSI контроллер]\n"
+"Контроллер=scsi%d\n"
+"Канал=%d\n"
+"ID=%d\n"
+"LUN=%d\n"
+
+#: modules/devices/storage.c:167
+msgid ""
+"\n"
+"[IDE Disks]\n"
+msgstr ""
+"\n"
+"[IDE диски]\n"
+
+#: modules/devices/storage.c:250
+#, c-format
+msgid "Driver=%s\n"
+msgstr "Драйвер=%s\n"
+
+#: modules/devices/storage.c:324
+#, c-format
+msgid ""
+"Device Name=hd%c\n"
+"Media=%s\n"
+"Cache=%dkb\n"
+msgstr ""
+"Имя устройства=hd%c\n"
+"Медиа=%s\n"
+"Кэш=%d кБ\n"
+
+#: modules/devices/storage.c:334
+#, c-format
+msgid ""
+"[Geometry]\n"
+"Physical=%s\n"
+"Logical=%s\n"
+msgstr ""
+"[Геометрия]\n"
+"Физическая=%s\n"
+"Логическая=%s\n"
+
+#: modules/devices/storage.c:344
+#, c-format
+msgid ""
+"[Capabilities]\n"
+"%s"
+msgstr ""
+"[Возможности]\n"
+"%s"
+
+#: modules/devices/storage.c:351
+#, c-format
+msgid ""
+"[Speeds]\n"
+"%s"
+msgstr ""
+"[Скорости]\n"
+"%s"
+
+#: modules/devices/usb.c:44 modules/devices/usb.c:326
+msgid "mA"
+msgstr "мА"
+
+#. /%.2f is version
+#: modules/devices/usb.c:53 modules/devices/usb.c:190
+#, c-format
+msgid "USB %.2f Hub"
+msgstr ""
+
+#: modules/devices/usb.c:55 modules/devices/usb.c:192
+#, c-format
+msgid "Unknown USB %.2f Device (class %d)"
+msgstr ""
+
+#: modules/devices/usb.c:85 modules/devices/usb.c:232
+msgid "Speed"
+msgstr ""
+
+#: modules/devices/usb.c:85 modules/devices/usb.c:232
+msgid "Mbit/s"
+msgstr ""
+
+#: modules/devices/usb.c:86 modules/devices/usb.c:233 modules/devices/usb.c:350
+msgid "Max Current"
+msgstr "Максимальная сила тока"
+
+#: modules/devices/usb.c:88 modules/devices/usb.c:235 modules/devices/usb.c:352
+msgid "USB Version"
+msgstr "Версия USB"
+
+#: modules/devices/usb.c:90 modules/devices/usb.c:238 modules/devices/usb.c:354
+msgid "Vendor ID"
+msgstr "ID поставщика"
+
+#: modules/devices/usb.c:91 modules/devices/usb.c:239 modules/devices/usb.c:355
+msgid "Product ID"
+msgstr "ID продукта"
+
+#: modules/devices/usb.c:231
+msgid "Port"
+msgstr ""
+
+#: modules/devices/usb.c:241
+msgid "Level"
+msgstr ""
+
+#: modules/devices/x86/processor.c:149
+msgid "Cache information not available=\n"
+msgstr "Информация о кэше недоступна=\n"
+
+#: modules/devices/x86/processor.c:155
+#, c-format
+msgid "Level %d (%s)=%d-way set-associative, %d sets, %dKB size\n"
+msgstr ""
+"Уровень %d (%s)=%d-канальный множественно-ассоциативный, %d множеств, размер "
+"%d кБ\n"
+
+#. /cache type, as appears in: Level 1 (Data)
+#: modules/devices/x86/processor.c:170
+msgctxt "cache-type"
+msgid "Data"
+msgstr "данные"
+
+#. /cache type, as appears in: Level 1 (Instruction)
+#: modules/devices/x86/processor.c:171
+msgctxt "cache-type"
+msgid "Instruction"
+msgstr "инструкции"
+
+#. /cache type, as appears in: Level 2 (Unified)
+#: modules/devices/x86/processor.c:172
+msgctxt "cache-type"
+msgid "Unified"
+msgstr "унифицированный"
+
+#: modules/devices/x86/processor.c:410
+msgid "Model Name"
+msgstr "Название"
+
+#: modules/devices/x86/processor.c:411
+msgid "Family, model, stepping"
+msgstr "Семейство, модель, степпинг"
+
+#: modules/devices/x86/processor.c:417
+msgid "Microcode Version"
+msgstr "Версия микрокода"
+
+#: modules/devices/x86/processor.c:418
+msgid "Configuration"
+msgstr "Конфигурация"
+
+#: modules/devices/x86/processor.c:419
+msgid "Cache Size"
+msgstr "Размер кэша"
+
+#: modules/devices/x86/processor.c:419
+msgid "kb"
+msgstr "кБ"
+
+#: modules/devices/x86/processor.c:426
+msgid "Power Management"
+msgstr "Управление питанием"
+
+#: modules/devices/x86/processor.c:427
+msgid "Bug Workarounds"
+msgstr "Обход багов"
+
+#: modules/devices/x86/processor.c:454 modules/devices/x86/processor.c:468
+msgid "Package Information"
+msgstr "Информация о комплекте"
+
+#. /flag:fpu
+#: modules/devices/x86/x86_data.c:43
+msgctxt "x86-flag"
+msgid "Onboard FPU (floating point support)"
+msgstr "Встроенный FPU (поддержка плавающей запятой)"
+
+#. /flag:vme
+#: modules/devices/x86/x86_data.c:44
+msgctxt "x86-flag"
+msgid "Virtual 8086 mode enhancements"
+msgstr "Улучшения виртуального режима 8086"
+
+#. /flag:de
+#: modules/devices/x86/x86_data.c:45
+msgctxt "x86-flag"
+msgid "Debugging Extensions (CR4.DE)"
+msgstr "Расширения отладки (CR4.DE)"
+
+#. /flag:pse
+#: modules/devices/x86/x86_data.c:46
+msgctxt "x86-flag"
+msgid "Page Size Extensions (4MB memory pages)"
+msgstr "Расширения размера страницы (страницы памяти 4 Мб)"
+
+#. /flag:tsc
+#: modules/devices/x86/x86_data.c:47
+msgctxt "x86-flag"
+msgid "Time Stamp Counter (RDTSC)"
+msgstr "Счетчик временной метки (RDTSC)"
+
+#. /flag:msr
+#: modules/devices/x86/x86_data.c:48
+msgctxt "x86-flag"
+msgid "Model-Specific Registers (RDMSR, WRMSR)"
+msgstr "Регистры конкретной модели (RDMSR, WRMSR)"
+
+#. /flag:pae
+#: modules/devices/x86/x86_data.c:49
+msgctxt "x86-flag"
+msgid "Physical Address Extensions (support for more than 4GB of RAM)"
+msgstr "Расширения физического адреса (поддержка более 4 Гб ОЗУ)"
+
+#. /flag:mce
+#: modules/devices/x86/x86_data.c:50
+msgctxt "x86-flag"
+msgid "Machine Check Exception"
+msgstr "Исключение машинного контроля"
+
+#. /flag:cx8
+#: modules/devices/x86/x86_data.c:51
+msgctxt "x86-flag"
+msgid "CMPXCHG8 instruction (64-bit compare-and-swap)"
+msgstr "Инструкция CMPXCHG8 (64-битное сравнение-и-подкачка)"
+
+#. /flag:apic
+#: modules/devices/x86/x86_data.c:52
+msgctxt "x86-flag"
+msgid "Onboard APIC"
+msgstr "Встроенный APIC"
+
+#. /flag:sep
+#: modules/devices/x86/x86_data.c:53
+msgctxt "x86-flag"
+msgid "SYSENTER/SYSEXIT"
+msgstr ""
+
+#. /flag:mtrr
+#: modules/devices/x86/x86_data.c:54
+msgctxt "x86-flag"
+msgid "Memory Type Range Registers"
+msgstr "Регистры диапазона типа памяти"
+
+#. /flag:pge
+#: modules/devices/x86/x86_data.c:55
+msgctxt "x86-flag"
+msgid "Page Global Enable (global bit in PDEs and PTEs)"
+msgstr "Включение глобальной страницы (глобальный бит в PDE и PTE)"
+
+#. /flag:mca
+#: modules/devices/x86/x86_data.c:56
+msgctxt "x86-flag"
+msgid "Machine Check Architecture"
+msgstr "Архитектура машинного контроля"
+
+#. /flag:cmov
+#: modules/devices/x86/x86_data.c:57
+msgctxt "x86-flag"
+msgid "CMOV instructions (conditional move) (also FCMOV)"
+msgstr "Инструкции CMOV (условная пересылка данных) (также FCMOV)"
+
+#. /flag:pat
+#: modules/devices/x86/x86_data.c:58
+msgctxt "x86-flag"
+msgid "Page Attribute Table"
+msgstr "Таблица атрибутов страницы"
+
+#. /flag:pse36
+#: modules/devices/x86/x86_data.c:59
+msgctxt "x86-flag"
+msgid "36-bit PSEs (huge pages)"
+msgstr "36-битные PSE (огромные страницы)"
+
+#. /flag:pn
+#: modules/devices/x86/x86_data.c:60
+msgctxt "x86-flag"
+msgid "Processor serial number"
+msgstr "Серийный номер процессора"
+
+#. /flag:clflush
+#: modules/devices/x86/x86_data.c:61
+msgctxt "x86-flag"
+msgid "Cache Line Flush instruction"
+msgstr "Инструкция Cache Line Flush"
+
+#. /flag:dts
+#: modules/devices/x86/x86_data.c:62
+msgctxt "x86-flag"
+msgid ""
+"Debug Store (buffer for debugging and profiling instructions), or "
+"alternately: digital thermal sensor"
+msgstr ""
+
+#. /flag:acpi
+#: modules/devices/x86/x86_data.c:63
+msgctxt "x86-flag"
+msgid "ACPI via MSR (temperature monitoring and clock speed modulation)"
+msgstr "ACPI через MSR (мониторинг температуры и модуляции тактовой частоты)"
+
+#. /flag:mmx
+#: modules/devices/x86/x86_data.c:64
+msgctxt "x86-flag"
+msgid "Multimedia Extensions"
+msgstr "Расширения мультимедиа"
+
+#. /flag:fxsr
+#: modules/devices/x86/x86_data.c:65
+msgctxt "x86-flag"
+msgid "FXSAVE/FXRSTOR, CR4.OSFXSR"
+msgstr ""
+
+#. /flag:sse
+#: modules/devices/x86/x86_data.c:66
+msgctxt "x86-flag"
+msgid "Intel SSE vector instructions"
+msgstr "Векторные инструкции Intel SSE"
+
+#. /flag:sse2
+#: modules/devices/x86/x86_data.c:67
+msgctxt "x86-flag"
+msgid "SSE2"
+msgstr ""
+
+#. /flag:ss
+#: modules/devices/x86/x86_data.c:68
+msgctxt "x86-flag"
+msgid "CPU self snoop"
+msgstr "Проверка процессора"
+
+#. /flag:ht
+#: modules/devices/x86/x86_data.c:69
+msgctxt "x86-flag"
+msgid "Hyper-Threading"
+msgstr "Многопоточность (Hyper-Threading)"
+
+#. /flag:tm
+#: modules/devices/x86/x86_data.c:70
+msgctxt "x86-flag"
+msgid "Automatic clock control (Thermal Monitor)"
+msgstr "Автоматический контроль частоты (монитор температуры)"
+
+#. /flag:ia64
+#: modules/devices/x86/x86_data.c:71
+msgctxt "x86-flag"
+msgid ""
+"Intel Itanium Architecture 64-bit (not to be confused with Intel's 64-bit "
+"x86 architecture with flag x86-64 or \"AMD64\" bit indicated by flag lm)"
+msgstr ""
+"64-битная архитектура Intel Itanium (не путать с 64-битной архитектурой x86 "
+"от Intel с флагом x86-64 или \"AMD64\"-битной с флагом bit)"
+
+#. /flag:pbe
+#: modules/devices/x86/x86_data.c:72
+msgctxt "x86-flag"
+msgid "Pending Break Enable (PBE# pin) wakeup support"
+msgstr "Поддержка пробуждения Pending Break Enable (PBE# pin)"
+
+#. /flag:syscall
+#: modules/devices/x86/x86_data.c:75
+msgctxt "x86-flag"
+msgid "SYSCALL (Fast System Call) and SYSRET (Return From Fast System Call)"
+msgstr ""
+"SYSCALL (Быстрый вызов системы) и SYSRET (Возврат после быстрого вызова "
+"системы)"
+
+#. /flag:mp
+#: modules/devices/x86/x86_data.c:76
+msgctxt "x86-flag"
+msgid "Multiprocessing Capable."
+msgstr "Возможна работа в многопроцессном режиме."
+
+#. /flag:nx
+#: modules/devices/x86/x86_data.c:77
+msgctxt "x86-flag"
+msgid "Execute Disable"
+msgstr "Выполнение отключено"
+
+#. /flag:mmxext
+#: modules/devices/x86/x86_data.c:78
+msgctxt "x86-flag"
+msgid "AMD MMX extensions"
+msgstr "Расширения AMD MMX"
+
+#. /flag:fxsr_opt
+#: modules/devices/x86/x86_data.c:79
+msgctxt "x86-flag"
+msgid "FXSAVE/FXRSTOR optimizations"
+msgstr "Оптимизации FXSAVE/FXRSTOR"
+
+#. /flag:pdpe1gb
+#: modules/devices/x86/x86_data.c:80
+msgctxt "x86-flag"
+msgid "One GB pages (allows hugepagesz=1G)"
+msgstr "Страница размером 1 Гб (разрешает hugepagesz=1G)"
+
+#. /flag:rdtscp
+#: modules/devices/x86/x86_data.c:81
+msgctxt "x86-flag"
+msgid "Read Time-Stamp Counter and Processor ID"
+msgstr "Чтение счетчика временной метки и ID процессора"
+
+#. /flag:lm
+#: modules/devices/x86/x86_data.c:82
+msgctxt "x86-flag"
+msgid "Long Mode (x86-64: amd64, also known as Intel 64, i.e. 64-bit capable)"
+msgstr ""
+"Длинный режим (x86-64: amd64, также известен как Intel 64, т.е. совместимый "
+"с 64-бит)"
+
+#. /flag:3dnow
+#: modules/devices/x86/x86_data.c:83
+msgctxt "x86-flag"
+msgid "3DNow! (AMD vector instructions, competing with Intel's SSE1)"
+msgstr "3DNow! (векторные инструкции AMD, конкурируют с SSE1 от Intel)"
+
+#. /flag:3dnowext
+#: modules/devices/x86/x86_data.c:84
+msgctxt "x86-flag"
+msgid "AMD 3DNow! extensions"
+msgstr "Расширения AMD 3DNow!"
+
+#. /flag:recovery
+#: modules/devices/x86/x86_data.c:86
+msgctxt "x86-flag"
+msgid "CPU in recovery mode"
+msgstr "Процессор в режиме восстановления"
+
+#. /flag:longrun
+#: modules/devices/x86/x86_data.c:87
+msgctxt "x86-flag"
+msgid "Longrun power control"
+msgstr "Управление питанием LongRun"
+
+#. /flag:lrti
+#: modules/devices/x86/x86_data.c:88
+msgctxt "x86-flag"
+msgid "LongRun table interface"
+msgstr "Интерфейс таблицы LongRun"
+
+#. /flag:cxmmx
+#: modules/devices/x86/x86_data.c:90
+msgctxt "x86-flag"
+msgid "Cyrix MMX extensions"
+msgstr "Расширения Cyrix MMX"
+
+#. /flag:k6_mtrr
+#: modules/devices/x86/x86_data.c:91
+msgctxt "x86-flag"
+msgid "AMD K6 nonstandard MTRRs"
+msgstr "Нестандартные диапазонные регистры типа памяти (MTRR) AMD K6"
+
+#. /flag:cyrix_arr
+#: modules/devices/x86/x86_data.c:92
+msgctxt "x86-flag"
+msgid "Cyrix ARRs (= MTRRs)"
+msgstr ""
+"Регистры адресного диапазона (ARR) Cyrix (= диапазонные регистры типа памяти "
+"(MTRR))"
+
+#. /flag:centaur_mcr
+#: modules/devices/x86/x86_data.c:93
+msgctxt "x86-flag"
+msgid "Centaur MCRs (= MTRRs)"
+msgstr ""
+"Сбросы мастер-контроля (MCR) Centaur (= диапазонные регистры типа памяти "
+"(MTRR))"
+
+#. /flag:constant_tsc
+#: modules/devices/x86/x86_data.c:94
+msgctxt "x86-flag"
+msgid "TSC ticks at a constant rate"
+msgstr "Счетчик метки времени (TSC) работает на постоянной частоте"
+
+#. /flag:up
+#: modules/devices/x86/x86_data.c:95
+msgctxt "x86-flag"
+msgid "SMP kernel running on UP"
+msgstr "Ядро SMP запущено на UP"
+
+#. /flag:art
+#: modules/devices/x86/x86_data.c:96
+msgctxt "x86-flag"
+msgid "Always-Running Timer"
+msgstr "Постоянный таймер"
+
+#. /flag:arch_perfmon
+#: modules/devices/x86/x86_data.c:97
+msgctxt "x86-flag"
+msgid "Intel Architectural PerfMon"
+msgstr "Архитектурный монитор призводительности Intel"
+
+#. /flag:pebs
+#: modules/devices/x86/x86_data.c:98
+msgctxt "x86-flag"
+msgid "Precise-Event Based Sampling"
+msgstr "Сэмплинг, основанный на точных событиях"
+
+#. /flag:bts
+#: modules/devices/x86/x86_data.c:99
+msgctxt "x86-flag"
+msgid "Branch Trace Store"
+msgstr "Хранилище отслеживания ветви"
+
+#. /flag:rep_good
+#: modules/devices/x86/x86_data.c:100
+msgctxt "x86-flag"
+msgid "rep microcode works well"
+msgstr "микрокод rep работает нормально"
+
+#. /flag:acc_power
+#: modules/devices/x86/x86_data.c:101
+msgctxt "x86-flag"
+msgid "AMD accumulated power mechanism"
+msgstr "Механизм накопления питания AMD"
+
+#. /flag:nopl
+#: modules/devices/x86/x86_data.c:102
+msgctxt "x86-flag"
+msgid "The NOPL (0F 1F) instructions"
+msgstr "Инструкции NOPL (0F 1F)"
+
+#. /flag:xtopology
+#: modules/devices/x86/x86_data.c:103
+msgctxt "x86-flag"
+msgid "cpu topology enum extensions"
+msgstr "расширения cpu топологии enum"
+
+#. /flag:tsc_reliable
+#: modules/devices/x86/x86_data.c:104
+msgctxt "x86-flag"
+msgid "TSC is known to be reliable"
+msgstr "Счетчик метки времени (TSC) считается надежным"
+
+#. /flag:nonstop_tsc
+#: modules/devices/x86/x86_data.c:105
+msgctxt "x86-flag"
+msgid "TSC does not stop in C states"
+msgstr "Счетчик метки времени (TSC) не останавливается в состояниях C"
+
+#. /flag:extd_apicid
+#: modules/devices/x86/x86_data.c:106
+msgctxt "x86-flag"
+msgid "has extended APICID (8 bits)"
+msgstr "имеются расширенные APICID (8 бит)"
+
+#. /flag:amd_dcm
+#: modules/devices/x86/x86_data.c:107
+msgctxt "x86-flag"
+msgid "multi-node processor"
+msgstr "многоузловой процессор"
+
+#. /flag:aperfmperf
+#: modules/devices/x86/x86_data.c:108
+msgctxt "x86-flag"
+msgid "APERFMPERF"
+msgstr ""
+
+#. /flag:eagerfpu
+#: modules/devices/x86/x86_data.c:109
+msgctxt "x86-flag"
+msgid "Non lazy FPU restore"
+msgstr "Неленивое восстановление FPU"
+
+#. /flag:nonstop_tsc_s3
+#: modules/devices/x86/x86_data.c:110
+msgctxt "x86-flag"
+msgid "TSC doesn't stop in S3 state"
+msgstr "Счетчик метки времени (TSC) не останавливается в состоянии S3"
+
+#. /flag:mce_recovery
+#: modules/devices/x86/x86_data.c:111
+msgctxt "x86-flag"
+msgid "CPU has recoverable machine checks"
+msgstr "У процессора есть возможность восстановить машинный контроль"
+
+#. /flag:pni
+#: modules/devices/x86/x86_data.c:114
+msgctxt "x86-flag"
+msgid "SSE-3 (\"Prescott New Instructions\")"
+msgstr "SSE-3 (\"Новые инструкции Prescott\")"
+
+#. /flag:pclmulqdq
+#: modules/devices/x86/x86_data.c:115
+msgctxt "x86-flag"
+msgid ""
+"Perform a Carry-Less Multiplication of Quadword instruction - accelerator "
+"for GCM)"
+msgstr ""
+"Выполнение менее ресурсоемкого умножения инструкции учетверенного слова - "
+"ускоряет GCM)"
+
+#. /flag:dtes64
+#: modules/devices/x86/x86_data.c:116
+msgctxt "x86-flag"
+msgid "64-bit Debug Store"
+msgstr "Хранилище 64-битной отладки"
+
+#. /flag:monitor
+#: modules/devices/x86/x86_data.c:117
+msgctxt "x86-flag"
+msgid "Monitor/Mwait support (Intel SSE3 supplements)"
+msgstr "Поддержка Monitor/Mwait (дополняет Intel SSE3)"
+
+#. /flag:ds_cpl
+#: modules/devices/x86/x86_data.c:118
+msgctxt "x86-flag"
+msgid "CPL Qual. Debug Store"
+msgstr "Хранилище отладки CPL Qual."
+
+#. /flag:vmx
+#: modules/devices/x86/x86_data.c:119
+msgctxt "x86-flag"
+msgid "Hardware virtualization, Intel VMX"
+msgstr "Аппаратная виртуализация, Intel VMX"
+
+#. /flag:smx
+#: modules/devices/x86/x86_data.c:120
+msgctxt "x86-flag"
+msgid "Safer mode TXT (TPM support)"
+msgstr "Безопасный режим TXT (поддержка TPM)"
+
+#. /flag:est
+#: modules/devices/x86/x86_data.c:121
+msgctxt "x86-flag"
+msgid "Enhanced SpeedStep"
+msgstr "Технология энергосбережения Enhanced SpeedStep"
+
+#. /flag:tm2
+#: modules/devices/x86/x86_data.c:122
+msgctxt "x86-flag"
+msgid "Thermal Monitor 2"
+msgstr "Монитор температуры 2"
+
+#. /flag:ssse3
+#: modules/devices/x86/x86_data.c:123
+msgctxt "x86-flag"
+msgid "Supplemental SSE-3"
+msgstr "Дополнительный SSE-3"
+
+#. /flag:cid
+#: modules/devices/x86/x86_data.c:124
+msgctxt "x86-flag"
+msgid "Context ID"
+msgstr "ID контекста"
+
+#. /flag:sdbg
+#: modules/devices/x86/x86_data.c:125
+msgctxt "x86-flag"
+msgid "silicon debug"
+msgstr "отладка кремния"
+
+#. /flag:fma
+#: modules/devices/x86/x86_data.c:126
+msgctxt "x86-flag"
+msgid "Fused multiply-add"
+msgstr "Умножение-сложение с однократным округлением"
+
+#. /flag:cx16
+#: modules/devices/x86/x86_data.c:127
+msgctxt "x86-flag"
+msgid "CMPXCHG16B"
+msgstr ""
+
+#. /flag:xtpr
+#: modules/devices/x86/x86_data.c:128
+msgctxt "x86-flag"
+msgid "Send Task Priority Messages"
+msgstr "Отправлять сообщения о приоритете задач"
+
+#. /flag:pdcm
+#: modules/devices/x86/x86_data.c:129
+msgctxt "x86-flag"
+msgid "Performance Capabilities"
+msgstr "Возможности производительности"
+
+#. /flag:pcid
+#: modules/devices/x86/x86_data.c:130
+msgctxt "x86-flag"
+msgid "Process Context Identifiers"
+msgstr "Идентификаторы контекста процесса"
+
+#. /flag:dca
+#: modules/devices/x86/x86_data.c:131
+msgctxt "x86-flag"
+msgid "Direct Cache Access"
+msgstr "Прямой доступ к кэшу"
+
+#. /flag:sse4_1
+#: modules/devices/x86/x86_data.c:132
+msgctxt "x86-flag"
+msgid "SSE-4.1"
+msgstr ""
+
+#. /flag:sse4_2
+#: modules/devices/x86/x86_data.c:133
+msgctxt "x86-flag"
+msgid "SSE-4.2"
+msgstr ""
+
+#. /flag:x2apic
+#: modules/devices/x86/x86_data.c:134
+msgctxt "x86-flag"
+msgid "x2APIC"
+msgstr ""
+
+#. /flag:movbe
+#: modules/devices/x86/x86_data.c:135
+msgctxt "x86-flag"
+msgid "Move Data After Swapping Bytes instruction"
+msgstr "Инструкция переноса данных после подкачки байт"
+
+#. /flag:popcnt
+#: modules/devices/x86/x86_data.c:136
+msgctxt "x86-flag"
+msgid ""
+"Return the Count of Number of Bits Set to 1 instruction (Hamming weight, i."
+"e. bit count)"
+msgstr ""
+"Возвращение набора счетчика бит в 1 инструкцию (вес Хэмминга, т.е. счетчик "
+"бит)"
+
+#. /flag:tsc_deadline_timer
+#: modules/devices/x86/x86_data.c:137
+msgctxt "x86-flag"
+msgid "Tsc deadline timer"
+msgstr "Таймер окончания счетчика метки времени (TSC)"
+
+#. /flag:aes/aes-ni
+#: modules/devices/x86/x86_data.c:138
+msgctxt "x86-flag"
+msgid "Advanced Encryption Standard (New Instructions)"
+msgstr "Стандарт дополнительного шифрования (новые инструкции)"
+
+#. /flag:xsave
+#: modules/devices/x86/x86_data.c:139
+msgctxt "x86-flag"
+msgid "Save Processor Extended States: also provides XGETBY,XRSTOR,XSETBY"
+msgstr ""
+"Сохранение расширенных состояний процессора: также добавляет XGETBY,XRSTOR,"
+"XSETBY"
+
+#. /flag:avx
+#: modules/devices/x86/x86_data.c:140
+msgctxt "x86-flag"
+msgid "Advanced Vector Extensions"
+msgstr "Дополнительные векторные расширения"
+
+#. /flag:f16c
+#: modules/devices/x86/x86_data.c:141
+msgctxt "x86-flag"
+msgid "16-bit fp conversions (CVT16)"
+msgstr "16-битные конверсии fp (CVT16)"
+
+#. /flag:rdrand
+#: modules/devices/x86/x86_data.c:142
+msgctxt "x86-flag"
+msgid "Read Random Number from hardware random number generator instruction"
+msgstr "Инструкция считывания случайного числа из аппаратного генератора"
+
+#. /flag:hypervisor
+#: modules/devices/x86/x86_data.c:143
+msgctxt "x86-flag"
+msgid "Running on a hypervisor"
+msgstr "Запущено в гипервизоре"
+
+#. /Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001
+#. /flag:rng
+#: modules/devices/x86/x86_data.c:145
+msgctxt "x86-flag"
+msgid "Random Number Generator present (xstore)"
+msgstr "Наличие генератора случайных чисел (xstore)"
+
+#. /flag:rng_en
+#: modules/devices/x86/x86_data.c:146
+msgctxt "x86-flag"
+msgid "Random Number Generator enabled"
+msgstr "Генератор случайных чисел включен"
+
+#. /flag:ace
+#: modules/devices/x86/x86_data.c:147
+msgctxt "x86-flag"
+msgid "on-CPU crypto (xcrypt)"
+msgstr "шифрование на процессоре (xcrypt)"
+
+#. /flag:ace_en
+#: modules/devices/x86/x86_data.c:148
+msgctxt "x86-flag"
+msgid "on-CPU crypto enabled"
+msgstr "шифрование на процессоре включено"
+
+#. /flag:ace2
+#: modules/devices/x86/x86_data.c:149
+msgctxt "x86-flag"
+msgid "Advanced Cryptography Engine v2"
+msgstr ""
+
+#. /flag:ace2_en
+#: modules/devices/x86/x86_data.c:150
+msgctxt "x86-flag"
+msgid "ACE v2 enabled"
+msgstr "ACE v2 включен"
+
+#. /flag:phe
+#: modules/devices/x86/x86_data.c:151
+msgctxt "x86-flag"
+msgid "PadLock Hash Engine"
+msgstr "Движок контрольных сумм PadLock"
+
+#. /flag:phe_en
+#: modules/devices/x86/x86_data.c:152
+msgctxt "x86-flag"
+msgid "PHE enabled"
+msgstr "PHE включен"
+
+#. /flag:pmm
+#: modules/devices/x86/x86_data.c:153
+msgctxt "x86-flag"
+msgid "PadLock Montgomery Multiplier"
+msgstr "Множитель PadLock Montgomery"
+
+#. /flag:pmm_en
+#: modules/devices/x86/x86_data.c:154
+msgctxt "x86-flag"
+msgid "PMM enabled"
+msgstr "PMM включен"
+
+#. /flag:lahf_lm
+#: modules/devices/x86/x86_data.c:156
+msgctxt "x86-flag"
+msgid "Load AH from Flags (LAHF) and Store AH into Flags (SAHF) in long mode"
+msgstr ""
+"Загрузка AH из флагов (LAHF) и хранение AH в флагах (SAHF) в длинном режиме"
+
+#. /flag:cmp_legacy
+#: modules/devices/x86/x86_data.c:157
+msgctxt "x86-flag"
+msgid "If yes HyperThreading not valid"
+msgstr "Если да, многопоточность не работает"
+
+#. /flag:svm
+#: modules/devices/x86/x86_data.c:158
+msgctxt "x86-flag"
+msgid "\"Secure virtual machine\": AMD-V"
+msgstr "\"Безопасная виртуальная машина\": AMD-V"
+
+#. /flag:extapic
+#: modules/devices/x86/x86_data.c:159
+msgctxt "x86-flag"
+msgid "Extended APIC space"
+msgstr "Расширенное пространство APIC"
+
+#. /flag:cr8_legacy
+#: modules/devices/x86/x86_data.c:160
+msgctxt "x86-flag"
+msgid "CR8 in 32-bit mode"
+msgstr "CR8 в 32-битном режиме"
+
+#. /flag:abm
+#: modules/devices/x86/x86_data.c:161
+msgctxt "x86-flag"
+msgid "Advanced Bit Manipulation"
+msgstr "Дополнительное управление битами"
+
+#. /flag:sse4a
+#: modules/devices/x86/x86_data.c:162
+msgctxt "x86-flag"
+msgid "SSE-4A"
+msgstr ""
+
+#. /flag:misalignsse
+#: modules/devices/x86/x86_data.c:163
+msgctxt "x86-flag"
+msgid ""
+"indicates if a general-protection exception (#GP) is generated when some "
+"legacy SSE instructions operate on unaligned data. Also depends on CR0 and "
+"Alignment Checking bit"
+msgstr ""
+"показывает, если исключение из общей защиты (#GP) создано при использовании "
+"неверных данных некоторыми устаревшими инструкциями SSE. Также зависит от "
+"CR0 и бита проверки выравнивания"
+
+#. /flag:3dnowprefetch
+#: modules/devices/x86/x86_data.c:164
+msgctxt "x86-flag"
+msgid "3DNow prefetch instructions"
+msgstr "инструкции 3DNow prefetch"
+
+#. /flag:osvw
+#: modules/devices/x86/x86_data.c:165
+msgctxt "x86-flag"
+msgid ""
+"indicates OS Visible Workaround, which allows the OS to work around "
+"processor errata."
+msgstr ""
+"отображает OS Visible Workaround, позволяющий ОС работать в обход опечаток "
+"процессора."
+
+#. /flag:ibs
+#: modules/devices/x86/x86_data.c:166
+msgctxt "x86-flag"
+msgid "Instruction Based Sampling"
+msgstr "Сэмплинг, основанный на инструкциях"
+
+#. /flag:xop
+#: modules/devices/x86/x86_data.c:167
+msgctxt "x86-flag"
+msgid "extended AVX instructions"
+msgstr "расширенные инструкции AVX"
+
+#. /flag:skinit
+#: modules/devices/x86/x86_data.c:168
+msgctxt "x86-flag"
+msgid "SKINIT/STGI instructions"
+msgstr "инструкции SKINIT/STGI"
+
+#. /flag:wdt
+#: modules/devices/x86/x86_data.c:169
+msgctxt "x86-flag"
+msgid "Watchdog timer"
+msgstr "Сторожевой таймер"
+
+#. /flag:lwp
+#: modules/devices/x86/x86_data.c:170
+msgctxt "x86-flag"
+msgid "Light Weight Profiling"
+msgstr "Легковесное профилирование"
+
+#. /flag:fma4
+#: modules/devices/x86/x86_data.c:171
+msgctxt "x86-flag"
+msgid "4 operands MAC instructions"
+msgstr "Инструкции MAC 4 операндов"
+
+#. /flag:tce
+#: modules/devices/x86/x86_data.c:172
+msgctxt "x86-flag"
+msgid "translation cache extension"
+msgstr "расширение переноса кэша"
+
+#. /flag:nodeid_msr
+#: modules/devices/x86/x86_data.c:173
+msgctxt "x86-flag"
+msgid "NodeId MSR"
+msgstr ""
+
+#. /flag:tbm
+#: modules/devices/x86/x86_data.c:174
+msgctxt "x86-flag"
+msgid "Trailing Bit Manipulation"
+msgstr "Скользящее манипулирование битами"
+
+#. /flag:topoext
+#: modules/devices/x86/x86_data.c:175
+msgctxt "x86-flag"
+msgid "Topology Extensions CPUID leafs"
+msgstr "Расширения топологии потоков CPUID"
+
+#. /flag:perfctr_core
+#: modules/devices/x86/x86_data.c:176
+msgctxt "x86-flag"
+msgid "Core Performance Counter Extensions"
+msgstr "Расширения счетчика производительности ядра"
+
+#. /flag:perfctr_nb
+#: modules/devices/x86/x86_data.c:177
+msgctxt "x86-flag"
+msgid "NB Performance Counter Extensions"
+msgstr "Расширения счетчика производительности NB"
+
+#. /flag:bpext
+#: modules/devices/x86/x86_data.c:178
+msgctxt "x86-flag"
+msgid "data breakpoint extension"
+msgstr "расширение точки прерывания данных"
+
+#. /flag:ptsc
+#: modules/devices/x86/x86_data.c:179
+msgctxt "x86-flag"
+msgid "performance time-stamp counter"
+msgstr "счетчик временной метки производительности"
+
+#. /flag:perfctr_l2
+#: modules/devices/x86/x86_data.c:180
+msgctxt "x86-flag"
+msgid "L2 Performance Counter Extensions"
+msgstr "Расширения счетчика производительности L2"
+
+#. /flag:mwaitx
+#: modules/devices/x86/x86_data.c:181
+msgctxt "x86-flag"
+msgid "MWAIT extension (MONITORX/MWAITX)"
+msgstr "Расширение MWAIT (MONITORX/MWAITX)"
+
+#. /flag:cpb
+#: modules/devices/x86/x86_data.c:183
+msgctxt "x86-flag"
+msgid "AMD Core Performance Boost"
+msgstr "Увеличение производительности ядра AMD"
+
+#. /flag:epb
+#: modules/devices/x86/x86_data.c:184
+msgctxt "x86-flag"
+msgid "IA32_ENERGY_PERF_BIAS support"
+msgstr "Поддержка IA32_ENERGY_PERF_BIAS"
+
+#. /flag:hw_pstate
+#: modules/devices/x86/x86_data.c:185
+msgctxt "x86-flag"
+msgid "AMD HW-PState"
+msgstr ""
+
+#. /flag:proc_feedback
+#: modules/devices/x86/x86_data.c:186
+msgctxt "x86-flag"
+msgid "AMD ProcFeedbackInterface"
+msgstr ""
+
+#. /flag:intel_pt
+#: modules/devices/x86/x86_data.c:187
+msgctxt "x86-flag"
+msgid "Intel Processor Tracing"
+msgstr "Отслеживание процессора Intel"
+
+#. /flag:tpr_shadow
+#: modules/devices/x86/x86_data.c:189
+msgctxt "x86-flag"
+msgid "Intel TPR Shadow"
+msgstr ""
+
+#. /flag:vnmi
+#: modules/devices/x86/x86_data.c:190
+msgctxt "x86-flag"
+msgid "Intel Virtual NMI"
+msgstr ""
+
+#. /flag:flexpriority
+#: modules/devices/x86/x86_data.c:191
+msgctxt "x86-flag"
+msgid "Intel FlexPriority"
+msgstr ""
+
+#. /flag:ept
+#: modules/devices/x86/x86_data.c:192
+msgctxt "x86-flag"
+msgid "Intel Extended Page Table"
+msgstr ""
+
+#. /flag:vpid
+#: modules/devices/x86/x86_data.c:193
+msgctxt "x86-flag"
+msgid "Intel Virtual Processor ID"
+msgstr ""
+
+#. /flag:vmmcall
+#: modules/devices/x86/x86_data.c:194
+msgctxt "x86-flag"
+msgid "prefer VMMCALL to VMCALL"
+msgstr "предпочитать VMMCALL, а не VMCALL"
+
+#. /flag:fsgsbase
+#: modules/devices/x86/x86_data.c:196
+msgctxt "x86-flag"
+msgid "{RD/WR}{FS/GS}BASE instructions"
+msgstr "Инструкции {RD/WR}{FS/GS}BASE"
+
+#. /flag:tsc_adjust
+#: modules/devices/x86/x86_data.c:197
+msgctxt "x86-flag"
+msgid "TSC adjustment MSR"
+msgstr "TSC выраснивание MSR"
+
+#. /flag:bmi1
+#: modules/devices/x86/x86_data.c:198
+msgctxt "x86-flag"
+msgid "1st group bit manipulation extensions"
+msgstr "Расширения управления битами 1-й группы"
+
+#. /flag:hle
+#: modules/devices/x86/x86_data.c:199
+msgctxt "x86-flag"
+msgid "Hardware Lock Elision"
+msgstr "Аппаратная блокировка Elision"
+
+#. /flag:avx2
+#: modules/devices/x86/x86_data.c:200
+msgctxt "x86-flag"
+msgid "AVX2 instructions"
+msgstr "Инструкции AVX2"
+
+#. /flag:smep
+#: modules/devices/x86/x86_data.c:201
+msgctxt "x86-flag"
+msgid "Supervisor Mode Execution Protection"
+msgstr "Защита выполнения режима супервизора"
+
+#. /flag:bmi2
+#: modules/devices/x86/x86_data.c:202
+msgctxt "x86-flag"
+msgid "2nd group bit manipulation extensions"
+msgstr "Расширения управления битами 2-й группы"
+
+#. /flag:erms
+#: modules/devices/x86/x86_data.c:203
+msgctxt "x86-flag"
+msgid "Enhanced REP MOVSB/STOSB"
+msgstr "Расширенный REP MOVSB/STOSB"
+
+#. /flag:invpcid
+#: modules/devices/x86/x86_data.c:204
+msgctxt "x86-flag"
+msgid "Invalidate Processor Context ID"
+msgstr "Аннулировать ID контекста процессора"
+
+#. /flag:rtm
+#: modules/devices/x86/x86_data.c:205
+msgctxt "x86-flag"
+msgid "Restricted Transactional Memory"
+msgstr "Ограниченная память переносов"
+
+#. /flag:cqm
+#: modules/devices/x86/x86_data.c:206
+msgctxt "x86-flag"
+msgid "Cache QoS Monitoring"
+msgstr "Мониторинг кэша QoS"
+
+#. /flag:mpx
+#: modules/devices/x86/x86_data.c:207
+msgctxt "x86-flag"
+msgid "Memory Protection Extension"
+msgstr "Расширение защиты памяти"
+
+#. /flag:avx512f
+#: modules/devices/x86/x86_data.c:208
+msgctxt "x86-flag"
+msgid "AVX-512 foundation"
+msgstr "Основа AVX-512"
+
+#. /flag:avx512dq
+#: modules/devices/x86/x86_data.c:209
+msgctxt "x86-flag"
+msgid "AVX-512 Double/Quad instructions"
+msgstr "Инструкции AVX-512 Double/Quad"
+
+#. /flag:rdseed
+#: modules/devices/x86/x86_data.c:210
+msgctxt "x86-flag"
+msgid "The RDSEED instruction"
+msgstr "Инструкция RDSEED"
+
+#. /flag:adx
+#: modules/devices/x86/x86_data.c:211
+msgctxt "x86-flag"
+msgid "The ADCX and ADOX instructions"
+msgstr "Инструкции ADCX и ADOX"
+
+#. /flag:smap
+#: modules/devices/x86/x86_data.c:212
+msgctxt "x86-flag"
+msgid "Supervisor Mode Access Prevention"
+msgstr "Предотвращение доступа к режиму супервизора"
+
+#. /flag:clflushopt
+#: modules/devices/x86/x86_data.c:213
+msgctxt "x86-flag"
+msgid "CLFLUSHOPT instruction"
+msgstr "Инструкция CLFLUSHOPT"
+
+#. /flag:clwb
+#: modules/devices/x86/x86_data.c:214
+msgctxt "x86-flag"
+msgid "CLWB instruction"
+msgstr "Инструкция CLWB"
+
+#. /flag:avx512pf
+#: modules/devices/x86/x86_data.c:215
+msgctxt "x86-flag"
+msgid "AVX-512 Prefetch"
+msgstr ""
+
+#. /flag:avx512er
+#: modules/devices/x86/x86_data.c:216
+msgctxt "x86-flag"
+msgid "AVX-512 Exponential and Reciprocal"
+msgstr ""
+
+#. /flag:avx512cd
+#: modules/devices/x86/x86_data.c:217
+msgctxt "x86-flag"
+msgid "AVX-512 Conflict Detection"
+msgstr "Обнаружения конфликтов AVX-512"
+
+#. /flag:sha_ni
+#: modules/devices/x86/x86_data.c:218
+msgctxt "x86-flag"
+msgid "SHA1/SHA256 Instruction Extensions"
+msgstr "Расширения инструкций SHA1/SHA256"
+
+#. /flag:avx512bw
+#: modules/devices/x86/x86_data.c:219
+msgctxt "x86-flag"
+msgid "AVX-512 Byte/Word instructions"
+msgstr "Инструкции AVX-512 Byte/Word"
+
+#. /flag:avx512vl
+#: modules/devices/x86/x86_data.c:220
+msgctxt "x86-flag"
+msgid "AVX-512 128/256 Vector Length extensions"
+msgstr "Расширения длины вектора AVX-512 128/256"
+
+#. /flag:xsaveopt
+#: modules/devices/x86/x86_data.c:222
+msgctxt "x86-flag"
+msgid "Optimized XSAVE"
+msgstr "Оптимизированный XSAVE"
+
+#. /flag:xsavec
+#: modules/devices/x86/x86_data.c:223
+msgctxt "x86-flag"
+msgid "XSAVEC"
+msgstr ""
+
+#. /flag:xgetbv1
+#: modules/devices/x86/x86_data.c:224
+msgctxt "x86-flag"
+msgid "XGETBV with ECX = 1"
+msgstr "XGETBV с ECX = 1"
+
+#. /flag:xsaves
+#: modules/devices/x86/x86_data.c:225
+msgctxt "x86-flag"
+msgid "XSAVES/XRSTORS"
+msgstr ""
+
+#. /flag:cqm_llc
+#: modules/devices/x86/x86_data.c:227
+msgctxt "x86-flag"
+msgid "LLC QoS"
+msgstr ""
+
+#. /flag:cqm_occup_llc
+#: modules/devices/x86/x86_data.c:229
+msgctxt "x86-flag"
+msgid "LLC occupancy monitoring"
+msgstr "Мониторинг занятости LLC"
+
+#. /flag:cqm_mbm_total
+#: modules/devices/x86/x86_data.c:230
+msgctxt "x86-flag"
+msgid "LLC total MBM monitoring"
+msgstr "Полный MBM-мониторинг LLC"
+
+#. /flag:cqm_mbm_local
+#: modules/devices/x86/x86_data.c:231
+msgctxt "x86-flag"
+msgid "LLC local MBM monitoring"
+msgstr "Локальный MBM-мониторинг LLC"
+
+#. /flag:clzero
+#: modules/devices/x86/x86_data.c:233
+msgctxt "x86-flag"
+msgid "CLZERO instruction"
+msgstr "Инструкция CLZERO"
+
+#. /flag:irperf
+#: modules/devices/x86/x86_data.c:234
+msgctxt "x86-flag"
+msgid "instructions retired performance counter"
+msgstr "инструкции счетчика отложенной производительности"
+
+#. /flag:dtherm
+#: modules/devices/x86/x86_data.c:236
+msgctxt "x86-flag"
+msgid "digital thermal sensor"
+msgstr "цифровой сенсор температуры"
+
+#. /flag:ida
+#: modules/devices/x86/x86_data.c:237
+msgctxt "x86-flag"
+msgid "Intel Dynamic Acceleration"
+msgstr "Динамическое ускорение Intel"
+
+#. /flag:arat
+#: modules/devices/x86/x86_data.c:238
+msgctxt "x86-flag"
+msgid "Always Running APIC Timer"
+msgstr "Таймер APIC всегда запущен"
+
+#. /flag:pln
+#: modules/devices/x86/x86_data.c:239
+msgctxt "x86-flag"
+msgid "Intel Power Limit Notification"
+msgstr "Уведомление о лимите энергии Intel"
+
+#. /flag:pts
+#: modules/devices/x86/x86_data.c:240
+msgctxt "x86-flag"
+msgid "Intel Package Thermal Status"
+msgstr "Статус температуры Intel"
+
+#. /flag:hwp
+#: modules/devices/x86/x86_data.c:241
+msgctxt "x86-flag"
+msgid "Intel Hardware P-states"
+msgstr "Аппаратные P-states Intel"
+
+#. /flag:hwp_notify
+#: modules/devices/x86/x86_data.c:242
+msgctxt "x86-flag"
+msgid "HWP notification"
+msgstr "Уведомление HWP"
+
+#. /flag:hwp_act_window
+#: modules/devices/x86/x86_data.c:243
+msgctxt "x86-flag"
+msgid "HWP Activity Window"
+msgstr "Окно активности HWP"
+
+#. /flag:hwp_epp
+#: modules/devices/x86/x86_data.c:244
+msgctxt "x86-flag"
+msgid "HWP Energy Performance Preference"
+msgstr "Настройка производительности энергии HWP"
+
+#. /flag:hwp_pkg_req
+#: modules/devices/x86/x86_data.c:245
+msgctxt "x86-flag"
+msgid "HWP package-level request"
+msgstr "Запрос уровня пакета HWP"
+
+#. /flag:npt
+#: modules/devices/x86/x86_data.c:247
+msgctxt "x86-flag"
+msgid "AMD Nested Page Table support"
+msgstr "Поддержка таблиц вложенной страницы AMD"
+
+#. /flag:lbrv
+#: modules/devices/x86/x86_data.c:248
+msgctxt "x86-flag"
+msgid "AMD LBR Virtualization support"
+msgstr "Поддержка виртуализации AMD LBR"
+
+#. /flag:svm_lock
+#: modules/devices/x86/x86_data.c:249
+msgctxt "x86-flag"
+msgid "AMD SVM locking MSR"
+msgstr "Блокировка MSR AMD SVM"
+
+#. /flag:nrip_save
+#: modules/devices/x86/x86_data.c:250
+msgctxt "x86-flag"
+msgid "AMD SVM next_rip save"
+msgstr "Сохранение next_rip AMD SVM"
+
+#. /flag:tsc_scale
+#: modules/devices/x86/x86_data.c:251
+msgctxt "x86-flag"
+msgid "AMD TSC scaling support"
+msgstr "Поддержка масштабирования AMD TSC"
+
+#. /flag:vmcb_clean
+#: modules/devices/x86/x86_data.c:252
+msgctxt "x86-flag"
+msgid "AMD VMCB clean bits support"
+msgstr "Поддержка чистых бит AMD VMCB"
+
+#. /flag:flushbyasid
+#: modules/devices/x86/x86_data.c:253
+msgctxt "x86-flag"
+msgid "AMD flush-by-ASID support"
+msgstr "Поддержка AMD flush-by-ASID"
+
+#. /flag:decodeassists
+#: modules/devices/x86/x86_data.c:254
+msgctxt "x86-flag"
+msgid "AMD Decode Assists support"
+msgstr "Поддержка помощи декодирования"
+
+#. /flag:pausefilter
+#: modules/devices/x86/x86_data.c:255
+msgctxt "x86-flag"
+msgid "AMD filtered pause intercept"
+msgstr "Перехват фильтрованной паузы AMD"
+
+#. /flag:pfthreshold
+#: modules/devices/x86/x86_data.c:256
+msgctxt "x86-flag"
+msgid "AMD pause filter threshold"
+msgstr "Порог фильтра паузы AMD"
+
+#. /flag:avic
+#: modules/devices/x86/x86_data.c:257
+msgctxt "x86-flag"
+msgid "Virtual Interrupt Controller"
+msgstr "Контроллер виртуального прерывания"
+
+#. /flag:pku
+#: modules/devices/x86/x86_data.c:259
+msgctxt "x86-flag"
+msgid "Protection Keys for Userspace"
+msgstr "Ключи защиты для пространства пользователя"
+
+#. /flag:ospke
+#: modules/devices/x86/x86_data.c:260
+msgctxt "x86-flag"
+msgid "OS Protection Keys Enable"
+msgstr "Включение защиты ключей ОС"
+
+#. /flag:overflow_recov
+#: modules/devices/x86/x86_data.c:262
+msgctxt "x86-flag"
+msgid "MCA overflow recovery support"
+msgstr "Поддержка восстановления после переполнения MCA"
+
+#. /flag:succor
+#: modules/devices/x86/x86_data.c:263
+msgctxt "x86-flag"
+msgid "uncorrectable error containment and recovery"
+msgstr "неисправимое содержание ошибки и восстановление"
+
+#. /flag:smca
+#: modules/devices/x86/x86_data.c:264
+msgctxt "x86-flag"
+msgid "Scalable MCA"
+msgstr "Масштабируемый MCA"
+
+#. /bug:f00f
+#: modules/devices/x86/x86_data.c:267
+msgctxt "x86-flag"
+msgid "Intel F00F bug"
+msgstr "Ошибка Intel F00F"
+
+#. /bug:fdiv
+#: modules/devices/x86/x86_data.c:268
+msgctxt "x86-flag"
+msgid "FPU FDIV"
+msgstr ""
+
+#. /bug:coma
+#: modules/devices/x86/x86_data.c:269
+msgctxt "x86-flag"
+msgid "Cyrix 6x86 coma"
+msgstr ""
+
+#. /bug:tlb_mmatch
+#: modules/devices/x86/x86_data.c:270
+msgctxt "x86-flag"
+msgid "AMD Erratum 383"
+msgstr ""
+
+#. /bug:apic_c1e
+#. /bug:amd_e400
+#: modules/devices/x86/x86_data.c:271 modules/devices/x86/x86_data.c:280
+msgctxt "x86-flag"
+msgid "AMD Erratum 400"
+msgstr ""
+
+#. /bug:11ap
+#: modules/devices/x86/x86_data.c:272
+msgctxt "x86-flag"
+msgid "Bad local APIC aka 11AP"
+msgstr "Неверный локальный APIC или 11AP"
+
+#. /bug:fxsave_leak
+#: modules/devices/x86/x86_data.c:273
+msgctxt "x86-flag"
+msgid "FXSAVE leaks FOP/FIP/FOP"
+msgstr "FXSAVE утекает FOP/FIP/FOP"
+
+#. /bug:clflush_monitor
+#: modules/devices/x86/x86_data.c:274
+msgctxt "x86-flag"
+msgid "AAI65, CLFLUSH required before MONITOR"
+msgstr "AAI65, CLFLUSH требуются до MONITOR"
+
+#. /bug:sysret_ss_attrs
+#: modules/devices/x86/x86_data.c:275
+msgctxt "x86-flag"
+msgid "SYSRET doesn't fix up SS attrs"
+msgstr "SYSRET не исправляет атрибуты SS"
+
+#. /bug:espfix
+#: modules/devices/x86/x86_data.c:276
+msgctxt "x86-flag"
+msgid "IRET to 16-bit SS corrupts ESP/RSP high bits"
+msgstr "IRET на 16-битные SS прерывает высшие биты ESP/RSP"
+
+#. /bug:null_seg
+#: modules/devices/x86/x86_data.c:277
+msgctxt "x86-flag"
+msgid "Nulling a selector preserves the base"
+msgstr "Обнуление селектора продпочитается основному"
+
+#. /bug:swapgs_fence
+#: modules/devices/x86/x86_data.c:278
+msgctxt "x86-flag"
+msgid "SWAPGS without input dep on GS"
+msgstr "SWAPGS без ввода зависит от GS"
+
+#. /bug:monitor
+#: modules/devices/x86/x86_data.c:279
+msgctxt "x86-flag"
+msgid "IPI required to wake up remote CPU"
+msgstr "требуется IPI для удаленного пробуждения процессора"
+
+#. /x86/kernel/cpu/powerflags.h
+#. /flag:pm:ts
+#: modules/devices/x86/x86_data.c:283
+msgctxt "x86-flag"
+msgid "temperature sensor"
+msgstr "сенсор температуры"
+
+#. /flag:pm:fid
+#: modules/devices/x86/x86_data.c:284
+msgctxt "x86-flag"
+msgid "frequency id control"
+msgstr "контроль частоты id"
+
+#. /flag:pm:vid
+#: modules/devices/x86/x86_data.c:285
+msgctxt "x86-flag"
+msgid "voltage id control"
+msgstr "контроль вольтажа id"
+
+#. /flag:pm:ttp
+#: modules/devices/x86/x86_data.c:286
+msgctxt "x86-flag"
+msgid "thermal trip"
+msgstr "изменение температуры"
+
+#. /flag:pm:tm
+#: modules/devices/x86/x86_data.c:287
+msgctxt "x86-flag"
+msgid "hardware thermal control"
+msgstr "аппаратный контроль температуры"
+
+#. /flag:pm:stc
+#: modules/devices/x86/x86_data.c:288
+msgctxt "x86-flag"
+msgid "software thermal control"
+msgstr "программный контроль температуры"
+
+#. /flag:pm:100mhzsteps
+#: modules/devices/x86/x86_data.c:289
+msgctxt "x86-flag"
+msgid "100 MHz multiplier control"
+msgstr "контроль множителя 100 МГц"
+
+#. /flag:pm:hwpstate
+#: modules/devices/x86/x86_data.c:290
+msgctxt "x86-flag"
+msgid "hardware P-state control"
+msgstr "аппаратное управление P-state"
+
+#. /flag:pm:cpb
+#: modules/devices/x86/x86_data.c:291
+msgctxt "x86-flag"
+msgid "core performance boost"
+msgstr "повышение производительности ядра"
+
+#. /flag:pm:eff_freq_ro
+#: modules/devices/x86/x86_data.c:292
+msgctxt "x86-flag"
+msgid "Readonly aperf/mperf"
+msgstr "aperf/mperf только для чтения"
+
+#. /flag:pm:proc_feedback
+#: modules/devices/x86/x86_data.c:293
+msgctxt "x86-flag"
+msgid "processor feedback interface"
+msgstr "интерфейс отзыва процессора"
+
+#. /flag:pm:acc_power
+#: modules/devices/x86/x86_data.c:294
+msgctxt "x86-flag"
+msgid "accumulated power mechanism"
+msgstr "механизм накопления питания"
+
+#: modules/network.c:59
+msgid "Interfaces"
+msgstr "Интерфейсы"
+
+#: modules/network.c:60
+msgid "IP Connections"
+msgstr "IP Подключения"
+
+#: modules/network.c:61
+msgid "Routing Table"
+msgstr "Таблица маршрутизации"
+
+#: modules/network.c:62 modules/network.c:303
+msgid "ARP Table"
+msgstr "Таблица ARP"
+
+#: modules/network.c:63
+msgid "DNS Servers"
+msgstr "DNS сервера"
+
+#: modules/network.c:64
+msgid "Statistics"
+msgstr "Статистика"
+
+#: modules/network.c:65
+msgid "Shared Directories"
+msgstr "Общие каталоги"
+
+#: modules/network.c:304 modules/network.c:326 modules/network.c:357
+#: modules/network/net.c:472
+msgid "IP Address"
+msgstr "IP-адрес"
+
+#: modules/network.c:304 modules/network.c:357 modules/network.c:374
+msgid "Interface"
+msgstr "Интерфейс"
+
+#: modules/network.c:304
+msgid "MAC Address"
+msgstr "MAC-адрес"
+
+#: modules/network.c:313
+msgid "SAMBA"
+msgstr ""
+
+#: modules/network.c:314
+msgid "NFS"
+msgstr ""
+
+#: modules/network.c:325
+msgid "Name Servers"
+msgstr ""
+
+#: modules/network.c:340
+msgid "Connections"
+msgstr ""
+
+#: modules/network.c:341
+msgid "Local Address"
+msgstr "Локальный адрес"
+
+#: modules/network.c:341
+msgid "Protocol"
+msgstr "Протокол"
+
+#: modules/network.c:341
+msgid "Foreign Address"
+msgstr "Удалённый адрес"
+
+#: modules/network.c:341
+msgid "State"
+msgstr "Состояние"
+
+#: modules/network.c:357
+msgid "Sent"
+msgstr "Отправлено"
+
+#: modules/network.c:357
+msgid "Received"
+msgstr "Получено"
+
+#: modules/network.c:373
+msgid "IP routing table"
+msgstr ""
+
+#: modules/network.c:374
+msgid "Destination/Gateway"
+msgstr "Цель / Шлюз"
+
+#: modules/network.c:374
+msgid "Flags"
+msgstr "Флаги"
+
+#: modules/network.c:374 modules/network/net.c:473
+msgid "Mask"
+msgstr "Маска"
+
+#: modules/network.c:402
+msgid "Network"
+msgstr "Сеть"
+
+#: modules/network.c:435
+msgid "Gathers information about this computer's network connection"
+msgstr "Собирает информацию о сетевых подключениях"
+
+#: modules/network/net.c:72
+msgctxt "wi-op-mode"
+msgid "Auto"
+msgstr ""
+
+#: modules/network/net.c:73
+msgctxt "wi-op-mode"
+msgid "Ad-Hoc"
+msgstr ""
+
+#: modules/network/net.c:74
+msgctxt "wi-op-mode"
+msgid "Managed"
+msgstr ""
+
+#: modules/network/net.c:75
+msgctxt "wi-op-mode"
+msgid "Master"
+msgstr ""
+
+#: modules/network/net.c:76
+msgctxt "wi-op-mode"
+msgid "Repeater"
+msgstr ""
+
+#: modules/network/net.c:77
+msgctxt "wi-op-mode"
+msgid "Secondary"
+msgstr ""
+
+#: modules/network/net.c:78
+msgctxt "wi-op-mode"
+msgid "(Unknown)"
+msgstr ""
+
+#: modules/network/net.c:242 modules/network/net.c:262
+#: modules/network/net.c:270
+msgctxt "net-if-type"
+msgid "Ethernet"
+msgstr ""
+
+#: modules/network/net.c:243
+msgctxt "net-if-type"
+msgid "Loopback"
+msgstr ""
+
+#: modules/network/net.c:244
+msgctxt "net-if-type"
+msgid "Point-to-Point"
+msgstr ""
+
+#: modules/network/net.c:245 modules/network/net.c:246
+#: modules/network/net.c:247 modules/network/net.c:248
+#: modules/network/net.c:272
+msgctxt "net-if-type"
+msgid "Wireless"
+msgstr ""
+
+#: modules/network/net.c:249
+msgctxt "net-if-type"
+msgid "Virtual Point-to-Point (TUN)"
+msgstr ""
+
+#: modules/network/net.c:250
+msgctxt "net-if-type"
+msgid "Ethernet (TAP)"
+msgstr ""
+
+#: modules/network/net.c:251
+msgctxt "net-if-type"
+msgid "Parallel Line Internet Protocol"
+msgstr ""
+
+#: modules/network/net.c:252
+msgctxt "net-if-type"
+msgid "Infrared"
+msgstr ""
+
+#: modules/network/net.c:253 modules/network/net.c:271
+msgctxt "net-if-type"
+msgid "Serial Line Internet Protocol"
+msgstr ""
+
+#: modules/network/net.c:254
+msgctxt "net-if-type"
+msgid "Integrated Services Digital Network"
+msgstr ""
+
+#: modules/network/net.c:255
+msgctxt "net-if-type"
+msgid "IPv6-over-IPv4 Tunnel"
+msgstr ""
+
+#: modules/network/net.c:256
+msgctxt "net-if-type"
+msgid "VMWare Virtual Network Interface (NAT)"
+msgstr ""
+
+#: modules/network/net.c:257
+msgctxt "net-if-type"
+msgid "VMWare Virtual Network Interface"
+msgstr ""
+
+#: modules/network/net.c:258
+msgctxt "net-if-type"
+msgid "Personal Area Network (PAN)"
+msgstr ""
+
+#: modules/network/net.c:259
+msgctxt "net-if-type"
+msgid "Bluetooth"
+msgstr ""
+
+#: modules/network/net.c:260
+msgctxt "net-if-type"
+msgid "Bridge Interface"
+msgstr ""
+
+#: modules/network/net.c:261
+msgctxt "net-if-type"
+msgid "Hamachi Virtual Personal Network"
+msgstr ""
+
+#: modules/network/net.c:263
+msgctxt "net-if-type"
+msgid "Intermediate Functional Block"
+msgstr ""
+
+#: modules/network/net.c:264
+msgctxt "net-if-type"
+msgid "GRE Network Tunnel"
+msgstr ""
+
+#: modules/network/net.c:265
+msgctxt "net-if-type"
+msgid "Mesh Network"
+msgstr ""
+
+#: modules/network/net.c:266
+msgctxt "net-if-type"
+msgid "Wireless Master Interface"
+msgstr ""
+
+#: modules/network/net.c:267
+msgctxt "net-if-type"
+msgid "VirtualBox Virtual Network Interface"
+msgstr ""
+
+#: modules/network/net.c:273
+msgctxt "net-if-type"
+msgid "Wireless (WAN)"
+msgstr ""
+
+#: modules/network/net.c:275
+msgctxt "net-if-type"
+msgid "(Unknown)"
+msgstr ""
+
+#: modules/network/net.c:343 modules/network/net.c:353
+msgid "Network Interfaces"
+msgstr ""
+
+#: modules/network/net.c:343
+msgid "None Found"
+msgstr ""
+
+#: modules/network/net.c:395 modules/network/net.c:417
+#: modules/network/net.c:418
+msgid "MiB"
+msgstr " МиБ"
+
+#: modules/network/net.c:409
+msgid "Network Adapter Properties"
+msgstr "Свойства сетевого адаптера"
+
+#: modules/network/net.c:410
+msgid "Interface Type"
+msgstr "Тип интерфейса"
+
+#: modules/network/net.c:411
+msgid "Hardware Address (MAC)"
+msgstr "Аппаратный адрес (MAC)"
+
+#: modules/network/net.c:415
+msgid "MTU"
+msgstr ""
+
+#: modules/network/net.c:416
+msgid "Transfer Details"
+msgstr "Информация о передаче данных"
+
+#: modules/network/net.c:417
+msgid "Bytes Received"
+msgstr "Получено байт"
+
+#: modules/network/net.c:418
+msgid "Bytes Sent"
+msgstr "Отправлено байт"
+
+#: modules/network/net.c:435 modules/network/net.c:457
+#: modules/network/net.c:458
+msgid "dBm"
+msgstr ""
+
+#: modules/network/net.c:435
+msgid "mW"
+msgstr ""
+
+#: modules/network/net.c:449
+msgid "Wireless Properties"
+msgstr ""
+
+#: modules/network/net.c:450
+msgid "Network Name (SSID)"
+msgstr ""
+
+#: modules/network/net.c:451
+msgid "Bit Rate"
+msgstr ""
+
+#: modules/network/net.c:451
+msgid "Mb/s"
+msgstr ""
+
+#: modules/network/net.c:452
+msgid "Transmission Power"
+msgstr ""
+
+#: modules/network/net.c:454
+msgid "Status"
+msgstr ""
+
+#: modules/network/net.c:455
+msgid "Link Quality"
+msgstr ""
+
+#: modules/network/net.c:456
+msgid "Signal / Noise"
+msgstr ""
+
+#: modules/network/net.c:471
+msgid "Internet Protocol (IPv4)"
+msgstr ""
+
+#: modules/network/net.c:472 modules/network/net.c:473
+#: modules/network/net.c:475
+msgid "(Not set)"
+msgstr ""
+
+#: modules/network/net.c:474
+msgid "Broadcast Address"
+msgstr "Широковещательный адрес"
diff --git a/po/salvage.sh b/po/salvage.sh
new file mode 100644
index 0000000..295187f
--- /dev/null
+++ b/po/salvage.sh
@@ -0,0 +1,83 @@
+#!bash
+
+# To help with https://github.com/lpereira/hardinfo/issues/100
+# Saves the old label translations.
+#
+# This is not an automated magical tool, it is an ugly hack of a helper
+# for a tedious process. Read the instructions if you want to use it!
+#
+# bash updatepo.sh
+# { commit here or the next commit's diff will be noisy and useless }
+#
+# { repeat for each language... }
+#     bash salvage.sh XX.po >XX.po.salv
+#     { edit XX.po.salv, remove nonsense }
+#     msgcat --use-first XX.po XX.po.salv > XX.po.merged
+#     diff XX.po XX.po.merged
+#     { if there are any added translations, they do not actually appear
+#       in hardinfo.pot, and they will end up "obsolete" and then re-processed
+#       in the next salvage. So save some hassle and just remove them now. }
+#     mv XX.po.merged XX.po
+#
+# { when all languages are done run updatepo.sh again to clean up }
+# bash updatepo.sh
+#
+
+if [ -z "$@" ]; then
+    echo "READ script before running!"
+    echo "Error: Needs .po file to process"
+    exit 1
+fi
+
+do_salvage() {
+    msgid=()
+    msgstr=()
+
+    while IFS= read -r line; do
+        msgid+=( "$line" )
+    done <<< "$MSGEXEC_MSGID"
+
+    while IFS= read -r line; do
+        msgstr+=( "$line" )
+    done <&0
+
+    for i in ${!msgid[@]}; do
+        # column titles
+        msgid[$i]=`echo "${msgid[$i]}" | sed -e 's/ColumnTitle\$.*=//'`
+        msgstr[$i]=`echo "${msgstr[$i]}" | sed -e 's/ColumnTitle\$.*=//'`
+
+        # section titles
+        msgid[$i]=`echo "${msgid[$i]}" | sed -e 's/\[\(.*\)\]/\1/'`
+        msgstr[$i]=`echo "${msgstr[$i]}" | sed -e 's/\[\(.*\)\]/\1/'`
+
+        # regular labels
+        msgid[$i]=`echo "${msgid[$i]}" | sed -e 's/=.*$//'`
+        msgstr[$i]=`echo "${msgstr[$i]}" | sed -e 's/=.*$//'`
+
+        # junk
+        msgid[$i]=`echo "${msgid[$i]}" | sed -e 's/%s//'`
+        msgid[$i]=`echo "${msgid[$i]}" | sed -e 's/%s//'`
+
+        if [[ -n "${msgid[$i]}" && -n "${msgstr[$i]}" ]]; then
+            if [ "${msgid[$i]}" != "${msgstr[$i]}" ]; then
+                echo "msgid \"${msgid[$i]}\""
+                echo "msgstr \"${msgstr[$i]}\""
+                echo ""
+            fi
+        fi
+    done
+}
+
+cat >salvage.tmp <<'EOT'
+
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+EOT
+
+export -f do_salvage
+msgattrib --only-obsolete "$@" | msgexec bash -c 'do_salvage "$0"' >>salvage.tmp
+msguniq salvage.tmp
+rm salvage.tmp
diff --git a/po/updatepo.sh b/po/updatepo.sh
new file mode 100644
index 0000000..d5b0f9d
--- /dev/null
+++ b/po/updatepo.sh
@@ -0,0 +1,52 @@
+#!bash
+
+GITVER=`git describe --always --dirty`
+GITHASH=`git rev-parse HEAD`
+
+echo "Update gettext translation files."
+
+DER=`pwd`
+if [ ! -e "updatepo.sh" ]
+then
+    echo "Error: Run from po/, the location of hardinfo.pot and XX.po files."
+    exit 1
+fi
+
+MSGTOTALOLD=`msgattrib --untranslated hardinfo.pot | grep -E "^msgstr \"\"" | wc -l`
+echo "hardinfo.pot has $MSGTOTALOLD strings"
+
+mv hardinfo.pot hardinfo.pot.old
+echo "" > hardinfo.pot # empty existing file to join (-j) with
+for d in hardinfo/ shell/ modules/ includes/;
+do
+    # work from hardinfo root to get reasonable file reference comments
+    cd ..
+    echo -n `pwd`; echo "/$d ..."
+    find "$d" -type f -name "*.[hc]" -print | sort | xargs xgettext -j -d hardinfo -o "$DER/hardinfo.pot" -k_ -kN_ -kC_:1c,2 -kNC_:1c,2 -c/ --from-code=UTF-8
+    cd "$DER"
+done;
+
+MSGTOTAL=`msgattrib --untranslated hardinfo.pot | grep -E "^msgstr \"\"" | wc -l`
+TDIFF=$(($MSGTOTAL - $MSGTOTALOLD))
+CHANGE="$TDIFF"
+if [ $TDIFF -gt 0 ]; then CHANGE="+$TDIFF"; fi
+if [ $TDIFF -eq 0 ]; then CHANGE="no change"; fi
+echo "hardinfo.pot now has $MSGTOTAL strings ($CHANGE)"
+echo "(as of $GITVER $GITHASH)"
+
+for f in *.po
+do
+    cp "$f" "$f.old"
+
+    msgmerge -q -N "$f" hardinfo.pot > tmp.po
+
+    # set/reset the X-Poedit-Basepath header
+    grep -v '"X-Poedit-Basepath\:[^"]*"' tmp.po | sed 's:\("Language\:[^"]*"\):\1\n"X-Poedit-Basepath\: ../\\n":' >"$f"
+
+    rm -f tmp.po
+
+    # stats
+    UNMSG=`msgattrib --untranslated "$f" | grep -E "^msgstr \"\"" | wc -l`
+    DONE=" "; if [ $UNMSG -eq 0 ]; then DONE="x"; fi
+    echo "- [$DONE] $f : ($UNMSG / $MSGTOTAL remain untranslated)"
+done
diff --git a/shell/callbacks.c b/shell/callbacks.c
new file mode 100644
index 0000000..9bb5c99
--- /dev/null
+++ b/shell/callbacks.c
@@ -0,0 +1,247 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <gtk/gtk.h>
+
+#include "hardinfo.h"
+#include "callbacks.h"
+#include "iconcache.h"
+
+#include "shell.h"
+#include "report.h"
+#include "syncmanager.h"
+#include "xmlrpc-server.h"
+
+#include "config.h"
+
+void cb_sync_manager()
+{
+    Shell *shell = shell_get_main_shell();
+
+    sync_manager_show(shell->window);
+}
+
+void cb_open_web_page()
+{
+    open_url("http://www.hardinfo.org");
+}
+
+void cb_report_bug()
+{
+    open_url("https://github.com/lpereira/hardinfo");
+}
+
+void cb_refresh()
+{
+    shell_do_reload();
+}
+
+void cb_copy_to_clipboard()
+{
+    ShellModuleEntry *entry = shell_get_main_shell()->selected;
+
+    if (entry) {
+	gchar *data = module_entry_function(entry);
+	GtkClipboard *clip =
+	    gtk_clipboard_get(gdk_atom_intern("CLIPBOARD", FALSE));
+	ReportContext *ctx = report_context_text_new(NULL);
+
+	ctx->entry = entry;
+
+	report_header(ctx);
+	report_table(ctx, data);
+	report_footer(ctx);
+
+	gtk_clipboard_set_text(clip, ctx->output, -1);
+
+	g_free(data);
+	report_context_free(ctx);
+    }
+}
+
+void cb_side_pane()
+{
+    gboolean visible;
+
+    visible = shell_action_get_active("SidePaneAction");
+    shell_set_side_pane_visible(visible);
+}
+
+void cb_toolbar()
+{
+    gboolean visible;
+
+    visible = shell_action_get_active("ToolbarAction");
+    shell_ui_manager_set_visible("/MainMenuBarAction", visible);
+}
+
+void cb_about_module(GtkAction * action)
+{
+    Shell *shell = shell_get_main_shell();
+    GSList *modules = shell->tree->modules;
+    ModuleAbout *ma;
+    gchar *name;
+
+    g_object_get(G_OBJECT(action), "tooltip", &name, NULL);
+
+    for (; modules; modules = modules->next) {
+	ShellModule *sm = (ShellModule *) modules->data;
+
+	if (!g_str_equal(sm->name, name))
+	    continue;
+
+	if ((ma = module_get_about(sm))) {
+	    GtkWidget *about;
+	    gchar *text;
+
+	    about = gtk_about_dialog_new();
+
+	    gtk_window_set_transient_for(GTK_WINDOW(about), GTK_WINDOW(shell->window));
+
+	    text = g_strdup(sm->name);
+#if GTK_CHECK_VERSION(2, 12, 0)
+	    gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about), text);
+#else
+	    gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(about), text);
+#endif
+	    g_free(text);
+
+	    gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),
+					 ma->version);
+
+	    text = g_strdup_printf(_("Written by %s\nLicensed under %s"),
+				   ma->author, ma->license);
+	    gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about), text);
+	    g_free(text);
+
+	    if (ma->description)
+		gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about),
+					      _(ma->description));
+
+	    gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about), sm->icon);
+	    gtk_dialog_run(GTK_DIALOG(about));
+	    gtk_widget_destroy(about);
+	} else {
+	    g_warning
+		(_("No about information is associated with the %s module."),
+		 name);
+	}
+
+	break;
+    }
+
+    g_free(name);
+}
+
+void cb_about()
+{
+    Shell *shell = shell_get_main_shell();
+    GtkWidget *about;
+    gchar *copyright = NULL;
+    const gchar *authors[] = {
+        _("Author:"),
+        "Leandro A. F. Pereira",
+        "",
+        _("Contributors:"),
+        "Agney Lopes Roth Ferraz",
+        "Andrey Esin",
+        "Burt P.",
+        "",
+        _("Based on work by:"),
+        _("MD5 implementation by Colin Plumb (see md5.c for details)"),
+        _("SHA1 implementation by Steve Reid (see sha1.c for details)"),
+        _("Blowfish implementation by Paul Kocher (see blowfich.c for details)"),
+        _("Raytracing benchmark by John Walker (see fbench.c for details)"),
+        _("FFT benchmark by Scott Robert Ladd (see fftbench.c for details)"),
+        _("Some code partly based on x86cpucaps by Osamu Kayasono"),
+        _("Vendor list based on GtkSysInfo by Pissens Sebastien"),
+        _("DMI support based on code by Stewart Adam"),
+        _("SCSI support based on code by Pascal F. Martin"),
+        NULL
+    };
+    const gchar *artists[] = {
+        "Jakub Szypulka",
+        _("Tango Project"),
+        _("The GNOME Project"),
+        _("VMWare, Inc. (USB icon from VMWare Workstation 6)"),
+        NULL
+    };
+
+    about = gtk_about_dialog_new();
+    gtk_window_set_transient_for(GTK_WINDOW(about), GTK_WINDOW(shell->window));
+
+#if GTK_CHECK_VERSION(2, 12, 0)
+    gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about), "HardInfo");
+#else
+    gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(about), "HardInfo");
+#endif
+
+    copyright = g_strdup_printf("Copyright \302\251 2003-%d Leandro A. F. Pereira", HARDINFO_COPYRIGHT_LATEST_YEAR);
+
+    gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about), VERSION);
+    gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about), copyright);
+    gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about),
+				  _("System information and benchmark tool"));
+    gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about),
+			      icon_cache_get_pixbuf("logo.png"));
+
+    gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about),
+				 _("HardInfo is free software; you can redistribute it and/or modify "
+				 "it under the terms of the GNU General Public License as published by "
+				 "the Free Software Foundation, version 2.\n\n"
+				 "This program is distributed in the hope that it will be useful, "
+				 "but WITHOUT ANY WARRANTY; without even the implied warranty of "
+				 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the "
+				 "GNU General Public License for more details.\n\n"
+				 "You should have received a copy of the GNU General Public License "
+				 "along with this program; if not, write to the Free Software "
+				 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA"));
+    gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(about), TRUE);
+
+    gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about), authors);
+    gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(about), artists);
+    gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(about),
+        _("translator-credits"));
+
+    gtk_dialog_run(GTK_DIALOG(about));
+    gtk_widget_destroy(about);
+
+    g_free(copyright);
+}
+
+void cb_generate_report()
+{
+    Shell *shell = shell_get_main_shell();
+    gboolean btn_refresh = shell_action_get_enabled("RefreshAction");
+    gboolean btn_copy = shell_action_get_enabled("CopyAction");
+
+    report_dialog_show(shell->tree->model, shell->window);
+
+    shell_action_set_enabled("RefreshAction", btn_refresh);
+    shell_action_set_enabled("CopyAction", btn_copy);
+}
+
+void cb_quit(void)
+{
+    do {
+	gtk_main_quit();
+    } while (gtk_main_level() > 1);
+
+    exit(0);
+}
diff --git a/shell/iconcache.c b/shell/iconcache.c
new file mode 100644
index 0000000..74b19b0
--- /dev/null
+++ b/shell/iconcache.c
@@ -0,0 +1,100 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#include <iconcache.h>
+#include <config.h>
+#include <hardinfo.h>
+
+static GHashTable *cache = NULL;
+
+void icon_cache_init(void)
+{
+    if (!cache) {
+        DEBUG("initializing icon cache");
+	cache = g_hash_table_new(g_str_hash, g_str_equal);
+    }
+}
+
+GdkPixbuf *icon_cache_get_pixbuf(const gchar * file)
+{
+    GdkPixbuf *icon;
+
+    if (!cache)
+	icon_cache_init();
+
+    icon = g_hash_table_lookup(cache, file);
+
+    if (!icon) {
+	gchar *path;
+
+	path = g_build_filename(params.path_data, "pixmaps", file, NULL);
+	icon = gdk_pixbuf_new_from_file(path, NULL);
+	g_hash_table_insert(cache, g_strdup(file), icon);
+
+	g_free(path);
+    }
+
+    if (icon) {
+      g_object_ref(icon);
+    }
+
+    return icon;
+}
+
+GtkWidget *icon_cache_get_image(const gchar * file)
+{
+    GdkPixbuf *icon;
+
+    icon = icon_cache_get_pixbuf(file);
+    return gtk_image_new_from_pixbuf(icon);
+}
+
+GdkPixbuf *icon_cache_get_pixbuf_at_size(const gchar * file, gint wid,
+					 gint hei)
+{
+    GdkPixbuf *icon;
+
+    if (!cache)
+	icon_cache_init();
+
+    icon = g_hash_table_lookup(cache, file);
+
+    if (!icon) {
+	gchar *path;
+
+	path = g_build_filename(params.path_data, "pixmaps", file, NULL);
+	icon = gdk_pixbuf_new_from_file_at_size(path, wid, hei, NULL);
+	g_hash_table_insert(cache, g_strdup(file), icon);
+
+	g_free(path);
+    }
+
+    if (icon) {
+      g_object_ref(icon);
+    }
+
+    return icon;
+}
+
+GtkWidget *icon_cache_get_image_at_size(const gchar * file, gint wid,
+					gint hei)
+{
+    GdkPixbuf *icon;
+
+    icon = icon_cache_get_pixbuf_at_size(file, wid, hei);
+    return gtk_image_new_from_pixbuf(icon);
+}
diff --git a/shell/loadgraph-uber.c b/shell/loadgraph-uber.c
new file mode 100644
index 0000000..61964b3
--- /dev/null
+++ b/shell/loadgraph-uber.c
@@ -0,0 +1,127 @@
+/*
+ * Christian Hergert's uber-graph (GPL3)
+ * wrapped in an interface compatible with
+ * Leandro A. F. Pereira's loadgraph (GPL2.1).
+ */
+
+#include <string.h>
+#include "loadgraph.h"
+#include "uber.h"
+
+#define LG_MAX_LINES 9
+
+static const gchar *default_colors[] = { "#73d216",
+                                         "#f57900",
+     /*colors from simple.c sample */    "#3465a4",
+                                         "#ef2929",
+                                         "#75507b",
+                                         "#ce5c00",
+                                         "#c17d11",
+                                         "#ce5c00",
+                                         "#729fcf",
+                                         NULL };
+
+struct _LoadGraph {
+    GtkWidget *uber_widget;
+    gdouble cur_value[LG_MAX_LINES];
+    gint height;
+};
+
+gdouble
+_sample_func (UberLineGraph *graph,
+                 guint      line,
+                 gpointer   user_data)
+{
+    LoadGraph *lg = (LoadGraph *)user_data;
+    return lg->cur_value[line-1];
+}
+
+LoadGraph *load_graph_new(gint size)
+{
+    LoadGraph *lg;
+    GdkRGBA color;
+    int i = 0;
+
+    lg = g_new0(LoadGraph, 1);
+    lg->uber_widget = uber_line_graph_new();
+    lg->height = (size+1) * 2; /* idk */
+    for (i = 0; i < LG_MAX_LINES; i++) {
+        lg->cur_value[i] = UBER_LINE_GRAPH_NO_VALUE;
+        //GtkWidget *label = uber_label_new();
+        //uber_label_set_text(UBER_LABEL(label), "BLAH!");
+        gdk_rgba_parse(&color, default_colors[i]);
+        uber_line_graph_add_line(UBER_LINE_GRAPH(lg->uber_widget), &color, NULL); /* UBER_LABEL(label) */
+    }
+    uber_line_graph_set_autoscale(UBER_LINE_GRAPH(lg->uber_widget), TRUE);
+    uber_line_graph_set_data_func(UBER_LINE_GRAPH(lg->uber_widget),
+                (UberLineGraphFunc)_sample_func, (gpointer *)lg, NULL);
+    return lg;
+}
+
+void load_graph_set_data_suffix(LoadGraph * lg, gchar * suffix)
+{
+
+}
+
+gchar *load_graph_get_data_suffix(LoadGraph * lg)
+{
+    return strdup("");
+}
+
+GtkWidget *load_graph_get_framed(LoadGraph * lg)
+{
+    if (lg != NULL)
+        return lg->uber_widget;
+    return NULL;
+}
+
+void load_graph_clear(LoadGraph * lg)
+{
+    int i;
+    if (lg != NULL) {
+        for (i = 0; i < LG_MAX_LINES; i++) {
+            lg->cur_value[i] = UBER_LINE_GRAPH_NO_VALUE;
+        }
+        uber_graph_scale_changed(lg->uber_widget);
+    }
+}
+
+void load_graph_set_color(LoadGraph * lg, LoadGraphColor color)
+{
+
+}
+
+void load_graph_destroy(LoadGraph * lg)
+{
+    if (lg != NULL) {
+        g_object_unref(lg->uber_widget);
+        g_free(lg);
+    }
+}
+
+static gboolean _expose(GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
+{
+    return TRUE;
+}
+
+void load_graph_configure_expose(LoadGraph * lg)
+{
+
+}
+
+void load_graph_update_ex(LoadGraph *lg, guint line, gdouble value)
+{
+    if (lg != NULL && line < LG_MAX_LINES)
+        lg->cur_value[line] = value;
+}
+
+void load_graph_update(LoadGraph * lg, gdouble value)
+{
+    load_graph_update_ex(lg, 0, value);
+}
+
+gint load_graph_get_height(LoadGraph *lg) {
+    if (lg != NULL)
+        return lg->height;
+    return 0;
+}
diff --git a/shell/loadgraph.c b/shell/loadgraph.c
new file mode 100644
index 0000000..ceb9172
--- /dev/null
+++ b/shell/loadgraph.c
@@ -0,0 +1,300 @@
+/*
+ * Simple Load Graph
+ * Version 0.1 - Wed, Jan 11 2006
+ *   - initial release
+ * Version 0.1.1 - Fri, Jan 13 2006
+ *   - fixes autoscaling
+ *   - add color
+ *
+ * Copyright (C) 2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ * The Simple Load Graph is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License, version 2.1, as published by the Free Software Foundation.
+ *
+ * The Simple Load Graph is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the Simple Load Graph; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ */
+
+#include "loadgraph.h"
+
+struct _LoadGraph {
+    GdkPixmap     *buf;
+    GdkGC         *grid;
+    GdkGC         *trace;
+    GdkGC         *fill;
+    GtkWidget     *area;
+
+    gint          *data;
+    gfloat         scale;
+
+    gint       size;
+    gint       width, height;
+    LoadGraphColor color;
+
+    gint       max_value, remax_count;
+
+    PangoLayout   *layout;
+    gchar     *suffix;
+};
+
+static void _draw(LoadGraph * lg);
+
+LoadGraph *load_graph_new(gint size)
+{
+    LoadGraph *lg;
+
+    lg = g_new0(LoadGraph, 1);
+
+    size++;
+
+    lg->suffix = g_strdup("");
+    lg->area = gtk_drawing_area_new();
+    lg->size = (size * 3) / 2;
+    lg->data = g_new0(gint, lg->size);
+
+    lg->scale = 1.0;
+
+    lg->width = size * 6;
+    lg->height = size * 2;
+
+    lg->max_value = 1;
+    lg->remax_count = 0;
+
+    lg->layout = pango_layout_new(gtk_widget_get_pango_context(lg->area));
+
+    gtk_widget_set_size_request(lg->area, lg->width, lg->height);
+    gtk_widget_show(lg->area);
+
+    return lg;
+}
+
+void load_graph_set_data_suffix(LoadGraph * lg, gchar * suffix)
+{
+    g_free(lg->suffix);
+    lg->suffix = g_strdup(suffix);
+}
+
+gchar *load_graph_get_data_suffix(LoadGraph * lg)
+{
+    return lg->suffix;
+}
+
+GtkWidget *load_graph_get_framed(LoadGraph * lg)
+{
+    GtkWidget *align, *frame;
+
+    align = gtk_alignment_new(0.5, 0.5, 0, 0);
+    gtk_widget_show(align);
+
+    frame = gtk_frame_new(NULL);
+    gtk_widget_show(frame);
+    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
+
+    gtk_container_add(GTK_CONTAINER(align), frame);
+    gtk_container_add(GTK_CONTAINER(frame), lg->area);
+
+    return align;
+}
+
+void load_graph_clear(LoadGraph * lg)
+{
+    gint i;
+
+    for (i = 0; i < lg->size; i++)
+        lg->data[i] = 0;
+
+    lg->scale = 1.0;
+    lg->max_value = 1;
+    lg->remax_count = 0;
+
+    _draw(lg);
+}
+
+void load_graph_set_color(LoadGraph * lg, LoadGraphColor color)
+{
+    lg->color = color;
+    gdk_rgb_gc_set_foreground(lg->trace, lg->color);
+    gdk_rgb_gc_set_foreground(lg->fill, lg->color - 0x303030);
+    gdk_rgb_gc_set_foreground(lg->grid, lg->color - 0xcdcdcd);
+}
+
+void load_graph_destroy(LoadGraph * lg)
+{
+    g_free(lg->data);
+    gtk_widget_destroy(lg->area);
+    gdk_pixmap_unref(lg->buf);
+    g_object_unref(lg->trace);
+    g_object_unref(lg->grid);
+    g_object_unref(lg->fill);
+    g_object_unref(lg->layout);
+    g_free(lg);
+}
+
+static gboolean _expose(GtkWidget * widget, GdkEventExpose * event,
+            gpointer user_data)
+{
+    LoadGraph *lg = (LoadGraph *) user_data;
+    GdkDrawable *draw = GDK_DRAWABLE(lg->buf);
+
+    gdk_draw_drawable(lg->area->window,
+              lg->area->style->black_gc,
+              draw, 0, 0, 0, 0, lg->width, lg->height);
+    return FALSE;
+}
+
+void load_graph_configure_expose(LoadGraph * lg)
+{
+    /* creates the backing store pixmap */
+    gtk_widget_realize(lg->area);
+    lg->buf = gdk_pixmap_new(lg->area->window, lg->width, lg->height, -1);
+
+    /* create the graphic contexts */
+    lg->grid = gdk_gc_new(GDK_DRAWABLE(lg->buf));
+    lg->trace = gdk_gc_new(GDK_DRAWABLE(lg->buf));
+    lg->fill = gdk_gc_new(GDK_DRAWABLE(lg->buf));
+
+    /* the default color is green */
+    load_graph_set_color(lg, LG_COLOR_GREEN);
+
+    /* init graphic contexts */
+    gdk_gc_set_line_attributes(lg->grid,
+                   1, GDK_LINE_ON_OFF_DASH,
+                   GDK_CAP_NOT_LAST, GDK_JOIN_ROUND);
+    gdk_gc_set_dashes(lg->grid, 0, (gint8*)"\2\2", 2);
+
+    gdk_gc_set_line_attributes(lg->trace,
+                   1, GDK_LINE_SOLID,
+                   GDK_CAP_PROJECTING, GDK_JOIN_ROUND);
+
+    /* configures the expose event */
+    g_signal_connect(G_OBJECT(lg->area), "expose-event",
+             (GCallback) _expose, lg);
+}
+
+static void _draw_label_and_line(LoadGraph * lg, gint position, gint value)
+{
+    gchar *tmp;
+
+    /* draw lines */
+    if (position > 0)
+        gdk_draw_line(GDK_DRAWABLE(lg->buf), lg->grid, 0, position,
+                  lg->width, position);
+    else
+        position = -1 * position;
+
+    /* draw label */
+    tmp =
+    g_strdup_printf("<span size=\"x-small\">%d%s</span>", value,
+            lg->suffix);
+
+    pango_layout_set_markup(lg->layout, tmp, -1);
+    pango_layout_set_width(lg->layout,
+               lg->area->allocation.width * PANGO_SCALE);
+    gdk_draw_layout(GDK_DRAWABLE(lg->buf), lg->trace, 2, position,
+            lg->layout);
+
+    g_free(tmp);
+}
+
+static void _draw(LoadGraph * lg)
+{
+    GdkDrawable *draw = GDK_DRAWABLE(lg->buf);
+    gint i, d;
+
+    /* clears the drawing area */
+    gdk_draw_rectangle(draw, lg->area->style->black_gc,
+               TRUE, 0, 0, lg->width, lg->height);
+
+
+    /* the graph */
+    GdkPoint *points = g_new0(GdkPoint, lg->size + 1);
+
+    for (i = 0; i < lg->size; i++) {
+        points[i].x = i * 4;
+        points[i].y = lg->height - lg->data[i] * lg->scale;
+    }
+
+    points[0].x = points[1].x = 0;
+    points[0].y = points[i].y = lg->height;
+    points[i].x = points[i - 1].x = lg->width;
+
+    gdk_draw_polygon(draw, lg->fill, TRUE, points, lg->size + 1);
+    gdk_draw_polygon(draw, lg->trace, FALSE, points, lg->size + 1);
+
+    g_free(points);
+
+    /* vertical bars */
+    for (i = lg->width, d = 0; i > 1; i--, d++)
+        if ((d % 45) == 0 && d)
+            gdk_draw_line(draw, lg->grid, i, 0, i, lg->height);
+
+    /* horizontal bars and labels; 25%, 50% and 75% */
+    _draw_label_and_line(lg, -1, lg->max_value);
+    _draw_label_and_line(lg, lg->height / 4, 3 * (lg->max_value / 4));
+    _draw_label_and_line(lg, lg->height / 2, lg->max_value / 2);
+    _draw_label_and_line(lg, 3 * (lg->height / 4), lg->max_value / 4);
+
+    gtk_widget_queue_draw(lg->area);
+}
+
+void load_graph_update_ex(LoadGraph *lg, guint line, gdouble value)
+{
+    /* not implemented */
+    if (line == 0)
+        load_graph_update(lg, value);
+}
+
+void load_graph_update(LoadGraph * lg, gdouble v)
+{
+    gint i;
+    gint value = (gint)v;
+
+    if (value < 0)
+        return;
+
+    /* shift-right our data */
+    for (i = 0; i < lg->size - 1; i++) {
+        lg->data[i] = lg->data[i + 1];
+    }
+
+    /* insert the updated value */
+    lg->data[i] = value;
+
+    /* calculates the maximum value */
+    if (lg->remax_count++ > 20) {
+        /* only finds the maximum amongst the data every 20 times */
+        lg->remax_count = 0;
+
+        gint max = lg->data[0];
+        for (i = 1; i < lg->size; i++) {
+            if (lg->data[i] > max)
+            max = lg->data[i];
+        }
+
+        lg->max_value = max;
+    } else {
+        /* otherwise, select the maximum between the current maximum
+           and the supplied value */
+        lg->max_value = MAX(value, lg->max_value);
+    }
+
+    /* recalculates the scale; always use 90% of it */
+    lg->scale = 0.90 * ((gfloat) lg->height / (gfloat) lg->max_value);
+
+    /* redraw */
+    _draw(lg);
+}
+
+gint load_graph_get_height(LoadGraph *lg) {
+    if (lg != NULL)
+        return lg->height;
+    return 0;
+}
diff --git a/shell/menu.c b/shell/menu.c
new file mode 100644
index 0000000..b0f01e5
--- /dev/null
+++ b/shell/menu.c
@@ -0,0 +1,166 @@
+/*
+ * HardInfo
+ * Copyright(C) 2003-2007 Leandro A. F. Pereira.
+ *
+ * menu.c is based on UI Manager tutorial by Ryan McDougall
+ * Copyright(C) 2005 Ryan McDougall.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <menu.h>
+#include <config.h>
+
+#include <stock.h>
+
+#include <callbacks.h>
+#include <hardinfo.h>
+
+
+#include "uidefs.h"
+
+static GtkActionEntry entries[] = {
+    {"InformationMenuAction", NULL, N_("_Information")},	/* name, stock id, label */
+    {"RemoteMenuAction", NULL, N_("_Remote")},
+    {"ViewMenuAction", NULL, N_("_View")},
+    {"HelpMenuAction", NULL, N_("_Help")},
+    {"HelpMenuModulesAction", HI_STOCK_ABOUT_MODULES, N_("About _Modules")},
+    {"MainMenuBarAction", NULL, ""},
+
+    {"ReportAction", HI_STOCK_REPORT,	/* name, stock id */
+     N_("Generate _Report"), "<control>R",	/* label, accelerator */
+     NULL,			/* tooltip */
+     G_CALLBACK(cb_generate_report)},
+
+    {"SyncManagerAction", HI_STOCK_SYNC_MENU,
+     N_("_Network Updater..."), NULL,
+     NULL,
+     G_CALLBACK(cb_sync_manager)},
+
+    {"OpenAction", "_Open",
+     N_("_Open..."), NULL,
+     NULL,
+     G_CALLBACK(cb_sync_manager)},
+
+    {"CopyAction", "_Copy",
+     N_("_Copy to Clipboard"), "<control>C",
+     N_("Copy to clipboard"),
+     G_CALLBACK(cb_copy_to_clipboard)},
+
+    {"RefreshAction", "_Refresh",
+     N_("_Refresh"), "F5",
+     NULL,
+     G_CALLBACK(cb_refresh)},
+
+    {"HomePageAction", HI_STOCK_INTERNET,
+     N_("_Open HardInfo Web Site"), NULL,
+     NULL,
+     G_CALLBACK(cb_open_web_page)},
+
+    {"ReportBugAction", HI_STOCK_INTERNET,
+     N_("_Report bug"), NULL,
+     NULL,
+     G_CALLBACK(cb_report_bug)},
+
+    {"AboutAction", "_About",
+     N_("_About HardInfo"), NULL,
+     N_("Displays program version information"),
+     G_CALLBACK(cb_about)},
+
+    {"QuitAction", "_Quit",
+     N_("_Quit"), "<control>Q",
+     NULL,
+     G_CALLBACK(cb_quit)}
+};
+
+static GtkToggleActionEntry toggle_entries[] = {
+    {"SidePaneAction", NULL,
+     N_("_Side Pane"), NULL,
+     N_("Toggles side pane visibility"),
+     G_CALLBACK(cb_side_pane)},
+    {"ToolbarAction", NULL,
+     N_("_Toolbar"), NULL,
+     NULL,
+     G_CALLBACK(cb_toolbar)},
+};
+
+/* Implement a handler for GtkUIManager's "add_widget" signal. The UI manager
+ * will emit this signal whenever it needs you to place a new widget it has. */
+static void
+menu_add_widget(GtkUIManager * ui, GtkWidget * widget,
+		GtkContainer * container)
+{
+    gtk_box_pack_start(GTK_BOX(container), widget, FALSE, FALSE, 0);
+    gtk_widget_show(widget);
+}
+
+void menu_init(Shell * shell)
+{
+    GtkWidget *menu_box;	/* Packing box for the menu and toolbars */
+    GtkActionGroup *action_group;	/* Packing group for our Actions */
+    GtkUIManager *menu_manager;	/* The magic widget! */
+    GError *error;		/* For reporting exceptions or errors */
+    GtkAccelGroup *accel_group;
+
+    /* Create our objects */
+    menu_box = shell->vbox;
+    action_group = gtk_action_group_new("HardInfo");
+    menu_manager = gtk_ui_manager_new();
+
+    shell->action_group = action_group;
+    shell->ui_manager = menu_manager;
+
+    /* Pack up our objects:
+     * menu_box -> window
+     * actions -> action_group
+     * action_group -> menu_manager */
+    gtk_action_group_set_translation_domain( action_group, "hardinfo" );//gettext
+    gtk_action_group_add_actions(action_group, entries,
+				 G_N_ELEMENTS(entries), NULL);
+    gtk_action_group_add_toggle_actions(action_group, toggle_entries,
+					G_N_ELEMENTS(toggle_entries),
+					NULL);
+    gtk_ui_manager_insert_action_group(menu_manager, action_group, 0);
+
+
+    /* Read in the UI from our XML file */
+    error = NULL;
+    gtk_ui_manager_add_ui_from_string(menu_manager, uidefs_str, -1,
+				      &error);
+
+    if (error) {
+	g_error("Building menus failed: %s", error->message);
+	g_error_free(error);
+	return;
+    }
+
+    /* Enable menu accelerators */
+    accel_group = gtk_ui_manager_get_accel_group(menu_manager);
+    gtk_window_add_accel_group(GTK_WINDOW(shell->window), accel_group);
+
+    /* Connect up important signals */
+    /* This signal is necessary in order to place widgets from the UI manager
+     * into the menu_box */
+    g_signal_connect(menu_manager, "add_widget",
+		     G_CALLBACK(menu_add_widget), menu_box);
+
+    /* Show the window and run the main loop, we're done! */
+    gtk_widget_show(menu_box);
+
+    gtk_toolbar_set_style(GTK_TOOLBAR
+			  (gtk_ui_manager_get_widget
+			   (shell->ui_manager, "/MainMenuBarAction")),
+			  GTK_TOOLBAR_BOTH_HORIZ);
+}
diff --git a/shell/report.c b/shell/report.c
new file mode 100644
index 0000000..6abb03a
--- /dev/null
+++ b/shell/report.c
@@ -0,0 +1,963 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2008 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <report.h>
+#include <stdio.h>
+#include <string.h>
+#include <shell.h>
+#include <iconcache.h>
+#include <hardinfo.h>
+#include <config.h>
+
+static ReportDialog *report_dialog_new(GtkTreeModel * model,
+				       GtkWidget * parent);
+static void set_all_active(ReportDialog * rd, gboolean setting);
+
+static FileTypes file_types[] = {
+    {"HTML (*.html)", "text/html", ".html", report_context_html_new},
+    {"Plain Text (*.txt)", "text/plain", ".txt", report_context_text_new},
+    {NULL, NULL, NULL, NULL}
+};
+
+void report_header(ReportContext * ctx)
+{
+    ctx->header(ctx);
+}
+
+void report_footer(ReportContext * ctx)
+{
+    ctx->footer(ctx);
+}
+
+void report_title(ReportContext * ctx, gchar * text)
+{
+    ctx->title(ctx, text);
+}
+
+void report_subtitle(ReportContext * ctx, gchar * text)
+{
+    ctx->subtitle(ctx, text);
+}
+
+void report_subsubtitle(ReportContext * ctx, gchar * text)
+{
+    ctx->subsubtitle(ctx, text);
+}
+
+void report_key_value(ReportContext * ctx, gchar * key, gchar * value)
+{
+    ctx->keyvalue(ctx, key, value);
+}
+
+gint report_get_visible_columns(ReportContext *ctx)
+{
+    gint columns;
+
+    /* Column count starts at two, since we always have at least
+       two columns visible. */
+    columns = 2;
+
+    /* Either the Progress column or the Value column is available at
+       the same time. So we don't count them. */
+
+    if (ctx->columns & REPORT_COL_EXTRA1)
+      columns++;
+
+    if (ctx->columns & REPORT_COL_EXTRA2)
+      columns++;
+
+    return columns;
+}
+
+void report_context_configure(ReportContext * ctx, GKeyFile * keyfile)
+{
+    gchar **keys;
+    const gchar *group = "$ShellParam$";
+
+    /* FIXME: sometime in the future we'll save images in the report. this
+       flag will be set if we should support that.
+
+       so i don't forget how to encode the images inside the html files:
+       https://en.wikipedia.org/wiki/Data:_URI_scheme */
+
+    ctx->is_image_enabled = (g_key_file_get_boolean(keyfile,
+						    group,
+						    "ViewType",
+						    NULL) == SHELL_VIEW_PROGRESS);
+
+
+    keys = g_key_file_get_keys(keyfile, group, NULL, NULL);
+    if (keys) {
+      gint i = 0;
+
+      for (; keys[i]; i++) {
+        gchar *key = keys[i];
+
+        if (g_str_equal(key, "ShowColumnHeaders")) {
+          ctx->show_column_headers = g_key_file_get_boolean(keyfile, group, key, NULL);
+        } else if (g_str_has_prefix(key, "ColumnTitle")) {
+          gchar *value, *title = strchr(key, '$');
+
+          if (!title) {
+                  DEBUG("couldn't find column title");
+                  break;
+          }
+          title++;
+          if (!*title) {
+                  DEBUG("title is empty");
+                  break;
+          }
+
+          value = g_key_file_get_value(keyfile, group, key, NULL);
+          if (g_str_equal(title, "Extra1")) {
+                  ctx->columns |= REPORT_COL_EXTRA1;
+          } else if (g_str_equal(title, "Extra2")) {
+                  ctx->columns |= REPORT_COL_EXTRA2;
+          } else if (g_str_equal(title, "Value")) {
+                  ctx->columns |= REPORT_COL_VALUE;
+          } else if (g_str_equal(title, "TextValue")) {
+                  ctx->columns |= REPORT_COL_TEXTVALUE;
+          } else if (g_str_equal(title, "Progress")) {
+                  ctx->columns |= REPORT_COL_PROGRESS;
+          }
+
+          g_hash_table_replace(ctx->column_titles,
+                               g_strdup(title), g_strdup(value));
+        } else if (g_str_equal(key, "ViewType")) {
+          if (g_key_file_get_integer(keyfile, group, "ViewType", NULL) == SHELL_VIEW_PROGRESS) {
+            ctx->columns &= ~REPORT_COL_VALUE;
+            ctx->columns |= REPORT_COL_PROGRESS;
+          }
+        }
+      }
+
+      g_strfreev(keys);
+    }
+
+}
+
+void report_table(ReportContext * ctx, gchar * text)
+{
+    GKeyFile *key_file = g_key_file_new();
+    gchar **groups;
+    gint i;
+
+    /* make only "Value" column visible ("Key" column is always visible) */
+    ctx->columns = REPORT_COL_VALUE;
+    ctx->show_column_headers = FALSE;
+
+    /**/
+    g_key_file_load_from_data(key_file, text, strlen(text), 0, NULL);
+    groups = g_key_file_get_groups(key_file, NULL);
+
+    for (i = 0; groups[i]; i++) {
+	if (groups[i][0] == '$') {
+	    report_context_configure(ctx, key_file);
+	    break;
+	}
+    }
+
+    for (i = 0; groups[i]; i++) {
+	gchar *group, *tmpgroup;
+	gchar **keys;
+	gint j;
+
+	if (groups[i][0] == '$') {
+	    continue;
+	}
+
+	group = groups[i];
+
+	tmpgroup = g_strdup(group);
+	strend(group, '#');
+
+	report_subsubtitle(ctx, group);
+
+#if 0
+	if (ctx->is_image_enabled) {
+	    report_embed_image(ctx, key_file, group);
+	} else {
+#endif
+	    keys = g_key_file_get_keys(key_file, tmpgroup, NULL, NULL);
+	    for (j = 0; keys[j]; j++) {
+		gchar *key = keys[j];
+		gchar *value;
+
+		value = g_key_file_get_value(key_file, tmpgroup, key, NULL);
+
+		if (g_utf8_validate(key, -1, NULL) && g_utf8_validate(value, -1, NULL)) {
+		    strend(key, '#');
+
+		    if (g_str_equal(value, "...")) {
+			g_free(value);
+			if (!(value = ctx->entry->fieldfunc(key))) {
+			    value = g_strdup("...");
+			}
+		    }
+
+		    if (*key == '$') {
+			report_key_value(ctx, strchr(key + 1, '$') + 1,
+					 value);
+		    } else {
+			report_key_value(ctx, key, value);
+		    }
+
+		}
+
+		g_free(value);
+	    }
+
+	    g_strfreev(keys);
+#if 0
+	}
+#endif
+	g_free(tmpgroup);
+    }
+
+    g_strfreev(groups);
+    g_key_file_free(key_file);
+}
+
+static void report_html_header(ReportContext * ctx)
+{
+    g_free(ctx->output);
+
+    ctx->output =
+	g_strdup_printf
+	("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Final//EN\">\n"
+	 "<html><head>\n" "<title>HardInfo (%s) System Report</title>\n"
+	 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"
+	 "<style>\n" "    body    { background: #fff }\n"
+	 "    .title  { font: bold 130%% serif; color: #0066FF; padding: 30px 0 10px 0 }\n"
+	 "    .stitle { font: bold 100%% sans-serif; color: #0044DD; padding: 30px 0 10px 0 }\n"
+	 "    .sstitle{ font: bold 80%% serif; color: #000000; background: #efefef }\n"
+	 "    .field  { font: 80%% sans-serif; color: #000000; padding: 2px; padding-left: 50px }\n"
+	 "    .value  { font: 80%% sans-serif; color: #505050 }\n"
+	 "</style>\n" "</head><body>\n",
+	 VERSION);
+}
+
+static void report_html_footer(ReportContext * ctx)
+{
+    ctx->output = h_strconcat(ctx->output,
+			      "</table></html>", NULL);
+}
+
+static void report_html_title(ReportContext * ctx, gchar * text)
+{
+    if (!ctx->first_table) {
+      ctx->output = h_strdup_cprintf("</table>", ctx->output);
+    }
+
+    ctx->output = h_strdup_cprintf("<h1 class=\"title\">%s</h1>", ctx->output, text);
+}
+
+static void report_html_subtitle(ReportContext * ctx, gchar * text)
+{
+    gint columns = report_get_visible_columns(ctx);
+
+    if (!ctx->first_table) {
+      ctx->output = h_strdup_cprintf("</table>", ctx->output);
+    } else {
+      ctx->first_table = FALSE;
+    }
+
+    ctx->output = h_strdup_cprintf("<table><tr><td colspan=\"%d\" class=\"stit"
+				  "le\">%s</td></tr>\n",
+				  ctx->output,
+				  columns,
+				  text);
+}
+
+static void report_html_subsubtitle(ReportContext * ctx, gchar * text)
+{
+    gint columns = report_get_visible_columns(ctx);
+
+    ctx->output = h_strdup_cprintf("<tr><td colspan=\"%d\" class=\"ssti"
+				  "tle\">%s</td></tr>\n",
+				  ctx->output,
+				  columns,
+				  text);
+}
+
+static void
+report_html_key_value(ReportContext * ctx, gchar * key, gchar * value)
+{
+    gint columns = report_get_visible_columns(ctx);
+    gchar **values;
+    gint i, mc;
+
+    if (columns == 2) {
+      ctx->output = h_strdup_cprintf("<tr><td class=\"field\">%s</td>"
+                                    "<td class=\"value\">%s</td></tr>\n",
+                                    ctx->output,
+                                    key, value);
+    } else {
+      values = g_strsplit(value, "|", columns);
+      mc = g_strv_length(values) - 1;
+
+      ctx->output = h_strdup_cprintf("\n<tr>\n<td class=\"field\">%s</td>", ctx->output, key);
+
+      for (i = mc; i >= 0; i--) {
+        ctx->output = h_strdup_cprintf("<td class=\"value\">%s</td>",
+                                       ctx->output,
+                                       values[i]);
+      }
+
+      ctx->output = h_strdup_cprintf("</tr>\n", ctx->output);
+
+      g_strfreev(values);
+    }
+}
+
+static void report_text_header(ReportContext * ctx)
+{
+    g_free(ctx->output);
+
+    ctx->output = g_strdup("");
+}
+
+static void report_text_footer(ReportContext * ctx)
+{
+}
+
+static void report_text_title(ReportContext * ctx, gchar * text)
+{
+    gchar *str = (gchar *) ctx->output;
+    int i = strlen(text);
+
+    str = h_strdup_cprintf("\n%s\n", str, text);
+    for (; i; i--)
+	str = h_strconcat(str, "*", NULL);
+
+    str = h_strconcat(str, "\n\n", NULL);
+    ctx->output = str;
+}
+
+static void report_text_subtitle(ReportContext * ctx, gchar * text)
+{
+    gchar *str = ctx->output;
+    int i = strlen(text);
+
+    str = h_strdup_cprintf("\n%s\n", str, text);
+    for (; i; i--)
+	str = h_strconcat(str, "-", NULL);
+
+    str = h_strconcat(str, "\n\n", NULL);
+    ctx->output = str;
+}
+
+static void report_text_subsubtitle(ReportContext * ctx, gchar * text)
+{
+    ctx->output = h_strdup_cprintf("-%s-\n", ctx->output, text);
+}
+
+static void
+report_text_key_value(ReportContext * ctx, gchar * key, gchar * value)
+{
+    gint columns = report_get_visible_columns(ctx);
+    gchar **values;
+    gint i, mc;
+
+    if (columns == 2) {
+      if (strlen(value))
+          ctx->output = h_strdup_cprintf("%s\t\t: %s\n", ctx->output, key, value);
+      else
+          ctx->output = h_strdup_cprintf("%s\n", ctx->output, key);
+    } else {
+      values = g_strsplit(value, "|", columns);
+      mc = g_strv_length(values) - 1;
+
+      ctx->output = h_strdup_cprintf("%s\t", ctx->output, key);
+
+      for (i = mc; i >= 0; i--) {
+        ctx->output = h_strdup_cprintf("%s\t",
+                                       ctx->output,
+                                       values[i]);
+      }
+
+      ctx->output = h_strdup_cprintf("\n", ctx->output);
+
+      g_strfreev(values);
+    }
+}
+
+static GSList *report_create_module_list_from_dialog(ReportDialog * rd)
+{
+    ShellModule *module;
+    GSList *modules = NULL;
+    GtkTreeModel *model = rd->model;
+    GtkTreeIter iter;
+
+    gtk_tree_model_get_iter_first(model, &iter);
+    do {
+	gboolean selected;
+	gchar *name;
+
+	gtk_tree_model_get(model, &iter, TREE_COL_SEL, &selected, -1);
+	if (!selected)
+	    continue;
+
+	module = g_new0(ShellModule, 1);
+
+	gtk_tree_model_get(model, &iter, TREE_COL_NAME, &name, -1);
+	module->name = name;
+	module->entries = NULL;
+
+	if (gtk_tree_model_iter_has_child(model, &iter)) {
+	    ShellModuleEntry *entry;
+
+	    gint children = gtk_tree_model_iter_n_children(model, &iter);
+	    gint i;
+
+	    for (i = 0; i < children; i++) {
+		GtkTreeIter child;
+
+		gtk_tree_model_iter_nth_child(model, &child, &iter, i);
+
+		gtk_tree_model_get(model, &child, TREE_COL_SEL, &selected,
+				   -1);
+		if (!selected)
+		    continue;
+
+		gtk_tree_model_get(model, &child, TREE_COL_MODULE_ENTRY, &entry,
+				   -1);
+		module->entries = g_slist_append(module->entries, entry);
+	    }
+	}
+
+	modules = g_slist_append(modules, module);
+    } while (gtk_tree_model_iter_next(rd->model, &iter));
+
+    return modules;
+}
+
+static void
+report_create_inner_from_module_list(ReportContext * ctx, GSList * modules)
+{
+    for (; modules; modules = modules->next) {
+	ShellModule *module = (ShellModule *) modules->data;
+	GSList *entries;
+
+	if (!params.gui_running)
+	    fprintf(stderr, "\033[40;32m%s\033[0m\n", module->name);
+
+	report_title(ctx, module->name);
+
+	for (entries = module->entries; entries; entries = entries->next) {
+	    ShellModuleEntry *entry = (ShellModuleEntry *) entries->data;
+
+	    if (!params.gui_running)
+		fprintf(stderr, "\033[2K\033[40;32;1m %s\033[0m\n",
+			entry->name);
+
+	    ctx->entry = entry;
+	    report_subtitle(ctx, entry->name);
+	    module_entry_scan(entry);
+	    report_table(ctx, module_entry_function(entry));
+	}
+    }
+}
+
+void report_module_list_free(GSList * modules)
+{
+    GSList *m;
+
+    for (m = modules; m; m = m->next) {
+	ShellModule *module = (ShellModule *) m->data;
+
+	g_slist_free(module->entries);
+    }
+
+    g_slist_free(modules);
+}
+
+static gchar *report_get_filename(void)
+{
+    GtkWidget *dialog;
+    gchar *filename = NULL;
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    dialog = gtk_file_chooser_dialog_new(_("Save File"),
+					 NULL,
+					 GTK_FILE_CHOOSER_ACTION_SAVE,
+					 _("_Cancel"),
+					 GTK_RESPONSE_CANCEL,
+					 _("_Save"),
+					 GTK_RESPONSE_ACCEPT, NULL);
+#else
+    dialog = gtk_file_chooser_dialog_new(_("Save File"),
+					 NULL,
+					 GTK_FILE_CHOOSER_ACTION_SAVE,
+					 GTK_STOCK_CANCEL,
+					 GTK_RESPONSE_CANCEL,
+					 GTK_STOCK_SAVE,
+					 GTK_RESPONSE_ACCEPT, NULL);
+#endif
+
+    gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
+				      "hardinfo_report");
+
+    file_chooser_add_filters(dialog, file_types);
+    file_chooser_open_expander(dialog);
+
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+	gchar *ext = file_chooser_get_extension(dialog, file_types);
+	filename = file_chooser_build_filename(dialog, ext);
+    }
+    gtk_widget_destroy(dialog);
+    return filename;
+}
+
+ReportContext *report_context_html_new()
+{
+    ReportContext *ctx;
+
+    ctx = g_new0(ReportContext, 1);
+    ctx->header = report_html_header;
+    ctx->footer = report_html_footer;
+    ctx->title = report_html_title;
+    ctx->subtitle = report_html_subtitle;
+    ctx->subsubtitle = report_html_subsubtitle;
+    ctx->keyvalue = report_html_key_value;
+
+    ctx->output = g_strdup("");
+    ctx->format = REPORT_FORMAT_HTML;
+
+    ctx->column_titles = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                               g_free, g_free);
+    ctx->first_table = TRUE;
+
+    return ctx;
+}
+
+ReportContext *report_context_text_new()
+{
+    ReportContext *ctx;
+
+    ctx = g_new0(ReportContext, 1);
+    ctx->header = report_text_header;
+    ctx->footer = report_text_footer;
+    ctx->title = report_text_title;
+    ctx->subtitle = report_text_subtitle;
+    ctx->subsubtitle = report_text_subsubtitle;
+    ctx->keyvalue = report_text_key_value;
+
+    ctx->output = g_strdup("");
+    ctx->format = REPORT_FORMAT_TEXT;
+
+    ctx->column_titles = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                               g_free, g_free);
+    ctx->first_table = TRUE;
+
+    return ctx;
+}
+
+void report_context_free(ReportContext * ctx)
+{
+    g_hash_table_destroy(ctx->column_titles);
+    g_free(ctx->output);
+    g_free(ctx);
+}
+
+void report_create_from_module_list(ReportContext * ctx, GSList * modules)
+{
+    report_header(ctx);
+
+    report_create_inner_from_module_list(ctx, modules);
+    report_module_list_free(modules);
+
+    report_footer(ctx);
+}
+
+gchar *report_create_from_module_list_format(GSList * modules,
+					     ReportFormat format)
+{
+    ReportContext *(*create_context) ();
+    ReportContext *ctx;
+    gchar *retval;
+
+    if (format >= N_REPORT_FORMAT)
+	return NULL;
+
+    create_context = file_types[format].data;
+    if (!create_context)
+	return NULL;
+
+    ctx = create_context();
+
+    report_create_from_module_list(ctx, modules);
+    retval = g_strdup(ctx->output);
+
+    report_context_free(ctx);
+
+    return retval;
+}
+
+static gboolean report_generate(ReportDialog * rd)
+{
+    GSList *modules;
+    ReportContext *ctx;
+    ReportContext *(*create_context) ();
+    gchar *file;
+    FILE *stream;
+
+    if (!(file = report_get_filename()))
+	return FALSE;
+
+    if (!(stream = fopen(file, "w+"))) {
+	g_free(file);
+	return FALSE;
+    }
+
+    create_context = file_types_get_data_by_name(file_types, file);
+
+    if (!create_context) {
+	g_warning(_("Cannot create ReportContext. Programming bug?"));
+	g_free(file);
+	fclose(stream);
+	return FALSE;
+    }
+
+    ctx = create_context();
+    modules = report_create_module_list_from_dialog(rd);
+
+    report_create_from_module_list(ctx, modules);
+    fputs(ctx->output, stream);
+    fclose(stream);
+
+    if (ctx->format == REPORT_FORMAT_HTML) {
+	GtkWidget *dialog;
+	dialog = gtk_message_dialog_new(NULL,
+					GTK_DIALOG_DESTROY_WITH_PARENT,
+					GTK_MESSAGE_QUESTION,
+					GTK_BUTTONS_NONE,
+					_("Open the report with your web browser?"));
+#if GTK_CHECK_VERSION(3, 0, 0)
+    gtk_dialog_add_buttons(GTK_DIALOG(dialog),
+			       _("_No"), GTK_RESPONSE_REJECT,
+			       _("_Open"), GTK_RESPONSE_ACCEPT, NULL);
+#else
+	gtk_dialog_add_buttons(GTK_DIALOG(dialog),
+			       GTK_STOCK_NO, GTK_RESPONSE_REJECT,
+			       GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
+#endif
+	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+	    gchar *temp;
+
+	    temp = g_strdup_printf("file://%s", file);
+	    open_url(temp);
+
+	    g_free(temp);
+        }
+
+	gtk_widget_destroy(dialog);
+    }
+
+    report_context_free(ctx);
+    g_free(file);
+
+    return TRUE;
+}
+
+void report_dialog_show(GtkTreeModel * model, GtkWidget * parent)
+{
+    gboolean success;
+    ReportDialog *rd = report_dialog_new(model, parent);
+
+    if (gtk_dialog_run(GTK_DIALOG(rd->dialog)) == GTK_RESPONSE_ACCEPT) {
+	shell_status_update(_("Generating report..."));
+	gtk_widget_hide(rd->dialog);
+	shell_view_set_enabled(FALSE);
+	shell_status_set_enabled(TRUE);
+
+	success = report_generate(rd);
+
+	shell_status_set_enabled(FALSE);
+
+	if (success)
+	    shell_status_update(_("Report saved."));
+	else
+	    shell_status_update(_("Error while creating the report."));
+    }
+
+    set_all_active(rd, FALSE);
+    gtk_widget_destroy(rd->dialog);
+    g_free(rd);
+}
+
+static void
+set_children_active(GtkTreeModel * model, GtkTreeIter * iter,
+		    gboolean setting)
+{
+    if (gtk_tree_model_iter_has_child(model, iter)) {
+	gint children = gtk_tree_model_iter_n_children(model, iter);
+
+	gtk_tree_store_set(GTK_TREE_STORE(model), iter, TREE_COL_SEL,
+			   setting, -1);
+
+	for (children--; children >= 0; children--) {
+	    GtkTreeIter child;
+
+	    gtk_tree_model_iter_nth_child(model, &child, iter, children);
+	    gtk_tree_store_set(GTK_TREE_STORE(model), &child, TREE_COL_SEL,
+			       setting, -1);
+	}
+    }
+}
+
+static void set_all_active(ReportDialog * rd, gboolean setting)
+{
+    GtkTreeIter iter;
+    GtkTreeModel *model = rd->model;
+
+    gtk_tree_model_get_iter_first(model, &iter);
+
+    do {
+	set_children_active(model, &iter, setting);
+    } while (gtk_tree_model_iter_next(model, &iter));
+}
+
+static void report_dialog_sel_none(GtkWidget * widget, ReportDialog * rd)
+{
+    set_all_active(rd, FALSE);
+}
+
+static void report_dialog_sel_all(GtkWidget * widget, ReportDialog * rd)
+{
+    set_all_active(rd, TRUE);
+}
+
+static void
+report_dialog_sel_toggle(GtkCellRendererToggle * cellrenderertoggle,
+			 gchar * path_str, ReportDialog * rd)
+{
+    GtkTreeModel *model = rd->model;
+    GtkTreeIter iter;
+    GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
+    gboolean active;
+
+    gtk_tree_model_get_iter(model, &iter, path);
+    gtk_tree_model_get(model, &iter, TREE_COL_SEL, &active, -1);
+
+    active = !active;
+    gtk_tree_store_set(GTK_TREE_STORE(model), &iter, TREE_COL_SEL, active,
+		       -1);
+    set_children_active(model, &iter, active);
+
+    if (active) {
+        GtkTreeIter parent;
+
+        if (gtk_tree_model_iter_parent(model, &parent, &iter)) {
+            gtk_tree_store_set(GTK_TREE_STORE(model), &parent,
+                               TREE_COL_SEL, active, -1);
+        }
+    }
+
+    gtk_tree_path_free(path);
+}
+
+static ReportDialog
+    * report_dialog_new(GtkTreeModel * model, GtkWidget * parent)
+{
+    ReportDialog *rd;
+    GtkWidget *dialog;
+    GtkWidget *dialog1_vbox;
+    GtkWidget *scrolledwindow2;
+    GtkWidget *treeview2;
+    GtkWidget *vbuttonbox3;
+    GtkWidget *button3;
+    GtkWidget *button6;
+    GtkWidget *dialog1_action_area;
+    GtkWidget *button8;
+    GtkWidget *button7;
+    GtkWidget *label;
+    GtkWidget *hbox;
+
+    GtkTreeViewColumn *column;
+    GtkCellRenderer *cr_text, *cr_pbuf, *cr_toggle;
+
+    rd = g_new0(ReportDialog, 1);
+
+    dialog = gtk_dialog_new();
+    gtk_window_set_title(GTK_WINDOW(dialog), _("Generate Report"));
+    gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
+    gtk_window_set_default_size(GTK_WINDOW(dialog), 420, 260);
+    gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent));
+    gtk_window_set_position(GTK_WINDOW(dialog),
+			    GTK_WIN_POS_CENTER_ON_PARENT);
+    gtk_window_set_type_hint(GTK_WINDOW(dialog),
+			     GDK_WINDOW_TYPE_HINT_DIALOG);
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+    dialog1_vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+#else
+    dialog1_vbox = GTK_DIALOG(dialog)->vbox;
+#endif
+    gtk_box_set_spacing(GTK_BOX(dialog1_vbox), 5);
+    gtk_container_set_border_width(GTK_CONTAINER(dialog1_vbox), 4);
+    gtk_widget_show(dialog1_vbox);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+#else
+    hbox = gtk_hbox_new(FALSE, 5);
+#endif
+    gtk_box_pack_start(GTK_BOX(dialog1_vbox), hbox, FALSE, FALSE, 0);
+
+    label = gtk_label_new(_("<big><b>Generate Report</b></big>\n"
+			  "Please choose the information that you wish "
+			  "to view in your report:"));
+    gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+    gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
+#if GTK_CHECK_VERSION(3, 0, 0)
+    gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
+#else
+    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+#endif
+
+    gtk_box_pack_start(GTK_BOX(hbox),
+		       icon_cache_get_image("report-large.png"),
+		       FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
+    gtk_widget_show_all(hbox);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+#else
+    hbox = gtk_hbox_new(FALSE, 5);
+#endif
+    gtk_box_pack_start(GTK_BOX(dialog1_vbox), hbox, TRUE, TRUE, 0);
+    gtk_widget_show(hbox);
+
+    scrolledwindow2 = gtk_scrolled_window_new(NULL, NULL);
+    gtk_widget_show(scrolledwindow2);
+    gtk_box_pack_start(GTK_BOX(hbox), scrolledwindow2, TRUE, TRUE,
+		       0);
+    gtk_widget_set_size_request(scrolledwindow2, -1, 200);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow2),
+				   GTK_POLICY_AUTOMATIC,
+				   GTK_POLICY_AUTOMATIC);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
+					(scrolledwindow2), GTK_SHADOW_IN);
+
+    treeview2 = gtk_tree_view_new_with_model(model);
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview2), FALSE);
+    gtk_widget_show(treeview2);
+    gtk_container_add(GTK_CONTAINER(scrolledwindow2), treeview2);
+
+    column = gtk_tree_view_column_new();
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview2), column);
+
+    cr_toggle = gtk_cell_renderer_toggle_new();
+    gtk_tree_view_column_pack_start(column, cr_toggle, FALSE);
+    g_signal_connect(cr_toggle, "toggled",
+		     G_CALLBACK(report_dialog_sel_toggle), rd);
+    gtk_tree_view_column_add_attribute(column, cr_toggle, "active",
+				       TREE_COL_SEL);
+
+    cr_pbuf = gtk_cell_renderer_pixbuf_new();
+    gtk_tree_view_column_pack_start(column, cr_pbuf, FALSE);
+    gtk_tree_view_column_add_attribute(column, cr_pbuf, "pixbuf",
+				       TREE_COL_PBUF);
+
+    cr_text = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, cr_text, TRUE);
+    gtk_tree_view_column_add_attribute(column, cr_text, "markup",
+				       TREE_COL_NAME);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    vbuttonbox3 = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
+#else
+    vbuttonbox3 = gtk_vbutton_box_new();
+#endif
+    gtk_widget_show(vbuttonbox3);
+    gtk_box_pack_start(GTK_BOX(hbox), vbuttonbox3, FALSE, TRUE, 0);
+    gtk_box_set_spacing(GTK_BOX(vbuttonbox3), 5);
+    gtk_button_box_set_layout(GTK_BUTTON_BOX(vbuttonbox3),
+			      GTK_BUTTONBOX_START);
+
+    button3 = gtk_button_new_with_mnemonic(_("Select _None"));
+    gtk_widget_show(button3);
+    gtk_container_add(GTK_CONTAINER(vbuttonbox3), button3);
+#if GTK_CHECK_VERSION(2, 18, 0)
+    gtk_widget_set_can_default(button3, TRUE);
+#else
+    GTK_WIDGET_SET_FLAGS(button3, GTK_CAN_DEFAULT);
+#endif
+    g_signal_connect(button3, "clicked",
+		     G_CALLBACK(report_dialog_sel_none), rd);
+
+    button6 = gtk_button_new_with_mnemonic(_("Select _All"));
+    gtk_widget_show(button6);
+    gtk_container_add(GTK_CONTAINER(vbuttonbox3), button6);
+#if GTK_CHECK_VERSION(2, 18, 0)
+    gtk_widget_set_can_default(button6, TRUE);
+#else
+    GTK_WIDGET_SET_FLAGS(button6, GTK_CAN_DEFAULT);
+#endif
+    g_signal_connect(button6, "clicked", G_CALLBACK(report_dialog_sel_all),
+		     rd);
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+/* TODO:GTK3
+ * [https://developer.gnome.org/gtk3/stable/GtkDialog.html#gtk-dialog-get-action-area]
+ * gtk_dialog_get_action_area has been deprecated since version 3.12 and should not be used in newly-written code.
+ * Direct access to the action area is discouraged; use gtk_dialog_add_button(), etc.
+ */
+    dialog1_action_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+#else
+    dialog1_action_area = GTK_DIALOG(dialog)->action_area;
+#endif
+    gtk_widget_show(dialog1_action_area);
+    gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog1_action_area),
+			      GTK_BUTTONBOX_END);
+
+    button8 = gtk_button_new_with_mnemonic(_("_Cancel"));
+    gtk_widget_show(button8);
+    gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button8,
+				 GTK_RESPONSE_CANCEL);
+#if GTK_CHECK_VERSION(2, 18, 0)
+    gtk_widget_set_can_default(button8, TRUE);
+#else
+    GTK_WIDGET_SET_FLAGS(button8, GTK_CAN_DEFAULT);
+#endif
+
+    button7 = gtk_button_new_with_mnemonic(_("_Generate"));
+    gtk_widget_show(button7);
+    gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button7,
+				 GTK_RESPONSE_ACCEPT);
+#if GTK_CHECK_VERSION(2, 18, 0)
+    gtk_widget_set_can_default(button7, TRUE);
+#else
+    GTK_WIDGET_SET_FLAGS(button7, GTK_CAN_DEFAULT);
+#endif
+
+    rd->dialog = dialog;
+    rd->btn_cancel = button8;
+    rd->btn_generate = button7;
+    rd->btn_sel_all = button6;
+    rd->btn_sel_none = button3;
+    rd->treeview = treeview2;
+    rd->model = model;
+
+    gtk_tree_view_collapse_all(GTK_TREE_VIEW(treeview2));
+    set_all_active(rd, TRUE);
+
+    return rd;
+}
diff --git a/shell/shell.c b/shell/shell.c
new file mode 100644
index 0000000..8688f9a
--- /dev/null
+++ b/shell/shell.c
@@ -0,0 +1,2051 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib/gstdio.h>
+
+#include "config.h"
+
+#include "hardinfo.h"
+
+#include "shell.h"
+#include "syncmanager.h"
+#include "iconcache.h"
+#include "menu.h"
+#include "stock.h"
+
+#include "callbacks.h"
+
+/*
+ * Internal Prototypes ********************************************************
+ */
+
+static void create_window();
+static ShellTree *tree_new(void);
+static ShellInfoTree *info_tree_new(gboolean extra);
+
+static void module_selected(gpointer data);
+static void module_selected_show_info(ShellModuleEntry * entry,
+				      gboolean reload);
+static void info_selected(GtkTreeSelection * ts, gpointer data);
+static void info_selected_show_extra(gchar * data);
+static gboolean reload_section(gpointer data);
+static gboolean rescan_section(gpointer data);
+static gboolean update_field(gpointer data);
+
+/*
+ * Globals ********************************************************************
+ */
+
+static Shell *shell = NULL;
+static GHashTable *update_tbl = NULL;
+static GSList *update_sfusrc = NULL;
+
+/*
+ * Code :) ********************************************************************
+ */
+
+Shell *shell_get_main_shell(void)
+{
+    return shell;
+}
+
+void shell_ui_manager_set_visible(const gchar * path, gboolean setting)
+{
+    GtkWidget *widget;
+
+    if (!params.gui_running)
+	return;
+
+    widget = gtk_ui_manager_get_widget(shell->ui_manager, path);
+    if (!widget)
+	return;
+
+    if (setting)
+	gtk_widget_show(widget);
+    else
+	gtk_widget_hide(widget);
+}
+
+void shell_clear_tree_models(Shell *shell)
+{
+    gtk_tree_store_clear(GTK_TREE_STORE(shell->tree->model));
+    gtk_tree_store_clear(GTK_TREE_STORE(shell->info->model));
+    gtk_tree_store_clear(GTK_TREE_STORE(shell->moreinfo->model));
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(shell->info->view), FALSE);
+}
+
+void shell_clear_timeouts(Shell *shell)
+{
+    h_hash_table_remove_all(update_tbl);
+}
+
+void shell_action_set_property(const gchar * action_name,
+			       const gchar * property, gboolean setting)
+{
+    GtkAction *action;
+
+    if (!params.gui_running)
+	return;
+
+    action = gtk_action_group_get_action(shell->action_group, action_name);
+    if (action) {
+	GValue value = { 0 };
+
+	g_value_init(&value, G_TYPE_BOOLEAN);
+	g_value_set_boolean(&value, setting);
+
+	g_object_set_property(G_OBJECT(action), property, &value);
+
+	g_value_unset(&value);
+    }
+}
+
+void shell_action_set_label(const gchar * action_name, gchar * label)
+{
+#if GTK_CHECK_VERSION(2,16,0)
+    if (params.gui_running && shell->action_group) {
+	GtkAction *action;
+
+	action =
+	    gtk_action_group_get_action(shell->action_group, action_name);
+	if (action) {
+	    gtk_action_set_label(action, label);
+	}
+    }
+#endif
+}
+
+void shell_action_set_enabled(const gchar * action_name, gboolean setting)
+{
+    if (params.gui_running && shell->action_group) {
+	GtkAction *action;
+
+	action =
+	    gtk_action_group_get_action(shell->action_group, action_name);
+	if (action) {
+	    gtk_action_set_sensitive(action, setting);
+	}
+    }
+}
+
+gboolean shell_action_get_enabled(const gchar * action_name)
+{
+    GtkAction *action;
+
+    if (!params.gui_running)
+	return FALSE;
+
+    action = gtk_action_group_get_action(shell->action_group, action_name);
+    if (action) {
+	return gtk_action_get_sensitive(action);
+    }
+
+    return FALSE;
+}
+
+void shell_set_side_pane_visible(gboolean setting)
+{
+    if (!params.gui_running)
+	return;
+
+    if (setting)
+	gtk_widget_show(shell->tree->scroll);
+    else
+	gtk_widget_hide(shell->tree->scroll);
+}
+
+gboolean shell_action_get_active(const gchar * action_name)
+{
+    GtkAction *action;
+    GSList *proxies;
+
+    /* FIXME: Ugh. Are you sure there isn't any simpler way? O_o */
+    if (!params.gui_running)
+	return FALSE;
+
+    action = gtk_action_group_get_action(shell->action_group, action_name);
+    if (action) {
+	proxies = gtk_action_get_proxies(action);
+
+	for (; proxies; proxies = proxies->next) {
+	    GtkWidget *widget = (GtkWidget *) proxies->data;
+
+	    if (GTK_IS_CHECK_MENU_ITEM(widget)) {
+		return
+		    gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM
+						   (widget));
+	    }
+	}
+    }
+
+    return FALSE;
+}
+
+void shell_action_set_active(const gchar * action_name, gboolean setting)
+{
+    GtkAction *action;
+    GSList *proxies;
+
+    /* FIXME: Ugh. Are you sure there isn't any simpler way? O_o */
+    if (!params.gui_running)
+	return;
+
+    action = gtk_action_group_get_action(shell->action_group, action_name);
+    if (action) {
+	proxies = gtk_action_get_proxies(action);
+
+	for (; proxies; proxies = proxies->next) {
+	    GtkWidget *widget = (GtkWidget *) proxies->data;
+
+	    if (GTK_IS_CHECK_MENU_ITEM(widget)) {
+		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget),
+					       setting);
+		return;
+	    }
+	}
+    }
+}
+
+void shell_status_pulse(void)
+{
+    if (params.gui_running) {
+	if (shell->_pulses++ == 5) {
+	    /* we're pulsing for some time, disable the interface and change the cursor
+	       to a hourglass */
+	    shell_view_set_enabled(FALSE);
+	}
+
+	gtk_progress_bar_pulse(GTK_PROGRESS_BAR(shell->progress));
+	while (gtk_events_pending())
+	    gtk_main_iteration();
+    } else {
+	static gint counter = 0;
+
+	fprintf(stderr, "\033[2K\033[40;37;1m %c\033[0m\r",
+		"|/-\\"[counter++ % 4]);
+    }
+}
+
+void shell_status_set_percentage(gint percentage)
+{
+    if (params.gui_running) {
+	gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(shell->progress),
+				      (float) percentage / 100.0);
+	while (gtk_events_pending())
+	    gtk_main_iteration();
+    } else {
+	if (percentage < 1 || percentage >= 100) {
+	    fprintf(stderr, "\033[2K");
+	} else {
+	    gchar pbar[] = "----------";
+
+	    memset(pbar, '#', percentage / 10);
+
+	    fprintf(stderr, "\r\033[40;37;1m%3d%% \033[40;34;1m"
+		    "%s\033[0m\r", percentage, pbar);
+	}
+    }
+}
+
+void shell_view_set_enabled(gboolean setting)
+{
+    if (!params.gui_running)
+	return;
+
+    if (setting) {
+	shell->_pulses = 0;
+	widget_set_cursor(shell->window, GDK_LEFT_PTR);
+    } else {
+	widget_set_cursor(shell->window, GDK_WATCH);
+    }
+
+    gtk_widget_set_sensitive(shell->hpaned, setting);
+    shell_action_set_enabled("ViewMenuAction", setting);
+    shell_action_set_enabled("ConnectToAction", setting);
+    shell_action_set_enabled("RefreshAction", setting);
+    shell_action_set_enabled("CopyAction", setting);
+    shell_action_set_enabled("ReportAction", setting);
+    shell_action_set_enabled("SyncManagerAction", setting && sync_manager_count_entries() > 0);
+
+}
+
+void shell_status_set_enabled(gboolean setting)
+{
+    if (!params.gui_running)
+	return;
+
+    if (setting)
+	gtk_widget_show(shell->progress);
+    else {
+	gtk_widget_hide(shell->progress);
+	shell_view_set_enabled(TRUE);
+
+	shell_status_update(_("Done."));
+    }
+}
+
+void shell_do_reload(void)
+{
+    if (!params.gui_running || !shell->selected)
+	return;
+
+    shell_action_set_enabled("RefreshAction", FALSE);
+    shell_action_set_enabled("CopyAction", FALSE);
+    shell_action_set_enabled("ReportAction", FALSE);
+
+    shell_status_set_enabled(TRUE);
+
+    module_entry_reload(shell->selected);
+    module_selected(NULL);
+
+    shell_action_set_enabled("RefreshAction", TRUE);
+    shell_action_set_enabled("CopyAction", TRUE);
+    shell_action_set_enabled("ReportAction", TRUE);
+}
+
+void shell_status_update(const gchar * message)
+{
+    if (params.gui_running) {
+	gtk_label_set_markup(GTK_LABEL(shell->status), message);
+	gtk_progress_bar_pulse(GTK_PROGRESS_BAR(shell->progress));
+	while (gtk_events_pending())
+	    gtk_main_iteration();
+    } else {
+	fprintf(stderr, "\033[2K\033[40;37;1m %s\033[0m\r", message);
+    }
+}
+
+static void destroy_me(void)
+{
+    cb_quit();
+}
+
+static void close_note(GtkWidget * widget, gpointer user_data)
+{
+    gtk_widget_hide(shell->note->event_box);
+}
+
+static ShellNote *note_new(void)
+{
+    ShellNote *note;
+    GtkWidget *hbox, *icon, *button;
+    GtkWidget *border_box;
+    /* colors stolen from gtkinfobar.c */
+    GdkColor info_default_border_color     = { 0, 0xb800, 0xad00, 0x9d00 };
+    GdkColor info_default_fill_color       = { 0, 0xff00, 0xff00, 0xbf00 };
+
+    note = g_new0(ShellNote, 1);
+    note->label = gtk_label_new("");
+    note->event_box = gtk_event_box_new();
+    button = gtk_button_new();
+
+    border_box = gtk_event_box_new();
+    gtk_container_set_border_width(GTK_CONTAINER(border_box), 1);
+    gtk_container_add(GTK_CONTAINER(note->event_box), border_box);
+    gtk_widget_show(border_box);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    /* TODO:GTK3 css-based style */
+#else
+    gtk_widget_modify_bg(border_box, GTK_STATE_NORMAL, &info_default_fill_color);
+    gtk_widget_modify_bg(note->event_box, GTK_STATE_NORMAL, &info_default_border_color);
+#endif
+
+    icon = icon_cache_get_image("close.png");
+    gtk_widget_show(icon);
+    gtk_container_add(GTK_CONTAINER(button), icon);
+    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+    g_signal_connect(G_OBJECT(button), "clicked", (GCallback) close_note,
+		     NULL);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3);
+#else
+    hbox = gtk_hbox_new(FALSE, 3);
+#endif
+    icon = icon_cache_get_image("dialog-information.png");
+
+    gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(hbox), note->label, FALSE, FALSE, 0);
+    gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+
+    gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+    gtk_container_add(GTK_CONTAINER(border_box), hbox);
+    gtk_widget_show_all(hbox);
+
+    return note;
+}
+
+void shell_set_title(Shell *shell, gchar *subtitle)
+{
+    if (subtitle) {
+        gchar *tmp;
+
+        tmp = g_strdup_printf(_("%s - System Information"), subtitle);
+        gtk_window_set_title(GTK_WINDOW(shell->window), tmp);
+
+        g_free(tmp);
+    } else {
+        gtk_window_set_title(GTK_WINDOW(shell->window), _("System Information"));
+    }
+}
+
+static void create_window(void)
+{
+    GtkWidget *vbox, *hbox;
+
+    shell = g_new0(Shell, 1);
+
+    shell->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_icon(GTK_WINDOW(shell->window),
+			icon_cache_get_pixbuf("logo.png"));
+    shell_set_title(shell, NULL);
+    gtk_window_set_default_size(GTK_WINDOW(shell->window), 800, 600);
+    g_signal_connect(G_OBJECT(shell->window), "destroy", destroy_me, NULL);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+#else
+    vbox = gtk_vbox_new(FALSE, 0);
+#endif
+    gtk_widget_show(vbox);
+    gtk_container_add(GTK_CONTAINER(shell->window), vbox);
+    shell->vbox = vbox;
+
+    menu_init(shell);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+#else
+    hbox = gtk_hbox_new(FALSE, 5);
+#endif
+    gtk_widget_show(hbox);
+    gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 3);
+
+    shell->progress = gtk_progress_bar_new();
+    gtk_widget_set_size_request(shell->progress, 80, 10);
+    gtk_widget_hide(shell->progress);
+    gtk_box_pack_end(GTK_BOX(hbox), shell->progress, FALSE, FALSE, 5);
+
+    shell->status = gtk_label_new("");
+#if GTK_CHECK_VERSION(3, 0, 0)
+    gtk_widget_set_valign(GTK_WIDGET(shell->status), GTK_ALIGN_CENTER);
+#else
+    gtk_misc_set_alignment(GTK_MISC(shell->status), 0.0, 0.5);
+#endif
+    gtk_widget_show(shell->status);
+    gtk_box_pack_start(GTK_BOX(hbox), shell->status, FALSE, FALSE, 5);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    shell->hpaned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
+#else
+    shell->hpaned = gtk_hpaned_new();
+#endif
+    gtk_widget_show(shell->hpaned);
+    gtk_box_pack_end(GTK_BOX(vbox), shell->hpaned, TRUE, TRUE, 0);
+    gtk_paned_set_position(GTK_PANED(shell->hpaned), 210);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
+#else
+    vbox = gtk_vbox_new(FALSE, 5);
+#endif
+    gtk_widget_show(vbox);
+    gtk_paned_add2(GTK_PANED(shell->hpaned), vbox);
+
+    shell->note = note_new();
+    gtk_box_pack_end(GTK_BOX(vbox), shell->note->event_box, FALSE, FALSE, 0);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    shell->vpaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
+#else
+    shell->vpaned = gtk_vpaned_new();
+#endif
+    gtk_box_pack_start(GTK_BOX(vbox), shell->vpaned, TRUE, TRUE, 0);
+    gtk_widget_show(shell->vpaned);
+
+    shell->notebook = gtk_notebook_new();
+    gtk_paned_add2(GTK_PANED(shell->vpaned), shell->notebook);
+
+    gtk_widget_show(shell->window);
+    while (gtk_events_pending())
+	gtk_main_iteration();
+}
+
+static void view_menu_select_entry(gpointer data, gpointer data2)
+{
+    GtkTreePath *path;
+    GtkTreeIter *iter = (GtkTreeIter *) data2;
+
+    path = gtk_tree_model_get_path(shell->tree->model, iter);
+
+    gtk_tree_selection_select_path(shell->tree->selection, path);
+    gtk_tree_view_set_cursor(GTK_TREE_VIEW(shell->tree->view), path, NULL,
+			     FALSE);
+    gtk_tree_path_free(path);
+}
+
+static void menu_item_set_icon_always_visible(Shell *shell,
+                                              gchar *parent_path,
+                                              gchar *item_id)
+{
+    GtkWidget *menuitem;
+    gchar *path;
+
+    path = g_strdup_printf("%s/%s", parent_path, item_id);
+    menuitem = gtk_ui_manager_get_widget(shell->ui_manager, path);
+#if GTK_CHECK_VERSION(3, 0, 0)
+#else
+    gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(menuitem), TRUE);
+#endif
+    g_free(path);
+}
+
+static void add_module_to_menu(gchar * name, GdkPixbuf * pixbuf)
+{
+    GtkAction *action;
+    GtkWidget *menuitem;
+    gchar *about_module = g_strdup_printf("AboutModule%s", name);
+    gchar *path;
+    gint merge_id;
+
+    GtkActionEntry entries[] = {
+	{
+	 name,			/* name */
+	 name,			/* stockid */
+	 name,			/* label */
+	 NULL,			/* accelerator */
+	 NULL,			/* tooltip */
+	 NULL,			/* callback */
+	 },
+	{
+	 about_module,
+	 name,
+	 name,
+	 NULL,
+	 name,
+	 (GCallback) cb_about_module,
+	 },
+    };
+
+    stock_icon_register_pixbuf(pixbuf, name);
+
+    if ((action = gtk_action_group_get_action(shell->action_group, name))) {
+        gtk_action_group_remove_action(shell->action_group, action);
+    }
+
+    if ((action = gtk_action_group_get_action(shell->action_group, about_module))) {
+        gtk_action_group_remove_action(shell->action_group, action);
+    }
+
+    gtk_action_group_add_actions(shell->action_group, entries, 2, NULL);
+
+    merge_id = gtk_ui_manager_new_merge_id(shell->ui_manager);
+    gtk_ui_manager_add_ui(shell->ui_manager,
+                          merge_id,
+			  "/menubar/ViewMenu/LastSep",
+			  name, name, GTK_UI_MANAGER_MENU, TRUE);
+    shell->merge_ids = g_slist_prepend(shell->merge_ids, GINT_TO_POINTER(merge_id));
+
+    merge_id = gtk_ui_manager_new_merge_id(shell->ui_manager);
+    gtk_ui_manager_add_ui(shell->ui_manager,
+                          merge_id,
+			  "/menubar/HelpMenu/HelpMenuModules/LastSep",
+			  about_module, about_module, GTK_UI_MANAGER_AUTO,
+			  TRUE);
+    shell->merge_ids = g_slist_prepend(shell->merge_ids, GINT_TO_POINTER(merge_id));
+
+    menu_item_set_icon_always_visible(shell, "/menubar/ViewMenu", name);
+}
+
+static void
+add_module_entry_to_view_menu(gchar * module, gchar * name,
+			      GdkPixbuf * pixbuf, GtkTreeIter * iter)
+{
+    GtkAction *action;
+    GtkWidget *menuitem;
+    gint merge_id;
+    gchar *path;
+    GtkActionEntry entry = {
+       name,			/* name */
+       name,			/* stockid */
+       name,			/* label */
+       NULL,			/* accelerator */
+       NULL,			/* tooltip */
+       (GCallback) view_menu_select_entry,	/* callback */
+    };
+
+    stock_icon_register_pixbuf(pixbuf, name);
+
+    if ((action = gtk_action_group_get_action(shell->action_group, name))) {
+        gtk_action_group_remove_action(shell->action_group, action);
+    }
+
+    gtk_action_group_add_actions(shell->action_group, &entry, 1, iter);
+
+    merge_id = gtk_ui_manager_new_merge_id(shell->ui_manager);
+    path = g_strdup_printf("/menubar/ViewMenu/%s", module);
+    gtk_ui_manager_add_ui(shell->ui_manager,
+                          merge_id,
+                          path,
+			  name, name, GTK_UI_MANAGER_AUTO, FALSE);
+    shell->merge_ids = g_slist_prepend(shell->merge_ids, GINT_TO_POINTER(merge_id));
+
+    menu_item_set_icon_always_visible(shell, path, name);
+
+    g_free(path);
+}
+
+void shell_add_modules_to_gui(gpointer _shell_module, gpointer _shell_tree)
+{
+    ShellModule *module = (ShellModule *) _shell_module;
+    ShellTree *shelltree = (ShellTree *) _shell_tree;
+    GtkTreeStore *store = GTK_TREE_STORE(shelltree->model);
+    GtkTreeIter parent;
+
+    if (!module) {
+        return;
+    }
+
+    gtk_tree_store_append(store, &parent, NULL);
+    gtk_tree_store_set(store, &parent,
+                       TREE_COL_NAME, module->name,
+		       TREE_COL_MODULE, module,
+		       TREE_COL_MODULE_ENTRY, NULL,
+		       TREE_COL_SEL, FALSE,
+		       -1);
+
+    if (module->icon) {
+	gtk_tree_store_set(store, &parent, TREE_COL_PBUF, module->icon,
+			   -1);
+    }
+
+    add_module_to_menu(module->name, module->icon);
+
+    if (module->entries) {
+	ShellModuleEntry *entry;
+	GSList *p;
+
+	for (p = module->entries; p; p = g_slist_next(p)) {
+	    GtkTreeIter child;
+	    entry = (ShellModuleEntry *) p->data;
+
+	    gtk_tree_store_append(store, &child, &parent);
+	    gtk_tree_store_set(store, &child, TREE_COL_NAME, entry->name,
+			       TREE_COL_MODULE_ENTRY, entry,
+			       TREE_COL_SEL, FALSE, -1);
+
+	    if (entry->icon) {
+		gtk_tree_store_set(store, &child, TREE_COL_PBUF,
+				   entry->icon, -1);
+	    }
+
+	    add_module_entry_to_view_menu(module->name, entry->name,
+					  entry->icon,
+					  gtk_tree_iter_copy(&child));
+
+	    shell_status_pulse();
+	}
+
+    }
+}
+
+static void __tree_iter_destroy(gpointer data)
+{
+    gtk_tree_iter_free((GtkTreeIter *) data);
+}
+
+ShellSummary *summary_new(void)
+{
+    ShellSummary *summary;
+
+    summary = g_new0(ShellSummary, 1);
+    summary->scroll = gtk_scrolled_window_new(NULL, NULL);
+#if GTK_CHECK_VERSION(3, 0, 0)
+    summary->view = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
+#else
+    summary->view = gtk_vbox_new(FALSE, 5);
+#endif
+    summary->items = NULL;
+
+    gtk_container_set_border_width(GTK_CONTAINER(summary->view), 6);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(summary->scroll),
+                                   GTK_POLICY_AUTOMATIC,
+                                   GTK_POLICY_AUTOMATIC);
+#if GTK_CHECK_VERSION(3, 0, 0)
+    gtk_container_add(GTK_CONTAINER(summary->scroll),
+                                          summary->view);
+#else
+    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(summary->scroll),
+                                          summary->view);
+#endif
+    gtk_widget_show_all(summary->scroll);
+
+    return summary;
+}
+
+static gboolean
+select_first_tree_item(gpointer data)
+{
+    GtkTreeIter first;
+
+    if (gtk_tree_model_get_iter_first(shell->tree->model, &first))
+        gtk_tree_selection_select_iter(shell->tree->selection, &first);
+
+    return FALSE;
+}
+
+void shell_init(GSList * modules)
+{
+    if (shell) {
+	g_error("Shell already created");
+	return;
+    }
+
+    DEBUG("initializing shell");
+
+    create_window();
+
+    shell_action_set_property("ConnectToAction", "is-important", TRUE);
+    shell_action_set_property("CopyAction", "is-important", TRUE);
+    shell_action_set_property("RefreshAction", "is-important", TRUE);
+    shell_action_set_property("ReportAction", "is-important", TRUE);
+    shell_action_set_property("ReportBugAction", "is-important", TRUE);
+
+    shell->tree = tree_new();
+    shell->info = info_tree_new(FALSE);
+    shell->moreinfo = info_tree_new(TRUE);
+    shell->loadgraph = load_graph_new(75);
+    shell->summary = summary_new();
+
+    update_tbl = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                       g_free, __tree_iter_destroy);
+
+    gtk_paned_pack1(GTK_PANED(shell->hpaned), shell->tree->scroll,
+		    SHELL_PACK_RESIZE, SHELL_PACK_SHRINK);
+    gtk_paned_pack1(GTK_PANED(shell->vpaned), shell->info->scroll,
+		    SHELL_PACK_RESIZE, SHELL_PACK_SHRINK);
+
+    gtk_notebook_append_page(GTK_NOTEBOOK(shell->notebook),
+			     shell->moreinfo->scroll, NULL);
+    gtk_notebook_append_page(GTK_NOTEBOOK(shell->notebook),
+			     load_graph_get_framed(shell->loadgraph),
+			     NULL);
+    gtk_notebook_append_page(GTK_NOTEBOOK(shell->notebook),
+                             shell->summary->scroll, NULL);
+
+    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(shell->notebook), FALSE);
+    gtk_notebook_set_show_border(GTK_NOTEBOOK(shell->notebook), FALSE);
+
+    shell_status_set_enabled(TRUE);
+    shell_status_update(_("Loading modules..."));
+
+    shell->tree->modules = modules ? modules : modules_load_all();
+
+    g_slist_foreach(shell->tree->modules, shell_add_modules_to_gui, shell->tree);
+    gtk_tree_view_expand_all(GTK_TREE_VIEW(shell->tree->view));
+
+    gtk_widget_show_all(shell->hpaned);
+
+    load_graph_configure_expose(shell->loadgraph);
+    gtk_widget_hide(shell->notebook);
+    gtk_widget_hide(shell->note->event_box);
+
+    shell_status_update(_("Done."));
+    shell_status_set_enabled(FALSE);
+
+    shell_action_set_enabled("RefreshAction", FALSE);
+    shell_action_set_enabled("CopyAction", FALSE);
+    shell_action_set_active("SidePaneAction", TRUE);
+    shell_action_set_active("ToolbarAction", TRUE);
+
+#ifndef HAS_LIBSOUP
+    shell_action_set_enabled("SyncManagerAction", FALSE);
+#else
+    shell_action_set_enabled("SyncManagerAction", sync_manager_count_entries() > 0);
+#endif
+
+    /* Should select Computer Summary (note: not Computer/Summary) */
+    g_idle_add(select_first_tree_item, NULL);
+}
+
+static gboolean update_field(gpointer data)
+{
+    ShellFieldUpdate *fu;
+    GtkTreeIter *iter;
+
+    fu = (ShellFieldUpdate *) data;
+    g_return_val_if_fail(fu != NULL, FALSE);
+
+    DEBUG("update_field [%s]", fu->field_name);
+
+    iter = g_hash_table_lookup(update_tbl, fu->field_name);
+    if (!iter) {
+        return FALSE;
+    }
+
+    /* if the entry is still selected, update it */
+    if (iter && fu->entry->selected && fu->entry->fieldfunc) {
+	GtkTreeStore *store = GTK_TREE_STORE(shell->info->model);
+	gchar *value = fu->entry->fieldfunc(fu->field_name);
+
+	/*
+	 * this function is also used to feed the load graph when ViewType
+	 * is SHELL_VIEW_LOAD_GRAPH
+	 */
+	if (shell->view_type == SHELL_VIEW_LOAD_GRAPH &&
+	    gtk_tree_selection_iter_is_selected(shell->info->selection,
+						iter)) {
+	    load_graph_update(shell->loadgraph, atof(value));
+	}
+
+	gtk_tree_store_set(store, iter, INFO_TREE_COL_VALUE, value, -1);
+
+	g_free(value);
+	return TRUE;
+    }
+
+    if (update_sfusrc) {
+	GSList *sfu;
+
+	for (sfu = update_sfusrc; sfu; sfu = sfu->next) {
+	    g_free(sfu->data);
+	}
+
+	g_slist_free(update_sfusrc);
+	update_sfusrc = NULL;
+    }
+
+    /* otherwise, cleanup and destroy the timeout */
+    g_free(fu->field_name);
+    g_free(fu);
+
+    return FALSE;
+}
+
+#define RANGE_SET_VALUE(tree,scrollbar,value) \
+  	  do { \
+  	      GtkRange CONCAT(*range, __LINE__) = GTK_RANGE(GTK_SCROLLED_WINDOW(shell->tree->scroll)->scrollbar); \
+  	      gtk_range_set_value(CONCAT(range, __LINE__), value); \
+              gtk_adjustment_value_changed(GTK_ADJUSTMENT(gtk_range_get_adjustment(CONCAT(range, __LINE__)))); \
+          } while (0)
+#define RANGE_GET_VALUE(tree,scrollbar) \
+  	  gtk_range_get_value(GTK_RANGE \
+	  		    (GTK_SCROLLED_WINDOW(shell->tree->scroll)-> \
+			     scrollbar))
+
+static gboolean reload_section(gpointer data)
+{
+    ShellModuleEntry *entry = (ShellModuleEntry *) data;
+#if GTK_CHECK_VERSION(2, 14, 0)
+    GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(shell->window));
+#endif
+
+    /* if the entry is still selected, update it */
+    if (entry->selected) {
+	GtkTreePath *path = NULL;
+	GtkTreeIter iter;
+	double pos_info_scroll, pos_more_scroll;
+
+	/* save current position */
+#if GTK_CHECK_VERSION(3, 0, 0)
+    /* TODO:GTK3 */
+#else
+	pos_info_scroll = RANGE_GET_VALUE(info, vscrollbar);
+	pos_more_scroll = RANGE_GET_VALUE(moreinfo, vscrollbar);
+#endif
+
+	/* avoid drawing the window while we reload */
+#if GTK_CHECK_VERSION(2, 14, 0)
+    gdk_window_freeze_updates(gdk_window);
+#else
+	gdk_window_freeze_updates(shell->window->window);
+#endif
+
+	/* gets the current selected path */
+	if (gtk_tree_selection_get_selected
+	    (shell->info->selection, &shell->info->model, &iter)) {
+	    path = gtk_tree_model_get_path(shell->info->model, &iter);
+        }
+
+	/* update the information, clear the treeview and populate it again */
+	module_entry_reload(entry);
+	info_selected_show_extra(NULL);	/* clears the more info store */
+	module_selected_show_info(entry, TRUE);
+
+	/* if there was a selection, reselect it */
+	if (path) {
+	    gtk_tree_selection_select_path(shell->info->selection, path);
+            gtk_tree_view_set_cursor(GTK_TREE_VIEW(shell->info->view), path, NULL,
+                                     FALSE);
+	    gtk_tree_path_free(path);
+        } else {
+            /* restore position */
+#if GTK_CHECK_VERSION(3, 0, 0)
+    /* TODO:GTK3 */
+#else
+            RANGE_SET_VALUE(info, vscrollbar, pos_info_scroll);
+            RANGE_SET_VALUE(moreinfo, vscrollbar, pos_more_scroll);
+#endif
+        }
+
+	/* make the window drawable again */
+#if GTK_CHECK_VERSION(2, 14, 0)
+    gdk_window_thaw_updates(gdk_window);
+#else
+	gdk_window_thaw_updates(shell->window->window);
+#endif
+    }
+
+    /* destroy the timeout: it'll be set up again */
+    return FALSE;
+}
+
+static gboolean rescan_section(gpointer data)
+{
+    ShellModuleEntry *entry = (ShellModuleEntry *) data;
+
+    module_entry_reload(entry);
+
+    return entry->selected;
+}
+
+static gint
+compare_float(float a, float b)
+{
+    return (a > b) - (a < b);
+}
+
+static gint
+info_tree_compare_val_func(GtkTreeModel * model,
+			   GtkTreeIter * a,
+			   GtkTreeIter * b, gpointer userdata)
+{
+    gint ret = 0;
+    gchar *col1, *col2;
+
+    gtk_tree_model_get(model, a, INFO_TREE_COL_VALUE, &col1, -1);
+    gtk_tree_model_get(model, b, INFO_TREE_COL_VALUE, &col2, -1);
+
+    if (!col1 && !col2)
+        ret = 0;
+    else if (!col1)
+        ret = -1;
+    else if (!col2)
+        ret = 1;
+    else if (shell->_order_type == SHELL_ORDER_ASCENDING)
+        ret = compare_float(atof(col2), atof(col1));
+    else
+        ret = compare_float(atof(col1), atof(col2));
+
+    g_free(col1);
+    g_free(col2);
+
+    return ret;
+}
+
+static void set_view_type(ShellViewType viewtype, gboolean reload)
+{
+#if GTK_CHECK_VERSION(2, 18, 0)
+    GtkAllocation* alloc;
+#endif
+
+    if (viewtype < SHELL_VIEW_NORMAL || viewtype >= SHELL_VIEW_N_VIEWS)
+	viewtype = SHELL_VIEW_NORMAL;
+
+    shell->normalize_percentage = TRUE;
+    shell->view_type = viewtype;
+    shell->_order_type = SHELL_ORDER_DESCENDING;
+
+    /* use an unsorted tree model */
+    GtkTreeSortable *sortable = GTK_TREE_SORTABLE(shell->info->model);
+
+    gtk_tree_sortable_set_sort_column_id(sortable,
+        GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
+        GTK_SORT_ASCENDING);
+    gtk_tree_view_set_model(GTK_TREE_VIEW(shell->info->view),
+        GTK_TREE_MODEL(sortable));
+
+    /* reset to the default view columns */
+    if (!reload) {
+      gtk_tree_view_column_set_visible(shell->info->col_extra1, FALSE);
+      gtk_tree_view_column_set_visible(shell->info->col_extra2, FALSE);
+      gtk_tree_view_column_set_visible(shell->info->col_progress, FALSE);
+      gtk_tree_view_column_set_visible(shell->info->col_value, TRUE);
+    }
+
+    /* turn off the rules hint */
+#if GTK_CHECK_VERSION(3, 0, 0)
+#else
+    gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(shell->info->view), FALSE);
+#endif
+
+    close_note(NULL, NULL);
+
+    switch (viewtype) {
+    default:
+    case SHELL_VIEW_NORMAL:
+        gtk_widget_show(shell->info->scroll);
+	gtk_widget_hide(shell->notebook);
+
+	if (!reload) {
+          gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(shell->info->view), FALSE);
+        }
+	break;
+    case SHELL_VIEW_DUAL:
+        gtk_widget_show(shell->info->scroll);
+        gtk_widget_show(shell->moreinfo->scroll);
+        gtk_notebook_set_current_page(GTK_NOTEBOOK(shell->notebook), 0);
+        gtk_widget_show(shell->notebook);
+
+#if GTK_CHECK_VERSION(2, 18, 0)
+        alloc = g_new(GtkAllocation, 1);
+        gtk_widget_get_allocation(shell->hpaned, alloc);
+        gtk_paned_set_position(GTK_PANED(shell->vpaned), alloc->height / 2);
+        g_free(alloc);
+#else
+    gtk_paned_set_position(GTK_PANED(shell->vpaned),
+                    shell->hpaned->allocation.height / 2);
+#endif
+        break;
+    case SHELL_VIEW_LOAD_GRAPH:
+        gtk_widget_show(shell->info->scroll);
+        gtk_notebook_set_current_page(GTK_NOTEBOOK(shell->notebook), 1);
+        gtk_widget_show(shell->notebook);
+        load_graph_clear(shell->loadgraph);
+
+#if GTK_CHECK_VERSION(2, 18, 0)
+        alloc = g_new(GtkAllocation, 1);
+        gtk_widget_get_allocation(shell->hpaned, alloc);
+        gtk_paned_set_position(GTK_PANED(shell->vpaned),
+                alloc->height - load_graph_get_height(shell->loadgraph) - 16);
+        g_free(alloc);
+#else
+    gtk_paned_set_position(GTK_PANED(shell->vpaned),
+			       shell->hpaned->allocation.height -
+			       load_graph_get_height(shell->loadgraph) - 16);
+#endif
+
+	break;
+    case SHELL_VIEW_PROGRESS_DUAL:
+	gtk_widget_show(shell->notebook);
+        gtk_widget_show(shell->moreinfo->scroll);
+
+	gtk_notebook_set_current_page(GTK_NOTEBOOK(shell->notebook), 0);
+	/* fallthrough */
+    case SHELL_VIEW_PROGRESS:
+        gtk_widget_show(shell->info->scroll);
+
+	if (!reload) {
+  	  gtk_tree_view_column_set_visible(shell->info->col_progress, TRUE);
+  	  gtk_tree_view_column_set_visible(shell->info->col_value, FALSE);
+        }
+
+	if (viewtype == SHELL_VIEW_PROGRESS)
+		gtk_widget_hide(shell->notebook);
+	break;
+    case SHELL_VIEW_SUMMARY:
+        gtk_notebook_set_current_page(GTK_NOTEBOOK(shell->notebook), 2);
+
+        gtk_widget_show(shell->notebook);
+        gtk_widget_hide(shell->info->scroll);
+        gtk_widget_hide(shell->moreinfo->scroll);
+    }
+}
+
+static void
+group_handle_special(GKeyFile * key_file, ShellModuleEntry * entry,
+		     gchar * group, gchar ** keys, gboolean reload)
+{
+    if (g_str_equal(group, "$ShellParam$")) {
+        gboolean headers_visible = FALSE;
+	gint i;
+
+	for (i = 0; keys[i]; i++) {
+	    gchar *key = keys[i];
+
+	    if (g_str_has_prefix(key, "UpdateInterval")) {
+		ShellFieldUpdate *fu = g_new0(ShellFieldUpdate, 1);
+		ShellFieldUpdateSource *sfutbl;
+		gint ms;
+
+		ms = g_key_file_get_integer(key_file, group, key, NULL);
+
+		fu->field_name = g_strdup(g_utf8_strchr(key, -1, '$') + 1);
+		fu->entry = entry;
+
+		sfutbl = g_new0(ShellFieldUpdateSource, 1);
+		sfutbl->source_id = g_timeout_add(ms, update_field, fu);
+		sfutbl->sfu = fu;
+
+		update_sfusrc = g_slist_prepend(update_sfusrc, sfutbl);
+	    } else if (g_str_equal(key, "NormalizePercentage")) {
+		shell->normalize_percentage = g_key_file_get_boolean(key_file, group, key, NULL);
+	    } else if (g_str_equal(key, "LoadGraphSuffix")) {
+		gchar *suffix =
+		    g_key_file_get_value(key_file, group, key, NULL);
+		load_graph_set_data_suffix(shell->loadgraph, suffix);
+		g_free(suffix);
+	    } else if (g_str_equal(key, "ReloadInterval")) {
+		gint ms;
+
+		ms = g_key_file_get_integer(key_file, group, key, NULL);
+
+		g_timeout_add(ms, reload_section, entry);
+	    } else if (g_str_equal(key, "RescanInterval")) {
+		gint ms;
+
+		ms = g_key_file_get_integer(key_file, group, key, NULL);
+
+		g_timeout_add(ms, rescan_section, entry);
+	    } else if (g_str_equal(key, "ShowColumnHeaders")) {
+		headers_visible = g_key_file_get_boolean(key_file, group, key, NULL);
+	    } else if (g_str_has_prefix(key, "ColumnTitle")) {
+                GtkTreeViewColumn *column = NULL;
+		gchar *value, *title = g_utf8_strchr(key, -1, '$') + 1;
+
+                value = g_key_file_get_value(key_file, group, key, NULL);
+
+                if (g_str_equal(title, "Extra1")) {
+			column = shell->info->col_extra1;
+                } else if (g_str_equal(title, "Extra2")) {
+			column = shell->info->col_extra2;
+                } else if (g_str_equal(title, "Value")) {
+			column = shell->info->col_value;
+                } else if (g_str_equal(title, "TextValue")) {
+			column = shell->info->col_textvalue;
+                } else if (g_str_equal(title, "Progress")) {
+			column = shell->info->col_progress;
+                }
+
+                if (column) {
+                  gtk_tree_view_column_set_title(column, value);
+                  gtk_tree_view_column_set_visible(column, TRUE);
+                }
+
+                g_free(value);
+	    } else if (g_str_equal(key, "OrderType")) {
+		shell->_order_type = g_key_file_get_integer(key_file,
+							    group,
+							    key, NULL);
+	    } else if (g_str_equal(key, "ViewType")) {
+		set_view_type(g_key_file_get_integer(key_file, group,
+						     key, NULL), reload);
+	    } else if (g_str_has_prefix(key, "Icon")) {
+		GtkTreeIter *iter = g_hash_table_lookup(update_tbl,
+							g_utf8_strchr(key,
+							       -1, '$') + 1);
+
+		if (iter) {
+		    gchar *file =
+			g_key_file_get_value(key_file, group, key, NULL);
+		    gtk_tree_store_set(GTK_TREE_STORE(shell->info->model),
+				       iter, INFO_TREE_COL_PBUF,
+				       icon_cache_get_pixbuf_at_size(file,
+								     22,
+								     22),
+				       -1);
+		    g_free(file);
+		}
+	    } else if (g_str_equal(key, "Zebra")) {
+#if GTK_CHECK_VERSION(3, 0, 0)
+#else
+		gtk_tree_view_set_rules_hint(GTK_TREE_VIEW
+					     (shell->info->view),
+					     g_key_file_get_boolean
+					     (key_file, group, key, NULL));
+#endif
+	    }
+	}
+
+        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(shell->info->view), headers_visible);
+    } else {
+	g_warning("Unknown parameter group: ``%s''", group);
+    }
+}
+
+static void
+group_handle_normal(GKeyFile * key_file, ShellModuleEntry * entry,
+		    gchar * group, gchar ** keys, gsize ngroups)
+{
+    GtkTreeIter parent;
+    GtkTreeStore *store = GTK_TREE_STORE(shell->info->model);
+    gchar *tmp = g_strdup(group);
+    gint i;
+
+    if (ngroups > 1) {
+	gtk_tree_store_append(store, &parent, NULL);
+
+	strend(tmp, '#');
+	gtk_tree_store_set(store, &parent, INFO_TREE_COL_NAME, tmp, -1);
+	g_free(tmp);
+    }
+
+    for (i = 0; keys[i]; i++) {
+	gchar *key = keys[i];
+	gchar *value;
+	GtkTreeIter child;
+
+    value = g_key_file_get_value(key_file, group, key, NULL);
+    if (entry->fieldfunc && value && g_str_equal(value, "...")) {
+        g_free(value);
+        value = entry->fieldfunc(key);
+    }
+
+	if ((key && value) && g_utf8_validate(key, -1, NULL) && g_utf8_validate(value, -1, NULL)) {
+	    if (ngroups == 1) {
+		gtk_tree_store_append(store, &child, NULL);
+	    } else {
+		gtk_tree_store_append(store, &child, &parent);
+	    }
+
+	    /* FIXME: use g_key_file_get_string_list? */
+	    if (g_utf8_strchr(value, -1, '|')) {
+		gchar **columns = g_strsplit(value, "|", 0);
+
+		gtk_tree_store_set(store, &child, INFO_TREE_COL_VALUE, columns[0], -1);
+		if (columns[1]) {
+			gtk_tree_store_set(store, &child, INFO_TREE_COL_EXTRA1, columns[1], -1);
+			if (columns[2]) {
+				gtk_tree_store_set(store, &child, INFO_TREE_COL_EXTRA2, columns[2], -1);
+			}
+		}
+
+		g_strfreev(columns);
+	    } else {
+	    	gtk_tree_store_set(store, &child, INFO_TREE_COL_VALUE, value, -1);
+	    }
+
+	    strend(key, '#');
+
+	    if (*key == '$') {
+		gchar **tmp;
+
+		tmp = g_strsplit(++key, "$", 0);
+
+		gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME,
+				   tmp[1], INFO_TREE_COL_DATA, tmp[0], -1);
+
+		g_strfreev(tmp);
+	    } else {
+		gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, _(key),
+				   INFO_TREE_COL_DATA, NULL, -1);
+	    }
+
+	    g_hash_table_insert(update_tbl, g_strdup(key),
+				gtk_tree_iter_copy(&child));
+
+	}
+
+	g_free(value);
+    }
+}
+
+static void
+moreinfo_handle_normal(GKeyFile * key_file, gchar * group, gchar ** keys)
+{
+    GtkTreeIter parent;
+    GtkTreeStore *store = GTK_TREE_STORE(shell->moreinfo->model);
+    gint i;
+
+    gtk_tree_store_append(store, &parent, NULL);
+    gtk_tree_store_set(store, &parent, INFO_TREE_COL_NAME, group, -1);
+
+    for (i = 0; keys[i]; i++) {
+	gchar *key = keys[i];
+	GtkTreeIter child;
+	gchar *value;
+
+	value = g_key_file_get_value(key_file, group, key, NULL);
+
+	if (g_utf8_validate(key, -1, NULL)
+	    && g_utf8_validate(value, -1, NULL)) {
+	    strend(key, '#');
+
+	    gtk_tree_store_append(store, &child, &parent);
+	    gtk_tree_store_set(store, &child, INFO_TREE_COL_VALUE,
+			       value, INFO_TREE_COL_NAME, key, -1);
+	}
+
+	g_free(value);
+    }
+}
+
+static void update_progress()
+{
+    GtkTreeModel *model = shell->info->model;
+    GtkTreeStore *store = GTK_TREE_STORE(model);
+    GtkTreeIter iter, fiter;
+    gchar *tmp;
+    gdouble maxv = INT_MIN, minv = INT_MAX, coeff, cur;
+
+    if (!gtk_tree_model_get_iter_first(model, &fiter))
+	return;
+
+    /* finds the maximum value */
+    if (shell->normalize_percentage) {
+	iter = fiter;
+	do {
+	    gtk_tree_model_get(model, &iter, INFO_TREE_COL_VALUE, &tmp, -1);
+
+	    cur = atof(tmp);
+	    if (cur > maxv)
+		maxv = cur;
+	    if (cur < minv)
+		minv = cur;
+
+	    g_free(tmp);
+	} while (gtk_tree_model_iter_next(model, &iter));
+
+	if (minv - maxv < 0.001)
+	    maxv += 1.0f;
+    } else {
+	minv = 1.0f;
+	maxv = 100.0f;
+    }
+
+    coeff = (100.0f - 1.0f) / (maxv - minv);
+
+    /* fix the maximum relative percentage */
+    iter = fiter;
+    do {
+	char *space;
+	char formatted[128];
+	gdouble pct;
+
+	gtk_tree_model_get(model, &iter, INFO_TREE_COL_VALUE, &tmp, -1);
+	cur = atof(tmp);
+	space = g_utf8_strchr(tmp, -1, ' ');
+
+	pct = coeff * (cur - minv) + 1.0f;
+	if (shell->_order_type == SHELL_ORDER_ASCENDING)
+	    pct = 100.0 - pct;
+	pct = ceil(pct);
+
+	if (space) {
+	    snprintf(formatted, sizeof(formatted), "%.2f%s", cur, space);
+	} else {
+	    snprintf(formatted, sizeof(formatted), "%.2f", cur);
+	}
+
+	gtk_tree_store_set(store, &iter, INFO_TREE_COL_PROGRESS, pct,
+			   INFO_TREE_COL_VALUE, strreplacechr(formatted, ",",
+							      '.'), -1);
+
+	g_free(tmp);
+    } while (gtk_tree_model_iter_next(model, &iter));
+
+    /* now sort everything up. that wasn't as hard as i thought :) */
+    GtkTreeSortable *sortable = GTK_TREE_SORTABLE(shell->info->model);
+
+    gtk_tree_sortable_set_sort_func(sortable, INFO_TREE_COL_VALUE,
+				    info_tree_compare_val_func, 0, NULL);
+    gtk_tree_sortable_set_sort_column_id(sortable, INFO_TREE_COL_VALUE,
+					 GTK_SORT_DESCENDING);
+    gtk_tree_view_set_model(GTK_TREE_VIEW(shell->info->view),
+			    GTK_TREE_MODEL(sortable));
+}
+
+void shell_set_note_from_entry(ShellModuleEntry * entry)
+{
+    if (entry->notefunc) {
+	const gchar *note = module_entry_get_note(entry);
+
+	if (note) {
+	    gtk_label_set_markup(GTK_LABEL(shell->note->label), note);
+	    gtk_widget_show(shell->note->event_box);
+	} else {
+	    gtk_widget_hide(shell->note->event_box);
+	}
+    } else {
+	gtk_widget_hide(shell->note->event_box);
+    }
+}
+
+void shell_clear_field_updates(void)
+{
+    if (update_sfusrc) {
+        GSList *sfusrc;
+
+        for (sfusrc = update_sfusrc; sfusrc; sfusrc = sfusrc->next) {
+            ShellFieldUpdateSource *src =
+                (ShellFieldUpdateSource *) sfusrc->data;
+            g_source_remove(src->source_id);
+            g_free(src->sfu->field_name);
+            g_free(src->sfu);
+            g_free(src);
+        }
+
+        g_slist_free(update_sfusrc);
+        update_sfusrc = NULL;
+    }
+}
+
+static gboolean
+select_first_item(gpointer data)
+{
+    GtkTreeIter first;
+
+    if (gtk_tree_model_get_iter_first(shell->info->model, &first))
+        gtk_tree_selection_select_iter(shell->info->selection, &first);
+
+    return FALSE;
+}
+
+static gboolean
+select_marked_or_first_item(gpointer data)
+{
+    GtkTreeIter first, it;
+    gboolean found_selection = FALSE;
+    gchar *datacol;
+
+    if ( gtk_tree_model_get_iter_first(shell->info->model, &first) ) {
+        it = first;
+        while ( gtk_tree_model_iter_next(shell->info->model, &it) ) {
+            gtk_tree_model_get(shell->info->model, &it, INFO_TREE_COL_DATA, &datacol, -1);
+            if (datacol != NULL && *datacol == '*') {
+                gtk_tree_selection_select_iter(shell->info->selection, &it);
+                found_selection = TRUE;
+            }
+            g_free(datacol);
+        }
+
+        if (!found_selection)
+            gtk_tree_selection_select_iter(shell->info->selection, &first);
+    }
+    return FALSE;
+}
+
+static void
+module_selected_show_info(ShellModuleEntry * entry, gboolean reload)
+{
+    GKeyFile *key_file = g_key_file_new();
+    GtkTreeStore *store;
+    gchar *key_data, **groups;
+    gboolean has_shell_param = FALSE;
+    gint i;
+    gsize ngroups;
+#if GTK_CHECK_VERSION(2, 14, 0)
+    GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(shell->info->view));
+#endif
+
+    module_entry_scan(entry);
+    key_data = module_entry_function(entry);
+
+    /* */
+#if GTK_CHECK_VERSION(2, 14, 0)
+	gdk_window_freeze_updates(gdk_window);
+#else
+    gdk_window_freeze_updates(shell->info->view->window);
+#endif
+
+    g_object_ref(shell->info->model);
+    gtk_tree_view_set_model(GTK_TREE_VIEW(shell->info->view), NULL);
+
+    /* reset the view type to normal */
+    set_view_type(SHELL_VIEW_NORMAL, reload);
+
+    if (!reload) {
+        /* recreate the iter hash table */
+        h_hash_table_remove_all(update_tbl);
+    }
+
+    shell_clear_field_updates();
+
+    store = GTK_TREE_STORE(shell->info->model);
+
+    gtk_tree_store_clear(store);
+
+    g_key_file_load_from_data(key_file, key_data, strlen(key_data), 0,
+			      NULL);
+    groups = g_key_file_get_groups(key_file, &ngroups);
+
+    for (i = 0; groups[i]; i++)
+	if (groups[i][0] == '$')
+	    ngroups--;
+
+    for (i = 0; groups[i]; i++) {
+	gchar *group = groups[i];
+	gchar **keys = g_key_file_get_keys(key_file, group, NULL, NULL);
+
+	if (*group == '$') {
+	    group_handle_special(key_file, entry, group, keys, reload);
+	    has_shell_param = TRUE;
+	} else {
+	    group_handle_normal(key_file, entry, group, keys, ngroups);
+	}
+
+	g_strfreev(keys);
+    }
+
+    /* */
+    if (!has_shell_param) {
+        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(shell->info->view), FALSE);
+    }
+
+    /* */
+    g_object_unref(shell->info->model);
+    gtk_tree_view_set_model(GTK_TREE_VIEW(shell->info->view), shell->info->model);
+    gtk_tree_view_expand_all(GTK_TREE_VIEW(shell->info->view));
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+	gdk_window_thaw_updates(gdk_window);
+#else
+    gdk_window_thaw_updates(shell->info->view->window);
+#endif
+    shell_set_note_from_entry(entry);
+
+    if (shell->view_type == SHELL_VIEW_PROGRESS || shell->view_type == SHELL_VIEW_PROGRESS_DUAL) {
+	update_progress();
+    }
+
+#if GTK_CHECK_VERSION(2,12,0)
+    if (ngroups == 1) {
+        gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(shell->info->view),
+                                         FALSE);
+    } else {
+        gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(shell->info->view),
+                                         TRUE);
+    }
+#endif
+
+    g_strfreev(groups);
+    g_key_file_free(key_file);
+    g_free(key_data);
+
+    if (!reload) {
+        switch (shell->view_type) {
+        case SHELL_VIEW_DUAL:
+        case SHELL_VIEW_LOAD_GRAPH:
+        case SHELL_VIEW_PROGRESS_DUAL:
+            g_idle_add(select_marked_or_first_item, NULL);
+        }
+    }
+}
+
+static void info_selected_show_extra(gchar * data)
+{
+    GtkTreeStore *store;
+
+    store = GTK_TREE_STORE(shell->moreinfo->model);
+    gtk_tree_store_clear(store);
+
+    if (!shell->selected->morefunc)
+	return;
+
+    if (data) {
+        /* skip the select marker */
+        if (*data == '*')
+            data++;
+	GKeyFile *key_file = g_key_file_new();
+	gchar *key_data = shell->selected->morefunc(data);
+	gchar **groups;
+	gint i;
+
+	g_key_file_load_from_data(key_file, key_data, strlen(key_data), 0,
+				  NULL);
+	groups = g_key_file_get_groups(key_file, NULL);
+
+	for (i = 0; groups[i]; i++) {
+	    gchar *group = groups[i];
+	    gchar **keys =
+		g_key_file_get_keys(key_file, group, NULL, NULL);
+
+	    moreinfo_handle_normal(key_file, group, keys);
+	}
+
+	gtk_tree_view_expand_all(GTK_TREE_VIEW(shell->moreinfo->view));
+
+	g_strfreev(groups);
+	g_key_file_free(key_file);
+	g_free(key_data);
+    }
+}
+
+static gchar *shell_summary_clear_value(gchar *value)
+{
+     GKeyFile *keyfile;
+     gchar *return_value;
+
+     keyfile = g_key_file_new();
+     if (!value) return_value = g_strdup("");
+     else
+     if (g_key_file_load_from_data(keyfile, value,
+                                   strlen(value), 0, NULL)) {
+          gchar **groups;
+          gint group;
+
+          return_value = g_strdup("");
+
+          groups = g_key_file_get_groups(keyfile, NULL);
+          for (group = 0; groups[group]; group++) {
+               gchar **keys;
+               gint key;
+
+               keys = g_key_file_get_keys(keyfile, groups[group], NULL, NULL);
+               for (key = 0; keys[key]; key++) {
+                  gchar *temp = keys[key];
+
+                  if (*temp == '$') {
+                     temp++;
+                     while (*temp && *temp != '$')
+                        temp++;
+                     temp++;
+
+                     return_value = h_strdup_cprintf("%s\n", return_value, temp);
+                  } else {
+                     return_value = g_key_file_get_string(keyfile, groups[group],
+                                                          keys[key], NULL);
+                  }
+               }
+
+               g_strfreev(keys);
+          }
+
+          g_strfreev(groups);
+     } else {
+          return_value = g_strdup(value);
+     }
+
+     g_key_file_free(keyfile);
+
+     return g_strstrip(return_value);
+}
+
+static void shell_summary_add_item(ShellSummary *summary,
+                                   gchar *icon,
+                                   gchar *name,
+                                   gchar *value)
+{
+     GtkWidget *frame;
+     GtkWidget *frame_label_box;
+     GtkWidget *frame_image;
+     GtkWidget *frame_label;
+     GtkWidget *content;
+     GtkWidget *alignment;
+     gchar *temp;
+
+     temp = shell_summary_clear_value(value);
+
+     /* creates the frame */
+     frame = gtk_frame_new(NULL);
+     gtk_frame_set_shadow_type(GTK_FRAME(frame),
+                               GTK_SHADOW_NONE);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+     frame_label_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+#else
+     frame_label_box = gtk_hbox_new(FALSE, 5);
+#endif
+     frame_image = icon_cache_get_image(icon);
+     frame_label = gtk_label_new(name);
+     gtk_label_set_use_markup(GTK_LABEL(frame_label), TRUE);
+     gtk_box_pack_start(GTK_BOX(frame_label_box), frame_image, FALSE, FALSE, 0);
+     gtk_box_pack_start(GTK_BOX(frame_label_box), frame_label, FALSE, FALSE, 0);
+
+     content = gtk_label_new(temp);
+     /* TODO:GTK3 gtk_alignment_new(), etc is deprecated from 3.14 */
+#if GTK_CHECK_VERSION(3, 0, 0)
+     GtkWidget *frame_box;
+     frame_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+     gtk_widget_set_margin_start(GTK_WIDGET(frame_box), 48);
+     gtk_box_pack_start(GTK_BOX(frame_box), content, FALSE, FALSE, 0);
+     gtk_container_add(GTK_CONTAINER(frame), frame_box);
+#else
+     alignment = gtk_alignment_new(0.5, 0.5, 1, 1);
+     gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 48, 0);
+     gtk_widget_show(alignment);
+     gtk_container_add(GTK_CONTAINER(frame), alignment);
+     gtk_misc_set_alignment(GTK_MISC(content), 0.0, 0.5);
+     gtk_container_add(GTK_CONTAINER(alignment), content);
+#endif
+
+     gtk_widget_show_all(frame);
+     gtk_widget_show_all(frame_label_box);
+
+     gtk_frame_set_label_widget(GTK_FRAME(frame), frame_label_box);
+
+     /* pack the item on the summary screen */
+     gtk_box_pack_start(GTK_BOX(shell->summary->view), frame, FALSE, FALSE, 4);
+
+     /* add the item to the list of summary items */
+     summary->items = g_slist_prepend(summary->items, frame);
+
+     g_free(temp);
+}
+
+static void shell_summary_clear(ShellSummary *summary)
+{
+     GSList *item;
+
+     for (item = summary->items; item; item = item->next) {
+         gtk_widget_destroy(GTK_WIDGET(item->data));
+     }
+
+     g_slist_free(summary->items);
+     summary->items = NULL;
+
+     if (summary->header) gtk_widget_destroy(summary->header);
+     summary->header = NULL;
+}
+static void shell_summary_create_header(ShellSummary *summary,
+                                        gchar *title)
+{
+    GtkWidget *header, *label;
+    gchar *temp;
+
+    temp = g_strdup_printf(_("<b>%s \342\206\222 Summary</b>"), title);
+
+    header = gtk_menu_item_new_with_label(temp);
+    gtk_menu_item_select(GTK_MENU_ITEM(header));
+    gtk_widget_show(header);
+
+    label = gtk_bin_get_child(GTK_BIN(header));
+    gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
+
+    gtk_box_pack_start(GTK_BOX(shell->summary->view), header, FALSE, FALSE, 4);
+
+    summary->header = header;
+
+    g_free(temp);
+}
+
+static void shell_show_summary(void)
+{
+    GKeyFile *keyfile;
+    gchar *summary;
+
+    set_view_type(SHELL_VIEW_SUMMARY, FALSE);
+    shell_summary_clear(shell->summary);
+    shell_summary_create_header(shell->summary, shell->selected_module->name);
+
+    keyfile = g_key_file_new();
+    summary = shell->selected_module->summaryfunc();
+
+    if (g_key_file_load_from_data(keyfile, summary,
+                                  strlen(summary), 0, NULL)) {
+         gchar **groups;
+         gint group;
+
+         groups = g_key_file_get_groups(keyfile, NULL);
+
+         for (group = 0; groups[group]; group++) {
+             gchar *icon, *method, *method_result;
+
+             shell_status_pulse();
+
+             icon = g_key_file_get_string(keyfile, groups[group], "Icon", NULL);
+             method = g_key_file_get_string(keyfile, groups[group], "Method", NULL);
+             if (method) {
+                  method_result = module_call_method(method);
+             } else {
+                  method_result = g_strdup("N/A");
+             }
+
+             shell_summary_add_item(shell->summary,
+                                    icon, groups[group], method_result);
+             shell_status_pulse();
+
+             g_free(icon);
+             g_free(method);
+             g_free(method_result);
+         }
+
+         g_strfreev(groups);
+    } else {
+         DEBUG("error while parsing summary");
+         set_view_type(SHELL_VIEW_NORMAL, FALSE);
+    }
+
+    g_free(summary);
+    g_key_file_free(keyfile);
+
+    shell_view_set_enabled(TRUE);
+}
+
+static void module_selected(gpointer data)
+{
+    ShellTree *shelltree = shell->tree;
+    GtkTreeModel *model = GTK_TREE_MODEL(shelltree->model);
+    GtkTreeIter iter, parent;
+    ShellModuleEntry *entry;
+    static ShellModuleEntry *current = NULL;
+    static gboolean updating = FALSE;
+    GtkScrollbar		*hscrollbar, *vscrollbar;
+
+    /* Gets the currently selected item on the left-side TreeView; if there is no
+       selection, silently return */
+    if (!gtk_tree_selection_get_selected(shelltree->selection, &model, &iter)) {
+	return;
+    }
+
+    /* Mark the currently selected module as "unselected"; this is used to kill the
+       update timeout. */
+    if (current) {
+	current->selected = FALSE;
+    }
+
+    if (updating) {
+      return;
+    } else {
+      updating = TRUE;
+    }
+
+    if (!gtk_tree_model_iter_parent(model, &parent, &iter)) {
+        memcpy(&parent, &iter, sizeof(iter));
+    }
+
+    gtk_tree_model_get(model, &parent, TREE_COL_MODULE, &shell->selected_module, -1);
+
+    /* Get the current selection and shows its related info */
+    gtk_tree_model_get(model, &iter, TREE_COL_MODULE_ENTRY, &entry, -1);
+    if (entry && !entry->selected) {
+	gchar *title;
+
+	shell_status_set_enabled(TRUE);
+	shell_status_update(_("Updating..."));
+
+	entry->selected = TRUE;
+	shell->selected = entry;
+	module_selected_show_info(entry, FALSE);
+
+	info_selected_show_extra(NULL);	/* clears the more info store */
+	gtk_tree_view_columns_autosize(GTK_TREE_VIEW(shell->info->view));
+
+	/* urgh. why don't GTK do this when the model is cleared? */
+#if GTK_CHECK_VERSION(3, 0, 0)
+    /* TODO:GTK3 */
+#else
+        RANGE_SET_VALUE(info, vscrollbar, 0.0);
+        RANGE_SET_VALUE(info, hscrollbar, 0.0);
+        RANGE_SET_VALUE(moreinfo, vscrollbar, 0.0);
+        RANGE_SET_VALUE(moreinfo, hscrollbar, 0.0);
+#endif
+
+	title = g_strdup_printf("%s - %s", shell->selected_module->name, entry->name);
+	shell_set_title(shell, title);
+	g_free(title);
+
+	shell_action_set_enabled("RefreshAction", TRUE);
+	shell_action_set_enabled("CopyAction", TRUE);
+
+	shell_status_update(_("Done."));
+	shell_status_set_enabled(FALSE);
+    } else {
+	shell_set_title(shell, NULL);
+	shell_action_set_enabled("RefreshAction", FALSE);
+	shell_action_set_enabled("CopyAction", FALSE);
+
+	gtk_tree_store_clear(GTK_TREE_STORE(shell->info->model));
+	set_view_type(SHELL_VIEW_NORMAL, FALSE);
+
+        if (shell->selected_module->summaryfunc) {
+           shell_show_summary();
+        }
+    }
+
+    current = entry;
+    updating = FALSE;
+}
+
+static void info_selected(GtkTreeSelection * ts, gpointer data)
+{
+    ShellInfoTree *info = (ShellInfoTree *) data;
+    GtkTreeModel *model = GTK_TREE_MODEL(info->model);
+    GtkTreeIter parent;
+    gchar *datacol;
+
+    if (!gtk_tree_selection_get_selected(ts, &model, &parent))
+	return;
+
+    if (shell->view_type == SHELL_VIEW_NORMAL ||
+        shell->view_type == SHELL_VIEW_PROGRESS) {
+        gtk_tree_selection_unselect_all(ts);
+        return;
+    }
+
+    gtk_tree_model_get(model, &parent, INFO_TREE_COL_DATA, &datacol, -1);
+    info_selected_show_extra(datacol);
+    gtk_tree_view_columns_autosize(GTK_TREE_VIEW(shell->moreinfo->view));
+}
+
+static ShellInfoTree *info_tree_new(gboolean extra)
+{
+    ShellInfoTree *info;
+    GtkWidget *treeview, *scroll;
+    GtkTreeModel *model;
+    GtkTreeStore *store;
+    GtkTreeViewColumn *column;
+    GtkCellRenderer *cr_text, *cr_pbuf, *cr_progress;
+    GtkTreeSelection *sel;
+
+    info = g_new0(ShellInfoTree, 1);
+
+    scroll = gtk_scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
+					(scroll), GTK_SHADOW_IN);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
+				   GTK_POLICY_AUTOMATIC,
+				   GTK_POLICY_ALWAYS);
+
+    store =
+	gtk_tree_store_new(INFO_TREE_NCOL, G_TYPE_STRING, G_TYPE_STRING,
+			   G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_FLOAT,
+                           G_TYPE_STRING, G_TYPE_STRING);
+    model = GTK_TREE_MODEL(store);
+    treeview = gtk_tree_view_new_with_model(model);
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
+    gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(treeview), TRUE);
+
+    info->col_progress = column = gtk_tree_view_column_new();
+    gtk_tree_view_column_set_visible(column, FALSE);
+    gtk_tree_view_column_set_min_width(column, 240);
+    gtk_tree_view_column_set_clickable(column, TRUE);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+    cr_progress = gtk_cell_renderer_progress_new();
+    gtk_tree_view_column_pack_start(column, cr_progress, TRUE);
+    gtk_tree_view_column_add_attribute(column, cr_progress, "value",
+				       INFO_TREE_COL_PROGRESS);
+    gtk_tree_view_column_add_attribute(column, cr_progress, "text",
+				       INFO_TREE_COL_VALUE);
+    gtk_tree_view_column_set_visible(column, FALSE);
+
+    info->col_textvalue = column = gtk_tree_view_column_new();
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+    gtk_tree_view_column_set_clickable(column, TRUE);
+
+    cr_pbuf = gtk_cell_renderer_pixbuf_new();
+    gtk_tree_view_column_pack_start(column, cr_pbuf, FALSE);
+    gtk_tree_view_column_add_attribute(column, cr_pbuf, "pixbuf",
+				       INFO_TREE_COL_PBUF);
+
+    cr_text = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, cr_text, TRUE);
+    gtk_tree_view_column_add_attribute(column, cr_text, "markup",
+				       INFO_TREE_COL_NAME);
+
+    info->col_extra1 = column = gtk_tree_view_column_new();
+    gtk_tree_view_column_set_visible(column, FALSE);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+    gtk_tree_view_column_set_clickable(column, TRUE);
+
+    cr_text = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, cr_text, FALSE);
+    gtk_tree_view_column_add_attribute(column, cr_text, "markup",
+				       INFO_TREE_COL_EXTRA1);
+
+    info->col_extra2 = column = gtk_tree_view_column_new();
+    gtk_tree_view_column_set_visible(column, FALSE);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+    gtk_tree_view_column_set_clickable(column, TRUE);
+
+    cr_text = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, cr_text, FALSE);
+    gtk_tree_view_column_add_attribute(column, cr_text, "markup",
+				       INFO_TREE_COL_EXTRA2);
+
+    info->col_value = column = gtk_tree_view_column_new();
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+    gtk_tree_view_column_set_clickable(column, TRUE);
+
+    cr_text = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, cr_text, FALSE);
+    gtk_tree_view_column_add_attribute(column, cr_text, "markup",
+				       INFO_TREE_COL_VALUE);
+
+    sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+
+    if (!extra)
+	g_signal_connect(G_OBJECT(sel), "changed",
+			 (GCallback) info_selected, info);
+
+    gtk_container_add(GTK_CONTAINER(scroll), treeview);
+
+    info->scroll = scroll;
+    info->view = treeview;
+    info->model = model;
+    info->selection = sel;
+
+    gtk_widget_show_all(scroll);
+
+    return info;
+}
+
+static ShellTree *tree_new()
+{
+    ShellTree *shelltree;
+    GtkWidget *treeview, *scroll;
+    GtkTreeModel *model;
+    GtkTreeStore *store;
+    GtkCellRenderer *cr_text, *cr_pbuf;
+    GtkTreeViewColumn *column;
+    GtkTreeSelection *sel;
+
+    shelltree = g_new0(ShellTree, 1);
+
+    scroll = gtk_scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
+					(scroll), GTK_SHADOW_IN);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
+				   GTK_POLICY_NEVER,
+				   GTK_POLICY_AUTOMATIC);
+
+    store = gtk_tree_store_new(TREE_NCOL, GDK_TYPE_PIXBUF, G_TYPE_STRING,
+			       G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_BOOLEAN);
+    model = GTK_TREE_MODEL(store);
+    treeview = gtk_tree_view_new_with_model(model);
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
+
+#if GTK_CHECK_VERSION(2,12,0)
+    gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(treeview), FALSE);
+    gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(treeview), 24);
+#endif
+
+    column = gtk_tree_view_column_new();
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+    cr_pbuf = gtk_cell_renderer_pixbuf_new();
+    cr_text = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, cr_pbuf, FALSE);
+    gtk_tree_view_column_pack_start(column, cr_text, TRUE);
+
+    gtk_tree_view_column_add_attribute(column, cr_pbuf, "pixbuf",
+				       TREE_COL_PBUF);
+    gtk_tree_view_column_add_attribute(column, cr_text, "markup",
+				       TREE_COL_NAME);
+
+    sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+    g_signal_connect(G_OBJECT(sel), "changed", (GCallback) module_selected,
+		     NULL);
+
+    gtk_container_add(GTK_CONTAINER(scroll), treeview);
+
+    shelltree->scroll = scroll;
+    shelltree->view = treeview;
+    shelltree->model = model;
+    shelltree->modules = NULL;
+    shelltree->selection = sel;
+
+    gtk_widget_show_all(scroll);
+
+    return shelltree;
+}
diff --git a/shell/stock.c b/shell/stock.c
new file mode 100644
index 0000000..86d6677
--- /dev/null
+++ b/shell/stock.c
@@ -0,0 +1,103 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <stock.h>
+#include <iconcache.h>
+
+static struct {
+    gchar *filename;
+    gchar *stock_id;
+} stock_icons[] = {
+    { "report.png", HI_STOCK_REPORT},
+    { "internet.png", HI_STOCK_INTERNET},
+    { "module.png", HI_STOCK_MODULE},
+    { "about-modules.png", HI_STOCK_ABOUT_MODULES},
+    { "syncmanager-small.png", HI_STOCK_SYNC_MENU},
+    { "face-grin.png", HI_STOCK_DONATE},
+    { "server.png", HI_STOCK_SERVER},
+};
+
+static GtkIconFactory *icon_factory;
+
+void stock_icon_register(gchar * filename, gchar * stock_id)
+{
+#if GTK_CHECK_VERSION(3, 0, 0)
+#else
+    GtkIconSet *icon_set;
+    GtkIconSource *icon_source;
+
+    icon_set = gtk_icon_set_new();
+    icon_source = gtk_icon_source_new();
+
+    gtk_icon_source_set_pixbuf(icon_source,
+			       icon_cache_get_pixbuf(filename));
+    gtk_icon_set_add_source(icon_set, icon_source);
+    gtk_icon_source_free(icon_source);
+
+    gtk_icon_factory_add(icon_factory, stock_id, icon_set);
+
+    gtk_icon_set_unref(icon_set);
+#endif
+}
+
+void stock_icon_register_pixbuf(GdkPixbuf * pixbuf, gchar * stock_id)
+{
+#if GTK_CHECK_VERSION(3, 0, 0)
+#else
+    GtkIconSet *icon_set;
+    GtkIconSource *icon_source;
+
+    icon_set = gtk_icon_set_new();
+    icon_source = gtk_icon_source_new();
+
+    gtk_icon_source_set_pixbuf(icon_source, pixbuf);
+    gtk_icon_set_add_source(icon_set, icon_source);
+    gtk_icon_source_free(icon_source);
+
+    gtk_icon_factory_add(icon_factory, stock_id, icon_set);
+
+    gtk_icon_set_unref(icon_set);
+#endif
+}
+
+void stock_icons_init(void)
+{
+    gint i;
+    guint n_stock_icons = G_N_ELEMENTS(stock_icons);
+
+    DEBUG("initializing stock icons");
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+#else
+    icon_factory = gtk_icon_factory_new();
+#endif
+
+    for (i = 0; i < n_stock_icons; i++) {
+	stock_icon_register(stock_icons[i].filename,
+			    stock_icons[i].stock_id);
+    }
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+#else
+    gtk_icon_factory_add_default(icon_factory);
+#endif
+
+    g_object_unref(icon_factory);
+}
diff --git a/shell/syncmanager.c b/shell/syncmanager.c
new file mode 100644
index 0000000..db94d47
--- /dev/null
+++ b/shell/syncmanager.c
@@ -0,0 +1,793 @@
+/*
+ *    HardInfo - Displays System Information
+ *    Copyright (C) 2003-2009 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, version 2.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "syncmanager.h"
+#include "iconcache.h"
+#include "hardinfo.h"
+#include "config.h"
+
+#ifdef HAS_LIBSOUP
+#include <libsoup/soup.h>
+
+#include <stdarg.h>
+#include <string.h>
+
+typedef struct _SyncDialog SyncDialog;
+typedef struct _SyncNetArea SyncNetArea;
+typedef struct _SyncNetAction SyncNetAction;
+
+struct _SyncNetArea {
+    GtkWidget *vbox;
+};
+
+struct _SyncNetAction {
+    gchar *name;
+     gboolean(*do_action) (SyncDialog * sd, gpointer sna);
+
+    SyncEntry *entry;
+    GError *error;
+};
+
+struct _SyncDialog {
+    GtkWidget *dialog;
+    GtkWidget *label;
+
+    GtkWidget *button_sync;
+    GtkWidget *button_cancel;
+    GtkWidget *button_close;
+
+    GtkWidget *scroll_box;
+
+    SyncNetArea *sna;
+
+    gboolean flag_cancel:1;
+};
+
+static GSList *entries = NULL;
+static SoupSession *session = NULL;
+static GMainLoop *loop;
+static GQuark err_quark;
+
+#define XMLRPC_SERVER_URI   		"https://xmlrpc.hardinfo.org/"
+#define XMLRPC_SERVER_API_VERSION	1
+
+#define LABEL_SYNC_DEFAULT  _("<big><b>Synchronize with Central Database</b></big>\n" \
+                            "The following information may be synchronized " \
+                            "with the HardInfo central database.")
+#define LABEL_SYNC_SYNCING  _("<big><b>Synchronizing</b></big>\n" \
+                            "This may take some time.")
+
+static SyncDialog *sync_dialog_new(GtkWidget *parent);
+static void sync_dialog_destroy(SyncDialog * sd);
+static void sync_dialog_start_sync(SyncDialog * sd);
+
+static SyncNetArea *sync_dialog_netarea_new(void);
+static void sync_dialog_netarea_destroy(SyncNetArea * sna);
+static void sync_dialog_netarea_show(SyncDialog * sd);
+#if 0
+static void sync_dialog_netarea_hide(SyncDialog * sd);
+#endif
+static void sync_dialog_netarea_start_actions(SyncDialog * sd,
+					      SyncNetAction * sna, gint n);
+
+#define SNA_ERROR(code,message,...) if (!sna->error) {                                         \
+                                            sna->error = g_error_new(err_quark, code, message, \
+                                                         ##__VA_ARGS__);                       \
+                                    }
+#endif				/* HAS_LIBSOUP */
+
+
+gint sync_manager_count_entries(void)
+{
+#ifdef HAS_LIBSOUP
+    return g_slist_length(entries);
+#else
+    return 0;
+#endif
+}
+
+void sync_manager_add_entry(SyncEntry * entry)
+{
+#ifdef HAS_LIBSOUP
+    DEBUG("registering syncmanager entry ''%s''", entry->fancy_name);
+
+    entry->selected = TRUE;
+    entries = g_slist_append(entries, entry);
+#else
+    DEBUG("libsoup support is disabled.");
+#endif				/* HAS_LIBSOUP */
+}
+
+void sync_manager_clear_entries(void)
+{
+#ifdef HAS_LIBSOUP
+    DEBUG("clearing syncmanager entries");
+
+    g_slist_free(entries);
+    entries = NULL;
+#else
+    DEBUG("libsoup support is disabled.");
+#endif				/* HAS_LIBSOUP */
+}
+
+void sync_manager_show(GtkWidget *parent)
+{
+#ifndef HAS_LIBSOUP
+    g_warning
+	(_("HardInfo was compiled without libsoup support. (Network Updater requires it.)"));
+#else				/* !HAS_LIBSOUP */
+    SyncDialog *sd = sync_dialog_new(parent);
+
+    err_quark = g_quark_from_static_string("syncmanager");
+
+    if (gtk_dialog_run(GTK_DIALOG(sd->dialog)) == GTK_RESPONSE_ACCEPT) {
+	shell_view_set_enabled(FALSE);
+	shell_status_set_enabled(TRUE);
+
+	sync_dialog_start_sync(sd);
+
+	shell_status_set_enabled(FALSE);
+	shell_view_set_enabled(TRUE);
+    }
+
+    sync_dialog_destroy(sd);
+#endif				/* HAS_LIBSOUP */
+}
+
+#ifdef HAS_LIBSOUP
+static gint _soup_get_xmlrpc_value_int(SoupMessage * msg,
+				       SyncNetAction * sna)
+{
+    gint int_value = -1;
+
+    sna->error = NULL;
+
+    if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) {
+	SNA_ERROR(1, _("%s (error #%d)"), msg->reason_phrase,
+		  msg->status_code);
+	goto bad;
+    }
+
+    GVariant *value = soup_xmlrpc_parse_response(msg->response_body->data,
+                                                 msg->response_body->length,
+                                                 "h", NULL);
+    if (!value) {
+	SNA_ERROR(2, _("Could not parse XML-RPC response"));
+	goto bad;
+    }
+
+    int_value = g_variant_get_int32(value);
+    g_variant_unref(value);
+
+bad:
+    return int_value;
+}
+
+static gchar *_soup_get_xmlrpc_value_string(SoupMessage * msg,
+					    SyncNetAction * sna)
+{
+    gchar *string = NULL;
+
+    sna->error = NULL;
+
+    if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) {
+	SNA_ERROR(1, _("%s (error #%d)"), msg->reason_phrase,
+		  msg->status_code);
+	goto bad;
+    }
+
+    GVariant *value = soup_xmlrpc_parse_response(msg->response_body->data,
+                                                 msg->response_body->length,
+                                                 "s", NULL);
+    if (!value) {
+	SNA_ERROR(2, _("Could not parse XML-RPC response"));
+	goto bad;
+    }
+
+    string = g_strdup(g_variant_get_string(value, NULL));
+    g_variant_unref(value);
+
+bad:
+    return string;
+}
+
+static gboolean _soup_xmlrpc_call(gchar * method, SyncNetAction * sna,
+				  SoupSessionCallback callback)
+{
+    SoupMessage *msg;
+
+    sna->error = NULL;
+
+    msg = soup_xmlrpc_message_new(XMLRPC_SERVER_URI, method, NULL, NULL);
+    if (!msg)
+	return FALSE;
+
+    DEBUG("calling xmlrpc method %s", method);
+
+    soup_session_queue_message(session, msg, callback, sna);
+    g_main_run(loop);
+
+    return TRUE;
+}
+
+static gboolean _soup_xmlrpc_call_with_parameters(gchar * method,
+						  SyncNetAction * sna,
+						  SoupSessionCallback
+						  callback, ...)
+{
+    SoupMessage *msg;
+    GVariantBuilder builder;
+    GVariant *parameters;
+    gchar *argument, *body;
+    va_list ap;
+
+    sna->error = NULL;
+
+    msg = soup_message_new("POST", XMLRPC_SERVER_URI);
+
+    DEBUG("calling xmlrpc method %s", method);
+    if (!msg)
+	return FALSE;
+
+    g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+    va_start(ap, callback);
+    while ((argument = va_arg(ap, gchar *))) {
+        g_variant_builder_add(&builder, "s", argument);
+	DEBUG("with parameter: %s", argument);
+    }
+    va_end(ap);
+    parameters = g_variant_builder_end(&builder);
+    g_variant_builder_unref(&builder);
+
+    body = soup_xmlrpc_build_request(method, parameters, NULL);
+    g_variant_unref(parameters);
+    if (body) {
+        soup_message_set_request(msg, "text/xml",
+                                 SOUP_MEMORY_TAKE, body, strlen(body));
+
+        soup_session_queue_message(session, msg, callback, sna);
+        g_main_run(loop);
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static void _action_check_api_version_got_response(SoupSession * session,
+						   SoupMessage * msg,
+						   gpointer user_data)
+{
+    SyncNetAction *sna = (SyncNetAction *) user_data;
+    gint version = _soup_get_xmlrpc_value_int(msg, sna);
+
+    if (version != XMLRPC_SERVER_API_VERSION) {
+	SNA_ERROR(5, _("Server says it supports API version %d, but "
+		  "this version of HardInfo only supports API "
+		  "version %d."), version, XMLRPC_SERVER_API_VERSION);
+    }
+
+    g_main_quit(loop);
+}
+
+static gboolean _action_check_api_version(SyncDialog * sd,
+					  gpointer user_data)
+{
+    SyncNetAction *sna = (SyncNetAction *) user_data;
+
+    if (!_soup_xmlrpc_call("server.getAPIVersion", sna,
+			   _action_check_api_version_got_response))
+	return FALSE;
+
+    return sna->error ? FALSE : TRUE;
+}
+
+static void _action_call_function_got_response(SoupSession * session,
+					       SoupMessage * msg,
+					       gpointer user_data)
+{
+    SyncNetAction *sna = (SyncNetAction *) user_data;
+    gchar *string;
+
+    if ((string = _soup_get_xmlrpc_value_string(msg, sna)) &&
+	sna->entry->save_to) {
+	DEBUG("received string: %s\n", string);
+	gchar *filename = g_build_filename(g_get_home_dir(), ".hardinfo",
+					   sna->entry->save_to, NULL);
+
+	DEBUG("saving to %s", filename);
+
+	g_file_set_contents(filename, string, -1, NULL);
+	g_free(filename);
+    }
+
+    if (sna->entry->callback) {
+	sna->entry->callback(sna->entry, string);
+    }
+
+    g_free(string);
+    g_main_quit(loop);
+}
+
+static gboolean _action_call_function(SyncDialog * sd, gpointer user_data)
+{
+    SyncNetAction *sna = (SyncNetAction *) user_data;
+
+    if (sna->entry) {
+	gchar *str_data = NULL;
+
+	if (sna->entry->get_data)
+	    str_data = sna->entry->get_data();
+
+	if (!_soup_xmlrpc_call_with_parameters("sync.callFunctionEx", sna,
+					       _action_call_function_got_response,
+					       VERSION, ARCH,
+					       sna->entry->name,
+					       str_data, NULL)) {
+	    g_free(str_data);
+
+	    return FALSE;
+	}
+
+	g_free(str_data);
+    }
+
+    return sna->error ? FALSE : TRUE;
+}
+
+static gboolean _cancel_sync(GtkWidget * widget, gpointer data)
+{
+    SyncDialog *sd = (SyncDialog *) data;
+
+    if (session) {
+	soup_session_abort(session);
+    }
+
+    sd->flag_cancel = TRUE;
+    g_main_quit(loop);
+
+    gtk_widget_set_sensitive(widget, FALSE);
+
+    return FALSE;
+}
+
+static SyncNetAction *sync_manager_get_selected_actions(gint * n)
+{
+    gint i;
+    GSList *entry;
+    SyncNetAction *actions;
+    SyncNetAction
+      action_check_api = { _("Contacting HardInfo Central Database"), _action_check_api_version },
+      action_clean_up = { _("Cleaning up"), NULL};
+
+    actions = g_new0(SyncNetAction, 2 + g_slist_length(entries));
+
+    for (entry = entries, i = 1; entry; entry = entry->next) {
+	SyncEntry *e = (SyncEntry *) entry->data;
+
+	if (e->selected) {
+	    SyncNetAction sna =
+		{ e->fancy_name, _action_call_function, e };
+
+	    actions[i++] = sna;
+	}
+    }
+
+    actions[0] = action_check_api;
+    actions[i++] = action_clean_up;
+
+    *n = i;
+    return actions;
+}
+
+static SoupURI *sync_manager_get_proxy(void)
+{
+    const gchar *conf;
+
+    if (!(conf = g_getenv("HTTP_PROXY"))) {
+	if (!(conf = g_getenv("http_proxy"))) {
+	    return NULL;
+	}
+    }
+
+    return soup_uri_new(conf);
+}
+
+static void sync_dialog_start_sync(SyncDialog * sd)
+{
+    gint nactions;
+    SyncNetAction *actions;
+
+    if (!session) {
+	SoupURI *proxy = sync_manager_get_proxy();
+
+	session = soup_session_new_with_options(SOUP_SESSION_TIMEOUT, 10,
+						SOUP_SESSION_PROXY_URI,
+						proxy, NULL);
+	/* Crashes if we unref the proxy? O_o */
+	/*if (proxy)
+	   g_object_unref(proxy); */
+    }
+
+    loop = g_main_loop_new(NULL, TRUE);
+
+    gtk_widget_hide(sd->button_sync);
+    sync_dialog_netarea_show(sd);
+    g_signal_connect(G_OBJECT(sd->button_cancel), "clicked",
+		     (GCallback) _cancel_sync, sd);
+
+    actions = sync_manager_get_selected_actions(&nactions);
+    sync_dialog_netarea_start_actions(sd, actions, nactions);
+    g_free(actions);
+
+    if (sd->flag_cancel) {
+	gtk_widget_hide(sd->button_cancel);
+	gtk_widget_show(sd->button_close);
+
+	/* wait for the user to close the dialog */
+	g_main_run(loop);
+    }
+
+    g_main_loop_unref(loop);
+}
+
+static void sync_dialog_netarea_start_actions(SyncDialog * sd,
+					      SyncNetAction sna[], gint n)
+{
+    gint i;
+    GtkWidget **labels;
+    GtkWidget **status_labels;
+    const gchar *done_str  = "\342\234\223";
+    const gchar *error_str = "\342\234\227";
+    const gchar *curr_str  = "\342\226\266";
+    const gchar *empty_str = "\302\240\302\240";
+
+    labels = g_new0(GtkWidget *, n);
+    status_labels = g_new0(GtkWidget *, n);
+
+    for (i = 0; i < n; i++) {
+	GtkWidget *hbox;
+
+	hbox = gtk_hbox_new(FALSE, 5);
+
+	labels[i] = gtk_label_new(sna[i].name);
+	status_labels[i] = gtk_label_new(empty_str);
+
+	gtk_label_set_use_markup(GTK_LABEL(labels[i]), TRUE);
+	gtk_label_set_use_markup(GTK_LABEL(status_labels[i]), TRUE);
+
+	gtk_misc_set_alignment(GTK_MISC(labels[i]), 0.0, 0.5);
+	gtk_misc_set_alignment(GTK_MISC(status_labels[i]), 1.0, 0.5);
+
+	gtk_box_pack_start(GTK_BOX(hbox), status_labels[i], FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), labels[i], TRUE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(sd->sna->vbox), hbox, FALSE, FALSE, 3);
+
+	gtk_widget_show_all(hbox);
+    }
+
+    while (gtk_events_pending())
+	gtk_main_iteration();
+
+    for (i = 0; i < n; i++) {
+	gchar *markup;
+
+	if (sd->flag_cancel) {
+	    markup =
+		g_strdup_printf("<s>%s</s> <i>%s</i>",
+				sna[i].name, _("(canceled)"));
+	    gtk_label_set_markup(GTK_LABEL(labels[i]), markup);
+	    g_free(markup);
+
+	    gtk_label_set_markup(GTK_LABEL(status_labels[i]), error_str);
+	    break;
+	}
+
+	markup = g_strdup_printf("<b>%s</b>", sna[i].name);
+	gtk_label_set_markup(GTK_LABEL(labels[i]), markup);
+	g_free(markup);
+
+        gtk_label_set_markup(GTK_LABEL(status_labels[i]), curr_str);
+
+	if (sna[i].do_action && !sna[i].do_action(sd, &sna[i])) {
+	    markup =
+		g_strdup_printf("<b><s>%s</s></b> <i>%s</i>",
+				sna[i].name, _("(failed)"));
+	    gtk_label_set_markup(GTK_LABEL(labels[i]), markup);
+	    g_free(markup);
+
+	    sd->flag_cancel = TRUE;
+
+	    gtk_label_set_markup(GTK_LABEL(status_labels[i]), error_str);
+	    if (sna[i].error) {
+		if (sna[i].error->code != 1) {
+		    /* the user has not cancelled something... */
+		    g_warning
+			(_("Failed while performing \"%s\". Please file a bug report "
+			 "if this problem persists. (Use the Help\342\206\222Report"
+			 " bug option.)\n\nDetails: %s"), sna[i].name,
+			 sna[i].error->message);
+		}
+
+		g_error_free(sna[i].error);
+	    } else {
+		g_warning
+		    (_("Failed while performing \"%s\". Please file a bug report "
+		     "if this problem persists. (Use the Help\342\206\222Report"
+		     " bug option.)"), sna[i].name);
+	    }
+	    break;
+	}
+
+        gtk_label_set_markup(GTK_LABEL(status_labels[i]), done_str);
+	gtk_label_set_markup(GTK_LABEL(labels[i]), sna[i].name);
+    }
+
+    g_free(labels);
+    g_free(status_labels);
+}
+
+static SyncNetArea *sync_dialog_netarea_new(void)
+{
+    SyncNetArea *sna = g_new0(SyncNetArea, 1);
+
+    sna->vbox = gtk_vbox_new(FALSE, 0);
+
+    gtk_container_set_border_width(GTK_CONTAINER(sna->vbox), 10);
+
+    gtk_widget_show_all(sna->vbox);
+    gtk_widget_hide(sna->vbox);
+
+    return sna;
+}
+
+static void sync_dialog_netarea_destroy(SyncNetArea * sna)
+{
+    g_return_if_fail(sna != NULL);
+
+    g_free(sna);
+}
+
+static void sync_dialog_netarea_show(SyncDialog * sd)
+{
+    g_return_if_fail(sd && sd->sna);
+
+    gtk_widget_hide(GTK_WIDGET(sd->scroll_box));
+    gtk_widget_show(GTK_WIDGET(sd->sna->vbox));
+
+    gtk_label_set_markup(GTK_LABEL(sd->label), LABEL_SYNC_SYNCING);
+    gtk_window_set_default_size(GTK_WINDOW(sd->dialog), 0, 0);
+    gtk_window_reshow_with_initial_size(GTK_WINDOW(sd->dialog));
+}
+
+#if 0
+static void sync_dialog_netarea_hide(SyncDialog * sd)
+{
+    g_return_if_fail(sd && sd->sna);
+
+    gtk_widget_show(GTK_WIDGET(sd->scroll_box));
+    gtk_widget_hide(GTK_WIDGET(sd->sna->vbox));
+
+    gtk_label_set_markup(GTK_LABEL(sd->label), LABEL_SYNC_DEFAULT);
+    gtk_window_reshow_with_initial_size(GTK_WINDOW(sd->dialog));
+}
+#endif
+
+static void populate_store(GtkListStore * store)
+{
+    GSList *entry;
+    SyncEntry *e;
+
+    gtk_list_store_clear(store);
+
+    for (entry = entries; entry; entry = entry->next) {
+	GtkTreeIter iter;
+
+	e = (SyncEntry *) entry->data;
+
+	e->selected = TRUE;
+
+	gtk_list_store_append(store, &iter);
+	gtk_list_store_set(store, &iter, 0, TRUE, 1, e->fancy_name, 2, e,
+			   -1);
+    }
+}
+
+static void
+sel_toggle(GtkCellRendererToggle * cellrenderertoggle,
+	   gchar * path_str, GtkTreeModel * model)
+{
+    GtkTreeIter iter;
+    GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
+    SyncEntry *se;
+    gboolean active;
+
+    gtk_tree_model_get_iter(model, &iter, path);
+    gtk_tree_model_get(model, &iter, 0, &active, 2, &se, -1);
+
+    se->selected = !active;
+
+    gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, se->selected, -1);
+    gtk_tree_path_free(path);
+}
+
+static void close_clicked(void)
+{
+    g_main_quit(loop);
+}
+
+static SyncDialog *sync_dialog_new(GtkWidget *parent)
+{
+    SyncDialog *sd;
+    GtkWidget *dialog;
+    GtkWidget *dialog1_vbox;
+    GtkWidget *scrolledwindow2;
+    GtkWidget *treeview2;
+    GtkWidget *dialog1_action_area;
+    GtkWidget *button8;
+    GtkWidget *button7;
+    GtkWidget *button6;
+    GtkWidget *label;
+    GtkWidget *hbox;
+
+    GtkTreeViewColumn *column;
+    GtkTreeModel *model;
+    GtkListStore *store;
+    GtkCellRenderer *cr_text, *cr_toggle;
+
+    sd = g_new0(SyncDialog, 1);
+    sd->sna = sync_dialog_netarea_new();
+
+    dialog = gtk_dialog_new();
+    gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent));
+    gtk_window_set_title(GTK_WINDOW(dialog), _("Network Updater"));
+    gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+    gtk_window_set_icon(GTK_WINDOW(dialog),
+			icon_cache_get_pixbuf("syncmanager.png"));
+    gtk_window_set_default_size(GTK_WINDOW(dialog), 420, 260);
+    gtk_window_set_position(GTK_WINDOW(dialog),
+			    GTK_WIN_POS_CENTER_ON_PARENT);
+    gtk_window_set_type_hint(GTK_WINDOW(dialog),
+			     GDK_WINDOW_TYPE_HINT_DIALOG);
+
+    gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+    dialog1_vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+#else
+    dialog1_vbox = GTK_DIALOG(dialog)->vbox;
+#endif
+    gtk_box_set_spacing(GTK_BOX(dialog1_vbox), 5);
+    gtk_container_set_border_width(GTK_CONTAINER(dialog1_vbox), 4);
+    gtk_widget_show(dialog1_vbox);
+#if GTK_CHECK_VERSION(3, 0, 0)
+    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+#else
+    hbox = gtk_hbox_new(FALSE, 5);
+#endif
+    gtk_box_pack_start(GTK_BOX(dialog1_vbox), hbox, FALSE, FALSE, 0);
+
+    label = gtk_label_new(LABEL_SYNC_DEFAULT);
+    gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+    gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
+#if GTK_CHECK_VERSION(3, 0, 0)
+    gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
+#else
+    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+#endif
+
+    gtk_box_pack_start(GTK_BOX(hbox),
+		       icon_cache_get_image("syncmanager.png"),
+		       FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
+    gtk_widget_show_all(hbox);
+
+
+    gtk_box_pack_start(GTK_BOX(dialog1_vbox), sd->sna->vbox, TRUE, TRUE,
+		       0);
+
+    scrolledwindow2 = gtk_scrolled_window_new(NULL, NULL);
+    gtk_widget_show(scrolledwindow2);
+    gtk_box_pack_start(GTK_BOX(dialog1_vbox), scrolledwindow2, TRUE, TRUE,
+		       0);
+    gtk_widget_set_size_request(scrolledwindow2, -1, 200);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow2),
+				   GTK_POLICY_AUTOMATIC,
+				   GTK_POLICY_AUTOMATIC);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
+					(scrolledwindow2), GTK_SHADOW_IN);
+
+    store =
+	gtk_list_store_new(3, G_TYPE_BOOLEAN, G_TYPE_STRING,
+			   G_TYPE_POINTER);
+    model = GTK_TREE_MODEL(store);
+
+    treeview2 = gtk_tree_view_new_with_model(model);
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview2), FALSE);
+    gtk_widget_show(treeview2);
+    gtk_container_add(GTK_CONTAINER(scrolledwindow2), treeview2);
+
+    column = gtk_tree_view_column_new();
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview2), column);
+
+    cr_toggle = gtk_cell_renderer_toggle_new();
+    gtk_tree_view_column_pack_start(column, cr_toggle, FALSE);
+    g_signal_connect(cr_toggle, "toggled", G_CALLBACK(sel_toggle), model);
+    gtk_tree_view_column_add_attribute(column, cr_toggle, "active", 0);
+
+    cr_text = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, cr_text, TRUE);
+    gtk_tree_view_column_add_attribute(column, cr_text, "markup", 1);
+
+    populate_store(store);
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+    dialog1_action_area = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
+#else
+    dialog1_action_area = GTK_DIALOG(dialog)->action_area;
+#endif
+    gtk_widget_show(dialog1_action_area);
+    gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog1_action_area),
+			      GTK_BUTTONBOX_END);
+
+    button8 = gtk_button_new_with_mnemonic(_("_Cancel"));
+    gtk_widget_show(button8);
+    gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button8,
+				 GTK_RESPONSE_CANCEL);
+#if GTK_CHECK_VERSION(2, 18, 0)
+    gtk_widget_set_can_default(button8, TRUE);
+#else
+    GTK_WIDGET_SET_FLAGS(button8, GTK_CAN_DEFAULT);
+#endif
+    button7 = gtk_button_new_with_mnemonic(_("_Synchronize"));
+    gtk_widget_show(button7);
+    gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button7,
+				 GTK_RESPONSE_ACCEPT);
+#if GTK_CHECK_VERSION(2, 18, 0)
+    gtk_widget_set_can_default(button7, TRUE);
+#else
+    GTK_WIDGET_SET_FLAGS(button7, GTK_CAN_DEFAULT);
+#endif
+    button6 = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
+    g_signal_connect(G_OBJECT(button6), "clicked",
+		     (GCallback) close_clicked, NULL);
+    gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button6,
+				 GTK_RESPONSE_ACCEPT);
+#if GTK_CHECK_VERSION(2, 18, 0)
+    gtk_widget_set_can_default(button6, TRUE);
+#else
+    GTK_WIDGET_SET_FLAGS(button6, GTK_CAN_DEFAULT);
+#endif
+
+    sd->dialog = dialog;
+    sd->button_sync = button7;
+    sd->button_cancel = button8;
+    sd->button_close = button6;
+    sd->scroll_box = scrolledwindow2;
+    sd->label = label;
+
+    return sd;
+}
+
+static void sync_dialog_destroy(SyncDialog * sd)
+{
+    gtk_widget_destroy(sd->dialog);
+    sync_dialog_netarea_destroy(sd->sna);
+    g_free(sd);
+}
+#endif				/* HAS_LIBSOUP */
diff --git a/test/data/alpha_as_cpuinfo b/test/data/alpha_as_cpuinfo
new file mode 100644
index 0000000..698b3d4
--- /dev/null
+++ b/test/data/alpha_as_cpuinfo
@@ -0,0 +1,19 @@
+cpu                     : Alpha
+cpu model               : EV56
+cpu variation           : 7
+cpu revision            : 0
+cpu serial number       :
+system type             : Rawhide
+system variation        : Tincup
+system revision         : 0
+system serial number    : BT00000000
+cycle frequency [Hz]    : 531914893
+timer frequency [Hz]    : 1200.00
+page size [bytes]       : 8192
+phys. address bits      : 40
+max. addr. space #      : 127
+BogoMIPS                : 1063.92
+kernel unaligned acc    : 0 (pc=0,va=0)
+user unaligned acc      : 0 (pc=0,va=0)
+platform string         : AlphaServer 1200 5/533 4MB
+cpus detected : 1
diff --git a/test/data/arm_asus_android_cpuinfo b/test/data/arm_asus_android_cpuinfo
new file mode 100644
index 0000000..bc1e811
--- /dev/null
+++ b/test/data/arm_asus_android_cpuinfo
@@ -0,0 +1,17 @@
+Processor       : AArch64 Processor rev 1 (aarch64)
+processor       : 0
+processor       : 1
+processor       : 2
+processor       : 3
+processor       : 4
+processor       : 5
+processor       : 6
+processor       : 7
+Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer : 0x41
+CPU architecture: 8
+CPU variant     : 0x0
+CPU part        : 0xd03
+CPU revision    : 1
+
+Hardware        : Qualcomm Technologies, Inc MSM8939
diff --git a/test/data/arm_jetsontx2_cpuinfo b/test/data/arm_jetsontx2_cpuinfo
new file mode 100644
index 0000000..0ac0480
--- /dev/null
+++ b/test/data/arm_jetsontx2_cpuinfo
@@ -0,0 +1,61 @@
+processor	: 0
+model name	: ARMv8 Processor rev 3 (v8l)
+BogoMIPS	: 62.50
+Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer	: 0x41
+CPU architecture: 8
+CPU variant	: 0x1
+CPU part	: 0xd07
+CPU revision	: 3
+
+processor	: 1
+model name	: ARMv8 Processor rev 0 (v8l)
+BogoMIPS	: 62.50
+Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer	: 0x4e
+CPU architecture: 8
+CPU variant	: 0x0
+CPU part	: 0x003
+CPU revision	: 0
+MTS version	: 37620520
+
+processor	: 2
+model name	: ARMv8 Processor rev 0 (v8l)
+BogoMIPS	: 62.50
+Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer	: 0x4e
+CPU architecture: 8
+CPU variant	: 0x0
+CPU part	: 0x003
+CPU revision	: 0
+MTS version	: 37620520
+
+processor	: 3
+model name	: ARMv8 Processor rev 3 (v8l)
+BogoMIPS	: 62.50
+Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer	: 0x41
+CPU architecture: 8
+CPU variant	: 0x1
+CPU part	: 0xd07
+CPU revision	: 3
+
+processor	: 4
+model name	: ARMv8 Processor rev 3 (v8l)
+BogoMIPS	: 62.50
+Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer	: 0x41
+CPU architecture: 8
+CPU variant	: 0x1
+CPU part	: 0xd07
+CPU revision	: 3
+
+processor	: 5
+model name	: ARMv8 Processor rev 3 (v8l)
+BogoMIPS	: 62.50
+Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer	: 0x41
+CPU architecture: 8
+CPU variant	: 0x1
+CPU part	: 0xd07
+CPU revision	: 3
diff --git a/test/data/arm_marv_cpuinfo b/test/data/arm_marv_cpuinfo
new file mode 100644
index 0000000..e48bebc
--- /dev/null
+++ b/test/data/arm_marv_cpuinfo
@@ -0,0 +1,9 @@
+Processor       : Feroceon 88FR131 rev 1 (v5l)
+BogoMIPS        : 1192.75
+Features        : swp half fastmult edsp
+CPU implementer : 0x56
+CPU architecture: 5TE
+CPU variant     : 0x2
+CPU part        : 0x131
+CPU revision    : 1
+
diff --git a/test/data/arm_rpi3_aarch32_cpuinfo b/test/data/arm_rpi3_aarch32_cpuinfo
new file mode 100644
index 0000000..5092ba9
--- /dev/null
+++ b/test/data/arm_rpi3_aarch32_cpuinfo
@@ -0,0 +1,44 @@
+processor	: 0
+model name	: ARMv7 Processor rev 4 (v7l)
+BogoMIPS	: 38.40
+Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
+CPU implementer	: 0x41
+CPU architecture: 7
+CPU variant	: 0x0
+CPU part	: 0xd03
+CPU revision	: 4
+
+processor	: 1
+model name	: ARMv7 Processor rev 4 (v7l)
+BogoMIPS	: 38.40
+Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
+CPU implementer	: 0x41
+CPU architecture: 7
+CPU variant	: 0x0
+CPU part	: 0xd03
+CPU revision	: 4
+
+processor	: 2
+model name	: ARMv7 Processor rev 4 (v7l)
+BogoMIPS	: 38.40
+Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
+CPU implementer	: 0x41
+CPU architecture: 7
+CPU variant	: 0x0
+CPU part	: 0xd03
+CPU revision	: 4
+
+processor	: 3
+model name	: ARMv7 Processor rev 4 (v7l)
+BogoMIPS	: 38.40
+Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
+CPU implementer	: 0x41
+CPU architecture: 7
+CPU variant	: 0x0
+CPU part	: 0xd03
+CPU revision	: 4
+
+Hardware	: BCM2835
+Revision	: a02082
+Serial		: 00000000d5442118
+
diff --git a/test/data/arm_rpi3_aarch64_cpuinfo b/test/data/arm_rpi3_aarch64_cpuinfo
new file mode 100644
index 0000000..f7aef07
--- /dev/null
+++ b/test/data/arm_rpi3_aarch64_cpuinfo
@@ -0,0 +1,36 @@
+processor	: 0
+BogoMIPS	: 38.40
+Features	: fp asimd evtstrm crc32 cpuid
+CPU implementer	: 0x41
+CPU architecture: 8
+CPU variant	: 0x0
+CPU part	: 0xd03
+CPU revision	: 4
+
+processor	: 1
+BogoMIPS	: 38.40
+Features	: fp asimd evtstrm crc32 cpuid
+CPU implementer	: 0x41
+CPU architecture: 8
+CPU variant	: 0x0
+CPU part	: 0xd03
+CPU revision	: 4
+
+processor	: 2
+BogoMIPS	: 38.40
+Features	: fp asimd evtstrm crc32 cpuid
+CPU implementer	: 0x41
+CPU architecture: 8
+CPU variant	: 0x0
+CPU part	: 0xd03
+CPU revision	: 4
+
+processor	: 3
+BogoMIPS	: 38.40
+Features	: fp asimd evtstrm crc32 cpuid
+CPU implementer	: 0x41
+CPU architecture: 8
+CPU variant	: 0x0
+CPU part	: 0xd03
+CPU revision	: 4
+
diff --git a/test/data/ia64_x2_cpuinfo b/test/data/ia64_x2_cpuinfo
new file mode 100644
index 0000000..f355d80
--- /dev/null
+++ b/test/data/ia64_x2_cpuinfo
@@ -0,0 +1,27 @@
+processor  : 0
+vendor     : GenuineIntel
+arch       : IA-64
+family     : Itanium
+model      : 0
+revision   : 6
+archrev    : 0
+features   : standard
+cpu number : 0
+cpu regs   : 4
+cpu MHz    : 733.433976
+itc MHz    : 733.433976
+BogoMIPS   : 517.99
+
+processor  : 1
+vendor     : GenuineIntel
+arch       : IA-64
+family     : Itanium
+model      : 0
+revision   : 6
+archrev    : 0
+features   : standard
+cpu number : 0
+cpu regs   : 4
+cpu MHz    : 733.433976
+itc MHz    : 733.433976
+BogoMIPS : 729.80
diff --git a/test/data/m68k_sun3_cpuinfo b/test/data/m68k_sun3_cpuinfo
new file mode 100644
index 0000000..8c9c8d5
--- /dev/null
+++ b/test/data/m68k_sun3_cpuinfo
@@ -0,0 +1,6 @@
+CPU:            68020
+MMU:            Sun-3
+FPU:            68881
+Clocking:       19.9MHz
+BogoMips:       4.97
+Calibration: 24896 loops
diff --git a/test/data/mips_loongson_cpuinfo b/test/data/mips_loongson_cpuinfo
new file mode 100644
index 0000000..f2ee0e9
--- /dev/null
+++ b/test/data/mips_loongson_cpuinfo
@@ -0,0 +1,13 @@
+system type             : gdium
+processor               : 0
+cpu model               : ICT Loongson-2 V0.3  FPU V0.1
+BogoMIPS                : 598.60
+wait instruction        : no
+microsecond timers      : yes
+tlb_entries             : 64
+extra interrupt vector  : no
+hardware watchpoint     : no
+ASEs implemented        :
+shadow register sets    : 1
+VCED exceptions         : not available
+VCEI exceptions         : not available
diff --git a/test/data/parisc_hppa_fortex4_cpuinfo b/test/data/parisc_hppa_fortex4_cpuinfo
new file mode 100644
index 0000000..79efffc
--- /dev/null
+++ b/test/data/parisc_hppa_fortex4_cpuinfo
@@ -0,0 +1,59 @@
+processor       : 0
+cpu family      : PA-RISC 2.0
+cpu             : PA8500 (PCX-W)
+cpu MHz         : 440.000000
+model           : 9000/785/J7000
+model name      : Forte W 4-way
+hversion        : 0x00005bf0
+sversion        : 0x00000491
+I-cache         : 512 KB
+D-cache         : 1024 KB (WB)
+ITLB entries    : 160
+DTLB entries    : 160 - shared with ITLB
+bogomips        : 878.18
+software id     : 2002742099
+
+processor       : 1
+cpu family      : PA-RISC 2.0
+cpu             : PA8500 (PCX-W)
+cpu MHz         : 440.000000
+model           : 9000/785/J7000
+model name      : Forte W 4-way
+hversion        : 0x00005bf0
+sversion        : 0x00000491
+I-cache         : 512 KB
+D-cache         : 1024 KB (WB)
+ITLB entries    : 160
+DTLB entries    : 160 - shared with ITLB
+bogomips        : 878.18
+software id     : 2002742099
+
+processor       : 2
+cpu family      : PA-RISC 2.0
+cpu             : PA8500 (PCX-W)
+cpu MHz         : 440.000000
+model           : 9000/785/J7000
+model name      : Forte W 4-way
+hversion        : 0x00005bf0
+sversion        : 0x00000491
+I-cache         : 512 KB
+D-cache         : 1024 KB (WB)
+ITLB entries    : 160
+DTLB entries    : 160 - shared with ITLB
+bogomips        : 878.18
+software id     : 2002742099
+
+processor       : 3
+cpu family      : PA-RISC 2.0
+cpu             : PA8500 (PCX-W)
+cpu MHz         : 440.000000
+model           : 9000/785/J7000
+model name      : Forte W 4-way
+hversion        : 0x00005bf0
+sversion        : 0x00000491
+I-cache         : 512 KB
+D-cache         : 1024 KB (WB)
+ITLB entries    : 160
+DTLB entries    : 160 - shared with ITLB
+bogomips        : 878.18
+software id : 2002742099
diff --git a/test/data/power8_cpuinfo b/test/data/power8_cpuinfo
new file mode 100644
index 0000000..0544168
--- /dev/null
+++ b/test/data/power8_cpuinfo
@@ -0,0 +1,325 @@
+processor	: 0
+cpu		: POWER8 (raw), altivec supported
+clock		: 3857.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 1
+cpu		: POWER8 (raw), altivec supported
+clock		: 3857.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 2
+cpu		: POWER8 (raw), altivec supported
+clock		: 3857.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 3
+cpu		: POWER8 (raw), altivec supported
+clock		: 3857.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 4
+cpu		: POWER8 (raw), altivec supported
+clock		: 3857.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 5
+cpu		: POWER8 (raw), altivec supported
+clock		: 3857.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 6
+cpu		: POWER8 (raw), altivec supported
+clock		: 3857.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 7
+cpu		: POWER8 (raw), altivec supported
+clock		: 3857.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 8
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 9
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 10
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 11
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 12
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 13
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 14
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 15
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 16
+cpu		: POWER8 (raw), altivec supported
+clock		: 3059.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 17
+cpu		: POWER8 (raw), altivec supported
+clock		: 3059.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 18
+cpu		: POWER8 (raw), altivec supported
+clock		: 3059.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 19
+cpu		: POWER8 (raw), altivec supported
+clock		: 3059.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 20
+cpu		: POWER8 (raw), altivec supported
+clock		: 3059.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 21
+cpu		: POWER8 (raw), altivec supported
+clock		: 3059.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 22
+cpu		: POWER8 (raw), altivec supported
+clock		: 3059.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 23
+cpu		: POWER8 (raw), altivec supported
+clock		: 3059.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 24
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 25
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 26
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 27
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 28
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 29
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 30
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 31
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 32
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 33
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 34
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 35
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 36
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 37
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 38
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 39
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 40
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 41
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 42
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 43
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 44
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 45
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 46
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 47
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 48
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 49
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 50
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 51
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 52
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 53
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 54
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 55
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 56
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 57
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 58
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 59
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 60
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 61
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 62
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+processor	: 63
+cpu		: POWER8 (raw), altivec supported
+clock		: 2061.000000MHz
+revision	: 2.0 (pvr 004d 0200)
+
+timebase	: 512000000
+platform	: PowerNV
+model		: 8335-GCA        
+machine		: PowerNV 8335-GCA        
+firmware	: OPAL v3
diff --git a/test/data/ppc_g5_cpuinfo b/test/data/ppc_g5_cpuinfo
new file mode 100644
index 0000000..f326316
--- /dev/null
+++ b/test/data/ppc_g5_cpuinfo
@@ -0,0 +1,30 @@
+processor	: 0
+cpu		: PPC970MP, altivec supported
+clock		: 1250.000000MHz
+revision	: 1.1 (pvr 0044 0101)
+
+processor	: 1
+cpu		: PPC970MP, altivec supported
+clock		: 1250.000000MHz
+revision	: 1.1 (pvr 0044 0101)
+
+processor	: 2
+cpu		: PPC970MP, altivec supported
+clock		: 1250.000000MHz
+revision	: 1.1 (pvr 0044 0101)
+
+processor	: 3
+cpu		: PPC970MP, altivec supported
+clock		: 1250.000000MHz
+revision	: 1.1 (pvr 0044 0101)
+
+timebase	: 33333333
+platform	: PowerMac
+model		: PowerMac11,2
+machine		: PowerMac11,2
+motherboard	: PowerMac11,2 MacRISC4 Power Macintosh 
+detected as	: 337 (PowerMac G5 Dual Core)
+pmac flags	: 00000000
+L2 cache	: 1024K unified
+pmac-generation	: NewWorld
+
diff --git a/test/data/riscv_fake_cpuinfo b/test/data/riscv_fake_cpuinfo
new file mode 100644
index 0000000..3f23c5e
--- /dev/null
+++ b/test/data/riscv_fake_cpuinfo
@@ -0,0 +1,2 @@
+hart    : 0
+isa     : rv32a4p0c2pdfimsu_Xargle2P1_SXbargle
diff --git a/test/data/riscv_sim_cpuinfo b/test/data/riscv_sim_cpuinfo
new file mode 100644
index 0000000..a87cdec
--- /dev/null
+++ b/test/data/riscv_sim_cpuinfo
@@ -0,0 +1,2 @@
+hart	: 0
+isa	: RV64G
diff --git a/test/data/rpi1_raspbian.dts b/test/data/rpi1_raspbian.dts
new file mode 100644
index 0000000..ce50cba
--- /dev/null
+++ b/test/data/rpi1_raspbian.dts
@@ -0,0 +1,758 @@
+/dts-v1/;
+
+/ {
+	compatible = "brcm,bcm2835";
+	serial-number = "00000000925ea123";
+	model = "Raspberry Pi Model B Rev 1";
+	memreserve = <0xf000000 0x1000000>;
+	interrupt-parent = <0x1>;
+	#address-cells = <0x1>;
+	#size-cells = <0x1>;
+
+	clocks {
+		compatible = "simple-bus";
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+
+		clock@3 {
+			compatible = "fixed-clock";
+			#clock-cells = <0x0>;
+			phandle = <0x2>;
+			reg = <0x3>;
+			clock-output-names = "osc";
+			clock-frequency = <0x124f800>;
+		};
+
+		clock@4 {
+			compatible = "fixed-clock";
+			#clock-cells = <0x0>;
+			phandle = <0x11>;
+			reg = <0x4>;
+			clock-output-names = "otg";
+			clock-frequency = <0x1c9c3800>;
+		};
+	};
+
+	__overrides__ {
+		i2c1 = [00 00 00 1b 73 74 61 74 75 73 00];
+		i2c_vc = [00 00 00 1b 73 74 61 74 75 73 00];
+		sd_overclock = "", "", "", " brcm,overclock-50:0";
+		i2c0_baudrate = [00 00 00 1a 63 6c 6f 63 6b 2d 66 72 65 71 75 65 6e 63 79 3a 30 00];
+		sd_pio_limit = "", "", "", " brcm,pio-limit:0";
+		act_led_trigger = [00 00 00 1c 6c 69 6e 75 78 2c 64 65 66 61 75 6c 74 2d 74 72 69 67 67 65 72 00];
+		audio = [00 00 00 1d 73 74 61 74 75 73 00];
+		sd_debug = "", "", "", " brcm,debug";
+		cache_line_size = [00 00 00 15 63 61 63 68 65 2d 6c 69 6e 65 2d 73 69 7a 65 3a 30 00];
+		i2c1_baudrate = [00 00 00 1b 63 6c 6f 63 6b 2d 66 72 65 71 75 65 6e 63 79 3a 30 00];
+		spi = [00 00 00 19 73 74 61 74 75 73 00];
+		i2c_arm = [00 00 00 1a 73 74 61 74 75 73 00];
+		uart0 = [00 00 00 16 73 74 61 74 75 73 00];
+		i2c2_iknowwhatimdoing = [00 00 00 10 73 74 61 74 75 73 00];
+		i2s = [00 00 00 18 73 74 61 74 75 73 00];
+		i2c0 = [00 00 00 1a 73 74 61 74 75 73 00];
+		watchdog = [00 00 00 1e 73 74 61 74 75 73 00];
+		i2c_baudrate = [00 00 00 1a 63 6c 6f 63 6b 2d 66 72 65 71 75 65 6e 63 79 3a 30 00];
+		i2c_vc_baudrate = [00 00 00 1b 63 6c 6f 63 6b 2d 66 72 65 71 75 65 6e 63 79 3a 30 00];
+		act_led_activelow = <0x1c 0x6770696f 0x733a3800>;
+		i2c2_baudrate = [00 00 00 10 63 6c 6f 63 6b 2d 66 72 65 71 75 65 6e 63 79 3a 30 00];
+		sd_force_pio = "", "", "", " brcm,force-pio?";
+		uart1 = [00 00 00 17 73 74 61 74 75 73 00];
+		i2c_arm_baudrate = [00 00 00 1a 63 6c 6f 63 6b 2d 66 72 65 71 75 65 6e 63 79 3a 30 00];
+		random = [00 00 00 1f 73 74 61 74 75 73 00];
+		act_led_gpio = <0x1c 0x6770696f 0x733a3400>;
+		i2c = [00 00 00 1a 73 74 61 74 75 73 00];
+	};
+
+	system {
+		linux,serial = <0x0 0x925b29dd>;
+		linux,revision = <0x2>;
+	};
+
+	__symbols__ {
+		pwm = "/soc/pwm@7e20c000";
+		clk_usb = "/clocks/clock@4";
+		pixelvalve0 = "/soc/pixelvalve@7e206000";
+		intc = "/soc/interrupt-controller@7e00b200";
+		spi2 = "/soc/spi@7e2150c0";
+		dsi1 = "/soc/dsi@7e700000";
+		clocks = "/soc/cprman@7e101000";
+		i2c1 = "/soc/i2c@7e804000";
+		i2c_vc = "/soc/i2c@7e804000";
+		firmwarekms = "/soc/firmwarekms@7e600000";
+		smi = "/soc/smi@7e600000";
+		gpu = "/soc/gpu";
+		spi0 = "/soc/spi@7e204000";
+		thermal = "/soc/thermal";
+		vdd_5v0_reg = "/fixedregulator_5v0";
+		vchiq = "/soc/vchiq";
+		sdhost = "/soc/sdhost@7e202000";
+		aux = "/soc/aux@0x7e215000";
+		gpio = "/soc/gpio@7e200000";
+		dpi = "/soc/dpi@7e208000";
+		v3d = "/soc/v3d@7ec00000";
+		audio = "/soc/audio";
+		vdd_3v3_reg = "/fixedregulator_3v3";
+		dma = "/soc/dma@7e007000";
+		spidev1 = "/soc/spi@7e204000/spidev@1";
+		vc4 = "/soc/gpu";
+		power = "/soc/power";
+		soc = "/soc";
+		leds = "/leds";
+		i2s_pins = "/soc/gpio@7e200000/i2s";
+		firmware = "/soc/firmware";
+		cprman = "/soc/cprman@7e101000";
+		mmc = "/soc/mmc@7e300000";
+		pixelvalve1 = "/soc/pixelvalve@7e207000";
+		spi = "/soc/spi@7e204000";
+		spi0_pins = "/soc/gpio@7e200000/spi0_pins";
+		pitouchscreen_touch = "/soc/i2cdsi/bridge@38";
+		i2c_arm = "/soc/i2c@7e205000";
+		clk_osc = "/clocks/clock@3";
+		ethernet = "/soc/usb@7e980000/usb1@1/usbether@1";
+		uart0 = "/soc/serial@7e201000";
+		i2c1_pins = "/soc/gpio@7e200000/i2c1";
+		fb = "/soc/fb";
+		sdhost_pins = "/soc/gpio@7e200000/sdhost_pins";
+		i2c2 = "/soc/i2c@7e805000";
+		i2s = "/soc/i2s@7e203000";
+		spi1 = "/soc/spi@7e215080";
+		usb = "/soc/usb@7e980000";
+		dsi0 = "/soc/dsi@7e209000";
+		audio_pins = "/soc/gpio@7e200000/audio_pins";
+		i2c0 = "/soc/i2c@7e205000";
+		i2c0_pins = "/soc/gpio@7e200000/i2c0";
+		watchdog = "/soc/watchdog@7e100000";
+		vec = "/soc/vec@7e806000";
+		i2c_dsi = "/soc/i2cdsi";
+		pitouchscreen_bridge = "/soc/i2cdsi/bridge@45";
+		spi0_cs_pins = "/soc/gpio@7e200000/spi0_cs_pins";
+		sound = "/soc/sound";
+		hvs = "/soc/hvs@7e400000";
+		act_led = "/leds/act";
+		spidev0 = "/soc/spi@7e204000/spidev@0";
+		hdmi = "/soc/hdmi@7e902000";
+		pixelvalve2 = "/soc/pixelvalve@7e807000";
+		mailbox = "/soc/mailbox@7e00b880";
+		uart1 = "/soc/serial@7e215040";
+		random = "/soc/rng@7e104000";
+		i2c = "/soc/i2c@7e205000";
+	};
+
+	soc {
+		compatible = "simple-bus";
+		ranges = <0x7e000000 0x20000000 0x2000000>;
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		phandle = <0x21>;
+		dma-ranges = <0x40000000 0x0 0x20000000>;
+
+		serial@7e201000 {
+			compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
+			clocks = <0x6 0x13 0x6 0x14>;
+			clock-names = "uartclk", "apb_pclk";
+			status = "okay";
+			interrupts = <0x2 0x19>;
+			phandle = <0x16>;
+			arm,primecell-periphid = <0x241011>;
+			reg = <0x7e201000 0x1000>;
+		};
+
+		pixelvalve@7e207000 {
+			compatible = "brcm,bcm2835-pixelvalve1";
+			status = "disabled";
+			interrupts = <0x2 0xe>;
+			phandle = <0x25>;
+			reg = <0x7e207000 0x100>;
+		};
+
+		cprman@7e101000 {
+			compatible = "brcm,bcm2835-cprman";
+			clocks = <0x2 0x3 0x0 0x3 0x1 0x3 0x2 0x4 0x0 0x4 0x1 0x4 0x2>;
+			firmware = <0x5>;
+			#clock-cells = <0x1>;
+			phandle = <0x6>;
+			reg = <0x7e101000 0x2000>;
+		};
+
+		hvs@7e400000 {
+			compatible = "brcm,bcm2835-hvs";
+			status = "disabled";
+			interrupts = <0x2 0x1>;
+			phandle = <0x29>;
+			reg = <0x7e400000 0x6000>;
+		};
+
+		gpio@7e200000 {
+			compatible = "brcm,bcm2835-gpio";
+			gpio-controller;
+			#interrupt-cells = <0x2>;
+			interrupts = <0x2 0x11 0x2 0x12>;
+			phandle = <0x9>;
+			reg = <0x7e200000 0xb4>;
+			#gpio-cells = <0x2>;
+			interrupt-controller;
+
+			i2c1 {
+				brcm,pins = <0x2 0x3>;
+				phandle = <0xf>;
+				brcm,function = <0x4>;
+			};
+
+			spi0_pins {
+				brcm,pins = <0x9 0xa 0xb>;
+				phandle = <0xa>;
+				brcm,function = <0x4>;
+			};
+
+			sdhost_pins {
+				brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>;
+				phandle = <0x12>;
+				brcm,function = <0x4>;
+			};
+
+			i2s {
+				brcm,pins = <0x1c 0x1d 0x1e 0x1f>;
+				phandle = <0x8>;
+				brcm,function = <0x6>;
+			};
+
+			audio_pins {
+				brcm,pins = <0x28 0x2d>;
+				phandle = <0x14>;
+				brcm,function = <0x4>;
+			};
+
+			i2c0 {
+				brcm,pins = <0x0 0x1>;
+				phandle = <0xc>;
+				brcm,function = <0x4>;
+			};
+
+			spi0_cs_pins {
+				brcm,pins = <0x8 0x7>;
+				phandle = <0xb>;
+				brcm,function = <0x1>;
+			};
+		};
+
+		pixelvalve@7e807000 {
+			compatible = "brcm,bcm2835-pixelvalve2";
+			status = "disabled";
+			interrupts = <0x2 0xa>;
+			phandle = <0x2b>;
+			reg = <0x7e807000 0x100>;
+		};
+
+		v3d@7ec00000 {
+			power-domains = <0xe 0xa>;
+			compatible = "brcm,vc4-v3d";
+			status = "disabled";
+			interrupts = <0x1 0xa>;
+			phandle = <0x2f>;
+			reg = <0x7ec00000 0x1000>;
+		};
+
+		gpu {
+			compatible = "brcm,bcm2835-vc4";
+			status = "disabled";
+			phandle = <0x30>;
+		};
+
+		mmc@7e300000 {
+			compatible = "brcm,bcm2835-mmc";
+			clocks = <0x6 0x1c>;
+			status = "disabled";
+			interrupts = <0x2 0x1e>;
+			brcm,overclock-50 = <0x0>;
+			dma-names = "rx-tx";
+			phandle = <0x32>;
+			reg = <0x7e300000 0x100>;
+			dmas = <0x7 0xb>;
+		};
+
+		arm-pmu {
+			compatible = "arm,arm1176-pmu";
+		};
+
+		thermal {
+			compatible = "brcm,bcm2835-thermal";
+			firmware = <0x5>;
+			phandle = <0x39>;
+		};
+
+		spi@7e204000 {
+			compatible = "brcm,bcm2835-spi";
+			clocks = <0x6 0x14>;
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x16>;
+			cs-gpios = <0x9 0x8 0x1 0x9 0x7 0x1>;
+			#size-cells = <0x0>;
+			dma-names = "tx", "rx";
+			phandle = <0x19>;
+			reg = <0x7e204000 0x1000>;
+			pinctrl-0 = <0xa 0xb>;
+			dmas = <0x7 0x6 0x7 0x7>;
+			pinctrl-names = "default";
+
+			spidev@1 {
+				compatible = "spidev";
+				#address-cells = <0x1>;
+				#size-cells = <0x0>;
+				phandle = <0x23>;
+				reg = <0x1>;
+				spi-max-frequency = <0x7a120>;
+			};
+
+			spidev@0 {
+				compatible = "spidev";
+				#address-cells = <0x1>;
+				#size-cells = <0x0>;
+				phandle = <0x22>;
+				reg = <0x0>;
+				spi-max-frequency = <0x7a120>;
+			};
+		};
+
+		i2cdsi {
+			gpios = <0x9 0x2 0x0 0x9 0x3 0x0>;
+			compatible = "i2c-gpio";
+			status = "disabled";
+			#address-cells = <0x1>;
+			#size-cells = <0x0>;
+			phandle = <0x35>;
+
+			bridge@45 {
+				compatible = "raspberrypi,touchscreen-bridge-i2c";
+				phandle = <0x36>;
+				reg = <0x45>;
+			};
+
+			bridge@38 {
+				compatible = "raspberrypi,touchscreen-ts-i2c";
+				phandle = <0x37>;
+				reg = <0x38>;
+			};
+		};
+
+		vchiq {
+			compatible = "brcm,bcm2835-vchiq";
+			cache-line-size = <0x20>;
+			firmware = <0x5>;
+			interrupts = <0x0 0x2>;
+			phandle = <0x15>;
+			reg = <0x7e00b840 0xf>;
+		};
+
+		i2c@7e804000 {
+			compatible = "brcm,bcm2835-i2c";
+			clocks = <0x6 0x14>;
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x15>;
+			#size-cells = <0x0>;
+			phandle = <0x1b>;
+			reg = <0x7e804000 0x1000>;
+			clock-frequency = <0x186a0>;
+			pinctrl-0 = <0xf>;
+			pinctrl-names = "default";
+		};
+
+		audio {
+			brcm,pwm-channels = <0x8>;
+			compatible = "brcm,bcm2835-audio";
+			status = "okay";
+			phandle = <0x1d>;
+			pinctrl-0 = <0x14>;
+			pinctrl-names = "default";
+		};
+
+		timer@7e003000 {
+			compatible = "brcm,bcm2835-system-timer";
+			interrupts = <0x1 0x0 0x1 0x1 0x1 0x2 0x1 0x3>;
+			reg = <0x7e003000 0x1000>;
+			clock-frequency = <0xf4240>;
+		};
+
+		i2s@7e203000 {
+			compatible = "brcm,bcm2835-i2s";
+			clocks = <0x6 0x1f>;
+			#sound-dai-cells = <0x0>;
+			status = "disabled";
+			dma-names = "tx", "rx";
+			phandle = <0x18>;
+			reg = <0x7e203000 0x24>;
+			pinctrl-0 = <0x8>;
+			dmas = <0x7 0x2 0x7 0x3>;
+			pinctrl-names = "default";
+		};
+
+		mailbox@7e00b880 {
+			compatible = "brcm,bcm2835-mbox";
+			#mbox-cells = <0x0>;
+			interrupts = <0x0 0x1>;
+			phandle = <0x13>;
+			reg = <0x7e00b880 0x40>;
+		};
+
+		gpiomem {
+			compatible = "brcm,bcm2835-gpiomem";
+			reg = <0x7e200000 0x1000>;
+		};
+
+		vec@7e806000 {
+			compatible = "brcm,bcm2835-vec";
+			clocks = <0x6 0x18>;
+			status = "disabled";
+			interrupts = <0x2 0x1b>;
+			phandle = <0x2a>;
+			reg = <0x7e806000 0x1000>;
+		};
+
+		power {
+			compatible = "raspberrypi,bcm2835-power";
+			firmware = <0x5>;
+			phandle = <0xe>;
+			#power-domain-cells = <0x1>;
+		};
+
+		pixelvalve@7e206000 {
+			compatible = "brcm,bcm2835-pixelvalve0";
+			status = "disabled";
+			interrupts = <0x2 0xd>;
+			phandle = <0x24>;
+			reg = <0x7e206000 0x100>;
+		};
+
+		firmware {
+			compatible = "raspberrypi,bcm2835-firmware";
+			mboxes = <0x13>;
+			phandle = <0x5>;
+		};
+
+		dsi@7e209000 {
+			compatible = "brcm,bcm2835-dsi0";
+			clocks = <0x6 0x20 0x6 0x2f 0x6 0x31>;
+			clock-names = "phy", "escape", "pixel";
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x4>;
+			#size-cells = <0x0>;
+			#clock-cells = <0x1>;
+			phandle = <0x3>;
+			reg = <0x7e209000 0x78>;
+			clock-output-names = "dsi0_byte", "dsi0_ddr2", "dsi0_ddr";
+		};
+
+		fb {
+			compatible = "brcm,bcm2708-fb";
+			firmware = <0x5>;
+			status = "okay";
+			phandle = <0x38>;
+		};
+
+		sdhost@7e202000 {
+			compatible = "brcm,bcm2835-sdhost";
+			clocks = <0x6 0x14>;
+			brcm,pio-limit = <0x1>;
+			status = "okay";
+			interrupts = <0x2 0x18>;
+			brcm,overclock-50 = <0x0>;
+			bus-width = <0x4>;
+			dma-names = "rx-tx";
+			phandle = <0x20>;
+			reg = <0x7e202000 0x100>;
+			pinctrl-0 = <0x12>;
+			dmas = <0x7 0xd>;
+			pinctrl-names = "default";
+		};
+
+		dpi@7e208000 {
+			compatible = "brcm,bcm2835-dpi";
+			clocks = <0x6 0x14 0x6 0x2c>;
+			clock-names = "core", "pixel";
+			status = "disabled";
+			#address-cells = <0x1>;
+			#size-cells = <0x0>;
+			phandle = <0x31>;
+			reg = <0x7e208000 0x8c>;
+		};
+
+		hdmi@7e902000 {
+			power-domains = <0xe 0x5>;
+			compatible = "brcm,bcm2835-hdmi";
+			clocks = <0x6 0x10 0x6 0x19>;
+			clock-names = "pixel", "hdmi";
+			ddc = <0x10>;
+			status = "disabled";
+			interrupts = <0x2 0x8 0x2 0x9>;
+			dma-names = "audio-rx";
+			phandle = <0x2c>;
+			hpd-gpios = <0x9 0x2e 0x0>;
+			reg = <0x7e902000 0x600 0x7e808000 0x100>;
+			dmas = <0x7 0x11>;
+		};
+
+		pwm@7e20c000 {
+			compatible = "brcm,bcm2835-pwm";
+			clocks = <0x6 0x1e>;
+			status = "disabled";
+			assigned-clock-rates = <0x989680>;
+			assigned-clocks = <0x6 0x1e>;
+			phandle = <0x28>;
+			reg = <0x7e20c000 0x28>;
+			#pwm-cells = <0x2>;
+		};
+
+		watchdog@7e100000 {
+			compatible = "brcm,bcm2835-pm-wdt";
+			phandle = <0x1e>;
+			reg = <0x7e100000 0x28>;
+		};
+
+		interrupt-controller@7e00b200 {
+			compatible = "brcm,bcm2835-armctrl-ic";
+			#interrupt-cells = <0x2>;
+			phandle = <0x1>;
+			reg = <0x7e00b200 0x200>;
+			interrupt-controller;
+		};
+
+		dsi@7e700000 {
+			power-domains = <0xe 0x12>;
+			compatible = "brcm,bcm2835-dsi1";
+			clocks = <0x6 0x23 0x6 0x30 0x6 0x32>;
+			clock-names = "phy", "escape", "pixel";
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0xc>;
+			#size-cells = <0x0>;
+			#clock-cells = <0x1>;
+			phandle = <0x4>;
+			reg = <0x7e700000 0x8c>;
+			clock-output-names = "dsi1_byte", "dsi1_ddr2", "dsi1_ddr";
+		};
+
+		sound {
+			status = "disabled";
+			phandle = <0x3a>;
+		};
+
+		i2c@7e205000 {
+			compatible = "brcm,bcm2835-i2c";
+			clocks = <0x6 0x14>;
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x15>;
+			#size-cells = <0x0>;
+			phandle = <0x1a>;
+			reg = <0x7e205000 0x1000>;
+			clock-frequency = <0x186a0>;
+			pinctrl-0 = <0xc>;
+			pinctrl-names = "default";
+		};
+
+		serial@7e215040 {
+			compatible = "brcm,bcm2835-aux-uart";
+			clocks = <0xd 0x0>;
+			status = "disabled";
+			interrupt-parent = <0xd>;
+			interrupts = <0x0>;
+			phandle = <0x17>;
+			reg = <0x7e215040 0x40>;
+		};
+
+		dma@7e007000 {
+			#dma-cells = <0x1>;
+			compatible = "brcm,bcm2835-dma";
+			brcm,dma-channel-mask = <0x7f34>;
+			interrupts = <0x1 0x10 0x1 0x11 0x1 0x12 0x1 0x13 0x1 0x14 0x1 0x15 0x1 0x16 0x1 0x17 0x1 0x18 0x1 0x19 0x1 0x1a 0x1 0x1b 0x1 0x1b 0x1 0x1b 0x1 0x1b 0x1 0x1c>;
+			phandle = <0x7>;
+			reg = <0x7e007000 0xf00>;
+			interrupt-names = "dma0", "dma1", "dma2", "dma3", "dma4", "dma5", "dma6", "dma7", "dma8", "dma9", "dma10", "dma11", "dma12", "dma13", "dma14", "dma-shared-all";
+		};
+
+		i2c@7e805000 {
+			compatible = "brcm,bcm2835-i2c";
+			clocks = <0x6 0x14>;
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x15>;
+			#size-cells = <0x0>;
+			phandle = <0x10>;
+			reg = <0x7e805000 0x1000>;
+			clock-frequency = <0x186a0>;
+		};
+
+		spi@7e215080 {
+			compatible = "brcm,bcm2835-aux-spi";
+			clocks = <0xd 0x1>;
+			status = "disabled";
+			interrupt-parent = <0xd>;
+			#address-cells = <0x1>;
+			interrupts = <0x1>;
+			#size-cells = <0x0>;
+			phandle = <0x26>;
+			reg = <0x7e215080 0x40>;
+		};
+
+		aux@0x7e215000 {
+			compatible = "brcm,bcm2835-aux";
+			clocks = <0x6 0x14>;
+			#interrupt-cells = <0x1>;
+			interrupts = <0x1 0x1d>;
+			#clock-cells = <0x1>;
+			phandle = <0xd>;
+			reg = <0x7e215000 0x8>;
+			interrupt-controller;
+		};
+
+		firmwarekms@7e600000 {
+			compatible = "raspberrypi,rpi-firmware-kms";
+			status = "disabled";
+			interrupts = <0x2 0x10>;
+			brcm,firmware = <0x5>;
+			phandle = <0x33>;
+			reg = <0x7e600000 0x100>;
+		};
+
+		rng@7e104000 {
+			compatible = "brcm,bcm2835-rng";
+			phandle = <0x1f>;
+			reg = <0x7e104000 0x10>;
+		};
+
+		usb@7e980000 {
+			power-domains = <0xe 0x6>;
+			compatible = "brcm,bcm2708-usb";
+			clocks = <0x11>;
+			clock-names = "otg";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x0 0x1 0x9>;
+			#size-cells = <0x0>;
+			phandle = <0x2d>;
+			reg = <0x7e980000 0x10000 0x7e006000 0x1000>;
+
+			usb1@1 {
+				compatible = "usb424,9512";
+				#address-cells = <0x1>;
+				#size-cells = <0x0>;
+				reg = <0x1>;
+
+				usbether@1 {
+					compatible = "usb424,ec00";
+					local-mac-address = [04 05 07 01 02 03];
+					phandle = <0x2e>;
+					reg = <0x1>;
+				};
+			};
+		};
+
+		smi@7e600000 {
+			compatible = "brcm,bcm2835-smi";
+			clocks = <0x6 0x2a>;
+			status = "disabled";
+			interrupts = <0x2 0x10>;
+			assigned-clock-rates = <0x7735940>;
+			dma-names = "rx-tx";
+			assigned-clocks = <0x6 0x2a>;
+			phandle = <0x34>;
+			reg = <0x7e600000 0x100>;
+			dmas = <0x7 0x4>;
+		};
+
+		spi@7e2150c0 {
+			compatible = "brcm,bcm2835-aux-spi";
+			clocks = <0xd 0x2>;
+			status = "disabled";
+			interrupt-parent = <0xd>;
+			#address-cells = <0x1>;
+			interrupts = <0x2>;
+			#size-cells = <0x0>;
+			phandle = <0x27>;
+			reg = <0x7e2150c0 0x40>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		phandle = <0x3d>;
+
+		act {
+			gpios = <0x9 0x10 0x1>;
+			label = "led0";
+			phandle = <0x1c>;
+			linux,default-trigger = "mmc0";
+		};
+	};
+
+	aliases {
+		intc = "/soc/interrupt-controller@7e00b200";
+		spi2 = "/soc/spi@7e2150c0";
+		i2c1 = "/soc/i2c@7e804000";
+		i2c_vc = "/soc/i2c@7e804000";
+		spi0 = "/soc/spi@7e204000";
+		thermal = "/soc/thermal";
+		vchiq = "/soc/vchiq";
+		sdhost = "/soc/sdhost@7e202000";
+		aux = "/soc/aux@0x7e215000";
+		gpio = "/soc/gpio@7e200000";
+		audio = "/soc/audio";
+		dma = "/soc/dma@7e007000";
+		soc = "/soc";
+		leds = "/leds";
+		mmc = "/soc/mmc@7e300000";
+		serial1 = "/soc/serial@7e215040";
+		i2c_arm = "/soc/i2c@7e205000";
+		ethernet = "/soc/usb@7e980000/usb1@1/usbether@1";
+		uart0 = "/soc/serial@7e201000";
+		fb = "/soc/fb";
+		i2c2 = "/soc/i2c@7e805000";
+		i2s = "/soc/i2s@7e203000";
+		spi1 = "/soc/spi@7e215080";
+		usb = "/soc/usb@7e980000";
+		i2c0 = "/soc/i2c@7e205000";
+		watchdog = "/soc/watchdog@7e100000";
+		sound = "/soc/sound";
+		mailbox = "/soc/mailbox@7e00b880";
+		uart1 = "/soc/serial@7e215040";
+		random = "/soc/rng@7e104000";
+		i2c = "/soc/i2c@7e205000";
+		serial0 = "/soc/serial@7e201000";
+	};
+
+	chosen {
+		bootargs = "bcm2708_fb.fbwidth=1680 bcm2708_fb.fbheight=1050 bcm2708_fb.fbdepth=16 bcm2708_fb.fbswap=1 vc_mem.mem_base=0xfa00000 vc_mem.mem_size=0x10000000  dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait";
+		kaslr-seed = <0xb1f76783 0x32e6766e>;
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0xf000000>;
+	};
+
+	fixedregulator_3v3 {
+		compatible = "regulator-fixed";
+		phandle = <0x3c>;
+		regulator-min-microvolt = <0x325aa0>;
+		regulator-max-microvolt = <0x325aa0>;
+		regulator-always-on;
+		regulator-name = "3v3";
+	};
+
+	fixedregulator_5v0 {
+		compatible = "regulator-fixed";
+		phandle = <0x3b>;
+		regulator-min-microvolt = <0x4c4b40>;
+		regulator-max-microvolt = <0x4c4b40>;
+		regulator-always-on;
+		regulator-name = "5v0";
+	};
+
+	axi {
+
+		vc_mem {
+			reg = <0xfa00000 0x10000000 0x40000000>;
+		};
+	};
+};
diff --git a/test/data/rpi3_arch_arm64.dts b/test/data/rpi3_arch_arm64.dts
new file mode 100644
index 0000000..5054edd
--- /dev/null
+++ b/test/data/rpi3_arch_arm64.dts
@@ -0,0 +1,666 @@
+/dts-v1/;
+
+/ {
+	compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
+	serial-number = "00000000d544ea12";
+	model = "Raspberry Pi 3 Model B";
+	interrupt-parent = <0x1>;
+	#address-cells = <0x1>;
+	#size-cells = <0x1>;
+
+	clocks {
+		compatible = "simple-bus";
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+
+		clock@3 {
+			compatible = "fixed-clock";
+			#clock-cells = <0x0>;
+			phandle = <0x3>;
+			reg = <0x3>;
+			clock-output-names = "osc";
+			clock-frequency = <0x124f800>;
+			linux,phandle = <0x3>;
+		};
+
+		clock@4 {
+			compatible = "fixed-clock";
+			#clock-cells = <0x0>;
+			phandle = <0xe>;
+			reg = <0x4>;
+			clock-output-names = "otg";
+			clock-frequency = <0x1c9c3800>;
+			linux,phandle = <0xe>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		ranges = <0x7e000000 0x3f000000 0x1000000 0x40000000 0x40000000 0x1000>;
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		dma-ranges = <0xc0000000 0x0 0x3f000000>;
+
+		serial@7e201000 {
+			compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
+			clocks = <0x4 0x13 0x4 0x14>;
+			clock-names = "uartclk", "apb_pclk";
+			interrupts = <0x2 0x19>;
+			arm,primecell-periphid = <0x241011>;
+			reg = <0x7e201000 0x1000>;
+		};
+
+		pixelvalve@7e207000 {
+			compatible = "brcm,bcm2835-pixelvalve1";
+			interrupts = <0x2 0xe>;
+			reg = <0x7e207000 0x100>;
+		};
+
+		cprman@7e101000 {
+			compatible = "brcm,bcm2835-cprman";
+			clocks = <0x3>;
+			#clock-cells = <0x1>;
+			phandle = <0x4>;
+			reg = <0x7e101000 0x2000>;
+			linux,phandle = <0x4>;
+		};
+
+		thermal@7e212000 {
+			compatible = "brcm,bcm2837-thermal";
+			clocks = <0x4 0x1b>;
+			status = "okay";
+			reg = <0x7e212000 0x8>;
+		};
+
+		hvs@7e400000 {
+			compatible = "brcm,bcm2835-hvs";
+			interrupts = <0x2 0x1>;
+			reg = <0x7e400000 0x6000>;
+		};
+
+		gpio@7e200000 {
+			compatible = "brcm,bcm2835-gpio";
+			gpio-controller;
+			#interrupt-cells = <0x2>;
+			interrupts = <0x2 0x11 0x2 0x12 0x2 0x13 0x2 0x14>;
+			phandle = <0x11>;
+			reg = <0x7e200000 0xb4>;
+			#gpio-cells = <0x2>;
+			linux,phandle = <0x11>;
+			pinctrl-names = "default";
+			interrupt-controller;
+
+			uart0_gpio14 {
+				brcm,pins = <0xe 0xf>;
+				brcm,function = <0x4>;
+			};
+
+			gpclk1_gpio5 {
+				brcm,pins = <0x5>;
+				brcm,function = <0x4>;
+			};
+
+			uart1_ctsrts_gpio16 {
+				brcm,pins = <0x10 0x11>;
+				brcm,function = <0x2>;
+			};
+
+			jtag_gpio4 {
+				brcm,pins = <0x4 0x5 0x6 0xc 0xd>;
+				brcm,function = <0x3>;
+			};
+
+			alt0 {
+				brcm,pins = <0x4 0x5 0x7 0x8 0x9 0xa 0xb 0xe 0xf>;
+				brcm,function = <0x4>;
+			};
+
+			uart0_gpio30 {
+				brcm,pins = <0x1e 0x1f>;
+				brcm,function = <0x7>;
+			};
+
+			uart1_ctsrts_gpio42 {
+				brcm,pins = <0x2a 0x2b>;
+				brcm,function = <0x2>;
+			};
+
+			gpclk0_gpio4 {
+				brcm,pins = <0x4>;
+				brcm,function = <0x4>;
+			};
+
+			pwm0_gpio12 {
+				brcm,pins = <0xc>;
+				brcm,function = <0x4>;
+			};
+
+			pwm1_gpio19 {
+				brcm,pins = <0x13>;
+				brcm,function = <0x2>;
+			};
+
+			pwm0_gpio40 {
+				brcm,pins = <0x28>;
+				phandle = <0x8>;
+				brcm,function = <0x4>;
+				linux,phandle = <0x8>;
+			};
+
+			gpclk2_gpio43 {
+				brcm,pins = <0x2b>;
+				brcm,function = <0x4>;
+			};
+
+			uart1_ctsrts_gpio30 {
+				brcm,pins = <0x1e 0x1f>;
+				brcm,function = <0x2>;
+			};
+
+			gpioout {
+				brcm,pins = <0x6>;
+				brcm,function = <0x1>;
+			};
+
+			spi0_gpio35 {
+				brcm,pins = <0x23 0x24 0x25 0x26 0x27>;
+				brcm,function = <0x4>;
+			};
+
+			pwm1_gpio45 {
+				brcm,pins = <0x2d>;
+				phandle = <0x9>;
+				brcm,function = <0x4>;
+				linux,phandle = <0x9>;
+			};
+
+			pcm_gpio28 {
+				brcm,pins = <0x1c 0x1d 0x1e 0x1f>;
+				brcm,function = <0x6>;
+			};
+
+			dpi_gpio0 {
+				brcm,pins = <0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b>;
+				brcm,function = <0x6>;
+			};
+
+			i2c0_gpio0 {
+				brcm,pins = <0x0 0x1>;
+				phandle = <0x6>;
+				brcm,function = <0x4>;
+				linux,phandle = <0x6>;
+			};
+
+			pcm_gpio18 {
+				brcm,pins = <0x12 0x13 0x14 0x15>;
+				brcm,function = <0x4>;
+			};
+
+			pwm1_gpio13 {
+				brcm,pins = <0xd>;
+				brcm,function = <0x4>;
+			};
+
+			pwm1_gpio41 {
+				brcm,pins = <0x29>;
+				brcm,function = <0x4>;
+			};
+
+			spi0_gpio7 {
+				brcm,pins = <0x7 0x8 0x9 0xa 0xb>;
+				brcm,function = <0x4>;
+			};
+
+			i2c1_gpio44 {
+				brcm,pins = <0x2c 0x2d>;
+				brcm,function = <0x6>;
+			};
+
+			i2c_slave_gpio18 {
+				brcm,pins = <0x12 0x13 0x14 0x15>;
+				brcm,function = <0x7>;
+			};
+
+			emmc_gpio48 {
+				brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>;
+				phandle = <0xa>;
+				brcm,function = <0x7>;
+				linux,phandle = <0xa>;
+			};
+
+			i2c1_gpio2 {
+				brcm,pins = <0x2 0x3>;
+				phandle = <0xb>;
+				brcm,function = <0x4>;
+				linux,phandle = <0xb>;
+			};
+
+			spi1_gpio16 {
+				brcm,pins = <0x10 0x11 0x12 0x13 0x14 0x15>;
+				brcm,function = <0x3>;
+			};
+
+			jtag_gpio22 {
+				brcm,pins = <0x16 0x17 0x18 0x19 0x1a 0x1b>;
+				brcm,function = <0x3>;
+			};
+
+			uart1_gpio36 {
+				brcm,pins = <0x24 0x25 0x26 0x27>;
+				brcm,function = <0x6>;
+			};
+
+			spi2_gpio40 {
+				brcm,pins = <0x28 0x29 0x2a 0x2b 0x2c 0x2d>;
+				brcm,function = <0x3>;
+			};
+
+			i2c0_gpio44 {
+				brcm,pins = <0x2c 0x2d>;
+				brcm,function = <0x5>;
+			};
+
+			uart0_ctsrts_gpio16 {
+				brcm,pins = <0x10 0x11>;
+				brcm,function = <0x7>;
+			};
+
+			gpclk2_gpio6 {
+				brcm,pins = <0x6>;
+				brcm,function = <0x4>;
+			};
+
+			sdhost_gpio48 {
+				brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>;
+				brcm,function = <0x4>;
+			};
+
+			emmc_gpio34 {
+				brcm,pins = <0x22 0x23 0x24 0x25 0x26 0x27>;
+				brcm,pull = <0x0 0x2 0x2 0x2 0x2 0x2>;
+				brcm,function = <0x7>;
+			};
+
+			gpclk1_gpio44 {
+				brcm,pins = <0x2c>;
+				brcm,function = <0x4>;
+			};
+
+			uart1_gpio14 {
+				brcm,pins = <0xe 0xf>;
+				brcm,function = <0x2>;
+			};
+
+			i2c0_gpio32 {
+				brcm,pins = <0x20 0x22>;
+				brcm,function = <0x4>;
+			};
+
+			uart1_gpio32 {
+				brcm,pins = <0x20 0x21>;
+				brcm,function = <0x2>;
+			};
+
+			pwm0_gpio18 {
+				brcm,pins = <0x12>;
+				brcm,function = <0x2>;
+			};
+
+			gpclk1_gpio42 {
+				brcm,pins = <0x2a>;
+				brcm,function = <0x4>;
+			};
+
+			uart0_ctsrts_gpio32 {
+				brcm,pins = <0x20 0x21>;
+				brcm,function = <0x7>;
+			};
+
+			uart1_gpio40 {
+				brcm,pins = <0x28 0x29>;
+				brcm,function = <0x2>;
+			};
+
+			emmc_gpio22 {
+				brcm,pins = <0x16 0x17 0x18 0x19 0x1a 0x1b>;
+				brcm,function = <0x7>;
+			};
+		};
+
+		pixelvalve@7e807000 {
+			compatible = "brcm,bcm2835-pixelvalve2";
+			interrupts = <0x2 0xa>;
+			reg = <0x7e807000 0x100>;
+		};
+
+		v3d@7ec00000 {
+			power-domains = <0xc 0xa>;
+			compatible = "brcm,bcm2835-v3d";
+			interrupts = <0x1 0xa>;
+			reg = <0x7ec00000 0x1000>;
+		};
+
+		gpu {
+			compatible = "brcm,bcm2835-vc4";
+		};
+
+		spi@7e204000 {
+			compatible = "brcm,bcm2835-spi";
+			clocks = <0x4 0x14>;
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x16>;
+			#size-cells = <0x0>;
+			reg = <0x7e204000 0x1000>;
+		};
+
+		sdhci@7e300000 {
+			compatible = "brcm,bcm2835-sdhci";
+			clocks = <0x4 0x1c>;
+			status = "okay";
+			interrupts = <0x2 0x1e>;
+			bus-width = <0x4>;
+			reg = <0x7e300000 0x100>;
+			pinctrl-0 = <0xa>;
+			pinctrl-names = "default";
+		};
+
+		i2c@7e804000 {
+			compatible = "brcm,bcm2835-i2c";
+			clocks = <0x4 0x14>;
+			status = "okay";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x15>;
+			#size-cells = <0x0>;
+			reg = <0x7e804000 0x1000>;
+			clock-frequency = <0x186a0>;
+			pinctrl-0 = <0xb>;
+			pinctrl-names = "default";
+		};
+
+		timer@7e003000 {
+			compatible = "brcm,bcm2835-system-timer";
+			interrupts = <0x1 0x0 0x1 0x1 0x1 0x2 0x1 0x3>;
+			reg = <0x7e003000 0x1000>;
+			clock-frequency = <0xf4240>;
+		};
+
+		i2s@7e203000 {
+			compatible = "brcm,bcm2835-i2s";
+			status = "disabled";
+			dma-names = "tx", "rx";
+			reg = <0x7e203000 0x20 0x7e101098 0x2>;
+			dmas = <0x5 0x2 0x5 0x3>;
+		};
+
+		mailbox@7e00b880 {
+			compatible = "brcm,bcm2835-mbox";
+			#mbox-cells = <0x0>;
+			interrupts = <0x0 0x1>;
+			phandle = <0xf>;
+			reg = <0x7e00b880 0x40>;
+			linux,phandle = <0xf>;
+		};
+
+		vec@7e806000 {
+			power-domains = <0xc 0x7>;
+			compatible = "brcm,bcm2835-vec";
+			clocks = <0x4 0x18>;
+			status = "okay";
+			interrupts = <0x2 0x1b>;
+			reg = <0x7e806000 0x1000>;
+		};
+
+		power {
+			compatible = "raspberrypi,bcm2835-power";
+			firmware = <0x10>;
+			phandle = <0xc>;
+			linux,phandle = <0xc>;
+			#power-domain-cells = <0x1>;
+		};
+
+		pixelvalve@7e206000 {
+			compatible = "brcm,bcm2835-pixelvalve0";
+			interrupts = <0x2 0xd>;
+			reg = <0x7e206000 0x100>;
+		};
+
+		firmware {
+			compatible = "raspberrypi,bcm2835-firmware";
+			mboxes = <0xf>;
+			phandle = <0x10>;
+			linux,phandle = <0x10>;
+		};
+
+		hdmi@7e902000 {
+			power-domains = <0xc 0x5>;
+			compatible = "brcm,bcm2835-hdmi";
+			clocks = <0x4 0x10 0x4 0x19>;
+			clock-names = "pixel", "hdmi";
+			ddc = <0xd>;
+			status = "okay";
+			interrupts = <0x2 0x8 0x2 0x9>;
+			reg = <0x7e902000 0x600 0x7e808000 0x100>;
+		};
+
+		pwm@7e20c000 {
+			compatible = "brcm,bcm2835-pwm";
+			clocks = <0x4 0x1e>;
+			status = "okay";
+			assigned-clock-rates = <0x989680>;
+			assigned-clocks = <0x4 0x1e>;
+			reg = <0x7e20c000 0x28>;
+			pinctrl-0 = <0x8 0x9>;
+			#pwm-cells = <0x2>;
+			pinctrl-names = "default";
+		};
+
+		watchdog@7e100000 {
+			compatible = "brcm,bcm2835-pm-wdt";
+			reg = <0x7e100000 0x28>;
+		};
+
+		interrupt-controller@7e00b200 {
+			compatible = "brcm,bcm2836-armctrl-ic";
+			#interrupt-cells = <0x2>;
+			interrupt-parent = <0x2>;
+			interrupts = <0x8>;
+			phandle = <0x1>;
+			reg = <0x7e00b200 0x200>;
+			linux,phandle = <0x1>;
+			interrupt-controller;
+		};
+
+		local_intc {
+			compatible = "brcm,bcm2836-l1-intc";
+			#interrupt-cells = <0x1>;
+			interrupt-parent = <0x2>;
+			phandle = <0x2>;
+			reg = <0x40000000 0x100>;
+			linux,phandle = <0x2>;
+			interrupt-controller;
+		};
+
+		i2c@7e205000 {
+			compatible = "brcm,bcm2835-i2c";
+			clocks = <0x4 0x14>;
+			status = "okay";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x15>;
+			#size-cells = <0x0>;
+			reg = <0x7e205000 0x1000>;
+			clock-frequency = <0x186a0>;
+			pinctrl-0 = <0x6>;
+			pinctrl-names = "default";
+		};
+
+		serial@7e215040 {
+			compatible = "brcm,bcm2835-aux-uart";
+			clocks = <0x7 0x0>;
+			status = "okay";
+			interrupts = <0x1 0x1d>;
+			reg = <0x7e215040 0x40>;
+		};
+
+		dma@7e007000 {
+			#dma-cells = <0x1>;
+			compatible = "brcm,bcm2835-dma";
+			brcm,dma-channel-mask = <0x7f35>;
+			interrupts = <0x1 0x10 0x1 0x11 0x1 0x12 0x1 0x13 0x1 0x14 0x1 0x15 0x1 0x16 0x1 0x17 0x1 0x18 0x1 0x19 0x1 0x1a 0x1 0x1b 0x1 0x1b 0x1 0x1b 0x1 0x1b 0x1 0x1c>;
+			phandle = <0x5>;
+			reg = <0x7e007000 0xf00>;
+			linux,phandle = <0x5>;
+			interrupt-names = "dma0", "dma1", "dma2", "dma3", "dma4", "dma5", "dma6", "dma7", "dma8", "dma9", "dma10", "dma11", "dma12", "dma13", "dma14", "dma-shared-all";
+		};
+
+		i2c@7e805000 {
+			compatible = "brcm,bcm2835-i2c";
+			clocks = <0x4 0x14>;
+			status = "okay";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x15>;
+			#size-cells = <0x0>;
+			phandle = <0xd>;
+			reg = <0x7e805000 0x1000>;
+			linux,phandle = <0xd>;
+		};
+
+		spi@7e215080 {
+			compatible = "brcm,bcm2835-aux-spi";
+			clocks = <0x7 0x1>;
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x1 0x1d>;
+			#size-cells = <0x0>;
+			reg = <0x7e215080 0x40>;
+		};
+
+		aux@0x7e215000 {
+			compatible = "brcm,bcm2835-aux";
+			clocks = <0x4 0x14>;
+			#clock-cells = <0x1>;
+			phandle = <0x7>;
+			reg = <0x7e215000 0x8>;
+			linux,phandle = <0x7>;
+		};
+
+		rng@7e104000 {
+			compatible = "brcm,bcm2835-rng";
+			reg = <0x7e104000 0x10>;
+		};
+
+		usb@7e980000 {
+			power-domains = <0xc 0x6>;
+			compatible = "brcm,bcm2835-usb";
+			clocks = <0xe>;
+			clock-names = "otg";
+			#address-cells = <0x1>;
+			interrupts = <0x1 0x9>;
+			#size-cells = <0x0>;
+			reg = <0x7e980000 0x10000>;
+			dr_mode = "host";
+
+			usb1@1 {
+				compatible = "usb424,9514";
+				#address-cells = <0x1>;
+				#size-cells = <0x0>;
+				reg = <0x1>;
+
+				usbether@1 {
+					compatible = "usb424,ec00";
+					reg = <0x1>;
+				};
+			};
+		};
+
+		spi@7e2150c0 {
+			compatible = "brcm,bcm2835-aux-spi";
+			clocks = <0x7 0x2>;
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x1 0x1d>;
+			#size-cells = <0x0>;
+			reg = <0x7e2150c0 0x40>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		act {
+			gpios = <0x11 0x2f 0x0>;
+			label = "ACT";
+			default-state = "keep";
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	aliases {
+		ethernet = "/soc/usb@7e980000/usb1@1/usbether@1";
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200 console=tty0 root=PARTUUID=08d5518c-02 rw rootwait smsc95xx.macaddr=01:02:03:04:05:06";
+		linux,initrd-start = ":wP";
+		linux,initrd-end = <0x3ab2d71e>;
+	};
+
+	framebuffer@3daf0000 {
+		compatible = "simple-framebuffer";
+		width = <0x290>;
+		stride = <0xa40>;
+		status = "okay";
+		reg = <0x3daf0000 0x10a800>;
+		format = "a8r8g8b8";
+		height = <0x1a0>;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		always-on;
+		interrupt-parent = <0x2>;
+		interrupts = <0x0 0x1 0x3 0x2>;
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x3b000000>;
+	};
+
+	cpus {
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+
+		cpu@3 {
+			compatible = "arm,cortex-a53";
+			cpu-release-addr = <0x0 0xf0>;
+			device_type = "cpu";
+			enable-method = "spin-table";
+			reg = <0x3>;
+		};
+
+		cpu@1 {
+			compatible = "arm,cortex-a53";
+			cpu-release-addr = <0x0 0xe0>;
+			device_type = "cpu";
+			enable-method = "spin-table";
+			reg = <0x1>;
+		};
+
+		cpu@2 {
+			compatible = "arm,cortex-a53";
+			cpu-release-addr = <0x0 0xe8>;
+			device_type = "cpu";
+			enable-method = "spin-table";
+			reg = <0x2>;
+		};
+
+		cpu@0 {
+			compatible = "arm,cortex-a53";
+			cpu-release-addr = <0x0 0xd8>;
+			device_type = "cpu";
+			enable-method = "spin-table";
+			reg = <0x0>;
+		};
+	};
+};
diff --git a/test/data/rpi3_raspbian.dts b/test/data/rpi3_raspbian.dts
new file mode 100644
index 0000000..9d6bf63
--- /dev/null
+++ b/test/data/rpi3_raspbian.dts
@@ -0,0 +1,892 @@
+/dts-v1/;
+
+/ {
+	compatible = "brcm,bcm2837", "brcm,bcm2836";
+	serial-number = "00000000d544ea12";
+	model = "Raspberry Pi 3 Model B Rev 1.2";
+	memreserve = <0x3b000000 0x4000000>;
+	interrupt-parent = <0x1>;
+	#address-cells = <0x1>;
+	#size-cells = <0x1>;
+
+	clocks {
+		compatible = "simple-bus";
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+
+		clock@3 {
+			compatible = "fixed-clock";
+			#clock-cells = <0x0>;
+			phandle = <0x3>;
+			reg = <0x3>;
+			clock-output-names = "osc";
+			clock-frequency = <0x124f800>;
+		};
+
+		clock@4 {
+			compatible = "fixed-clock";
+			#clock-cells = <0x0>;
+			phandle = <0x16>;
+			reg = <0x4>;
+			clock-output-names = "otg";
+			clock-frequency = <0x1c9c3800>;
+		};
+	};
+
+	__overrides__ {
+		pwr_led_gpio = "", "", "", "(gpios:4";
+		i2c1 = "", "", "", "&status";
+		i2c_vc = "", "", "", "%status";
+		sd_overclock = "", "", "", ",brcm,overclock-50:0";
+		i2c0_baudrate = "", "", "", "%clock-frequency:0";
+		sd_pio_limit = "", "", "", ",brcm,pio-limit:0";
+		act_led_trigger = "", "", "", "'linux,default-trigger";
+		audio = "", "", "", ")status";
+		sd_debug = "", "", "", ",brcm,debug";
+		cache_line_size = [00 00 00 1c 63 61 63 68 65 2d 6c 69 6e 65 2d 73 69 7a 65 3a 30 00];
+		i2c1_baudrate = "", "", "", "&clock-frequency:0";
+		spi = "", "", "", "$status";
+		i2c_arm = "", "", "", "&status";
+		pwr_led_activelow = "", "", "", "(gpios:8";
+		uart0 = "", "", "", "!status";
+		i2c2_iknowwhatimdoing = [00 00 00 14 73 74 61 74 75 73 00];
+		i2s = "", "", "", "#status";
+		i2c0 = "", "", "", "%status";
+		arm_freq = <0x1d 0x636c6f63 0x6b2d6672 0x65717565 0x6e63793a 0x30000000 0x1e636c 0x6f636b2d 0x66726571 0x75656e63 0x793a3000 0x1f 0x636c6f63 0x6b2d6672 0x65717565 0x6e63793a 0x30000000 0x20636c 0x6f636b2d 0x66726571 0x75656e63 0x793a3000>;
+		watchdog = "", "", "", "*status";
+		i2c_baudrate = "", "", "", "&clock-frequency:0";
+		i2c_vc_baudrate = "", "", "", "%clock-frequency:0";
+		act_led_activelow = "", "", "", "'gpios:8";
+		i2c2_baudrate = [00 00 00 14 63 6c 6f 63 6b 2d 66 72 65 71 75 65 6e 63 79 3a 30 00];
+		sd_force_pio = "", "", "", ",brcm,force-pio?";
+		pwr_led_trigger = "", "", "", "(linux,default-trigger";
+		uart1 = "", "", "", "\"status";
+		i2c_arm_baudrate = "", "", "", "&clock-frequency:0";
+		random = "", "", "", "+status";
+		act_led_gpio = "", "", "", "'gpios:4";
+		i2c = "", "", "", "&status";
+	};
+
+	system {
+		linux,serial = <0x0 0xd5442118>;
+		linux,revision = <0xa02082>;
+	};
+
+	__symbols__ {
+		pwm = "/soc/pwm@7e20c000";
+		clk_usb = "/clocks/clock@4";
+		pixelvalve0 = "/soc/pixelvalve@7e206000";
+		intc = "/soc/interrupt-controller@7e00b200";
+		spi2 = "/soc/spi@7e2150c0";
+		dsi1 = "/soc/dsi@7e700000";
+		clocks = "/soc/cprman@7e101000";
+		i2c1 = "/soc/i2c@7e804000";
+		i2c_vc = "/soc/i2c@7e205000";
+		firmwarekms = "/soc/firmwarekms@7e600000";
+		smi = "/soc/smi@7e600000";
+		gpu = "/soc/gpu";
+		spi0 = "/soc/spi@7e204000";
+		thermal = "/soc/thermal";
+		vdd_5v0_reg = "/fixedregulator_5v0";
+		vchiq = "/soc/vchiq";
+		sdhost = "/soc/sdhost@7e202000";
+		aux = "/soc/aux@0x7e215000";
+		gpio = "/soc/gpio@7e200000";
+		dpi = "/soc/dpi@7e208000";
+		v3d = "/soc/v3d@7ec00000";
+		audio = "/soc/audio";
+		vdd_3v3_reg = "/fixedregulator_3v3";
+		dma = "/soc/dma@7e007000";
+		spidev1 = "/soc/spi@7e204000/spidev@1";
+		v7_cpu3 = "/cpus/cpu@3";
+		vc4 = "/soc/gpu";
+		power = "/soc/power";
+		soc = "/soc";
+		v7_cpu1 = "/cpus/cpu@1";
+		leds = "/leds";
+		i2s_pins = "/soc/gpio@7e200000/i2s";
+		firmware = "/soc/firmware";
+		cprman = "/soc/cprman@7e101000";
+		mmc = "/soc/mmc@7e300000";
+		pixelvalve1 = "/soc/pixelvalve@7e207000";
+		spi = "/soc/spi@7e204000";
+		spi0_pins = "/soc/gpio@7e200000/spi0_pins";
+		pitouchscreen_touch = "/soc/i2cdsi/bridge@38";
+		i2c_arm = "/soc/i2c@7e804000";
+		clk_osc = "/clocks/clock@3";
+		ethernet = "/soc/usb@7e980000/usb1@1/usbether@1";
+		uart0 = "/soc/serial@7e201000";
+		i2c1_pins = "/soc/gpio@7e200000/i2c1";
+		fb = "/soc/fb";
+		sdhost_pins = "/soc/gpio@7e200000/sdhost_pins";
+		i2c2 = "/soc/i2c@7e805000";
+		uart1_pins = "/soc/gpio@7e200000/uart1_pins";
+		i2s = "/soc/i2s@7e203000";
+		spi1 = "/soc/spi@7e215080";
+		virtgpio = "/soc/virtgpio";
+		usb = "/soc/usb@7e980000";
+		dsi0 = "/soc/dsi@7e209000";
+		expgpio = "/soc/expgpio";
+		audio_pins = "/soc/gpio@7e200000/audio_pins";
+		i2c0 = "/soc/i2c@7e205000";
+		i2c0_pins = "/soc/gpio@7e200000/i2c0";
+		pwr_led = "/leds/pwr";
+		watchdog = "/soc/watchdog@7e100000";
+		uart0_pins = "/soc/gpio@7e200000/uart0_pins";
+		vec = "/soc/vec@7e806000";
+		local_intc = "/soc/local_intc";
+		i2c_dsi = "/soc/i2cdsi";
+		pitouchscreen_bridge = "/soc/i2cdsi/bridge@45";
+		spi0_cs_pins = "/soc/gpio@7e200000/spi0_cs_pins";
+		sound = "/soc/sound";
+		hvs = "/soc/hvs@7e400000";
+		act_led = "/leds/act";
+		spidev0 = "/soc/spi@7e204000/spidev@0";
+		v7_cpu2 = "/cpus/cpu@2";
+		bt_pins = "/soc/gpio@7e200000/bt_pins";
+		sdio_pins = "/soc/gpio@7e200000/sdio_pins";
+		cpus = "/cpus";
+		hdmi = "/soc/hdmi@7e902000";
+		pixelvalve2 = "/soc/pixelvalve@7e807000";
+		v7_cpu0 = "/cpus/cpu@0";
+		mailbox = "/soc/mailbox@7e00b880";
+		uart1 = "/soc/serial@7e215040";
+		random = "/soc/rng@7e104000";
+		i2c = "/soc/i2c@7e804000";
+	};
+
+	soc {
+		compatible = "simple-bus";
+		ranges = <0x7e000000 0x3f000000 0x1000000 0x40000000 0x40000000 0x40000>;
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		phandle = <0x2d>;
+		dma-ranges = <0xc0000000 0x0 0x3f000000>;
+
+		serial@7e201000 {
+			compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
+			clocks = <0x7 0x13 0x7 0x14>;
+			clock-names = "uartclk", "apb_pclk";
+			status = "okay";
+			interrupts = <0x2 0x19>;
+			phandle = <0x21>;
+			arm,primecell-periphid = <0x241011>;
+			reg = <0x7e201000 0x1000>;
+			pinctrl-0 = <0x8 0x9>;
+			pinctrl-names = "default";
+		};
+
+		pixelvalve@7e207000 {
+			compatible = "brcm,bcm2835-pixelvalve1";
+			status = "disabled";
+			interrupts = <0x2 0xe>;
+			phandle = <0x31>;
+			reg = <0x7e207000 0x100>;
+		};
+
+		cprman@7e101000 {
+			compatible = "brcm,bcm2835-cprman";
+			clocks = <0x3 0x4 0x0 0x4 0x1 0x4 0x2 0x5 0x0 0x5 0x1 0x5 0x2>;
+			firmware = <0x6>;
+			#clock-cells = <0x1>;
+			phandle = <0x7>;
+			reg = <0x7e101000 0x2000>;
+		};
+
+		hvs@7e400000 {
+			compatible = "brcm,bcm2835-hvs";
+			status = "disabled";
+			interrupts = <0x2 0x1>;
+			phandle = <0x35>;
+			reg = <0x7e400000 0x6000>;
+		};
+
+		gpio@7e200000 {
+			compatible = "brcm,bcm2835-gpio";
+			gpio-controller;
+			#interrupt-cells = <0x2>;
+			interrupts = <0x2 0x11 0x2 0x12>;
+			phandle = <0xc>;
+			reg = <0x7e200000 0xb4>;
+			#gpio-cells = <0x2>;
+			interrupt-controller;
+
+			i2c1 {
+				brcm,pins = <0x2 0x3>;
+				phandle = <0x13>;
+				brcm,function = <0x4>;
+			};
+
+			spi0_pins {
+				brcm,pins = <0x9 0xa 0xb>;
+				phandle = <0xd>;
+				brcm,function = <0x4>;
+			};
+
+			sdhost_pins {
+				brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>;
+				phandle = <0x17>;
+				brcm,function = <0x4>;
+			};
+
+			uart1_pins {
+				brcm,pins;
+				phandle = <0x11>;
+				brcm,pull;
+				brcm,function;
+			};
+
+			i2s {
+				brcm,pins = <0x12 0x13 0x14 0x15>;
+				phandle = <0xb>;
+				brcm,function = <0x4>;
+			};
+
+			audio_pins {
+				brcm,pins = <0x28 0x29>;
+				phandle = <0x1a>;
+				brcm,function = <0x4>;
+			};
+
+			i2c0 {
+				brcm,pins = <0x0 0x1>;
+				phandle = <0xf>;
+				brcm,function = <0x4>;
+			};
+
+			uart0_pins {
+				brcm,pins = <0x20 0x21>;
+				phandle = <0x8>;
+				brcm,pull = <0x0 0x2>;
+				brcm,function = <0x7>;
+			};
+
+			spi0_cs_pins {
+				brcm,pins = <0x8 0x7>;
+				phandle = <0xe>;
+				brcm,function = <0x1>;
+			};
+
+			bt_pins {
+				brcm,pins = <0x2b>;
+				phandle = <0x9>;
+				brcm,pull = <0x0>;
+				brcm,function = <0x4>;
+			};
+
+			sdio_pins {
+				brcm,pins = <0x22 0x23 0x24 0x25 0x26 0x27>;
+				phandle = <0x18>;
+				brcm,pull = <0x0 0x2 0x2 0x2 0x2 0x2>;
+				brcm,function = <0x7>;
+			};
+		};
+
+		pixelvalve@7e807000 {
+			compatible = "brcm,bcm2835-pixelvalve2";
+			status = "disabled";
+			interrupts = <0x2 0xa>;
+			phandle = <0x37>;
+			reg = <0x7e807000 0x100>;
+		};
+
+		v3d@7ec00000 {
+			power-domains = <0x12 0xa>;
+			compatible = "brcm,vc4-v3d";
+			status = "disabled";
+			interrupts = <0x1 0xa>;
+			phandle = <0x3b>;
+			reg = <0x7ec00000 0x1000>;
+		};
+
+		gpu {
+			compatible = "brcm,bcm2835-vc4";
+			status = "disabled";
+			phandle = <0x3c>;
+		};
+
+		mmc@7e300000 {
+			compatible = "brcm,bcm2835-mmc";
+			clocks = <0x7 0x1c>;
+			status = "okay";
+			interrupts = <0x2 0x1e>;
+			brcm,overclock-50 = <0x0>;
+			bus-width = <0x4>;
+			dma-names = "rx-tx";
+			phandle = <0x3e>;
+			reg = <0x7e300000 0x100>;
+			pinctrl-0 = <0x18>;
+			dmas = <0xa 0xb>;
+			non-removable;
+			pinctrl-names = "default";
+		};
+
+		arm-pmu {
+			compatible = "arm,cortex-a7-pmu";
+			interrupt-parent = <0x2>;
+			interrupts = <0x9>;
+		};
+
+		thermal {
+			compatible = "brcm,bcm2835-thermal";
+			firmware = <0x6>;
+			phandle = <0x45>;
+		};
+
+		spi@7e204000 {
+			compatible = "brcm,bcm2835-spi";
+			clocks = <0x7 0x14>;
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x16>;
+			cs-gpios = <0xc 0x8 0x1 0xc 0x7 0x1>;
+			#size-cells = <0x0>;
+			dma-names = "tx", "rx";
+			phandle = <0x24>;
+			reg = <0x7e204000 0x1000>;
+			pinctrl-0 = <0xd 0xe>;
+			dmas = <0xa 0x6 0xa 0x7>;
+			pinctrl-names = "default";
+
+			spidev@1 {
+				compatible = "spidev";
+				#address-cells = <0x1>;
+				#size-cells = <0x0>;
+				phandle = <0x2f>;
+				reg = <0x1>;
+				spi-max-frequency = <0x7a120>;
+			};
+
+			spidev@0 {
+				compatible = "spidev";
+				#address-cells = <0x1>;
+				#size-cells = <0x0>;
+				phandle = <0x2e>;
+				reg = <0x0>;
+				spi-max-frequency = <0x7a120>;
+			};
+		};
+
+		i2cdsi {
+			gpios = <0xc 0x2c 0x0 0xc 0x2d 0x0>;
+			compatible = "i2c-gpio";
+			status = "disabled";
+			#address-cells = <0x1>;
+			#size-cells = <0x0>;
+			phandle = <0x41>;
+
+			bridge@45 {
+				compatible = "raspberrypi,touchscreen-bridge-i2c";
+				phandle = <0x42>;
+				reg = <0x45>;
+			};
+
+			bridge@38 {
+				compatible = "raspberrypi,touchscreen-ts-i2c";
+				phandle = <0x43>;
+				reg = <0x38>;
+			};
+		};
+
+		vchiq {
+			compatible = "brcm,bcm2835-vchiq";
+			cache-line-size = <0x40>;
+			firmware = <0x6>;
+			interrupts = <0x0 0x2>;
+			phandle = <0x1c>;
+			reg = <0x7e00b840 0xf>;
+		};
+
+		i2c@7e804000 {
+			compatible = "brcm,bcm2835-i2c";
+			clocks = <0x7 0x14>;
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x15>;
+			#size-cells = <0x0>;
+			phandle = <0x26>;
+			reg = <0x7e804000 0x1000>;
+			clock-frequency = <0x186a0>;
+			pinctrl-0 = <0x13>;
+			pinctrl-names = "default";
+		};
+
+		audio {
+			brcm,pwm-channels = <0x8>;
+			compatible = "brcm,bcm2835-audio";
+			status = "okay";
+			phandle = <0x29>;
+			pinctrl-0 = <0x1a>;
+			pinctrl-names = "default";
+		};
+
+		i2s@7e203000 {
+			compatible = "brcm,bcm2835-i2s";
+			clocks = <0x7 0x1f>;
+			#sound-dai-cells = <0x0>;
+			status = "disabled";
+			dma-names = "tx", "rx";
+			phandle = <0x23>;
+			reg = <0x7e203000 0x24>;
+			pinctrl-0 = <0xb>;
+			dmas = <0xa 0x2 0xa 0x3>;
+			pinctrl-names = "default";
+		};
+
+		mailbox@7e00b880 {
+			compatible = "brcm,bcm2835-mbox";
+			#mbox-cells = <0x0>;
+			interrupts = <0x0 0x1>;
+			phandle = <0x19>;
+			reg = <0x7e00b880 0x40>;
+		};
+
+		gpiomem {
+			compatible = "brcm,bcm2835-gpiomem";
+			reg = <0x7e200000 0x1000>;
+		};
+
+		vec@7e806000 {
+			compatible = "brcm,bcm2835-vec";
+			clocks = <0x7 0x18>;
+			status = "disabled";
+			interrupts = <0x2 0x1b>;
+			phandle = <0x36>;
+			reg = <0x7e806000 0x1000>;
+		};
+
+		power {
+			compatible = "raspberrypi,bcm2835-power";
+			firmware = <0x6>;
+			phandle = <0x12>;
+			#power-domain-cells = <0x1>;
+		};
+
+		pixelvalve@7e206000 {
+			compatible = "brcm,bcm2835-pixelvalve0";
+			status = "disabled";
+			interrupts = <0x2 0xd>;
+			phandle = <0x30>;
+			reg = <0x7e206000 0x100>;
+		};
+
+		firmware {
+			compatible = "raspberrypi,bcm2835-firmware";
+			mboxes = <0x19>;
+			phandle = <0x6>;
+		};
+
+		dsi@7e209000 {
+			compatible = "brcm,bcm2835-dsi0";
+			clocks = <0x7 0x20 0x7 0x2f 0x7 0x31>;
+			clock-names = "phy", "escape", "pixel";
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x4>;
+			#size-cells = <0x0>;
+			#clock-cells = <0x1>;
+			phandle = <0x4>;
+			reg = <0x7e209000 0x78>;
+			clock-output-names = "dsi0_byte", "dsi0_ddr2", "dsi0_ddr";
+		};
+
+		fb {
+			compatible = "brcm,bcm2708-fb";
+			firmware = <0x6>;
+			status = "okay";
+			phandle = <0x44>;
+		};
+
+		sdhost@7e202000 {
+			compatible = "brcm,bcm2835-sdhost";
+			clocks = <0x7 0x14>;
+			brcm,pio-limit = <0x1>;
+			status = "okay";
+			interrupts = <0x2 0x18>;
+			brcm,overclock-50 = <0x0>;
+			bus-width = <0x4>;
+			dma-names = "rx-tx";
+			phandle = <0x2c>;
+			reg = <0x7e202000 0x100>;
+			pinctrl-0 = <0x17>;
+			dmas = <0xa 0xd>;
+			pinctrl-names = "default";
+		};
+
+		virtgpio {
+			compatible = "brcm,bcm2835-virtgpio";
+			gpio-controller;
+			firmware = <0x6>;
+			status = "okay";
+			phandle = <0x1b>;
+			#gpio-cells = <0x2>;
+		};
+
+		dpi@7e208000 {
+			compatible = "brcm,bcm2835-dpi";
+			clocks = <0x7 0x14 0x7 0x2c>;
+			clock-names = "core", "pixel";
+			status = "disabled";
+			#address-cells = <0x1>;
+			#size-cells = <0x0>;
+			phandle = <0x3d>;
+			reg = <0x7e208000 0x8c>;
+		};
+
+		expgpio {
+			compatible = "brcm,bcm2835-expgpio";
+			gpio-controller;
+			firmware = <0x6>;
+			status = "okay";
+			phandle = <0x15>;
+			#gpio-cells = <0x2>;
+		};
+
+		hdmi@7e902000 {
+			power-domains = <0x12 0x5>;
+			compatible = "brcm,bcm2835-hdmi";
+			clocks = <0x7 0x10 0x7 0x19>;
+			clock-names = "pixel", "hdmi";
+			ddc = <0x14>;
+			status = "disabled";
+			interrupts = <0x2 0x8 0x2 0x9>;
+			dma-names = "audio-rx";
+			phandle = <0x38>;
+			hpd-gpios = <0x15 0x4 0x1>;
+			reg = <0x7e902000 0x600 0x7e808000 0x100>;
+			dmas = <0xa 0x11>;
+		};
+
+		timer {
+			compatible = "arm,armv7-timer";
+			always-on;
+			interrupt-parent = <0x2>;
+			interrupts = <0x0 0x1 0x3 0x2>;
+		};
+
+		pwm@7e20c000 {
+			compatible = "brcm,bcm2835-pwm";
+			clocks = <0x7 0x1e>;
+			status = "disabled";
+			assigned-clock-rates = <0x989680>;
+			assigned-clocks = <0x7 0x1e>;
+			phandle = <0x34>;
+			reg = <0x7e20c000 0x28>;
+			#pwm-cells = <0x2>;
+		};
+
+		watchdog@7e100000 {
+			compatible = "brcm,bcm2835-pm-wdt";
+			phandle = <0x2a>;
+			reg = <0x7e100000 0x28>;
+		};
+
+		interrupt-controller@7e00b200 {
+			compatible = "brcm,bcm2836-armctrl-ic";
+			#interrupt-cells = <0x2>;
+			interrupt-parent = <0x2>;
+			interrupts = <0x8>;
+			phandle = <0x1>;
+			reg = <0x7e00b200 0x200>;
+			interrupt-controller;
+		};
+
+		local_intc {
+			compatible = "brcm,bcm2836-l1-intc";
+			#interrupt-cells = <0x1>;
+			interrupt-parent = <0x2>;
+			phandle = <0x2>;
+			reg = <0x40000000 0x100>;
+			interrupt-controller;
+		};
+
+		dsi@7e700000 {
+			power-domains = <0x12 0x12>;
+			compatible = "brcm,bcm2835-dsi1";
+			clocks = <0x7 0x23 0x7 0x30 0x7 0x32>;
+			clock-names = "phy", "escape", "pixel";
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0xc>;
+			#size-cells = <0x0>;
+			#clock-cells = <0x1>;
+			phandle = <0x5>;
+			reg = <0x7e700000 0x8c>;
+			clock-output-names = "dsi1_byte", "dsi1_ddr2", "dsi1_ddr";
+		};
+
+		sound {
+			status = "disabled";
+			phandle = <0x46>;
+		};
+
+		i2c@7e205000 {
+			compatible = "brcm,bcm2835-i2c";
+			clocks = <0x7 0x14>;
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x15>;
+			#size-cells = <0x0>;
+			phandle = <0x25>;
+			reg = <0x7e205000 0x1000>;
+			clock-frequency = <0x186a0>;
+			pinctrl-0 = <0xf>;
+			pinctrl-names = "default";
+		};
+
+		serial@7e215040 {
+			compatible = "brcm,bcm2835-aux-uart";
+			clocks = <0x10 0x0>;
+			status = "disabled";
+			interrupt-parent = <0x10>;
+			interrupts = <0x0>;
+			phandle = <0x22>;
+			reg = <0x7e215040 0x40>;
+			pinctrl-0 = <0x11>;
+			pinctrl-names = "default";
+		};
+
+		dma@7e007000 {
+			#dma-cells = <0x1>;
+			compatible = "brcm,bcm2835-dma";
+			brcm,dma-channel-mask = <0x7f34>;
+			interrupts = <0x1 0x10 0x1 0x11 0x1 0x12 0x1 0x13 0x1 0x14 0x1 0x15 0x1 0x16 0x1 0x17 0x1 0x18 0x1 0x19 0x1 0x1a 0x1 0x1b 0x1 0x1b 0x1 0x1b 0x1 0x1b 0x1 0x1c>;
+			phandle = <0xa>;
+			reg = <0x7e007000 0xf00>;
+			interrupt-names = "dma0", "dma1", "dma2", "dma3", "dma4", "dma5", "dma6", "dma7", "dma8", "dma9", "dma10", "dma11", "dma12", "dma13", "dma14", "dma-shared-all";
+		};
+
+		i2c@7e805000 {
+			compatible = "brcm,bcm2835-i2c";
+			clocks = <0x7 0x14>;
+			status = "disabled";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x15>;
+			#size-cells = <0x0>;
+			phandle = <0x14>;
+			reg = <0x7e805000 0x1000>;
+			clock-frequency = <0x186a0>;
+		};
+
+		spi@7e215080 {
+			compatible = "brcm,bcm2835-aux-spi";
+			clocks = <0x10 0x1>;
+			status = "disabled";
+			interrupt-parent = <0x10>;
+			#address-cells = <0x1>;
+			interrupts = <0x1>;
+			#size-cells = <0x0>;
+			phandle = <0x32>;
+			reg = <0x7e215080 0x40>;
+		};
+
+		aux@0x7e215000 {
+			compatible = "brcm,bcm2835-aux";
+			clocks = <0x7 0x14>;
+			#interrupt-cells = <0x1>;
+			interrupts = <0x1 0x1d>;
+			#clock-cells = <0x1>;
+			phandle = <0x10>;
+			reg = <0x7e215000 0x8>;
+			interrupt-controller;
+		};
+
+		firmwarekms@7e600000 {
+			compatible = "raspberrypi,rpi-firmware-kms";
+			status = "disabled";
+			interrupts = <0x2 0x10>;
+			brcm,firmware = <0x6>;
+			phandle = <0x3f>;
+			reg = <0x7e600000 0x100>;
+		};
+
+		rng@7e104000 {
+			compatible = "brcm,bcm2835-rng";
+			phandle = <0x2b>;
+			reg = <0x7e104000 0x10>;
+		};
+
+		syscon@40000000 {
+			compatible = "brcm,bcm2836-arm-local", "syscon";
+			reg = <0x40000000 0x100>;
+		};
+
+		usb@7e980000 {
+			power-domains = <0x12 0x6>;
+			compatible = "brcm,bcm2708-usb";
+			clocks = <0x16>;
+			clock-names = "otg";
+			#address-cells = <0x1>;
+			interrupts = <0x2 0x0 0x1 0x9>;
+			#size-cells = <0x0>;
+			phandle = <0x39>;
+			reg = <0x7e980000 0x10000 0x7e006000 0x1000>;
+
+			usb1@1 {
+				compatible = "usb424,9514";
+				#address-cells = <0x1>;
+				#size-cells = <0x0>;
+				reg = <0x1>;
+
+				usbether@1 {
+					compatible = "usb424,ec00";
+					local-mac-address = [04 05 06 01 02 03];
+					phandle = <0x3a>;
+					reg = <0x1>;
+				};
+			};
+		};
+
+		smi@7e600000 {
+			compatible = "brcm,bcm2835-smi";
+			clocks = <0x7 0x2a>;
+			status = "disabled";
+			interrupts = <0x2 0x10>;
+			assigned-clock-rates = <0x7735940>;
+			dma-names = "rx-tx";
+			assigned-clocks = <0x7 0x2a>;
+			phandle = <0x40>;
+			reg = <0x7e600000 0x100>;
+			dmas = <0xa 0x4>;
+		};
+
+		spi@7e2150c0 {
+			compatible = "brcm,bcm2835-aux-spi";
+			clocks = <0x10 0x2>;
+			status = "disabled";
+			interrupt-parent = <0x10>;
+			#address-cells = <0x1>;
+			interrupts = <0x2>;
+			#size-cells = <0x0>;
+			phandle = <0x33>;
+			reg = <0x7e2150c0 0x40>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		phandle = <0x49>;
+
+		act {
+			gpios = <0x1b 0x0 0x0>;
+			label = "led0";
+			phandle = <0x27>;
+			linux,default-trigger = "mmc0";
+		};
+
+		pwr {
+			gpios = <0x15 0x7 0x0>;
+			label = "led1";
+			phandle = <0x28>;
+			linux,default-trigger = "input";
+		};
+	};
+
+	aliases {
+		intc = "/soc/interrupt-controller@7e00b200";
+		spi2 = "/soc/spi@7e2150c0";
+		i2c1 = "/soc/i2c@7e804000";
+		i2c_vc = "/soc/i2c@7e205000";
+		spi0 = "/soc/spi@7e204000";
+		thermal = "/soc/thermal";
+		vchiq = "/soc/vchiq";
+		sdhost = "/soc/sdhost@7e202000";
+		aux = "/soc/aux@0x7e215000";
+		gpio = "/soc/gpio@7e200000";
+		audio = "/soc/audio";
+		dma = "/soc/dma@7e007000";
+		soc = "/soc";
+		leds = "/leds";
+		mmc = "/soc/mmc@7e300000";
+		serial1 = "/soc/serial@7e201000";
+		i2c_arm = "/soc/i2c@7e804000";
+		ethernet = "/soc/usb@7e980000/usb1@1/usbether@1";
+		uart0 = "/soc/serial@7e201000";
+		fb = "/soc/fb";
+		i2c2 = "/soc/i2c@7e805000";
+		i2s = "/soc/i2s@7e203000";
+		spi1 = "/soc/spi@7e215080";
+		usb = "/soc/usb@7e980000";
+		i2c0 = "/soc/i2c@7e205000";
+		watchdog = "/soc/watchdog@7e100000";
+		sound = "/soc/sound";
+		mailbox = "/soc/mailbox@7e00b880";
+		uart1 = "/soc/serial@7e215040";
+		random = "/soc/rng@7e104000";
+		i2c = "/soc/i2c@7e804000";
+		serial0 = "/soc/serial@7e215040";
+	};
+
+	chosen {
+		bootargs = "8250.nr_uarts=0 bcm2708_fb.fbwidth=640 bcm2708_fb.fbheight=480 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3dc00000 vc_mem.mem_size=0x3f000000  dwc_otg.lpm_enable=0 console=ttyS0,115200 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait";
+		kaslr-seed = <0xef42e779 0x662d8187>;
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x3b000000>;
+	};
+
+	fixedregulator_3v3 {
+		compatible = "regulator-fixed";
+		phandle = <0x48>;
+		regulator-min-microvolt = <0x325aa0>;
+		regulator-max-microvolt = <0x325aa0>;
+		regulator-always-on;
+		regulator-name = "3v3";
+	};
+
+	cpus {
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+		phandle = <0x4a>;
+
+		cpu@3 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			phandle = <0x20>;
+			reg = <0x3>;
+			clock-frequency = <0x47868c00>;
+		};
+
+		cpu@1 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			phandle = <0x1e>;
+			reg = <0x1>;
+			clock-frequency = <0x47868c00>;
+		};
+
+		cpu@2 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			phandle = <0x1f>;
+			reg = <0x2>;
+			clock-frequency = <0x47868c00>;
+		};
+
+		cpu@0 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			phandle = <0x1d>;
+			reg = <0x0>;
+			clock-frequency = <0x47868c00>;
+		};
+	};
+
+	fixedregulator_5v0 {
+		compatible = "regulator-fixed";
+		phandle = <0x47>;
+		regulator-min-microvolt = <0x4c4b40>;
+		regulator-max-microvolt = <0x4c4b40>;
+		regulator-always-on;
+		regulator-name = "5v0";
+	};
+
+	axi {
+
+		vc_mem {
+			reg = <0x3dc00000 0x3f000000 0xc0000000>;
+		};
+	};
+};
diff --git a/test/data/s390_hurcules_cpuinfo b/test/data/s390_hurcules_cpuinfo
new file mode 100644
index 0000000..722678f
--- /dev/null
+++ b/test/data/s390_hurcules_cpuinfo
@@ -0,0 +1,5 @@
+vendor_id       : IBM/S390
+# processors    : 2
+bogomips per cpu: 411.23
+processor 0: version = FF, identification = 111000,  machine = 7060
+processor 1: version = FF, identification = 111111, machine = 7060
diff --git a/test/data/sh_dreamcast_cpuinfo b/test/data/sh_dreamcast_cpuinfo
new file mode 100644
index 0000000..84e9dd9
--- /dev/null
+++ b/test/data/sh_dreamcast_cpuinfo
@@ -0,0 +1,9 @@
+machine         : Sega Dreamcast
+processor       : 0
+cpu family      : sh4
+cpu type        : SH7750
+cache size      : 8K-bytes/16K-bytes
+bogomips        : 199.06
+cpu clock       : 199.49MHz
+bus clock       : 99.74MHz
+module clock : 49.87MHz
diff --git a/test/data/sh_sh3_cpuinfo b/test/data/sh_sh3_cpuinfo
new file mode 100644
index 0000000..a9389be
--- /dev/null
+++ b/test/data/sh_sh3_cpuinfo
@@ -0,0 +1,4 @@
+cpu family      : SH-3
+cache size      : 8K-byte
+bogomips : 39.83
+
diff --git a/test/data/sh_sh64_cpuinfo b/test/data/sh_sh64_cpuinfo
new file mode 100644
index 0000000..ba869c4
--- /dev/null
+++ b/test/data/sh_sh64_cpuinfo
@@ -0,0 +1,13 @@
+machine         : Hitachi Cayman
+processor       : 0
+cpu family      : SH-5
+cpu type        : SH5-101
+icache size     : 32K-bytes
+dcache size     : 32K-bytes
+itlb entries    : 64
+dtlb entries    : 64
+cpu clock       : 314.73MHz
+bus clock       : 157.36MHz
+module clock    : 26.22MHz
+bogomips : 313.75
+
diff --git a/test/data/sparc_m7_cpuinfo b/test/data/sparc_m7_cpuinfo
new file mode 100644
index 0000000..b3556e3
--- /dev/null
+++ b/test/data/sparc_m7_cpuinfo
@@ -0,0 +1,45 @@
+cpu             : SPARC-M7
+fpu             : SPARC-M7 integrated FPU
+pmu             : sparc-m7
+prom            : OBP 4.40.1 2016/04/25 06:45
+type            : sun4v
+ncpus probed    : 16
+ncpus active    : 16
+D$ parity tl1   : 0
+I$ parity tl1   : 0
+cpucaps         : flush,stbar,swap,muldiv,v9,blkinit,n2,mul32,div32,v8plus,popc,vis,vis2,ASIBlkInit,fmaf,vis3,hpc,ima,pause,cbcond,adp,aes,des,camellia,md5,sha1,sha256,sha512,mpmul,montmul,montsqr,crc32c
+Cpu0ClkTck      : 00000000f65c15b0
+Cpu1ClkTck      : 00000000f65c15b0
+Cpu2ClkTck      : 00000000f65c15b0
+Cpu3ClkTck      : 00000000f65c15b0
+Cpu4ClkTck      : 00000000f65c15b0
+Cpu5ClkTck      : 00000000f65c15b0
+Cpu6ClkTck      : 00000000f65c15b0
+Cpu7ClkTck      : 00000000f65c15b0
+Cpu8ClkTck      : 00000000f65c15b0
+Cpu9ClkTck      : 00000000f65c15b0
+Cpu10ClkTck     : 00000000f65c15b0
+Cpu11ClkTck     : 00000000f65c15b0
+Cpu12ClkTck     : 00000000f65c15b0
+Cpu13ClkTck     : 00000000f65c15b0
+Cpu14ClkTck     : 00000000f65c15b0
+Cpu15ClkTck     : 00000000f65c15b0
+MMU Type        : Hypervisor (sun4v)
+MMU PGSZs       : 8K,64K,4MB,256MB,2GB,16GB
+State:
+CPU0:           online
+CPU1:           online
+CPU2:           online
+CPU3:           online
+CPU4:           online
+CPU5:           online
+CPU6:           online
+CPU7:           online
+CPU8:           online
+CPU9:           online
+CPU10:          online
+CPU11:          online
+CPU12:          online
+CPU13:          online
+CPU14:          online
+CPU15:          online
diff --git a/test/data/x86_amdr7_cpuinfo b/test/data/x86_amdr7_cpuinfo
new file mode 100644
index 0000000..ba52761
--- /dev/null
+++ b/test/data/x86_amdr7_cpuinfo
@@ -0,0 +1,447 @@
+processor	: 0
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 0
+cpu cores	: 8
+apicid		: 0
+initial apicid	: 0
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 1
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 0
+cpu cores	: 8
+apicid		: 1
+initial apicid	: 1
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 2
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 1
+cpu cores	: 8
+apicid		: 2
+initial apicid	: 2
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 3
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 1
+cpu cores	: 8
+apicid		: 3
+initial apicid	: 3
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 4
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 2
+cpu cores	: 8
+apicid		: 4
+initial apicid	: 4
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 5
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 2
+cpu cores	: 8
+apicid		: 5
+initial apicid	: 5
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 6
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 3
+cpu cores	: 8
+apicid		: 6
+initial apicid	: 6
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 7
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 3
+cpu cores	: 8
+apicid		: 7
+initial apicid	: 7
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 8
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 3600.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 4
+cpu cores	: 8
+apicid		: 8
+initial apicid	: 8
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 9
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 4
+cpu cores	: 8
+apicid		: 9
+initial apicid	: 9
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 10
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 5
+cpu cores	: 8
+apicid		: 10
+initial apicid	: 10
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 11
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 5
+cpu cores	: 8
+apicid		: 11
+initial apicid	: 11
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 12
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 6
+cpu cores	: 8
+apicid		: 12
+initial apicid	: 12
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 13
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 6
+cpu cores	: 8
+apicid		: 13
+initial apicid	: 13
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 14
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 7
+cpu cores	: 8
+apicid		: 14
+initial apicid	: 14
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
+
+processor	: 15
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 1
+model name	: AMD Ryzen 7 1800X Eight-Core Processor
+stepping	: 1
+microcode	: 0x8001105
+cpu MHz		: 2200.000
+cache size	: 512 KB
+physical id	: 0
+siblings	: 16
+core id		: 7
+cpu cores	: 8
+apicid		: 15
+initial apicid	: 15
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 mwaitx hw_pstate vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic overflow_recov succor smca
+bugs		: fxsave_leak sysret_ss_attrs null_seg
+bogomips	: 7186.18
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
diff --git a/test/data/x86_cyrix6x86coma_cpuinfo b/test/data/x86_cyrix6x86coma_cpuinfo
new file mode 100644
index 0000000..9080825
--- /dev/null
+++ b/test/data/x86_cyrix6x86coma_cpuinfo
@@ -0,0 +1,17 @@
+processor       : 0
+vendor_id       : CyrixInstead
+cpu family      : 5
+model           : 4
+model name      : 6x86L 2x Core/Bus Clock
+stepping        : 2
+fdiv_bug        : no
+hlt_bug         : no
+sep_bug         : no
+f00f_bug        : no
+coma_bug        : yes
+fpu             : yes
+fpu_exception   : yes
+cpuid level     : 1
+wp              : yes
+flags           : fpu de cx8 mtrr
+bogomips : 149.50
diff --git a/test/data/x86_pent_cpuinfo b/test/data/x86_pent_cpuinfo
new file mode 100644
index 0000000..e8a7ef8
--- /dev/null
+++ b/test/data/x86_pent_cpuinfo
@@ -0,0 +1,17 @@
+processor       : 0
+vendor_id       : GenuineIntel
+cpu family      : 5
+model           : 4
+model name      : Pentium MMX
+stepping        : 3
+cpu MHz         : 232.300
+fdiv_bug        : no
+hlt_bug         : no
+f00f_bug        : yes
+coma_bug        : no
+fpu             : yes
+fpu_exception   : yes
+cpuid level     : 1
+wp              : yes
+flags           : fpu vme de pse tsc msr mce cx8 mmx
+bogomips        : 465.42
diff --git a/test/data/x86_pentf00f_cpuinfo b/test/data/x86_pentf00f_cpuinfo
new file mode 100644
index 0000000..7a511dd
--- /dev/null
+++ b/test/data/x86_pentf00f_cpuinfo
@@ -0,0 +1,18 @@
+processor       : 0
+vendor_id       : GenuineIntel
+cpu family      : 5
+model           : 2
+model name      : Pentium 75 - 200
+stepping        : 12
+cpu MHz         : 133.335273
+fdiv_bug        : no
+hlt_bug         : no
+sep_bug         : no
+f00f_bug        : yes
+fpu             : yes
+fpu_exception   : yes
+cpuid level     : 1
+wp              : yes
+flags           : fpu vme de pse tsc msr mce cx8
+bogomips : 53.04
+
diff --git a/test/rm_hardinfo.sh b/test/rm_hardinfo.sh
new file mode 100644
index 0000000..8cd5807
--- /dev/null
+++ b/test/rm_hardinfo.sh
@@ -0,0 +1,30 @@
+#!bash
+
+# when you just want it all gone.
+#
+# it is not smart in any way, and will screw up your package manager
+# if hardinfo is installed as a package.
+
+if [[ $EUID -ne 0 ]]; then
+   echo "This script must be run as root."
+   exit 1
+fi
+
+remove_hardinfo() {
+  BASEDER="$1"
+  echo "Removing hardinfo from $BASEDER ..."
+  rm -rf "$BASEDER/share/hardinfo"
+  rm -rf "$BASEDER/lib/hardinfo"
+  rm -f "$BASEDER"/share/locale/*/LC_MESSAGES/hardinfo.mo
+  rm -f "$BASEDER/bin/hardinfo"
+  rm -f "$BASEDER/share/applications/hardinfo.desktop"
+  rm -f "$BASEDER/share/doc/hardinfo"
+  rm -f "$BASEDER/share/man/man1/hardinfo.1.gz"
+  rm -f "$BASEDER/share/pixmaps/hardinfo.xpm"
+  rm -f "$BASEDER/share/menu/hardinfo"
+  #locate -e hardinfo | grep "$BASEDER"
+}
+
+remove_hardinfo "/usr/local"
+remove_hardinfo "/usr"
+# add some other base install path here
diff --git a/test/test.sh b/test/test.sh
new file mode 100644
index 0000000..7f52e2b
--- /dev/null
+++ b/test/test.sh
@@ -0,0 +1,33 @@
+
+DATADER=`pwd`
+
+do_test() {
+    ARCH="$1"
+    CPUINFO="$DATADER/$2"
+    mkdir "build-$ARCH"
+    cd "build-$ARCH"
+    cmake ../.. -DOVRARCH=$ARCH -DOVRCPUINFO=\"$CPUINFO\"
+    make -j
+    cd ..
+}
+
+#do_test x86 data/x86_pent_cpuinfo
+#do_test x86 data/x86_amdr7_cpuinfo
+#do_test x86 data/x86_pentf00f_cpuinfo
+#do_test x86 data/x86_cyrix6x86coma_cpuinfo
+#do_test ppc data/ppc_g5_cpuinfo
+#do_test ppc data/power8_cpuinfo
+#do_test arm data/arm_rpi3_aarch64_cpuinfo
+#do_test arm data/arm_jetsontx2_cpuinfo
+#do_test sparc data/sparc_m7_cpuinfo
+#do_test mips data/mips_loongson_cpuinfo
+#do_test alpha data/alpha_as_cpuinfo
+#do_test parisc data/parisc_hppa_fortex4_cpuinfo
+#do_test ia64 data/ia64_x2_cpuinfo
+#do_test m68k data/m68k_sun3_cpuinfo
+#do_test sh data/sh_dreamcast_cpuinfo
+#do_test sh data/sh_sh3_cpuinfo
+#do_test sh data/sh_sh64_cpuinfo
+#do_test s390 data/s390_hurcules_cpuinfo
+#do_test riscv data/riscv_sim_cpuinfo
+#do_test riscv data/riscv_fake_cpuinfo
diff --git a/test/ws_scan.sh b/test/ws_scan.sh
new file mode 100644
index 0000000..d22586f
--- /dev/null
+++ b/test/ws_scan.sh
@@ -0,0 +1,11 @@
+#!bash
+
+# checks for mixed indentation and empty lines with whitespace
+# run from test/
+
+cd ..
+grep -lHIrP --include=*.{h,c} -- '^((\t+ +)|( +\t+)|\s+$)' | sed 's/^/- [ ] /' > test/hardinfo-bad.txt
+grep -LHIrP --include=*.{h,c} -- '^((\t+ +)|( +\t+)|\s+$)' | sed 's/^/- [x] /' > test/hardinfo-good.txt
+cat test/hardinfo-bad.txt test/hardinfo-good.txt | LC_ALL=C sort -k 1.5 | grep -vP " (test|build|deps)"
+rm test/hardinfo-bad.txt test/hardinfo-good.txt
+cd test

Run locally

More details

Full run details