From 9a50155ec3e27aa6cedf3f118196f1947c769a29 Mon Sep 17 00:00:00 2001 From: "Leandro A. F. Pereira" Date: Mon, 3 May 2010 09:25:43 -0300 Subject: Use CMake instead of ToscoConf. --- hardinfo2/.gitignore | 2 - hardinfo2/CMakeLists.txt | 184 +++ hardinfo2/Makefile.in | 75 - hardinfo2/benchmark.c | 661 --------- hardinfo2/binreloc.c | 672 --------- hardinfo2/binreloc.h | 68 - hardinfo2/blowfish.c | 493 ------- hardinfo2/blowfish.h | 33 - hardinfo2/callbacks.c | 430 ------ hardinfo2/callbacks.h | 45 - hardinfo2/computer.c | 702 ---------- hardinfo2/computer.h | 162 --- hardinfo2/configure | 299 ---- hardinfo2/devices.c | 482 ------- hardinfo2/egg-markdown.c | 1586 ---------------------- hardinfo2/egg-markdown.h | 84 -- hardinfo2/expr.c | 250 ---- hardinfo2/expr.h | 48 - hardinfo2/fbench.c | 745 ---------- hardinfo2/fftbench.c | 211 --- hardinfo2/fftbench.h | 19 - hardinfo2/guibench.c | 353 ----- hardinfo2/guibench.h | 24 - hardinfo2/hardinfo.c | 161 --- hardinfo2/hardinfo.h | 149 -- hardinfo2/hardinfo/hardinfo.c | 161 +++ hardinfo2/help-viewer.c | 514 ------- hardinfo2/help-viewer.h | 43 - hardinfo2/help-viewer/egg-markdown.c | 1586 ++++++++++++++++++++++ hardinfo2/help-viewer/help-viewer.c | 514 +++++++ hardinfo2/help-viewer/markdown-text-view.c | 637 +++++++++ hardinfo2/iconcache.c | 102 -- hardinfo2/iconcache.h | 30 - hardinfo2/includes/benchmark.h | 21 + hardinfo2/includes/binreloc.h | 68 + hardinfo2/includes/blowfish.h | 33 + hardinfo2/includes/callbacks.h | 45 + hardinfo2/includes/computer.h | 186 +++ hardinfo2/includes/devices.h | 87 ++ hardinfo2/includes/egg-markdown.h | 84 ++ hardinfo2/includes/expr.h | 48 + hardinfo2/includes/fftbench.h | 19 + hardinfo2/includes/guibench.h | 24 + hardinfo2/includes/hardinfo.h | 151 +++ hardinfo2/includes/help-viewer.h | 43 + hardinfo2/includes/iconcache.h | 30 + hardinfo2/includes/loadgraph.h | 69 + hardinfo2/includes/markdown-text-view.h | 70 + hardinfo2/includes/md5.h | 26 + hardinfo2/includes/menu.h | 25 + hardinfo2/includes/network.h | 14 + hardinfo2/includes/nqueens.h | 13 + hardinfo2/includes/remote.h | 29 + hardinfo2/includes/report.h | 93 ++ hardinfo2/includes/sha1.h | 30 + hardinfo2/includes/shell.h | 225 +++ hardinfo2/includes/socket.h | 36 + hardinfo2/includes/ssh-conn.h | 66 + hardinfo2/includes/stock.h | 34 + hardinfo2/includes/syncmanager.h | 42 + hardinfo2/includes/test-utils.h | 24 + hardinfo2/includes/uidefs.h | 79 ++ hardinfo2/includes/vendor.h | 33 + hardinfo2/includes/x86/processor-platform.h | 36 + hardinfo2/includes/xmlrpc-client.h | 43 + hardinfo2/includes/xmlrpc-server.h | 25 + hardinfo2/loadgraph.c | 347 ----- hardinfo2/loadgraph.h | 69 - hardinfo2/markdown-text-view.c | 637 --------- hardinfo2/markdown-text-view.h | 70 - hardinfo2/md5.c | 317 ----- hardinfo2/md5.h | 26 - hardinfo2/menu.c | 202 --- hardinfo2/menu.h | 25 - hardinfo2/modules/benchmark.c | 654 +++++++++ hardinfo2/modules/benchmark/blowfish.c | 493 +++++++ hardinfo2/modules/benchmark/cryptohash.c | 79 ++ hardinfo2/modules/benchmark/drawing.c | 29 + hardinfo2/modules/benchmark/fbench.c | 745 ++++++++++ hardinfo2/modules/benchmark/fft.c | 65 + hardinfo2/modules/benchmark/fftbench.c | 211 +++ hardinfo2/modules/benchmark/fib.c | 50 + hardinfo2/modules/benchmark/guibench.c | 353 +++++ hardinfo2/modules/benchmark/md5.c | 317 +++++ hardinfo2/modules/benchmark/nqueens.c | 37 + hardinfo2/modules/benchmark/raytrace.c | 47 + hardinfo2/modules/benchmark/sha1.c | 329 +++++ hardinfo2/modules/computer.c | 689 ++++++++++ hardinfo2/modules/computer/alsa.c | 71 + hardinfo2/modules/computer/boots.c | 65 + hardinfo2/modules/computer/display.c | 148 ++ hardinfo2/modules/computer/environment.c | 45 + hardinfo2/modules/computer/filesystem.c | 112 ++ hardinfo2/modules/computer/languages.c | 112 ++ hardinfo2/modules/computer/loadavg.c | 50 + hardinfo2/modules/computer/memory.c | 59 + hardinfo2/modules/computer/modules.c | 174 +++ hardinfo2/modules/computer/os.c | 220 +++ hardinfo2/modules/computer/uptime.c | 76 ++ hardinfo2/modules/computer/users.c | 65 + hardinfo2/modules/devices.c | 442 ++++++ hardinfo2/modules/devices/battery.c | 307 +++++ hardinfo2/modules/devices/devmemory.c | 107 ++ hardinfo2/modules/devices/dmi.c | 200 +++ hardinfo2/modules/devices/inputdevices.c | 144 ++ hardinfo2/modules/devices/pci.c | 245 ++++ hardinfo2/modules/devices/printers.c | 271 ++++ hardinfo2/modules/devices/resources.c | 105 ++ hardinfo2/modules/devices/sensors.c | 383 ++++++ hardinfo2/modules/devices/storage.c | 377 +++++ hardinfo2/modules/devices/usb.c | 349 +++++ hardinfo2/modules/devices/x86/processor.c | 562 ++++++++ hardinfo2/modules/network.c | 443 ++++++ hardinfo2/modules/network/net.c | 454 +++++++ hardinfo2/modules/network/nfs.c | 61 + hardinfo2/modules/network/samba.c | 124 ++ hardinfo2/network.c | 445 ------ hardinfo2/nqueens.c | 37 - hardinfo2/nqueens.h | 13 - hardinfo2/remote.c | 1307 ------------------ hardinfo2/remote.h | 29 - hardinfo2/remote/remote.c | 1307 ++++++++++++++++++ hardinfo2/remote/ssh-conn.c | 338 +++++ hardinfo2/remote/xmlrpc-client.c | 247 ++++ hardinfo2/remote/xmlrpc-server.c | 782 +++++++++++ hardinfo2/report.c | 890 ------------ hardinfo2/report.h | 93 -- hardinfo2/sha1.c | 329 ----- hardinfo2/sha1.h | 30 - hardinfo2/shell.c | 1961 --------------------------- hardinfo2/shell.h | 225 --- hardinfo2/shell/callbacks.c | 430 ++++++ hardinfo2/shell/iconcache.c | 100 ++ hardinfo2/shell/loadgraph.c | 347 +++++ hardinfo2/shell/menu.c | 202 +++ hardinfo2/shell/report.c | 890 ++++++++++++ hardinfo2/shell/shell.c | 1961 +++++++++++++++++++++++++++ hardinfo2/shell/stock.c | 91 ++ hardinfo2/shell/syncmanager.c | 758 +++++++++++ hardinfo2/socket.c | 127 -- hardinfo2/socket.h | 36 - hardinfo2/ssh-conn.c | 338 ----- hardinfo2/ssh-conn.h | 66 - hardinfo2/stock.c | 91 -- hardinfo2/stock.h | 34 - hardinfo2/syncmanager.c | 758 ----------- hardinfo2/syncmanager.h | 42 - hardinfo2/uidefs.h | 79 -- hardinfo2/util.c | 1287 ------------------ hardinfo2/util/binreloc.c | 672 +++++++++ hardinfo2/util/expr.c | 250 ++++ hardinfo2/util/socket.c | 127 ++ hardinfo2/util/util.c | 1292 ++++++++++++++++++ hardinfo2/util/vendor.c | 195 +++ hardinfo2/vendor.c | 195 --- hardinfo2/vendor.h | 33 - hardinfo2/xmlrpc-client.c | 247 ---- hardinfo2/xmlrpc-client.h | 43 - hardinfo2/xmlrpc-server.c | 782 ----------- hardinfo2/xmlrpc-server.h | 25 - 160 files changed, 24791 insertions(+), 19678 deletions(-) create mode 100644 hardinfo2/CMakeLists.txt delete mode 100644 hardinfo2/Makefile.in delete mode 100644 hardinfo2/benchmark.c delete mode 100644 hardinfo2/binreloc.c delete mode 100644 hardinfo2/binreloc.h delete mode 100644 hardinfo2/blowfish.c delete mode 100644 hardinfo2/blowfish.h delete mode 100644 hardinfo2/callbacks.c delete mode 100644 hardinfo2/callbacks.h delete mode 100644 hardinfo2/computer.c delete mode 100644 hardinfo2/computer.h delete mode 100755 hardinfo2/configure delete mode 100644 hardinfo2/devices.c delete mode 100644 hardinfo2/egg-markdown.c delete mode 100644 hardinfo2/egg-markdown.h delete mode 100644 hardinfo2/expr.c delete mode 100644 hardinfo2/expr.h delete mode 100644 hardinfo2/fbench.c delete mode 100644 hardinfo2/fftbench.c delete mode 100644 hardinfo2/fftbench.h delete mode 100644 hardinfo2/guibench.c delete mode 100644 hardinfo2/guibench.h delete mode 100644 hardinfo2/hardinfo.c delete mode 100644 hardinfo2/hardinfo.h create mode 100644 hardinfo2/hardinfo/hardinfo.c delete mode 100644 hardinfo2/help-viewer.c delete mode 100644 hardinfo2/help-viewer.h create mode 100644 hardinfo2/help-viewer/egg-markdown.c create mode 100644 hardinfo2/help-viewer/help-viewer.c create mode 100644 hardinfo2/help-viewer/markdown-text-view.c delete mode 100644 hardinfo2/iconcache.c delete mode 100644 hardinfo2/iconcache.h create mode 100644 hardinfo2/includes/benchmark.h create mode 100644 hardinfo2/includes/binreloc.h create mode 100644 hardinfo2/includes/blowfish.h create mode 100644 hardinfo2/includes/callbacks.h create mode 100644 hardinfo2/includes/computer.h create mode 100644 hardinfo2/includes/devices.h create mode 100644 hardinfo2/includes/egg-markdown.h create mode 100644 hardinfo2/includes/expr.h create mode 100644 hardinfo2/includes/fftbench.h create mode 100644 hardinfo2/includes/guibench.h create mode 100644 hardinfo2/includes/hardinfo.h create mode 100644 hardinfo2/includes/help-viewer.h create mode 100644 hardinfo2/includes/iconcache.h create mode 100644 hardinfo2/includes/loadgraph.h create mode 100644 hardinfo2/includes/markdown-text-view.h create mode 100644 hardinfo2/includes/md5.h create mode 100644 hardinfo2/includes/menu.h create mode 100644 hardinfo2/includes/network.h create mode 100644 hardinfo2/includes/nqueens.h create mode 100644 hardinfo2/includes/remote.h create mode 100644 hardinfo2/includes/report.h create mode 100644 hardinfo2/includes/sha1.h create mode 100644 hardinfo2/includes/shell.h create mode 100644 hardinfo2/includes/socket.h create mode 100644 hardinfo2/includes/ssh-conn.h create mode 100644 hardinfo2/includes/stock.h create mode 100644 hardinfo2/includes/syncmanager.h create mode 100644 hardinfo2/includes/test-utils.h create mode 100644 hardinfo2/includes/uidefs.h create mode 100644 hardinfo2/includes/vendor.h create mode 100644 hardinfo2/includes/x86/processor-platform.h create mode 100644 hardinfo2/includes/xmlrpc-client.h create mode 100644 hardinfo2/includes/xmlrpc-server.h delete mode 100644 hardinfo2/loadgraph.c delete mode 100644 hardinfo2/loadgraph.h delete mode 100644 hardinfo2/markdown-text-view.c delete mode 100644 hardinfo2/markdown-text-view.h delete mode 100644 hardinfo2/md5.c delete mode 100644 hardinfo2/md5.h delete mode 100644 hardinfo2/menu.c delete mode 100644 hardinfo2/menu.h create mode 100644 hardinfo2/modules/benchmark.c create mode 100644 hardinfo2/modules/benchmark/blowfish.c create mode 100644 hardinfo2/modules/benchmark/cryptohash.c create mode 100644 hardinfo2/modules/benchmark/drawing.c create mode 100644 hardinfo2/modules/benchmark/fbench.c create mode 100644 hardinfo2/modules/benchmark/fft.c create mode 100644 hardinfo2/modules/benchmark/fftbench.c create mode 100644 hardinfo2/modules/benchmark/fib.c create mode 100644 hardinfo2/modules/benchmark/guibench.c create mode 100644 hardinfo2/modules/benchmark/md5.c create mode 100644 hardinfo2/modules/benchmark/nqueens.c create mode 100644 hardinfo2/modules/benchmark/raytrace.c create mode 100644 hardinfo2/modules/benchmark/sha1.c create mode 100644 hardinfo2/modules/computer.c create mode 100644 hardinfo2/modules/computer/alsa.c create mode 100644 hardinfo2/modules/computer/boots.c create mode 100644 hardinfo2/modules/computer/display.c create mode 100644 hardinfo2/modules/computer/environment.c create mode 100644 hardinfo2/modules/computer/filesystem.c create mode 100644 hardinfo2/modules/computer/languages.c create mode 100644 hardinfo2/modules/computer/loadavg.c create mode 100644 hardinfo2/modules/computer/memory.c create mode 100644 hardinfo2/modules/computer/modules.c create mode 100644 hardinfo2/modules/computer/os.c create mode 100644 hardinfo2/modules/computer/uptime.c create mode 100644 hardinfo2/modules/computer/users.c create mode 100644 hardinfo2/modules/devices.c create mode 100644 hardinfo2/modules/devices/battery.c create mode 100644 hardinfo2/modules/devices/devmemory.c create mode 100644 hardinfo2/modules/devices/dmi.c create mode 100644 hardinfo2/modules/devices/inputdevices.c create mode 100644 hardinfo2/modules/devices/pci.c create mode 100644 hardinfo2/modules/devices/printers.c create mode 100644 hardinfo2/modules/devices/resources.c create mode 100644 hardinfo2/modules/devices/sensors.c create mode 100644 hardinfo2/modules/devices/storage.c create mode 100644 hardinfo2/modules/devices/usb.c create mode 100644 hardinfo2/modules/devices/x86/processor.c create mode 100644 hardinfo2/modules/network.c create mode 100644 hardinfo2/modules/network/net.c create mode 100644 hardinfo2/modules/network/nfs.c create mode 100644 hardinfo2/modules/network/samba.c delete mode 100644 hardinfo2/network.c delete mode 100644 hardinfo2/nqueens.c delete mode 100644 hardinfo2/nqueens.h delete mode 100644 hardinfo2/remote.c delete mode 100644 hardinfo2/remote.h create mode 100644 hardinfo2/remote/remote.c create mode 100644 hardinfo2/remote/ssh-conn.c create mode 100644 hardinfo2/remote/xmlrpc-client.c create mode 100644 hardinfo2/remote/xmlrpc-server.c delete mode 100644 hardinfo2/report.c delete mode 100644 hardinfo2/report.h delete mode 100644 hardinfo2/sha1.c delete mode 100644 hardinfo2/sha1.h delete mode 100644 hardinfo2/shell.c delete mode 100644 hardinfo2/shell.h create mode 100644 hardinfo2/shell/callbacks.c create mode 100644 hardinfo2/shell/iconcache.c create mode 100644 hardinfo2/shell/loadgraph.c create mode 100644 hardinfo2/shell/menu.c create mode 100644 hardinfo2/shell/report.c create mode 100644 hardinfo2/shell/shell.c create mode 100644 hardinfo2/shell/stock.c create mode 100644 hardinfo2/shell/syncmanager.c delete mode 100644 hardinfo2/socket.c delete mode 100644 hardinfo2/socket.h delete mode 100644 hardinfo2/ssh-conn.c delete mode 100644 hardinfo2/ssh-conn.h delete mode 100644 hardinfo2/stock.c delete mode 100644 hardinfo2/stock.h delete mode 100644 hardinfo2/syncmanager.c delete mode 100644 hardinfo2/syncmanager.h delete mode 100644 hardinfo2/uidefs.h delete mode 100644 hardinfo2/util.c create mode 100644 hardinfo2/util/binreloc.c create mode 100644 hardinfo2/util/expr.c create mode 100644 hardinfo2/util/socket.c create mode 100644 hardinfo2/util/util.c create mode 100644 hardinfo2/util/vendor.c delete mode 100644 hardinfo2/vendor.c delete mode 100644 hardinfo2/vendor.h delete mode 100644 hardinfo2/xmlrpc-client.c delete mode 100644 hardinfo2/xmlrpc-client.h delete mode 100644 hardinfo2/xmlrpc-server.c delete mode 100644 hardinfo2/xmlrpc-server.h (limited to 'hardinfo2') diff --git a/hardinfo2/.gitignore b/hardinfo2/.gitignore index 74b81873..000e8741 100644 --- a/hardinfo2/.gitignore +++ b/hardinfo2/.gitignore @@ -1,7 +1,5 @@ -hardinfo Makefile config.h -modules/* *.so *.o *~ diff --git a/hardinfo2/CMakeLists.txt b/hardinfo2/CMakeLists.txt new file mode 100644 index 00000000..24641294 --- /dev/null +++ b/hardinfo2/CMakeLists.txt @@ -0,0 +1,184 @@ +project(HardInfo) +cmake_minimum_required(VERSION 2.6) + +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|x86_64") + set(HARDINFO_ARCH "x86") +elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "ppc{32,64}") + 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 "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,4}") + set(HARDINFO_ARCH "sh") +else() + message(FATAL_ERROR "Unsupported architecture: ${CMAKE_HOST_SYSTEM_PROCESSOR}") +endif() + +message(STATUS "Building HardInfo for architecture: ${HARDINFO_OS}-${HARDINFO_ARCH}") + +include(FindPkgConfig) +pkg_check_modules(GTK REQUIRED gtk+-2.0>=2.10 glib-2.0>=2.10 gthread-2.0>=2.10) +pkg_check_modules(LIBSOUP libsoup-2.4>=2.26) + +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/includes + ${CMAKE_SOURCE_DIR}/includes/${HARDINFO_ARCH} + ${GTK_INCLUDE_DIRS} + ${LIBSOUP_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(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 +) +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/inputdevices.c + modules/devices/pci.c + modules/devices/printers.c + modules/devices/resources.c + modules/devices/sensors.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 + 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/fib.c + modules/benchmark/guibench.c + modules/benchmark/md5.c + modules/benchmark/nqueens.c + modules/benchmark/raytrace.c + modules/benchmark/sha1.c +) + +foreach (_module ${HARDINFO_MODULES}) + add_library(${_module} MODULE ${MODULE_${_module}_SOURCES}) +endforeach() + +add_library(hardinfo-remote SHARED + remote/remote.c + remote/ssh-conn.c + remote/xmlrpc-client.c + remote/xmlrpc-server.c +) +add_library(hardinfo-help-viewer SHARED + help-viewer/egg-markdown.c + help-viewer/help-viewer.c + help-viewer/markdown-text-view.c +) +add_library(hardinfo-shell SHARED + shell/callbacks.c + shell/iconcache.c + shell/loadgraph.c + shell/menu.c + shell/report.c + shell/shell.c + shell/stock.c + shell/syncmanager.c +) +add_library(hardinfo-util SHARED + util/binreloc.c + util/expr.c + util/socket.c + util/vendor.c + util/util.c +) +add_executable(hardinfo + hardinfo/hardinfo.c +) +target_link_libraries(hardinfo + ${GTK_LIBRARIES} + ${LIBSOUP_LIBRARIES} + hardinfo-shell + hardinfo-util +) +target_link_libraries(hardinfo-shell + hardinfo-help-viewer + hardinfo-remote +) + +install(TARGETS hardinfo ${HARDINFO_MODULES} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib/hardinfo/modules + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE +) +install(TARGETS hardinfo-shell hardinfo-util hardinfo-help-viewer hardinfo-remote + LIBRARY DESTINATION lib + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE +) +install(FILES ${HARDINFO_RESOURCES} + DESTINATION share/hardinfo + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +) +install(DIRECTORY pixmaps + DESTINATION share/hardinfo + PATTERN "*.{png,svg}" + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +) +install(DIRECTORY doc + DESTINATION share/hardinfo + PATTERN "*.{hlp,png}" + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +) + \ No newline at end of file diff --git a/hardinfo2/Makefile.in b/hardinfo2/Makefile.in deleted file mode 100644 index ab41e6bc..00000000 --- a/hardinfo2/Makefile.in +++ /dev/null @@ -1,75 +0,0 @@ - -CCFLAGS = -fPIC -pipe -Wall -Werror -g -CFLAGS = $(GTK_CFLAGS) $(SOUP_CFLAGS) -I. -CC = gcc $(ARCHOPTS) $(CCFLAGS) -CCSLOW = gcc -O0 $(CCFLAGS) - -# ---------------------------------------------------------------------------- - -OBJECTS = hardinfo.o shell.o util.o iconcache.o loadgraph.o \ - menu.o stock.o callbacks.o expr.o report.o binreloc.o \ - vendor.o socket.o syncmanager.o remote.o xmlrpc-server.o \ - xmlrpc-client.o ssh-conn.o egg-markdown.o markdown-text-view.o \ - help-viewer.o -BENCHMARK_OBJECTS = fbench.o sha1.o blowfish.o md5.o nqueens.o fftbench.o guibench.o - -MODULES = computer.so devices.so benchmark.so network.so - -all: hardinfo - -hardinfo: $(OBJECTS) $(MODULES) - $(CC) $(CCFLAGS) -o hardinfo -Wl,-export-dynamic $(OBJECTS) $(GTK_LIBS) \ - $(SOUP_LIBS) - -$(BENCHMARK_OBJECTS): - $(CCSLOW) $(CCFLAGS) $(CFLAGS) -c $*.c -o $@ - -benchmark.so: benchmark.c $(BENCHMARK_OBJECTS) - $(CC) $(CCFLAGS) $(CFLAGS) -o $@ -shared $< $(GTK_FLAGS) $(GTK_LIBS) $(BENCHMARK_OBJECTS) - -%.so: %.c - $(CC) $(CCFLAGS) $(CFLAGS) -o $@ -shared $< $(GTK_FLAGS) $(GTK_LIBS) - -clean: - rm -rf .xvpics pixmaps/.xvpics *.o *.so hardinfo report - find . -name \*~ -exec rm -v {} \; - find . -name x86 -type l -exec rm -v {} \; - -dist-clean: clean - rm -rf Makefile debian/hardinfo/ config.h arch/this - -package: dist-clean - @echo "Creating tar.gz..." - cd .. && tar czf $(PACKAGE).tar.gz $(PACKAGE)/* && cd $(PACKAGE) - @echo "Creating tar.bz2..." - cd .. && tar cjf $(PACKAGE).tar.bz2 $(PACKAGE)/* && cd $(PACKAGE) - -deb: dist-clean - @echo "Creating deb..." - dpkg-buildpackage -rfakeroot -k${USER} - -install: all - - rm -rf ${DESTDIR}${LIBDIR}/hardinfo/modules ${DESTDIR}/usr/share/hardinfo/pixmaps - - install -d ${DESTDIR}/usr/bin - install -d ${DESTDIR}/usr/local - install -d ${DESTDIR}/usr/share/applications - install -d ${DESTDIR}${LIBDIR}/hardinfo/modules - install -d ${DESTDIR}/usr/share/hardinfo/pixmaps - install -d ${DESTDIR}/usr/share/hardinfo/doc - - install -m 644 hardinfo.desktop ${DESTDIR}/usr/share/applications - install -m 755 hardinfo ${DESTDIR}/usr/bin/hardinfo - - install -m 755 ${MODULES} ${DESTDIR}${LIBDIR}/hardinfo/modules - install -m 644 pixmaps/* ${DESTDIR}/usr/share/hardinfo/pixmaps - install -m 644 doc/*.hlp ${DESTDIR}/usr/share/hardinfo/doc || true - install -m 644 doc/*.png ${DESTDIR}/usr/share/hardinfo/doc || true - - install -m 644 benchmark.conf ${DESTDIR}/usr/share/hardinfo - install -m 644 benchmark.data ${DESTDIR}/usr/share/hardinfo - -installer: - makepackage - diff --git a/hardinfo2/benchmark.c b/hardinfo2/benchmark.c deleted file mode 100644 index 3ca5513e..00000000 --- a/hardinfo2/benchmark.c +++ /dev/null @@ -1,661 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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 -#include -#include -#include -#include - -#include -#include - -#include -#include - -enum { - BENCHMARK_BLOWFISH, - BENCHMARK_CRYPTOHASH, - BENCHMARK_FIB, - BENCHMARK_NQUEENS, - BENCHMARK_FFT, - BENCHMARK_RAYTRACE, - BENCHMARK_GUI, - BENCHMARK_N_ENTRIES -} Entries; - -void scan_fft(gboolean reload); -void scan_raytr(gboolean reload); -void scan_bfsh(gboolean reload); -void scan_cryptohash(gboolean reload); -void scan_fib(gboolean reload); -void scan_nqueens(gboolean reload); -void scan_gui(gboolean reload); - -gchar *callback_fft(); -gchar *callback_raytr(); -gchar *callback_bfsh(); -gchar *callback_fib(); -gchar *callback_cryptohash(); -gchar *callback_nqueens(); -gchar *callback_gui(); - -static ModuleEntry entries[] = { - {"CPU Blowfish", "blowfish.png", callback_bfsh, scan_bfsh, MODULE_FLAG_NONE}, - {"CPU CryptoHash", "cryptohash.png", callback_cryptohash, scan_cryptohash, MODULE_FLAG_NONE}, - {"CPU Fibonacci", "nautilus.png", callback_fib, scan_fib, MODULE_FLAG_NONE}, - {"CPU N-Queens", "nqueens.png", callback_nqueens, scan_nqueens, MODULE_FLAG_NONE}, - {"FPU FFT", "fft.png", callback_fft, scan_fft, MODULE_FLAG_NONE}, - {"FPU Raytracing", "raytrace.png", callback_raytr, scan_raytr, MODULE_FLAG_NONE}, - {"GPU Drawing", "module.png", callback_gui, scan_gui, MODULE_FLAG_NO_REMOTE}, - {NULL} -}; - -static gboolean sending_benchmark_results = FALSE; - -typedef struct _ParallelBenchTask ParallelBenchTask; - -struct _ParallelBenchTask { - gint thread_number; - guint start, end; - gpointer data, callback; -}; - -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; - - 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; -} - -gdouble benchmark_parallel_for(guint start, guint end, - gpointer callback, gpointer callback_data) { - gchar *temp; - guint n_cores, iter_per_core, iter, thread_number = 0; - gdouble elapsed_time; - GSList *threads = NULL, *t; - GTimer *timer; - - timer = g_timer_new(); - - temp = module_call_method("devices::getProcessorCount"); - n_cores = temp ? atoi(temp) : 1; - g_free(temp); - - while (1) { - iter_per_core = (end - start) / n_cores; - - if (iter_per_core == 0) { - DEBUG("not enough items per core; disabling one"); - n_cores--; - } else { - break; - } - } - - DEBUG("processor has %d cores; processing %d elements (%d per core)", - n_cores, (end - start), iter_per_core); - - g_timer_start(timer); - for (iter = start; iter < end; iter += iter_per_core) { - ParallelBenchTask *pbt = g_new0(ParallelBenchTask, 1); - GThread *thread; - - DEBUG("launching thread %d", 1 + (iter / iter_per_core)); - - pbt->thread_number = thread_number++; - pbt->start = iter == 0 ? 0 : iter; - pbt->end = iter + iter_per_core - 1; - pbt->data = callback_data; - pbt->callback = callback; - - if (pbt->end > end) - pbt->end = end; - - thread = g_thread_create((GThreadFunc) benchmark_parallel_for_dispatcher, - pbt, TRUE, NULL); - threads = g_slist_append(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); - g_thread_join((GThread *)t->data); - } - - g_timer_stop(timer); - elapsed_time = g_timer_elapsed(timer, NULL); - - g_slist_free(threads); - g_timer_destroy(timer); - - DEBUG("finishing; all threads took %f seconds to finish", elapsed_time); - - return elapsed_time; -} - -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; -} - -static gchar *__benchmark_include_results(gdouble result, - const gchar * benchmark, - ShellOrderType order_type) -{ - GKeyFile *conf; - gchar **machines; - gchar *path, *results = g_strdup(""), *return_value, *processor_frequency; - int i; - - 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); - - machines = g_key_file_get_keys(conf, benchmark, NULL, NULL); - for (i = 0; machines && machines[i]; i++) { - gchar *value, *cleaned_machine; - - value = g_key_file_get_value(conf, benchmark, machines[i], NULL); - cleaned_machine = clean_cpuname(machines[i]); - results = h_strconcat(results, cleaned_machine, "=", value, "\n", NULL); - - g_free(value); - g_free(cleaned_machine); - } - - g_strfreev(machines); - g_free(path); - g_key_file_free(conf); - - if (result > 0.0f) { - processor_frequency = module_call_method("devices::getProcessorFrequency"); - return_value = g_strdup_printf("[$ShellParam$]\n" - "Zebra=1\n" - "OrderType=%d\n" - "ViewType=3\n" - "ColumnTitle$Extra1=CPU Clock\n" - "ColumnTitle$Progress=Results\n" - "ColumnTitle$TextValue=CPU\n" - "ShowColumnHeaders=true\n" - "[%s]\n" - "This Machine=%.3f|%s MHz\n" - "%s", order_type, benchmark, result, processor_frequency, results); - g_free(processor_frequency); - } else { - return_value = g_strdup_printf("[$ShellParam$]\n" - "Zebra=1\n" - "OrderType=%d\n" - "ViewType=3\n" - "ColumnTitle$Extra1=CPU Clock\n" - "ColumnTitle$Progress=Results\n" - "ColumnTitle$TextValue=CPU\n" - "ShowColumnHeaders=true\n" - "[%s]\n" - "%s", order_type, benchmark, results); - } - return return_value; -} - - - -static gchar *benchmark_include_results_reverse(gdouble result, - const gchar * benchmark) -{ - return __benchmark_include_results(result, benchmark, - SHELL_ORDER_DESCENDING); -} - -static gchar *benchmark_include_results(gdouble result, - const gchar * benchmark) -{ - return __benchmark_include_results(result, benchmark, - SHELL_ORDER_ASCENDING); -} - -static gdouble bench_results[BENCHMARK_N_ENTRIES]; - -#include -#include -#include -#include -#include -#include -#include - -gchar *callback_gui() -{ - return benchmark_include_results_reverse(bench_results[BENCHMARK_GUI], - "GPU Drawing"); -} - -gchar *callback_fft() -{ - return benchmark_include_results(bench_results[BENCHMARK_FFT], - "FPU FFT"); -} - -gchar *callback_nqueens() -{ - return benchmark_include_results(bench_results[BENCHMARK_NQUEENS], - "CPU N-Queens"); -} - -gchar *callback_raytr() -{ - return benchmark_include_results(bench_results[BENCHMARK_RAYTRACE], - "FPU Raytracing"); -} - -gchar *callback_bfsh() -{ - return benchmark_include_results(bench_results[BENCHMARK_BLOWFISH], - "CPU Blowfish"); -} - -gchar *callback_cryptohash() -{ - return benchmark_include_results_reverse(bench_results[BENCHMARK_CRYPTOHASH], - "CPU CryptoHash"); -} - -gchar *callback_fib() -{ - return benchmark_include_results(bench_results[BENCHMARK_FIB], - "CPU Fibonacci"); -} - -typedef struct _BenchmarkDialog BenchmarkDialog; -struct _BenchmarkDialog { - GtkWidget *dialog; - double result; -}; - -static gboolean do_benchmark_handler(GIOChannel *source, - GIOCondition condition, - gpointer data) -{ - BenchmarkDialog *bench_dialog = (BenchmarkDialog*)data; - GIOStatus status; - gchar *result; - - status = g_io_channel_read_line(source, &result, NULL, NULL, NULL); - if (status != G_IO_STATUS_NORMAL) { - DEBUG("error while reading benchmark result"); - - bench_dialog->result = -1.0f; - gtk_widget_destroy(bench_dialog->dialog); - return FALSE; - } - - bench_dialog->result = atof(result); - 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_status = g_strdup_printf("Benchmarking: %s.", 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); - - 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."); - g_object_set_data(G_OBJECT(bench_dialog), "result", "0.0"); - 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); - - while (gtk_events_pending()) { - gtk_main_iteration(); - } - - benchmark_dialog = g_new0(BenchmarkDialog, 1); - benchmark_dialog->dialog = bench_dialog; - benchmark_dialog->result = -1.0f; - - 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; - - 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->result; - - 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); -} - -void scan_gui(gboolean reload) -{ - SCAN_START(); - - 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] = 0.0f; - } - SCAN_END(); -} - -void scan_fft(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_fft, BENCHMARK_FFT); - SCAN_END(); -} - -void scan_nqueens(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_nqueens, BENCHMARK_NQUEENS); - SCAN_END(); -} - -void scan_raytr(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_raytrace, BENCHMARK_RAYTRACE); - SCAN_END(); -} - -void scan_bfsh(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_fish, BENCHMARK_BLOWFISH); - SCAN_END(); -} - -void scan_cryptohash(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_cryptohash, BENCHMARK_CRYPTOHASH); - SCAN_END(); -} - -void scan_fib(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_fib, BENCHMARK_FIB); - SCAN_END(); -} - -const gchar *hi_note_func(gint entry) -{ - switch (entry) { - case BENCHMARK_CRYPTOHASH: - return "Results in MiB/second. Higher is better."; - - 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; -} - -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 = "Perform tasks and compare with other systems", - .version = VERSION, - .license = "GNU GPL version 2"} - }; - - return ma; -} - -static gchar *get_benchmark_results() -{ - void (*scan_callback) (gboolean rescan); - - sending_benchmark_results = TRUE; - - gint i = G_N_ELEMENTS(entries) - 1; - 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=%d\n", - machine, - machineclock, - machineram, i); - for (; i >= 0; i--) { - if ((scan_callback = entries[i].scan_callback)) { - if (bench_results[i] < 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); - - return g_strdup_printf("%f", 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 = "Send benchmark results", - .name = "SendBenchmarkResults", - .save_to = NULL, - .get_data = get_benchmark_results}, - { - .fancy_name = "Receive benchmark results", - .name = "RecvBenchmarkResults", - .save_to = "benchmark.conf", - .get_data = NULL} - }; - - sync_manager_add_entry(&se[0]); - sync_manager_add_entry(&se[1]); -} - -gchar **hi_module_get_dependencies(void) -{ - static gchar *deps[] = { "devices.so", NULL }; - - return deps; -} - diff --git a/hardinfo2/binreloc.c b/hardinfo2/binreloc.c deleted file mode 100644 index 1d1acfe6..00000000 --- a/hardinfo2/binreloc.c +++ /dev/null @@ -1,672 +0,0 @@ -/* - * BinReloc - a library for creating relocatable executables - * Written by: Hongli Lai - * 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 -#include -#include -#include -#include -#include -#include -#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; - } - -#ifdef ARCH_x86_64 - dir = g_build_filename(prefix, "lib64", NULL); -#else - dir = g_build_filename(prefix, "lib", NULL); -#endif - - 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/hardinfo2/binreloc.h b/hardinfo2/binreloc.h deleted file mode 100644 index 3bf48bc6..00000000 --- a/hardinfo2/binreloc.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * BinReloc - a library for creating relocatable executables - * Written by: Hongli Lai - * 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 - -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/hardinfo2/blowfish.c b/hardinfo2/blowfish.c deleted file mode 100644 index 034315ab..00000000 --- a/hardinfo2/blowfish.c +++ /dev/null @@ -1,493 +0,0 @@ -/* -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 "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; - } - } -} - - diff --git a/hardinfo2/blowfish.h b/hardinfo2/blowfish.h deleted file mode 100644 index 3f33e945..00000000 --- a/hardinfo2/blowfish.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -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/hardinfo2/callbacks.c b/hardinfo2/callbacks.c deleted file mode 100644 index 021560e2..00000000 --- a/hardinfo2/callbacks.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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 -#include - -#include "hardinfo.h" -#include "callbacks.h" -#include "iconcache.h" - -#include "shell.h" -#include "report.h" -#include "remote.h" -#include "syncmanager.h" -#include "help-viewer.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_connect_to() -{ -#ifdef HAS_LIBSOUP - Shell *shell = shell_get_main_shell(); - - connect_dialog_show(shell->window); -#endif /* HAS_LIBSOUP */ -} - -void cb_manage_hosts() -{ -#ifdef HAS_LIBSOUP - Shell *shell = shell_get_main_shell(); - - host_manager_show(shell->window); -#endif /* HAS_LIBSOUP */ -} - -void cb_connect_host(GtkAction * action) -{ -#ifdef HAS_LIBSOUP - Shell *shell = shell_get_main_shell(); - gchar *name; - - g_object_get(G_OBJECT(action), "name", &name, NULL); - - if (remote_connect_host(name)) { - gchar *tmp; - - tmp = g_strdup_printf("Remote: %s", name); - shell_set_remote_label(shell, tmp); - - g_free(tmp); - } else { - cb_local_computer(); - } - - g_free(name); -#endif /* HAS_LIBSOUP */ -} - -static gboolean server_start_helper(gpointer server_loop) -{ -#ifdef HAS_LIBSOUP - GMainLoop *loop = (GMainLoop *)server_loop; - - xmlrpc_server_start(loop); - - return FALSE; -#endif /* HAS_LIBSOUP */ -} - -void cb_act_as_server() -{ -#ifdef HAS_LIBSOUP - gboolean accepting; - static GMainLoop *server_loop = NULL; - - accepting = shell_action_get_active("ActAsServerAction"); - if (accepting) { - server_loop = g_main_loop_new(NULL, FALSE); - g_idle_add(server_start_helper, server_loop); - } else { - g_main_loop_quit(server_loop); - } -#endif /* HAS_LIBSOUP */ -} - -void cb_local_computer() -{ -#ifdef HAS_LIBSOUP - Shell *shell = shell_get_main_shell(); - - shell_status_update("Disconnecting..."); - remote_disconnect_all(TRUE); - - shell_status_update("Unloading modules..."); - module_unload_all(); - - shell_status_update("Loading local modules..."); - shell->tree->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)); - - shell_view_set_enabled(TRUE); - shell_status_update("Done."); - shell_set_remote_label(shell, ""); -#endif /* HAS_LIBSOUP */ -} - -void cb_save_graphic() -{ - Shell *shell = shell_get_main_shell(); - GtkWidget *dialog; - gchar *filename; - - /* save the pixbuf to a png file */ - dialog = gtk_file_chooser_dialog_new("Save Image", - NULL, - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, - GTK_RESPONSE_ACCEPT, NULL); - - filename = g_strconcat(shell->selected->name, ".png", NULL); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename); - g_free(filename); - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - gtk_widget_destroy(dialog); - - shell_status_update("Saving image..."); - - tree_view_save_image(filename); - - shell_status_update("Done."); - g_free(filename); - - return; - } - - gtk_widget_destroy(dialog); -} - -void cb_open_web_page() -{ - open_url("http://wiki.hardinfo.org"); -} - -void cb_open_online_docs() -{ - Shell *shell; - - shell = shell_get_main_shell(); - if (shell->help_viewer) { - help_viewer_open_page(shell->help_viewer, "index.hlp"); - } else { - gchar *help_dir; - - help_dir = g_build_filename(params.path_data, "doc", NULL); - shell->help_viewer = help_viewer_new(help_dir, "index.hlp"); - g_free(help_dir); - } -} - -void cb_open_online_docs_context() -{ - Shell *shell; - - shell = shell_get_main_shell(); - - if (shell->selected->flags & MODULE_FLAG_HAS_HELP) { - gchar *temp; - - if (shell->selected_module->dll) { - gchar *name_temp; - - name_temp = (gchar *)g_module_name(shell->selected_module->dll); - name_temp = g_path_get_basename(name_temp); - strend(name_temp, '.'); - - temp = g_strdup_printf("context-help-%s-%d.hlp", - name_temp, - shell->selected->number); - - g_free(name_temp); - } else { - goto no_context_help; - } - - if (shell->help_viewer) { - help_viewer_open_page(shell->help_viewer, temp); - } else { - gchar *help_dir; - - help_dir = g_build_filename(params.path_data, "doc", NULL); - shell->help_viewer = help_viewer_new(help_dir, temp); - g_free(help_dir); - } - - g_free(temp); - } else { - GtkWidget *dialog; - -no_context_help: - dialog = gtk_message_dialog_new(GTK_WINDOW(shell->window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "No context help available."); - - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - } -} - -void cb_report_bug() -{ - open_url("http://wiki.hardinfo.org/BugReports"); -} - -void cb_donate() -{ - open_url("http://wiki.hardinfo.org/Donate"); -} - -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(); - - text = g_strdup_printf("%s Module", sm->name); - gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(about), text); - 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() -{ - GtkWidget *about; - const gchar *authors[] = { - "Author:", - "Leandro A. F. Pereira", - "", - "Contributors:", - "Agney Lopes Roth Ferraz", - "Andrey Esin", - "", - "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_about_dialog_set_name(GTK_ABOUT_DIALOG(about), "HardInfo"); - gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about), VERSION); - gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about), - "Copyright \302\251 2003-2009 " - "Leandro A. F. Pereira"); - 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"); -#if GTK_CHECK_VERSION(2,8,0) - gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(about), TRUE); -#endif - - gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about), authors); - gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(about), artists); - - gtk_dialog_run(GTK_DIALOG(about)); - gtk_widget_destroy(about); -} - -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/hardinfo2/callbacks.h b/hardinfo2/callbacks.h deleted file mode 100644 index d53e1861..00000000 --- a/hardinfo2/callbacks.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 - -void cb_about(); -void cb_about_module(GtkAction *action); -void cb_generate_report(); -void cb_save_graphic(); -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/hardinfo2/computer.c b/hardinfo2/computer.c deleted file mode 100644 index 34696004..00000000 --- a/hardinfo2/computer.c +++ /dev/null @@ -1,702 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2008 Leandro A. F. Pereira - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -/* Callbacks */ -gchar *callback_summary(); -gchar *callback_os(); -gchar *callback_modules(); -gchar *callback_boots(); -gchar *callback_locales(); -gchar *callback_fs(); -gchar *callback_display(); -gchar *callback_network(); -gchar *callback_users(); -gchar *callback_env_var(); -#if GLIB_CHECK_VERSION(2,14,0) -gchar *callback_dev(); -#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_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[] = { - {"Summary", "summary.png", callback_summary, scan_summary, MODULE_FLAG_NONE}, - {"Operating System", "os.png", callback_os, scan_os, MODULE_FLAG_NONE}, - {"Kernel Modules", "module.png", callback_modules, scan_modules, MODULE_FLAG_NONE}, - {"Boots", "boot.png", callback_boots, scan_boots, MODULE_FLAG_NONE}, - {"Languages", "language.png", callback_locales, scan_locales, MODULE_FLAG_NONE}, - {"Filesystems", "dev_removable.png", callback_fs, scan_fs, MODULE_FLAG_NONE}, - {"Display", "monitor.png", callback_display, scan_display, MODULE_FLAG_NONE}, - {"Environment Variables", "environment.png", callback_env_var, scan_env_var, MODULE_FLAG_NONE}, -#if GLIB_CHECK_VERSION(2,14,0) - {"Development", "devel.png", callback_dev, scan_dev, MODULE_FLAG_NONE}, -#endif /* GLIB_CHECK_VERSION(2,14,0) */ - {"Users", "users.png", callback_users, scan_users, MODULE_FLAG_NONE}, - {NULL}, -}; - -#include "computer.h" - -static GHashTable *moreinfo = NULL; -static gchar *module_list = NULL; -static Computer *computer = NULL; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -gchar *hi_more_info(gchar * entry) -{ - gchar *info = (gchar *) g_hash_table_lookup(moreinfo, 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 { - tmp = g_strdup(""); - } - - 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(); -} - -#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[] = { - { "Scripting Languages", NULL, FALSE }, - { "CPython", "python -V", "\\d+\\.\\d+\\.\\d+", FALSE }, - { "Perl", "perl -v", "\\d+\\.\\d+\\.\\d+", TRUE }, - { "PHP", "php --version", "\\d+\\.\\d+\\.\\S+", TRUE}, - { "Ruby", "ruby --version", "\\d+\\.\\d+\\.\\d+", TRUE }, - { "Bash", "bash --version", "\\d+\\.\\d+\\.\\S+", TRUE}, - { "Compilers", NULL, FALSE }, - { "C (GCC)", "gcc -v", "\\d+\\.\\d+\\.\\d+", FALSE }, - { "Java", "javac -version", "\\d+\\.\\d+\\.\\d+", FALSE }, - { "CSharp (Mono, old)", "mcs --version", "\\d+\\.\\d+\\.\\d+\\.\\d+", TRUE }, - { "CSharp (Mono)", "gmcs --version", "\\d+\\.\\d+\\.\\d+\\.\\d+", TRUE }, - { "Vala", "valac --version", "\\d+\\.\\d+\\.\\d+", TRUE }, - { "Haskell (GHC)", "ghc -v", "\\d+\\.\\d+\\.\\d+", FALSE }, - { "FreePascal", "fpc --version", "\\d+\\.\\d+\\.\\S+", TRUE }, - { "Tools", NULL, FALSE }, - { "make", "make --version", "\\d+\\.\\d+", TRUE }, - { "GDB", "gdb --version", "\\d+\\.\\S+", TRUE }, - { "strace", "strace -V", "\\d+\\.\\d+\\.\\d+", TRUE }, - { "valgrind", "valgrind --version", "\\d+\\.\\d+\\.\\S+", TRUE }, - { "QMake", "qmake --version", "\\d+\\.\\S+", TRUE}, - }; - - g_free(dev_list); - - dev_list = g_strdup(""); - - for (i = 0; i < G_N_ELEMENTS(detect_lang); i++) { - gchar *version = NULL; - gchar *output; - 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, NULL, NULL, NULL); - } else { - found = g_spawn_command_line_sync(detect_lang[i].version_command, NULL, &output, NULL, NULL); - } - - 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) { - dev_list = h_strdup_cprintf("%s=%s\n", dev_list, detect_lang[i].compiler_name, version); - g_free(version); - } else { - dev_list = h_strdup_cprintf("%s=Not found\n", dev_list, detect_lang[i].compiler_name); - } - - temp = g_strdup_printf("Detecting version: %s", - detect_lang[i].compiler_name); - shell_status_update(temp); - g_free(temp); - } - - SCAN_END(); -} - -gchar *callback_dev() -{ - return g_strdup_printf("[$ShellParam$]\n" - "ColumnTitle$TextValue=Program\n" - "ColumnTitle$Value=Version\n" - "ShowColumnHeaders=true\n" - "%s", dev_list); -} -#endif /* GLIB_CHECK_VERSION(2,14,0) */ - -/* Table based off imvirt by Thomas Liske - Copyright (c) 2008 IBH IT-Service GmbH under GPLv2. */ -gchar *computer_get_virtualization() -{ - 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", "Virtual (VMware)" }, - { ": VMware Virtual IDE CDROM Drive", "Virtual (VMware)" }, - /* QEMU */ - { "QEMU", "Virtual (QEMU)" }, - { "QEMU Virtual CPU", "Virtual (QEMU)" }, - { ": QEMU HARDDISK", "Virtual (QEMU)" }, - { ": QEMU CD-ROM", "Virtual (QEMU)" }, - /* Generic Virtual Machine */ - { ": Virtual HD,", "Virtual (Unknown)" }, - { ": Virtual CD,", "Virtual (Unknown)" }, - /* Virtual Box */ - { "VBOX", "Virtual (VirtualBox)" }, - { ": VBOX HARDDISK", "Virtual (VirtualBox)" }, - { ": VBOX CD-ROM", "Virtual (VirtualBox)" }, - /* Xen */ - { "Xen virtual console", "Virtual (Xen)" }, - { "Xen reported: ", "Virtual (Xen)" }, - { "xen-vbd: registered block device", "Virtual (Xen)" }, - { NULL } - }; - - DEBUG("Detecting virtual machine"); - - if (g_file_test("/proc/xen", G_FILE_TEST_EXISTS)) { - DEBUG("/proc/xen found; assuming Xen"); - return g_strdup("Xen"); - } - - 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 g_strdup("Physical machine"); -} - -gchar *callback_summary() -{ - gchar *processor_name, *alsa_cards; - gchar *input_devices, *printers; - gchar *storage_devices, *summary; - gchar *virt; - - processor_name = module_call_method("devices::getProcessorName"); - alsa_cards = computer_get_alsacards(computer); - input_devices = module_call_method("devices::getInputDevices"); - printers = module_call_method("devices::getPrinters"); - storage_devices = module_call_method("devices::getStorageDevices"); - virt = computer_get_virtualization(); - - summary = g_strdup_printf("[$ShellParam$]\n" - "UpdateInterval$Memory=1000\n" - "UpdateInterval$Date/Time=1000\n" - "#ReloadInterval=5000\n" - "[Computer]\n" - "Processor=%s\n" - "Memory=...\n" - "Machine Type=%s\n" - "Operating System=%s\n" - "User Name=%s\n" - "Date/Time=...\n" - "[Display]\n" - "Resolution=%dx%d pixels\n" - "OpenGL Renderer=%s\n" - "X11 Vendor=%s\n" - "\n%s\n" - "[Input Devices]\n%s\n" - "\n%s\n" - "\n%s\n", - processor_name, - virt, - computer->os->distro, - computer->os->username, - computer->display->width, - computer->display->height, - computer->display->ogl_renderer, - computer->display->vendor, - alsa_cards, - input_devices, printers, storage_devices); - - g_free(processor_name); - g_free(alsa_cards); - g_free(input_devices); - g_free(printers); - g_free(storage_devices); - g_free(virt); - - return summary; -} - -gchar *callback_os() -{ - return g_strdup_printf("[$ShellParam$]\n" - "UpdateInterval$Uptime=10000\n" - "UpdateInterval$Load Average=1000\n" - "[Version]\n" - "Kernel=%s\n" - "Version=%s\n" - "C Library=%s\n" - "Distribution=%s\n" - "[Current Session]\n" - "Computer Name=%s\n" - "User Name=%s\n" - "#Language=%s\n" - "Home Directory=%s\n" - "Desktop Environment=%s\n" - "[Misc]\n" - "Uptime=...\n" - "Load Average=...", - computer->os->kernel, - computer->os->kernel_version, - computer->os->libc, - computer->os->distro, - computer->os->hostname, - computer->os->username, - computer->os->language, - computer->os->homedir, computer->os->desktop); -} - -gchar *callback_modules() -{ - return g_strdup_printf("[Loaded Modules]\n" - "%s" - "[$ShellParam$]\n" - "ViewType=1\n" - "ColumnTitle$TextValue=Name\n" - "ColumnTitle$Value=Description\n" - "ShowColumnHeaders=true\n", module_list); -} - -gchar *callback_boots() -{ - return g_strdup_printf("[$ShellParam$]\n" - "ColumnTitle$TextValue=Date & Time\n" - "ColumnTitle$Value=Kernel Version\n" - "ShowColumnHeaders=true\n" - "\n" - "%s", computer->os->boots); -} - -gchar *callback_locales() -{ - return g_strdup_printf("[$ShellParam$]\n" - "ViewType=1\n" - "ColumnTitle$TextValue=Language Code\n" - "ColumnTitle$Value=Name\n" - "ShowColumnHeaders=true\n" - "[Available Languages]\n" - "%s", computer->os->languages); -} - -gchar *callback_fs() -{ - return g_strdup_printf("[$ShellParam$]\n" - "ViewType=4\n" - "ReloadInterval=5000\n" - "Zebra=1\n" - "NormalizePercentage=false\n" - "ColumnTitle$Extra1=Mount Point\n" - "ColumnTitle$Progress=Usage\n" - "ColumnTitle$TextValue=Device\n" - "ShowColumnHeaders=true\n" - "[Mounted File Systems]\n%s\n", fs_list); -} - -gchar *callback_display() -{ - return g_strdup_printf("[Display]\n" - "Resolution=%dx%d pixels\n" - "Vendor=%s\n" - "Version=%s\n" - "[Monitors]\n" - "%s" - "[Extensions]\n" - "%s" - "[OpenGL]\n" - "Vendor=%s\n" - "Renderer=%s\n" - "Version=%s\n" - "Direct Rendering=%s\n", - computer->display->width, - computer->display->height, - computer->display->vendor, - computer->display->version, - computer->display->monitors, - computer->display->extensions, - computer->display->ogl_vendor, - computer->display->ogl_renderer, - computer->display->ogl_version, - computer->display->dri ? "Yes" : "No"); -} - -gchar *callback_users() -{ - return g_strdup_printf("[$ShellParam$]\n" - "ReloadInterval=10000\n" - "ViewType=1\n" - "[Users]\n" - "%s\n", users); -} - -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_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}, - {"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("[Operating System]\n" - "Icon=os.png\n" - "Method=computer::getOS\n" - "[CPU]\n" - "Icon=processor.png\n" - "Method=devices::getProcessorName\n" - "[RAM]\n" - "Icon=memory.png\n" - "Method=devices::getMemoryTotal\n" - "[Motherboard]\n" - "Icon=module.png\n" - "[Graphics]\n" - "Icon=monitor.png\n" - "Method=computer::getDisplaySummary\n" - "[Storage]\n" - "Icon=hdd.png\n" - "Method=devices::getStorageDevices\n" - "[Printers]\n" - "Icon=printer.png\n" - "Method=devices::getPrinters\n" - "[Audio]\n" - "Icon=audio.png\n" - "Method=computer::getAudioCards\n"); -} - -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); - - h_hash_table_remove_all(moreinfo); - g_hash_table_destroy(moreinfo); -} - -void hi_module_init(void) -{ - computer = g_new0(Computer, 1); - moreinfo = - g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); -} - -ModuleAbout *hi_module_get_about(void) -{ - static ModuleAbout ma[] = { - { - .author = "Leandro A. F. Pereira", - .description = "Gathers high-level computer information", - .version = VERSION, - .license = "GNU GPL version 2"} - }; - - return ma; -} - diff --git a/hardinfo2/computer.h b/hardinfo2/computer.h deleted file mode 100644 index ff84c271..00000000 --- a/hardinfo2/computer.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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__ - -#define DB_PREFIX "/etc/" - -static struct { - gchar *file, *codename; -} distro_db[] = { - { 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 "puppyversion", "ppy" }, - { 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" }, - { NULL, NULL } -}; - -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; -}; - -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; \ - } - -#endif /* __COMPUTER_H__ */ diff --git a/hardinfo2/configure b/hardinfo2/configure deleted file mode 100755 index e68b61c3..00000000 --- a/hardinfo2/configure +++ /dev/null @@ -1,299 +0,0 @@ -#!/usr/bin/env bash -# -# ToscoConf 0.05 -# Copyright (c) 2003-2009 Leandro Pereira -# All rights reserved. -# -# This script is in the Tosco Public License. It may be copied and/or -# modified, in whole or in part, provided that all copies must retain the -# above copyright notice, this condition and the following disclaimer. -# -# THIS SOFTWARE IS PROVIDED ``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) -# -# --------------------------------------------------------------------------- - -function usage { - echo "Usage: [-l libdir] [-r release] [-h]" - echo " -l libdir Specify the library dir [default=autodetect]" - echo " -r release Build a (release,debug) version [default=autodetect]" - echo " -h This help" -} - -ARGS=`getopt l:p:r:h $*` -if test $? != 0; then - usage - exit 1 -fi -set -- $ARGS - -FORCE_LIBDIR="" -FORCE_RELEASE="" - -for arg; do - case "$arg" in - -l) - shift; - FORCE_LIBDIR=$1; - shift ;; - -h) - usage; - exit 0 ;; - -r) - shift; - case "$1" in - release|debug) - FORCE_RELEASE=$1 ;; - *) - echo "Invalid build type; use either release or debug" - exit 1 ;; - esac - shift;; - esac -done - -# --------------------------------------------------------------------------- - -PACKAGE=`basename ${PWD} | cut -d"-" -f1`; -VERSION=`basename ${PWD} | cut -d"-" -f2`; - -if [ "$PACKAGE" == "$VERSION" ]; then - VERSION=$(date +"%F.%H:%M:%S") - RELEASE=0 -else - RELEASE=1 -fi - -echo "ToscoConf (version 0.05) for $PACKAGE version $VERSION" - -# --------------------------------------------------------------------------- - -case "$FORCE_RELEASE" in - debug) RELEASE=0;; - release) RELEASE=1;; -esac - -# --------------------------------------------------------------------------- - -echo "Determining system architecture." -OS=`uname` -case $OS in - Linux) - ;; - *) - echo "$OS (not supported, yet!)" - exit ;; -esac - -PROC=`uname -m` -LIBDIR='/usr/lib' -case $PROC in - i?86) - ln -sf linux/x86 arch/this - ARCH="ARCH_i386" ;; - ppc*) - ln -sf linux/ppc arch/this - ARCH="ARCH_PPC" ;; - x86_64) - ln -sf linux/x86_64 arch/this - ARCH="ARCH_x86_64" - LIBDIR="/usr/lib64" ;; - mips*) - ln -sf linux/mips arch/this - ARCH="ARCH_MIPS" ;; - parisc*) - ln -sf linux/parisc arch/this - ARCH="ARCH_PARISC" ;; - sparc*) - ln -sf linux/sparc arch/this - ARCH="ARCH_SPARC" ;; - armv*) - ln -sf linux/armv4l arch/this - ARCH="ARCH_ARMV4L" ;; - ia64) - ln -sf linux/ia64 arch/this - ARCH="ARCH_IA64" ;; - alpha) - ln -sf linux/alpha arch/this - ARCH="ARCH_ALPHA" ;; - s390*) - ln -sf linux/s390 arch/this - ARCH="ARCH_S390" ;; - m68k) - ln -sf linux/m68k arch/this - ARCH="ARCH_m68k" ;; - sh*) - ln -sf linux/sh arch/this - ARCH="ARCH_sh" ;; -esac - -if [ "x$ARCH" == "x" ]; then - echo "Your architecture is not supported yet. Please send the" - echo "output of the following commands to leandro@hardinfo.org:" - echo "" - echo " $ cat /proc/cpuinfo" - echo " $ uname -a" - echo " $ uname -m" - exit 1 -fi - -# --------------------------------------------------------------------------- - -echo "Building $PACKAGE for $OS $PROC ($ARCH)." -echo "" - -# --------------------------------------------------------------------------- - -if [ "x$FORCE_LIBDIR" != "x" ]; then - echo "Forcing libdir to be $FORCE_LIBDIR" - LIBDIR=$FORCE_LIBDIR -fi - -# --------------------------------------------------------------------------- - -GTK2=-1 -MIN_VERSION="2.6.0" -echo -n "Checking for GTK version >= ${MIN_VERSION}... " -for i in `which pkg-config`; do - $i --errors-to-stdout gtk+-2.0 \ - --atleast-version=$MIN_VERSION > /dev/null - case $? in - 0) - GTK_FLAGS=`pkg-config gtk+-2.0 --cflags` - GTK_LIBS=`pkg-config gtk+-2.0 --libs` - echo "found `pkg-config gtk+-2.0 --modversion`" - GTK2=1 - break ;; - *) - echo "not found." ;; - esac -done - -# -------------------------------------------------------------------------- - -if [ $GTK2 -eq -1 ]; then - echo -e "\nYou need the GTK libraries, including the development stuff." - echo "If you're using Debian, running the command as root:" - echo -e "\n\taptitude install libgtk2.0-dev\n" - echo "Will do the trick." - exit 1 -fi - -# --------------------------------------------------------------------------- - -SOUP=-1 -MIN_VERSION="2.4" -echo -n "Checking for libsoup version >= ${MIN_VERSION}... " -for i in `which pkg-config`; do - $i --errors-to-stdout libsoup-2.4 \ - --atleast-version=$MIN_VERSION > /dev/null - case $? in - 0) - SOUP_FLAGS=`pkg-config libsoup-2.4 --cflags --static` - SOUP_LIBS=`pkg-config libsoup-2.4 --libs --static` - echo "found `pkg-config libsoup-2.4 --modversion`" - SOUP=1 - break ;; - *) - echo "not found." ;; - esac -done - -# -------------------------------------------------------------------------- - -if [ $SOUP -eq -1 ]; then - echo "Disabling libsoup support. (Network Updater won't be available.)" -fi - -# -------------------------------------------------------------------------- - -echo -n "Checking for Linux Wireless Extensions (CONFIG_NET_RADIO)... " -if [ -e /proc/net/wireless ]; then - echo "found." - LINUX_WE=1 -else - echo "not found." - LINUX_WE=-1 -fi - -# -------------------------------------------------------------------------- - -if [ $LINUX_WE -eq -1 ]; then - echo "Disabling Linux Wireless Extensions support." -fi - -# -------------------------------------------------------------------------- - -echo -e "\nWriting config.h..." -cat << EOF > config.h -#ifndef __CONFIG_H__ -#define __CONFIG_H__ - -#define VERSION "$VERSION" -#define $ARCH -#define ARCH "$ARCH" -#define PLATFORM "`uname`" -#define KERNEL "`uname -r`" -#define HOSTNAME "`hostname`" -#define PREFIX "/usr/share/hardinfo" -#define LIBPREFIX "$LIBDIR/hardinfo" - -EOF - -if [ "$SOUP" == "1" ]; then - echo "#define HAS_LIBSOUP" >> config.h -fi - -if [ "$LINUX_WE" == "1" ]; then - echo "#define HAS_LINUX_WE" >> config.h -fi - -if [ "$RELEASE" == "1" ]; then - echo "#define DEBUG(...)" >> config.h -else - echo '#define DEBUG(msg,...) fprintf(stderr, "*** %s:%d (%s) *** " msg "\n", \' >> config.h - echo ' __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)' >> config.h -fi - -cat << EOF >> config.h -#define ENABLE_BINRELOC 1 -#define RELEASE $RELEASE - -#endif /* __CONFIG_H__ */ -EOF - -echo "Writing Makefile..." - -cat << EOF > Makefile -GTK_LIBS = -lpthread -lgthread-2.0 -lrt ${GTK_LIBS} -GTK_CFLAGS = ${GTK_FLAGS} -SOUP_LIBS = ${SOUP_LIBS} -SOUP_CFLAGS = ${SOUP_FLAGS} -PACKAGE = `basename ${PWD}` -ARCHOPTS = -LIBDIR = $LIBDIR -EOF - -cat Makefile.in >> Makefile - -echo -e "\nDone. Type \"make\" to compile the program.\n" - -if [ "$RELEASE" == 0 ]; then - cat << EOF -******************************************************************** -* This is work in progress! Please report bugs or send patches to: * -* http://bugs.hardinfo.org * -******************************************************************** -EOF -else - cat << EOF -If you get errors, probably you don't have the right libraries, -includes or utilities. However, if you're sure this is a bug in my -code, please use the bug tracker at . -EOF -fi diff --git a/hardinfo2/devices.c b/hardinfo2/devices.c deleted file mode 100644 index 0607ba39..00000000 --- a/hardinfo2/devices.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 -#include -#include - -#include -#include -#include -#include - -#include -#include - -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_i386) || defined(ARCH_x86_64) -gchar *callback_dmi(); -#endif -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_i386) || defined(ARCH_x86_64) -void scan_dmi(gboolean reload); -#endif -void scan_device_resources(gboolean reload); - -static ModuleEntry entries[] = { - {"Processor", "processor.png", callback_processors, scan_processors, MODULE_FLAG_NONE}, - {"Memory", "memory.png", callback_memory, scan_memory, MODULE_FLAG_NONE}, - {"PCI Devices", "devices.png", callback_pci, scan_pci, MODULE_FLAG_NONE}, - {"USB Devices", "usb.png", callback_usb, scan_usb, MODULE_FLAG_NONE}, - {"Printers", "printer.png", callback_printers, scan_printers, MODULE_FLAG_NONE}, - {"Battery", "battery.png", callback_battery, scan_battery, MODULE_FLAG_NONE}, - {"Sensors", "therm.png", callback_sensors, scan_sensors, MODULE_FLAG_NONE}, - {"Input Devices", "inputdevices.png", callback_input, scan_input, MODULE_FLAG_NONE}, - {"Storage", "hdd.png", callback_storage, scan_storage, MODULE_FLAG_NONE}, -#if defined(ARCH_i386) || defined(ARCH_x86_64) - {"DMI", "computer.png", callback_dmi, scan_dmi, MODULE_FLAG_NONE}, -#endif /* x86 or x86_64 */ - {"Resources", "resources.png", callback_device_resources, scan_device_resources, MODULE_FLAG_NONE}, - {NULL} -}; - -static GHashTable *moreinfo = NULL; -static GSList *processors = NULL; -static gchar *printer_list = NULL, *printer_icons = NULL; -static gchar *pci_list = NULL; -static gchar *input_list = NULL; -static gchar *storage_list = NULL; -static gchar *battery_list = NULL; -static gchar *meminfo = NULL, *lginterval = NULL; - -#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; \ - } - -#include - -typedef struct _Processor Processor; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(ARCH_i386) || defined(ARCH_x86_64) -#include -#endif /* x86 or x86_64 */ - -gchar *get_processor_name(void) -{ - scan_processors(FALSE); - - Processor *p = (Processor *) processors->data; - - if (g_slist_length(processors) > 1) { - return idle_free(g_strdup_printf("%dx %s", - g_slist_length(processors), - p->model_name)); - } else { - return p->model_name; - } -} - -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)); -} - -gchar *get_processor_frequency(void) -{ - Processor *p; - - scan_processors(FALSE); - - p = (Processor *)processors->data; - if (p->cpu_mhz == 0.0f) { - return g_strdup("Unknown"); - } else { - return g_strdup_printf("%.0f", p->cpu_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) -{ - /* FIXME */ - return g_strdup("0.0"); -} - -ShellModuleMethod *hi_exported_methods(void) -{ - static ShellModuleMethod m[] = { - {"getProcessorCount", get_processor_count}, - {"getProcessorName", get_processor_name}, - {"getProcessorFrequency", get_processor_frequency}, - {"getMemoryTotal", get_memory_total}, - {"getStorageDevices", get_storage_devices}, - {"getPrinters", get_printers}, - {"getInputDevices", get_input_devices}, - {"getPCIDeviceDescription", get_pci_device_description}, - {NULL} - }; - - return m; -} - -gchar *hi_more_info(gchar * entry) -{ - gchar *info = (gchar *) g_hash_table_lookup(moreinfo, entry); - - if (info) - return g_strdup(info); - - return g_strdup("?"); -} - -gchar *hi_get_field(gchar * field) -{ - gchar *info = (gchar *) g_hash_table_lookup(moreinfo, field); - - if (info) - return g_strdup(info); - - return g_strdup(field); -} - -#if defined(ARCH_i386) || defined(ARCH_x86_64) -void scan_dmi(gboolean reload) -{ - SCAN_START(); - __scan_dmi(); - SCAN_END(); -} -#endif - -void scan_processors(gboolean reload) -{ - SCAN_START(); - if (!processors) - processors = __scan_processors(); - SCAN_END(); -} - -void scan_memory(gboolean reload) -{ - SCAN_START(); - __scan_memory(); - SCAN_END(); -} - -void scan_battery(gboolean reload) -{ - SCAN_START(); - __scan_battery(); - SCAN_END(); -} - -void scan_pci(gboolean reload) -{ - SCAN_START(); - __scan_pci(); - SCAN_END(); -} - -void scan_sensors(gboolean reload) -{ - SCAN_START(); - __scan_sensors(); - SCAN_END(); -} - -void scan_printers(gboolean reload) -{ - SCAN_START(); - __scan_printers(); - 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_i386) || defined(ARCH_x86_64) -gchar *callback_dmi() -{ - return g_strdup(dmi_info); -} -#endif - -gchar *callback_memory() -{ - return g_strdup_printf("[Memory]\n" - "%s\n" - "[$ShellParam$]\n" - "ViewType=2\n" - "LoadGraphSuffix= kB\n" - "RescanInterval=2000\n" - "%s\n", meminfo, 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("[$ShellParam$]\n" - "ReloadInterval=5000\n" "%s", sensors); -} - -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 = "Update PCI ID listing", - .name = "GetPCIIds", - .save_to = "pci.ids", - .get_data = NULL - }; - - sync_manager_add_entry(&se); - } - -#if defined(ARCH_i386) || defined(ARCH_x86_64) - { - static SyncEntry se = { - .fancy_name = "Update CPU feature database", - .name = "RecvCPUFlags", - .save_to = "cpuflags.conf", - .get_data = NULL - }; - - sync_manager_add_entry(&se); - } -#endif /* defined(ARCH_i386) || defined(ARCH_x86_64) */ - - moreinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - __init_memory_labels(); - __init_cups(); -} - -void hi_module_deinit(void) -{ - h_hash_table_remove_all(moreinfo); - g_hash_table_destroy(moreinfo); - g_hash_table_destroy(memlabels); - g_module_close(cups); -} - -ModuleAbout *hi_module_get_about(void) -{ - static ModuleAbout ma[] = { - { - .author = "Leandro A. F. Pereira", - .description = "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; -} diff --git a/hardinfo2/egg-markdown.c b/hardinfo2/egg-markdown.c deleted file mode 100644 index 4056d4f9..00000000 --- a/hardinfo2/egg-markdown.c +++ /dev/null @@ -1,1586 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 Richard Hughes - * Copyright (C) 2009 Leandro Pereira - * - * 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. - */ - -#include "config.h" - -#define _GNU_SOURCE -#include -#include -#include - -#include "egg-markdown.h" - -/******************************************************************************* - * - * This is a simple Markdown parser. - * It can output to Pango, HTML or plain text. The following limitations are - * already known, and properly deliberate: - * - * - No code section support - * - No ordered list support - * - No blockquote section support - * - No image support - * - No links or email support - * - No backslash escapes support - * - No HTML escaping support - * - Auto-escapes certain word patterns, like http:// - * - * It does support the rest of the standard pretty well, although it's not - * been run against any conformance tests. The parsing is single pass, with - * a simple enumerated intepretor mode and a single line back-memory. - * - ******************************************************************************/ - -static void egg_markdown_finalize (GObject *object); - -#define EGG_MARKDOWN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_MARKDOWN, EggMarkdownPrivate)) - -typedef gchar *(EggMarkdownLinkBuilder)(gchar *title, gchar *uri, gint link_id); -typedef gchar *(EggMarkdownImageBuilder)(gchar *alt_text, gchar *path, gint link_id); - -typedef enum { - EGG_MARKDOWN_MODE_BLANK, - EGG_MARKDOWN_MODE_RULE, - EGG_MARKDOWN_MODE_BULLETT, - EGG_MARKDOWN_MODE_PARA, - EGG_MARKDOWN_MODE_H1, - EGG_MARKDOWN_MODE_H2, - EGG_MARKDOWN_MODE_UNKNOWN -} EggMarkdownMode; - -typedef struct { - const gchar *em_start; - const gchar *em_end; - const gchar *strong_start; - const gchar *strong_end; - const gchar *code_start; - const gchar *code_end; - const gchar *h1_start; - const gchar *h1_end; - const gchar *h2_start; - const gchar *h2_end; - const gchar *bullett_start; - const gchar *bullett_end; - const gchar *rule; - - EggMarkdownLinkBuilder *link_builder; - EggMarkdownImageBuilder *image_builder; -} EggMarkdownTags; - -struct EggMarkdownPrivate -{ - EggMarkdownMode mode; - EggMarkdownTags tags; - EggMarkdownOutput output; - gint max_lines; - guint line_count; - gboolean smart_quoting; - gboolean escape; - gboolean autocode; - GString *pending; - GString *processed; - GArray *link_table; -}; - -G_DEFINE_TYPE (EggMarkdown, egg_markdown, G_TYPE_OBJECT) - -/** - * egg_markdown_to_text_line_is_rule: - * - * Horizontal rules are created by placing three or more hyphens, asterisks, - * or underscores on a line by themselves. - * You may use spaces between the hyphens or asterisks. - **/ -static gboolean -egg_markdown_to_text_line_is_rule (const gchar *line) -{ - guint i; - guint len; - guint count = 0; - gchar *copy = NULL; - gboolean ret = FALSE; - - len = strnlen (line, EGG_MARKDOWN_MAX_LINE_LENGTH); - if (len == 0) - goto out; - - /* replace non-rule chars with ~ */ - copy = g_strdup (line); - g_strcanon (copy, "-*_ ", '~'); - for (i=0; i= 3) - ret = TRUE; -out: - g_free (copy); - return ret; -} - -/** - * egg_markdown_to_text_line_is_bullett: - **/ -static gboolean -egg_markdown_to_text_line_is_bullett (const gchar *line) -{ - return (g_str_has_prefix (line, "- ") || - g_str_has_prefix (line, "* ") || - g_str_has_prefix (line, "+ ") || - g_str_has_prefix (line, " - ") || - g_str_has_prefix (line, " * ") || - g_str_has_prefix (line, " + ")); -} - -/** - * egg_markdown_to_text_line_is_header1: - **/ -static gboolean -egg_markdown_to_text_line_is_header1 (const gchar *line) -{ - return g_str_has_prefix (line, "# "); -} - -/** - * egg_markdown_to_text_line_is_header2: - **/ -static gboolean -egg_markdown_to_text_line_is_header2 (const gchar *line) -{ - return g_str_has_prefix (line, "## "); -} - -/** - * egg_markdown_to_text_line_is_header1_type2: - **/ -static gboolean -egg_markdown_to_text_line_is_header1_type2 (const gchar *line) -{ - return g_str_has_prefix (line, "==="); -} - -/** - * egg_markdown_to_text_line_is_header2_type2: - **/ -static gboolean -egg_markdown_to_text_line_is_header2_type2 (const gchar *line) -{ - return g_str_has_prefix (line, "---"); -} - -#if 0 -/** - * egg_markdown_to_text_line_is_code: - **/ -static gboolean -egg_markdown_to_text_line_is_code (const gchar *line) -{ - return (g_str_has_prefix (line, " ") || g_str_has_prefix (line, "\t")); -} - -/** - * egg_markdown_to_text_line_is_blockquote: - **/ -static gboolean -egg_markdown_to_text_line_is_blockquote (const gchar *line) -{ - return (g_str_has_prefix (line, "> ")); -} -#endif - -/** - * egg_markdown_to_text_line_is_blank: - **/ -static gboolean -egg_markdown_to_text_line_is_blank (const gchar *line) -{ - guint i; - guint len; - gboolean ret = FALSE; - - len = strnlen (line, EGG_MARKDOWN_MAX_LINE_LENGTH); - - /* a line with no characters is blank by definition */ - if (len == 0) { - ret = TRUE; - goto out; - } - - /* find if there are only space chars */ - for (i=0; ipriv->link_table, path_copy); - - formatted_img = self->priv->tags.image_builder(alt_text, - path, - self->priv->link_table->len - 1); - - data = g_strdup_printf ("%s%s%s", - start, formatted_img, end); - - g_free(formatted_img); - } else { - /* not found, keep return as-is */ - data = g_strdup (line); - } - - g_free (copy); - return data; -} - - -/** - * egg_markdown_to_text_line_formatter_link: - **/ -static gchar * -egg_markdown_to_text_line_formatter_link (EggMarkdown *self, const gchar *line) -{ - const guint len = 1; /* needed to know for shifts */ - gchar *str1; - gchar *str2; - gchar *start = NULL; - gchar *link = NULL; - gchar *link_title = NULL; - gchar *end = NULL; - gchar *copy = NULL; - gchar *data = NULL; - - /* find sections */ - copy = g_strdup (line); - str1 = egg_markdown_strstr_spaces (copy, "["); - if (str1 != NULL) { - *str1 = '\0'; - str2 = egg_markdown_strstr_spaces (str1+len, "]"); - if (str2 != NULL) { - *str2 = '\0'; - start = copy; - link = str1 + len; - end = str2 + len; - - str2 = strstr (link, " "); - if (str2 != NULL) { - *str2 = '\0'; - link_title = str2 + len; - } - } - } - - /* if we found, replace and keep looking for the same string */ - if (start && (link && *link) && link_title && end) { - gchar *formatted_link; - gchar *link_copy = g_strdup(link); - - g_array_append_val(self->priv->link_table, link_copy); - - formatted_link = self->priv->tags.link_builder(link_title, - link, - self->priv->link_table->len - 1); - - data = g_strdup_printf ("%s%s%s", - start, formatted_link, end); - - g_free(formatted_link); - } else { - /* not found, keep return as-is */ - data = g_strdup (line); - } - - g_free (copy); - return data; -} - -void -egg_markdown_clear(EggMarkdown *self) -{ - int i; - - for (i = 0; i < self->priv->link_table->len; i++) { - g_free(g_array_index(self->priv->link_table, gchar *, i)); - } - - g_array_free(self->priv->link_table, TRUE); - self->priv->link_table = g_array_new(FALSE, FALSE, sizeof(gchar *)); -} - -gchar * -egg_markdown_get_link_uri(EggMarkdown *self, const gint link_id) -{ - g_return_val_if_fail(link_id < self->priv->link_table->len, NULL); - - return g_strdup(g_array_index(self->priv->link_table, gchar *, link_id)); -} - -/** - * egg_markdown_to_text_line_format_sections: - **/ -static gchar * -egg_markdown_to_text_line_format_sections (EggMarkdown *self, const gchar *line) -{ - gchar *data = g_strdup (line); - gchar *temp; - - /* smart quoting */ - if (self->priv->smart_quoting) { - if (self->priv->escape) { - temp = data; - data = egg_markdown_to_text_line_formatter (temp, """, "“", "â€"); - g_free (temp); - - temp = data; - data = egg_markdown_to_text_line_formatter (temp, "'", "‘", "’"); - g_free (temp); - } else { - temp = data; - data = egg_markdown_to_text_line_formatter (temp, "\"", "“", "â€"); - g_free (temp); - - temp = data; - data = egg_markdown_to_text_line_formatter (temp, "'", "‘", "’"); - g_free (temp); - } - } - - /* image */ - temp = data; - data = egg_markdown_to_text_line_formatter_image (self, temp); - g_free(temp); - - /* link */ - temp = data; - data = egg_markdown_to_text_line_formatter_link (self, temp); - g_free(temp); - - /* bold1 */ - temp = data; - data = egg_markdown_to_text_line_formatter (temp, "**", self->priv->tags.strong_start, self->priv->tags.strong_end); - g_free (temp); - - /* bold2 */ - temp = data; - data = egg_markdown_to_text_line_formatter (temp, "__", self->priv->tags.strong_start, self->priv->tags.strong_end); - g_free (temp); - - /* italic1 */ - temp = data; - data = egg_markdown_to_text_line_formatter (temp, "*", self->priv->tags.em_start, self->priv->tags.em_end); - g_free (temp); - - /* italic2 */ - temp = data; - data = egg_markdown_to_text_line_formatter (temp, "_", self->priv->tags.em_start, self->priv->tags.em_end); - g_free (temp); - - /* em-dash */ - temp = data; - data = egg_markdown_replace (temp, " -- ", " — "); - g_free (temp); - - return data; -} - -/** - * egg_markdown_to_text_line_format: - **/ -static gchar * -egg_markdown_to_text_line_format (EggMarkdown *self, const gchar *line) -{ - guint i; - gchar *text; - gboolean mode = FALSE; - gchar **codes; - GString *string; - - /* optimise the trivial case where we don't have any code tags */ - text = strstr (line, "`"); - if (text == NULL) { - text = egg_markdown_to_text_line_format_sections (self, line); - goto out; - } - - /* we want to parse the code sections without formatting */ - codes = g_strsplit (line, "`", -1); - string = g_string_new (""); - for (i=0; codes[i] != NULL; i++) { - if (!mode) { - text = egg_markdown_to_text_line_format_sections (self, codes[i]); - g_string_append (string, text); - g_free (text); - mode = TRUE; - } else { - /* just append without formatting */ - g_string_append (string, self->priv->tags.code_start); - g_string_append (string, codes[i]); - g_string_append (string, self->priv->tags.code_end); - mode = FALSE; - } - } - text = g_string_free (string, FALSE); -out: - return text; -} - -/** - * egg_markdown_add_pending: - **/ -static gboolean -egg_markdown_add_pending (EggMarkdown *self, const gchar *line) -{ - gchar *copy; - - /* would put us over the limit */ - if (self->priv->line_count >= self->priv->max_lines) - return FALSE; - - copy = g_strdup (line); - - /* strip leading and trailing spaces */ - g_strstrip (copy); - - /* append */ - g_string_append_printf (self->priv->pending, "%s ", copy); - - g_free (copy); - return TRUE; -} - -/** - * egg_markdown_add_pending_header: - **/ -static gboolean -egg_markdown_add_pending_header (EggMarkdown *self, const gchar *line) -{ - gchar *copy; - gboolean ret; - - /* strip trailing # */ - copy = g_strdup (line); - g_strdelimit (copy, "#", ' '); - ret = egg_markdown_add_pending (self, copy); - g_free (copy); - return ret; -} - -/** - * egg_markdown_count_chars_in_word: - **/ -static guint -egg_markdown_count_chars_in_word (const gchar *text, gchar find) -{ - guint i; - guint len; - guint count = 0; - - /* get length */ - len = strnlen (text, EGG_MARKDOWN_MAX_LINE_LENGTH); - if (len == 0) - goto out; - - /* find matching chars */ - for (i=0; i 1) - return TRUE; - - /* nothing special */ - return FALSE; -} - -/** - * egg_markdown_word_auto_format_code: - **/ -static gchar * -egg_markdown_word_auto_format_code (const gchar *text) -{ - guint i; - gchar *temp; - gchar **words; - gboolean ret = FALSE; - - /* split sentence up with space */ - words = g_strsplit (text, " ", -1); - - /* search each word */ - for (i=0; words[i] != NULL; i++) { - if (egg_markdown_word_is_code (words[i])) { - temp = g_strdup_printf ("`%s`", words[i]); - g_free (words[i]); - words[i] = temp; - ret = TRUE; - } - } - - /* no replacements, so just return a copy */ - if (!ret) { - temp = g_strdup (text); - goto out; - } - - /* join the array back into a string */ - temp = g_strjoinv (" ", words); -out: - g_strfreev (words); - return temp; -} - -/** - * egg_markdown_flush_pending: - **/ -static void -egg_markdown_flush_pending (EggMarkdown *self) -{ - gchar *copy; - gchar *temp; - - /* no data yet */ - if (self->priv->mode == EGG_MARKDOWN_MODE_UNKNOWN) - return; - - /* remove trailing spaces */ - while (g_str_has_suffix (self->priv->pending->str, " ")) - g_string_set_size (self->priv->pending, self->priv->pending->len - 1); - - /* pango requires escaping */ - copy = g_strdup (self->priv->pending->str); - if (!self->priv->escape && self->priv->output == EGG_MARKDOWN_OUTPUT_PANGO) { - g_strdelimit (copy, "<", '('); - g_strdelimit (copy, ">", ')'); - } - - /* check words for code */ - if (self->priv->autocode && - (self->priv->mode == EGG_MARKDOWN_MODE_PARA || - self->priv->mode == EGG_MARKDOWN_MODE_BULLETT)) { - temp = egg_markdown_word_auto_format_code (copy); - g_free (copy); - copy = temp; - } - - /* escape */ - if (self->priv->escape) { - temp = g_markup_escape_text (copy, -1); - g_free (copy); - copy = temp; - } - - /* do formatting */ - temp = egg_markdown_to_text_line_format (self, copy); - if (self->priv->mode == EGG_MARKDOWN_MODE_BULLETT) { - g_string_append_printf (self->priv->processed, "%s%s%s\n", self->priv->tags.bullett_start, temp, self->priv->tags.bullett_end); - self->priv->line_count++; - } else if (self->priv->mode == EGG_MARKDOWN_MODE_H1) { - g_string_append_printf (self->priv->processed, "%s%s%s\n", self->priv->tags.h1_start, temp, self->priv->tags.h1_end); - } else if (self->priv->mode == EGG_MARKDOWN_MODE_H2) { - g_string_append_printf (self->priv->processed, "%s%s%s\n", self->priv->tags.h2_start, temp, self->priv->tags.h2_end); - } else if (self->priv->mode == EGG_MARKDOWN_MODE_PARA || - self->priv->mode == EGG_MARKDOWN_MODE_RULE) { - g_string_append_printf (self->priv->processed, "%s\n", temp); - self->priv->line_count++; - } - - DEBUG ("adding '%s'", temp); - - /* clear */ - g_string_truncate (self->priv->pending, 0); - g_free (copy); - g_free (temp); -} - -/** - * egg_markdown_to_text_line_process: - **/ -static gboolean -egg_markdown_to_text_line_process (EggMarkdown *self, const gchar *line) -{ - gboolean ret; - - /* blank */ - ret = egg_markdown_to_text_line_is_blank (line); - if (ret) { - DEBUG ("blank: '%s'", line); - egg_markdown_flush_pending (self); - /* a new line after a list is the end of list, not a gap */ - if (self->priv->mode != EGG_MARKDOWN_MODE_BULLETT) - ret = egg_markdown_add_pending (self, "\n"); - self->priv->mode = EGG_MARKDOWN_MODE_BLANK; - goto out; - } - - /* header1_type2 */ - ret = egg_markdown_to_text_line_is_header1_type2 (line); - if (ret) { - DEBUG ("header1_type2: '%s'", line); - if (self->priv->mode == EGG_MARKDOWN_MODE_PARA) - self->priv->mode = EGG_MARKDOWN_MODE_H1; - goto out; - } - - /* header2_type2 */ - ret = egg_markdown_to_text_line_is_header2_type2 (line); - if (ret) { - DEBUG ("header2_type2: '%s'", line); - if (self->priv->mode == EGG_MARKDOWN_MODE_PARA) - self->priv->mode = EGG_MARKDOWN_MODE_H2; - goto out; - } - - /* rule */ - ret = egg_markdown_to_text_line_is_rule (line); - if (ret) { - DEBUG ("rule: '%s'", line); - egg_markdown_flush_pending (self); - self->priv->mode = EGG_MARKDOWN_MODE_RULE; - ret = egg_markdown_add_pending (self, self->priv->tags.rule); - goto out; - } - - /* bullett */ - ret = egg_markdown_to_text_line_is_bullett (line); - if (ret) { - DEBUG ("bullett: '%s'", line); - egg_markdown_flush_pending (self); - self->priv->mode = EGG_MARKDOWN_MODE_BULLETT; - ret = egg_markdown_add_pending (self, &line[2]); - goto out; - } - - /* header1 */ - ret = egg_markdown_to_text_line_is_header1 (line); - if (ret) { - DEBUG ("header1: '%s'", line); - egg_markdown_flush_pending (self); - self->priv->mode = EGG_MARKDOWN_MODE_H1; - ret = egg_markdown_add_pending_header (self, &line[2]); - goto out; - } - - /* header2 */ - ret = egg_markdown_to_text_line_is_header2 (line); - if (ret) { - DEBUG ("header2: '%s'", line); - egg_markdown_flush_pending (self); - self->priv->mode = EGG_MARKDOWN_MODE_H2; - ret = egg_markdown_add_pending_header (self, &line[3]); - goto out; - } - - /* paragraph */ - if (self->priv->mode == EGG_MARKDOWN_MODE_BLANK || self->priv->mode == EGG_MARKDOWN_MODE_UNKNOWN) { - egg_markdown_flush_pending (self); - self->priv->mode = EGG_MARKDOWN_MODE_PARA; - } - - /* add to pending */ - DEBUG ("continue: '%s'", line); - ret = egg_markdown_add_pending (self, line); -out: - /* if we failed to add, we don't know the mode */ - if (!ret) - self->priv->mode = EGG_MARKDOWN_MODE_UNKNOWN; - return ret; -} - -/** - * egg_markdown_linkbuilder_pango: - **/ -static gchar * -egg_markdown_linkbuilder_pango (gchar *title, gchar *uri, gint link_id) -{ - /* FIXME: This is a nasty hack, since extending Pango markup to allow new tags - * is too complicated. We use the language code as a link index - * since it won't allow anything besides letters or numbers. - * To obtain the link URI, use egg_markdown_get_link_uri(). */ - return g_strdup_printf("%s", - link_id, title); -} - -/** - * egg_markdown_linkbuilder_html - **/ -static gchar * -egg_markdown_linkbuilder_html (gchar *title, gchar *uri, gint link_id) -{ - return g_strdup_printf("%s", uri, title); -} - -/** - * egg_markdown_linkbuilder_text - **/ -static gchar * -egg_markdown_linkbuilder_text (gchar *title, gchar *uri, gint link_id) -{ - return g_strdup_printf("%s (%s)", title, uri); -} - -/** - * egg_markdown_imagebuilder_pango: - **/ -static gchar * -egg_markdown_imagebuilder_pango (gchar *alt_text, gchar *uri, gint link_id) -{ - /* FIXME See egg_markdown_linkbuilder_pango() */ - return g_strdup_printf("%s", - link_id, alt_text); -} - -/** - * egg_markdown_imagebuilder_html - **/ -static gchar * -egg_markdown_imagebuilder_html (gchar *alt_text, gchar *uri, gint link_id) -{ - return g_strdup_printf("\"%s\"", uri, alt_text); -} - -/** - * egg_markdown_imagebuilder_text - **/ -static gchar * -egg_markdown_imagebuilder_text (gchar *alt_text, gchar *uri, gint link_id) -{ - return g_strdup(alt_text); -} - -/** - * egg_markdown_set_output: - **/ -gboolean -egg_markdown_set_output (EggMarkdown *self, EggMarkdownOutput output) -{ - gboolean ret = TRUE; - g_return_val_if_fail (EGG_IS_MARKDOWN (self), FALSE); - - /* PangoMarkup */ - if (output == EGG_MARKDOWN_OUTPUT_PANGO) { - self->priv->tags.em_start = ""; - self->priv->tags.em_end = ""; - self->priv->tags.strong_start = ""; - self->priv->tags.strong_end = ""; - self->priv->tags.code_start = ""; - self->priv->tags.code_end = ""; - self->priv->tags.h1_start = ""; - self->priv->tags.h1_end = ""; - self->priv->tags.h2_start = ""; - self->priv->tags.h2_end = ""; - self->priv->tags.bullett_start = " • "; - self->priv->tags.bullett_end = ""; - self->priv->tags.rule = "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯\n"; - self->priv->tags.link_builder = egg_markdown_linkbuilder_pango; - self->priv->tags.image_builder = egg_markdown_imagebuilder_pango; - - /* XHTML */ - } else if (output == EGG_MARKDOWN_OUTPUT_HTML) { - self->priv->tags.em_start = ""; - self->priv->tags.em_end = ""; - self->priv->tags.strong_start = ""; - self->priv->tags.strong_end = ""; - self->priv->tags.code_start = ""; - self->priv->tags.code_end = ""; - self->priv->tags.h1_start = "

"; - self->priv->tags.h1_end = "

"; - self->priv->tags.h2_start = "

"; - self->priv->tags.h2_end = "

"; - self->priv->tags.bullett_start = "
  • "; - self->priv->tags.bullett_end = "
  • "; - self->priv->tags.rule = "
    "; - self->priv->tags.link_builder = egg_markdown_linkbuilder_html; - self->priv->tags.image_builder = egg_markdown_imagebuilder_html; - - /* plain text */ - } else if (output == EGG_MARKDOWN_OUTPUT_TEXT) { - self->priv->tags.em_start = ""; - self->priv->tags.em_end = ""; - self->priv->tags.strong_start = ""; - self->priv->tags.strong_end = ""; - self->priv->tags.code_start = ""; - self->priv->tags.code_end = ""; - self->priv->tags.h1_start = "["; - self->priv->tags.h1_end = "]"; - self->priv->tags.h2_start = "-"; - self->priv->tags.h2_end = "-"; - self->priv->tags.bullett_start = "* "; - self->priv->tags.bullett_end = ""; - self->priv->tags.rule = " ----- \n"; - self->priv->tags.link_builder = egg_markdown_linkbuilder_text; - self->priv->tags.image_builder = egg_markdown_imagebuilder_text; - - /* unknown */ - } else { - g_warning ("unknown output enum"); - ret = FALSE; - } - - /* save if valid */ - if (ret) - self->priv->output = output; - return ret; -} - -/** - * egg_markdown_set_max_lines: - **/ -gboolean -egg_markdown_set_max_lines (EggMarkdown *self, gint max_lines) -{ - g_return_val_if_fail (EGG_IS_MARKDOWN (self), FALSE); - self->priv->max_lines = max_lines; - return TRUE; -} - -/** - * egg_markdown_set_smart_quoting: - **/ -gboolean -egg_markdown_set_smart_quoting (EggMarkdown *self, gboolean smart_quoting) -{ - g_return_val_if_fail (EGG_IS_MARKDOWN (self), FALSE); - self->priv->smart_quoting = smart_quoting; - return TRUE; -} - -/** - * egg_markdown_set_escape: - **/ -gboolean -egg_markdown_set_escape (EggMarkdown *self, gboolean escape) -{ - g_return_val_if_fail (EGG_IS_MARKDOWN (self), FALSE); - self->priv->escape = escape; - return TRUE; -} - -/** - * egg_markdown_set_autocode: - **/ -gboolean -egg_markdown_set_autocode (EggMarkdown *self, gboolean autocode) -{ - g_return_val_if_fail (EGG_IS_MARKDOWN (self), FALSE); - self->priv->autocode = autocode; - return TRUE; -} - -/** - * egg_markdown_parse: - **/ -gchar * -egg_markdown_parse (EggMarkdown *self, const gchar *markdown) -{ - gchar **lines; - guint i; - guint len; - gchar *temp; - gboolean ret; - - g_return_val_if_fail (EGG_IS_MARKDOWN (self), NULL); - g_return_val_if_fail (self->priv->output != EGG_MARKDOWN_OUTPUT_UNKNOWN, NULL); - - DEBUG ("input='%s'", markdown); - - /* process */ - self->priv->mode = EGG_MARKDOWN_MODE_UNKNOWN; - self->priv->line_count = 0; - g_string_truncate (self->priv->pending, 0); - g_string_truncate (self->priv->processed, 0); - lines = g_strsplit (markdown, "\n", -1); - len = g_strv_length (lines); - - /* process each line */ - for (i=0; ipriv->processed->str, "\n")) - g_string_set_size (self->priv->processed, self->priv->processed->len - 1); - - /* get a copy */ - temp = g_strdup (self->priv->processed->str); - g_string_truncate (self->priv->pending, 0); - g_string_truncate (self->priv->processed, 0); - - DEBUG ("output='%s'", temp); - - return temp; -} - -/** - * egg_markdown_class_init: - * @klass: The EggMarkdownClass - **/ -static void -egg_markdown_class_init (EggMarkdownClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = egg_markdown_finalize; - g_type_class_add_private (klass, sizeof (EggMarkdownPrivate)); -} - -/** - * egg_markdown_init: - **/ -static void -egg_markdown_init (EggMarkdown *self) -{ - self->priv = EGG_MARKDOWN_GET_PRIVATE (self); - - self->priv->mode = EGG_MARKDOWN_MODE_UNKNOWN; - self->priv->output = EGG_MARKDOWN_OUTPUT_UNKNOWN; - self->priv->pending = g_string_new (""); - self->priv->processed = g_string_new (""); - self->priv->link_table = g_array_new(FALSE, FALSE, sizeof(gchar *)); - self->priv->max_lines = -1; - self->priv->smart_quoting = FALSE; - self->priv->escape = FALSE; - self->priv->autocode = FALSE; -} - -/** - * egg_markdown_finalize: - * @object: The object to finalize - **/ -static void -egg_markdown_finalize (GObject *object) -{ - EggMarkdown *self; - int i; - - g_return_if_fail (EGG_IS_MARKDOWN (object)); - - self = EGG_MARKDOWN (object); - - g_return_if_fail (self->priv != NULL); - g_string_free (self->priv->pending, TRUE); - g_string_free (self->priv->processed, TRUE); - - for (i = 0; i < self->priv->link_table->len; i++) { - g_free(g_array_index(self->priv->link_table, gchar *, i)); - } - g_array_free (self->priv->link_table, TRUE); - - G_OBJECT_CLASS (egg_markdown_parent_class)->finalize (object); -} - -/** - * egg_markdown_new: - * - * Return value: a new EggMarkdown object. - **/ -EggMarkdown * -egg_markdown_new (void) -{ - EggMarkdown *self; - self = g_object_new (EGG_TYPE_MARKDOWN, NULL); - return EGG_MARKDOWN (self); -} - -/*************************************************************************** - *** MAKE CHECK TESTS *** - ***************************************************************************/ -#ifdef EGG_TEST -#include "egg-test.h" - -void -egg_markdown_test (EggTest *test) -{ - EggMarkdown *self; - gchar *text; - gboolean ret; - const gchar *markdown; - const gchar *markdown_expected; - - if (!egg_test_start (test, "EggMarkdown")) - return; - - /************************************************************ - **************** line_is_rule ************** - ************************************************************/ - ret = egg_markdown_to_text_line_is_rule ("* * *"); - egg_test_title_assert (test, "is rule (1)", ret); - - /************************************************************/ - ret = egg_markdown_to_text_line_is_rule ("***"); - egg_test_title_assert (test, "is rule (2)", ret); - - /************************************************************/ - ret = egg_markdown_to_text_line_is_rule ("*****"); - egg_test_title_assert (test, "is rule (3)", ret); - - /************************************************************/ - ret = egg_markdown_to_text_line_is_rule ("- - -"); - egg_test_title_assert (test, "is rule (4)", ret); - - /************************************************************/ - ret = egg_markdown_to_text_line_is_rule ("---------------------------------------"); - egg_test_title_assert (test, "is rule (5)", ret); - - /************************************************************/ - ret = egg_markdown_to_text_line_is_rule (""); - egg_test_title_assert (test, "is rule (blank)", !ret); - - /************************************************************/ - ret = egg_markdown_to_text_line_is_rule ("richard hughes"); - egg_test_title_assert (test, "is rule (text)", !ret); - - /************************************************************/ - ret = egg_markdown_to_text_line_is_rule ("- richard-hughes"); - egg_test_title_assert (test, "is rule (bullet)", !ret); - - /************************************************************/ - ret = egg_markdown_to_text_line_is_blank (""); - egg_test_title_assert (test, "is blank (blank)", ret); - - /************************************************************/ - ret = egg_markdown_to_text_line_is_blank (" \t "); - egg_test_title_assert (test, "is blank (mix)", ret); - - /************************************************************/ - ret = egg_markdown_to_text_line_is_blank ("richard hughes"); - egg_test_title_assert (test, "is blank (name)", !ret); - - /************************************************************/ - ret = egg_markdown_to_text_line_is_blank ("ccccccccc"); - egg_test_title_assert (test, "is blank (full)", !ret); - - - /************************************************************ - **************** replace ************** - ************************************************************/ - text = egg_markdown_replace ("summary -- really -- sure!", " -- ", " – "); - egg_test_title (test, "replace (multiple)"); - if (g_str_equal (text, "summary – really – sure!")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got %s", text); - g_free (text); - - /************************************************************ - **************** formatter ************** - ************************************************************/ - text = egg_markdown_to_text_line_formatter ("**is important** text", "**", "", ""); - egg_test_title (test, "formatter (left)"); - if (g_str_equal (text, "is important text")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got %s", text); - g_free (text); - - /************************************************************/ - text = egg_markdown_to_text_line_formatter ("this is **important**", "**", "", ""); - egg_test_title (test, "formatter (right)"); - if (g_str_equal (text, "this is important")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got %s", text); - g_free (text); - - /************************************************************/ - text = egg_markdown_to_text_line_formatter ("**important**", "**", "", ""); - egg_test_title (test, "formatter (only)"); - if (g_str_equal (text, "important")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got %s", text); - g_free (text); - - /************************************************************/ - text = egg_markdown_to_text_line_formatter ("***important***", "**", "", ""); - egg_test_title (test, "formatter (only)"); - if (g_str_equal (text, "*important*")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got %s", text); - g_free (text); - - /************************************************************/ - text = egg_markdown_to_text_line_formatter ("I guess * this is * not bold", "*", "", ""); - egg_test_title (test, "formatter (with spaces)"); - if (g_str_equal (text, "I guess * this is * not bold")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got %s", text); - g_free (text); - - /************************************************************/ - text = egg_markdown_to_text_line_formatter ("this **is important** text in **several** places", "**", "", ""); - egg_test_title (test, "formatter (middle, multiple)"); - if (g_str_equal (text, "this is important text in several places")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got %s", text); - g_free (text); - - /************************************************************/ - text = egg_markdown_word_auto_format_code ("this is http://www.hughsie.com/with_spaces_in_url inline link"); - egg_test_title (test, "auto formatter (url)"); - if (g_str_equal (text, "this is `http://www.hughsie.com/with_spaces_in_url` inline link")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got %s", text); - g_free (text); - - /************************************************************/ - text = egg_markdown_to_text_line_formatter ("this was \"triffic\" it was", "\"", "“", "â€"); - egg_test_title (test, "formatter (quotes)"); - if (g_str_equal (text, "this was “triffic†it was")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got %s", text); - g_free (text); - - /************************************************************/ - text = egg_markdown_to_text_line_formatter ("This isn't a present", "'", "‘", "’"); - egg_test_title (test, "formatter (one quote)"); - if (g_str_equal (text, "This isn't a present")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got %s", text); - g_free (text); - - /************************************************************ - **************** markdown ************** - ************************************************************/ - egg_test_title (test, "get EggMarkdown object"); - self = egg_markdown_new (); - egg_test_assert (test, self != NULL); - - /************************************************************/ - ret = egg_markdown_set_output (self, EGG_MARKDOWN_OUTPUT_PANGO); - egg_test_title_assert (test, "set pango output", ret); - - /************************************************************/ - markdown = "OEMs\n" - "====\n" - " - Bullett\n"; - markdown_expected = - "OEMs\n" - "• Bullett"; - egg_test_title (test, "markdown (type2 header)"); - text = egg_markdown_parse (self, markdown); - if (g_str_equal (text, markdown_expected)) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); - g_free (text); - - - /************************************************************/ - markdown = "this is http://www.hughsie.com/with_spaces_in_url inline link\n"; - markdown_expected = "this is http://www.hughsie.com/with_spaces_in_url inline link"; - egg_test_title (test, "markdown (autocode)"); - egg_markdown_set_autocode (self, TRUE); - text = egg_markdown_parse (self, markdown); - if (g_str_equal (text, markdown_expected)) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); - g_free (text); - - /************************************************************/ - markdown = "*** This software is currently in alpha state ***\n"; - markdown_expected = " This software is currently in alpha state "; - egg_test_title (test, "markdown some invalid header"); - text = egg_markdown_parse (self, markdown); - if (g_str_equal (text, markdown_expected)) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); - g_free (text); - - /************************************************************/ - markdown = " - This is a *very*\n" - " short paragraph\n" - " that is not usual.\n" - " - Another"; - markdown_expected = - "• This is a very short paragraph that is not usual.\n" - "• Another"; - egg_test_title (test, "markdown (complex1)"); - text = egg_markdown_parse (self, markdown); - if (g_str_equal (text, markdown_expected)) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); - g_free (text); - - /************************************************************/ - markdown = "* This is a *very*\n" - " short paragraph\n" - " that is not usual.\n" - "* This is the second\n" - " bullett point.\n" - "* And the third.\n" - " \n" - "* * *\n" - " \n" - "Paragraph one\n" - "isn't __very__ long at all.\n" - "\n" - "Paragraph two\n" - "isn't much better."; - markdown_expected = - "• This is a very short paragraph that is not usual.\n" - "• This is the second bullett point.\n" - "• And the third.\n" - "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯\n" - "Paragraph one isn't very long at all.\n" - "Paragraph two isn't much better."; - egg_test_title (test, "markdown (complex1)"); - text = egg_markdown_parse (self, markdown); - if (g_str_equal (text, markdown_expected)) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); - g_free (text); - - /************************************************************/ - markdown = "This is a spec file description or\n" - "an **update** description in bohdi.\n" - "\n" - "* * *\n" - "# Big title #\n" - "\n" - "The *following* things 'were' fixed:\n" - "- Fix `dave`\n" - "* Fubar update because of \"security\"\n"; - markdown_expected = - "This is a spec file description or an update description in bohdi.\n" - "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯\n" - "Big title\n" - "The following things 'were' fixed:\n" - "• Fix dave\n" - "• Fubar update because of \"security\""; - egg_test_title (test, "markdown (complex2)"); - text = egg_markdown_parse (self, markdown); - if (g_str_equal (text, markdown_expected)) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); - g_free (text); - - /************************************************************/ - markdown = "* list seporated with spaces -\n" - " first item\n" - "\n" - "* second item\n" - "\n" - "* third item\n"; - markdown_expected = - "• list seporated with spaces - first item\n" - "• second item\n" - "• third item"; - egg_test_title (test, "markdown (list with spaces)"); - text = egg_markdown_parse (self, markdown); - if (g_str_equal (text, markdown_expected)) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); - g_free (text); - - /************************************************************/ - ret = egg_markdown_set_max_lines (self, 1); - egg_test_title_assert (test, "set max_lines", ret); - - /************************************************************/ - markdown = "* list seporated with spaces -\n" - " first item\n" - "* second item\n"; - markdown_expected = - "• list seporated with spaces - first item"; - egg_test_title (test, "markdown (one line limit)"); - text = egg_markdown_parse (self, markdown); - if (g_str_equal (text, markdown_expected)) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); - g_free (text); - - /************************************************************/ - ret = egg_markdown_set_max_lines (self, 1); - egg_test_title_assert (test, "set max_lines", ret); - - /************************************************************/ - markdown = "* list & spaces"; - markdown_expected = - "• list & spaces"; - egg_test_title (test, "markdown (escaping)"); - text = egg_markdown_parse (self, markdown); - if (g_str_equal (text, markdown_expected)) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); - g_free (text); - - /************************************************************/ - egg_test_title (test, "markdown (free text)"); - text = egg_markdown_parse (self, "This isn't a present"); - if (g_str_equal (text, "This isn't a present")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s'", text); - g_free (text); - - /************************************************************/ - egg_test_title (test, "markdown (autotext underscore)"); - text = egg_markdown_parse (self, "This isn't CONFIG_UEVENT_HELPER_PATH present"); - if (g_str_equal (text, "This isn't CONFIG_UEVENT_HELPER_PATH present")) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s'", text); - g_free (text); - - /************************************************************/ - markdown = "*Thu Mar 12 12:00:00 2009* Dan Walsh - 2.0.79-1\n" - "- Update to upstream \n" - " * Netlink socket handoff patch from Adam Jackson.\n" - " * AVC caching of compute_create results by Eric Paris.\n" - "\n" - "*Tue Mar 10 12:00:00 2009* Dan Walsh - 2.0.78-5\n" - "- Add patch from ajax to accellerate X SELinux \n" - "- Update eparis patch\n"; - markdown_expected = - "Thu Mar 12 12:00:00 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.79-1\n" - "• Update to upstream\n" - "• Netlink socket handoff patch from Adam Jackson.\n" - "• AVC caching of compute_create results by Eric Paris.\n" - "Tue Mar 10 12:00:00 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.78-5\n" - "• Add patch from ajax to accellerate X SELinux\n" - "• Update eparis patch"; - egg_test_title (test, "markdown (end of bullett)"); - egg_markdown_set_escape (self, TRUE); - ret = egg_markdown_set_max_lines (self, 1024); - text = egg_markdown_parse (self, markdown); - if (g_str_equal (text, markdown_expected)) - egg_test_success (test, NULL); - else - egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); - g_free (text); - - g_object_unref (self); - - egg_test_end (test); -} -#endif - diff --git a/hardinfo2/egg-markdown.h b/hardinfo2/egg-markdown.h deleted file mode 100644 index 4475b9f0..00000000 --- a/hardinfo2/egg-markdown.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 Richard Hughes - * Copyright (C) 2009 Leandro Pereira - * - * 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 - -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/hardinfo2/expr.c b/hardinfo2/expr.c deleted file mode 100644 index 32e303d7..00000000 --- a/hardinfo2/expr.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 -#include -#include -#include -#include - -#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/hardinfo2/expr.h b/hardinfo2/expr.h deleted file mode 100644 index 4bda6b72..00000000 --- a/hardinfo2/expr.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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/hardinfo2/fbench.c b/hardinfo2/fbench.c deleted file mode 100644 index df1b8e19..00000000 --- a/hardinfo2/fbench.c +++ /dev/null @@ -1,745 +0,0 @@ -/* - - John Walker's Floating Point Benchmark, derived from... - - Marinchip Interactive Lens Design System - - John Walker December 1980 - - By John Walker - http://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 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 -#include -#include -#ifndef INTRIG -#include -#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/hardinfo2/fftbench.c b/hardinfo2/fftbench.c deleted file mode 100644 index dc25dfd6..00000000 --- a/hardinfo2/fftbench.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - 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://www.coyotegulch.com - - 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 -#include -#include -#include -#include -#include - -#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); - lup_solve(fftbench); -} - -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/hardinfo2/fftbench.h b/hardinfo2/fftbench.h deleted file mode 100644 index 7c0afc3d..00000000 --- a/hardinfo2/fftbench.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __FFTBENCH_H__ -#define __FFTBENCH_H__ - -#include - -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/hardinfo2/guibench.c b/hardinfo2/guibench.c deleted file mode 100644 index b9573278..00000000 --- a/hardinfo2/guibench.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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 - -#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/hardinfo2/guibench.h b/hardinfo2/guibench.h deleted file mode 100644 index d24403bc..00000000 --- a/hardinfo2/guibench.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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/hardinfo2/hardinfo.c b/hardinfo2/hardinfo.c deleted file mode 100644 index d36da0aa..00000000 --- a/hardinfo2/hardinfo.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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 -#include - -#include -#include -#include -#include -#include -#include - -#include - -ProgramParameters params = { 0 }; - -int main(int argc, char **argv) -{ - GSList *modules; - - DEBUG("HardInfo version " VERSION ". Debug version."); - - DEBUG("g_thread_init()"); - if (!g_thread_supported()) - g_thread_init(NULL); - - /* parse all command line parameters */ - parameters_init(&argc, &argv, ¶ms); - - /* show version information and quit */ - if (params.show_version) { - g_print("HardInfo version " VERSION "\n"); - g_print - ("Copyright (C) 2003-2009 Leandro A. F. Pereira. See COPYING for details.\n\n"); - - g_print("Compile-time options:\n" - " Release version: %s (%s)\n" - " BinReloc enabled: %s\n" - " Data prefix: %s\n" - " Library prefix: %s\n" - " Compiled on: %s %s (%s)\n", - RELEASE ? "Yes" : "No (" VERSION ")", ARCH, - ENABLE_BINRELOC ? "Yes" : "No", - PREFIX, LIBPREFIX, PLATFORM, KERNEL, HOSTNAME); - - 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 permision.", - 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 && !params.run_xmlrpc_server) { - /* we only try to open the UI if the user didn't asked 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(); - - if (params.run_xmlrpc_server) { - g_type_init(); - - xmlrpc_server_init(); - xmlrpc_server_start(NULL); - } else 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 { - 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."); - } - - DEBUG("finished"); - return 0; -} diff --git a/hardinfo2/hardinfo.h b/hardinfo2/hardinfo.h deleted file mode 100644 index 48d0cf88..00000000 --- a/hardinfo2/hardinfo.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 -#include - -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 *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); -void tree_view_save_image(gchar *filename); - -/* 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) - -#endif /* __HARDINFO_H__ */ diff --git a/hardinfo2/hardinfo/hardinfo.c b/hardinfo2/hardinfo/hardinfo.c new file mode 100644 index 00000000..784a3c06 --- /dev/null +++ b/hardinfo2/hardinfo/hardinfo.c @@ -0,0 +1,161 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 +#include + +#include +#include +#include +#include +#include +#include + +#include + +ProgramParameters params = { 0 }; + +int main(int argc, char **argv) +{ + GSList *modules; + + DEBUG("HardInfo version " VERSION ". Debug version."); + + DEBUG("g_thread_init()"); + if (!g_thread_supported()) + g_thread_init(NULL); + + /* parse all command line parameters */ + parameters_init(&argc, &argv, ¶ms); + + /* show version information and quit */ + if (params.show_version) { + g_print("HardInfo version " VERSION "\n"); + g_print + ("Copyright (C) 2003-2009 Leandro A. F. Pereira. See COPYING for details.\n\n"); + + g_print("Compile-time options:\n" + " Release version: %s (%s)\n" + " BinReloc enabled: %s\n" + " Data prefix: %s\n" + " Library prefix: %s\n" + " Compiled on: %s %s (%s)\n", + RELEASE ? "Yes" : "No (" VERSION ")", ARCH, + ENABLE_BINRELOC ? "Yes" : "No", + PREFIX, LIBPREFIX, PLATFORM, KERNEL, HOSTNAME); + + 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 permision.", + 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 && !params.run_xmlrpc_server) { + /* we only try to open the UI if the user didn't asked 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(); + + if (params.run_xmlrpc_server) { + g_type_init(); + + xmlrpc_server_init(); + xmlrpc_server_start(NULL); + } else if (params.run_benchmark) { + gchar *result; + + result = module_call_method_param("benchmark::runBenchmark", params.run_benchmark); + if (!result) { + g_error("Unknown benchmark ``%s'' or libbenchmark.so not loaded", params.run_benchmark); + } else { + 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."); + } + + DEBUG("finished"); + return 0; +} diff --git a/hardinfo2/help-viewer.c b/hardinfo2/help-viewer.c deleted file mode 100644 index ace6ef37..00000000 --- a/hardinfo2/help-viewer.c +++ /dev/null @@ -1,514 +0,0 @@ -/* - * HelpViewer - Simple Help file browser - * Copyright (C) 2009 Leandro A. F. Pereira - * - * 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 - */ - -#define _GNU_SOURCE /* for strcasestr() */ -#include -#include -#include - -#include "config.h" -#include "shell.h" -#include "markdown-text-view.h" -#include "help-viewer.h" -#include "hardinfo.h" - -static void do_search(HelpViewer *hv, gchar *text); - -static void forward_clicked(GtkWidget *widget, gpointer data) -{ - HelpViewer *hv = (HelpViewer *)data; - GSList *temp; - - /* puts the current file on the back stack */ - hv->back_stack = g_slist_prepend(hv->back_stack, g_strdup(hv->current_file)); - - /* enables the back button */ - gtk_widget_set_sensitive(hv->btn_back, TRUE); - - /* loads the new current file */ - if (g_str_has_prefix(hv->forward_stack->data, "search://")) { - do_search(hv, hv->forward_stack->data + sizeof("search://") - 1); - } else { - markdown_textview_load_file(MARKDOWN_TEXTVIEW(hv->text_view), hv->forward_stack->data); - } - - /* pops the stack */ - temp = hv->forward_stack->next; - g_free(hv->forward_stack->data); - g_slist_free1(hv->forward_stack); - hv->forward_stack = temp; - - /* if there aren't items on forward stack anymore, disables the button */ - if (!hv->forward_stack) { - gtk_widget_set_sensitive(hv->btn_forward, FALSE); - } -} - -static void back_clicked(GtkWidget *widget, gpointer data) -{ - HelpViewer *hv = (HelpViewer *)data; - GSList *temp; - - /* puts the current file on the forward stack */ - hv->forward_stack = g_slist_prepend(hv->forward_stack, g_strdup(hv->current_file)); - - /* enables the forward button */ - gtk_widget_set_sensitive(hv->btn_forward, TRUE); - - /* loads the new current file */ - if (g_str_has_prefix(hv->back_stack->data, "search://")) { - do_search(hv, hv->back_stack->data + sizeof("search://") - 1); - } else { - markdown_textview_load_file(MARKDOWN_TEXTVIEW(hv->text_view), hv->back_stack->data); - } - - /* pops the stack */ - temp = hv->back_stack->next; - g_free(hv->back_stack->data); - g_slist_free1(hv->back_stack); - hv->back_stack = temp; - - /* if there aren't items on back stack anymore, disables the button */ - if (!hv->back_stack) { - gtk_widget_set_sensitive(hv->btn_back, FALSE); - } -} - -static void link_clicked(MarkdownTextView *text_view, gchar *link, gpointer data) -{ - HelpViewer *hv = (HelpViewer *)data; - - if (g_str_has_prefix(link, "http://")) { - open_url(link); - } else { - /* adds the current file to the back stack (before loading the new file */ - hv->back_stack = g_slist_prepend(hv->back_stack, g_strdup(hv->current_file)); - gtk_widget_set_sensitive(hv->btn_back, TRUE); - - gtk_statusbar_pop(GTK_STATUSBAR(hv->status_bar), 1); - markdown_textview_load_file(text_view, link); - } -} - -static void file_load_complete(MarkdownTextView *text_view, gchar *file, gpointer data) -{ - HelpViewer *hv = (HelpViewer *)data; - - /* sets the currently-loaded file */ - g_free(hv->current_file); - hv->current_file = g_strdup(file); - - gtk_statusbar_push(GTK_STATUSBAR(hv->status_bar), 1, "Done."); -} - -static void hovering_over_link(MarkdownTextView *text_view, gchar *link, gpointer data) -{ - HelpViewer *hv = (HelpViewer *)data; - gchar *temp; - - temp = g_strconcat("Link to ", link, NULL); - - gtk_statusbar_push(GTK_STATUSBAR(hv->status_bar), 1, temp); - - g_free(temp); -} - -static void hovering_over_text(MarkdownTextView *text_view, gpointer data) -{ - HelpViewer *hv = (HelpViewer *)data; - - gtk_statusbar_pop(GTK_STATUSBAR(hv->status_bar), 1); -} - -static void do_search(HelpViewer *hv, gchar *text) -{ - GString *markdown; - GDir *dir; - gchar **terms; - gint no_results = 0; - int term; - - /* - * FIXME: This search is currently pretty slow; think on a better way to do search. - * Ideas: - * - Build a index the first time the help file is opened - * - Search only titles and subtitles - */ - - terms = g_strsplit(text, " ", 0); - markdown = g_string_new("# Search Results\n"); - g_string_append_printf(markdown, "Search terms: *%s*\n****\n", text); - - gtk_widget_set_sensitive(hv->window, FALSE); - - if ((dir = g_dir_open(hv->help_directory, 0, NULL))) { - const gchar *name; - - while ((name = g_dir_read_name(dir))) { -#if GTK_CHECK_VERSION(2,16,0) - gtk_entry_progress_pulse(GTK_ENTRY(hv->text_search)); -#endif /* GTK_CHECK_VERSION(2,16,0) */ - - if (g_str_has_suffix(name, ".hlp")) { - FILE *file; - gchar *path; - gchar buffer[256]; - - path = g_build_filename(hv->help_directory, name, NULL); - if ((file = fopen(path, "rb"))) { - gboolean found = FALSE; - gchar *title = NULL; - - while (!found && fgets(buffer, sizeof buffer, file)) { - if (!title && (g_str_has_prefix(buffer, "# ") || g_str_has_prefix(buffer, " # "))) { - title = g_strstrip(strchr(buffer, '#') + 1); - title = g_strdup(title); - } - - for (term = 0; !found && terms[term]; term++) { -#ifdef strcasestr - found = strcasestr(buffer, terms[term]) != NULL; -#else - gchar *upper1, *upper2; - - upper1 = g_utf8_strup(buffer, -1); - upper2 = g_utf8_strup(terms[term], -1); - - found = strstr(upper1, upper2) != NULL; - - g_free(upper1); - g_free(upper2); -#endif - } - } - - if (found) { - no_results++; - - if (title) { - g_string_append_printf(markdown, - "* [%s %s]\n", name, title); - } else { - g_string_append_printf(markdown, - "* [%s %s]\n", name, name); - } - } - - g_free(title); - fclose(file); - } - - g_free(path); - } - } - - g_dir_close(dir); - } - - - if (no_results == 0) { - g_string_append_printf(markdown, - "Search returned no results."); - } else { - g_string_append_printf(markdown, - "****\n%d results found.", no_results); - } - - /* shows the results inside the textview */ - markdown_textview_set_text(MARKDOWN_TEXTVIEW(hv->text_view), markdown->str); - - g_free(hv->current_file); - hv->current_file = g_strdup_printf("search://%s", text); - -#if GTK_CHECK_VERSION(2,16,0) - gtk_entry_set_progress_fraction(GTK_ENTRY(hv->text_search), 0.0f); -#endif /* GTK_CHECK_VERSION(2,16,0) */ - gtk_widget_set_sensitive(hv->window, TRUE); - - g_string_free(markdown, TRUE); - g_strfreev(terms); -} - -static void activate(GtkEntry *entry, gpointer data) -{ - HelpViewer *hv = (HelpViewer *)data; - - /* adds the current file to the back stack (before loading the new file */ - hv->back_stack = g_slist_prepend(hv->back_stack, g_strdup(hv->current_file)); - gtk_widget_set_sensitive(hv->btn_back, TRUE); - - do_search((HelpViewer *)data, (gchar *)gtk_entry_get_text(entry)); -} - -#if GTK_CHECK_VERSION(2,16,0) -static void icon_press(GtkEntry *entry, gint position, - GdkEventButton *event, gpointer data) -{ - if (position == GTK_ENTRY_ICON_SECONDARY) - activate(entry, data); -} -#endif /* GTK_CHECK_VERSION(2,16,0) */ - -static void home_clicked(GtkWidget *button, gpointer data) -{ - HelpViewer *hv = (HelpViewer *)data; - - help_viewer_open_page(hv, "index.hlp"); -} - -void help_viewer_open_page(HelpViewer *hv, const gchar *page) -{ - gchar *temp; - - temp = g_strdup(hv->current_file); - - if (!markdown_textview_load_file(MARKDOWN_TEXTVIEW(hv->text_view), page)) { - GtkWidget *dialog; - Shell *shell; - - shell = shell_get_main_shell(); - dialog = gtk_message_dialog_new(GTK_WINDOW(shell->window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Cannot open help file (%s).", - page); - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - - g_free(temp); - } else { - /* adds the current file to the back stack (before loading the new file */ - hv->back_stack = g_slist_prepend(hv->back_stack, temp); - gtk_widget_set_sensitive(hv->btn_back, TRUE); - gtk_window_present(GTK_WINDOW(hv->window)); - } -} - -void help_viewer_destroy(HelpViewer *hv) -{ - Shell *shell; - GSList *item; - - for (item = hv->back_stack; item; item = item->next) { - g_free(item->data); - } - - for (item = hv->forward_stack; item; item = item->next) { - g_free(item->data); - } - - g_slist_free(hv->back_stack); - g_slist_free(hv->forward_stack); - - g_free(hv->current_file); - g_free(hv->help_directory); - - shell = shell_get_main_shell(); - shell->help_viewer = NULL; -} - -static gboolean destroy_me(GtkWidget *widget, gpointer data) -{ - HelpViewer *hv = (HelpViewer *)data; - - help_viewer_destroy(hv); - - return FALSE; -} - -HelpViewer * -help_viewer_new (const gchar *help_dir, const gchar *help_file) -{ - Shell *shell; - HelpViewer *hv; - GtkWidget *help_viewer; - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *toolbar1; - GtkIconSize tmp_toolbar_icon_size; - GtkWidget *btn_back; - GtkWidget *btn_forward; - GtkWidget *separatortoolitem1; - GtkWidget *toolbar2; - GtkWidget *toolitem3; -#if !GTK_CHECK_VERSION(2,16,0) - GtkWidget *label1; -#endif /* GTK_CHECK_VERSION(2,16,0) */ - GtkWidget *toolitem4; - GtkWidget *txt_search; - GtkWidget *scrolledhelp_viewer; - GtkWidget *markdown_textview; - GtkWidget *status_bar; - GtkWidget *btn_home; - GdkPixbuf *icon; - - shell = shell_get_main_shell(); - - help_viewer = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_widget_set_size_request(help_viewer, 300, 200); - gtk_window_set_default_size(GTK_WINDOW(help_viewer), 640, 480); - gtk_window_set_title(GTK_WINDOW(help_viewer), "Help Viewer"); - gtk_window_set_transient_for(GTK_WINDOW(help_viewer), GTK_WINDOW(shell->window)); - - icon = gtk_widget_render_icon(help_viewer, GTK_STOCK_HELP, - GTK_ICON_SIZE_DIALOG, - NULL); - gtk_window_set_icon(GTK_WINDOW(help_viewer), icon); - g_object_unref(icon); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_widget_show (vbox); - gtk_container_add (GTK_CONTAINER (help_viewer), vbox); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - - toolbar1 = gtk_toolbar_new (); - gtk_widget_show (toolbar1); - gtk_box_pack_start (GTK_BOX (hbox), toolbar1, TRUE, TRUE, 0); - gtk_toolbar_set_style (GTK_TOOLBAR (toolbar1), GTK_TOOLBAR_BOTH_HORIZ); - tmp_toolbar_icon_size = gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar1)); - - btn_back = (GtkWidget*) gtk_tool_button_new_from_stock ("gtk-go-back"); - gtk_widget_show (btn_back); - gtk_container_add (GTK_CONTAINER (toolbar1), btn_back); - gtk_tool_item_set_is_important (GTK_TOOL_ITEM (btn_back), TRUE); - gtk_widget_set_sensitive(btn_back, FALSE); - - btn_forward = (GtkWidget*) gtk_tool_button_new_from_stock ("gtk-go-forward"); - gtk_widget_show (btn_forward); - gtk_container_add (GTK_CONTAINER (toolbar1), btn_forward); - gtk_widget_set_sensitive(btn_forward, FALSE); - - separatortoolitem1 = (GtkWidget*) gtk_separator_tool_item_new (); - gtk_widget_show (separatortoolitem1); - gtk_container_add (GTK_CONTAINER (toolbar1), separatortoolitem1); - - btn_home = (GtkWidget*) gtk_tool_button_new_from_stock ("gtk-home"); - gtk_widget_show (btn_home); - gtk_container_add (GTK_CONTAINER (toolbar1), btn_home); - - toolbar2 = gtk_toolbar_new (); - gtk_widget_show (toolbar2); - gtk_box_pack_end (GTK_BOX (hbox), toolbar2, FALSE, TRUE, 0); - gtk_toolbar_set_style (GTK_TOOLBAR (toolbar2), GTK_TOOLBAR_BOTH_HORIZ); - gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar2), FALSE); - tmp_toolbar_icon_size = gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar2)); - - toolitem3 = (GtkWidget*) gtk_tool_item_new (); - gtk_widget_show (toolitem3); - gtk_container_add (GTK_CONTAINER (toolbar2), toolitem3); - -#if !GTK_CHECK_VERSION(2,16,0) - label1 = gtk_label_new_with_mnemonic ("_Search:"); - gtk_widget_show (label1); - gtk_container_add (GTK_CONTAINER (toolitem3), label1); -#endif /* GTK_CHECK_VERSION(2,16,0) */ - - toolitem4 = (GtkWidget*) gtk_tool_item_new (); - gtk_widget_show (toolitem4); - gtk_container_add (GTK_CONTAINER (toolbar2), toolitem4); - - txt_search = gtk_entry_new (); - gtk_widget_show (txt_search); - gtk_container_add (GTK_CONTAINER (toolitem4), txt_search); - gtk_entry_set_invisible_char (GTK_ENTRY (txt_search), 9679); -#if GTK_CHECK_VERSION(2,16,0) - gtk_entry_set_icon_from_stock(GTK_ENTRY(txt_search), - GTK_ENTRY_ICON_SECONDARY, - GTK_STOCK_FIND); -#endif /* GTK_CHECK_VERSION(2,16,0) */ - - scrolledhelp_viewer = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (scrolledhelp_viewer); - gtk_box_pack_start (GTK_BOX (vbox), scrolledhelp_viewer, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledhelp_viewer), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - - markdown_textview = markdown_textview_new(); - markdown_textview_set_image_directory(MARKDOWN_TEXTVIEW(markdown_textview), help_dir); - gtk_widget_show (markdown_textview); - gtk_container_add (GTK_CONTAINER (scrolledhelp_viewer), markdown_textview); - - status_bar = gtk_statusbar_new (); - gtk_widget_show (status_bar); - gtk_box_pack_start (GTK_BOX (vbox), status_bar, FALSE, FALSE, 0); - - hv = g_new0(HelpViewer, 1); - hv->window = help_viewer; - hv->status_bar = status_bar; - hv->btn_back = btn_back; - hv->btn_forward = btn_forward; - hv->text_view = markdown_textview; - hv->text_search = txt_search; - hv->help_directory = g_strdup(help_dir); - hv->back_stack = NULL; - hv->forward_stack = NULL; - - g_signal_connect(markdown_textview, "link-clicked", G_CALLBACK(link_clicked), hv); - g_signal_connect(markdown_textview, "hovering-over-link", G_CALLBACK(hovering_over_link), hv); - g_signal_connect(markdown_textview, "hovering-over-text", G_CALLBACK(hovering_over_text), hv); - g_signal_connect(markdown_textview, "file-load-complete", G_CALLBACK(file_load_complete), hv); - - g_signal_connect(btn_back, "clicked", G_CALLBACK(back_clicked), hv); - g_signal_connect(btn_forward, "clicked", G_CALLBACK(forward_clicked), hv); - g_signal_connect(btn_home, "clicked", G_CALLBACK(home_clicked), hv); - - g_signal_connect(help_viewer, "delete-event", G_CALLBACK(destroy_me), hv); - g_signal_connect(txt_search, "activate", G_CALLBACK(activate), hv); - -#if GTK_CHECK_VERSION(2,16,0) - g_signal_connect(txt_search, "icon-press", G_CALLBACK(icon_press), hv); -#endif /* GTK_CHECK_VERSION(2,16,0) */ - - if (!markdown_textview_load_file(MARKDOWN_TEXTVIEW(markdown_textview), help_file ? help_file : "index.hlp")) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new(GTK_WINDOW(shell->window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Cannot open help file (%s).", - help_file ? help_file : "index.hlp"); - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - - gtk_widget_destroy(hv->window); - g_free(hv); - - return NULL; - } - - gtk_widget_show_all(hv->window); - - return hv; -} - -#ifdef HELPVIEWER_TEST -int main(int argc, char **argv) -{ - HelpViewer *hv; - - gtk_init(&argc, &argv); - - hv = help_viewer_new("documentation", NULL); - - gtk_main(); -} -#endif /* HELPVIEWER_TEST */ diff --git a/hardinfo2/help-viewer.h b/hardinfo2/help-viewer.h deleted file mode 100644 index 688ff325..00000000 --- a/hardinfo2/help-viewer.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * HelpViewer - Simple Help file browser - * Copyright (C) 2009 Leandro A. F. Pereira - * - * 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/hardinfo2/help-viewer/egg-markdown.c b/hardinfo2/help-viewer/egg-markdown.c new file mode 100644 index 00000000..4056d4f9 --- /dev/null +++ b/hardinfo2/help-viewer/egg-markdown.c @@ -0,0 +1,1586 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Richard Hughes + * Copyright (C) 2009 Leandro Pereira + * + * 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. + */ + +#include "config.h" + +#define _GNU_SOURCE +#include +#include +#include + +#include "egg-markdown.h" + +/******************************************************************************* + * + * This is a simple Markdown parser. + * It can output to Pango, HTML or plain text. The following limitations are + * already known, and properly deliberate: + * + * - No code section support + * - No ordered list support + * - No blockquote section support + * - No image support + * - No links or email support + * - No backslash escapes support + * - No HTML escaping support + * - Auto-escapes certain word patterns, like http:// + * + * It does support the rest of the standard pretty well, although it's not + * been run against any conformance tests. The parsing is single pass, with + * a simple enumerated intepretor mode and a single line back-memory. + * + ******************************************************************************/ + +static void egg_markdown_finalize (GObject *object); + +#define EGG_MARKDOWN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_MARKDOWN, EggMarkdownPrivate)) + +typedef gchar *(EggMarkdownLinkBuilder)(gchar *title, gchar *uri, gint link_id); +typedef gchar *(EggMarkdownImageBuilder)(gchar *alt_text, gchar *path, gint link_id); + +typedef enum { + EGG_MARKDOWN_MODE_BLANK, + EGG_MARKDOWN_MODE_RULE, + EGG_MARKDOWN_MODE_BULLETT, + EGG_MARKDOWN_MODE_PARA, + EGG_MARKDOWN_MODE_H1, + EGG_MARKDOWN_MODE_H2, + EGG_MARKDOWN_MODE_UNKNOWN +} EggMarkdownMode; + +typedef struct { + const gchar *em_start; + const gchar *em_end; + const gchar *strong_start; + const gchar *strong_end; + const gchar *code_start; + const gchar *code_end; + const gchar *h1_start; + const gchar *h1_end; + const gchar *h2_start; + const gchar *h2_end; + const gchar *bullett_start; + const gchar *bullett_end; + const gchar *rule; + + EggMarkdownLinkBuilder *link_builder; + EggMarkdownImageBuilder *image_builder; +} EggMarkdownTags; + +struct EggMarkdownPrivate +{ + EggMarkdownMode mode; + EggMarkdownTags tags; + EggMarkdownOutput output; + gint max_lines; + guint line_count; + gboolean smart_quoting; + gboolean escape; + gboolean autocode; + GString *pending; + GString *processed; + GArray *link_table; +}; + +G_DEFINE_TYPE (EggMarkdown, egg_markdown, G_TYPE_OBJECT) + +/** + * egg_markdown_to_text_line_is_rule: + * + * Horizontal rules are created by placing three or more hyphens, asterisks, + * or underscores on a line by themselves. + * You may use spaces between the hyphens or asterisks. + **/ +static gboolean +egg_markdown_to_text_line_is_rule (const gchar *line) +{ + guint i; + guint len; + guint count = 0; + gchar *copy = NULL; + gboolean ret = FALSE; + + len = strnlen (line, EGG_MARKDOWN_MAX_LINE_LENGTH); + if (len == 0) + goto out; + + /* replace non-rule chars with ~ */ + copy = g_strdup (line); + g_strcanon (copy, "-*_ ", '~'); + for (i=0; i= 3) + ret = TRUE; +out: + g_free (copy); + return ret; +} + +/** + * egg_markdown_to_text_line_is_bullett: + **/ +static gboolean +egg_markdown_to_text_line_is_bullett (const gchar *line) +{ + return (g_str_has_prefix (line, "- ") || + g_str_has_prefix (line, "* ") || + g_str_has_prefix (line, "+ ") || + g_str_has_prefix (line, " - ") || + g_str_has_prefix (line, " * ") || + g_str_has_prefix (line, " + ")); +} + +/** + * egg_markdown_to_text_line_is_header1: + **/ +static gboolean +egg_markdown_to_text_line_is_header1 (const gchar *line) +{ + return g_str_has_prefix (line, "# "); +} + +/** + * egg_markdown_to_text_line_is_header2: + **/ +static gboolean +egg_markdown_to_text_line_is_header2 (const gchar *line) +{ + return g_str_has_prefix (line, "## "); +} + +/** + * egg_markdown_to_text_line_is_header1_type2: + **/ +static gboolean +egg_markdown_to_text_line_is_header1_type2 (const gchar *line) +{ + return g_str_has_prefix (line, "==="); +} + +/** + * egg_markdown_to_text_line_is_header2_type2: + **/ +static gboolean +egg_markdown_to_text_line_is_header2_type2 (const gchar *line) +{ + return g_str_has_prefix (line, "---"); +} + +#if 0 +/** + * egg_markdown_to_text_line_is_code: + **/ +static gboolean +egg_markdown_to_text_line_is_code (const gchar *line) +{ + return (g_str_has_prefix (line, " ") || g_str_has_prefix (line, "\t")); +} + +/** + * egg_markdown_to_text_line_is_blockquote: + **/ +static gboolean +egg_markdown_to_text_line_is_blockquote (const gchar *line) +{ + return (g_str_has_prefix (line, "> ")); +} +#endif + +/** + * egg_markdown_to_text_line_is_blank: + **/ +static gboolean +egg_markdown_to_text_line_is_blank (const gchar *line) +{ + guint i; + guint len; + gboolean ret = FALSE; + + len = strnlen (line, EGG_MARKDOWN_MAX_LINE_LENGTH); + + /* a line with no characters is blank by definition */ + if (len == 0) { + ret = TRUE; + goto out; + } + + /* find if there are only space chars */ + for (i=0; ipriv->link_table, path_copy); + + formatted_img = self->priv->tags.image_builder(alt_text, + path, + self->priv->link_table->len - 1); + + data = g_strdup_printf ("%s%s%s", + start, formatted_img, end); + + g_free(formatted_img); + } else { + /* not found, keep return as-is */ + data = g_strdup (line); + } + + g_free (copy); + return data; +} + + +/** + * egg_markdown_to_text_line_formatter_link: + **/ +static gchar * +egg_markdown_to_text_line_formatter_link (EggMarkdown *self, const gchar *line) +{ + const guint len = 1; /* needed to know for shifts */ + gchar *str1; + gchar *str2; + gchar *start = NULL; + gchar *link = NULL; + gchar *link_title = NULL; + gchar *end = NULL; + gchar *copy = NULL; + gchar *data = NULL; + + /* find sections */ + copy = g_strdup (line); + str1 = egg_markdown_strstr_spaces (copy, "["); + if (str1 != NULL) { + *str1 = '\0'; + str2 = egg_markdown_strstr_spaces (str1+len, "]"); + if (str2 != NULL) { + *str2 = '\0'; + start = copy; + link = str1 + len; + end = str2 + len; + + str2 = strstr (link, " "); + if (str2 != NULL) { + *str2 = '\0'; + link_title = str2 + len; + } + } + } + + /* if we found, replace and keep looking for the same string */ + if (start && (link && *link) && link_title && end) { + gchar *formatted_link; + gchar *link_copy = g_strdup(link); + + g_array_append_val(self->priv->link_table, link_copy); + + formatted_link = self->priv->tags.link_builder(link_title, + link, + self->priv->link_table->len - 1); + + data = g_strdup_printf ("%s%s%s", + start, formatted_link, end); + + g_free(formatted_link); + } else { + /* not found, keep return as-is */ + data = g_strdup (line); + } + + g_free (copy); + return data; +} + +void +egg_markdown_clear(EggMarkdown *self) +{ + int i; + + for (i = 0; i < self->priv->link_table->len; i++) { + g_free(g_array_index(self->priv->link_table, gchar *, i)); + } + + g_array_free(self->priv->link_table, TRUE); + self->priv->link_table = g_array_new(FALSE, FALSE, sizeof(gchar *)); +} + +gchar * +egg_markdown_get_link_uri(EggMarkdown *self, const gint link_id) +{ + g_return_val_if_fail(link_id < self->priv->link_table->len, NULL); + + return g_strdup(g_array_index(self->priv->link_table, gchar *, link_id)); +} + +/** + * egg_markdown_to_text_line_format_sections: + **/ +static gchar * +egg_markdown_to_text_line_format_sections (EggMarkdown *self, const gchar *line) +{ + gchar *data = g_strdup (line); + gchar *temp; + + /* smart quoting */ + if (self->priv->smart_quoting) { + if (self->priv->escape) { + temp = data; + data = egg_markdown_to_text_line_formatter (temp, """, "“", "â€"); + g_free (temp); + + temp = data; + data = egg_markdown_to_text_line_formatter (temp, "'", "‘", "’"); + g_free (temp); + } else { + temp = data; + data = egg_markdown_to_text_line_formatter (temp, "\"", "“", "â€"); + g_free (temp); + + temp = data; + data = egg_markdown_to_text_line_formatter (temp, "'", "‘", "’"); + g_free (temp); + } + } + + /* image */ + temp = data; + data = egg_markdown_to_text_line_formatter_image (self, temp); + g_free(temp); + + /* link */ + temp = data; + data = egg_markdown_to_text_line_formatter_link (self, temp); + g_free(temp); + + /* bold1 */ + temp = data; + data = egg_markdown_to_text_line_formatter (temp, "**", self->priv->tags.strong_start, self->priv->tags.strong_end); + g_free (temp); + + /* bold2 */ + temp = data; + data = egg_markdown_to_text_line_formatter (temp, "__", self->priv->tags.strong_start, self->priv->tags.strong_end); + g_free (temp); + + /* italic1 */ + temp = data; + data = egg_markdown_to_text_line_formatter (temp, "*", self->priv->tags.em_start, self->priv->tags.em_end); + g_free (temp); + + /* italic2 */ + temp = data; + data = egg_markdown_to_text_line_formatter (temp, "_", self->priv->tags.em_start, self->priv->tags.em_end); + g_free (temp); + + /* em-dash */ + temp = data; + data = egg_markdown_replace (temp, " -- ", " — "); + g_free (temp); + + return data; +} + +/** + * egg_markdown_to_text_line_format: + **/ +static gchar * +egg_markdown_to_text_line_format (EggMarkdown *self, const gchar *line) +{ + guint i; + gchar *text; + gboolean mode = FALSE; + gchar **codes; + GString *string; + + /* optimise the trivial case where we don't have any code tags */ + text = strstr (line, "`"); + if (text == NULL) { + text = egg_markdown_to_text_line_format_sections (self, line); + goto out; + } + + /* we want to parse the code sections without formatting */ + codes = g_strsplit (line, "`", -1); + string = g_string_new (""); + for (i=0; codes[i] != NULL; i++) { + if (!mode) { + text = egg_markdown_to_text_line_format_sections (self, codes[i]); + g_string_append (string, text); + g_free (text); + mode = TRUE; + } else { + /* just append without formatting */ + g_string_append (string, self->priv->tags.code_start); + g_string_append (string, codes[i]); + g_string_append (string, self->priv->tags.code_end); + mode = FALSE; + } + } + text = g_string_free (string, FALSE); +out: + return text; +} + +/** + * egg_markdown_add_pending: + **/ +static gboolean +egg_markdown_add_pending (EggMarkdown *self, const gchar *line) +{ + gchar *copy; + + /* would put us over the limit */ + if (self->priv->line_count >= self->priv->max_lines) + return FALSE; + + copy = g_strdup (line); + + /* strip leading and trailing spaces */ + g_strstrip (copy); + + /* append */ + g_string_append_printf (self->priv->pending, "%s ", copy); + + g_free (copy); + return TRUE; +} + +/** + * egg_markdown_add_pending_header: + **/ +static gboolean +egg_markdown_add_pending_header (EggMarkdown *self, const gchar *line) +{ + gchar *copy; + gboolean ret; + + /* strip trailing # */ + copy = g_strdup (line); + g_strdelimit (copy, "#", ' '); + ret = egg_markdown_add_pending (self, copy); + g_free (copy); + return ret; +} + +/** + * egg_markdown_count_chars_in_word: + **/ +static guint +egg_markdown_count_chars_in_word (const gchar *text, gchar find) +{ + guint i; + guint len; + guint count = 0; + + /* get length */ + len = strnlen (text, EGG_MARKDOWN_MAX_LINE_LENGTH); + if (len == 0) + goto out; + + /* find matching chars */ + for (i=0; i 1) + return TRUE; + + /* nothing special */ + return FALSE; +} + +/** + * egg_markdown_word_auto_format_code: + **/ +static gchar * +egg_markdown_word_auto_format_code (const gchar *text) +{ + guint i; + gchar *temp; + gchar **words; + gboolean ret = FALSE; + + /* split sentence up with space */ + words = g_strsplit (text, " ", -1); + + /* search each word */ + for (i=0; words[i] != NULL; i++) { + if (egg_markdown_word_is_code (words[i])) { + temp = g_strdup_printf ("`%s`", words[i]); + g_free (words[i]); + words[i] = temp; + ret = TRUE; + } + } + + /* no replacements, so just return a copy */ + if (!ret) { + temp = g_strdup (text); + goto out; + } + + /* join the array back into a string */ + temp = g_strjoinv (" ", words); +out: + g_strfreev (words); + return temp; +} + +/** + * egg_markdown_flush_pending: + **/ +static void +egg_markdown_flush_pending (EggMarkdown *self) +{ + gchar *copy; + gchar *temp; + + /* no data yet */ + if (self->priv->mode == EGG_MARKDOWN_MODE_UNKNOWN) + return; + + /* remove trailing spaces */ + while (g_str_has_suffix (self->priv->pending->str, " ")) + g_string_set_size (self->priv->pending, self->priv->pending->len - 1); + + /* pango requires escaping */ + copy = g_strdup (self->priv->pending->str); + if (!self->priv->escape && self->priv->output == EGG_MARKDOWN_OUTPUT_PANGO) { + g_strdelimit (copy, "<", '('); + g_strdelimit (copy, ">", ')'); + } + + /* check words for code */ + if (self->priv->autocode && + (self->priv->mode == EGG_MARKDOWN_MODE_PARA || + self->priv->mode == EGG_MARKDOWN_MODE_BULLETT)) { + temp = egg_markdown_word_auto_format_code (copy); + g_free (copy); + copy = temp; + } + + /* escape */ + if (self->priv->escape) { + temp = g_markup_escape_text (copy, -1); + g_free (copy); + copy = temp; + } + + /* do formatting */ + temp = egg_markdown_to_text_line_format (self, copy); + if (self->priv->mode == EGG_MARKDOWN_MODE_BULLETT) { + g_string_append_printf (self->priv->processed, "%s%s%s\n", self->priv->tags.bullett_start, temp, self->priv->tags.bullett_end); + self->priv->line_count++; + } else if (self->priv->mode == EGG_MARKDOWN_MODE_H1) { + g_string_append_printf (self->priv->processed, "%s%s%s\n", self->priv->tags.h1_start, temp, self->priv->tags.h1_end); + } else if (self->priv->mode == EGG_MARKDOWN_MODE_H2) { + g_string_append_printf (self->priv->processed, "%s%s%s\n", self->priv->tags.h2_start, temp, self->priv->tags.h2_end); + } else if (self->priv->mode == EGG_MARKDOWN_MODE_PARA || + self->priv->mode == EGG_MARKDOWN_MODE_RULE) { + g_string_append_printf (self->priv->processed, "%s\n", temp); + self->priv->line_count++; + } + + DEBUG ("adding '%s'", temp); + + /* clear */ + g_string_truncate (self->priv->pending, 0); + g_free (copy); + g_free (temp); +} + +/** + * egg_markdown_to_text_line_process: + **/ +static gboolean +egg_markdown_to_text_line_process (EggMarkdown *self, const gchar *line) +{ + gboolean ret; + + /* blank */ + ret = egg_markdown_to_text_line_is_blank (line); + if (ret) { + DEBUG ("blank: '%s'", line); + egg_markdown_flush_pending (self); + /* a new line after a list is the end of list, not a gap */ + if (self->priv->mode != EGG_MARKDOWN_MODE_BULLETT) + ret = egg_markdown_add_pending (self, "\n"); + self->priv->mode = EGG_MARKDOWN_MODE_BLANK; + goto out; + } + + /* header1_type2 */ + ret = egg_markdown_to_text_line_is_header1_type2 (line); + if (ret) { + DEBUG ("header1_type2: '%s'", line); + if (self->priv->mode == EGG_MARKDOWN_MODE_PARA) + self->priv->mode = EGG_MARKDOWN_MODE_H1; + goto out; + } + + /* header2_type2 */ + ret = egg_markdown_to_text_line_is_header2_type2 (line); + if (ret) { + DEBUG ("header2_type2: '%s'", line); + if (self->priv->mode == EGG_MARKDOWN_MODE_PARA) + self->priv->mode = EGG_MARKDOWN_MODE_H2; + goto out; + } + + /* rule */ + ret = egg_markdown_to_text_line_is_rule (line); + if (ret) { + DEBUG ("rule: '%s'", line); + egg_markdown_flush_pending (self); + self->priv->mode = EGG_MARKDOWN_MODE_RULE; + ret = egg_markdown_add_pending (self, self->priv->tags.rule); + goto out; + } + + /* bullett */ + ret = egg_markdown_to_text_line_is_bullett (line); + if (ret) { + DEBUG ("bullett: '%s'", line); + egg_markdown_flush_pending (self); + self->priv->mode = EGG_MARKDOWN_MODE_BULLETT; + ret = egg_markdown_add_pending (self, &line[2]); + goto out; + } + + /* header1 */ + ret = egg_markdown_to_text_line_is_header1 (line); + if (ret) { + DEBUG ("header1: '%s'", line); + egg_markdown_flush_pending (self); + self->priv->mode = EGG_MARKDOWN_MODE_H1; + ret = egg_markdown_add_pending_header (self, &line[2]); + goto out; + } + + /* header2 */ + ret = egg_markdown_to_text_line_is_header2 (line); + if (ret) { + DEBUG ("header2: '%s'", line); + egg_markdown_flush_pending (self); + self->priv->mode = EGG_MARKDOWN_MODE_H2; + ret = egg_markdown_add_pending_header (self, &line[3]); + goto out; + } + + /* paragraph */ + if (self->priv->mode == EGG_MARKDOWN_MODE_BLANK || self->priv->mode == EGG_MARKDOWN_MODE_UNKNOWN) { + egg_markdown_flush_pending (self); + self->priv->mode = EGG_MARKDOWN_MODE_PARA; + } + + /* add to pending */ + DEBUG ("continue: '%s'", line); + ret = egg_markdown_add_pending (self, line); +out: + /* if we failed to add, we don't know the mode */ + if (!ret) + self->priv->mode = EGG_MARKDOWN_MODE_UNKNOWN; + return ret; +} + +/** + * egg_markdown_linkbuilder_pango: + **/ +static gchar * +egg_markdown_linkbuilder_pango (gchar *title, gchar *uri, gint link_id) +{ + /* FIXME: This is a nasty hack, since extending Pango markup to allow new tags + * is too complicated. We use the language code as a link index + * since it won't allow anything besides letters or numbers. + * To obtain the link URI, use egg_markdown_get_link_uri(). */ + return g_strdup_printf("%s", + link_id, title); +} + +/** + * egg_markdown_linkbuilder_html + **/ +static gchar * +egg_markdown_linkbuilder_html (gchar *title, gchar *uri, gint link_id) +{ + return g_strdup_printf("%s", uri, title); +} + +/** + * egg_markdown_linkbuilder_text + **/ +static gchar * +egg_markdown_linkbuilder_text (gchar *title, gchar *uri, gint link_id) +{ + return g_strdup_printf("%s (%s)", title, uri); +} + +/** + * egg_markdown_imagebuilder_pango: + **/ +static gchar * +egg_markdown_imagebuilder_pango (gchar *alt_text, gchar *uri, gint link_id) +{ + /* FIXME See egg_markdown_linkbuilder_pango() */ + return g_strdup_printf("%s", + link_id, alt_text); +} + +/** + * egg_markdown_imagebuilder_html + **/ +static gchar * +egg_markdown_imagebuilder_html (gchar *alt_text, gchar *uri, gint link_id) +{ + return g_strdup_printf("\"%s\"", uri, alt_text); +} + +/** + * egg_markdown_imagebuilder_text + **/ +static gchar * +egg_markdown_imagebuilder_text (gchar *alt_text, gchar *uri, gint link_id) +{ + return g_strdup(alt_text); +} + +/** + * egg_markdown_set_output: + **/ +gboolean +egg_markdown_set_output (EggMarkdown *self, EggMarkdownOutput output) +{ + gboolean ret = TRUE; + g_return_val_if_fail (EGG_IS_MARKDOWN (self), FALSE); + + /* PangoMarkup */ + if (output == EGG_MARKDOWN_OUTPUT_PANGO) { + self->priv->tags.em_start = ""; + self->priv->tags.em_end = ""; + self->priv->tags.strong_start = ""; + self->priv->tags.strong_end = ""; + self->priv->tags.code_start = ""; + self->priv->tags.code_end = ""; + self->priv->tags.h1_start = ""; + self->priv->tags.h1_end = ""; + self->priv->tags.h2_start = ""; + self->priv->tags.h2_end = ""; + self->priv->tags.bullett_start = " • "; + self->priv->tags.bullett_end = ""; + self->priv->tags.rule = "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯\n"; + self->priv->tags.link_builder = egg_markdown_linkbuilder_pango; + self->priv->tags.image_builder = egg_markdown_imagebuilder_pango; + + /* XHTML */ + } else if (output == EGG_MARKDOWN_OUTPUT_HTML) { + self->priv->tags.em_start = ""; + self->priv->tags.em_end = ""; + self->priv->tags.strong_start = ""; + self->priv->tags.strong_end = ""; + self->priv->tags.code_start = ""; + self->priv->tags.code_end = ""; + self->priv->tags.h1_start = "

    "; + self->priv->tags.h1_end = "

    "; + self->priv->tags.h2_start = "

    "; + self->priv->tags.h2_end = "

    "; + self->priv->tags.bullett_start = "
  • "; + self->priv->tags.bullett_end = "
  • "; + self->priv->tags.rule = "
    "; + self->priv->tags.link_builder = egg_markdown_linkbuilder_html; + self->priv->tags.image_builder = egg_markdown_imagebuilder_html; + + /* plain text */ + } else if (output == EGG_MARKDOWN_OUTPUT_TEXT) { + self->priv->tags.em_start = ""; + self->priv->tags.em_end = ""; + self->priv->tags.strong_start = ""; + self->priv->tags.strong_end = ""; + self->priv->tags.code_start = ""; + self->priv->tags.code_end = ""; + self->priv->tags.h1_start = "["; + self->priv->tags.h1_end = "]"; + self->priv->tags.h2_start = "-"; + self->priv->tags.h2_end = "-"; + self->priv->tags.bullett_start = "* "; + self->priv->tags.bullett_end = ""; + self->priv->tags.rule = " ----- \n"; + self->priv->tags.link_builder = egg_markdown_linkbuilder_text; + self->priv->tags.image_builder = egg_markdown_imagebuilder_text; + + /* unknown */ + } else { + g_warning ("unknown output enum"); + ret = FALSE; + } + + /* save if valid */ + if (ret) + self->priv->output = output; + return ret; +} + +/** + * egg_markdown_set_max_lines: + **/ +gboolean +egg_markdown_set_max_lines (EggMarkdown *self, gint max_lines) +{ + g_return_val_if_fail (EGG_IS_MARKDOWN (self), FALSE); + self->priv->max_lines = max_lines; + return TRUE; +} + +/** + * egg_markdown_set_smart_quoting: + **/ +gboolean +egg_markdown_set_smart_quoting (EggMarkdown *self, gboolean smart_quoting) +{ + g_return_val_if_fail (EGG_IS_MARKDOWN (self), FALSE); + self->priv->smart_quoting = smart_quoting; + return TRUE; +} + +/** + * egg_markdown_set_escape: + **/ +gboolean +egg_markdown_set_escape (EggMarkdown *self, gboolean escape) +{ + g_return_val_if_fail (EGG_IS_MARKDOWN (self), FALSE); + self->priv->escape = escape; + return TRUE; +} + +/** + * egg_markdown_set_autocode: + **/ +gboolean +egg_markdown_set_autocode (EggMarkdown *self, gboolean autocode) +{ + g_return_val_if_fail (EGG_IS_MARKDOWN (self), FALSE); + self->priv->autocode = autocode; + return TRUE; +} + +/** + * egg_markdown_parse: + **/ +gchar * +egg_markdown_parse (EggMarkdown *self, const gchar *markdown) +{ + gchar **lines; + guint i; + guint len; + gchar *temp; + gboolean ret; + + g_return_val_if_fail (EGG_IS_MARKDOWN (self), NULL); + g_return_val_if_fail (self->priv->output != EGG_MARKDOWN_OUTPUT_UNKNOWN, NULL); + + DEBUG ("input='%s'", markdown); + + /* process */ + self->priv->mode = EGG_MARKDOWN_MODE_UNKNOWN; + self->priv->line_count = 0; + g_string_truncate (self->priv->pending, 0); + g_string_truncate (self->priv->processed, 0); + lines = g_strsplit (markdown, "\n", -1); + len = g_strv_length (lines); + + /* process each line */ + for (i=0; ipriv->processed->str, "\n")) + g_string_set_size (self->priv->processed, self->priv->processed->len - 1); + + /* get a copy */ + temp = g_strdup (self->priv->processed->str); + g_string_truncate (self->priv->pending, 0); + g_string_truncate (self->priv->processed, 0); + + DEBUG ("output='%s'", temp); + + return temp; +} + +/** + * egg_markdown_class_init: + * @klass: The EggMarkdownClass + **/ +static void +egg_markdown_class_init (EggMarkdownClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = egg_markdown_finalize; + g_type_class_add_private (klass, sizeof (EggMarkdownPrivate)); +} + +/** + * egg_markdown_init: + **/ +static void +egg_markdown_init (EggMarkdown *self) +{ + self->priv = EGG_MARKDOWN_GET_PRIVATE (self); + + self->priv->mode = EGG_MARKDOWN_MODE_UNKNOWN; + self->priv->output = EGG_MARKDOWN_OUTPUT_UNKNOWN; + self->priv->pending = g_string_new (""); + self->priv->processed = g_string_new (""); + self->priv->link_table = g_array_new(FALSE, FALSE, sizeof(gchar *)); + self->priv->max_lines = -1; + self->priv->smart_quoting = FALSE; + self->priv->escape = FALSE; + self->priv->autocode = FALSE; +} + +/** + * egg_markdown_finalize: + * @object: The object to finalize + **/ +static void +egg_markdown_finalize (GObject *object) +{ + EggMarkdown *self; + int i; + + g_return_if_fail (EGG_IS_MARKDOWN (object)); + + self = EGG_MARKDOWN (object); + + g_return_if_fail (self->priv != NULL); + g_string_free (self->priv->pending, TRUE); + g_string_free (self->priv->processed, TRUE); + + for (i = 0; i < self->priv->link_table->len; i++) { + g_free(g_array_index(self->priv->link_table, gchar *, i)); + } + g_array_free (self->priv->link_table, TRUE); + + G_OBJECT_CLASS (egg_markdown_parent_class)->finalize (object); +} + +/** + * egg_markdown_new: + * + * Return value: a new EggMarkdown object. + **/ +EggMarkdown * +egg_markdown_new (void) +{ + EggMarkdown *self; + self = g_object_new (EGG_TYPE_MARKDOWN, NULL); + return EGG_MARKDOWN (self); +} + +/*************************************************************************** + *** MAKE CHECK TESTS *** + ***************************************************************************/ +#ifdef EGG_TEST +#include "egg-test.h" + +void +egg_markdown_test (EggTest *test) +{ + EggMarkdown *self; + gchar *text; + gboolean ret; + const gchar *markdown; + const gchar *markdown_expected; + + if (!egg_test_start (test, "EggMarkdown")) + return; + + /************************************************************ + **************** line_is_rule ************** + ************************************************************/ + ret = egg_markdown_to_text_line_is_rule ("* * *"); + egg_test_title_assert (test, "is rule (1)", ret); + + /************************************************************/ + ret = egg_markdown_to_text_line_is_rule ("***"); + egg_test_title_assert (test, "is rule (2)", ret); + + /************************************************************/ + ret = egg_markdown_to_text_line_is_rule ("*****"); + egg_test_title_assert (test, "is rule (3)", ret); + + /************************************************************/ + ret = egg_markdown_to_text_line_is_rule ("- - -"); + egg_test_title_assert (test, "is rule (4)", ret); + + /************************************************************/ + ret = egg_markdown_to_text_line_is_rule ("---------------------------------------"); + egg_test_title_assert (test, "is rule (5)", ret); + + /************************************************************/ + ret = egg_markdown_to_text_line_is_rule (""); + egg_test_title_assert (test, "is rule (blank)", !ret); + + /************************************************************/ + ret = egg_markdown_to_text_line_is_rule ("richard hughes"); + egg_test_title_assert (test, "is rule (text)", !ret); + + /************************************************************/ + ret = egg_markdown_to_text_line_is_rule ("- richard-hughes"); + egg_test_title_assert (test, "is rule (bullet)", !ret); + + /************************************************************/ + ret = egg_markdown_to_text_line_is_blank (""); + egg_test_title_assert (test, "is blank (blank)", ret); + + /************************************************************/ + ret = egg_markdown_to_text_line_is_blank (" \t "); + egg_test_title_assert (test, "is blank (mix)", ret); + + /************************************************************/ + ret = egg_markdown_to_text_line_is_blank ("richard hughes"); + egg_test_title_assert (test, "is blank (name)", !ret); + + /************************************************************/ + ret = egg_markdown_to_text_line_is_blank ("ccccccccc"); + egg_test_title_assert (test, "is blank (full)", !ret); + + + /************************************************************ + **************** replace ************** + ************************************************************/ + text = egg_markdown_replace ("summary -- really -- sure!", " -- ", " – "); + egg_test_title (test, "replace (multiple)"); + if (g_str_equal (text, "summary – really – sure!")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got %s", text); + g_free (text); + + /************************************************************ + **************** formatter ************** + ************************************************************/ + text = egg_markdown_to_text_line_formatter ("**is important** text", "**", "", ""); + egg_test_title (test, "formatter (left)"); + if (g_str_equal (text, "is important text")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got %s", text); + g_free (text); + + /************************************************************/ + text = egg_markdown_to_text_line_formatter ("this is **important**", "**", "", ""); + egg_test_title (test, "formatter (right)"); + if (g_str_equal (text, "this is important")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got %s", text); + g_free (text); + + /************************************************************/ + text = egg_markdown_to_text_line_formatter ("**important**", "**", "", ""); + egg_test_title (test, "formatter (only)"); + if (g_str_equal (text, "important")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got %s", text); + g_free (text); + + /************************************************************/ + text = egg_markdown_to_text_line_formatter ("***important***", "**", "", ""); + egg_test_title (test, "formatter (only)"); + if (g_str_equal (text, "*important*")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got %s", text); + g_free (text); + + /************************************************************/ + text = egg_markdown_to_text_line_formatter ("I guess * this is * not bold", "*", "", ""); + egg_test_title (test, "formatter (with spaces)"); + if (g_str_equal (text, "I guess * this is * not bold")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got %s", text); + g_free (text); + + /************************************************************/ + text = egg_markdown_to_text_line_formatter ("this **is important** text in **several** places", "**", "", ""); + egg_test_title (test, "formatter (middle, multiple)"); + if (g_str_equal (text, "this is important text in several places")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got %s", text); + g_free (text); + + /************************************************************/ + text = egg_markdown_word_auto_format_code ("this is http://www.hughsie.com/with_spaces_in_url inline link"); + egg_test_title (test, "auto formatter (url)"); + if (g_str_equal (text, "this is `http://www.hughsie.com/with_spaces_in_url` inline link")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got %s", text); + g_free (text); + + /************************************************************/ + text = egg_markdown_to_text_line_formatter ("this was \"triffic\" it was", "\"", "“", "â€"); + egg_test_title (test, "formatter (quotes)"); + if (g_str_equal (text, "this was “triffic†it was")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got %s", text); + g_free (text); + + /************************************************************/ + text = egg_markdown_to_text_line_formatter ("This isn't a present", "'", "‘", "’"); + egg_test_title (test, "formatter (one quote)"); + if (g_str_equal (text, "This isn't a present")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got %s", text); + g_free (text); + + /************************************************************ + **************** markdown ************** + ************************************************************/ + egg_test_title (test, "get EggMarkdown object"); + self = egg_markdown_new (); + egg_test_assert (test, self != NULL); + + /************************************************************/ + ret = egg_markdown_set_output (self, EGG_MARKDOWN_OUTPUT_PANGO); + egg_test_title_assert (test, "set pango output", ret); + + /************************************************************/ + markdown = "OEMs\n" + "====\n" + " - Bullett\n"; + markdown_expected = + "OEMs\n" + "• Bullett"; + egg_test_title (test, "markdown (type2 header)"); + text = egg_markdown_parse (self, markdown); + if (g_str_equal (text, markdown_expected)) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); + g_free (text); + + + /************************************************************/ + markdown = "this is http://www.hughsie.com/with_spaces_in_url inline link\n"; + markdown_expected = "this is http://www.hughsie.com/with_spaces_in_url inline link"; + egg_test_title (test, "markdown (autocode)"); + egg_markdown_set_autocode (self, TRUE); + text = egg_markdown_parse (self, markdown); + if (g_str_equal (text, markdown_expected)) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); + g_free (text); + + /************************************************************/ + markdown = "*** This software is currently in alpha state ***\n"; + markdown_expected = " This software is currently in alpha state "; + egg_test_title (test, "markdown some invalid header"); + text = egg_markdown_parse (self, markdown); + if (g_str_equal (text, markdown_expected)) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); + g_free (text); + + /************************************************************/ + markdown = " - This is a *very*\n" + " short paragraph\n" + " that is not usual.\n" + " - Another"; + markdown_expected = + "• This is a very short paragraph that is not usual.\n" + "• Another"; + egg_test_title (test, "markdown (complex1)"); + text = egg_markdown_parse (self, markdown); + if (g_str_equal (text, markdown_expected)) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); + g_free (text); + + /************************************************************/ + markdown = "* This is a *very*\n" + " short paragraph\n" + " that is not usual.\n" + "* This is the second\n" + " bullett point.\n" + "* And the third.\n" + " \n" + "* * *\n" + " \n" + "Paragraph one\n" + "isn't __very__ long at all.\n" + "\n" + "Paragraph two\n" + "isn't much better."; + markdown_expected = + "• This is a very short paragraph that is not usual.\n" + "• This is the second bullett point.\n" + "• And the third.\n" + "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯\n" + "Paragraph one isn't very long at all.\n" + "Paragraph two isn't much better."; + egg_test_title (test, "markdown (complex1)"); + text = egg_markdown_parse (self, markdown); + if (g_str_equal (text, markdown_expected)) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); + g_free (text); + + /************************************************************/ + markdown = "This is a spec file description or\n" + "an **update** description in bohdi.\n" + "\n" + "* * *\n" + "# Big title #\n" + "\n" + "The *following* things 'were' fixed:\n" + "- Fix `dave`\n" + "* Fubar update because of \"security\"\n"; + markdown_expected = + "This is a spec file description or an update description in bohdi.\n" + "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯\n" + "Big title\n" + "The following things 'were' fixed:\n" + "• Fix dave\n" + "• Fubar update because of \"security\""; + egg_test_title (test, "markdown (complex2)"); + text = egg_markdown_parse (self, markdown); + if (g_str_equal (text, markdown_expected)) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); + g_free (text); + + /************************************************************/ + markdown = "* list seporated with spaces -\n" + " first item\n" + "\n" + "* second item\n" + "\n" + "* third item\n"; + markdown_expected = + "• list seporated with spaces - first item\n" + "• second item\n" + "• third item"; + egg_test_title (test, "markdown (list with spaces)"); + text = egg_markdown_parse (self, markdown); + if (g_str_equal (text, markdown_expected)) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); + g_free (text); + + /************************************************************/ + ret = egg_markdown_set_max_lines (self, 1); + egg_test_title_assert (test, "set max_lines", ret); + + /************************************************************/ + markdown = "* list seporated with spaces -\n" + " first item\n" + "* second item\n"; + markdown_expected = + "• list seporated with spaces - first item"; + egg_test_title (test, "markdown (one line limit)"); + text = egg_markdown_parse (self, markdown); + if (g_str_equal (text, markdown_expected)) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); + g_free (text); + + /************************************************************/ + ret = egg_markdown_set_max_lines (self, 1); + egg_test_title_assert (test, "set max_lines", ret); + + /************************************************************/ + markdown = "* list & spaces"; + markdown_expected = + "• list & spaces"; + egg_test_title (test, "markdown (escaping)"); + text = egg_markdown_parse (self, markdown); + if (g_str_equal (text, markdown_expected)) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); + g_free (text); + + /************************************************************/ + egg_test_title (test, "markdown (free text)"); + text = egg_markdown_parse (self, "This isn't a present"); + if (g_str_equal (text, "This isn't a present")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s'", text); + g_free (text); + + /************************************************************/ + egg_test_title (test, "markdown (autotext underscore)"); + text = egg_markdown_parse (self, "This isn't CONFIG_UEVENT_HELPER_PATH present"); + if (g_str_equal (text, "This isn't CONFIG_UEVENT_HELPER_PATH present")) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s'", text); + g_free (text); + + /************************************************************/ + markdown = "*Thu Mar 12 12:00:00 2009* Dan Walsh - 2.0.79-1\n" + "- Update to upstream \n" + " * Netlink socket handoff patch from Adam Jackson.\n" + " * AVC caching of compute_create results by Eric Paris.\n" + "\n" + "*Tue Mar 10 12:00:00 2009* Dan Walsh - 2.0.78-5\n" + "- Add patch from ajax to accellerate X SELinux \n" + "- Update eparis patch\n"; + markdown_expected = + "Thu Mar 12 12:00:00 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.79-1\n" + "• Update to upstream\n" + "• Netlink socket handoff patch from Adam Jackson.\n" + "• AVC caching of compute_create results by Eric Paris.\n" + "Tue Mar 10 12:00:00 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.78-5\n" + "• Add patch from ajax to accellerate X SELinux\n" + "• Update eparis patch"; + egg_test_title (test, "markdown (end of bullett)"); + egg_markdown_set_escape (self, TRUE); + ret = egg_markdown_set_max_lines (self, 1024); + text = egg_markdown_parse (self, markdown); + if (g_str_equal (text, markdown_expected)) + egg_test_success (test, NULL); + else + egg_test_failed (test, "failed, got '%s', expected '%s'", text, markdown_expected); + g_free (text); + + g_object_unref (self); + + egg_test_end (test); +} +#endif + diff --git a/hardinfo2/help-viewer/help-viewer.c b/hardinfo2/help-viewer/help-viewer.c new file mode 100644 index 00000000..ace6ef37 --- /dev/null +++ b/hardinfo2/help-viewer/help-viewer.c @@ -0,0 +1,514 @@ +/* + * HelpViewer - Simple Help file browser + * Copyright (C) 2009 Leandro A. F. Pereira + * + * 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 + */ + +#define _GNU_SOURCE /* for strcasestr() */ +#include +#include +#include + +#include "config.h" +#include "shell.h" +#include "markdown-text-view.h" +#include "help-viewer.h" +#include "hardinfo.h" + +static void do_search(HelpViewer *hv, gchar *text); + +static void forward_clicked(GtkWidget *widget, gpointer data) +{ + HelpViewer *hv = (HelpViewer *)data; + GSList *temp; + + /* puts the current file on the back stack */ + hv->back_stack = g_slist_prepend(hv->back_stack, g_strdup(hv->current_file)); + + /* enables the back button */ + gtk_widget_set_sensitive(hv->btn_back, TRUE); + + /* loads the new current file */ + if (g_str_has_prefix(hv->forward_stack->data, "search://")) { + do_search(hv, hv->forward_stack->data + sizeof("search://") - 1); + } else { + markdown_textview_load_file(MARKDOWN_TEXTVIEW(hv->text_view), hv->forward_stack->data); + } + + /* pops the stack */ + temp = hv->forward_stack->next; + g_free(hv->forward_stack->data); + g_slist_free1(hv->forward_stack); + hv->forward_stack = temp; + + /* if there aren't items on forward stack anymore, disables the button */ + if (!hv->forward_stack) { + gtk_widget_set_sensitive(hv->btn_forward, FALSE); + } +} + +static void back_clicked(GtkWidget *widget, gpointer data) +{ + HelpViewer *hv = (HelpViewer *)data; + GSList *temp; + + /* puts the current file on the forward stack */ + hv->forward_stack = g_slist_prepend(hv->forward_stack, g_strdup(hv->current_file)); + + /* enables the forward button */ + gtk_widget_set_sensitive(hv->btn_forward, TRUE); + + /* loads the new current file */ + if (g_str_has_prefix(hv->back_stack->data, "search://")) { + do_search(hv, hv->back_stack->data + sizeof("search://") - 1); + } else { + markdown_textview_load_file(MARKDOWN_TEXTVIEW(hv->text_view), hv->back_stack->data); + } + + /* pops the stack */ + temp = hv->back_stack->next; + g_free(hv->back_stack->data); + g_slist_free1(hv->back_stack); + hv->back_stack = temp; + + /* if there aren't items on back stack anymore, disables the button */ + if (!hv->back_stack) { + gtk_widget_set_sensitive(hv->btn_back, FALSE); + } +} + +static void link_clicked(MarkdownTextView *text_view, gchar *link, gpointer data) +{ + HelpViewer *hv = (HelpViewer *)data; + + if (g_str_has_prefix(link, "http://")) { + open_url(link); + } else { + /* adds the current file to the back stack (before loading the new file */ + hv->back_stack = g_slist_prepend(hv->back_stack, g_strdup(hv->current_file)); + gtk_widget_set_sensitive(hv->btn_back, TRUE); + + gtk_statusbar_pop(GTK_STATUSBAR(hv->status_bar), 1); + markdown_textview_load_file(text_view, link); + } +} + +static void file_load_complete(MarkdownTextView *text_view, gchar *file, gpointer data) +{ + HelpViewer *hv = (HelpViewer *)data; + + /* sets the currently-loaded file */ + g_free(hv->current_file); + hv->current_file = g_strdup(file); + + gtk_statusbar_push(GTK_STATUSBAR(hv->status_bar), 1, "Done."); +} + +static void hovering_over_link(MarkdownTextView *text_view, gchar *link, gpointer data) +{ + HelpViewer *hv = (HelpViewer *)data; + gchar *temp; + + temp = g_strconcat("Link to ", link, NULL); + + gtk_statusbar_push(GTK_STATUSBAR(hv->status_bar), 1, temp); + + g_free(temp); +} + +static void hovering_over_text(MarkdownTextView *text_view, gpointer data) +{ + HelpViewer *hv = (HelpViewer *)data; + + gtk_statusbar_pop(GTK_STATUSBAR(hv->status_bar), 1); +} + +static void do_search(HelpViewer *hv, gchar *text) +{ + GString *markdown; + GDir *dir; + gchar **terms; + gint no_results = 0; + int term; + + /* + * FIXME: This search is currently pretty slow; think on a better way to do search. + * Ideas: + * - Build a index the first time the help file is opened + * - Search only titles and subtitles + */ + + terms = g_strsplit(text, " ", 0); + markdown = g_string_new("# Search Results\n"); + g_string_append_printf(markdown, "Search terms: *%s*\n****\n", text); + + gtk_widget_set_sensitive(hv->window, FALSE); + + if ((dir = g_dir_open(hv->help_directory, 0, NULL))) { + const gchar *name; + + while ((name = g_dir_read_name(dir))) { +#if GTK_CHECK_VERSION(2,16,0) + gtk_entry_progress_pulse(GTK_ENTRY(hv->text_search)); +#endif /* GTK_CHECK_VERSION(2,16,0) */ + + if (g_str_has_suffix(name, ".hlp")) { + FILE *file; + gchar *path; + gchar buffer[256]; + + path = g_build_filename(hv->help_directory, name, NULL); + if ((file = fopen(path, "rb"))) { + gboolean found = FALSE; + gchar *title = NULL; + + while (!found && fgets(buffer, sizeof buffer, file)) { + if (!title && (g_str_has_prefix(buffer, "# ") || g_str_has_prefix(buffer, " # "))) { + title = g_strstrip(strchr(buffer, '#') + 1); + title = g_strdup(title); + } + + for (term = 0; !found && terms[term]; term++) { +#ifdef strcasestr + found = strcasestr(buffer, terms[term]) != NULL; +#else + gchar *upper1, *upper2; + + upper1 = g_utf8_strup(buffer, -1); + upper2 = g_utf8_strup(terms[term], -1); + + found = strstr(upper1, upper2) != NULL; + + g_free(upper1); + g_free(upper2); +#endif + } + } + + if (found) { + no_results++; + + if (title) { + g_string_append_printf(markdown, + "* [%s %s]\n", name, title); + } else { + g_string_append_printf(markdown, + "* [%s %s]\n", name, name); + } + } + + g_free(title); + fclose(file); + } + + g_free(path); + } + } + + g_dir_close(dir); + } + + + if (no_results == 0) { + g_string_append_printf(markdown, + "Search returned no results."); + } else { + g_string_append_printf(markdown, + "****\n%d results found.", no_results); + } + + /* shows the results inside the textview */ + markdown_textview_set_text(MARKDOWN_TEXTVIEW(hv->text_view), markdown->str); + + g_free(hv->current_file); + hv->current_file = g_strdup_printf("search://%s", text); + +#if GTK_CHECK_VERSION(2,16,0) + gtk_entry_set_progress_fraction(GTK_ENTRY(hv->text_search), 0.0f); +#endif /* GTK_CHECK_VERSION(2,16,0) */ + gtk_widget_set_sensitive(hv->window, TRUE); + + g_string_free(markdown, TRUE); + g_strfreev(terms); +} + +static void activate(GtkEntry *entry, gpointer data) +{ + HelpViewer *hv = (HelpViewer *)data; + + /* adds the current file to the back stack (before loading the new file */ + hv->back_stack = g_slist_prepend(hv->back_stack, g_strdup(hv->current_file)); + gtk_widget_set_sensitive(hv->btn_back, TRUE); + + do_search((HelpViewer *)data, (gchar *)gtk_entry_get_text(entry)); +} + +#if GTK_CHECK_VERSION(2,16,0) +static void icon_press(GtkEntry *entry, gint position, + GdkEventButton *event, gpointer data) +{ + if (position == GTK_ENTRY_ICON_SECONDARY) + activate(entry, data); +} +#endif /* GTK_CHECK_VERSION(2,16,0) */ + +static void home_clicked(GtkWidget *button, gpointer data) +{ + HelpViewer *hv = (HelpViewer *)data; + + help_viewer_open_page(hv, "index.hlp"); +} + +void help_viewer_open_page(HelpViewer *hv, const gchar *page) +{ + gchar *temp; + + temp = g_strdup(hv->current_file); + + if (!markdown_textview_load_file(MARKDOWN_TEXTVIEW(hv->text_view), page)) { + GtkWidget *dialog; + Shell *shell; + + shell = shell_get_main_shell(); + dialog = gtk_message_dialog_new(GTK_WINDOW(shell->window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Cannot open help file (%s).", + page); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + g_free(temp); + } else { + /* adds the current file to the back stack (before loading the new file */ + hv->back_stack = g_slist_prepend(hv->back_stack, temp); + gtk_widget_set_sensitive(hv->btn_back, TRUE); + gtk_window_present(GTK_WINDOW(hv->window)); + } +} + +void help_viewer_destroy(HelpViewer *hv) +{ + Shell *shell; + GSList *item; + + for (item = hv->back_stack; item; item = item->next) { + g_free(item->data); + } + + for (item = hv->forward_stack; item; item = item->next) { + g_free(item->data); + } + + g_slist_free(hv->back_stack); + g_slist_free(hv->forward_stack); + + g_free(hv->current_file); + g_free(hv->help_directory); + + shell = shell_get_main_shell(); + shell->help_viewer = NULL; +} + +static gboolean destroy_me(GtkWidget *widget, gpointer data) +{ + HelpViewer *hv = (HelpViewer *)data; + + help_viewer_destroy(hv); + + return FALSE; +} + +HelpViewer * +help_viewer_new (const gchar *help_dir, const gchar *help_file) +{ + Shell *shell; + HelpViewer *hv; + GtkWidget *help_viewer; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *toolbar1; + GtkIconSize tmp_toolbar_icon_size; + GtkWidget *btn_back; + GtkWidget *btn_forward; + GtkWidget *separatortoolitem1; + GtkWidget *toolbar2; + GtkWidget *toolitem3; +#if !GTK_CHECK_VERSION(2,16,0) + GtkWidget *label1; +#endif /* GTK_CHECK_VERSION(2,16,0) */ + GtkWidget *toolitem4; + GtkWidget *txt_search; + GtkWidget *scrolledhelp_viewer; + GtkWidget *markdown_textview; + GtkWidget *status_bar; + GtkWidget *btn_home; + GdkPixbuf *icon; + + shell = shell_get_main_shell(); + + help_viewer = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_size_request(help_viewer, 300, 200); + gtk_window_set_default_size(GTK_WINDOW(help_viewer), 640, 480); + gtk_window_set_title(GTK_WINDOW(help_viewer), "Help Viewer"); + gtk_window_set_transient_for(GTK_WINDOW(help_viewer), GTK_WINDOW(shell->window)); + + icon = gtk_widget_render_icon(help_viewer, GTK_STOCK_HELP, + GTK_ICON_SIZE_DIALOG, + NULL); + gtk_window_set_icon(GTK_WINDOW(help_viewer), icon); + g_object_unref(icon); + + vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox); + gtk_container_add (GTK_CONTAINER (help_viewer), vbox); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + toolbar1 = gtk_toolbar_new (); + gtk_widget_show (toolbar1); + gtk_box_pack_start (GTK_BOX (hbox), toolbar1, TRUE, TRUE, 0); + gtk_toolbar_set_style (GTK_TOOLBAR (toolbar1), GTK_TOOLBAR_BOTH_HORIZ); + tmp_toolbar_icon_size = gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar1)); + + btn_back = (GtkWidget*) gtk_tool_button_new_from_stock ("gtk-go-back"); + gtk_widget_show (btn_back); + gtk_container_add (GTK_CONTAINER (toolbar1), btn_back); + gtk_tool_item_set_is_important (GTK_TOOL_ITEM (btn_back), TRUE); + gtk_widget_set_sensitive(btn_back, FALSE); + + btn_forward = (GtkWidget*) gtk_tool_button_new_from_stock ("gtk-go-forward"); + gtk_widget_show (btn_forward); + gtk_container_add (GTK_CONTAINER (toolbar1), btn_forward); + gtk_widget_set_sensitive(btn_forward, FALSE); + + separatortoolitem1 = (GtkWidget*) gtk_separator_tool_item_new (); + gtk_widget_show (separatortoolitem1); + gtk_container_add (GTK_CONTAINER (toolbar1), separatortoolitem1); + + btn_home = (GtkWidget*) gtk_tool_button_new_from_stock ("gtk-home"); + gtk_widget_show (btn_home); + gtk_container_add (GTK_CONTAINER (toolbar1), btn_home); + + toolbar2 = gtk_toolbar_new (); + gtk_widget_show (toolbar2); + gtk_box_pack_end (GTK_BOX (hbox), toolbar2, FALSE, TRUE, 0); + gtk_toolbar_set_style (GTK_TOOLBAR (toolbar2), GTK_TOOLBAR_BOTH_HORIZ); + gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar2), FALSE); + tmp_toolbar_icon_size = gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar2)); + + toolitem3 = (GtkWidget*) gtk_tool_item_new (); + gtk_widget_show (toolitem3); + gtk_container_add (GTK_CONTAINER (toolbar2), toolitem3); + +#if !GTK_CHECK_VERSION(2,16,0) + label1 = gtk_label_new_with_mnemonic ("_Search:"); + gtk_widget_show (label1); + gtk_container_add (GTK_CONTAINER (toolitem3), label1); +#endif /* GTK_CHECK_VERSION(2,16,0) */ + + toolitem4 = (GtkWidget*) gtk_tool_item_new (); + gtk_widget_show (toolitem4); + gtk_container_add (GTK_CONTAINER (toolbar2), toolitem4); + + txt_search = gtk_entry_new (); + gtk_widget_show (txt_search); + gtk_container_add (GTK_CONTAINER (toolitem4), txt_search); + gtk_entry_set_invisible_char (GTK_ENTRY (txt_search), 9679); +#if GTK_CHECK_VERSION(2,16,0) + gtk_entry_set_icon_from_stock(GTK_ENTRY(txt_search), + GTK_ENTRY_ICON_SECONDARY, + GTK_STOCK_FIND); +#endif /* GTK_CHECK_VERSION(2,16,0) */ + + scrolledhelp_viewer = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledhelp_viewer); + gtk_box_pack_start (GTK_BOX (vbox), scrolledhelp_viewer, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledhelp_viewer), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + + markdown_textview = markdown_textview_new(); + markdown_textview_set_image_directory(MARKDOWN_TEXTVIEW(markdown_textview), help_dir); + gtk_widget_show (markdown_textview); + gtk_container_add (GTK_CONTAINER (scrolledhelp_viewer), markdown_textview); + + status_bar = gtk_statusbar_new (); + gtk_widget_show (status_bar); + gtk_box_pack_start (GTK_BOX (vbox), status_bar, FALSE, FALSE, 0); + + hv = g_new0(HelpViewer, 1); + hv->window = help_viewer; + hv->status_bar = status_bar; + hv->btn_back = btn_back; + hv->btn_forward = btn_forward; + hv->text_view = markdown_textview; + hv->text_search = txt_search; + hv->help_directory = g_strdup(help_dir); + hv->back_stack = NULL; + hv->forward_stack = NULL; + + g_signal_connect(markdown_textview, "link-clicked", G_CALLBACK(link_clicked), hv); + g_signal_connect(markdown_textview, "hovering-over-link", G_CALLBACK(hovering_over_link), hv); + g_signal_connect(markdown_textview, "hovering-over-text", G_CALLBACK(hovering_over_text), hv); + g_signal_connect(markdown_textview, "file-load-complete", G_CALLBACK(file_load_complete), hv); + + g_signal_connect(btn_back, "clicked", G_CALLBACK(back_clicked), hv); + g_signal_connect(btn_forward, "clicked", G_CALLBACK(forward_clicked), hv); + g_signal_connect(btn_home, "clicked", G_CALLBACK(home_clicked), hv); + + g_signal_connect(help_viewer, "delete-event", G_CALLBACK(destroy_me), hv); + g_signal_connect(txt_search, "activate", G_CALLBACK(activate), hv); + +#if GTK_CHECK_VERSION(2,16,0) + g_signal_connect(txt_search, "icon-press", G_CALLBACK(icon_press), hv); +#endif /* GTK_CHECK_VERSION(2,16,0) */ + + if (!markdown_textview_load_file(MARKDOWN_TEXTVIEW(markdown_textview), help_file ? help_file : "index.hlp")) { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new(GTK_WINDOW(shell->window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Cannot open help file (%s).", + help_file ? help_file : "index.hlp"); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + gtk_widget_destroy(hv->window); + g_free(hv); + + return NULL; + } + + gtk_widget_show_all(hv->window); + + return hv; +} + +#ifdef HELPVIEWER_TEST +int main(int argc, char **argv) +{ + HelpViewer *hv; + + gtk_init(&argc, &argv); + + hv = help_viewer_new("documentation", NULL); + + gtk_main(); +} +#endif /* HELPVIEWER_TEST */ diff --git a/hardinfo2/help-viewer/markdown-text-view.c b/hardinfo2/help-viewer/markdown-text-view.c new file mode 100644 index 00000000..6bfcc131 --- /dev/null +++ b/hardinfo2/help-viewer/markdown-text-view.c @@ -0,0 +1,637 @@ +/* + * Markdown Text View + * GtkTextView subclass that supports Markdown syntax + * + * Copyright (C) 2009 Leandro Pereira + * Portions Copyright (C) 2007-2008 Richard Hughes + * 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. + */ +#include +#include + +#include "markdown-text-view.h" +#include "config.h" + +static GdkCursor *hand_cursor = NULL; + +G_DEFINE_TYPE(MarkdownTextView, markdown_textview, GTK_TYPE_TEXT_VIEW); + +enum { + LINK_CLICKED, + HOVERING_OVER_LINK, + HOVERING_OVER_TEXT, + FILE_LOAD_COMPLETE, + LAST_SIGNAL +}; + +static guint markdown_textview_signals[LAST_SIGNAL] = { 0 }; + +GtkWidget *markdown_textview_new() +{ + return g_object_new(TYPE_MARKDOWN_TEXTVIEW, NULL); +} + +static void markdown_textview_class_init(MarkdownTextViewClass * klass) +{ + GObjectClass *object_class; + + if (!hand_cursor) { + hand_cursor = gdk_cursor_new(GDK_HAND2); + } + + object_class = G_OBJECT_CLASS(klass); + + markdown_textview_signals[LINK_CLICKED] = g_signal_new( + "link-clicked", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(MarkdownTextViewClass, link_clicked), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + + markdown_textview_signals[HOVERING_OVER_LINK] = g_signal_new( + "hovering-over-link", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(MarkdownTextViewClass, hovering_over_link), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + + markdown_textview_signals[HOVERING_OVER_TEXT] = g_signal_new( + "hovering-over-text", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(MarkdownTextViewClass, hovering_over_text), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + markdown_textview_signals[FILE_LOAD_COMPLETE] = g_signal_new( + "file-load-complete", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(MarkdownTextViewClass, file_load_complete), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); +} + +static void +gtk_text_buffer_insert_markup(GtkTextBuffer * buffer, GtkTextIter * iter, + const gchar * markup) +{ + PangoAttrIterator *paiter; + PangoAttrList *attrlist; + GtkTextMark *mark; + GError *error = NULL; + gchar *text; + + g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer)); + g_return_if_fail(markup != NULL); + + if (*markup == '\000') + return; + + /* invalid */ + if (!pango_parse_markup(markup, -1, 0, &attrlist, &text, NULL, &error)) { + g_warning("Invalid markup string: %s", error->message); + g_error_free(error); + return; + } + + /* trivial, no markup */ + if (attrlist == NULL) { + gtk_text_buffer_insert(buffer, iter, text, -1); + g_free(text); + return; + } + + /* create mark with right gravity */ + mark = gtk_text_buffer_create_mark(buffer, NULL, iter, FALSE); + paiter = pango_attr_list_get_iterator(attrlist); + + do { + PangoAttribute *attr; + GtkTextTag *tag; + GtkTextTag *tag_para; + gint start, end; + + pango_attr_iterator_range(paiter, &start, &end); + + if (end == G_MAXINT) /* last chunk */ + end = start - 1; /* resulting in -1 to be passed to _insert */ + + tag = gtk_text_tag_new(NULL); + + if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_LANGUAGE))) + g_object_set(tag, "language", + pango_language_to_string(((PangoAttrLanguage *) + attr)->value), NULL); + + if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_FAMILY))) + g_object_set(tag, "family", ((PangoAttrString *) attr)->value, + NULL); + + if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_STYLE))) + g_object_set(tag, "style", ((PangoAttrInt *) attr)->value, + NULL); + + if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_WEIGHT))) + g_object_set(tag, "weight", ((PangoAttrInt *) attr)->value, + NULL); + + if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_VARIANT))) + g_object_set(tag, "variant", ((PangoAttrInt *) attr)->value, + NULL); + + if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_STRETCH))) + g_object_set(tag, "stretch", ((PangoAttrInt *) attr)->value, + NULL); + + if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_SIZE))) + g_object_set(tag, "size", ((PangoAttrInt *) attr)->value, + NULL); + + if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_FONT_DESC))) + g_object_set(tag, "font-desc", + ((PangoAttrFontDesc *) attr)->desc, NULL); + + if ((attr = + pango_attr_iterator_get(paiter, PANGO_ATTR_FOREGROUND))) { + GdkColor col = { 0, + ((PangoAttrColor *) attr)->color.red, + ((PangoAttrColor *) attr)->color.green, + ((PangoAttrColor *) attr)->color.blue + }; + + g_object_set(tag, "foreground-gdk", &col, NULL); + } + + if ((attr = + pango_attr_iterator_get(paiter, PANGO_ATTR_BACKGROUND))) { + GdkColor col = { 0, + ((PangoAttrColor *) attr)->color.red, + ((PangoAttrColor *) attr)->color.green, + ((PangoAttrColor *) attr)->color.blue + }; + + g_object_set(tag, "background-gdk", &col, NULL); + } + + if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_UNDERLINE))) + g_object_set(tag, "underline", ((PangoAttrInt *) attr)->value, + NULL); + + if ((attr = + pango_attr_iterator_get(paiter, PANGO_ATTR_STRIKETHROUGH))) + g_object_set(tag, "strikethrough", + (gboolean) (((PangoAttrInt *) attr)->value != 0), + NULL); + + if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_RISE))) + g_object_set(tag, "rise", ((PangoAttrInt *) attr)->value, + NULL); + + if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_SCALE))) + g_object_set(tag, "scale", ((PangoAttrFloat *) attr)->value, + NULL); + + gtk_text_tag_table_add(gtk_text_buffer_get_tag_table(buffer), tag); + + tag_para = + gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table + (buffer), "para"); + gtk_text_buffer_insert_with_tags(buffer, iter, text + start, + end - start, tag, tag_para, NULL); + + /* mark had right gravity, so it should be + * at the end of the inserted text now */ + gtk_text_buffer_get_iter_at_mark(buffer, iter, mark); + } while (pango_attr_iterator_next(paiter)); + + gtk_text_buffer_delete_mark(buffer, mark); + pango_attr_iterator_destroy(paiter); + pango_attr_list_unref(attrlist); + g_free(text); +} + + +static void +set_cursor_if_appropriate(MarkdownTextView * self, gint x, gint y) +{ + GSList *tags = NULL, *tagp = NULL; + GtkTextIter iter; + gboolean hovering = FALSE; + gchar *link_uri = NULL; + + gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(self), &iter, x, + y); + + tags = gtk_text_iter_get_tags(&iter); + for (tagp = tags; tagp != NULL; tagp = tagp->next) { + GtkTextTag *tag = tagp->data; + gint is_underline = 0; + gchar *lang = NULL; + + g_object_get(G_OBJECT(tag), + "underline", &is_underline, + "language", &lang, + NULL); + + if (is_underline == 1 && lang) { + link_uri = egg_markdown_get_link_uri(self->markdown, atoi(lang)); + g_free(lang); + hovering = TRUE; + break; + } + + g_free(lang); + } + + if (hovering != self->hovering_over_link) { + self->hovering_over_link = hovering; + + if (self->hovering_over_link) { + g_signal_emit(self, markdown_textview_signals[HOVERING_OVER_LINK], + 0, link_uri); + gdk_window_set_cursor(gtk_text_view_get_window + (GTK_TEXT_VIEW(self), + GTK_TEXT_WINDOW_TEXT), hand_cursor); + } else { + g_signal_emit(self, markdown_textview_signals[HOVERING_OVER_TEXT], 0); + gdk_window_set_cursor(gtk_text_view_get_window + (GTK_TEXT_VIEW(self), + GTK_TEXT_WINDOW_TEXT), NULL); + } + } + + if (link_uri) + g_free(link_uri); + + if (tags) + g_slist_free(tags); +} + +/* Update the cursor image if the pointer moved. + */ +static gboolean +motion_notify_event(GtkWidget * self, GdkEventMotion * event) +{ + gint x, y; + + gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(self), + GTK_TEXT_WINDOW_WIDGET, + event->x, event->y, &x, &y); + + set_cursor_if_appropriate(MARKDOWN_TEXTVIEW(self), x, y); + + gdk_window_get_pointer(self->window, NULL, NULL, NULL); + return FALSE; +} + +/* Also update the cursor image if the window becomes visible + * (e.g. when a window covering it got iconified). + */ +static gboolean +visibility_notify_event(GtkWidget * self, GdkEventVisibility * event) +{ + gint wx, wy, bx, by; + + gdk_window_get_pointer(self->window, &wx, &wy, NULL); + + gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(self), + GTK_TEXT_WINDOW_WIDGET, + wx, wy, &bx, &by); + + set_cursor_if_appropriate(MARKDOWN_TEXTVIEW(self), bx, by); + + return FALSE; +} + +static void +follow_if_link(GtkWidget * widget, GtkTextIter * iter) +{ + GSList *tags = NULL, *tagp = NULL; + MarkdownTextView *self = MARKDOWN_TEXTVIEW(widget); + + tags = gtk_text_iter_get_tags(iter); + for (tagp = tags; tagp != NULL; tagp = tagp->next) { + GtkTextTag *tag = tagp->data; + gint is_underline = 0; + gchar *lang = NULL; + + g_object_get(G_OBJECT(tag), + "underline", &is_underline, + "language", &lang, + NULL); + + if (is_underline == 1 && lang) { + gchar *link = egg_markdown_get_link_uri(self->markdown, atoi(lang)); + if (link) { + g_signal_emit(self, markdown_textview_signals[LINK_CLICKED], + 0, link); + g_free(link); + } + g_free(lang); + break; + } + + g_free(lang); + } + + if (tags) + g_slist_free(tags); +} + +static gboolean +key_press_event(GtkWidget * self, + GdkEventKey * event) +{ + GtkTextIter iter; + GtkTextBuffer *buffer; + + switch (event->keyval) { + case GDK_Return: + case GDK_KP_Enter: + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); + gtk_text_buffer_get_iter_at_mark(buffer, &iter, + gtk_text_buffer_get_insert + (buffer)); + follow_if_link(self, &iter); + break; + + default: + break; + } + + return FALSE; +} + +static gboolean +event_after(GtkWidget * self, GdkEvent * ev) +{ + GtkTextIter start, end, iter; + GtkTextBuffer *buffer; + GdkEventButton *event; + gint x, y; + + if (ev->type != GDK_BUTTON_RELEASE) + return FALSE; + + event = (GdkEventButton *) ev; + + if (event->button != 1) + return FALSE; + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); + + /* we shouldn't follow a link if the user has selected something */ + gtk_text_buffer_get_selection_bounds(buffer, &start, &end); + if (gtk_text_iter_get_offset(&start) != gtk_text_iter_get_offset(&end)) + return FALSE; + + gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(self), + GTK_TEXT_WINDOW_WIDGET, + event->x, event->y, &x, &y); + + gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(self), &iter, x, + y); + + follow_if_link(self, &iter); + + return FALSE; +} + +void +markdown_textview_clear(MarkdownTextView * self) +{ + GtkTextBuffer *text_buffer; + + g_return_if_fail(IS_MARKDOWN_TEXTVIEW(self)); + + egg_markdown_clear(self->markdown); + + text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); + gtk_text_buffer_set_text(text_buffer, "\n", 1); +} + +static void +load_images(MarkdownTextView * self) +{ + GtkTextBuffer *buffer; + GtkTextIter iter; + GSList *tags, *tagp; + gchar *image_path; + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); + gtk_text_buffer_get_start_iter(buffer, &iter); + + do { + tags = gtk_text_iter_get_tags(&iter); + for (tagp = tags; tagp != NULL; tagp = tagp->next) { + GtkTextTag *tag = tagp->data; + gint is_underline = 0; + gchar *lang = NULL; + + g_object_get(G_OBJECT(tag), + "underline", &is_underline, + "language", &lang, + NULL); + + if (is_underline == 2 && lang) { + GdkPixbuf *pixbuf; + gchar *path; + + image_path = egg_markdown_get_link_uri(self->markdown, atoi(lang)); + path = g_build_filename(self->image_directory, image_path, NULL); + pixbuf = gdk_pixbuf_new_from_file(path, NULL); + if (pixbuf) { + GtkTextMark *mark; + GtkTextIter start; + + mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, FALSE); + + gtk_text_buffer_get_iter_at_mark(buffer, &start, mark); + gtk_text_iter_forward_to_tag_toggle(&iter, tag); + gtk_text_buffer_delete(buffer, &start, &iter); + + gtk_text_buffer_insert_pixbuf(buffer, &iter, pixbuf); + + g_object_unref(pixbuf); + gtk_text_buffer_delete_mark(buffer, mark); + } + + g_free(image_path); + g_free(lang); + g_free(path); + break; + } + + g_free(lang); + } + + if (tags) + g_slist_free(tags); + } while (gtk_text_iter_forward_to_tag_toggle(&iter, NULL)); +} + +static gboolean +append_text(MarkdownTextView * self, + const gchar * text) +{ + GtkTextIter iter; + GtkTextBuffer *text_buffer; + gchar *line; + + g_return_val_if_fail(IS_MARKDOWN_TEXTVIEW(self), FALSE); + + text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); + gtk_text_buffer_get_end_iter(text_buffer, &iter); + + line = egg_markdown_parse(self->markdown, text); + if (line && *line) { + gtk_text_buffer_insert_markup(text_buffer, &iter, line); + gtk_text_buffer_insert(text_buffer, &iter, "\n", 1); + g_free(line); + + return TRUE; + } + + return FALSE; +} + +gboolean +markdown_textview_set_text(MarkdownTextView * self, + const gchar * text) +{ + gboolean result = TRUE; + gchar **lines; + gint line; + + g_return_val_if_fail(IS_MARKDOWN_TEXTVIEW(self), FALSE); + + markdown_textview_clear(self); + + lines = g_strsplit(text, "\n", 0); + for (line = 0; result && lines[line]; line++) { + result = append_text(self, (const gchar *)lines[line]); + } + g_strfreev(lines); + + load_images(self); + + return result; +} + +gboolean +markdown_textview_load_file(MarkdownTextView * self, + const gchar * file_name) +{ + FILE *text_file; + gchar *path; + + g_return_val_if_fail(IS_MARKDOWN_TEXTVIEW(self), FALSE); + + path = g_build_filename(self->image_directory, file_name, NULL); + + /* we do assume UTF-8 encoding */ + if ((text_file = fopen(path, "rb"))) { + GtkTextBuffer *text_buffer; + GtkTextIter iter; + gchar *line; + gchar buffer[EGG_MARKDOWN_MAX_LINE_LENGTH]; + + text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); + + gtk_text_buffer_set_text(text_buffer, "\n", 1); + gtk_text_buffer_get_start_iter(text_buffer, &iter); + + egg_markdown_clear(self->markdown); + + while (fgets(buffer, EGG_MARKDOWN_MAX_LINE_LENGTH, text_file)) { + line = egg_markdown_parse(self->markdown, buffer); + + if (line && *line) { + gtk_text_buffer_insert_markup(text_buffer, &iter, line); + gtk_text_buffer_insert(text_buffer, &iter, "\n", 1); + } + + g_free(line); + } + fclose(text_file); + + load_images(self); + + g_signal_emit(self, markdown_textview_signals[FILE_LOAD_COMPLETE], 0, file_name); + + g_free(path); + + return TRUE; + } + + g_free(path); + + return FALSE; +} + +void +markdown_textview_set_image_directory(MarkdownTextView * self, const gchar *directory) +{ + g_return_if_fail(IS_MARKDOWN_TEXTVIEW(self)); + + g_free(self->image_directory); + self->image_directory = g_strdup(directory); +} + +static void markdown_textview_init(MarkdownTextView * self) +{ + self->markdown = egg_markdown_new(); + self->image_directory = g_strdup("."); + + egg_markdown_set_output(self->markdown, EGG_MARKDOWN_OUTPUT_PANGO); + egg_markdown_set_escape(self->markdown, TRUE); + egg_markdown_set_autocode(self->markdown, TRUE); + egg_markdown_set_smart_quoting(self->markdown, TRUE); + + gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(self), GTK_WRAP_WORD); + gtk_text_view_set_editable(GTK_TEXT_VIEW(self), FALSE); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(self), 10); + gtk_text_view_set_right_margin(GTK_TEXT_VIEW(self), 10); + gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(self), 3); + gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW(self), 3); + + g_signal_connect(self, "event-after", + G_CALLBACK(event_after), NULL); + g_signal_connect(self, "key-press-event", + G_CALLBACK(key_press_event), NULL); + g_signal_connect(self, "motion-notify-event", + G_CALLBACK(motion_notify_event), NULL); + g_signal_connect(self, "visibility-notify-event", + G_CALLBACK(visibility_notify_event), NULL); +} + diff --git a/hardinfo2/iconcache.c b/hardinfo2/iconcache.c deleted file mode 100644 index c927ca5e..00000000 --- a/hardinfo2/iconcache.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 -#include -#include - -static GHashTable *cache = NULL; - -void icon_cache_init(void) -{ - DEBUG("initializing icon cache"); - if (!cache) { - cache = g_hash_table_new(g_str_hash, g_str_equal); - } else { - DEBUG("already initialized? huh?"); - } -} - -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/hardinfo2/iconcache.h b/hardinfo2/iconcache.h deleted file mode 100644 index 97f59a82..00000000 --- a/hardinfo2/iconcache.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 - -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/hardinfo2/includes/benchmark.h b/hardinfo2/includes/benchmark.h new file mode 100644 index 00000000..27bcbf4c --- /dev/null +++ b/hardinfo2/includes/benchmark.h @@ -0,0 +1,21 @@ +#ifndef __BENCHMARK_H__ +#define __BENCHMARK_H__ + +#include "hardinfo.h" + +extern ProgramParameters params; + +enum { + BENCHMARK_BLOWFISH, + BENCHMARK_CRYPTOHASH, + BENCHMARK_FIB, + BENCHMARK_NQUEENS, + BENCHMARK_FFT, + BENCHMARK_RAYTRACE, + BENCHMARK_GUI, + BENCHMARK_N_ENTRIES +} BenchmarkEntries; + +extern gdouble bench_results[BENCHMARK_N_ENTRIES]; + +#endif /* __BENCHMARK_H__ */ \ No newline at end of file diff --git a/hardinfo2/includes/binreloc.h b/hardinfo2/includes/binreloc.h new file mode 100644 index 00000000..3bf48bc6 --- /dev/null +++ b/hardinfo2/includes/binreloc.h @@ -0,0 +1,68 @@ +/* + * BinReloc - a library for creating relocatable executables + * Written by: Hongli Lai + * 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 + +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/hardinfo2/includes/blowfish.h b/hardinfo2/includes/blowfish.h new file mode 100644 index 00000000..3f33e945 --- /dev/null +++ b/hardinfo2/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/hardinfo2/includes/callbacks.h b/hardinfo2/includes/callbacks.h new file mode 100644 index 00000000..d53e1861 --- /dev/null +++ b/hardinfo2/includes/callbacks.h @@ -0,0 +1,45 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 + +void cb_about(); +void cb_about_module(GtkAction *action); +void cb_generate_report(); +void cb_save_graphic(); +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/hardinfo2/includes/computer.h b/hardinfo2/includes/computer.h new file mode 100644 index 00000000..05f7c4be --- /dev/null +++ b/hardinfo2/includes/computer.h @@ -0,0 +1,186 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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" + +#define DB_PREFIX "/etc/" + +static struct { + gchar *file, *codename; +} distro_db[] = { + { 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 "puppyversion", "ppy" }, + { 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" }, + { NULL, NULL } +}; + +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; +}; + +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 *fs_list; +extern GHashTable *_module_hash_table; +extern Computer *computer; +extern GHashTable *moreinfo; +extern gchar *module_list; + +gchar *computer_get_formatted_loadavg(); +gchar *computer_get_formatted_uptime(); +gchar *computer_get_alsacards(Computer * computer); + +OperatingSystem *computer_get_os(void); +AlsaInfo *computer_get_alsainfo(void); +LoadInfo *computer_get_loadinfo(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/hardinfo2/includes/devices.h b/hardinfo2/includes/devices.h new file mode 100644 index 00000000..adbffd8c --- /dev/null +++ b/hardinfo2/includes/devices.h @@ -0,0 +1,87 @@ +#ifndef __DEVICES_H__ +#define __DEVICES_H__ + +#include "hardinfo.h" +#include "processor-platform.h" + +#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); +void cpu_flags_init(void); +gchar *processor_get_capabilities_from_flags(gchar * strflags); +gchar *processor_get_detailed_info(Processor * processor); +gchar *processor_get_info(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); + +extern gchar *battery_list; +extern gchar *dmi_info; +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 *_resources; +extern gchar *sensors; +extern gchar *storage_icons; +extern gchar *storage_list; +extern gchar *usb_list; +extern GHashTable *memlabels; +extern GHashTable *moreinfo; +extern GHashTable *_pci_devices; +extern GHashTable *sensor_compute; +extern GHashTable *sensor_labels; +extern GModule *cups; + + + +#endif /* __DEVICES_H__ */ \ No newline at end of file diff --git a/hardinfo2/includes/egg-markdown.h b/hardinfo2/includes/egg-markdown.h new file mode 100644 index 00000000..4475b9f0 --- /dev/null +++ b/hardinfo2/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 + * Copyright (C) 2009 Leandro Pereira + * + * 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 + +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/hardinfo2/includes/expr.h b/hardinfo2/includes/expr.h new file mode 100644 index 00000000..4bda6b72 --- /dev/null +++ b/hardinfo2/includes/expr.h @@ -0,0 +1,48 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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/hardinfo2/includes/fftbench.h b/hardinfo2/includes/fftbench.h new file mode 100644 index 00000000..7c0afc3d --- /dev/null +++ b/hardinfo2/includes/fftbench.h @@ -0,0 +1,19 @@ +#ifndef __FFTBENCH_H__ +#define __FFTBENCH_H__ + +#include + +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/hardinfo2/includes/guibench.h b/hardinfo2/includes/guibench.h new file mode 100644 index 00000000..d24403bc --- /dev/null +++ b/hardinfo2/includes/guibench.h @@ -0,0 +1,24 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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/hardinfo2/includes/hardinfo.h b/hardinfo2/includes/hardinfo.h new file mode 100644 index 00000000..42a92a30 --- /dev/null +++ b/hardinfo2/includes/hardinfo.h @@ -0,0 +1,151 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 +#include "config.h" +#include "shell.h" +#include "vendor.h" + +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 *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); +void tree_view_save_image(gchar *filename); + +/* 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) + +#endif /* __HARDINFO_H__ */ diff --git a/hardinfo2/includes/help-viewer.h b/hardinfo2/includes/help-viewer.h new file mode 100644 index 00000000..688ff325 --- /dev/null +++ b/hardinfo2/includes/help-viewer.h @@ -0,0 +1,43 @@ +/* + * HelpViewer - Simple Help file browser + * Copyright (C) 2009 Leandro A. F. Pereira + * + * 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/hardinfo2/includes/iconcache.h b/hardinfo2/includes/iconcache.h new file mode 100644 index 00000000..97f59a82 --- /dev/null +++ b/hardinfo2/includes/iconcache.h @@ -0,0 +1,30 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 + +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/hardinfo2/includes/loadgraph.h b/hardinfo2/includes/loadgraph.h new file mode 100644 index 00000000..3a53f793 --- /dev/null +++ b/hardinfo2/includes/loadgraph.h @@ -0,0 +1,69 @@ +/* + * Simple Load Graph + * Copyright (C) 2006 Leandro A. F. Pereira + * + * 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 +#include +#include + +typedef struct _LoadGraph LoadGraph; + +typedef enum { + LG_COLOR_GREEN = 0x4FB05A, + LG_COLOR_BLUE = 0x4F58B0, + LG_COLOR_RED = 0xB04F4F +} LoadGraphColor; + +struct _LoadGraph { + GdkPixmap *buf; + GtkWidget *area; + + GdkGC *grid; + GdkGC *trace; + GdkGC *fill; + + gint *data; + gfloat scale; + + gint size; + gint width, height; + LoadGraphColor color; + + gint max_value, remax_count; + + PangoLayout *layout; + gchar *suffix; +}; + +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, gint 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); + +#endif /* __LOADGRAPH_H__ */ diff --git a/hardinfo2/includes/markdown-text-view.h b/hardinfo2/includes/markdown-text-view.h new file mode 100644 index 00000000..648ea39c --- /dev/null +++ b/hardinfo2/includes/markdown-text-view.h @@ -0,0 +1,70 @@ +/* + * Markdown Text View + * GtkTextView subclass that supports Markdown syntax + * + * Copyright (C) 2009 Leandro Pereira + * Portions Copyright (C) 2007-2008 Richard Hughes + * 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 +#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/hardinfo2/includes/md5.h b/hardinfo2/includes/md5.h new file mode 100644 index 00000000..1522170c --- /dev/null +++ b/hardinfo2/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/hardinfo2/includes/menu.h b/hardinfo2/includes/menu.h new file mode 100644 index 00000000..361b2323 --- /dev/null +++ b/hardinfo2/includes/menu.h @@ -0,0 +1,25 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 + +void menu_init(Shell *shell); + +#endif /* __MENU_H__ */ diff --git a/hardinfo2/includes/network.h b/hardinfo2/includes/network.h new file mode 100644 index 00000000..e8113089 --- /dev/null +++ b/hardinfo2/includes/network.h @@ -0,0 +1,14 @@ +#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; +extern GHashTable *moreinfo; + +void scan_net_interfaces(void); + +#endif /* __NETWORK_H__ */ \ No newline at end of file diff --git a/hardinfo2/includes/nqueens.h b/hardinfo2/includes/nqueens.h new file mode 100644 index 00000000..a4be93f0 --- /dev/null +++ b/hardinfo2/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/hardinfo2/includes/remote.h b/hardinfo2/includes/remote.h new file mode 100644 index 00000000..6a988a3b --- /dev/null +++ b/hardinfo2/includes/remote.h @@ -0,0 +1,29 @@ +/* + * Remote Client + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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/hardinfo2/includes/report.h b/hardinfo2/includes/report.h new file mode 100644 index 00000000..782621cb --- /dev/null +++ b/hardinfo2/includes/report.h @@ -0,0 +1,93 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 +#include + +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/hardinfo2/includes/sha1.h b/hardinfo2/includes/sha1.h new file mode 100644 index 00000000..573ff8ac --- /dev/null +++ b/hardinfo2/includes/sha1.h @@ -0,0 +1,30 @@ +/* + * SHA-1 in C + * By Steve Reid + * 100% Public Domain + */ + +#ifndef __SHA1_H__ +#define __SHA1_H__ + +#include + +#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/hardinfo2/includes/shell.h b/hardinfo2/includes/shell.h new file mode 100644 index 00000000..2eb9e6d2 --- /dev/null +++ b/hardinfo2/includes/shell.h @@ -0,0 +1,225 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 + +#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/hardinfo2/includes/socket.h b/hardinfo2/includes/socket.h new file mode 100644 index 00000000..7c44837e --- /dev/null +++ b/hardinfo2/includes/socket.h @@ -0,0 +1,36 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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/hardinfo2/includes/ssh-conn.h b/hardinfo2/includes/ssh-conn.h new file mode 100644 index 00000000..b1b0a9ca --- /dev/null +++ b/hardinfo2/includes/ssh-conn.h @@ -0,0 +1,66 @@ +/* + Remote Client + HardInfo - Displays System Information + Copyright (C) 2003-2009 Leandro A. F. Pereira + + Based on ssh-method.c from GnomeVFS + Copyright (C) 1999 Free Software Foundation + Original author: Ian McKellar + + 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 + +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/hardinfo2/includes/stock.h b/hardinfo2/includes/stock.h new file mode 100644 index 00000000..706e5c51 --- /dev/null +++ b/hardinfo2/includes/stock.h @@ -0,0 +1,34 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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/hardinfo2/includes/syncmanager.h b/hardinfo2/includes/syncmanager.h new file mode 100644 index 00000000..ae0ed267 --- /dev/null +++ b/hardinfo2/includes/syncmanager.h @@ -0,0 +1,42 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 + +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/hardinfo2/includes/test-utils.h b/hardinfo2/includes/test-utils.h new file mode 100644 index 00000000..21cac6b5 --- /dev/null +++ b/hardinfo2/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/hardinfo2/includes/uidefs.h b/hardinfo2/includes/uidefs.h new file mode 100644 index 00000000..a54823ad --- /dev/null +++ b/hardinfo2/includes/uidefs.h @@ -0,0 +1,79 @@ +#ifndef __UIDEFS_H__ +#define __UIDEFS_H__ + +#include "config.h" + +#if RELEASE +#define DEBUG_TOOLBAR_ITEMS +#else /* !RELEASE */ +#define DEBUG_TOOLBAR_ITEMS "" \ + "" +#endif /* !RELEASE */ + +#ifdef HAS_LIBSOUP +#define REMOTE_MENU_ITEMS " " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " + +#define SYNC_MANAGER_ITEMS " " \ +" " + +#else /* !HAS_LIBSOUP */ +#define REMOTE_MENU_ITEMS +#define SYNC_MANAGER_ITEMS +#endif /* !HAS_LIBSOUP */ + +char *uidefs_str = "" \ +" " \ +" " \ +" " \ +" " \ +SYNC_MANAGER_ITEMS +/* + * Save Image is not ready for prime time. Yet. + * "" \ + */ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" "\ +" " \ +" " \ +" " \ +REMOTE_MENU_ITEMS \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +DEBUG_TOOLBAR_ITEMS \ +" " \ +" " \ +""; + +#endif /* __UIDEFS_H__ */ diff --git a/hardinfo2/includes/vendor.h b/hardinfo2/includes/vendor.h new file mode 100644 index 00000000..778e2ea3 --- /dev/null +++ b/hardinfo2/includes/vendor.h @@ -0,0 +1,33 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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/hardinfo2/includes/x86/processor-platform.h b/hardinfo2/includes/x86/processor-platform.h new file mode 100644 index 00000000..dd9ae9d9 --- /dev/null +++ b/hardinfo2/includes/x86/processor-platform.h @@ -0,0 +1,36 @@ +#ifndef __PROCESSOR_PLATFORM_H__ +#define __PROCESSOR_PLATFORM_H__ + +#include "hardinfo.h" + +typedef struct _Processor Processor; +typedef struct _ProcessorCache ProcessorCache; + +struct _ProcessorCache { + gint level; + gint number_of_sets; + gint physical_line_partition; + gint size; + gchar *type; + gint ways_of_associativity; +}; + +struct _Processor { + gchar *model_name; + gchar *vendor_id; + gchar *flags; + gint cache_size; + gfloat bogomips, cpu_mhz; + + gchar *has_fpu; + gchar *bug_fdiv, *bug_hlt, *bug_f00f, *bug_coma; + + gint model, family, stepping; + gchar *strmodel; + + gint id; + + GSList *cache; +}; + +#endif /* __PROCESSOR_PLATFORM_H__ */ diff --git a/hardinfo2/includes/xmlrpc-client.h b/hardinfo2/includes/xmlrpc-client.h new file mode 100644 index 00000000..32fad08c --- /dev/null +++ b/hardinfo2/includes/xmlrpc-client.h @@ -0,0 +1,43 @@ +/* + * XMLRPC Client + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 + +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/hardinfo2/includes/xmlrpc-server.h b/hardinfo2/includes/xmlrpc-server.h new file mode 100644 index 00000000..e608b711 --- /dev/null +++ b/hardinfo2/includes/xmlrpc-server.h @@ -0,0 +1,25 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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/hardinfo2/loadgraph.c b/hardinfo2/loadgraph.c deleted file mode 100644 index c8503072..00000000 --- a/hardinfo2/loadgraph.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * 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 - * - * 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" - -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); - -#if 0 /* old-style grid */ - gdk_rgb_gc_set_foreground(lg->grid, 0x707070); -#endif - - gdk_gc_set_line_attributes(lg->trace, - 1, GDK_LINE_SOLID, - GDK_CAP_PROJECTING, GDK_JOIN_ROUND); - -#if 0 /* old-style fill */ - gdk_gc_set_line_attributes(lg->fill, - 1, GDK_LINE_SOLID, - GDK_CAP_BUTT, GDK_JOIN_BEVEL); -#endif - - /* 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("%d%s", 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); - -#if 0 /* old-style drawing */ - for (i = 0; i < lg->size; i++) { - gint this = lg->height - lg->data[i] * lg->scale; - gint next = lg->height - lg->data[i + 1] * lg->scale; - gint i4 = i * 4; - - gdk_draw_line(draw, lg->fill, i4, this, i4, lg->height); - gdk_draw_line(draw, lg->fill, i4 + 2, this, i4 + 2, lg->height); - } - - for (i = 0; i < lg->size; i++) { - gint this = lg->height - lg->data[i] * lg->scale; - gint next = lg->height - lg->data[i + 1] * lg->scale; - gint i4 = i * 4; - - gdk_draw_line(draw, lg->trace, i4, this, i4 + 2, - (this + next) / 2); - gdk_draw_line(draw, lg->trace, i4 + 2, (this + next) / 2, - i4 + 4, next); - } -#endif - - gtk_widget_queue_draw(lg->area); -} - -void load_graph_update(LoadGraph * lg, gint value) -{ - gint i; - - if (value < 0) - return; - - /* shift-right our data */ - for (i = 0; i < lg->size; 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); -} - -#ifdef LOADGRAPH_UNIT_TEST -gboolean lg_update(gpointer d) -{ - LoadGraph *lg = (LoadGraph *) d; - - static int i = 0; - static int j = 1; - - if (i > 150) { - j = -1; - } else if (i < 0) { - j = 1; - } - - i += j; - if (rand() % 10 > 8) - i *= 2; - if (rand() % 10 < 2) - i /= 2; - load_graph_update(lg, i + rand() % 50); - - return TRUE; -} - -int main(int argc, char **argv) -{ - LoadGraph *lg; - GtkWidget *window; - - gtk_init(&argc, &argv); - - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_widget_show(window); - - lg = load_graph_new(50); - gtk_container_add(GTK_CONTAINER(window), load_graph_get_framed(lg)); - gtk_container_set_border_width(GTK_CONTAINER(window), 20); - load_graph_configure_expose(lg); - - lg_update(lg); - - g_timeout_add(100, lg_update, lg); - - gtk_main(); - - return 0; -} -#endif diff --git a/hardinfo2/loadgraph.h b/hardinfo2/loadgraph.h deleted file mode 100644 index 3a53f793..00000000 --- a/hardinfo2/loadgraph.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Simple Load Graph - * Copyright (C) 2006 Leandro A. F. Pereira - * - * 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 -#include -#include - -typedef struct _LoadGraph LoadGraph; - -typedef enum { - LG_COLOR_GREEN = 0x4FB05A, - LG_COLOR_BLUE = 0x4F58B0, - LG_COLOR_RED = 0xB04F4F -} LoadGraphColor; - -struct _LoadGraph { - GdkPixmap *buf; - GtkWidget *area; - - GdkGC *grid; - GdkGC *trace; - GdkGC *fill; - - gint *data; - gfloat scale; - - gint size; - gint width, height; - LoadGraphColor color; - - gint max_value, remax_count; - - PangoLayout *layout; - gchar *suffix; -}; - -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, gint 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); - -#endif /* __LOADGRAPH_H__ */ diff --git a/hardinfo2/markdown-text-view.c b/hardinfo2/markdown-text-view.c deleted file mode 100644 index 6bfcc131..00000000 --- a/hardinfo2/markdown-text-view.c +++ /dev/null @@ -1,637 +0,0 @@ -/* - * Markdown Text View - * GtkTextView subclass that supports Markdown syntax - * - * Copyright (C) 2009 Leandro Pereira - * Portions Copyright (C) 2007-2008 Richard Hughes - * 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. - */ -#include -#include - -#include "markdown-text-view.h" -#include "config.h" - -static GdkCursor *hand_cursor = NULL; - -G_DEFINE_TYPE(MarkdownTextView, markdown_textview, GTK_TYPE_TEXT_VIEW); - -enum { - LINK_CLICKED, - HOVERING_OVER_LINK, - HOVERING_OVER_TEXT, - FILE_LOAD_COMPLETE, - LAST_SIGNAL -}; - -static guint markdown_textview_signals[LAST_SIGNAL] = { 0 }; - -GtkWidget *markdown_textview_new() -{ - return g_object_new(TYPE_MARKDOWN_TEXTVIEW, NULL); -} - -static void markdown_textview_class_init(MarkdownTextViewClass * klass) -{ - GObjectClass *object_class; - - if (!hand_cursor) { - hand_cursor = gdk_cursor_new(GDK_HAND2); - } - - object_class = G_OBJECT_CLASS(klass); - - markdown_textview_signals[LINK_CLICKED] = g_signal_new( - "link-clicked", - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(MarkdownTextViewClass, link_clicked), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING); - - markdown_textview_signals[HOVERING_OVER_LINK] = g_signal_new( - "hovering-over-link", - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(MarkdownTextViewClass, hovering_over_link), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING); - - markdown_textview_signals[HOVERING_OVER_TEXT] = g_signal_new( - "hovering-over-text", - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(MarkdownTextViewClass, hovering_over_text), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - markdown_textview_signals[FILE_LOAD_COMPLETE] = g_signal_new( - "file-load-complete", - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(MarkdownTextViewClass, file_load_complete), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING); -} - -static void -gtk_text_buffer_insert_markup(GtkTextBuffer * buffer, GtkTextIter * iter, - const gchar * markup) -{ - PangoAttrIterator *paiter; - PangoAttrList *attrlist; - GtkTextMark *mark; - GError *error = NULL; - gchar *text; - - g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer)); - g_return_if_fail(markup != NULL); - - if (*markup == '\000') - return; - - /* invalid */ - if (!pango_parse_markup(markup, -1, 0, &attrlist, &text, NULL, &error)) { - g_warning("Invalid markup string: %s", error->message); - g_error_free(error); - return; - } - - /* trivial, no markup */ - if (attrlist == NULL) { - gtk_text_buffer_insert(buffer, iter, text, -1); - g_free(text); - return; - } - - /* create mark with right gravity */ - mark = gtk_text_buffer_create_mark(buffer, NULL, iter, FALSE); - paiter = pango_attr_list_get_iterator(attrlist); - - do { - PangoAttribute *attr; - GtkTextTag *tag; - GtkTextTag *tag_para; - gint start, end; - - pango_attr_iterator_range(paiter, &start, &end); - - if (end == G_MAXINT) /* last chunk */ - end = start - 1; /* resulting in -1 to be passed to _insert */ - - tag = gtk_text_tag_new(NULL); - - if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_LANGUAGE))) - g_object_set(tag, "language", - pango_language_to_string(((PangoAttrLanguage *) - attr)->value), NULL); - - if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_FAMILY))) - g_object_set(tag, "family", ((PangoAttrString *) attr)->value, - NULL); - - if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_STYLE))) - g_object_set(tag, "style", ((PangoAttrInt *) attr)->value, - NULL); - - if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_WEIGHT))) - g_object_set(tag, "weight", ((PangoAttrInt *) attr)->value, - NULL); - - if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_VARIANT))) - g_object_set(tag, "variant", ((PangoAttrInt *) attr)->value, - NULL); - - if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_STRETCH))) - g_object_set(tag, "stretch", ((PangoAttrInt *) attr)->value, - NULL); - - if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_SIZE))) - g_object_set(tag, "size", ((PangoAttrInt *) attr)->value, - NULL); - - if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_FONT_DESC))) - g_object_set(tag, "font-desc", - ((PangoAttrFontDesc *) attr)->desc, NULL); - - if ((attr = - pango_attr_iterator_get(paiter, PANGO_ATTR_FOREGROUND))) { - GdkColor col = { 0, - ((PangoAttrColor *) attr)->color.red, - ((PangoAttrColor *) attr)->color.green, - ((PangoAttrColor *) attr)->color.blue - }; - - g_object_set(tag, "foreground-gdk", &col, NULL); - } - - if ((attr = - pango_attr_iterator_get(paiter, PANGO_ATTR_BACKGROUND))) { - GdkColor col = { 0, - ((PangoAttrColor *) attr)->color.red, - ((PangoAttrColor *) attr)->color.green, - ((PangoAttrColor *) attr)->color.blue - }; - - g_object_set(tag, "background-gdk", &col, NULL); - } - - if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_UNDERLINE))) - g_object_set(tag, "underline", ((PangoAttrInt *) attr)->value, - NULL); - - if ((attr = - pango_attr_iterator_get(paiter, PANGO_ATTR_STRIKETHROUGH))) - g_object_set(tag, "strikethrough", - (gboolean) (((PangoAttrInt *) attr)->value != 0), - NULL); - - if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_RISE))) - g_object_set(tag, "rise", ((PangoAttrInt *) attr)->value, - NULL); - - if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_SCALE))) - g_object_set(tag, "scale", ((PangoAttrFloat *) attr)->value, - NULL); - - gtk_text_tag_table_add(gtk_text_buffer_get_tag_table(buffer), tag); - - tag_para = - gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table - (buffer), "para"); - gtk_text_buffer_insert_with_tags(buffer, iter, text + start, - end - start, tag, tag_para, NULL); - - /* mark had right gravity, so it should be - * at the end of the inserted text now */ - gtk_text_buffer_get_iter_at_mark(buffer, iter, mark); - } while (pango_attr_iterator_next(paiter)); - - gtk_text_buffer_delete_mark(buffer, mark); - pango_attr_iterator_destroy(paiter); - pango_attr_list_unref(attrlist); - g_free(text); -} - - -static void -set_cursor_if_appropriate(MarkdownTextView * self, gint x, gint y) -{ - GSList *tags = NULL, *tagp = NULL; - GtkTextIter iter; - gboolean hovering = FALSE; - gchar *link_uri = NULL; - - gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(self), &iter, x, - y); - - tags = gtk_text_iter_get_tags(&iter); - for (tagp = tags; tagp != NULL; tagp = tagp->next) { - GtkTextTag *tag = tagp->data; - gint is_underline = 0; - gchar *lang = NULL; - - g_object_get(G_OBJECT(tag), - "underline", &is_underline, - "language", &lang, - NULL); - - if (is_underline == 1 && lang) { - link_uri = egg_markdown_get_link_uri(self->markdown, atoi(lang)); - g_free(lang); - hovering = TRUE; - break; - } - - g_free(lang); - } - - if (hovering != self->hovering_over_link) { - self->hovering_over_link = hovering; - - if (self->hovering_over_link) { - g_signal_emit(self, markdown_textview_signals[HOVERING_OVER_LINK], - 0, link_uri); - gdk_window_set_cursor(gtk_text_view_get_window - (GTK_TEXT_VIEW(self), - GTK_TEXT_WINDOW_TEXT), hand_cursor); - } else { - g_signal_emit(self, markdown_textview_signals[HOVERING_OVER_TEXT], 0); - gdk_window_set_cursor(gtk_text_view_get_window - (GTK_TEXT_VIEW(self), - GTK_TEXT_WINDOW_TEXT), NULL); - } - } - - if (link_uri) - g_free(link_uri); - - if (tags) - g_slist_free(tags); -} - -/* Update the cursor image if the pointer moved. - */ -static gboolean -motion_notify_event(GtkWidget * self, GdkEventMotion * event) -{ - gint x, y; - - gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(self), - GTK_TEXT_WINDOW_WIDGET, - event->x, event->y, &x, &y); - - set_cursor_if_appropriate(MARKDOWN_TEXTVIEW(self), x, y); - - gdk_window_get_pointer(self->window, NULL, NULL, NULL); - return FALSE; -} - -/* Also update the cursor image if the window becomes visible - * (e.g. when a window covering it got iconified). - */ -static gboolean -visibility_notify_event(GtkWidget * self, GdkEventVisibility * event) -{ - gint wx, wy, bx, by; - - gdk_window_get_pointer(self->window, &wx, &wy, NULL); - - gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(self), - GTK_TEXT_WINDOW_WIDGET, - wx, wy, &bx, &by); - - set_cursor_if_appropriate(MARKDOWN_TEXTVIEW(self), bx, by); - - return FALSE; -} - -static void -follow_if_link(GtkWidget * widget, GtkTextIter * iter) -{ - GSList *tags = NULL, *tagp = NULL; - MarkdownTextView *self = MARKDOWN_TEXTVIEW(widget); - - tags = gtk_text_iter_get_tags(iter); - for (tagp = tags; tagp != NULL; tagp = tagp->next) { - GtkTextTag *tag = tagp->data; - gint is_underline = 0; - gchar *lang = NULL; - - g_object_get(G_OBJECT(tag), - "underline", &is_underline, - "language", &lang, - NULL); - - if (is_underline == 1 && lang) { - gchar *link = egg_markdown_get_link_uri(self->markdown, atoi(lang)); - if (link) { - g_signal_emit(self, markdown_textview_signals[LINK_CLICKED], - 0, link); - g_free(link); - } - g_free(lang); - break; - } - - g_free(lang); - } - - if (tags) - g_slist_free(tags); -} - -static gboolean -key_press_event(GtkWidget * self, - GdkEventKey * event) -{ - GtkTextIter iter; - GtkTextBuffer *buffer; - - switch (event->keyval) { - case GDK_Return: - case GDK_KP_Enter: - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); - gtk_text_buffer_get_iter_at_mark(buffer, &iter, - gtk_text_buffer_get_insert - (buffer)); - follow_if_link(self, &iter); - break; - - default: - break; - } - - return FALSE; -} - -static gboolean -event_after(GtkWidget * self, GdkEvent * ev) -{ - GtkTextIter start, end, iter; - GtkTextBuffer *buffer; - GdkEventButton *event; - gint x, y; - - if (ev->type != GDK_BUTTON_RELEASE) - return FALSE; - - event = (GdkEventButton *) ev; - - if (event->button != 1) - return FALSE; - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); - - /* we shouldn't follow a link if the user has selected something */ - gtk_text_buffer_get_selection_bounds(buffer, &start, &end); - if (gtk_text_iter_get_offset(&start) != gtk_text_iter_get_offset(&end)) - return FALSE; - - gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(self), - GTK_TEXT_WINDOW_WIDGET, - event->x, event->y, &x, &y); - - gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(self), &iter, x, - y); - - follow_if_link(self, &iter); - - return FALSE; -} - -void -markdown_textview_clear(MarkdownTextView * self) -{ - GtkTextBuffer *text_buffer; - - g_return_if_fail(IS_MARKDOWN_TEXTVIEW(self)); - - egg_markdown_clear(self->markdown); - - text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); - gtk_text_buffer_set_text(text_buffer, "\n", 1); -} - -static void -load_images(MarkdownTextView * self) -{ - GtkTextBuffer *buffer; - GtkTextIter iter; - GSList *tags, *tagp; - gchar *image_path; - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); - gtk_text_buffer_get_start_iter(buffer, &iter); - - do { - tags = gtk_text_iter_get_tags(&iter); - for (tagp = tags; tagp != NULL; tagp = tagp->next) { - GtkTextTag *tag = tagp->data; - gint is_underline = 0; - gchar *lang = NULL; - - g_object_get(G_OBJECT(tag), - "underline", &is_underline, - "language", &lang, - NULL); - - if (is_underline == 2 && lang) { - GdkPixbuf *pixbuf; - gchar *path; - - image_path = egg_markdown_get_link_uri(self->markdown, atoi(lang)); - path = g_build_filename(self->image_directory, image_path, NULL); - pixbuf = gdk_pixbuf_new_from_file(path, NULL); - if (pixbuf) { - GtkTextMark *mark; - GtkTextIter start; - - mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, FALSE); - - gtk_text_buffer_get_iter_at_mark(buffer, &start, mark); - gtk_text_iter_forward_to_tag_toggle(&iter, tag); - gtk_text_buffer_delete(buffer, &start, &iter); - - gtk_text_buffer_insert_pixbuf(buffer, &iter, pixbuf); - - g_object_unref(pixbuf); - gtk_text_buffer_delete_mark(buffer, mark); - } - - g_free(image_path); - g_free(lang); - g_free(path); - break; - } - - g_free(lang); - } - - if (tags) - g_slist_free(tags); - } while (gtk_text_iter_forward_to_tag_toggle(&iter, NULL)); -} - -static gboolean -append_text(MarkdownTextView * self, - const gchar * text) -{ - GtkTextIter iter; - GtkTextBuffer *text_buffer; - gchar *line; - - g_return_val_if_fail(IS_MARKDOWN_TEXTVIEW(self), FALSE); - - text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); - gtk_text_buffer_get_end_iter(text_buffer, &iter); - - line = egg_markdown_parse(self->markdown, text); - if (line && *line) { - gtk_text_buffer_insert_markup(text_buffer, &iter, line); - gtk_text_buffer_insert(text_buffer, &iter, "\n", 1); - g_free(line); - - return TRUE; - } - - return FALSE; -} - -gboolean -markdown_textview_set_text(MarkdownTextView * self, - const gchar * text) -{ - gboolean result = TRUE; - gchar **lines; - gint line; - - g_return_val_if_fail(IS_MARKDOWN_TEXTVIEW(self), FALSE); - - markdown_textview_clear(self); - - lines = g_strsplit(text, "\n", 0); - for (line = 0; result && lines[line]; line++) { - result = append_text(self, (const gchar *)lines[line]); - } - g_strfreev(lines); - - load_images(self); - - return result; -} - -gboolean -markdown_textview_load_file(MarkdownTextView * self, - const gchar * file_name) -{ - FILE *text_file; - gchar *path; - - g_return_val_if_fail(IS_MARKDOWN_TEXTVIEW(self), FALSE); - - path = g_build_filename(self->image_directory, file_name, NULL); - - /* we do assume UTF-8 encoding */ - if ((text_file = fopen(path, "rb"))) { - GtkTextBuffer *text_buffer; - GtkTextIter iter; - gchar *line; - gchar buffer[EGG_MARKDOWN_MAX_LINE_LENGTH]; - - text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); - - gtk_text_buffer_set_text(text_buffer, "\n", 1); - gtk_text_buffer_get_start_iter(text_buffer, &iter); - - egg_markdown_clear(self->markdown); - - while (fgets(buffer, EGG_MARKDOWN_MAX_LINE_LENGTH, text_file)) { - line = egg_markdown_parse(self->markdown, buffer); - - if (line && *line) { - gtk_text_buffer_insert_markup(text_buffer, &iter, line); - gtk_text_buffer_insert(text_buffer, &iter, "\n", 1); - } - - g_free(line); - } - fclose(text_file); - - load_images(self); - - g_signal_emit(self, markdown_textview_signals[FILE_LOAD_COMPLETE], 0, file_name); - - g_free(path); - - return TRUE; - } - - g_free(path); - - return FALSE; -} - -void -markdown_textview_set_image_directory(MarkdownTextView * self, const gchar *directory) -{ - g_return_if_fail(IS_MARKDOWN_TEXTVIEW(self)); - - g_free(self->image_directory); - self->image_directory = g_strdup(directory); -} - -static void markdown_textview_init(MarkdownTextView * self) -{ - self->markdown = egg_markdown_new(); - self->image_directory = g_strdup("."); - - egg_markdown_set_output(self->markdown, EGG_MARKDOWN_OUTPUT_PANGO); - egg_markdown_set_escape(self->markdown, TRUE); - egg_markdown_set_autocode(self->markdown, TRUE); - egg_markdown_set_smart_quoting(self->markdown, TRUE); - - gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(self), GTK_WRAP_WORD); - gtk_text_view_set_editable(GTK_TEXT_VIEW(self), FALSE); - gtk_text_view_set_left_margin(GTK_TEXT_VIEW(self), 10); - gtk_text_view_set_right_margin(GTK_TEXT_VIEW(self), 10); - gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(self), 3); - gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW(self), 3); - - g_signal_connect(self, "event-after", - G_CALLBACK(event_after), NULL); - g_signal_connect(self, "key-press-event", - G_CALLBACK(key_press_event), NULL); - g_signal_connect(self, "motion-notify-event", - G_CALLBACK(motion_notify_event), NULL); - g_signal_connect(self, "visibility-notify-event", - G_CALLBACK(visibility_notify_event), NULL); -} - diff --git a/hardinfo2/markdown-text-view.h b/hardinfo2/markdown-text-view.h deleted file mode 100644 index 648ea39c..00000000 --- a/hardinfo2/markdown-text-view.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Markdown Text View - * GtkTextView subclass that supports Markdown syntax - * - * Copyright (C) 2009 Leandro Pereira - * Portions Copyright (C) 2007-2008 Richard Hughes - * 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 -#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/hardinfo2/md5.c b/hardinfo2/md5.c deleted file mode 100644 index 70f39c45..00000000 --- a/hardinfo2/md5.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * 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 - 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 /* 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<>(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 - -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/hardinfo2/md5.h b/hardinfo2/md5.h deleted file mode 100644 index 1522170c..00000000 --- a/hardinfo2/md5.h +++ /dev/null @@ -1,26 +0,0 @@ -/* 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/hardinfo2/menu.c b/hardinfo2/menu.c deleted file mode 100644 index 6b96e271..00000000 --- a/hardinfo2/menu.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * 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 -#include -#include - -#include - -#include -#include - -#include "uidefs.h" - -static GtkActionEntry entries[] = { - {"InformationMenuAction", NULL, "_Information"}, /* name, stock id, label */ - {"RemoteMenuAction", NULL, "_Remote"}, - {"ViewMenuAction", NULL, "_View"}, - {"HelpMenuAction", NULL, "_Help"}, - {"HelpMenuModulesAction", HI_STOCK_ABOUT_MODULES, "About _Modules"}, - {"MainMenuBarAction", NULL, ""}, - - {"ReportAction", HI_STOCK_REPORT, /* name, stock id */ - "Generate _Report", "R", /* label, accelerator */ - NULL, /* tooltip */ - G_CALLBACK(cb_generate_report)}, - - {"SyncManagerAction", HI_STOCK_SYNC_MENU, - "_Network Updater...", NULL, - NULL, - G_CALLBACK(cb_sync_manager)}, - - {"OpenAction", GTK_STOCK_OPEN, - "_Open...", NULL, - NULL, - G_CALLBACK(cb_sync_manager)}, - - {"ConnectToAction", GTK_STOCK_CONNECT, - "_Connect to...", NULL, - NULL, - G_CALLBACK(cb_connect_to)}, - - {"ManageAction", NULL, - "_Manage hosts...", NULL, - NULL, - G_CALLBACK(cb_manage_hosts)}, - - {"LocalComputerAction", GTK_STOCK_HOME, - "_Local computer", NULL, - NULL, - G_CALLBACK(cb_local_computer)}, - - {"CopyAction", GTK_STOCK_COPY, - "_Copy to Clipboard", "C", - "Copy to clipboard", - G_CALLBACK(cb_copy_to_clipboard)}, - - {"SaveGraphAction", GTK_STOCK_SAVE_AS, - "_Save image as...", "S", - NULL, - G_CALLBACK(cb_save_graphic)}, - - {"RefreshAction", GTK_STOCK_REFRESH, - "_Refresh", "F5", - NULL, - G_CALLBACK(cb_refresh)}, - - {"OnlineDocsAction", GTK_STOCK_HELP, - "Contents", "F1", - NULL, - G_CALLBACK(cb_open_online_docs)}, - - {"ContextHelpAction", NULL, - "Context help", "F1", - NULL, - G_CALLBACK(cb_open_online_docs_context)}, - - {"HomePageAction", HI_STOCK_INTERNET, - "_Open HardInfo Web Site", NULL, - NULL, - G_CALLBACK(cb_open_web_page)}, - - {"ReportBugAction", HI_STOCK_INTERNET, - "_Report bug", NULL, - NULL, - G_CALLBACK(cb_report_bug)}, - - {"DonateAction", HI_STOCK_DONATE, - "_Donate to the project", NULL, - NULL, - G_CALLBACK(cb_donate)}, - - {"AboutAction", GTK_STOCK_ABOUT, - "_About HardInfo", NULL, - "Displays program version information", - G_CALLBACK(cb_about)}, - - {"QuitAction", GTK_STOCK_QUIT, - "_Quit", "Q", - NULL, - G_CALLBACK(cb_quit)} -}; - -static GtkToggleActionEntry toggle_entries[] = { - {"SidePaneAction", NULL, - "_Side Pane", NULL, - "Toggles side pane visibility", - G_CALLBACK(cb_side_pane)}, - {"ToolbarAction", NULL, - "_Toolbar", NULL, - NULL, - G_CALLBACK(cb_toolbar)}, - {"ActAsServerAction", NULL, - "_Accept connections", NULL, - NULL, - G_CALLBACK(cb_act_as_server) } -}; - -/* 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_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/hardinfo2/menu.h b/hardinfo2/menu.h deleted file mode 100644 index 361b2323..00000000 --- a/hardinfo2/menu.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 - -void menu_init(Shell *shell); - -#endif /* __MENU_H__ */ diff --git a/hardinfo2/modules/benchmark.c b/hardinfo2/modules/benchmark.c new file mode 100644 index 00000000..1f85064a --- /dev/null +++ b/hardinfo2/modules/benchmark.c @@ -0,0 +1,654 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "benchmark.h" + +void scan_fft(gboolean reload); +void scan_raytr(gboolean reload); +void scan_bfsh(gboolean reload); +void scan_cryptohash(gboolean reload); +void scan_fib(gboolean reload); +void scan_nqueens(gboolean reload); +void scan_gui(gboolean reload); + +gchar *callback_fft(); +gchar *callback_raytr(); +gchar *callback_bfsh(); +gchar *callback_fib(); +gchar *callback_cryptohash(); +gchar *callback_nqueens(); +gchar *callback_gui(); + +static ModuleEntry entries[] = { + {"CPU Blowfish", "blowfish.png", callback_bfsh, scan_bfsh, MODULE_FLAG_NONE}, + {"CPU CryptoHash", "cryptohash.png", callback_cryptohash, scan_cryptohash, MODULE_FLAG_NONE}, + {"CPU Fibonacci", "nautilus.png", callback_fib, scan_fib, MODULE_FLAG_NONE}, + {"CPU N-Queens", "nqueens.png", callback_nqueens, scan_nqueens, MODULE_FLAG_NONE}, + {"FPU FFT", "fft.png", callback_fft, scan_fft, MODULE_FLAG_NONE}, + {"FPU Raytracing", "raytrace.png", callback_raytr, scan_raytr, MODULE_FLAG_NONE}, + {"GPU Drawing", "module.png", callback_gui, scan_gui, MODULE_FLAG_NO_REMOTE}, + {NULL} +}; + +static gboolean sending_benchmark_results = FALSE; + +typedef struct _ParallelBenchTask ParallelBenchTask; + +struct _ParallelBenchTask { + gint thread_number; + guint start, end; + gpointer data, callback; +}; + +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; + + 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; +} + +gdouble benchmark_parallel_for(guint start, guint end, + gpointer callback, gpointer callback_data) { + gchar *temp; + guint n_cores, iter_per_core, iter, thread_number = 0; + gdouble elapsed_time; + GSList *threads = NULL, *t; + GTimer *timer; + + timer = g_timer_new(); + + temp = module_call_method("devices::getProcessorCount"); + n_cores = temp ? atoi(temp) : 1; + g_free(temp); + + while (1) { + iter_per_core = (end - start) / n_cores; + + if (iter_per_core == 0) { + DEBUG("not enough items per core; disabling one"); + n_cores--; + } else { + break; + } + } + + DEBUG("processor has %d cores; processing %d elements (%d per core)", + n_cores, (end - start), iter_per_core); + + g_timer_start(timer); + for (iter = start; iter < end; iter += iter_per_core) { + ParallelBenchTask *pbt = g_new0(ParallelBenchTask, 1); + GThread *thread; + + DEBUG("launching thread %d", 1 + (iter / iter_per_core)); + + pbt->thread_number = thread_number++; + pbt->start = iter == 0 ? 0 : iter; + pbt->end = iter + iter_per_core - 1; + pbt->data = callback_data; + pbt->callback = callback; + + if (pbt->end > end) + pbt->end = end; + + thread = g_thread_create((GThreadFunc) benchmark_parallel_for_dispatcher, + pbt, TRUE, NULL); + threads = g_slist_append(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); + g_thread_join((GThread *)t->data); + } + + g_timer_stop(timer); + elapsed_time = g_timer_elapsed(timer, NULL); + + g_slist_free(threads); + g_timer_destroy(timer); + + DEBUG("finishing; all threads took %f seconds to finish", elapsed_time); + + return elapsed_time; +} + +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; +} + +static gchar *__benchmark_include_results(gdouble result, + const gchar * benchmark, + ShellOrderType order_type) +{ + GKeyFile *conf; + gchar **machines; + gchar *path, *results = g_strdup(""), *return_value, *processor_frequency; + int i; + + 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); + + machines = g_key_file_get_keys(conf, benchmark, NULL, NULL); + for (i = 0; machines && machines[i]; i++) { + gchar *value, *cleaned_machine; + + value = g_key_file_get_value(conf, benchmark, machines[i], NULL); + cleaned_machine = clean_cpuname(machines[i]); + results = h_strconcat(results, cleaned_machine, "=", value, "\n", NULL); + + g_free(value); + g_free(cleaned_machine); + } + + g_strfreev(machines); + g_free(path); + g_key_file_free(conf); + + if (result > 0.0f) { + processor_frequency = module_call_method("devices::getProcessorFrequency"); + return_value = g_strdup_printf("[$ShellParam$]\n" + "Zebra=1\n" + "OrderType=%d\n" + "ViewType=3\n" + "ColumnTitle$Extra1=CPU Clock\n" + "ColumnTitle$Progress=Results\n" + "ColumnTitle$TextValue=CPU\n" + "ShowColumnHeaders=true\n" + "[%s]\n" + "This Machine=%.3f|%s MHz\n" + "%s", order_type, benchmark, result, processor_frequency, results); + g_free(processor_frequency); + } else { + return_value = g_strdup_printf("[$ShellParam$]\n" + "Zebra=1\n" + "OrderType=%d\n" + "ViewType=3\n" + "ColumnTitle$Extra1=CPU Clock\n" + "ColumnTitle$Progress=Results\n" + "ColumnTitle$TextValue=CPU\n" + "ShowColumnHeaders=true\n" + "[%s]\n" + "%s", order_type, benchmark, results); + } + return return_value; +} + + + +static gchar *benchmark_include_results_reverse(gdouble result, + const gchar * benchmark) +{ + return __benchmark_include_results(result, benchmark, + SHELL_ORDER_DESCENDING); +} + +static gchar *benchmark_include_results(gdouble result, + const gchar * benchmark) +{ + return __benchmark_include_results(result, benchmark, + SHELL_ORDER_ASCENDING); +} + +gdouble bench_results[BENCHMARK_N_ENTRIES]; + +#include +#include +#include +#include +#include +#include +#include + +gchar *callback_gui() +{ + return benchmark_include_results_reverse(bench_results[BENCHMARK_GUI], + "GPU Drawing"); +} + +gchar *callback_fft() +{ + return benchmark_include_results(bench_results[BENCHMARK_FFT], + "FPU FFT"); +} + +gchar *callback_nqueens() +{ + return benchmark_include_results(bench_results[BENCHMARK_NQUEENS], + "CPU N-Queens"); +} + +gchar *callback_raytr() +{ + return benchmark_include_results(bench_results[BENCHMARK_RAYTRACE], + "FPU Raytracing"); +} + +gchar *callback_bfsh() +{ + return benchmark_include_results(bench_results[BENCHMARK_BLOWFISH], + "CPU Blowfish"); +} + +gchar *callback_cryptohash() +{ + return benchmark_include_results_reverse(bench_results[BENCHMARK_CRYPTOHASH], + "CPU CryptoHash"); +} + +gchar *callback_fib() +{ + return benchmark_include_results(bench_results[BENCHMARK_FIB], + "CPU Fibonacci"); +} + +typedef struct _BenchmarkDialog BenchmarkDialog; +struct _BenchmarkDialog { + GtkWidget *dialog; + double result; +}; + +static gboolean do_benchmark_handler(GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + BenchmarkDialog *bench_dialog = (BenchmarkDialog*)data; + GIOStatus status; + gchar *result; + + status = g_io_channel_read_line(source, &result, NULL, NULL, NULL); + if (status != G_IO_STATUS_NORMAL) { + DEBUG("error while reading benchmark result"); + + bench_dialog->result = -1.0f; + gtk_widget_destroy(bench_dialog->dialog); + return FALSE; + } + + bench_dialog->result = atof(result); + 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", "libbenchmark.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_status = g_strdup_printf("Benchmarking: %s.", 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); + + 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."); + g_object_set_data(G_OBJECT(bench_dialog), "result", "0.0"); + 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); + + while (gtk_events_pending()) { + gtk_main_iteration(); + } + + benchmark_dialog = g_new0(BenchmarkDialog, 1); + benchmark_dialog->dialog = bench_dialog; + benchmark_dialog->result = -1.0f; + + 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->result; + + 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); +} + +void scan_gui(gboolean reload) +{ + SCAN_START(); + + 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] = 0.0f; + } + SCAN_END(); +} + +void scan_fft(gboolean reload) +{ + SCAN_START(); + do_benchmark(benchmark_fft, BENCHMARK_FFT); + SCAN_END(); +} + +void scan_nqueens(gboolean reload) +{ + SCAN_START(); + do_benchmark(benchmark_nqueens, BENCHMARK_NQUEENS); + SCAN_END(); +} + +void scan_raytr(gboolean reload) +{ + SCAN_START(); + do_benchmark(benchmark_raytrace, BENCHMARK_RAYTRACE); + SCAN_END(); +} + +void scan_bfsh(gboolean reload) +{ + SCAN_START(); + do_benchmark(benchmark_fish, BENCHMARK_BLOWFISH); + SCAN_END(); +} + +void scan_cryptohash(gboolean reload) +{ + SCAN_START(); + do_benchmark(benchmark_cryptohash, BENCHMARK_CRYPTOHASH); + SCAN_END(); +} + +void scan_fib(gboolean reload) +{ + SCAN_START(); + do_benchmark(benchmark_fib, BENCHMARK_FIB); + SCAN_END(); +} + +const gchar *hi_note_func(gint entry) +{ + switch (entry) { + case BENCHMARK_CRYPTOHASH: + return "Results in MiB/second. Higher is better."; + + 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; +} + +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 = "Perform tasks and compare with other systems", + .version = VERSION, + .license = "GNU GPL version 2"} + }; + + return ma; +} + +static gchar *get_benchmark_results() +{ + void (*scan_callback) (gboolean rescan); + + sending_benchmark_results = TRUE; + + gint i = G_N_ELEMENTS(entries) - 1; + 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=%d\n", + machine, + machineclock, + machineram, i); + for (; i >= 0; i--) { + if ((scan_callback = entries[i].scan_callback)) { + if (bench_results[i] < 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); + + return g_strdup_printf("%f", 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 = "Send benchmark results", + .name = "SendBenchmarkResults", + .save_to = NULL, + .get_data = get_benchmark_results}, + { + .fancy_name = "Receive benchmark results", + .name = "RecvBenchmarkResults", + .save_to = "benchmark.conf", + .get_data = NULL} + }; + + sync_manager_add_entry(&se[0]); + sync_manager_add_entry(&se[1]); +} + +gchar **hi_module_get_dependencies(void) +{ + static gchar *deps[] = { "libdevices.so", NULL }; + + return deps; +} + diff --git a/hardinfo2/modules/benchmark/blowfish.c b/hardinfo2/modules/benchmark/blowfish.c new file mode 100644 index 00000000..034315ab --- /dev/null +++ b/hardinfo2/modules/benchmark/blowfish.c @@ -0,0 +1,493 @@ +/* +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 "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; + } + } +} + + diff --git a/hardinfo2/modules/benchmark/cryptohash.c b/hardinfo2/modules/benchmark/cryptohash.c new file mode 100644 index 00000000..99a19140 --- /dev/null +++ b/hardinfo2/modules/benchmark/cryptohash.c @@ -0,0 +1,79 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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" + +static void inline md5_step(char *data, glong srclen) +{ + struct MD5Context ctx; + guchar checksum[16]; + + MD5Init(&ctx); + MD5Update(&ctx, (guchar *)data, srclen); + MD5Final(checksum, &ctx); +} + +static 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; +} + +static void +benchmark_cryptohash(void) +{ + gdouble elapsed = 0; + 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..."); + + elapsed = benchmark_parallel_for(0, 5000, cryptohash_for, tmpsrc); + + g_free(bdata_path); + g_free(tmpsrc); + + bench_results[BENCHMARK_CRYPTOHASH] = 312.0 / elapsed; +} diff --git a/hardinfo2/modules/benchmark/drawing.c b/hardinfo2/modules/benchmark/drawing.c new file mode 100644 index 00000000..6f01fe6b --- /dev/null +++ b/hardinfo2/modules/benchmark/drawing.c @@ -0,0 +1,29 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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" + +static void +benchmark_gui(void) +{ + shell_view_set_enabled(FALSE); + shell_status_update("Running drawing benchmark..."); + + bench_results[BENCHMARK_GUI] = guibench(); +} diff --git a/hardinfo2/modules/benchmark/fbench.c b/hardinfo2/modules/benchmark/fbench.c new file mode 100644 index 00000000..df1b8e19 --- /dev/null +++ b/hardinfo2/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 + http://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 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 +#include +#include +#ifndef INTRIG +#include +#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/hardinfo2/modules/benchmark/fft.c b/hardinfo2/modules/benchmark/fft.c new file mode 100644 index 00000000..f1a0ced8 --- /dev/null +++ b/hardinfo2/modules/benchmark/fft.c @@ -0,0 +1,65 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 + +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; +} + +static void +benchmark_fft(void) +{ + gdouble elapsed = 0; + int n_cores, i; + gchar *temp; + FFTBench **benches; + + shell_view_set_enabled(FALSE); + shell_status_update("Running FFT benchmark..."); + + /* Pre-allocate all benchmarks */ + temp = module_call_method("devices::getProcessorCount"); + n_cores = temp ? atoi(temp) : 1; + g_free(temp); + + benches = g_new0(FFTBench *, n_cores); + for (i = 0; i < n_cores; i++) { + benches[i] = fft_bench_new(); + } + + /* Run the benchmark */ + elapsed = benchmark_parallel_for(0, 4, fft_for, benches); + + /* Free up the memory */ + for (i = 0; i < n_cores; i++) { + fft_bench_free(benches[i]); + } + g_free(benches); + + bench_results[BENCHMARK_FFT] = elapsed; +} diff --git a/hardinfo2/modules/benchmark/fftbench.c b/hardinfo2/modules/benchmark/fftbench.c new file mode 100644 index 00000000..dc25dfd6 --- /dev/null +++ b/hardinfo2/modules/benchmark/fftbench.c @@ -0,0 +1,211 @@ +/* + 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://www.coyotegulch.com + + 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 +#include +#include +#include +#include +#include + +#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); + lup_solve(fftbench); +} + +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/hardinfo2/modules/benchmark/fib.c b/hardinfo2/modules/benchmark/fib.c new file mode 100644 index 00000000..3ff54dba --- /dev/null +++ b/hardinfo2/modules/benchmark/fib.c @@ -0,0 +1,50 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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" + +static gulong +fib(gulong n) +{ + if (n == 0) + return 0; + else if (n <= 2) + return 1; + return fib(n - 1) + fib(n - 2); +} + +static void +benchmark_fib(void) +{ + GTimer *timer = g_timer_new(); + gdouble elapsed; + + 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); + elapsed = g_timer_elapsed(timer, NULL); + g_timer_destroy(timer); + + bench_results[BENCHMARK_FIB] = elapsed; +} diff --git a/hardinfo2/modules/benchmark/guibench.c b/hardinfo2/modules/benchmark/guibench.c new file mode 100644 index 00000000..b9573278 --- /dev/null +++ b/hardinfo2/modules/benchmark/guibench.c @@ -0,0 +1,353 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 + +#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/hardinfo2/modules/benchmark/md5.c b/hardinfo2/modules/benchmark/md5.c new file mode 100644 index 00000000..70f39c45 --- /dev/null +++ b/hardinfo2/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 + 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 /* 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<>(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 + +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/hardinfo2/modules/benchmark/nqueens.c b/hardinfo2/modules/benchmark/nqueens.c new file mode 100644 index 00000000..838731c4 --- /dev/null +++ b/hardinfo2/modules/benchmark/nqueens.c @@ -0,0 +1,37 @@ +/* + * N-Queens Problem Solver + * Found somewhere on the Internet; can't remember where. Possibly Wikipedia. + */ +#include +#include +#include + +#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; +} diff --git a/hardinfo2/modules/benchmark/raytrace.c b/hardinfo2/modules/benchmark/raytrace.c new file mode 100644 index 00000000..9fc6361e --- /dev/null +++ b/hardinfo2/modules/benchmark/raytrace.c @@ -0,0 +1,47 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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; +} + +static void +benchmark_raytrace(void) +{ + gdouble elapsed = 0; + + shell_view_set_enabled(FALSE); + shell_status_update("Performing John Walker's FBENCH..."); + + elapsed = benchmark_parallel_for(0, 1000, parallel_raytrace, NULL); + + bench_results[BENCHMARK_RAYTRACE] = elapsed; +} + diff --git a/hardinfo2/modules/benchmark/sha1.c b/hardinfo2/modules/benchmark/sha1.c new file mode 100644 index 00000000..b94ce254 --- /dev/null +++ b/hardinfo2/modules/benchmark/sha1.c @@ -0,0 +1,329 @@ +/* +SHA-1 in C +By Steve Reid +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 +#include +#include + +#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 "); + 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/hardinfo2/modules/computer.c b/hardinfo2/modules/computer.c new file mode 100644 index 00000000..cb349408 --- /dev/null +++ b/hardinfo2/modules/computer.c @@ -0,0 +1,689 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2008 Leandro A. F. Pereira + * + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "computer.h" + +/* Callbacks */ +gchar *callback_summary(); +gchar *callback_os(); +gchar *callback_modules(); +gchar *callback_boots(); +gchar *callback_locales(); +gchar *callback_fs(); +gchar *callback_display(); +gchar *callback_network(); +gchar *callback_users(); +gchar *callback_env_var(); +#if GLIB_CHECK_VERSION(2,14,0) +gchar *callback_dev(); +#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_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[] = { + {"Summary", "summary.png", callback_summary, scan_summary, MODULE_FLAG_NONE}, + {"Operating System", "os.png", callback_os, scan_os, MODULE_FLAG_NONE}, + {"Kernel Modules", "module.png", callback_modules, scan_modules, MODULE_FLAG_NONE}, + {"Boots", "boot.png", callback_boots, scan_boots, MODULE_FLAG_NONE}, + {"Languages", "language.png", callback_locales, scan_locales, MODULE_FLAG_NONE}, + {"Filesystems", "dev_removable.png", callback_fs, scan_fs, MODULE_FLAG_NONE}, + {"Display", "monitor.png", callback_display, scan_display, MODULE_FLAG_NONE}, + {"Environment Variables", "environment.png", callback_env_var, scan_env_var, MODULE_FLAG_NONE}, +#if GLIB_CHECK_VERSION(2,14,0) + {"Development", "devel.png", callback_dev, scan_dev, MODULE_FLAG_NONE}, +#endif /* GLIB_CHECK_VERSION(2,14,0) */ + {"Users", "users.png", callback_users, scan_users, MODULE_FLAG_NONE}, + {NULL}, +}; + + +GHashTable *moreinfo = NULL; +gchar *module_list = NULL; +Computer *computer = NULL; + +gchar *hi_more_info(gchar * entry) +{ + gchar *info = (gchar *) g_hash_table_lookup(moreinfo, 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 { + tmp = g_strdup(""); + } + + 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(); +} + +#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[] = { + { "Scripting Languages", NULL, FALSE }, + { "CPython", "python -V", "\\d+\\.\\d+\\.\\d+", FALSE }, + { "Perl", "perl -v", "\\d+\\.\\d+\\.\\d+", TRUE }, + { "PHP", "php --version", "\\d+\\.\\d+\\.\\S+", TRUE}, + { "Ruby", "ruby --version", "\\d+\\.\\d+\\.\\d+", TRUE }, + { "Bash", "bash --version", "\\d+\\.\\d+\\.\\S+", TRUE}, + { "Compilers", NULL, FALSE }, + { "C (GCC)", "gcc -v", "\\d+\\.\\d+\\.\\d+", FALSE }, + { "Java", "javac -version", "\\d+\\.\\d+\\.\\d+", FALSE }, + { "CSharp (Mono, old)", "mcs --version", "\\d+\\.\\d+\\.\\d+\\.\\d+", TRUE }, + { "CSharp (Mono)", "gmcs --version", "\\d+\\.\\d+\\.\\d+\\.\\d+", TRUE }, + { "Vala", "valac --version", "\\d+\\.\\d+\\.\\d+", TRUE }, + { "Haskell (GHC)", "ghc -v", "\\d+\\.\\d+\\.\\d+", FALSE }, + { "FreePascal", "fpc --version", "\\d+\\.\\d+\\.\\S+", TRUE }, + { "Tools", NULL, FALSE }, + { "make", "make --version", "\\d+\\.\\d+", TRUE }, + { "GDB", "gdb --version", "\\d+\\.\\S+", TRUE }, + { "strace", "strace -V", "\\d+\\.\\d+\\.\\d+", TRUE }, + { "valgrind", "valgrind --version", "\\d+\\.\\d+\\.\\S+", TRUE }, + { "QMake", "qmake --version", "\\d+\\.\\S+", TRUE}, + }; + + g_free(dev_list); + + dev_list = g_strdup(""); + + for (i = 0; i < G_N_ELEMENTS(detect_lang); i++) { + gchar *version = NULL; + gchar *output; + 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, NULL, NULL, NULL); + } else { + found = g_spawn_command_line_sync(detect_lang[i].version_command, NULL, &output, NULL, NULL); + } + + 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) { + dev_list = h_strdup_cprintf("%s=%s\n", dev_list, detect_lang[i].compiler_name, version); + g_free(version); + } else { + dev_list = h_strdup_cprintf("%s=Not found\n", dev_list, detect_lang[i].compiler_name); + } + + temp = g_strdup_printf("Detecting version: %s", + detect_lang[i].compiler_name); + shell_status_update(temp); + g_free(temp); + } + + SCAN_END(); +} + +gchar *callback_dev() +{ + return g_strdup_printf("[$ShellParam$]\n" + "ColumnTitle$TextValue=Program\n" + "ColumnTitle$Value=Version\n" + "ShowColumnHeaders=true\n" + "%s", dev_list); +} +#endif /* GLIB_CHECK_VERSION(2,14,0) */ + +/* Table based off imvirt by Thomas Liske + Copyright (c) 2008 IBH IT-Service GmbH under GPLv2. */ +gchar *computer_get_virtualization() +{ + 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", "Virtual (VMware)" }, + { ": VMware Virtual IDE CDROM Drive", "Virtual (VMware)" }, + /* QEMU */ + { "QEMU", "Virtual (QEMU)" }, + { "QEMU Virtual CPU", "Virtual (QEMU)" }, + { ": QEMU HARDDISK", "Virtual (QEMU)" }, + { ": QEMU CD-ROM", "Virtual (QEMU)" }, + /* Generic Virtual Machine */ + { ": Virtual HD,", "Virtual (Unknown)" }, + { ": Virtual CD,", "Virtual (Unknown)" }, + /* Virtual Box */ + { "VBOX", "Virtual (VirtualBox)" }, + { ": VBOX HARDDISK", "Virtual (VirtualBox)" }, + { ": VBOX CD-ROM", "Virtual (VirtualBox)" }, + /* Xen */ + { "Xen virtual console", "Virtual (Xen)" }, + { "Xen reported: ", "Virtual (Xen)" }, + { "xen-vbd: registered block device", "Virtual (Xen)" }, + { NULL } + }; + + DEBUG("Detecting virtual machine"); + + if (g_file_test("/proc/xen", G_FILE_TEST_EXISTS)) { + DEBUG("/proc/xen found; assuming Xen"); + return g_strdup("Xen"); + } + + 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 g_strdup("Physical machine"); +} + +gchar *callback_summary() +{ + gchar *processor_name, *alsa_cards; + gchar *input_devices, *printers; + gchar *storage_devices, *summary; + gchar *virt; + + processor_name = module_call_method("devices::getProcessorName"); + alsa_cards = computer_get_alsacards(computer); + input_devices = module_call_method("devices::getInputDevices"); + printers = module_call_method("devices::getPrinters"); + storage_devices = module_call_method("devices::getStorageDevices"); + virt = computer_get_virtualization(); + + summary = g_strdup_printf("[$ShellParam$]\n" + "UpdateInterval$Memory=1000\n" + "UpdateInterval$Date/Time=1000\n" + "#ReloadInterval=5000\n" + "[Computer]\n" + "Processor=%s\n" + "Memory=...\n" + "Machine Type=%s\n" + "Operating System=%s\n" + "User Name=%s\n" + "Date/Time=...\n" + "[Display]\n" + "Resolution=%dx%d pixels\n" + "OpenGL Renderer=%s\n" + "X11 Vendor=%s\n" + "\n%s\n" + "[Input Devices]\n%s\n" + "\n%s\n" + "\n%s\n", + processor_name, + virt, + computer->os->distro, + computer->os->username, + computer->display->width, + computer->display->height, + computer->display->ogl_renderer, + computer->display->vendor, + alsa_cards, + input_devices, printers, storage_devices); + + g_free(processor_name); + g_free(alsa_cards); + g_free(input_devices); + g_free(printers); + g_free(storage_devices); + g_free(virt); + + return summary; +} + +gchar *callback_os() +{ + return g_strdup_printf("[$ShellParam$]\n" + "UpdateInterval$Uptime=10000\n" + "UpdateInterval$Load Average=1000\n" + "[Version]\n" + "Kernel=%s\n" + "Version=%s\n" + "C Library=%s\n" + "Distribution=%s\n" + "[Current Session]\n" + "Computer Name=%s\n" + "User Name=%s\n" + "#Language=%s\n" + "Home Directory=%s\n" + "Desktop Environment=%s\n" + "[Misc]\n" + "Uptime=...\n" + "Load Average=...", + computer->os->kernel, + computer->os->kernel_version, + computer->os->libc, + computer->os->distro, + computer->os->hostname, + computer->os->username, + computer->os->language, + computer->os->homedir, computer->os->desktop); +} + +gchar *callback_modules() +{ + return g_strdup_printf("[Loaded Modules]\n" + "%s" + "[$ShellParam$]\n" + "ViewType=1\n" + "ColumnTitle$TextValue=Name\n" + "ColumnTitle$Value=Description\n" + "ShowColumnHeaders=true\n", module_list); +} + +gchar *callback_boots() +{ + return g_strdup_printf("[$ShellParam$]\n" + "ColumnTitle$TextValue=Date & Time\n" + "ColumnTitle$Value=Kernel Version\n" + "ShowColumnHeaders=true\n" + "\n" + "%s", computer->os->boots); +} + +gchar *callback_locales() +{ + return g_strdup_printf("[$ShellParam$]\n" + "ViewType=1\n" + "ColumnTitle$TextValue=Language Code\n" + "ColumnTitle$Value=Name\n" + "ShowColumnHeaders=true\n" + "[Available Languages]\n" + "%s", computer->os->languages); +} + +gchar *callback_fs() +{ + return g_strdup_printf("[$ShellParam$]\n" + "ViewType=4\n" + "ReloadInterval=5000\n" + "Zebra=1\n" + "NormalizePercentage=false\n" + "ColumnTitle$Extra1=Mount Point\n" + "ColumnTitle$Progress=Usage\n" + "ColumnTitle$TextValue=Device\n" + "ShowColumnHeaders=true\n" + "[Mounted File Systems]\n%s\n", fs_list); +} + +gchar *callback_display() +{ + return g_strdup_printf("[Display]\n" + "Resolution=%dx%d pixels\n" + "Vendor=%s\n" + "Version=%s\n" + "[Monitors]\n" + "%s" + "[Extensions]\n" + "%s" + "[OpenGL]\n" + "Vendor=%s\n" + "Renderer=%s\n" + "Version=%s\n" + "Direct Rendering=%s\n", + computer->display->width, + computer->display->height, + computer->display->vendor, + computer->display->version, + computer->display->monitors, + computer->display->extensions, + computer->display->ogl_vendor, + computer->display->ogl_renderer, + computer->display->ogl_version, + computer->display->dri ? "Yes" : "No"); +} + +gchar *callback_users() +{ + return g_strdup_printf("[$ShellParam$]\n" + "ReloadInterval=10000\n" + "ViewType=1\n" + "[Users]\n" + "%s\n", users); +} + +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_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}, + {"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[] = { "libdevices.so", NULL }; + + return deps; +} + +gchar *hi_module_get_summary(void) +{ + return g_strdup("[Operating System]\n" + "Icon=os.png\n" + "Method=computer::getOS\n" + "[CPU]\n" + "Icon=processor.png\n" + "Method=devices::getProcessorName\n" + "[RAM]\n" + "Icon=memory.png\n" + "Method=devices::getMemoryTotal\n" + "[Motherboard]\n" + "Icon=module.png\n" + "[Graphics]\n" + "Icon=monitor.png\n" + "Method=computer::getDisplaySummary\n" + "[Storage]\n" + "Icon=hdd.png\n" + "Method=devices::getStorageDevices\n" + "[Printers]\n" + "Icon=printer.png\n" + "Method=devices::getPrinters\n" + "[Audio]\n" + "Icon=audio.png\n" + "Method=computer::getAudioCards\n"); +} + +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); + + h_hash_table_remove_all(moreinfo); + g_hash_table_destroy(moreinfo); +} + +void hi_module_init(void) +{ + computer = g_new0(Computer, 1); + moreinfo = + g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); +} + +ModuleAbout *hi_module_get_about(void) +{ + static ModuleAbout ma[] = { + { + .author = "Leandro A. F. Pereira", + .description = "Gathers high-level computer information", + .version = VERSION, + .license = "GNU GPL version 2"} + }; + + return ma; +} + diff --git a/hardinfo2/modules/computer/alsa.c b/hardinfo2/modules/computer/alsa.c new file mode 100644 index 00000000..f1ff3ad8 --- /dev/null +++ b/hardinfo2/modules/computer/alsa.c @@ -0,0 +1,71 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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("[Audio Devices]\n"); + gint n = 0; + + if (computer->alsa) { + for (p = computer->alsa->cards; p; p = p->next) { + AlsaCard *ac = (AlsaCard *) p->data; + + tmp = h_strdup_cprintf("Audio Adapter#%d=%s\n", + tmp, ++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/hardinfo2/modules/computer/boots.c b/hardinfo2/modules/computer/boots.c new file mode 100644 index 00000000..4a1023f6 --- /dev/null +++ b/hardinfo2/modules/computer/boots.c @@ -0,0 +1,65 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 +#include +#include "hardinfo.h" +#include "computer.h" + +void +scan_boots_real(void) +{ + FILE *last; + char buffer[256]; + + scan_os(FALSE); + + if (!computer->os->boots) + computer->os->boots = g_strdup("[Boots]\n"); + else + return; + + last = popen("last", "r"); + if (last) { + while (fgets(buffer, 256, last)) { + if (strstr(buffer, "system boot")) { + gchar **tmp, *buf = buffer; + + strend(buffer, '\n'); + + while (*buf) { + if (*buf == ' ' && *(buf + 1) == ' ') { + strcpy(buf, buf + 1); + + buf--; + } else { + buf++; + } + } + + tmp = g_strsplit(buffer, " ", 0); + computer->os->boots = h_strdup_cprintf("\n%s %s %s %s=%s|%s", + computer->os->boots, + tmp[4], tmp[5], tmp[6], tmp[7], tmp[3], tmp[8]); + g_strfreev(tmp); + } + } + + pclose(last); + } +} diff --git a/hardinfo2/modules/computer/display.c b/hardinfo2/modules/computer/display.c new file mode 100644 index 00000000..ce23bbfd --- /dev/null +++ b/hardinfo2/modules/computer/display.c @@ -0,0 +1,148 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 + +#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, ":", 0); + + 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); + + 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/hardinfo2/modules/computer/environment.c b/hardinfo2/modules/computer/environment.c new file mode 100644 index 00000000..8ef63b2d --- /dev/null +++ b/hardinfo2/modules/computer/environment.c @@ -0,0 +1,45 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2008 Leandro A. F. Pereira + * + * 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("[Environment Variables]\n"); + 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/hardinfo2/modules/computer/filesystem.c b/hardinfo2/modules/computer/filesystem.c new file mode 100644 index 00000000..fcd8cf31 --- /dev/null +++ b/hardinfo2/modules/computer/filesystem.c @@ -0,0 +1,112 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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 +#include +#include "hardinfo.h" +#include "computer.h" + +gchar *fs_list = NULL; + +static gboolean +remove_filesystem_entries(gpointer key, gpointer value, gpointer data) +{ + return g_str_has_prefix(key, "FS"); +} + +void +scan_filesystems(void) +{ + FILE *mtab; + gchar buf[1024]; + struct statfs sfs; + int count = 0; + + g_free(fs_list); + fs_list = g_strdup(""); + g_hash_table_foreach_remove(moreinfo, remove_filesystem_entries, NULL); + + 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; + if ((strhash = g_hash_table_lookup(moreinfo, tmp[0]))) { + g_hash_table_remove(moreinfo, tmp[0]); + g_free(strhash); + } + + strreplacechr(tmp[0], "#", '_'); + + strhash = g_strdup_printf("[%s]\n" + "Filesystem=%s\n" + "Mounted As=%s\n" + "Mount Point=%s\n" + "Size=%s\n" + "Used=%s\n" + "Available=%s\n", + tmp[0], + tmp[2], + strstr(tmp[3], "rw") ? "Read-Write" : + "Read-Only", tmp[1], strsize, strused, + stravail); + g_hash_table_insert(moreinfo, g_strdup_printf("FS%d", ++count), strhash); + + 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/hardinfo2/modules/computer/languages.c b/hardinfo2/modules/computer/languages.c new file mode 100644 index 00000000..2808da1b --- /dev/null +++ b/hardinfo2/modules/computer/languages.c @@ -0,0 +1,112 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 + +#include "hardinfo.h" +#include "computer.h" + +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); + +#define FIELD(f) f ? f : "(Unknown)" + currlocale = g_strdup_printf("[Locale Information]\n" + "Name=%s (%s)\n" + "Source=%s\n" + "Address=%s\n" + "Email=%s\n" + "Language=%s\n" + "Territory=%s\n" + "Revision=%s\n" + "Date=%s\n" + "Codeset=%s\n", + name, FIELD(title), + FIELD(source), FIELD(address), + FIELD(email), FIELD(language), + FIELD(territory), FIELD(revision), + FIELD(date), FIELD(codeset)); +#undef FIELD + + g_hash_table_insert(moreinfo, g_strdup(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/hardinfo2/modules/computer/loadavg.c b/hardinfo2/modules/computer/loadavg.c new file mode 100644 index 00000000..523812be --- /dev/null +++ b/hardinfo2/modules/computer/loadavg.c @@ -0,0 +1,50 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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" + +LoadInfo * +computer_get_loadinfo(void) +{ + LoadInfo *li = g_new0(LoadInfo, 1); + FILE *procloadavg; + + procloadavg = fopen("/proc/loadavg", "r"); + (void)fscanf(procloadavg, "%f %f %f", &(li->load1), &(li->load5), + &(li->load15)); + fclose(procloadavg); + + return li; +} + +gchar * +computer_get_formatted_loadavg() +{ + LoadInfo *li; + gchar *tmp; + + li = computer_get_loadinfo(); + + tmp = + g_strdup_printf("%.2f, %.2f, %.2f", li->load1, li->load5, + li->load15); + + g_free(li); + return tmp; +} diff --git a/hardinfo2/modules/computer/memory.c b/hardinfo2/modules/computer/memory.c new file mode 100644 index 00000000..3d320e8a --- /dev/null +++ b/hardinfo2/modules/computer/memory.c @@ -0,0 +1,59 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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); + + 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/hardinfo2/modules/computer/modules.c b/hardinfo2/modules/computer/modules.c new file mode 100644 index 00000000..195c444b --- /dev/null +++ b/hardinfo2/modules/computer/modules.c @@ -0,0 +1,174 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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 + +#include "hardinfo.h" +#include "computer.h" + +#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; \ + } + +static gboolean +remove_module_devices(gpointer key, gpointer value, gpointer data) +{ + return g_str_has_prefix(key, "MOD"); +} + +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); + } + + if (module_list) { + g_free(module_list); + } + + module_list = NULL; + g_hash_table_foreach_remove(moreinfo, remove_module_devices, NULL); + + lsmod_path = find_program("lsmod"); + 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 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, "<none>")) { + 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 : ""); + +#define NONE_IF_NULL(var) (var) ? (var) : "N/A" + + /* create the module information string */ + strmodule = g_strdup_printf("[Module Information]\n" + "Path=%s\n" + "Used Memory=%.2fKiB\n" + "[Description]\n" + "Name=%s\n" + "Description=%s\n" + "Version Magic=%s\n" + "[Copyright]\n" + "Author=%s\n" + "License=%s\n", + NONE_IF_NULL(filename), + memory / 1024.0, + modname, + NONE_IF_NULL(description), + NONE_IF_NULL(vermagic), + NONE_IF_NULL(author), + NONE_IF_NULL(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); + } + + g_hash_table_insert(moreinfo, hashkey, strmodule); + + g_free(license); + g_free(description); + g_free(author); + g_free(vermagic); + g_free(filename); + } + pclose(lsmod); + + g_free(lsmod_path); +} diff --git a/hardinfo2/modules/computer/os.c b/hardinfo2/modules/computer/os.c new file mode 100644 index 00000000..36b061fc --- /dev/null +++ b/hardinfo2/modules/computer/os.c @@ -0,0 +1,220 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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 +#include +#include "hardinfo.h" +#include "computer.h" + +static gchar * +get_libc_version(void) +{ + FILE *libc; + gchar buf[256], *tmp, *p; + + if (g_file_test("/lib/ld-uClibc.so.0", G_FILE_TEST_EXISTS)) { + return g_strdup("uClibc Library"); + } else if (!g_file_test("/lib/libc.so.6", G_FILE_TEST_EXISTS)) { + goto err; + } + + libc = popen("/lib/libc.so.6", "r"); + if (!libc) goto err; + + (void)fgets(buf, 256, libc); + if (pclose(libc)) goto err; + + tmp = strstr(buf, "version "); + if (!tmp) goto err; + + p = strchr(tmp, ','); + if (p) *p = '\0'; + else goto err; + + return g_strdup_printf("GNU C Library version %s (%sstable)", + strchr(tmp, ' ') + 1, + strstr(buf, " stable ") ? "" : "un"); + err: + return g_strdup("Unknown"); +} + +#include + +void +detect_desktop_environment(OperatingSystem * os) +{ + const gchar *tmp = g_getenv("GNOME_DESKTOP_SESSION_ID"); + FILE *version; + char vers[16]; + + if (tmp) { + /* FIXME: this might not be true, as the gnome-panel in path + may not be the one that's running. + see where the user's running panel is and run *that* to + obtain the version. */ + version = popen("gnome-about --gnome-version", "r"); + if (version) { + (void)fscanf(version, "Version: %s", vers); + if (pclose(version)) + goto unknown; + } else { + goto unknown; + } + + os->desktop = g_strdup_printf("GNOME %s", vers); + } else if (g_getenv("KDE_FULL_SESSION")) { + + if (g_getenv("KDE_SESSION_VERSION") && strstr(g_getenv("KDE_SESSION_VERSION"),(gchar *)"4")) { + version = popen("kwin --version", "r"); + } else { + version = popen("kcontrol --version", "r"); + } + + if (version) { + char buf[32]; + + (void)fgets(buf, 32, version); + + (void)fscanf(version, "KDE: %s", vers); + if (pclose(version)) + goto unknown; + } else { + goto unknown; + } + + os->desktop = g_strdup_printf("KDE %s", vers); + } else { + unknown: + if (!g_getenv("DISPLAY")) { + os->desktop = g_strdup("Terminal"); + } else { + GdkScreen *screen = gdk_screen_get_default(); + + if (screen && GDK_IS_SCREEN(screen)) { + const gchar *windowman; + + windowman = gdk_x11_screen_get_window_manager_name(screen); + + if (g_str_equal(windowman, "Xfwm4")) { + /* FIXME: check if xprop -root | grep XFCE_DESKTOP_WINDOW + is defined */ + os->desktop = g_strdup("XFCE 4"); + } else { + os->desktop = g_strdup_printf("Unknown (Window Manager: %s)", + windowman); + } + } else { + os->desktop = g_strdup("Unknown"); + } + } + } +} + +OperatingSystem * +computer_get_os(void) +{ + struct utsname utsbuf; + OperatingSystem *os; + int i; + + os = g_new0(OperatingSystem, 1); + + /* Attempt to get the Distribution name; try using /etc/lsb-release first, + then doing the legacy method (checking for /etc/$DISTRO-release files) */ + if (g_file_test("/etc/lsb-release", G_FILE_TEST_EXISTS)) { + FILE *release; + gchar buffer[128]; + + release = popen("lsb_release -d", "r"); + if (release) { + (void)fgets(buffer, 128, release); + pclose(release); + + os->distro = buffer; + os->distro = g_strdup(os->distro + strlen("Description:\t")); + } + } + + for (i = 0;; i++) { + if (distro_db[i].file == NULL) { + os->distrocode = g_strdup("unk"); + os->distro = g_strdup("Unknown distribution"); + break; + } + + if (g_file_test(distro_db[i].file, G_FILE_TEST_EXISTS)) { + FILE *distro_ver; + char buf[128]; + + distro_ver = fopen(distro_db[i].file, "r"); + if (distro_ver) { + (void)fgets(buf, 128, distro_ver); + fclose(distro_ver); + } else { + continue; + } + + buf[strlen(buf) - 1] = 0; + + if (!os->distro) { + /* + * HACK: Some Debian systems doesn't include + * the distribuition name in /etc/debian_release, + * so add them here. + */ + if (!strncmp(distro_db[i].codename, "deb", 3) && + ((buf[0] >= '0' && buf[0] <= '9') || buf[0] != 'D')) { + os->distro = g_strdup_printf + ("Debian GNU/Linux %s", buf); + } else { + os->distro = g_strdup(buf); + } + } + + if (g_str_equal(distro_db[i].codename, "ppy")) { + gchar *tmp; + + tmp = g_strdup_printf("Puppy Linux %.2f", atof(os->distro) / 100.0); + g_free(os->distro); + os->distro = tmp; + } + + os->distrocode = g_strdup(distro_db[i].codename); + + break; + } + } + + os->distro = g_strstrip(os->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 = g_strdup(g_getenv("LC_MESSAGES")); + 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); + detect_desktop_environment(os); + + return os; +} diff --git a/hardinfo2/modules/computer/uptime.c b/hardinfo2/modules/computer/uptime.c new file mode 100644 index 00000000..8eb563fa --- /dev/null +++ b/hardinfo2/modules/computer/uptime.c @@ -0,0 +1,76 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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 { + 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; + gchar *tmp; + + ui = computer_get_uptime(); + + /* FIXME: Use ngettext */ +#define plural(x) ((x > 1) ? "s" : "") + + if (ui->days < 1) { + if (ui->hours < 1) { + tmp = + g_strdup_printf("%d minute%s", ui->minutes, + plural(ui->minutes)); + } else { + tmp = + g_strdup_printf("%d hour%s, %d minute%s", ui->hours, + plural(ui->hours), ui->minutes, + plural(ui->minutes)); + } + } else { + tmp = + g_strdup_printf("%d day%s, %d hour%s and %d minute%s", + ui->days, plural(ui->days), ui->hours, + plural(ui->hours), ui->minutes, + plural(ui->minutes)); + } + + g_free(ui); + return tmp; +} diff --git a/hardinfo2/modules/computer/users.c b/hardinfo2/modules/computer/users.c new file mode 100644 index 00000000..e303ac6e --- /dev/null +++ b/hardinfo2/modules/computer/users.c @@ -0,0 +1,65 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 +#include "hardinfo.h" +#include "computer.h" + +gchar *users = NULL; + +static gboolean +remove_users(gpointer key, gpointer value, gpointer data) +{ + return g_str_has_prefix(key, "USER"); +} + +void +scan_users_do(void) +{ + struct passwd *passwd_; + passwd_ = getpwent(); + if (!passwd_) + return; + + if (users) { + g_free(users); + g_hash_table_foreach_remove(moreinfo, remove_users, NULL); + } + + users = g_strdup(""); + + while (passwd_) { + gchar *key = g_strdup_printf("USER%s", passwd_->pw_name); + gchar *val = g_strdup_printf("[User Information]\n" + "User ID=%d\n" + "Group ID=%d\n" + "Home directory=%s\n" + "Default shell=%s\n", + (gint) passwd_->pw_uid, + (gint) passwd_->pw_gid, + passwd_->pw_dir, + passwd_->pw_shell); + g_hash_table_insert(moreinfo, key, val); + + strend(passwd_->pw_gecos, ','); + users = h_strdup_cprintf("$%s$%s=%s\n", users, key, passwd_->pw_name, passwd_->pw_gecos); + passwd_ = getpwent(); + } + + endpwent(); +} diff --git a/hardinfo2/modules/devices.c b/hardinfo2/modules/devices.c new file mode 100644 index 00000000..c15a9db1 --- /dev/null +++ b/hardinfo2/modules/devices.c @@ -0,0 +1,442 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "devices.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_i386) || defined(ARCH_x86_64) +gchar *callback_dmi(); +#endif +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_i386) || defined(ARCH_x86_64) +void scan_dmi(gboolean reload); +#endif +void scan_device_resources(gboolean reload); + +static ModuleEntry entries[] = { + {"Processor", "processor.png", callback_processors, scan_processors, MODULE_FLAG_NONE}, + {"Memory", "memory.png", callback_memory, scan_memory, MODULE_FLAG_NONE}, + {"PCI Devices", "devices.png", callback_pci, scan_pci, MODULE_FLAG_NONE}, + {"USB Devices", "usb.png", callback_usb, scan_usb, MODULE_FLAG_NONE}, + {"Printers", "printer.png", callback_printers, scan_printers, MODULE_FLAG_NONE}, + {"Battery", "battery.png", callback_battery, scan_battery, MODULE_FLAG_NONE}, + {"Sensors", "therm.png", callback_sensors, scan_sensors, MODULE_FLAG_NONE}, + {"Input Devices", "inputdevices.png", callback_input, scan_input, MODULE_FLAG_NONE}, + {"Storage", "hdd.png", callback_storage, scan_storage, MODULE_FLAG_NONE}, +#if defined(ARCH_i386) || defined(ARCH_x86_64) + {"DMI", "computer.png", callback_dmi, scan_dmi, MODULE_FLAG_NONE}, +#endif /* x86 or x86_64 */ + {"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; + +GHashTable *moreinfo = NULL; + +#include + +gchar *get_processor_name(void) +{ + scan_processors(FALSE); + + Processor *p = (Processor *) processors->data; + + if (g_slist_length(processors) > 1) { + return idle_free(g_strdup_printf("%dx %s", + g_slist_length(processors), + p->model_name)); + } else { + return p->model_name; + } +} + +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)); +} + +gchar *get_processor_frequency(void) +{ + Processor *p; + + scan_processors(FALSE); + + p = (Processor *)processors->data; + if (p->cpu_mhz == 0.0f) { + return g_strdup("Unknown"); + } else { + return g_strdup_printf("%.0f", p->cpu_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) +{ + /* FIXME */ + return g_strdup("0.0"); +} + +ShellModuleMethod *hi_exported_methods(void) +{ + static ShellModuleMethod m[] = { + {"getProcessorCount", get_processor_count}, + {"getProcessorName", get_processor_name}, + {"getProcessorFrequency", get_processor_frequency}, + {"getMemoryTotal", get_memory_total}, + {"getStorageDevices", get_storage_devices}, + {"getPrinters", get_printers}, + {"getInputDevices", get_input_devices}, + {"getPCIDeviceDescription", get_pci_device_description}, + {NULL} + }; + + return m; +} + +gchar *hi_more_info(gchar * entry) +{ + gchar *info = (gchar *) g_hash_table_lookup(moreinfo, entry); + + if (info) + return g_strdup(info); + + return g_strdup("?"); +} + +gchar *hi_get_field(gchar * field) +{ + gchar *info = (gchar *) g_hash_table_lookup(moreinfo, field); + + if (info) + return g_strdup(info); + + return g_strdup(field); +} + +#if defined(ARCH_i386) || defined(ARCH_x86_64) +void scan_dmi(gboolean reload) +{ + SCAN_START(); + __scan_dmi(); + SCAN_END(); +} +#endif + +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_i386) || defined(ARCH_x86_64) +gchar *callback_dmi() +{ + return g_strdup(dmi_info); +} +#endif + +gchar *callback_memory() +{ + return g_strdup_printf("[Memory]\n" + "%s\n" + "[$ShellParam$]\n" + "ViewType=2\n" + "LoadGraphSuffix= kB\n" + "RescanInterval=2000\n" + "%s\n", meminfo, 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("[$ShellParam$]\n" + "ReloadInterval=5000\n" "%s", sensors); +} + +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 = "Update PCI ID listing", + .name = "GetPCIIds", + .save_to = "pci.ids", + .get_data = NULL + }; + + sync_manager_add_entry(&se); + } + +#if defined(ARCH_i386) || defined(ARCH_x86_64) + { + static SyncEntry se = { + .fancy_name = "Update CPU feature database", + .name = "RecvCPUFlags", + .save_to = "cpuflags.conf", + .get_data = NULL + }; + + sync_manager_add_entry(&se); + } +#endif /* defined(ARCH_i386) || defined(ARCH_x86_64) */ + + moreinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + init_memory_labels(); + init_cups(); +} + +void hi_module_deinit(void) +{ + h_hash_table_remove_all(moreinfo); + g_hash_table_destroy(moreinfo); + g_hash_table_destroy(memlabels); + g_module_close(cups); +} + +ModuleAbout *hi_module_get_about(void) +{ + static ModuleAbout ma[] = { + { + .author = "Leandro A. F. Pereira", + .description = "Gathers information about hardware devices", + .version = VERSION, + .license = "GNU GPL version 2"} + }; + + return ma; +} + +gchar **hi_module_get_dependencies(void) +{ + static gchar *deps[] = { "libcomputer.so", NULL }; + + return deps; +} diff --git a/hardinfo2/modules/devices/battery.c b/hardinfo2/modules/devices/battery.c new file mode 100644 index 00000000..37416dbb --- /dev/null +++ b/hardinfo2/modules/devices/battery.c @@ -0,0 +1,307 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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 +#include + +#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 = 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")) { + charge_rate = atof(remaining) / atof(capacity); + + 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 = NULL; + } + + g_dir_close(acpi); + } + } + + g_free(acpi_path); +} + +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) +{ + if (battery_list) { + g_free(battery_list); + } + battery_list = g_strdup(""); + + __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/hardinfo2/modules/devices/devmemory.c b/hardinfo2/modules/devices/devmemory.c new file mode 100644 index 00000000..8c89d567 --- /dev/null +++ b/hardinfo2/modules/devices/devmemory.c @@ -0,0 +1,107 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 +#include "devices.h" + +GHashTable *memlabels = NULL; + +void scan_memory_do(void) +{ + gchar **keys, *tmp; + 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[1]); + + if ((tmp = g_hash_table_lookup(memlabels, newkeys[0]))) { + g_free(newkeys[0]); + newkeys[0] = g_strdup(tmp); + } + + g_hash_table_replace(moreinfo, g_strdup(newkeys[0]), g_strdup(newkeys[1])); + + tmp = g_strconcat(meminfo, newkeys[0], "=", newkeys[1], "\n", NULL); + g_free(meminfo); + meminfo = tmp; + + 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 struct { + char *proc_label; + char *real_label; + } proc2real[] = { + { "MemTotal", "Total Memory" }, + { "MemFree", "Free Memory" }, + { "SwapCached", "Cached Swap" }, + { "HighTotal", "High Memory" }, + { "HighFree", "Free High Memory" }, + { "LowTotal", "Low Memory" }, + { "LowFree", "Free Low Memory" }, + { "SwapTotal", "Virtual Memory" }, + { "SwapFree", "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/hardinfo2/modules/devices/dmi.c b/hardinfo2/modules/devices/dmi.c new file mode 100644 index 00000000..8cc45462 --- /dev/null +++ b/hardinfo2/modules/devices/dmi.c @@ -0,0 +1,200 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 + */ +#include +#include + +#include "devices.h" + +typedef struct _DMIInfo DMIInfo; + +struct _DMIInfo { + const gchar *name; + const gchar *file; /* for sysfs */ + const gchar *param; /* for dmidecode */ +}; + +DMIInfo dmi_info_table[] = { + { "$BIOS", NULL, NULL }, + { "Date", "/sys/class/dmi/id/bios_date", "bios-release-date" }, + { "Vendor", "/sys/class/dmi/id/bios_vendor", "bios-vendor" }, + { "Version", "/sys/class/dmi/id/bios_version", "bios-version" }, + { "$Board", NULL, NULL }, + { "Name", "/sys/class/dmi/id/board_name", "baseboard-product-name" }, + { "Vendor", "/sys/class/dmi/id/board_vendor", "baseboard-manufacturer" }, +}; + +gchar *dmi_info = NULL; + +gboolean dmi_get_info_dmidecode() +{ + FILE *dmi_pipe; + gchar buffer[256]; + DMIInfo *info; + gboolean dmi_failed = FALSE; + gint i; + + 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->name) == '$') { + dmi_info = h_strdup_cprintf("[%s]\n", dmi_info, + (info->name) + 1); + } else { + gchar *temp; + + if (!info->param) + continue; + + temp = g_strconcat("dmidecode -s ", info->param, NULL); + if ((dmi_pipe = popen(temp, "r"))) { + g_free(temp); + + (void)fgets(buffer, 256, dmi_pipe); + if (pclose(dmi_pipe)) { + dmi_failed = TRUE; + break; + } + + const gchar *url = vendor_get_url(buffer); + if (url) { + const gchar *vendor = vendor_get_name(buffer); + if (g_strstr_len(vendor, -1, g_strstrip(buffer)) || + g_strstr_len(g_strstrip(buffer), -1, vendor)) { + dmi_info = h_strdup_cprintf("%s=%s (%s)\n", + dmi_info, + info->name, + g_strstrip(buffer), + url); + } else { + dmi_info = h_strdup_cprintf("%s=%s (%s, %s)\n", + dmi_info, + info->name, + g_strstrip(buffer), + vendor, url); + } + } else { + dmi_info = h_strdup_cprintf("%s=%s\n", + dmi_info, + info->name, + buffer); + } + } else { + g_free(temp); + dmi_failed = TRUE; + break; + } + } + } + + if (dmi_failed) { + g_free(dmi_info); + dmi_info = NULL; + } + + return !dmi_failed; +} + +gboolean dmi_get_info_sys() +{ + FILE *dmi_file; + gchar buffer[256]; + DMIInfo *info; + gboolean dmi_failed = FALSE; + gint i; + + 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->name) == '$') { + dmi_info = h_strdup_cprintf("[%s]\n", dmi_info, + (info->name) + 1); + } else { + if (!info->file) + continue; + + if ((dmi_file = fopen(info->file, "r"))) { + (void)fgets(buffer, 256, dmi_file); + fclose(dmi_file); + + const gchar *url = vendor_get_url(buffer); + if (url) { + const gchar *vendor = vendor_get_name(buffer); + if (g_strstr_len(vendor, -1, g_strstrip(buffer)) || + g_strstr_len(g_strstrip(buffer), -1, vendor)) { + dmi_info = h_strdup_cprintf("%s=%s (%s)\n", + dmi_info, + info->name, + g_strstrip(buffer), + url); + } else { + dmi_info = h_strdup_cprintf("%s=%s (%s, %s)\n", + dmi_info, + info->name, + g_strstrip(buffer), + vendor, url); + } + } else { + dmi_info = h_strdup_cprintf("%s=%s\n", + dmi_info, + info->name, + g_strstrip(buffer)); + } + } else { + dmi_failed = TRUE; + break; + } + } + } + + if (dmi_failed) { + g_free(dmi_info); + dmi_info = NULL; + } + + return !dmi_failed; +} + +void __scan_dmi() +{ + gboolean dmi_ok; + + dmi_ok = dmi_get_info_sys(); + + if (!dmi_ok) { + dmi_ok = dmi_get_info_dmidecode(); + } + + 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/hardinfo2/modules/devices/inputdevices.c b/hardinfo2/modules/devices/inputdevices.c new file mode 100644 index 00000000..c280e218 --- /dev/null +++ b/hardinfo2/modules/devices/inputdevices.c @@ -0,0 +1,144 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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 + +#include "hardinfo.h" +#include "devices.h" + +gchar *input_icons = NULL; + +static gboolean +remove_input_devices(gpointer key, gpointer value, gpointer data) +{ + return g_str_has_prefix(key, "INP"); +} + +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[128]; + gchar *tmp, *name = NULL, *phys = NULL; + gint bus, vendor, product, version; + int d = 0, n = 0; + + dev = fopen("/proc/bus/input/devices", "r"); + if (!dev) + return; + + if (input_list) { + g_hash_table_foreach_remove(moreinfo, remove_input_devices, NULL); + g_free(input_list); + g_free(input_icons); + } + input_list = g_strdup(""); + input_icons = g_strdup(""); + + while (fgets(buffer, 128, dev)) { + tmp = buffer; + + switch (*tmp) { + case 'N': + name = g_strdup(tmp + strlen("N: Name=")); + 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 (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); + gchar *strhash = g_strdup_printf("[Device Information]\n" + "Name=%s\n" + "Type=%s\n" + "Bus=0x%x\n", + name, + input_devices[d].name, + bus); + + const gchar *url = vendor_get_url(name); + if (url) { + strhash = h_strdup_cprintf("Vendor=%s (%s)\n", + strhash, + vendor_get_name(name), + url); + } else { + strhash = h_strdup_cprintf("Vendor=%x\n", + strhash, + vendor); + } + + strhash = h_strdup_cprintf("Product=0x%x\n" + "Version=0x%x\n", + strhash, product, version); + + if (phys[1] != 0) { + strhash = h_strdup_cprintf("Connected to=%s\n", + strhash, phys); + } + + if (strstr(phys,"ir")) { + strhash = h_strdup_cprintf("InfraRed port=yes\n", + strhash); + } + + g_hash_table_insert(moreinfo, tmp, strhash); + + g_free(phys); + g_free(name); + } + } + + fclose(dev); +} diff --git a/hardinfo2/modules/devices/pci.c b/hardinfo2/modules/devices/pci.c new file mode 100644 index 00000000..a8439019 --- /dev/null +++ b/hardinfo2/modules/devices/pci.c @@ -0,0 +1,245 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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 + +#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("IRQ=%d\n", strdevice, irq); + if (freq) + strdevice = h_strdup_cprintf("Frequency=%dMHz\n", strdevice, freq); + if (latency) + strdevice = h_strdup_cprintf("Latency=%d\n", strdevice, latency); + + strdevice = h_strdup_cprintf("Bus Master=%s\n", strdevice, bus_master ? "Yes" : "No"); + } else if (!strncmp(buf, "Kernel modules", 14)) { + WALK_UNTIL(' '); + WALK_UNTIL(':'); + buf++; + + strdevice = h_strdup_cprintf("Kernel modules=%s\n", strdevice, 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("OEM Vendor=%s (%s)\n", + strdevice, + 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("Memory#%d=%d%cB (%s%s)\n", + strdevice, ++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("I/O ports at#%d=0x%x - 0x%x\n", + strdevice, ++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) { + g_hash_table_insert(moreinfo, strhash, strdevice); + 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("[Device Information]\n" + "Name=%s\n" + "Class=%s\n" + "Domain=%d\n" + "Bus, device, function=%d, %d, %d\n", + name, category, domain, bus, + device, function); + + const gchar *url = vendor_get_url(name); + if (url) { + strdevice = h_strdup_cprintf("Vendor=%s (%s)\n", + strdevice, + 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 */ + g_hash_table_insert(moreinfo, strhash, strdevice); + g_free(category); + g_free(name); + } + + g_free(lspci_path); + g_free(command_line); +} diff --git a/hardinfo2/modules/devices/printers.c b/hardinfo2/modules/devices/printers.c new file mode 100644 index 00000000..80851a00 --- /dev/null +++ b/hardinfo2/modules/devices/printers.c @@ -0,0 +1,271 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 +#include +#include + +#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; + +static gboolean +remove_printer_devices(gpointer key, gpointer value, gpointer data) +{ + return g_str_has_prefix(key, "PRN"); +} + +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 */ + g_hash_table_foreach_remove(moreinfo, remove_printer_devices, NULL); + + 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 ? "Default" : ""); + 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); + } + } + + g_hash_table_insert(moreinfo, prn_id, prn_moreinfo); + 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/hardinfo2/modules/devices/resources.c b/hardinfo2/modules/devices/resources.c new file mode 100644 index 00000000..270000dd --- /dev/null +++ b/hardinfo2/modules/devices/resources.c @@ -0,0 +1,105 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2008 Leandro A. F. Pereira + * + * 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 "devices.h" + +gchar *_resources = NULL; + +#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("PCI %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("Module %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; + + 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]); + + _resources = h_strdup_cprintf("%s=%s\n", _resources, + temp[0], name); + + g_strfreev(temp); + g_free(name); + } + + fclose(io); + } + } + + SCAN_END(); +} + +gchar *callback_device_resources(void) +{ + return g_strdup(_resources); +} diff --git a/hardinfo2/modules/devices/sensors.c b/hardinfo2/modules/devices/sensors.c new file mode 100644 index 00000000..9f02566d --- /dev/null +++ b/hardinfo2/modules/devices/sensors.c @@ -0,0 +1,383 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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 + +#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; + + 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); + + /* 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 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 void read_sensors_hwmon(void) +{ + int hwmon, count; + gchar *path_hwmon, *path_sensor, *tmp, *driver, *name, *mon; + hwmon = 0; + + path_hwmon = g_strdup_printf("/sys/class/hwmon/hwmon%d/device/", hwmon); + while (g_file_test(path_hwmon, G_FILE_TEST_EXISTS)) { + tmp = g_strdup_printf("%sdriver", path_hwmon); + driver = g_file_read_link(tmp, NULL); + g_free(tmp); + + tmp = g_path_get_basename(driver); + g_free(driver); + driver = tmp; + + if (!sensor_labels) { + read_sensor_labels(driver); + } + + sensors = g_strconcat(sensors, "[Cooling Fans]\n", NULL); + for (count = 1;; count++) { + path_sensor = + g_strdup_printf("%sfan%d_input", path_hwmon, count); + if (!g_file_get_contents(path_sensor, &tmp, NULL, NULL)) { + g_free(path_sensor); + break; + } + + mon = g_strdup_printf("fan%d", count); + name = get_sensor_label(mon); + if (!g_str_equal(name, "ignore")) { + sensors = h_strdup_cprintf("%s=%.0fRPM\n", + sensors, name, + adjust_sensor(mon, atof(tmp))); + } + + g_free(name); + g_free(mon); + g_free(tmp); + g_free(path_sensor); + } + + sensors = g_strconcat(sensors, "[Temperatures]\n", NULL); + for (count = 1;; count++) { + path_sensor = + g_strdup_printf("%stemp%d_input", path_hwmon, count); + if (!g_file_get_contents(path_sensor, &tmp, NULL, NULL)) { + g_free(path_sensor); + break; + } + + mon = g_strdup_printf("temp%d", count); + name = get_sensor_label(mon); + if (!g_str_equal(name, "ignore")) { + sensors = h_strdup_cprintf("%s=%.2f\302\260C\n", + sensors, name, + adjust_sensor(mon, + atof(tmp) / + 1000.0)); + } + + g_free(tmp); + g_free(name); + g_free(path_sensor); + g_free(mon); + } + + sensors = g_strconcat(sensors, "[Voltage Values]\n", NULL); + for (count = 0;; count++) { + path_sensor = + g_strdup_printf("%sin%d_input", path_hwmon, count); + if (!g_file_get_contents(path_sensor, &tmp, NULL, NULL)) { + g_free(path_sensor); + break; + } + + + mon = g_strdup_printf("in%d", count); + name = get_sensor_label(mon); + if (!g_str_equal(name, "ignore")) { + sensors = h_strdup_cprintf("%s=%.3fV\n", + sensors, name, + adjust_sensor(mon, + atof(tmp) / + 1000.0)); + } + + g_free(tmp); + g_free(mon); + g_free(name); + g_free(path_sensor); + } + + g_free(path_hwmon); + g_free(driver); + path_hwmon = + g_strdup_printf("/sys/class/hwmon/hwmon%d/device/", ++hwmon); + } + + 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; + gchar *temp = g_strdup(""); + + 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); + + temp = h_strdup_cprintf("\n%s=%d\302\260C\n", + temp, entry, temperature); + + g_free(contents); + } + } + + if (*temp != '\0') + sensors = + h_strdup_cprintf("\n[ACPI Thermal Zone]\n%s", + sensors, temp); + + 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); + + sensors = h_strdup_cprintf("\n[Omnibook]\n" + "CPU temperature=%d\302\260C\n", + sensors, temperature); + + g_free(contents); + } +} + +static void read_sensors_hddtemp(void) +{ + Socket *s; + static gchar *old = NULL; + gchar buffer[1024]; + gint len = 0; + + if ((s = sock_connect("127.0.0.1", 7634))) { + while (!len) + len = sock_read(s, buffer, sizeof(buffer)); + sock_close(s); + + if (len > 2 && buffer[0] == '|' && buffer[1] == '/') { + gchar **disks; + int i; + + if (old) + g_free(old); + + old = g_strdup("[Hard Disk Temperature]\n"); + + 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 + */ + old = h_strdup_cprintf("\n%s (%s)=%s\302\260%s\n", + old, + fields[1], fields[0], + fields[2], fields[3]); + + g_strfreev(fields); + } + + g_strfreev(disks); + } + } else { + g_free(old); + old = NULL; + } + + if (old) { + sensors = g_strconcat(sensors, "\n", old, NULL); + } +} + +void scan_sensors_do(void) +{ + if (sensors) + g_free(sensors); + + sensors = g_strdup(""); + + read_sensors_hwmon(); + read_sensors_acpi(); + read_sensors_omnibook(); + read_sensors_hddtemp(); + + /* FIXME: Add support for ibm acpi and more sensors */ +} diff --git a/hardinfo2/modules/devices/storage.c b/hardinfo2/modules/devices/storage.c new file mode 100644 index 00000000..23ab1de2 --- /dev/null +++ b/hardinfo2/modules/devices/storage.c @@ -0,0 +1,377 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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 + +#include "hardinfo.h" +#include "devices.h" + +gchar *storage_icons = NULL; + +static gboolean +remove_scsi_devices(gpointer key, gpointer value, gpointer data) +{ + return g_str_has_prefix(key, "SCSI"); +} + +/* SCSI support by Pascal F.Martin */ +void +__scan_scsi_devices(void) +{ + FILE *proc_scsi; + gchar buffer[256], *buf; + gint n = 0; + gint scsi_controller; + gint scsi_channel; + gint scsi_id; + gint scsi_lun; + gchar *vendor = NULL, *revision = NULL, *model = NULL; + gchar *scsi_storage_list; + + /* remove old devices from global device table */ + g_hash_table_foreach_remove(moreinfo, remove_scsi_devices, NULL); + + 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 (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); + g_hash_table_insert(moreinfo, devid, strhash); + + g_free(model); + g_free(revision); + g_free(vendor); + } + } + fclose(proc_scsi); + } + + if (n) { + storage_list = h_strconcat(storage_list, scsi_storage_list, NULL); + g_free(scsi_storage_list); + } +} + +static gboolean +remove_ide_devices(gpointer key, gpointer value, gpointer data) +{ + return g_str_has_prefix(key, "IDE"); +} + +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 */ + g_hash_table_foreach_remove(moreinfo, remove_ide_devices, NULL); + + 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"); + (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"); + (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"); + (void)fscanf(proc_ide, "%d", &cache); + fclose(proc_ide); + } + 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"); + + (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); + } + 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; + } + + g_hash_table_insert(moreinfo, devid, strhash); + + g_free(model); + model = g_strdup(""); + } 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/hardinfo2/modules/devices/usb.c b/hardinfo2/modules/devices/usb.c new file mode 100644 index 00000000..39914dd0 --- /dev/null +++ b/hardinfo2/modules/devices/usb.c @@ -0,0 +1,349 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2008 Leandro A. F. Pereira + * + * 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 + +#include "hardinfo.h" +#include "devices.h" + +gchar *usb_list = NULL; + +static gboolean +remove_usb_devices(gpointer key, gpointer value, gpointer data) +{ + return g_str_has_prefix(key, "USB"); +} + +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("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("USB %.2f Hub", version); + } else { + product = g_strdup_printf("Unknown USB %.2f Device (class %d)", version, classid); + } + } + + const gchar *url = vendor_get_url(manufacturer); + if (url) { + tmp = g_strdup_printf("%s (%s)", vendor_get_name(manufacturer), url); + + g_free(manufacturer); + manufacturer = tmp; + } + + tmp = g_strdup_printf("USB%d", n); + usb_list = h_strdup_cprintf("$%s$%s=\n", usb_list, tmp, product); + + strhash = g_strdup_printf("[Device Information]\n" + "Product=%s\n" + "Manufacturer=%s\n" + "Speed=%.2fMbit/s\n" + "Max Current=%s\n" + "[Misc]\n" + "USB Version=%.2f\n" + "Class=0x%x\n" + "Vendor=0x%x\n" + "Product ID=0x%x\n" + "Bus=%d\n", + product, + manufacturer, + speed, + mxpwr, + version, classid, vendor, prodid, bus); + + g_hash_table_insert(moreinfo, tmp, strhash); + + 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) { + g_hash_table_foreach_remove(moreinfo, remove_usb_devices, NULL); + g_free(usb_list); + } + usb_list = g_strdup("[USB Devices]\n"); + + 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; + gint bus, level, port, classid, trash; + gint vendor, prodid; + gfloat ver, rev, speed; + int n = 0; + + dev = fopen("/proc/bus/usb/devices", "r"); + if (!dev) + return 0; + + if (usb_list) { + g_hash_table_foreach_remove(moreinfo, remove_usb_devices, NULL); + g_free(usb_list); + } + usb_list = g_strdup("[USB Devices]\n"); + + 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 == '\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); + + const gchar *url = vendor_get_url(manuf); + if (url) { + gchar *tmp = + g_strdup_printf("%s (%s)", vendor_get_name(manuf), + url); + g_free(manuf); + manuf = tmp; + } + + gchar *strhash = g_strdup_printf("[Device Information]\n" + "Product=%s\n", + product); + if (manuf && strlen(manuf)) + strhash = h_strdup_cprintf("Manufacturer=%s\n", + strhash, manuf); + + strhash = h_strdup_cprintf("[Port #%d]\n" + "Speed=%.2fMbit/s\n" + "Max Current=%s\n" + "[Misc]\n" + "USB Version=%.2f\n" + "Revision=%.2f\n" + "Class=0x%x\n" + "Vendor=0x%x\n" + "Product ID=0x%x\n" + "Bus=%d\n" "Level=%d\n", + strhash, + port, speed, mxpwr, + ver, rev, classid, + vendor, prodid, bus, level); + + g_hash_table_insert(moreinfo, tmp, strhash); + } + + g_free(manuf); + g_free(product); + manuf = g_strdup(""); + product = g_strdup(""); + } + } + + fclose(dev); + + return n > 0; +} + +void __scan_usb_lsusb_add_device(char *buffer, FILE *lsusb, int usb_device_number) +{ + gint bus, device, vendor_id, product_id; + gchar *product, *vendor, *max_power, *tmp, *strhash; + + sscanf(buffer, "Bus %d Device %d: ID %x:%x", + &bus, &device, &vendor_id, &product_id); + + while (fgets(buffer, 512, lsusb)) { + if (g_str_has_prefix(buffer, " idVendor")) { + vendor = g_strstrip(g_strdup(buffer + 28)); + } else if (g_str_has_prefix(buffer, " idProduct")) { + product = g_strstrip(g_strdup(buffer + 28)); + } else if (g_str_has_prefix(buffer, " MaxPower")) { + max_power = g_strstrip(g_strdup(buffer + 26)); + } else if (g_str_has_prefix(buffer, "\n")) { + /* device separator */ + break; + } + } + + tmp = g_strdup_printf("USB%d", usb_device_number); + usb_list = h_strdup_cprintf("$%s$%s=\n", usb_list, tmp, product); + + strhash = g_strdup_printf("[Device Information]\n" + "Product=%s\n" + "Manufacturer=%s\n" + "Max Current=%s\n" + "[Misc]\n" + "USB Version=%.2f\n" + "Class=0x%x\n" + "Vendor=0x%x\n" + "Product ID=0x%x\n" + "Bus=%d\n", + product, + vendor, + max_power, + 0.0f /* FIXME */, + 0 /* FIXME */, + vendor_id, product_id, bus); + + g_hash_table_insert(moreinfo, tmp, strhash); + + g_free(vendor); + g_free(product); + g_free(max_power); +} + +gboolean __scan_usb_lsusb(void) +{ + static gchar *lsusb_path = NULL; + int usb_device_number = 0; + FILE *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", lsusb_path); + if (!(lsusb = popen(temp, "r"))) { + DEBUG("cannot run %s", lsusb_path); + + g_free(temp); + return FALSE; + } + + g_free(temp); + + if (usb_list) { + g_hash_table_foreach_remove(moreinfo, remove_usb_devices, NULL); + g_free(usb_list); + } + usb_list = g_strdup("[USB Devices]\n"); + + while (fgets(buffer, sizeof(buffer), lsusb)) { + if (g_str_has_prefix(buffer, "Bus ")) { + __scan_usb_lsusb_add_device(buffer, lsusb, ++usb_device_number); + } + } + + pclose(lsusb); + + return usb_device_number > 0; +} + +void __scan_usb(void) +{ + if (!__scan_usb_procfs()) { + if (!__scan_usb_sysfs()) { + __scan_usb_lsusb(); + } + } +} diff --git a/hardinfo2/modules/devices/x86/processor.c b/hardinfo2/modules/devices/x86/processor.c new file mode 100644 index 00000000..aee409f1 --- /dev/null +++ b/hardinfo2/modules/devices/x86/processor.c @@ -0,0 +1,562 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira + * + * 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" + +/* + * This function is partly based on x86cpucaps + * by Osamu Kayasono + */ +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, + cache->type, + cache->ways_of_associativity, + cache->number_of_sets, + cache->size); + } + + return result; +} + +static void __cache_obtain_info(Processor *processor, gint processor_number) +{ + ProcessorCache *cache; + gchar *endpoint, *entry, *index; + gint i; + + 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); + + g_free(index); + + processor->cache = g_slist_append(processor->cache, cache); + } + +fail: + g_free(endpoint); +} + +GSList *processor_scan(void) +{ + GSList *procs = NULL; + Processor *processor = NULL; + FILE *cpuinfo; + gchar buffer[512]; + gint processor_number = 0; + + cpuinfo = fopen("/proc/cpuinfo", "r"); + if (!cpuinfo) + return NULL; + + while (fgets(buffer, 512, cpuinfo)) { + gchar **tmp = g_strsplit(buffer, ":", 2); + + if (g_str_has_prefix(tmp[0], "processor")) { + if (processor) { + get_processor_strfamily(processor); + procs = g_slist_append(procs, processor); + } + + processor = g_new0(Processor, 1); + + __cache_obtain_info(processor, processor_number++); + } + + if (tmp[0] && tmp[1]) { + tmp[0] = g_strstrip(tmp[0]); + tmp[1] = g_strstrip(tmp[1]); + + get_str("model name", processor->model_name); + get_str("vendor_id", processor->vendor_id); + get_str("flags", processor->flags); + 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); + + get_int("model", processor->model); + get_int("cpu family", processor->family); + get_int("stepping", processor->stepping); + + get_int("processor", processor->id); + } + g_strfreev(tmp); + } + + if (processor) { + get_processor_strfamily(processor); + procs = g_slist_append(procs, processor); + } + + fclose(cpuinfo); + + return procs; +} + +/* + * Sources: + * - Linux' cpufeature.h + * - http://gentoo-wiki.com/Cpuinfo + * - Intel IA-32 Architecture Software Development Manual + */ +static struct { + char *name, *meaning; +} flag_meaning[] = { + { "3dnow", "3DNow! Technology" }, + { "3dnowext", "Extended 3DNow! Technology" }, + { "fpu", "Floating Point Unit" }, + { "vme", "Virtual 86 Mode Extension" }, + { "de", "Debug Extensions - I/O breakpoints" }, + { "pse", "Page Size Extensions (4MB pages)" }, + { "tsc", "Time Stamp Counter and RDTSC instruction" }, + { "msr", "Model Specific Registers" }, + { "pae", "Physical Address Extensions" }, + { "mce", "Machine Check Architeture" }, + { "cx8", "CMPXCHG8 instruction" }, + { "apic", "Advanced Programmable Interrupt Controller" }, + { "sep", "Fast System Call (SYSENTER/SYSEXIT)" }, + { "mtrr", "Memory Type Range Registers" }, + { "pge", "Page Global Enable" }, + { "mca", "Machine Check Architecture" }, + { "cmov", "Conditional Move instruction" }, + { "pat", "Page Attribute Table" }, + { "pse36", "36bit Page Size Extensions" }, + { "psn", "96 bit Processor Serial Number" }, + { "mmx", "MMX technology" }, + { "mmxext", "Extended MMX Technology" }, + { "cflush", "Cache Flush" }, + { "dtes", "Debug Trace Store" }, + { "fxsr", "FXSAVE and FXRSTOR instructions" }, + { "kni", "Streaming SIMD instructions" }, + { "xmm", "Streaming SIMD instructions" }, + { "ht", "HyperThreading" }, + { "mp", "Multiprocessing Capable" }, + { "sse", "SSE instructions" }, + { "sse2", "SSE2 (WNI) instructions" }, + { "acc", "Automatic Clock Control" }, + { "ia64", "IA64 Instructions" }, + { "syscall", "SYSCALL and SYSEXIT instructions" }, + { "nx", "No-execute Page Protection" }, + { "xd", "Execute Disable" }, + { "clflush", "Cache Line Flush instruction" }, + { "acpi", "Thermal Monitor and Software Controlled Clock" }, + { "dts", "Debug Store" }, + { "ss", "Self Snoop" }, + { "tm", "Thermal Monitor" }, + { "pbe", "Pending Break Enable" }, + { "pb", "Pending Break Enable" }, + { "pn", "Processor serial number" }, + { "ds", "Debug Store" }, + { "xmm2", "Streaming SIMD Extensions-2" }, + { "xmm3", "Streaming SIMD Extensions-3" }, + { "selfsnoop", "CPU self snoop" }, + { "rdtscp", "RDTSCP" }, + { "recovery", "CPU in recovery mode" }, + { "longrun", "Longrun power control" }, + { "lrti", "LongRun table interface" }, + { "cxmmx", "Cyrix MMX extensions" }, + { "k6_mtrr", "AMD K6 nonstandard MTRRs" }, + { "cyrix_arr", "Cyrix ARRs (= MTRRs)" }, + { "centaur_mcr","Centaur MCRs (= MTRRs)" }, + { "constant_tsc","TSC ticks at a constant rate" }, + { "up", "smp kernel running on up" }, + { "fxsave_leak","FXSAVE leaks FOP/FIP/FOP" }, + { "arch_perfmon","Intel Architectural PerfMon" }, + { "pebs", "Precise-Event Based Sampling" }, + { "bts", "Branch Trace Store" }, + { "sync_rdtsc", "RDTSC synchronizes the CPU" }, + { "rep_good", "rep microcode works well on this CPU" }, + { "mwait", "Monitor/Mwait support" }, + { "ds_cpl", "CPL Qualified Debug Store" }, + { "est", "Enhanced SpeedStep" }, + { "tm2", "Thermal Monitor 2" }, + { "cid", "Context ID" }, + { "xtpr", "Send Task Priority Messages" }, + { "xstore", "on-CPU RNG present (xstore insn)" }, + { "xstore_en", "on-CPU RNG enabled" }, + { "xcrypt", "on-CPU crypto (xcrypt insn)" }, + { "xcrypt_en", "on-CPU crypto enabled" }, + { "ace2", "Advanced Cryptography Engine v2" }, + { "ace2_en", "ACE v2 enabled" }, + { "phe", "PadLock Hash Engine" }, + { "phe_en", "PHE enabled" }, + { "pmm", "PadLock Montgomery Multiplier" }, + { "pmm_en", "PMM enabled" }, + { "lahf_lm", "LAHF/SAHF in long mode" }, + { "cmp_legacy", "HyperThreading not valid" }, + { "lm", "LAHF/SAHF in long mode" }, + { "ds_cpl", "CPL Qualified Debug Store" }, + { "vmx", "Virtualization support (Intel)" }, + { "svm", "Virtualization support (AMD)" }, + { "est", "Enhanced SpeedStep" }, + { "tm2", "Thermal Monitor 2" }, + { "ssse3", "Supplemental Streaming SIMD Extension 3" }, + { "cx16", "CMPXCHG16B instruction" }, + { "xptr", "Send Task Priority Messages" }, + { "pebs", "Precise Event Based Sampling" }, + { "bts", "Branch Trace Store" }, + { "ida", "Intel Dynamic Acceleration" }, + { "arch_perfmon","Intel Architectural PerfMon" }, + { "pni", "Streaming SIMD Extension 3 (Prescott New Instruction)" }, + { "rep_good", "rep microcode works well on this CPU" }, + { "ts", "Thermal Sensor" }, + { "sse3", "Streaming SIMD Extension 3" }, + { "sse4", "Streaming SIMD Extension 4" }, + { "tni", "Tejas New Instruction" }, + { "nni", "Nehalem New Instruction" }, + { "tpr", "Task Priority Register" }, + { "vid", "Voltage Identifier" }, + { "fid", "Frequency Identifier" }, + { "dtes64", "64-bit Debug Store" }, + { "monitor", "Monitor/Mwait support" }, + { NULL, NULL }, +}; + +GHashTable *cpu_flags = NULL; + +void cpu_flags_init(void) +{ + gint i; + gchar *path; + + cpu_flags = g_hash_table_new(g_str_hash, g_str_equal); + + path = g_build_filename(g_get_home_dir(), ".hardinfo", "cpuflags.conf", NULL); + if (!g_file_test(path, G_FILE_TEST_EXISTS)) { + DEBUG("using internal CPU flags database"); + + for (i = 0; flag_meaning[i].name != NULL; i++) { + g_hash_table_insert(cpu_flags, flag_meaning[i].name, + flag_meaning[i].meaning); + } + } else { + GKeyFile *flags_file; + + DEBUG("using %s as CPU flags database", path); + + flags_file = g_key_file_new(); + if (g_key_file_load_from_file(flags_file, path, 0, NULL)) { + gchar **flag_keys; + + flag_keys = g_key_file_get_keys(flags_file, "flags", + NULL, NULL); + for (i = 0; flag_keys[i]; i++) { + gchar *meaning; + + meaning = g_key_file_get_string(flags_file, "flags", + flag_keys[i], NULL); + + g_hash_table_insert(cpu_flags, g_strdup(flag_keys[i]), meaning); + + /* can't free meaning */ + } + + g_strfreev(flag_keys); + } + + g_key_file_free(flags_file); + } + + g_free(path); +} + +gchar *processor_get_capabilities_from_flags(gchar * strflags) +{ + /* FIXME: + * - Separate between processor capabilities, additional instructions and whatnot. + */ + gchar **flags, **old; + gchar *tmp = NULL; + gint j = 0; + + if (!cpu_flags) { + cpu_flags_init(); + } + + flags = g_strsplit(strflags, " ", 0); + old = flags; + + while (flags[j]) { + gchar *meaning = g_hash_table_lookup(cpu_flags, 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++; + } + + g_strfreev(old); + return tmp; +} + +gchar *processor_get_detailed_info(Processor * processor) +{ + gchar *tmp, *ret, *cache_info; + + tmp = processor_get_capabilities_from_flags(processor->flags); + cache_info = __cache_get_info_as_string(processor); + + ret = g_strdup_printf("[Processor]\n" + "Name=%s\n" + "Family, model, stepping=%d, %d, %d (%s)\n" + "Vendor=%s\n" + "[Configuration]\n" + "Cache Size=%dkb\n" + "Frequency=%.2fMHz\n" + "BogoMIPS=%.2f\n" + "Byte Order=%s\n" + "[Features]\n" + "FDIV Bug=%s\n" + "HLT Bug=%s\n" + "F00F Bug=%s\n" + "Coma Bug=%s\n" + "Has FPU=%s\n" + "[Cache]\n" + "%s\n" + "[Capabilities]\n" + "%s", + processor->model_name, + processor->family, + processor->model, + processor->stepping, + processor->strmodel, + vendor_get_name(processor->vendor_id), + processor->cache_size, + processor->cpu_mhz, processor->bogomips, +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + "Little Endian", +#else + "Big Endian", +#endif + processor->bug_fdiv ? processor->bug_fdiv : "no", + processor->bug_hlt ? processor->bug_hlt : "no", + processor->bug_f00f ? processor->bug_f00f : "no", + processor->bug_coma ? processor->bug_coma : "no", + processor->has_fpu ? processor->has_fpu : "no", + cache_info, + tmp); + g_free(tmp); + g_free(cache_info); + + 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=%.2fMHz\n", + tmp, processor->id, + processor->model_name, + processor->cpu_mhz); + + hashkey = g_strdup_printf("CPU%d", processor->id); + g_hash_table_insert(moreinfo, hashkey, + processor_get_detailed_info(processor)); + } + + 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/hardinfo2/modules/network.c b/hardinfo2/modules/network.c new file mode 100644 index 00000000..168e04a9 --- /dev/null +++ b/hardinfo2/modules/network.c @@ -0,0 +1,443 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2008 Leandro A. F. Pereira + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include "network.h" + +GHashTable *moreinfo = NULL; + +/* 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[] = { + {"Interfaces", "network-interface.png", callback_network, scan_network, MODULE_FLAG_NONE}, + {"IP Connections", "network-connections.png", callback_connections, scan_connections, MODULE_FLAG_NONE}, + {"Routing Table", "network.png", callback_route, scan_route, MODULE_FLAG_NONE}, + {"ARP Table", "module.png", callback_arp, scan_arp, MODULE_FLAG_NONE}, + {"DNS Servers", "dns.png", callback_dns, scan_dns, MODULE_FLAG_NONE}, + {"Statistics", "network-statistics.png", callback_statistics, scan_statistics, MODULE_FLAG_NONE}, + {"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; + + 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 if (isdigit(buffer[4])) { + gchar *tmp1 = buffer + 4, + *tmp2 = tmp1; + + while (*tmp2 && !isspace(*tmp2)) tmp2++; + *tmp2 = 0; + tmp2++; + + *tmp2 = toupper(*tmp2); + + __statistics = h_strdup_cprintf("%s=%s\n", + __statistics, + g_strstrip(tmp1), + g_strstrip(tmp2)); + } + } + + 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("[ARP Table]\n" + "%s\n" + "[$ShellParam$]\n" + "ReloadInterval=3000\n" + "ColumnTitle$TextValue=IP Address\n" + "ColumnTitle$Value=Interface\n" + "ColumnTitle$Extra1=MAC Address\n" + "ShowColumnHeaders=true\n", + __arp_table); +} + +gchar *callback_shares() +{ + return g_strdup_printf("[SAMBA]\n" + "%s\n" + "[NFS]\n" + "%s", smb_shares_list, nfs_shares_list); +} + +gchar *callback_dns() +{ + return g_strdup_printf("[Name servers]\n" + "%s\n" + "[$ShellParam$]\n" + "ColumnTitle$TextValue=IP Address\n" + "ColumnTitle$Value=Name\n" + "ShowColumnHeaders=true\n", __nameservers); +} + +gchar *callback_connections() +{ + return g_strdup_printf("[Connections]\n" + "%s\n" + "[$ShellParam$]\n" + "ReloadInterval=3000\n" + "ColumnTitle$TextValue=Local Address\n" + "ColumnTitle$Value=Protocol\n" + "ColumnTitle$Extra1=Foreign Address\n" + "ColumnTitle$Extra2=State\n" + "ShowColumnHeaders=true\n", + __connections); +} + +gchar *callback_network() +{ + return g_strdup_printf("%s\n" + "[$ShellParam$]\n" + "ReloadInterval=3000\n" + "ViewType=1\n" + "ColumnTitle$TextValue=Interface\n" + "ColumnTitle$Value=IP Address\n" + "ColumnTitle$Extra1=Sent\n" + "ColumnTitle$Extra2=Received\n" + "ShowColumnHeaders=true\n" + "%s", + network_interfaces, + network_icons); +} + +gchar *callback_route() +{ + return g_strdup_printf("[IP routing table]\n" + "%s\n" + "[$ShellParam$]\n" + "ViewType=0\n" + "ReloadInterval=3000\n" + "ColumnTitle$TextValue=Destination / Gateway\n" + "ColumnTitle$Value=Interface\n" + "ColumnTitle$Extra1=Flags\n" + "ColumnTitle$Extra2=Mask\n" + "ShowColumnHeaders=true\n", + __routing_table); +} + +gchar *callback_statistics() +{ + return g_strdup_printf("%s\n" + "[$ShellParam$]\n" + "ReloadInterval=3000\n", + __statistics); +} + +gchar *hi_more_info(gchar * entry) +{ + gchar *info = (gchar *) g_hash_table_lookup(moreinfo, 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) +{ + moreinfo = + g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); +} + +void hi_module_deinit(void) +{ + h_hash_table_remove_all(moreinfo); + g_hash_table_destroy(moreinfo); + + 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 = "Gathers information about this computer's network connection", + .version = VERSION, + .license = "GNU GPL version 2"} + }; + + return ma; +} diff --git a/hardinfo2/modules/network/net.c b/hardinfo2/modules/network/net.c new file mode 100644 index 00000000..c470bc37 --- /dev/null +++ b/hardinfo2/modules/network/net.c @@ -0,0 +1,454 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2008 Leandro A. F. Pereira + * + * 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 +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#ifdef HAS_LINUX_WE +#include +#include +#else +#include +#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[] = { "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary", "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 (strstr(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 ((r = ioctl(fd, SIOCGIWESSID, &wi_req) < 0)) { + strcpy(netinfo->wi_essid, ""); + } else { + netinfo->wi_essid[wi_req.u.essid.length] = '\0'; + } + + /* obtain bit rate */ + if ((r = ioctl(fd, SIOCGIWRATE, &wi_req) < 0)) { + netinfo->wi_rate = 0; + } else { + netinfo->wi_rate = wi_req.u.bitrate.value; + } + + /* obtain operation mode */ + if ((r = 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 ((r = 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; + strcpy(netinfo->name, if_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 { + sprintf(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 { + sprintf(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 { + sprintf(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[] = { + { "eth", "Ethernet", "network-interface" }, + { "lo", "Loopback", "network" }, + { "ppp", "Point-to-Point", "modem" }, + { "ath", "Wireless", "wireless" }, + { "wlan", "Wireless", "wireless" }, + { "ra", "Wireless", "wireless" }, + { "wl", "Wireless", "wireless" }, + { "wmaster", "Wireless", "wireless" }, + { "tun", "Virtual Point-to-Point (TUN)", "network" }, + { "tap", "Ethernet (TAP)", "network" }, + { "plip", "Parallel Line Internet Protocol", "network" }, + { "irlan", "Infrared", "network" }, + { "slip", "Serial Line Internet Protocol", "network" }, + { "isdn", "Integrated Services Digital Network", "modem" }, + { "sit", "IPv6-over-IPv4 Tunnel", "network" }, + { "vmnet8", "VMWare Virtual Network Interface (NAT)", "computer" }, + { "vmnet", "VMWare Virtual Network Interface", "computer" }, + { "pan", "Personal Area Network (PAN)", "bluetooth" }, + { "bnep", "Bluetooth", "bluetooth" }, + { "br", "Bridge Interface", "network" }, + { "ham", "Hamachi Virtual Personal Network", "network"}, + { "net", "Ethernet", "network-interface" }, + { "ifb", "Intermediate Functional Block", "network" }, + { "gre", "GRE Network Tunnel", "network" }, + { "msh", "Mesh Network", "wireless" }, + { "wmaster", "Wireless Master Interface", "wireless" }, + { NULL, "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"; + *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; + *icon = netdev2type[i].icon; +} + +static gboolean +remove_net_devices(gpointer key, gpointer value, gpointer data) +{ + return g_str_has_prefix(key, "NET"); +} + +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("[Network Interfaces]\n" + "None found=\n"); + } + + return; + } + + if (network_interfaces) { + g_free(network_interfaces); + } + + if (network_icons) { + g_free(network_icons); + } + + network_interfaces = g_strdup("[Network Interfaces]\n"); + 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|%.2lfMiB|%.2lfMiB\n", + network_interfaces, devid, ifacename, ni.ip[0] ? ni.ip : "", + trans_mb, recv_mb); + 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("[Network Adapter Properties]\n" + "Interface Type=%s\n" + "Hardware Address (MAC)=%02x:%02x:%02x:%02x:%02x:%02x\n" + "MTU=%d\n" + "[Transfer Details]\n" + "Bytes Received=%.0lf (%.2fMiB)\n" + "Bytes Sent=%.0lf (%.2fMiB)\n", + iface_type, + ni.mac[0], ni.mac[1], + ni.mac[2], ni.mac[3], + ni.mac[4], ni.mac[5], + ni.mtu, + recv_bytes, recv_mb, + trans_bytes, trans_mb); + +#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("%ddBm (%dmW)", dbm, mw); + } else { + txpower = g_strdup("Unknown"); + } + + detailed = h_strdup_cprintf("\n[Wireless Properties]\n" + "Network Name (SSID)=%s\n" + "Bit Rate=%dMb/s\n" + "Transmission Power=%s\n" + "Mode=%s\n" + "Status=%d\n" + "Link Quality=%d\n" + "Signal / Noise=%d / %d\n", + detailed, + ni.wi_essid, + ni.wi_rate / 1000000, + txpower, + wi_operation_modes[ni.wi_mode], + ni.wi_status, + ni.wi_quality_level, + 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[Internet Protocol (IPv4)]\n" + "IP Address=%s\n" "Mask=%s\n" + "Broadcast Address=%s\n", detailed, + ni.ip[0] ? ni.ip : "Not set", + ni.mask[0] ? ni.mask : "Not set", + ni.broadcast[0] ? ni. + broadcast : "Not set"); + } + + g_hash_table_insert(moreinfo, devid, detailed); + } + } + 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 */ + g_hash_table_foreach_remove(moreinfo, remove_net_devices, NULL); + + scan_net_interfaces_24(); +} diff --git a/hardinfo2/modules/network/nfs.c b/hardinfo2/modules/network/nfs.c new file mode 100644 index 00000000..63b2a2e6 --- /dev/null +++ b/hardinfo2/modules/network/nfs.c @@ -0,0 +1,61 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 + +#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]; + + if (nfs_shares_list) { + 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", + buf, nfs_shares_list); + count++; + } + + fclose(exports); + } + + if (!count) { + g_free(nfs_shares_list); + + nfs_shares_list = g_strdup("No NFS exports=\n"); + } +} + diff --git a/hardinfo2/modules/network/samba.c b/hardinfo2/modules/network/samba.c new file mode 100644 index 00000000..71ba6ab6 --- /dev/null +++ b/hardinfo2/modules/network/samba.c @@ -0,0 +1,124 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 + +#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; + + if ((usershare_list = popen("net usershare list", "r"))) { + char buffer[512]; + + shell_status_update("Scanning SAMBA user shares..."); + + while (fgets(buffer, 512, usershare_list)) { + gchar *usershare, *cmdline; + gsize length; + + cmdline = g_strdup_printf("net usershare info '%s'", + strend(buffer, '\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(); + } + + pclose(usershare_list); + } +} + +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/hardinfo2/network.c b/hardinfo2/network.c deleted file mode 100644 index 243b7706..00000000 --- a/hardinfo2/network.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2008 Leandro A. F. Pereira - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include - -static GHashTable *moreinfo = NULL; - -/* 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[] = { - {"Interfaces", "network-interface.png", callback_network, scan_network, MODULE_FLAG_NONE}, - {"IP Connections", "network-connections.png", callback_connections, scan_connections, MODULE_FLAG_NONE}, - {"Routing Table", "network.png", callback_route, scan_route, MODULE_FLAG_NONE}, - {"ARP Table", "module.png", callback_arp, scan_arp, MODULE_FLAG_NONE}, - {"DNS Servers", "dns.png", callback_dns, scan_dns, MODULE_FLAG_NONE}, - {"Statistics", "network-statistics.png", callback_statistics, scan_statistics, MODULE_FLAG_NONE}, - {"Shared Directories", "shares.png", callback_shares, scan_shares, MODULE_FLAG_NONE}, - {NULL}, -}; - -#include -#include -#include - -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; - - 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 if (isdigit(buffer[4])) { - gchar *tmp1 = buffer + 4, - *tmp2 = tmp1; - - while (*tmp2 && !isspace(*tmp2)) tmp2++; - *tmp2 = 0; - tmp2++; - - *tmp2 = toupper(*tmp2); - - __statistics = h_strdup_cprintf("%s=%s\n", - __statistics, - g_strstrip(tmp1), - g_strstrip(tmp2)); - } - } - - 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("[ARP Table]\n" - "%s\n" - "[$ShellParam$]\n" - "ReloadInterval=3000\n" - "ColumnTitle$TextValue=IP Address\n" - "ColumnTitle$Value=Interface\n" - "ColumnTitle$Extra1=MAC Address\n" - "ShowColumnHeaders=true\n", - __arp_table); -} - -gchar *callback_shares() -{ - return g_strdup_printf("[SAMBA]\n" - "%s\n" - "[NFS]\n" - "%s", smb_shares_list, nfs_shares_list); -} - -gchar *callback_dns() -{ - return g_strdup_printf("[Name servers]\n" - "%s\n" - "[$ShellParam$]\n" - "ColumnTitle$TextValue=IP Address\n" - "ColumnTitle$Value=Name\n" - "ShowColumnHeaders=true\n", __nameservers); -} - -gchar *callback_connections() -{ - return g_strdup_printf("[Connections]\n" - "%s\n" - "[$ShellParam$]\n" - "ReloadInterval=3000\n" - "ColumnTitle$TextValue=Local Address\n" - "ColumnTitle$Value=Protocol\n" - "ColumnTitle$Extra1=Foreign Address\n" - "ColumnTitle$Extra2=State\n" - "ShowColumnHeaders=true\n", - __connections); -} - -gchar *callback_network() -{ - return g_strdup_printf("%s\n" - "[$ShellParam$]\n" - "ReloadInterval=3000\n" - "ViewType=1\n" - "ColumnTitle$TextValue=Interface\n" - "ColumnTitle$Value=IP Address\n" - "ColumnTitle$Extra1=Sent\n" - "ColumnTitle$Extra2=Received\n" - "ShowColumnHeaders=true\n" - "%s", - network_interfaces, - network_icons); -} - -gchar *callback_route() -{ - return g_strdup_printf("[IP routing table]\n" - "%s\n" - "[$ShellParam$]\n" - "ViewType=0\n" - "ReloadInterval=3000\n" - "ColumnTitle$TextValue=Destination / Gateway\n" - "ColumnTitle$Value=Interface\n" - "ColumnTitle$Extra1=Flags\n" - "ColumnTitle$Extra2=Mask\n" - "ShowColumnHeaders=true\n", - __routing_table); -} - -gchar *callback_statistics() -{ - return g_strdup_printf("%s\n" - "[$ShellParam$]\n" - "ReloadInterval=3000\n", - __statistics); -} - -gchar *hi_more_info(gchar * entry) -{ - gchar *info = (gchar *) g_hash_table_lookup(moreinfo, 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) -{ - moreinfo = - g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); -} - -void hi_module_deinit(void) -{ - h_hash_table_remove_all(moreinfo); - g_hash_table_destroy(moreinfo); - - 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 = "Gathers information about this computer's network connection", - .version = VERSION, - .license = "GNU GPL version 2"} - }; - - return ma; -} diff --git a/hardinfo2/nqueens.c b/hardinfo2/nqueens.c deleted file mode 100644 index 838731c4..00000000 --- a/hardinfo2/nqueens.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * N-Queens Problem Solver - * Found somewhere on the Internet; can't remember where. Possibly Wikipedia. - */ -#include -#include -#include - -#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; -} diff --git a/hardinfo2/nqueens.h b/hardinfo2/nqueens.h deleted file mode 100644 index a4be93f0..00000000 --- a/hardinfo2/nqueens.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * 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/hardinfo2/remote.c b/hardinfo2/remote.c deleted file mode 100644 index d266735d..00000000 --- a/hardinfo2/remote.c +++ /dev/null @@ -1,1307 +0,0 @@ -/* - * Remote Client - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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 -#include - -#include "config.h" - -#ifdef HAS_LIBSOUP - -#include "shell.h" -#include "callbacks.h" -#include "iconcache.h" -#include "hardinfo.h" -#include "xmlrpc-client.h" -#include "ssh-conn.h" - -#define XMLRPC_SERVER_VERSION 1 - -/* - * TODO - * - * - Add hi_deinit() to modules (so they can free up their memory) - * - Import / Export host list - * - Detect machines on local network that runs SSH - * - IP range scan - * - mDNS - * - Allow the user to add/remove/edit a machine - * - Use ~/.ssh/known_hosts as a starting point? - * - Different icons for different machines? - * - Make sure SSH can do port forwarding - * - Make sure the remote host has HardInfo installed - * - Generate a random username/password to be passed to the XML-RPC server; use - * that username/password on the client; this is just to make sure nobody on the - * machine will be allowed to obtain information that might be sensitive. This - * will be passed with base64, so it can be sniffed; this needs root access anyway, - * so not really a problem. - * - Determine if we're gonna use GIOChannels or create a communication thread - * - Introduce a flag on the modules, stating their ability to be used locally/remotely - * (Benchmarks can't be used remotely; Displays won't work remotely [unless we use - * X forwarding, but that'll be local X11 info anyway]). - */ - -typedef struct _HostManager HostManager; -typedef struct _HostDialog HostDialog; - -typedef enum { - HOST_DIALOG_MODE_EDIT, - HOST_DIALOG_MODE_CONNECT -} HostDialogMode; - -struct _HostManager { - GtkWidget *dialog; - GtkWidget *btn_connect, *btn_cancel; - GtkWidget *btn_add, *btn_edit, *btn_remove; - - GtkListStore *tree_store; - - gint selected_id; - gchar *selected_name; - GtkTreeIter *selected_iter; -}; - -struct _HostDialog { - GtkWidget *dialog; - GtkWidget *notebook; - - GtkWidget *txt_hostname, *txt_port; - GtkWidget *txt_ssh_user, *txt_ssh_password; - - GtkWidget *cmb_type; - - GtkWidget *frm_options; - GtkWidget *btn_accept, *btn_cancel; -}; - -static HostManager *host_manager_new(GtkWidget * parent); -static void host_manager_destroy(HostManager * rd); -static HostDialog *host_dialog_new(GtkWidget * parent, - gchar * title, HostDialogMode mode); -static void host_dialog_destroy(HostDialog * hd); - - -static gchar *xmlrpc_server_uri = NULL; -static SSHConn *ssh_conn = NULL; - -void remote_disconnect_all(gboolean ssh) -{ - if (ssh && ssh_conn) { - ssh_close(ssh_conn); - ssh_conn = NULL; - } - - if (xmlrpc_server_uri) { - g_free(xmlrpc_server_uri); - xmlrpc_server_uri = NULL; - } -} - -static void remote_connection_error(void) -{ - GtkWidget *dialog; - static gboolean showing_error = FALSE; - - if (showing_error || !xmlrpc_server_uri) { - return; - } - - showing_error = TRUE; - - dialog = gtk_message_dialog_new(NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_NONE, - "Connection to %s was lost.", xmlrpc_server_uri); - - gtk_dialog_add_buttons(GTK_DIALOG(dialog), - GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - remote_disconnect_all(ssh_conn != NULL); - cb_local_computer(); - } - - gtk_widget_destroy(dialog); - - showing_error = FALSE; -} - -static gboolean remote_version_is_supported(void) -{ - gint remote_ver; - GtkWidget *dialog; - - shell_status_update("Obtaining remote server API version..."); - remote_ver = - xmlrpc_get_integer(xmlrpc_server_uri, - "server.getAPIVersion", NULL); - - switch (remote_ver) { - case -1: - dialog = gtk_message_dialog_new(NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_NONE, - "Remote host didn't respond. Try again?"); - - gtk_dialog_add_buttons(GTK_DIALOG(dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, - "Try again", GTK_RESPONSE_ACCEPT, NULL); - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - gtk_widget_destroy(dialog); - return remote_version_is_supported(); - } - - gtk_widget_destroy(dialog); - break; - case XMLRPC_SERVER_VERSION: - return TRUE; - default: - dialog = gtk_message_dialog_new(NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Remote Host has an unsupported " - "API version (%d). Expected " - "version is %d.", - remote_ver, XMLRPC_SERVER_VERSION); - - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - } - - return FALSE; -} - -static gchar *remote_module_entry_func() -{ - Shell *shell = shell_get_main_shell(); - gchar *ret; - - ret = - xmlrpc_get_string(xmlrpc_server_uri, - "module.entryFunction", "%s%i", - shell->selected_module->name, - shell->selected->number); - - if (!ret) { - ret = g_strdup(""); - } - - return ret; -} - -static void remote_module_entry_scan_func(gboolean reload) -{ - Shell *shell = shell_get_main_shell(); - - if (reload) { - xmlrpc_get_string(xmlrpc_server_uri, - "module.entryReload", "%s%i", - shell->selected_module->name, - shell->selected->number); - } else { - xmlrpc_get_string(xmlrpc_server_uri, - "module.entryScan", "%s%i", - shell->selected_module->name, - shell->selected->number); - } -} - -static gchar *remote_module_entry_field_func(gchar * entry) -{ - Shell *shell = shell_get_main_shell(); - gchar *ret; - - ret = - xmlrpc_get_string(xmlrpc_server_uri, - "module.entryGetField", "%s%i%s", - shell->selected_module->name, - shell->selected->number, entry); - - if (!ret) { - remote_connection_error(); - } - - return ret; -} - -static gchar *remote_module_entry_more_func(gchar * entry) -{ - Shell *shell = shell_get_main_shell(); - gchar *ret; - - ret = - xmlrpc_get_string(xmlrpc_server_uri, - "module.entryGetMoreInfo", "%s%i%s", - shell->selected_module->name, - shell->selected->number, entry); - - if (!ret) { - remote_connection_error(); - } - - return ret; -} - -static gchar *remote_module_entry_note_func(gint entry) -{ - Shell *shell = shell_get_main_shell(); - gchar *note; - - note = - xmlrpc_get_string(xmlrpc_server_uri, - "module.entryGetNote", "%s%i", - shell->selected_module->name, - shell->selected->number); - - if (note && *note == '\0') { - g_free(note); - return NULL; - } - - return note; -} - -static ModuleAbout *remote_module_get_about() -{ - return NULL; -} - -static gboolean load_module_list() -{ - Shell *shell; - GValueArray *modules; - int i = 0; - - shell_status_update("Unloading local modules..."); - module_unload_all(); - - shell_status_update("Obtaining remote server module list..."); - modules = - xmlrpc_get_array(xmlrpc_server_uri, "module.getModuleList", NULL); - if (!modules) { - return FALSE; - } - - shell = shell_get_main_shell(); - - for (; i < modules->n_values; i++) { - ShellModule *m; - ShellModuleEntry *e; - GValueArray *entries, *module; - int j = 0; - - module = g_value_get_boxed(&modules->values[i]); - - m = g_new0(ShellModule, 1); - m->name = g_strdup(g_value_get_string(&module->values[0])); - m->icon = - icon_cache_get_pixbuf(g_value_get_string(&module->values[1])); - m->aboutfunc = (gpointer) remote_module_get_about; - - shell_status_pulse(); - entries = xmlrpc_get_array(xmlrpc_server_uri, - "module.getEntryList", "%s", m->name); - if (entries && entries->n_values > 0) { - for (; j < entries->n_values; j++) { - GValueArray *tuple = - g_value_get_boxed(&entries->values[j]); - - e = g_new0(ShellModuleEntry, 1); - e->name = g_strdup(g_value_get_string(&tuple->values[0])); - e->icon = - icon_cache_get_pixbuf(g_value_get_string - (&tuple->values[1])); - e->icon_file = - g_strdup(g_value_get_string(&tuple->values[1])); - e->number = j; - - e->func = remote_module_entry_func; - e->scan_func = remote_module_entry_scan_func; - e->fieldfunc = remote_module_entry_field_func; - e->morefunc = remote_module_entry_more_func; - e->notefunc = remote_module_entry_note_func; - - m->entries = g_slist_append(m->entries, e); - - shell_status_pulse(); - } - - g_value_array_free(entries); - - shell->tree->modules = g_slist_append(shell->tree->modules, m); - } else { - g_free(m->name); - g_free(m); - } - } - - g_slist_foreach(shell->tree->modules, shell_add_modules_to_gui, - shell->tree); - gtk_tree_view_expand_all(GTK_TREE_VIEW(shell->tree->view)); - - g_value_array_free(modules); - - return TRUE; -} - -static gboolean remote_connect_direct(gchar * hostname, gint port) -{ - gboolean retval = FALSE; - - remote_disconnect_all(FALSE); - - xmlrpc_init(); - xmlrpc_server_uri = - g_strdup_printf("http://%s:%d/xmlrpc", hostname, port); - - shell_view_set_enabled(FALSE); - - if (remote_version_is_supported()) { - if (!load_module_list()) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new(NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Cannot obtain module list from server."); - - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - } else { - retval = TRUE; - } - } - - shell_status_update("Done."); - shell_view_set_enabled(TRUE); - - return retval; -} - -static gboolean remote_connect_ssh(gchar * hostname, - gint port, - gchar * username, gchar * password) -{ - GtkWidget *dialog; - SSHConnResponse ssh_response; - SoupURI *uri; - gchar *struri; - char buffer[32]; - gboolean error = FALSE; - - remote_disconnect_all(TRUE); - - shell_view_set_enabled(FALSE); - shell_status_update("Establishing SSH tunnel..."); - struri = g_strdup_printf("ssh://%s:%s@%s:%d/?L4343:localhost:4242", - username, password, hostname, port); - uri = soup_uri_new(struri); - ssh_response = ssh_new(uri, &ssh_conn, "hardinfo -x"); - - if (ssh_response != SSH_CONN_OK) { - error = TRUE; - ssh_close(ssh_conn); - } else { - gint res; - gint bytes_read; - - memset(buffer, 0, sizeof(buffer)); - res = - ssh_read(ssh_conn->fd_read, buffer, sizeof(buffer), - &bytes_read); - if (bytes_read != 0 && res == 1) { - if (strncmp(buffer, "XML-RPC server ready", 20) == 0) { - DEBUG("%s", buffer); - - if (remote_connect_direct("127.0.0.1", 4343)) { - DEBUG("connected! :)"); - goto out; - } - - DEBUG("unknown error while trying to connect... wtf?"); - } - - /* TODO FIXME Perhaps the server is already running; try to fix */ - DEBUG("hardinfo already running there?"); - } - - error = TRUE; - } - - out: - if (error) { - dialog = gtk_message_dialog_new_with_markup(NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Cannot establish tunnel.\n" - "%s\n\n" - "Please verify that:\n" - "\342\200\242 The hostname %s is correct;\n" - "\342\200\242 There is a SSH server running on port %d;\n" - "\342\200\242 Your username/password combination is correct.", - ssh_response == - SSH_CONN_OK ? "" : - ssh_conn_errors - [ssh_response], - hostname, port); - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - - ssh_close(ssh_conn); - ssh_conn = NULL; - } - - soup_uri_free(uri); - g_free(struri); - shell_view_set_enabled(TRUE); - shell_status_update("Done."); - - return !error; -} - -gboolean remote_connect_host(gchar * hostname) -{ - Shell *shell = shell_get_main_shell(); - gboolean retval = FALSE; - - if (!g_key_file_has_group(shell->hosts, hostname)) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new(NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Internal error."); - - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - } else { - const gint port = - g_key_file_get_integer(shell->hosts, hostname, "port", NULL); - gchar *type = - g_key_file_get_string(shell->hosts, hostname, "type", NULL); - - if (g_str_equal(type, "ssh")) { - gchar *username = - g_key_file_get_string(shell->hosts, hostname, "username", - NULL); - gchar *password = - g_key_file_get_string(shell->hosts, hostname, "password", - NULL); - - retval = - remote_connect_ssh(hostname, port, username, password); - - g_free(username); - g_free(password); - } else { - retval = remote_connect_direct(hostname, port); - } - - g_free(type); - } - - return retval; -} - -void connect_dialog_show(GtkWidget * parent) -{ - HostDialog *he = - host_dialog_new(parent, "Connect to", HOST_DIALOG_MODE_CONNECT); - - if (gtk_dialog_run(GTK_DIALOG(he->dialog)) == GTK_RESPONSE_ACCEPT) { - gboolean connected; - gchar *hostname = - (gchar *) gtk_entry_get_text(GTK_ENTRY(he->txt_hostname)); - const gint selected_type = - gtk_combo_box_get_active(GTK_COMBO_BOX(he->cmb_type)); - const gint port = - (int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(he->txt_port)); - - gtk_widget_set_sensitive(he->dialog, FALSE); - - if (selected_type == 1) { - gchar *username = - (gchar *) gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_user)); - gchar *password = - (gchar *) - gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_password)); - - connected = - remote_connect_ssh(hostname, port, username, password); - } else { - connected = remote_connect_direct(hostname, port); - } - - if (connected) { - Shell *shell = shell_get_main_shell(); - gchar *tmp; - - tmp = g_strdup_printf("Remote: %s", hostname); - shell_set_remote_label(shell, tmp); - - g_free(tmp); - } else { - cb_local_computer(); - } - } - - host_dialog_destroy(he); -} - -void host_manager_show(GtkWidget * parent) -{ - HostManager *rd = host_manager_new(parent); - - gtk_dialog_run(GTK_DIALOG(rd->dialog)); - - host_manager_destroy(rd); -} - -static void populate_store(HostManager * rd, GtkListStore * store) -{ - Shell *shell; - GtkTreeIter iter; - gchar **hosts; - gint i; - gsize no_groups; - - gtk_list_store_clear(store); - shell = shell_get_main_shell(); - - hosts = g_key_file_get_groups(shell->hosts, &no_groups); - DEBUG("%d hosts found", no_groups); - for (i = 0; i < no_groups; i++) { - gchar *icon; - - DEBUG("host #%d: %s", i, hosts[i]); - - icon = g_key_file_get_string(shell->hosts, hosts[i], "icon", NULL); - - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, - 0, - icon_cache_get_pixbuf(icon ? icon : - "server.png"), 1, - g_strdup(hosts[i]), 2, GINT_TO_POINTER(i), -1); - - g_free(icon); - } - - g_strfreev(hosts); -} - -static GtkTreeModel *host_dialog_get_completion_model(void) -{ - Shell *shell; - GtkListStore *store; - GtkTreeIter iter; - gchar **groups; - gint i = 0; - - shell = shell_get_main_shell(); - - store = gtk_list_store_new(1, G_TYPE_STRING); - for (groups = g_key_file_get_groups(shell->hosts, NULL); groups[i]; - i++) { - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, 0, g_strdup(groups[i]), -1); - } - g_strfreev(groups); - - return GTK_TREE_MODEL(store); -} - -static void host_combo_changed_cb(GtkComboBox * widget, gpointer user_data) -{ - HostDialog *host_dlg = (HostDialog *) user_data; - const gint default_ports[] = { 4242, 22 }; - gint index; - - index = gtk_combo_box_get_active(widget); - - gtk_notebook_set_current_page(GTK_NOTEBOOK(host_dlg->notebook), index); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(host_dlg->txt_port), - default_ports[index]); - - if (index == 0) { - gtk_widget_hide(host_dlg->frm_options); - } else { - gtk_widget_show(host_dlg->frm_options); - } -} - -static void -host_dialog_hostname_changed (GtkEditable *entry, gpointer user_data) -{ - HostDialog *host_dlg = (HostDialog *)user_data; - GRegex *regex_ip = NULL, *regex_host = NULL; - gboolean match; - const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry)); - - /* - * Regexes from: - * http://stackoverflow.com/questions/106179 - */ - const gchar *valid_ip_regex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|" \ - "25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}" \ - "|2[0-4][0-9]|25[0-5])$"; - const gchar *valid_hostname_regex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9" \ - "\\-]*[a-zA-Z0-9])\\.)*([A-Za-z]|[A-Z" \ - "a-z][A-Za-z0-9\\-]*[A-Za-z0-9])$"; - if (regex_ip == NULL) { - regex_ip = g_regex_new(valid_ip_regex, 0, 0, NULL); - } - - if (regex_host == NULL) { - regex_host = g_regex_new(valid_hostname_regex, 0, 0, NULL); - } - - match = g_regex_match(regex_ip, text, 0, NULL); - if (!match) { - match = g_regex_match(regex_host, text, 0, NULL); - } - - gtk_widget_set_sensitive(host_dlg->btn_accept, match); -} - -static void host_dialog_destroy(HostDialog * rd) -{ - gtk_widget_destroy(rd->dialog); - g_free(rd); -} - -static HostDialog *host_dialog_new(GtkWidget * parent, - gchar * title, HostDialogMode mode) -{ - HostDialog *host_dlg; - GtkWidget *dialog; - GtkWidget *dialog_vbox1; - GtkWidget *vbox1; - GtkWidget *frm_remote_host; - GtkWidget *alignment1; - GtkWidget *table1; - GtkWidget *label2; - GtkWidget *label3; - GtkWidget *label4; - GtkWidget *cmb_type; - GtkWidget *txt_hostname; - GtkWidget *alignment2; - GtkWidget *hbox1; - GtkObject *txt_port_adj; - GtkWidget *txt_port; - GtkWidget *label1; - GtkWidget *frm_options; - GtkWidget *alignment3; - GtkWidget *notebook; - GtkWidget *table2; - GtkWidget *label8; - GtkWidget *label9; - GtkWidget *txt_ssh_user; - GtkWidget *txt_ssh_password; - GtkWidget *label10; - GtkWidget *label5; - GtkWidget *dialog_action_area1; - GtkWidget *btn_cancel; - GtkWidget *btn_save; - GtkEntryCompletion *completion; - GtkTreeModel *completion_model; - - dialog = gtk_dialog_new(); - gtk_window_set_title(GTK_WINDOW(dialog), title); - 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_modal(GTK_WINDOW(dialog), TRUE); - gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); - gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); - gtk_window_set_type_hint(GTK_WINDOW(dialog), - GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_gravity(GTK_WINDOW(dialog), GDK_GRAVITY_CENTER); - - dialog_vbox1 = GTK_DIALOG(dialog)->vbox; - gtk_widget_show(dialog_vbox1); - - vbox1 = gtk_vbox_new(FALSE, 3); - gtk_widget_show(vbox1); - gtk_box_pack_start(GTK_BOX(dialog_vbox1), vbox1, TRUE, TRUE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5); - gtk_box_set_spacing(GTK_BOX(vbox1), 10); - - frm_remote_host = gtk_frame_new(NULL); - gtk_widget_show(frm_remote_host); - gtk_box_pack_start(GTK_BOX(vbox1), frm_remote_host, FALSE, TRUE, 0); - gtk_frame_set_shadow_type(GTK_FRAME(frm_remote_host), GTK_SHADOW_NONE); - - alignment1 = gtk_alignment_new(0.5, 0.5, 1, 1); - gtk_widget_show(alignment1); - gtk_container_add(GTK_CONTAINER(frm_remote_host), alignment1); - gtk_alignment_set_padding(GTK_ALIGNMENT(alignment1), 0, 0, 12, 0); - - table1 = gtk_table_new(3, 2, FALSE); - gtk_widget_show(table1); - gtk_container_add(GTK_CONTAINER(alignment1), table1); - gtk_table_set_row_spacings(GTK_TABLE(table1), 4); - gtk_table_set_col_spacings(GTK_TABLE(table1), 4); - - label2 = gtk_label_new("Protocol:"); - gtk_widget_show(label2); - gtk_table_attach(GTK_TABLE(table1), label2, 0, 1, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment(GTK_MISC(label2), 0, 0.5); - - label3 = gtk_label_new("Host:"); - gtk_widget_show(label3); - gtk_table_attach(GTK_TABLE(table1), label3, 0, 1, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment(GTK_MISC(label3), 0, 0.5); - - label4 = gtk_label_new("Port:"); - gtk_widget_show(label4); - gtk_table_attach(GTK_TABLE(table1), label4, 0, 1, 2, 3, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment(GTK_MISC(label4), 0, 0.5); - - cmb_type = gtk_combo_box_new_text(); - gtk_widget_show(cmb_type); - gtk_table_attach(GTK_TABLE(table1), cmb_type, 1, 2, 0, 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_type), - "Direct connection"); - gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_type), - "Remote tunnel over SSH"); - - txt_hostname = gtk_entry_new(); - gtk_widget_show(txt_hostname); - gtk_table_attach(GTK_TABLE(table1), txt_hostname, 1, 2, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - - alignment2 = gtk_alignment_new(0.5, 0.5, 1, 1); - gtk_widget_show(alignment2); - gtk_table_attach(GTK_TABLE(table1), alignment2, 1, 2, 2, 3, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - - hbox1 = gtk_hbox_new(FALSE, 0); - gtk_widget_show(hbox1); - gtk_container_add(GTK_CONTAINER(alignment2), hbox1); - - txt_port_adj = gtk_adjustment_new(4242, 1, 65535, 1, 10, 0); - txt_port = gtk_spin_button_new(GTK_ADJUSTMENT(txt_port_adj), 1, 0); - gtk_widget_show(txt_port); - gtk_box_pack_start(GTK_BOX(hbox1), txt_port, FALSE, TRUE, 0); - - label1 = gtk_label_new("Remote host"); - gtk_widget_show(label1); - gtk_frame_set_label_widget(GTK_FRAME(frm_remote_host), label1); - gtk_label_set_use_markup(GTK_LABEL(label1), TRUE); - - frm_options = gtk_frame_new(NULL); - gtk_widget_show(frm_options); - gtk_box_pack_start(GTK_BOX(vbox1), frm_options, FALSE, TRUE, 0); - gtk_frame_set_shadow_type(GTK_FRAME(frm_options), GTK_SHADOW_NONE); - - alignment3 = gtk_alignment_new(0.5, 0.5, 1, 1); - gtk_widget_show(alignment3); - gtk_container_add(GTK_CONTAINER(frm_options), alignment3); - gtk_alignment_set_padding(GTK_ALIGNMENT(alignment3), 0, 0, 12, 0); - - notebook = gtk_notebook_new(); - gtk_widget_show(notebook); - gtk_container_add(GTK_CONTAINER(alignment3), notebook); - GTK_WIDGET_UNSET_FLAGS(notebook, GTK_CAN_FOCUS); - gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE); - gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), FALSE); - - label10 = gtk_label_new(""); - gtk_widget_show(label10); - gtk_container_add(GTK_CONTAINER(notebook), label10); - gtk_label_set_use_markup(GTK_LABEL(label10), TRUE); - - table2 = gtk_table_new(2, 2, FALSE); - gtk_widget_show(table2); - gtk_container_add(GTK_CONTAINER(notebook), table2); - gtk_table_set_row_spacings(GTK_TABLE(table2), 4); - gtk_table_set_col_spacings(GTK_TABLE(table2), 4); - - label8 = gtk_label_new("User:"); - gtk_widget_show(label8); - gtk_table_attach(GTK_TABLE(table2), label8, 0, 1, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment(GTK_MISC(label8), 0, 0.5); - - label9 = gtk_label_new("Password:"); - gtk_widget_show(label9); - gtk_table_attach(GTK_TABLE(table2), label9, 0, 1, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment(GTK_MISC(label9), 0, 0.5); - - txt_ssh_user = gtk_entry_new(); - gtk_widget_show(txt_ssh_user); - gtk_table_attach(GTK_TABLE(table2), txt_ssh_user, 1, 2, 0, 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - - txt_ssh_password = gtk_entry_new(); - gtk_widget_show(txt_ssh_password); - gtk_table_attach(GTK_TABLE(table2), txt_ssh_password, 1, 2, 1, 2, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_entry_set_invisible_char(GTK_ENTRY(txt_ssh_password), 9679); - gtk_entry_set_visibility(GTK_ENTRY(txt_ssh_password), FALSE); - - label5 = gtk_label_new("Connection options"); - gtk_widget_show(label5); - gtk_frame_set_label_widget(GTK_FRAME(frm_options), label5); - gtk_label_set_use_markup(GTK_LABEL(label5), TRUE); - - dialog_action_area1 = GTK_DIALOG(dialog)->action_area; - gtk_widget_show(dialog_action_area1); - gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog_action_area1), - GTK_BUTTONBOX_END); - - btn_cancel = gtk_button_new_from_stock("gtk-cancel"); - gtk_widget_show(btn_cancel); - gtk_dialog_add_action_widget(GTK_DIALOG(dialog), btn_cancel, - GTK_RESPONSE_CANCEL); - GTK_WIDGET_SET_FLAGS(btn_cancel, GTK_CAN_DEFAULT); - - if (mode == HOST_DIALOG_MODE_EDIT) { - btn_save = gtk_button_new_from_stock(GTK_STOCK_SAVE); - } else if (mode == HOST_DIALOG_MODE_CONNECT) { - btn_save = gtk_button_new_from_stock(GTK_STOCK_CONNECT); - } - - gtk_widget_show(btn_save); - gtk_dialog_add_action_widget(GTK_DIALOG(dialog), btn_save, - GTK_RESPONSE_ACCEPT); - GTK_WIDGET_SET_FLAGS(btn_save, GTK_CAN_DEFAULT); - - host_dlg = g_new0(HostDialog, 1); - host_dlg->dialog = dialog; - host_dlg->notebook = notebook; - host_dlg->txt_hostname = txt_hostname; - host_dlg->txt_port = txt_port; - host_dlg->txt_ssh_user = txt_ssh_user; - host_dlg->txt_ssh_password = txt_ssh_password; - host_dlg->cmb_type = cmb_type; - host_dlg->frm_options = frm_options; - host_dlg->btn_accept = btn_save; - host_dlg->btn_cancel = btn_cancel; - - completion = gtk_entry_completion_new(); - gtk_entry_set_completion(GTK_ENTRY(host_dlg->txt_hostname), completion); - g_object_unref(completion); - - completion_model = host_dialog_get_completion_model(); - gtk_entry_completion_set_model(completion, completion_model); - g_object_unref(completion_model); - - gtk_entry_completion_set_text_column(completion, 0); - - gtk_combo_box_set_active(GTK_COMBO_BOX(host_dlg->cmb_type), 0); - - g_signal_connect(G_OBJECT(txt_hostname), "changed", - G_CALLBACK(host_dialog_hostname_changed), host_dlg); - g_signal_connect(G_OBJECT(cmb_type), "changed", - G_CALLBACK(host_combo_changed_cb), host_dlg); - - host_combo_changed_cb(GTK_COMBO_BOX(cmb_type), host_dlg); - host_dialog_hostname_changed(GTK_EDITABLE(txt_hostname), host_dlg); - - gtk_entry_set_activates_default(GTK_ENTRY(txt_hostname), TRUE); - - return host_dlg; -} - -static void host_manager_add(GtkWidget * button, gpointer data) -{ - Shell *shell = shell_get_main_shell(); - HostManager *rd = (HostManager *) data; - HostDialog *he = - host_dialog_new(rd->dialog, "Add a host", HOST_DIALOG_MODE_EDIT); - - retry: - if (gtk_dialog_run(GTK_DIALOG(he->dialog)) == GTK_RESPONSE_ACCEPT) { - const gchar *hostname = - gtk_entry_get_text(GTK_ENTRY(he->txt_hostname)); - - if (g_key_file_has_group(shell->hosts, hostname)) { - GtkWidget *dialog; - - dialog = - gtk_message_dialog_new_with_markup(GTK_WINDOW(rd->dialog), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Hostname %s already exists.", - hostname); - - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - - goto retry; - } else { - GtkTreeIter iter; - const gchar *type[] = { "direct", "ssh" }; - const gint selected_type = - gtk_combo_box_get_active(GTK_COMBO_BOX(he->cmb_type)); - const gint port = - (int) - gtk_spin_button_get_value(GTK_SPIN_BUTTON(he->txt_port)); - - g_key_file_set_string(shell->hosts, hostname, "type", - type[selected_type]); - g_key_file_set_integer(shell->hosts, hostname, "port", port); - - if (selected_type == 1) { - const gchar *username = - gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_user)); - const gchar *password = - gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_password)); - - g_key_file_set_string(shell->hosts, hostname, "username", - username); - g_key_file_set_string(shell->hosts, hostname, "password", - password); - } - - gtk_list_store_append(rd->tree_store, &iter); - gtk_list_store_set(rd->tree_store, &iter, - 0, icon_cache_get_pixbuf("server.png"), - 1, g_strdup(hostname), 2, 0, -1); - } - } - - host_dialog_destroy(he); -} - -static void host_manager_edit(GtkWidget * button, gpointer data) -{ - Shell *shell = shell_get_main_shell(); - GtkWidget *dialog; - HostManager *rd = (HostManager *) data; - HostDialog *he = - host_dialog_new(rd->dialog, "Edit a host", HOST_DIALOG_MODE_EDIT); - gchar *host_type; - gchar *previous_hostname; - gint host_port; - - host_type = - g_key_file_get_string(shell->hosts, rd->selected_name, "type", - NULL); - if (!host_type || g_str_equal(host_type, "direct")) { - gtk_combo_box_set_active(GTK_COMBO_BOX(he->cmb_type), 0); - } else if (g_str_equal(host_type, "ssh")) { - gchar *username, *password; - - gtk_combo_box_set_active(GTK_COMBO_BOX(he->cmb_type), 1); - - username = - g_key_file_get_string(shell->hosts, rd->selected_name, - "username", NULL); - if (username) { - gtk_entry_set_text(GTK_ENTRY(he->txt_ssh_user), username); - g_free(username); - } - - password = - g_key_file_get_string(shell->hosts, rd->selected_name, - "password", NULL); - if (password) { - gtk_entry_set_text(GTK_ENTRY(he->txt_ssh_password), password); - g_free(password); - } - } else { - dialog = gtk_message_dialog_new(GTK_WINDOW(rd->dialog), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Host has invalid type(%s).", - host_type); - - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - - goto bad; - } - - gtk_entry_set_text(GTK_ENTRY(he->txt_hostname), rd->selected_name); - previous_hostname = rd->selected_name; - - host_port = - g_key_file_get_integer(shell->hosts, rd->selected_name, "port", - NULL); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(he->txt_port), - host_port ? host_port : 4242); - - if (gtk_dialog_run(GTK_DIALOG(he->dialog)) == GTK_RESPONSE_ACCEPT) { - const gchar *type[] = { "direct", "ssh" }; - const gint selected_type = - gtk_combo_box_get_active(GTK_COMBO_BOX(he->cmb_type)); - const gint port = - (int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(he->txt_port)); - const gchar *hostname = - gtk_entry_get_text(GTK_ENTRY(he->txt_hostname)); - - if (!g_str_equal(previous_hostname, he->txt_hostname)) { - g_key_file_remove_group(shell->hosts, previous_hostname, NULL); - gtk_list_store_set(rd->tree_store, rd->selected_iter, - 1, g_strdup(hostname), -1); - } - - g_key_file_set_string(shell->hosts, hostname, "type", - type[selected_type]); - g_key_file_set_integer(shell->hosts, hostname, "port", port); - - if (selected_type == 1) { - const gchar *username = - gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_user)); - const gchar *password = - gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_password)); - - g_key_file_set_string(shell->hosts, hostname, "username", - username); - g_key_file_set_string(shell->hosts, hostname, "password", - password); - } - } - - bad: - host_dialog_destroy(he); - g_free(host_type); -} - -static void host_manager_remove(GtkWidget * button, gpointer data) -{ - Shell *shell = shell_get_main_shell(); - HostManager *rd = (HostManager *) data; - GtkWidget *dialog; - - dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(rd->dialog), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - "Remove the host %s?", - rd->selected_name); - - gtk_dialog_add_buttons(GTK_DIALOG(dialog), - GTK_STOCK_NO, GTK_RESPONSE_REJECT, - GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT, NULL); - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - g_key_file_remove_group(shell->hosts, rd->selected_name, NULL); - gtk_list_store_remove(rd->tree_store, rd->selected_iter); - - gtk_widget_set_sensitive(rd->btn_edit, FALSE); - gtk_widget_set_sensitive(rd->btn_remove, FALSE); - } - - gtk_widget_destroy(dialog); -} - -static void host_manager_tree_sel_changed(GtkTreeSelection * sel, - gpointer data) -{ - HostManager *rd = (HostManager *) data; - GtkTreeModel *model; - GtkTreeIter iter; - - if (gtk_tree_selection_get_selected(sel, &model, &iter)) { - gchar *name; - gint id; - - gtk_tree_model_get(model, &iter, 1, &name, 2, &id, -1); - - if (id != -1) { - gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_edit), TRUE); - gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_remove), TRUE); - } else { - gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_edit), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_remove), FALSE); - } - - g_free(rd->selected_name); - - if (rd->selected_iter) - gtk_tree_iter_free(rd->selected_iter); - - rd->selected_id = id; - rd->selected_name = name; - rd->selected_iter = gtk_tree_iter_copy(&iter); - } -} - -static void host_manager_destroy(HostManager * rd) -{ - shell_save_hosts_file(); - shell_update_remote_menu(); - gtk_widget_destroy(rd->dialog); - - g_free(rd); -} - -static HostManager *host_manager_new(GtkWidget * parent) -{ - HostManager *rd; - GtkWidget *dialog; - GtkWidget *dialog_vbox; - GtkWidget *scrolledwindow; - GtkWidget *treeview; - GtkWidget *vbuttonbox; - GtkWidget *btn_add; - GtkWidget *btn_edit; - GtkWidget *dialog_action_area; - GtkWidget *btn_cancel; - GtkWidget *btn_remove; - GtkWidget *hbox; - GtkTreeSelection *sel; - GtkTreeViewColumn *column; - GtkCellRenderer *cr_text, *cr_pbuf; - GtkListStore *store; - GtkTreeModel *model; - - rd = g_new0(HostManager, 1); - - dialog = gtk_dialog_new(); - gtk_window_set_title(GTK_WINDOW(dialog), "Remote Host Manager"); - 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); - - dialog_vbox = GTK_DIALOG(dialog)->vbox; - gtk_box_set_spacing(GTK_BOX(dialog_vbox), 5); - gtk_container_set_border_width(GTK_CONTAINER(dialog_vbox), 4); - gtk_widget_show(dialog_vbox); - - hbox = gtk_hbox_new(FALSE, 5); - gtk_box_pack_start(GTK_BOX(dialog_vbox), hbox, TRUE, TRUE, 0); - gtk_widget_show(hbox); - - scrolledwindow = gtk_scrolled_window_new(NULL, NULL); - gtk_widget_show(scrolledwindow); - gtk_box_pack_start(GTK_BOX(hbox), scrolledwindow, TRUE, TRUE, 0); - gtk_widget_set_size_request(scrolledwindow, -1, 200); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW - (scrolledwindow), GTK_SHADOW_IN); - - store = - gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT); - 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_widget_show(treeview); - gtk_container_add(GTK_CONTAINER(scrolledwindow), treeview); - gtk_tree_view_set_reorderable(GTK_TREE_VIEW(treeview), TRUE); - - column = gtk_tree_view_column_new(); - gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); - - 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); - - vbuttonbox = gtk_vbutton_box_new(); - gtk_widget_show(vbuttonbox); - gtk_box_pack_start(GTK_BOX(hbox), vbuttonbox, FALSE, TRUE, 0); - gtk_box_set_spacing(GTK_BOX(vbuttonbox), 5); - gtk_button_box_set_layout(GTK_BUTTON_BOX(vbuttonbox), - GTK_BUTTONBOX_START); - - btn_add = gtk_button_new_with_mnemonic("_Add"); - gtk_widget_show(btn_add); - gtk_container_add(GTK_CONTAINER(vbuttonbox), btn_add); - GTK_WIDGET_SET_FLAGS(btn_add, GTK_CAN_DEFAULT); - g_signal_connect(btn_add, "clicked", G_CALLBACK(host_manager_add), rd); - - btn_edit = gtk_button_new_with_mnemonic("_Edit"); - gtk_widget_show(btn_edit); - gtk_container_add(GTK_CONTAINER(vbuttonbox), btn_edit); - GTK_WIDGET_SET_FLAGS(btn_edit, GTK_CAN_DEFAULT); - g_signal_connect(btn_edit, "clicked", G_CALLBACK(host_manager_edit), - rd); - - btn_remove = gtk_button_new_with_mnemonic("_Remove"); - gtk_widget_show(btn_remove); - gtk_container_add(GTK_CONTAINER(vbuttonbox), btn_remove); - GTK_WIDGET_SET_FLAGS(btn_remove, GTK_CAN_DEFAULT); - g_signal_connect(btn_remove, "clicked", - G_CALLBACK(host_manager_remove), rd); - - dialog_action_area = GTK_DIALOG(dialog)->action_area; - gtk_widget_show(dialog_action_area); - gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog_action_area), - GTK_BUTTONBOX_END); - - btn_cancel = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_widget_show(btn_cancel); - gtk_dialog_add_action_widget(GTK_DIALOG(dialog), btn_cancel, - GTK_RESPONSE_CANCEL); - GTK_WIDGET_SET_FLAGS(btn_cancel, GTK_CAN_DEFAULT); - - gtk_tree_view_collapse_all(GTK_TREE_VIEW(treeview)); - - sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); - - g_signal_connect(G_OBJECT(sel), "changed", - (GCallback) host_manager_tree_sel_changed, rd); - - rd->dialog = dialog; - rd->btn_cancel = btn_cancel; - rd->btn_add = btn_add; - rd->btn_edit = btn_edit; - rd->btn_remove = btn_remove; - rd->tree_store = store; - - populate_store(rd, store); - gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_edit), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_remove), FALSE); - - return rd; -} - -#endif /* HAS_LIBSOUP */ diff --git a/hardinfo2/remote.h b/hardinfo2/remote.h deleted file mode 100644 index 6a988a3b..00000000 --- a/hardinfo2/remote.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Remote Client - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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/hardinfo2/remote/remote.c b/hardinfo2/remote/remote.c new file mode 100644 index 00000000..d266735d --- /dev/null +++ b/hardinfo2/remote/remote.c @@ -0,0 +1,1307 @@ +/* + * Remote Client + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 +#include + +#include "config.h" + +#ifdef HAS_LIBSOUP + +#include "shell.h" +#include "callbacks.h" +#include "iconcache.h" +#include "hardinfo.h" +#include "xmlrpc-client.h" +#include "ssh-conn.h" + +#define XMLRPC_SERVER_VERSION 1 + +/* + * TODO + * + * - Add hi_deinit() to modules (so they can free up their memory) + * - Import / Export host list + * - Detect machines on local network that runs SSH + * - IP range scan + * - mDNS + * - Allow the user to add/remove/edit a machine + * - Use ~/.ssh/known_hosts as a starting point? + * - Different icons for different machines? + * - Make sure SSH can do port forwarding + * - Make sure the remote host has HardInfo installed + * - Generate a random username/password to be passed to the XML-RPC server; use + * that username/password on the client; this is just to make sure nobody on the + * machine will be allowed to obtain information that might be sensitive. This + * will be passed with base64, so it can be sniffed; this needs root access anyway, + * so not really a problem. + * - Determine if we're gonna use GIOChannels or create a communication thread + * - Introduce a flag on the modules, stating their ability to be used locally/remotely + * (Benchmarks can't be used remotely; Displays won't work remotely [unless we use + * X forwarding, but that'll be local X11 info anyway]). + */ + +typedef struct _HostManager HostManager; +typedef struct _HostDialog HostDialog; + +typedef enum { + HOST_DIALOG_MODE_EDIT, + HOST_DIALOG_MODE_CONNECT +} HostDialogMode; + +struct _HostManager { + GtkWidget *dialog; + GtkWidget *btn_connect, *btn_cancel; + GtkWidget *btn_add, *btn_edit, *btn_remove; + + GtkListStore *tree_store; + + gint selected_id; + gchar *selected_name; + GtkTreeIter *selected_iter; +}; + +struct _HostDialog { + GtkWidget *dialog; + GtkWidget *notebook; + + GtkWidget *txt_hostname, *txt_port; + GtkWidget *txt_ssh_user, *txt_ssh_password; + + GtkWidget *cmb_type; + + GtkWidget *frm_options; + GtkWidget *btn_accept, *btn_cancel; +}; + +static HostManager *host_manager_new(GtkWidget * parent); +static void host_manager_destroy(HostManager * rd); +static HostDialog *host_dialog_new(GtkWidget * parent, + gchar * title, HostDialogMode mode); +static void host_dialog_destroy(HostDialog * hd); + + +static gchar *xmlrpc_server_uri = NULL; +static SSHConn *ssh_conn = NULL; + +void remote_disconnect_all(gboolean ssh) +{ + if (ssh && ssh_conn) { + ssh_close(ssh_conn); + ssh_conn = NULL; + } + + if (xmlrpc_server_uri) { + g_free(xmlrpc_server_uri); + xmlrpc_server_uri = NULL; + } +} + +static void remote_connection_error(void) +{ + GtkWidget *dialog; + static gboolean showing_error = FALSE; + + if (showing_error || !xmlrpc_server_uri) { + return; + } + + showing_error = TRUE; + + dialog = gtk_message_dialog_new(NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_NONE, + "Connection to %s was lost.", xmlrpc_server_uri); + + gtk_dialog_add_buttons(GTK_DIALOG(dialog), + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { + remote_disconnect_all(ssh_conn != NULL); + cb_local_computer(); + } + + gtk_widget_destroy(dialog); + + showing_error = FALSE; +} + +static gboolean remote_version_is_supported(void) +{ + gint remote_ver; + GtkWidget *dialog; + + shell_status_update("Obtaining remote server API version..."); + remote_ver = + xmlrpc_get_integer(xmlrpc_server_uri, + "server.getAPIVersion", NULL); + + switch (remote_ver) { + case -1: + dialog = gtk_message_dialog_new(NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_NONE, + "Remote host didn't respond. Try again?"); + + gtk_dialog_add_buttons(GTK_DIALOG(dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + "Try again", GTK_RESPONSE_ACCEPT, NULL); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { + gtk_widget_destroy(dialog); + return remote_version_is_supported(); + } + + gtk_widget_destroy(dialog); + break; + case XMLRPC_SERVER_VERSION: + return TRUE; + default: + dialog = gtk_message_dialog_new(NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Remote Host has an unsupported " + "API version (%d). Expected " + "version is %d.", + remote_ver, XMLRPC_SERVER_VERSION); + + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + } + + return FALSE; +} + +static gchar *remote_module_entry_func() +{ + Shell *shell = shell_get_main_shell(); + gchar *ret; + + ret = + xmlrpc_get_string(xmlrpc_server_uri, + "module.entryFunction", "%s%i", + shell->selected_module->name, + shell->selected->number); + + if (!ret) { + ret = g_strdup(""); + } + + return ret; +} + +static void remote_module_entry_scan_func(gboolean reload) +{ + Shell *shell = shell_get_main_shell(); + + if (reload) { + xmlrpc_get_string(xmlrpc_server_uri, + "module.entryReload", "%s%i", + shell->selected_module->name, + shell->selected->number); + } else { + xmlrpc_get_string(xmlrpc_server_uri, + "module.entryScan", "%s%i", + shell->selected_module->name, + shell->selected->number); + } +} + +static gchar *remote_module_entry_field_func(gchar * entry) +{ + Shell *shell = shell_get_main_shell(); + gchar *ret; + + ret = + xmlrpc_get_string(xmlrpc_server_uri, + "module.entryGetField", "%s%i%s", + shell->selected_module->name, + shell->selected->number, entry); + + if (!ret) { + remote_connection_error(); + } + + return ret; +} + +static gchar *remote_module_entry_more_func(gchar * entry) +{ + Shell *shell = shell_get_main_shell(); + gchar *ret; + + ret = + xmlrpc_get_string(xmlrpc_server_uri, + "module.entryGetMoreInfo", "%s%i%s", + shell->selected_module->name, + shell->selected->number, entry); + + if (!ret) { + remote_connection_error(); + } + + return ret; +} + +static gchar *remote_module_entry_note_func(gint entry) +{ + Shell *shell = shell_get_main_shell(); + gchar *note; + + note = + xmlrpc_get_string(xmlrpc_server_uri, + "module.entryGetNote", "%s%i", + shell->selected_module->name, + shell->selected->number); + + if (note && *note == '\0') { + g_free(note); + return NULL; + } + + return note; +} + +static ModuleAbout *remote_module_get_about() +{ + return NULL; +} + +static gboolean load_module_list() +{ + Shell *shell; + GValueArray *modules; + int i = 0; + + shell_status_update("Unloading local modules..."); + module_unload_all(); + + shell_status_update("Obtaining remote server module list..."); + modules = + xmlrpc_get_array(xmlrpc_server_uri, "module.getModuleList", NULL); + if (!modules) { + return FALSE; + } + + shell = shell_get_main_shell(); + + for (; i < modules->n_values; i++) { + ShellModule *m; + ShellModuleEntry *e; + GValueArray *entries, *module; + int j = 0; + + module = g_value_get_boxed(&modules->values[i]); + + m = g_new0(ShellModule, 1); + m->name = g_strdup(g_value_get_string(&module->values[0])); + m->icon = + icon_cache_get_pixbuf(g_value_get_string(&module->values[1])); + m->aboutfunc = (gpointer) remote_module_get_about; + + shell_status_pulse(); + entries = xmlrpc_get_array(xmlrpc_server_uri, + "module.getEntryList", "%s", m->name); + if (entries && entries->n_values > 0) { + for (; j < entries->n_values; j++) { + GValueArray *tuple = + g_value_get_boxed(&entries->values[j]); + + e = g_new0(ShellModuleEntry, 1); + e->name = g_strdup(g_value_get_string(&tuple->values[0])); + e->icon = + icon_cache_get_pixbuf(g_value_get_string + (&tuple->values[1])); + e->icon_file = + g_strdup(g_value_get_string(&tuple->values[1])); + e->number = j; + + e->func = remote_module_entry_func; + e->scan_func = remote_module_entry_scan_func; + e->fieldfunc = remote_module_entry_field_func; + e->morefunc = remote_module_entry_more_func; + e->notefunc = remote_module_entry_note_func; + + m->entries = g_slist_append(m->entries, e); + + shell_status_pulse(); + } + + g_value_array_free(entries); + + shell->tree->modules = g_slist_append(shell->tree->modules, m); + } else { + g_free(m->name); + g_free(m); + } + } + + g_slist_foreach(shell->tree->modules, shell_add_modules_to_gui, + shell->tree); + gtk_tree_view_expand_all(GTK_TREE_VIEW(shell->tree->view)); + + g_value_array_free(modules); + + return TRUE; +} + +static gboolean remote_connect_direct(gchar * hostname, gint port) +{ + gboolean retval = FALSE; + + remote_disconnect_all(FALSE); + + xmlrpc_init(); + xmlrpc_server_uri = + g_strdup_printf("http://%s:%d/xmlrpc", hostname, port); + + shell_view_set_enabled(FALSE); + + if (remote_version_is_supported()) { + if (!load_module_list()) { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new(NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Cannot obtain module list from server."); + + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + } else { + retval = TRUE; + } + } + + shell_status_update("Done."); + shell_view_set_enabled(TRUE); + + return retval; +} + +static gboolean remote_connect_ssh(gchar * hostname, + gint port, + gchar * username, gchar * password) +{ + GtkWidget *dialog; + SSHConnResponse ssh_response; + SoupURI *uri; + gchar *struri; + char buffer[32]; + gboolean error = FALSE; + + remote_disconnect_all(TRUE); + + shell_view_set_enabled(FALSE); + shell_status_update("Establishing SSH tunnel..."); + struri = g_strdup_printf("ssh://%s:%s@%s:%d/?L4343:localhost:4242", + username, password, hostname, port); + uri = soup_uri_new(struri); + ssh_response = ssh_new(uri, &ssh_conn, "hardinfo -x"); + + if (ssh_response != SSH_CONN_OK) { + error = TRUE; + ssh_close(ssh_conn); + } else { + gint res; + gint bytes_read; + + memset(buffer, 0, sizeof(buffer)); + res = + ssh_read(ssh_conn->fd_read, buffer, sizeof(buffer), + &bytes_read); + if (bytes_read != 0 && res == 1) { + if (strncmp(buffer, "XML-RPC server ready", 20) == 0) { + DEBUG("%s", buffer); + + if (remote_connect_direct("127.0.0.1", 4343)) { + DEBUG("connected! :)"); + goto out; + } + + DEBUG("unknown error while trying to connect... wtf?"); + } + + /* TODO FIXME Perhaps the server is already running; try to fix */ + DEBUG("hardinfo already running there?"); + } + + error = TRUE; + } + + out: + if (error) { + dialog = gtk_message_dialog_new_with_markup(NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Cannot establish tunnel.\n" + "%s\n\n" + "Please verify that:\n" + "\342\200\242 The hostname %s is correct;\n" + "\342\200\242 There is a SSH server running on port %d;\n" + "\342\200\242 Your username/password combination is correct.", + ssh_response == + SSH_CONN_OK ? "" : + ssh_conn_errors + [ssh_response], + hostname, port); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + ssh_close(ssh_conn); + ssh_conn = NULL; + } + + soup_uri_free(uri); + g_free(struri); + shell_view_set_enabled(TRUE); + shell_status_update("Done."); + + return !error; +} + +gboolean remote_connect_host(gchar * hostname) +{ + Shell *shell = shell_get_main_shell(); + gboolean retval = FALSE; + + if (!g_key_file_has_group(shell->hosts, hostname)) { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new(NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Internal error."); + + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + } else { + const gint port = + g_key_file_get_integer(shell->hosts, hostname, "port", NULL); + gchar *type = + g_key_file_get_string(shell->hosts, hostname, "type", NULL); + + if (g_str_equal(type, "ssh")) { + gchar *username = + g_key_file_get_string(shell->hosts, hostname, "username", + NULL); + gchar *password = + g_key_file_get_string(shell->hosts, hostname, "password", + NULL); + + retval = + remote_connect_ssh(hostname, port, username, password); + + g_free(username); + g_free(password); + } else { + retval = remote_connect_direct(hostname, port); + } + + g_free(type); + } + + return retval; +} + +void connect_dialog_show(GtkWidget * parent) +{ + HostDialog *he = + host_dialog_new(parent, "Connect to", HOST_DIALOG_MODE_CONNECT); + + if (gtk_dialog_run(GTK_DIALOG(he->dialog)) == GTK_RESPONSE_ACCEPT) { + gboolean connected; + gchar *hostname = + (gchar *) gtk_entry_get_text(GTK_ENTRY(he->txt_hostname)); + const gint selected_type = + gtk_combo_box_get_active(GTK_COMBO_BOX(he->cmb_type)); + const gint port = + (int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(he->txt_port)); + + gtk_widget_set_sensitive(he->dialog, FALSE); + + if (selected_type == 1) { + gchar *username = + (gchar *) gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_user)); + gchar *password = + (gchar *) + gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_password)); + + connected = + remote_connect_ssh(hostname, port, username, password); + } else { + connected = remote_connect_direct(hostname, port); + } + + if (connected) { + Shell *shell = shell_get_main_shell(); + gchar *tmp; + + tmp = g_strdup_printf("Remote: %s", hostname); + shell_set_remote_label(shell, tmp); + + g_free(tmp); + } else { + cb_local_computer(); + } + } + + host_dialog_destroy(he); +} + +void host_manager_show(GtkWidget * parent) +{ + HostManager *rd = host_manager_new(parent); + + gtk_dialog_run(GTK_DIALOG(rd->dialog)); + + host_manager_destroy(rd); +} + +static void populate_store(HostManager * rd, GtkListStore * store) +{ + Shell *shell; + GtkTreeIter iter; + gchar **hosts; + gint i; + gsize no_groups; + + gtk_list_store_clear(store); + shell = shell_get_main_shell(); + + hosts = g_key_file_get_groups(shell->hosts, &no_groups); + DEBUG("%d hosts found", no_groups); + for (i = 0; i < no_groups; i++) { + gchar *icon; + + DEBUG("host #%d: %s", i, hosts[i]); + + icon = g_key_file_get_string(shell->hosts, hosts[i], "icon", NULL); + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, + icon_cache_get_pixbuf(icon ? icon : + "server.png"), 1, + g_strdup(hosts[i]), 2, GINT_TO_POINTER(i), -1); + + g_free(icon); + } + + g_strfreev(hosts); +} + +static GtkTreeModel *host_dialog_get_completion_model(void) +{ + Shell *shell; + GtkListStore *store; + GtkTreeIter iter; + gchar **groups; + gint i = 0; + + shell = shell_get_main_shell(); + + store = gtk_list_store_new(1, G_TYPE_STRING); + for (groups = g_key_file_get_groups(shell->hosts, NULL); groups[i]; + i++) { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, g_strdup(groups[i]), -1); + } + g_strfreev(groups); + + return GTK_TREE_MODEL(store); +} + +static void host_combo_changed_cb(GtkComboBox * widget, gpointer user_data) +{ + HostDialog *host_dlg = (HostDialog *) user_data; + const gint default_ports[] = { 4242, 22 }; + gint index; + + index = gtk_combo_box_get_active(widget); + + gtk_notebook_set_current_page(GTK_NOTEBOOK(host_dlg->notebook), index); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(host_dlg->txt_port), + default_ports[index]); + + if (index == 0) { + gtk_widget_hide(host_dlg->frm_options); + } else { + gtk_widget_show(host_dlg->frm_options); + } +} + +static void +host_dialog_hostname_changed (GtkEditable *entry, gpointer user_data) +{ + HostDialog *host_dlg = (HostDialog *)user_data; + GRegex *regex_ip = NULL, *regex_host = NULL; + gboolean match; + const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry)); + + /* + * Regexes from: + * http://stackoverflow.com/questions/106179 + */ + const gchar *valid_ip_regex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|" \ + "25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}" \ + "|2[0-4][0-9]|25[0-5])$"; + const gchar *valid_hostname_regex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9" \ + "\\-]*[a-zA-Z0-9])\\.)*([A-Za-z]|[A-Z" \ + "a-z][A-Za-z0-9\\-]*[A-Za-z0-9])$"; + if (regex_ip == NULL) { + regex_ip = g_regex_new(valid_ip_regex, 0, 0, NULL); + } + + if (regex_host == NULL) { + regex_host = g_regex_new(valid_hostname_regex, 0, 0, NULL); + } + + match = g_regex_match(regex_ip, text, 0, NULL); + if (!match) { + match = g_regex_match(regex_host, text, 0, NULL); + } + + gtk_widget_set_sensitive(host_dlg->btn_accept, match); +} + +static void host_dialog_destroy(HostDialog * rd) +{ + gtk_widget_destroy(rd->dialog); + g_free(rd); +} + +static HostDialog *host_dialog_new(GtkWidget * parent, + gchar * title, HostDialogMode mode) +{ + HostDialog *host_dlg; + GtkWidget *dialog; + GtkWidget *dialog_vbox1; + GtkWidget *vbox1; + GtkWidget *frm_remote_host; + GtkWidget *alignment1; + GtkWidget *table1; + GtkWidget *label2; + GtkWidget *label3; + GtkWidget *label4; + GtkWidget *cmb_type; + GtkWidget *txt_hostname; + GtkWidget *alignment2; + GtkWidget *hbox1; + GtkObject *txt_port_adj; + GtkWidget *txt_port; + GtkWidget *label1; + GtkWidget *frm_options; + GtkWidget *alignment3; + GtkWidget *notebook; + GtkWidget *table2; + GtkWidget *label8; + GtkWidget *label9; + GtkWidget *txt_ssh_user; + GtkWidget *txt_ssh_password; + GtkWidget *label10; + GtkWidget *label5; + GtkWidget *dialog_action_area1; + GtkWidget *btn_cancel; + GtkWidget *btn_save; + GtkEntryCompletion *completion; + GtkTreeModel *completion_model; + + dialog = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(dialog), title); + 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_modal(GTK_WINDOW(dialog), TRUE); + gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); + gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); + gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); + gtk_window_set_type_hint(GTK_WINDOW(dialog), + GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_gravity(GTK_WINDOW(dialog), GDK_GRAVITY_CENTER); + + dialog_vbox1 = GTK_DIALOG(dialog)->vbox; + gtk_widget_show(dialog_vbox1); + + vbox1 = gtk_vbox_new(FALSE, 3); + gtk_widget_show(vbox1); + gtk_box_pack_start(GTK_BOX(dialog_vbox1), vbox1, TRUE, TRUE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5); + gtk_box_set_spacing(GTK_BOX(vbox1), 10); + + frm_remote_host = gtk_frame_new(NULL); + gtk_widget_show(frm_remote_host); + gtk_box_pack_start(GTK_BOX(vbox1), frm_remote_host, FALSE, TRUE, 0); + gtk_frame_set_shadow_type(GTK_FRAME(frm_remote_host), GTK_SHADOW_NONE); + + alignment1 = gtk_alignment_new(0.5, 0.5, 1, 1); + gtk_widget_show(alignment1); + gtk_container_add(GTK_CONTAINER(frm_remote_host), alignment1); + gtk_alignment_set_padding(GTK_ALIGNMENT(alignment1), 0, 0, 12, 0); + + table1 = gtk_table_new(3, 2, FALSE); + gtk_widget_show(table1); + gtk_container_add(GTK_CONTAINER(alignment1), table1); + gtk_table_set_row_spacings(GTK_TABLE(table1), 4); + gtk_table_set_col_spacings(GTK_TABLE(table1), 4); + + label2 = gtk_label_new("Protocol:"); + gtk_widget_show(label2); + gtk_table_attach(GTK_TABLE(table1), label2, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label2), 0, 0.5); + + label3 = gtk_label_new("Host:"); + gtk_widget_show(label3); + gtk_table_attach(GTK_TABLE(table1), label3, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label3), 0, 0.5); + + label4 = gtk_label_new("Port:"); + gtk_widget_show(label4); + gtk_table_attach(GTK_TABLE(table1), label4, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label4), 0, 0.5); + + cmb_type = gtk_combo_box_new_text(); + gtk_widget_show(cmb_type); + gtk_table_attach(GTK_TABLE(table1), cmb_type, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_type), + "Direct connection"); + gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_type), + "Remote tunnel over SSH"); + + txt_hostname = gtk_entry_new(); + gtk_widget_show(txt_hostname); + gtk_table_attach(GTK_TABLE(table1), txt_hostname, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + + alignment2 = gtk_alignment_new(0.5, 0.5, 1, 1); + gtk_widget_show(alignment2); + gtk_table_attach(GTK_TABLE(table1), alignment2, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + + hbox1 = gtk_hbox_new(FALSE, 0); + gtk_widget_show(hbox1); + gtk_container_add(GTK_CONTAINER(alignment2), hbox1); + + txt_port_adj = gtk_adjustment_new(4242, 1, 65535, 1, 10, 0); + txt_port = gtk_spin_button_new(GTK_ADJUSTMENT(txt_port_adj), 1, 0); + gtk_widget_show(txt_port); + gtk_box_pack_start(GTK_BOX(hbox1), txt_port, FALSE, TRUE, 0); + + label1 = gtk_label_new("Remote host"); + gtk_widget_show(label1); + gtk_frame_set_label_widget(GTK_FRAME(frm_remote_host), label1); + gtk_label_set_use_markup(GTK_LABEL(label1), TRUE); + + frm_options = gtk_frame_new(NULL); + gtk_widget_show(frm_options); + gtk_box_pack_start(GTK_BOX(vbox1), frm_options, FALSE, TRUE, 0); + gtk_frame_set_shadow_type(GTK_FRAME(frm_options), GTK_SHADOW_NONE); + + alignment3 = gtk_alignment_new(0.5, 0.5, 1, 1); + gtk_widget_show(alignment3); + gtk_container_add(GTK_CONTAINER(frm_options), alignment3); + gtk_alignment_set_padding(GTK_ALIGNMENT(alignment3), 0, 0, 12, 0); + + notebook = gtk_notebook_new(); + gtk_widget_show(notebook); + gtk_container_add(GTK_CONTAINER(alignment3), notebook); + GTK_WIDGET_UNSET_FLAGS(notebook, GTK_CAN_FOCUS); + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE); + gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), FALSE); + + label10 = gtk_label_new(""); + gtk_widget_show(label10); + gtk_container_add(GTK_CONTAINER(notebook), label10); + gtk_label_set_use_markup(GTK_LABEL(label10), TRUE); + + table2 = gtk_table_new(2, 2, FALSE); + gtk_widget_show(table2); + gtk_container_add(GTK_CONTAINER(notebook), table2); + gtk_table_set_row_spacings(GTK_TABLE(table2), 4); + gtk_table_set_col_spacings(GTK_TABLE(table2), 4); + + label8 = gtk_label_new("User:"); + gtk_widget_show(label8); + gtk_table_attach(GTK_TABLE(table2), label8, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label8), 0, 0.5); + + label9 = gtk_label_new("Password:"); + gtk_widget_show(label9); + gtk_table_attach(GTK_TABLE(table2), label9, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label9), 0, 0.5); + + txt_ssh_user = gtk_entry_new(); + gtk_widget_show(txt_ssh_user); + gtk_table_attach(GTK_TABLE(table2), txt_ssh_user, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + txt_ssh_password = gtk_entry_new(); + gtk_widget_show(txt_ssh_password); + gtk_table_attach(GTK_TABLE(table2), txt_ssh_password, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_invisible_char(GTK_ENTRY(txt_ssh_password), 9679); + gtk_entry_set_visibility(GTK_ENTRY(txt_ssh_password), FALSE); + + label5 = gtk_label_new("Connection options"); + gtk_widget_show(label5); + gtk_frame_set_label_widget(GTK_FRAME(frm_options), label5); + gtk_label_set_use_markup(GTK_LABEL(label5), TRUE); + + dialog_action_area1 = GTK_DIALOG(dialog)->action_area; + gtk_widget_show(dialog_action_area1); + gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog_action_area1), + GTK_BUTTONBOX_END); + + btn_cancel = gtk_button_new_from_stock("gtk-cancel"); + gtk_widget_show(btn_cancel); + gtk_dialog_add_action_widget(GTK_DIALOG(dialog), btn_cancel, + GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS(btn_cancel, GTK_CAN_DEFAULT); + + if (mode == HOST_DIALOG_MODE_EDIT) { + btn_save = gtk_button_new_from_stock(GTK_STOCK_SAVE); + } else if (mode == HOST_DIALOG_MODE_CONNECT) { + btn_save = gtk_button_new_from_stock(GTK_STOCK_CONNECT); + } + + gtk_widget_show(btn_save); + gtk_dialog_add_action_widget(GTK_DIALOG(dialog), btn_save, + GTK_RESPONSE_ACCEPT); + GTK_WIDGET_SET_FLAGS(btn_save, GTK_CAN_DEFAULT); + + host_dlg = g_new0(HostDialog, 1); + host_dlg->dialog = dialog; + host_dlg->notebook = notebook; + host_dlg->txt_hostname = txt_hostname; + host_dlg->txt_port = txt_port; + host_dlg->txt_ssh_user = txt_ssh_user; + host_dlg->txt_ssh_password = txt_ssh_password; + host_dlg->cmb_type = cmb_type; + host_dlg->frm_options = frm_options; + host_dlg->btn_accept = btn_save; + host_dlg->btn_cancel = btn_cancel; + + completion = gtk_entry_completion_new(); + gtk_entry_set_completion(GTK_ENTRY(host_dlg->txt_hostname), completion); + g_object_unref(completion); + + completion_model = host_dialog_get_completion_model(); + gtk_entry_completion_set_model(completion, completion_model); + g_object_unref(completion_model); + + gtk_entry_completion_set_text_column(completion, 0); + + gtk_combo_box_set_active(GTK_COMBO_BOX(host_dlg->cmb_type), 0); + + g_signal_connect(G_OBJECT(txt_hostname), "changed", + G_CALLBACK(host_dialog_hostname_changed), host_dlg); + g_signal_connect(G_OBJECT(cmb_type), "changed", + G_CALLBACK(host_combo_changed_cb), host_dlg); + + host_combo_changed_cb(GTK_COMBO_BOX(cmb_type), host_dlg); + host_dialog_hostname_changed(GTK_EDITABLE(txt_hostname), host_dlg); + + gtk_entry_set_activates_default(GTK_ENTRY(txt_hostname), TRUE); + + return host_dlg; +} + +static void host_manager_add(GtkWidget * button, gpointer data) +{ + Shell *shell = shell_get_main_shell(); + HostManager *rd = (HostManager *) data; + HostDialog *he = + host_dialog_new(rd->dialog, "Add a host", HOST_DIALOG_MODE_EDIT); + + retry: + if (gtk_dialog_run(GTK_DIALOG(he->dialog)) == GTK_RESPONSE_ACCEPT) { + const gchar *hostname = + gtk_entry_get_text(GTK_ENTRY(he->txt_hostname)); + + if (g_key_file_has_group(shell->hosts, hostname)) { + GtkWidget *dialog; + + dialog = + gtk_message_dialog_new_with_markup(GTK_WINDOW(rd->dialog), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Hostname %s already exists.", + hostname); + + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + goto retry; + } else { + GtkTreeIter iter; + const gchar *type[] = { "direct", "ssh" }; + const gint selected_type = + gtk_combo_box_get_active(GTK_COMBO_BOX(he->cmb_type)); + const gint port = + (int) + gtk_spin_button_get_value(GTK_SPIN_BUTTON(he->txt_port)); + + g_key_file_set_string(shell->hosts, hostname, "type", + type[selected_type]); + g_key_file_set_integer(shell->hosts, hostname, "port", port); + + if (selected_type == 1) { + const gchar *username = + gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_user)); + const gchar *password = + gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_password)); + + g_key_file_set_string(shell->hosts, hostname, "username", + username); + g_key_file_set_string(shell->hosts, hostname, "password", + password); + } + + gtk_list_store_append(rd->tree_store, &iter); + gtk_list_store_set(rd->tree_store, &iter, + 0, icon_cache_get_pixbuf("server.png"), + 1, g_strdup(hostname), 2, 0, -1); + } + } + + host_dialog_destroy(he); +} + +static void host_manager_edit(GtkWidget * button, gpointer data) +{ + Shell *shell = shell_get_main_shell(); + GtkWidget *dialog; + HostManager *rd = (HostManager *) data; + HostDialog *he = + host_dialog_new(rd->dialog, "Edit a host", HOST_DIALOG_MODE_EDIT); + gchar *host_type; + gchar *previous_hostname; + gint host_port; + + host_type = + g_key_file_get_string(shell->hosts, rd->selected_name, "type", + NULL); + if (!host_type || g_str_equal(host_type, "direct")) { + gtk_combo_box_set_active(GTK_COMBO_BOX(he->cmb_type), 0); + } else if (g_str_equal(host_type, "ssh")) { + gchar *username, *password; + + gtk_combo_box_set_active(GTK_COMBO_BOX(he->cmb_type), 1); + + username = + g_key_file_get_string(shell->hosts, rd->selected_name, + "username", NULL); + if (username) { + gtk_entry_set_text(GTK_ENTRY(he->txt_ssh_user), username); + g_free(username); + } + + password = + g_key_file_get_string(shell->hosts, rd->selected_name, + "password", NULL); + if (password) { + gtk_entry_set_text(GTK_ENTRY(he->txt_ssh_password), password); + g_free(password); + } + } else { + dialog = gtk_message_dialog_new(GTK_WINDOW(rd->dialog), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Host has invalid type(%s).", + host_type); + + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + goto bad; + } + + gtk_entry_set_text(GTK_ENTRY(he->txt_hostname), rd->selected_name); + previous_hostname = rd->selected_name; + + host_port = + g_key_file_get_integer(shell->hosts, rd->selected_name, "port", + NULL); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(he->txt_port), + host_port ? host_port : 4242); + + if (gtk_dialog_run(GTK_DIALOG(he->dialog)) == GTK_RESPONSE_ACCEPT) { + const gchar *type[] = { "direct", "ssh" }; + const gint selected_type = + gtk_combo_box_get_active(GTK_COMBO_BOX(he->cmb_type)); + const gint port = + (int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(he->txt_port)); + const gchar *hostname = + gtk_entry_get_text(GTK_ENTRY(he->txt_hostname)); + + if (!g_str_equal(previous_hostname, he->txt_hostname)) { + g_key_file_remove_group(shell->hosts, previous_hostname, NULL); + gtk_list_store_set(rd->tree_store, rd->selected_iter, + 1, g_strdup(hostname), -1); + } + + g_key_file_set_string(shell->hosts, hostname, "type", + type[selected_type]); + g_key_file_set_integer(shell->hosts, hostname, "port", port); + + if (selected_type == 1) { + const gchar *username = + gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_user)); + const gchar *password = + gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_password)); + + g_key_file_set_string(shell->hosts, hostname, "username", + username); + g_key_file_set_string(shell->hosts, hostname, "password", + password); + } + } + + bad: + host_dialog_destroy(he); + g_free(host_type); +} + +static void host_manager_remove(GtkWidget * button, gpointer data) +{ + Shell *shell = shell_get_main_shell(); + HostManager *rd = (HostManager *) data; + GtkWidget *dialog; + + dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(rd->dialog), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + "Remove the host %s?", + rd->selected_name); + + gtk_dialog_add_buttons(GTK_DIALOG(dialog), + GTK_STOCK_NO, GTK_RESPONSE_REJECT, + GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT, NULL); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { + g_key_file_remove_group(shell->hosts, rd->selected_name, NULL); + gtk_list_store_remove(rd->tree_store, rd->selected_iter); + + gtk_widget_set_sensitive(rd->btn_edit, FALSE); + gtk_widget_set_sensitive(rd->btn_remove, FALSE); + } + + gtk_widget_destroy(dialog); +} + +static void host_manager_tree_sel_changed(GtkTreeSelection * sel, + gpointer data) +{ + HostManager *rd = (HostManager *) data; + GtkTreeModel *model; + GtkTreeIter iter; + + if (gtk_tree_selection_get_selected(sel, &model, &iter)) { + gchar *name; + gint id; + + gtk_tree_model_get(model, &iter, 1, &name, 2, &id, -1); + + if (id != -1) { + gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_edit), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_remove), TRUE); + } else { + gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_edit), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_remove), FALSE); + } + + g_free(rd->selected_name); + + if (rd->selected_iter) + gtk_tree_iter_free(rd->selected_iter); + + rd->selected_id = id; + rd->selected_name = name; + rd->selected_iter = gtk_tree_iter_copy(&iter); + } +} + +static void host_manager_destroy(HostManager * rd) +{ + shell_save_hosts_file(); + shell_update_remote_menu(); + gtk_widget_destroy(rd->dialog); + + g_free(rd); +} + +static HostManager *host_manager_new(GtkWidget * parent) +{ + HostManager *rd; + GtkWidget *dialog; + GtkWidget *dialog_vbox; + GtkWidget *scrolledwindow; + GtkWidget *treeview; + GtkWidget *vbuttonbox; + GtkWidget *btn_add; + GtkWidget *btn_edit; + GtkWidget *dialog_action_area; + GtkWidget *btn_cancel; + GtkWidget *btn_remove; + GtkWidget *hbox; + GtkTreeSelection *sel; + GtkTreeViewColumn *column; + GtkCellRenderer *cr_text, *cr_pbuf; + GtkListStore *store; + GtkTreeModel *model; + + rd = g_new0(HostManager, 1); + + dialog = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(dialog), "Remote Host Manager"); + 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); + + dialog_vbox = GTK_DIALOG(dialog)->vbox; + gtk_box_set_spacing(GTK_BOX(dialog_vbox), 5); + gtk_container_set_border_width(GTK_CONTAINER(dialog_vbox), 4); + gtk_widget_show(dialog_vbox); + + hbox = gtk_hbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(dialog_vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show(hbox); + + scrolledwindow = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolledwindow); + gtk_box_pack_start(GTK_BOX(hbox), scrolledwindow, TRUE, TRUE, 0); + gtk_widget_set_size_request(scrolledwindow, -1, 200); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW + (scrolledwindow), GTK_SHADOW_IN); + + store = + gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT); + 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_widget_show(treeview); + gtk_container_add(GTK_CONTAINER(scrolledwindow), treeview); + gtk_tree_view_set_reorderable(GTK_TREE_VIEW(treeview), TRUE); + + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + 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); + + vbuttonbox = gtk_vbutton_box_new(); + gtk_widget_show(vbuttonbox); + gtk_box_pack_start(GTK_BOX(hbox), vbuttonbox, FALSE, TRUE, 0); + gtk_box_set_spacing(GTK_BOX(vbuttonbox), 5); + gtk_button_box_set_layout(GTK_BUTTON_BOX(vbuttonbox), + GTK_BUTTONBOX_START); + + btn_add = gtk_button_new_with_mnemonic("_Add"); + gtk_widget_show(btn_add); + gtk_container_add(GTK_CONTAINER(vbuttonbox), btn_add); + GTK_WIDGET_SET_FLAGS(btn_add, GTK_CAN_DEFAULT); + g_signal_connect(btn_add, "clicked", G_CALLBACK(host_manager_add), rd); + + btn_edit = gtk_button_new_with_mnemonic("_Edit"); + gtk_widget_show(btn_edit); + gtk_container_add(GTK_CONTAINER(vbuttonbox), btn_edit); + GTK_WIDGET_SET_FLAGS(btn_edit, GTK_CAN_DEFAULT); + g_signal_connect(btn_edit, "clicked", G_CALLBACK(host_manager_edit), + rd); + + btn_remove = gtk_button_new_with_mnemonic("_Remove"); + gtk_widget_show(btn_remove); + gtk_container_add(GTK_CONTAINER(vbuttonbox), btn_remove); + GTK_WIDGET_SET_FLAGS(btn_remove, GTK_CAN_DEFAULT); + g_signal_connect(btn_remove, "clicked", + G_CALLBACK(host_manager_remove), rd); + + dialog_action_area = GTK_DIALOG(dialog)->action_area; + gtk_widget_show(dialog_action_area); + gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog_action_area), + GTK_BUTTONBOX_END); + + btn_cancel = gtk_button_new_from_stock(GTK_STOCK_CLOSE); + gtk_widget_show(btn_cancel); + gtk_dialog_add_action_widget(GTK_DIALOG(dialog), btn_cancel, + GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS(btn_cancel, GTK_CAN_DEFAULT); + + gtk_tree_view_collapse_all(GTK_TREE_VIEW(treeview)); + + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + + g_signal_connect(G_OBJECT(sel), "changed", + (GCallback) host_manager_tree_sel_changed, rd); + + rd->dialog = dialog; + rd->btn_cancel = btn_cancel; + rd->btn_add = btn_add; + rd->btn_edit = btn_edit; + rd->btn_remove = btn_remove; + rd->tree_store = store; + + populate_store(rd, store); + gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_edit), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(rd->btn_remove), FALSE); + + return rd; +} + +#endif /* HAS_LIBSOUP */ diff --git a/hardinfo2/remote/ssh-conn.c b/hardinfo2/remote/ssh-conn.c new file mode 100644 index 00000000..7f099d35 --- /dev/null +++ b/hardinfo2/remote/ssh-conn.c @@ -0,0 +1,338 @@ +/* + Remote Client + HardInfo - Displays System Information + Copyright (C) 2003-2009 Leandro A. F. Pereira + + Based on ssh-method.c from GnomeVFS + Copyright (C) 1999 Free Software Foundation + Original author: Ian McKellar + + ssh-conn.c and ssh-conn.h are 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. + + ssh-conn.c and ssh-con.h are 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 ssh-conn.c and ssh-conn.h; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "config.h" +#ifdef HAS_LIBSOUP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ssh-conn.h" + +const char *ssh_conn_errors[] = { + "OK", + "No URI specified", + "Unknown protocol", + "Unknown error", + "Cannot spawn SSH", + "Bad parameters", + "Permission denied (invalid credentials)", + "Host key verification failed", + "Connection refused", + "Invalid username or password" +}; + +int ssh_write(SSHConn * conn, + gconstpointer buffer, gint num_bytes, gint * bytes_written) +{ + int written; + int count = 0; + + do { + written = write(conn->fd_write, buffer, (size_t) num_bytes); + if (written == -1 && errno == EINTR) { + count++; + usleep(10); + } + } while (written == -1 && errno == EINTR && count < 5); + + if (written == -1) { + return -1; + } + + *bytes_written = written; + + return 1; +} + +int ssh_read(gint fd, gpointer buffer, gint num_bytes, gint * bytes_read) +{ + int retval; + fd_set fds; + struct timeval tv = { 5, 0 }; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + + *bytes_read = 0; + + if ((retval = select(fd + 1, &fds, NULL, NULL, &tv)) < 0) { + return retval; + } + + if ((retval = read(fd, buffer, (size_t) num_bytes)) > 0) { + *bytes_read = retval; + return 1; + } + + return retval; +} + +void ssh_close(SSHConn * conn) +{ + if (!conn) { + return; + } + + close(conn->fd_read); + close(conn->fd_write); + close(conn->fd_error); + + if (conn->uri) { + soup_uri_free(conn->uri); + } + + kill(conn->pid, SIGINT); + + if (conn->askpass_path) { + DEBUG("unlinking %s", conn->askpass_path); + g_remove(conn->askpass_path); + g_free(conn->askpass_path); + } + + g_free(conn); +} + +static void ssh_conn_setup(gpointer user_data) +{ + gchar *askpass_path = (gchar *) user_data; + int fd; + + if ((fd = open("/dev/tty", O_RDWR)) != -1) { + ioctl(fd, TIOCNOTTY, NULL); + close(fd); + } + + if (askpass_path) { + g_setenv("DISPLAY", "none:0.", TRUE); + g_setenv("SSH_ASKPASS", askpass_path, TRUE); + } else { + g_setenv("SSH_ASKPASS", "/bin/false", TRUE); + } +} + +SSHConnResponse ssh_new(SoupURI * uri, + SSHConn ** conn_return, gchar * command) +{ + int argc, res, bytes_read; + char **argv, *askpass_path = NULL; + GString *cmd_line; + SSHConnResponse response; + SSHConn *connection; + gchar buffer[512]; + + if (!conn_return) { + return SSH_CONN_BAD_PARAMS; + } + + if (!uri) { + return SSH_CONN_NO_URI; + } + + if (!g_str_equal(uri->scheme, "ssh")) { + return SSH_CONN_UNKNOWN_PROTOCOL; + } + + if (uri->password) { + int tmp_askpass; + + askpass_path = + g_build_filename(g_get_home_dir(), ".hardinfo", + "ssh-askpass-XXXXXX", NULL); + tmp_askpass = g_mkstemp(askpass_path); + if (tmp_askpass > 0) { + gchar *tmp; + + g_chmod(askpass_path, 0700); + + tmp = g_strdup_printf("#!/bin/sh\n" + "echo '%s'\n" + "rm -f \"$0\"", uri->password); + write(tmp_askpass, tmp, strlen(tmp)); + close(tmp_askpass); + g_free(tmp); + + DEBUG("using [%s] as ssh-askpass", askpass_path); + } + } + + + cmd_line = g_string_new("ssh -x"); + + if (uri->query && strlen(uri->query)) { + GHashTable *query; + GList *keys, *key; + + query = soup_form_decode(uri->query); + keys = g_hash_table_get_keys(query); + + for (key = keys; key; key = key->next) { + gchar *param; + + g_string_append_printf(cmd_line, " -%s", (gchar *) key->data); + + if ((param = (gchar *) g_hash_table_lookup(query, key->data))) { + g_string_append_printf(cmd_line, "'%s'", param); + } + } + + g_list_free(keys); + g_hash_table_destroy(query); + } + + if (uri->user) { + g_string_append_printf(cmd_line, " -l '%s'", uri->user); + } + + if (uri->port) { + g_string_append_printf(cmd_line, " -p %d", uri->port); + } + + g_string_append_printf(cmd_line, + " %s \"LC_ALL=C %s\"", uri->host, command); + + DEBUG("cmd_line = [%s]", cmd_line->str); + + if (!g_shell_parse_argv(cmd_line->str, &argc, &argv, NULL)) { + response = SSH_CONN_BAD_PARAMS; + goto end; + } + + connection = g_new0(SSHConn, 1); + connection->exit_status = -1; + + DEBUG("spawning SSH"); + + if (!g_spawn_async_with_pipes(NULL, argv, NULL, + G_SPAWN_SEARCH_PATH, + ssh_conn_setup, askpass_path, + &connection->pid, + &connection->fd_write, + &connection->fd_read, + &connection->fd_error, NULL)) { + response = SSH_CONN_CANNOT_SPAWN_SSH; + goto end; + } + + memset(buffer, 0, sizeof(buffer)); + res = ssh_read(connection->fd_error, &buffer, sizeof(buffer), + &bytes_read); + DEBUG("bytes read: %d, result = %d", bytes_read, res); + if (bytes_read > 0 && res == 1) { + DEBUG("Received (error channel): [%s]", buffer); + + if (strstr(buffer, "Permission denied")) { + response = SSH_CONN_PERMISSION_DENIED; + goto end; + } else if (strstr(buffer, "Host key verification failed")) { + response = SSH_CONN_HOST_KEY_CHECK_FAIL; + goto end; + } else if (strstr(buffer, "Connection refused")) { + response = SSH_CONN_REFUSED; + goto end; + } + } + + DEBUG("no error detected; ssh conn established"); + + connection->uri = soup_uri_copy(uri); + response = SSH_CONN_OK; + + end: + g_strfreev(argv); + g_string_free(cmd_line, TRUE); + + if (askpass_path) { + if (connection) { + connection->askpass_path = askpass_path; + } else { + g_free(askpass_path); + } + } + + if (response != SSH_CONN_OK) { + if (connection->uri) { + soup_uri_free(connection->uri); + } + + g_free(connection); + + *conn_return = NULL; + } else { + *conn_return = connection; + } + + DEBUG("response = %d (%s)", response, ssh_conn_errors[response]); + + return response; +} + +#ifdef SSH_TEST +int main(int argc, char **argv) +{ + SSHConn *c; + SSHConnResponse r; + SoupURI *u; + char buffer[256]; + + if (argc < 2) { + g_print("Usage: %s URI command\n", argv[0]); + g_print("Example: %s ssh://user:password@host 'ls -la /'\n", + argv[0]); + return 1; + } + + u = soup_uri_new(argv[1]); + r = ssh_new(u, &c, argv[2]); + g_print("Connection result: %s\n", ssh_conn_errors[r]); + + if (r == SSH_CONN_OK) { + int bytes_read; + + while (ssh_read(c->fd_read, &buffer, sizeof(buffer), + &bytes_read) > 0) { + g_print("Bytes read: %d\n", bytes_read); + g_print("Contents: %s", buffer); + } + + g_print("Finished running remote command\n"); + } + + g_print("Closing SSH [ptr = %p]", c); + ssh_close(c); + + return 0; +} +#endif /* SSH_TEST */ +#endif /* HAS_LIBSOUP */ diff --git a/hardinfo2/remote/xmlrpc-client.c b/hardinfo2/remote/xmlrpc-client.c new file mode 100644 index 00000000..d363729b --- /dev/null +++ b/hardinfo2/remote/xmlrpc-client.c @@ -0,0 +1,247 @@ +/* + * XMLRPC Client + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 +#include "config.h" +#include "xmlrpc-client.h" + +#ifdef HAS_LIBSOUP +static GMainLoop *loop = NULL; +static SoupSession *session = NULL; +static gboolean lock = FALSE; + +void xmlrpc_init(void) +{ + if (!loop) { + loop = g_main_loop_new(FALSE, FALSE); + } + + if (!session) { + session = soup_session_async_new_with_options(SOUP_SESSION_TIMEOUT, 10, NULL); + } +} + +static void xmlrpc_response_get_integer(SoupSession *s, + SoupMessage *m, + gpointer user_data) +{ + gint *response = user_data; + + *response = -1; + + if (SOUP_STATUS_IS_SUCCESSFUL(m->status_code)) { + soup_xmlrpc_extract_method_response(m->response_body->data, + m->response_body->length, + NULL, + G_TYPE_INT, response); + } + + g_main_quit(loop); + lock = FALSE; +} + +gint xmlrpc_get_integer(gchar *addr, + gchar *method, + const gchar *param_types, + ...) +{ + gint integer; + GValueArray *params; + SoupMessage *msg; + gchar *body; + + msg = soup_message_new("POST", addr); + + params = g_value_array_new(1); + + if (param_types && *param_types) { + va_list ap; + + va_start(ap, param_types); + while (*param_types) { + switch (*param_types) { + case '%': + break; + case 'i': + soup_value_array_append(params, G_TYPE_INT, va_arg(ap, int)); + break; + case 's': + default: + soup_value_array_append(params, G_TYPE_STRING, va_arg(ap, char *)); + break; + } + + param_types++; + } + + va_end(ap); + } + + body = soup_xmlrpc_build_method_call(method, params->values, params->n_values); + g_value_array_free(params); + + soup_message_set_request(msg, "text/xml", + SOUP_MEMORY_TAKE, body, strlen(body)); + + while (lock) + g_main_iteration(FALSE); + + lock = TRUE; + soup_session_queue_message(session, msg, xmlrpc_response_get_integer, &integer); + g_main_run(loop); + + return integer; +} + +static void xmlrpc_response_get_string(SoupSession *s, + SoupMessage *m, + gpointer user_data) +{ + if (SOUP_STATUS_IS_SUCCESSFUL(m->status_code)) { + soup_xmlrpc_extract_method_response(m->response_body->data, + m->response_body->length, + NULL, + G_TYPE_STRING, user_data); + } + + g_main_quit(loop); + lock = FALSE; +} + +gchar *xmlrpc_get_string(gchar *addr, + gchar *method, + const gchar *param_types, + ...) +{ + GValueArray *params; + SoupMessage *msg; + gchar *body, *string = NULL; + + msg = soup_message_new("POST", addr); + + params = g_value_array_new(1); + + if (param_types && *param_types) { + va_list ap; + + va_start(ap, param_types); + while (*param_types) { + switch (*param_types) { + case '%': + break; + case 'i': + soup_value_array_append(params, G_TYPE_INT, va_arg(ap, int)); + break; + case 's': + default: + soup_value_array_append(params, G_TYPE_STRING, va_arg(ap, char *)); + break; + } + + param_types++; + } + + va_end(ap); + } + + body = soup_xmlrpc_build_method_call(method, params->values, params->n_values); + g_value_array_free(params); + + soup_message_set_request(msg, "text/xml", + SOUP_MEMORY_TAKE, body, strlen(body)); + + while (lock) + g_main_iteration(FALSE); + + lock = TRUE; + soup_session_queue_message(session, msg, xmlrpc_response_get_string, &string); + g_main_run(loop); + + return string; +} + +static void xmlrpc_response_get_array(SoupSession *s, + SoupMessage *m, + gpointer user_data) +{ + if (SOUP_STATUS_IS_SUCCESSFUL(m->status_code)) { + soup_xmlrpc_extract_method_response(m->response_body->data, + m->response_body->length, + NULL, + G_TYPE_VALUE_ARRAY, user_data); + } + + g_main_quit(loop); + lock = FALSE; +} + +GValueArray *xmlrpc_get_array(gchar *addr, + gchar *method, + const gchar *param_types, + ...) +{ + GValueArray *params, *answer = NULL; + SoupMessage *msg; + gchar *body; + + msg = soup_message_new("POST", addr); + + params = g_value_array_new(1); + + if (param_types && *param_types) { + va_list ap; + + va_start(ap, param_types); + while (*param_types) { + switch (*param_types) { + case '%': + break; + case 'i': + soup_value_array_append(params, G_TYPE_INT, va_arg(ap, int)); + break; + case 's': + default: + soup_value_array_append(params, G_TYPE_STRING, va_arg(ap, char *)); + break; + } + + param_types++; + } + + va_end(ap); + } + + body = soup_xmlrpc_build_method_call(method, params->values, params->n_values); + g_value_array_free(params); + + soup_message_set_request(msg, "text/xml", + SOUP_MEMORY_TAKE, body, strlen(body)); + + while (lock) + g_main_iteration(FALSE); + + lock = TRUE; + soup_session_queue_message(session, msg, xmlrpc_response_get_array, &answer); + g_main_run(loop); + + return answer; +} + +#endif /* HAS_LIBSOUP */ + diff --git a/hardinfo2/remote/xmlrpc-server.c b/hardinfo2/remote/xmlrpc-server.c new file mode 100644 index 00000000..e953cfd1 --- /dev/null +++ b/hardinfo2/remote/xmlrpc-server.c @@ -0,0 +1,782 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * This file is based off xmlrpc-server-test.c from libsoup test suite + * Copyright (C) 2008 Red Hat, Inc. + * + * 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 +#ifdef HAS_LIBSOUP +#include +#include +#include + +#include "shell.h" +#include "hardinfo.h" + +#define XMLRPC_SERVER_VERSION 1 +/* server namespace */ +static void method_get_api_version(SoupMessage * msg, + GValueArray * params); +static void method_shutdown_server(SoupMessage * msg, + GValueArray * params); +/* module namespace */ +static void method_get_module_list(SoupMessage * msg, + GValueArray * params); +static void method_get_entry_list(SoupMessage * msg, GValueArray * params); +static void method_entry_reload(SoupMessage * msg, GValueArray * params); +static void method_entry_scan(SoupMessage * msg, GValueArray * params); +static void method_entry_get_field(SoupMessage * msg, + GValueArray * params); +static void method_entry_get_moreinfo(SoupMessage * msg, + GValueArray * params); +static void method_entry_get_note(SoupMessage * msg, GValueArray * params); +static void method_entry_function(SoupMessage * msg, GValueArray * params); +static void method_get_about_info(SoupMessage * msg, GValueArray * params); +static void method_call_method(SoupMessage * msg, GValueArray * params); +static void method_call_method_param(SoupMessage * msg, + GValueArray * params); + +/* method handler table */ +static const struct { + gchar *method_name; + void *callback; +} handler_table[] = { + /* server namespace */ + { "server.getAPIVersion", method_get_api_version }, + { "server.shutdownServer", method_shutdown_server }, + /* module namespace */ + { "module.getModuleList", method_get_module_list }, + { "module.getEntryList", method_get_entry_list }, + { "module.entryReload", method_entry_reload }, + { "module.entryScan", method_entry_scan }, + { "module.entryFunction", method_entry_function }, + { "module.entryGetNote", method_entry_get_note }, + { "module.entryGetField", method_entry_get_field }, + { "module.entryGetMoreInfo", method_entry_get_moreinfo }, + { "module.getAboutInfo", method_get_about_info }, + { "module.callMethod", method_call_method }, + { "module.callMethodParam", method_call_method_param }, + { NULL } +}; + +static GHashTable *handlers = NULL; +static GMainLoop *loop = NULL; + +typedef struct _MethodParameter MethodParameter; +struct _MethodParameter { + int param_type; + void *variable; +}; + +static void +args_error(SoupMessage * msg, GValueArray * params, int expected) +{ + soup_xmlrpc_set_fault(msg, + SOUP_XMLRPC_FAULT_SERVER_ERROR_INVALID_METHOD_PARAMETERS, + "Wrong number of parameters: expected %d, got %d", + expected, params->n_values); +} + +static void +type_error(SoupMessage * msg, GType expected, GValueArray * params, + int bad_value) +{ + soup_xmlrpc_set_fault(msg, + SOUP_XMLRPC_FAULT_SERVER_ERROR_INVALID_METHOD_PARAMETERS, + "Bad parameter #%d: expected %s, got %s", + bad_value + 1, g_type_name(expected), + g_type_name(G_VALUE_TYPE + (¶ms->values[bad_value]))); +} + +static gboolean validate_parameters(SoupMessage *msg, GValueArray *params, + MethodParameter *method_params, gint n_params) +{ + int i; + + if (params->n_values != n_params) { + args_error(msg, params, n_params); + return FALSE; + } + + for (i = 0; i < n_params; i++) { + if (!soup_value_array_get_nth(params, i, + method_params[i].param_type, + method_params[i].variable)) { + int j; + + type_error(msg, method_params[i].param_type, params, i); + + for (j = 0; j < i; j++) { + if (method_params[j].param_type == G_TYPE_STRING) { + g_free(method_params[j].variable); + } + } + + return FALSE; + } + } + + return TRUE; +} + +static void method_get_module_list(SoupMessage * msg, GValueArray * params) +{ + GValueArray *out; + GSList *modules; + + out = soup_value_array_new(); + + for (modules = modules_get_list(); modules; modules = modules->next) { + ShellModule *module = (ShellModule *) modules->data; + gchar *icon_file, *tmp; + GValueArray *tuple; + + tuple = soup_value_array_new(); + + tmp = g_path_get_basename(g_module_name(module->dll)); + if ((icon_file = g_strrstr(tmp, G_MODULE_SUFFIX))) { + *icon_file = '\0'; + icon_file = g_strconcat(tmp, "png", NULL); + } else { + icon_file = ""; + } + + soup_value_array_append(tuple, G_TYPE_STRING, module->name); + soup_value_array_append(tuple, G_TYPE_STRING, icon_file); + + soup_value_array_append(out, G_TYPE_VALUE_ARRAY, tuple); + + g_value_array_free(tuple); + g_free(tmp); + } + + soup_xmlrpc_set_response(msg, G_TYPE_VALUE_ARRAY, out); + g_value_array_free(out); +} + +static void method_get_entry_list(SoupMessage * msg, GValueArray * params) +{ + ShellModule *module; + ShellModuleEntry *module_entry; + GSList *entry, *modules; + GValueArray *out; + gboolean found = FALSE; + gchar *module_name; + MethodParameter method_params[] = { + { G_TYPE_STRING, &module_name } + }; + + if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { + return; + } + + for (modules = modules_get_list(); modules; modules = modules->next) { + ShellModule *module = (ShellModule *) modules->data; + + if (!strncmp(module->name, module_name, strlen(module->name))) { + found = TRUE; + break; + } + } + + out = soup_value_array_new(); + + if (found) { + module = (ShellModule *) modules->data; + for (entry = module->entries; entry; entry = entry->next) { + GValueArray *tuple; + + module_entry = (ShellModuleEntry *) entry->data; + + if (module_entry->flags & MODULE_FLAG_NO_REMOTE) { + /* do nothing if we're not supposed to */ + } else { + tuple = soup_value_array_new(); + + soup_value_array_append(tuple, G_TYPE_STRING, module_entry->name); + soup_value_array_append(tuple, G_TYPE_STRING, module_entry->icon_file); + + soup_value_array_append(out, G_TYPE_VALUE_ARRAY, tuple); + g_value_array_free(tuple); + } + } + } + + soup_xmlrpc_set_response(msg, G_TYPE_VALUE_ARRAY, out); + g_value_array_free(out); +} + +static void method_entry_get_field(SoupMessage * msg, GValueArray * params) +{ + ShellModule *module; + GSList *modules; + gchar *module_name, *field_name, *answer = NULL; + gint entry_number; + gboolean found = FALSE; + MethodParameter method_params[] = { + { G_TYPE_STRING, &module_name }, + { G_TYPE_INT, &entry_number }, + { G_TYPE_STRING, &field_name } + }; + + if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { + return; + } + + for (modules = modules_get_list(); modules; modules = modules->next) { + module = (ShellModule *) modules->data; + + if (!strncmp(module->name, module_name, strlen(module->name))) { + found = TRUE; + break; + } + } + + if (found) { + if (entry_number < g_slist_length(module->entries)) { + GSList *entry_node = g_slist_nth(module->entries, entry_number); + ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; + + if (entry->flags & MODULE_FLAG_NO_REMOTE) { + /* do nothing */ + } else { + answer = module_entry_get_field(entry, field_name); + } + } + } + + if (!answer) { + answer = g_strdup(""); + } + + soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); + g_free(answer); +} + +static void method_entry_get_moreinfo(SoupMessage * msg, + GValueArray * params) +{ + ShellModule *module; + GSList *modules; + gchar *module_name, *field_name, *answer = NULL; + gint entry_number; + gboolean found = FALSE; + MethodParameter method_params[] = { + { G_TYPE_STRING, &module_name }, + { G_TYPE_INT, &entry_number }, + { G_TYPE_STRING, &field_name }, + }; + + if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { + return; + } + + for (modules = modules_get_list(); modules; modules = modules->next) { + module = (ShellModule *) modules->data; + + if (!strncmp(module->name, module_name, strlen(module->name))) { + found = TRUE; + break; + } + } + + if (found) { + if (entry_number < g_slist_length(module->entries)) { + GSList *entry_node = g_slist_nth(module->entries, entry_number); + ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; + + if (entry->flags & MODULE_FLAG_NO_REMOTE) { + /* do nothing */ + } else { + answer = module_entry_get_moreinfo(entry, field_name); + } + } + } + + if (!answer) { + answer = g_strdup(""); + } + + soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); + g_free(answer); +} + +static void method_entry_reload(SoupMessage * msg, GValueArray * params) +{ + ShellModule *module; + GSList *modules; + gchar *module_name; + gint entry_number; + gboolean found = FALSE, answer = FALSE; + MethodParameter method_params[] = { + { G_TYPE_STRING, &module_name }, + { G_TYPE_INT, &entry_number }, + }; + + if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { + return; + } + + for (modules = modules_get_list(); modules; modules = modules->next) { + module = (ShellModule *) modules->data; + + if (!strncmp(module->name, module_name, strlen(module->name))) { + found = TRUE; + break; + } + } + + if (found) { + if (entry_number < g_slist_length(module->entries)) { + GSList *entry_node = g_slist_nth(module->entries, entry_number); + ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; + + if (entry->flags & MODULE_FLAG_NO_REMOTE) { + /* do nothing */ + } else { + module_entry_reload(entry); + answer = TRUE; + } + } + } + + soup_xmlrpc_set_response(msg, G_TYPE_BOOLEAN, answer); +} + +static void method_entry_scan(SoupMessage * msg, GValueArray * params) +{ + ShellModule *module; + GSList *modules; + gchar *module_name; + gint entry_number; + gboolean found = FALSE, answer = FALSE; + MethodParameter method_params[] = { + { G_TYPE_STRING, &module_name }, + { G_TYPE_INT, &entry_number }, + }; + + if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { + return; + } + + for (modules = modules_get_list(); modules; modules = modules->next) { + module = (ShellModule *) modules->data; + + if (!strncmp(module->name, module_name, strlen(module->name))) { + found = TRUE; + break; + } + } + + if (found) { + if (entry_number < g_slist_length(module->entries)) { + GSList *entry_node = g_slist_nth(module->entries, entry_number); + ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; + + if (entry->flags & MODULE_FLAG_NO_REMOTE) { + /* do nothing */ + } else { + module_entry_scan(entry); + answer = TRUE; + } + } + } + + soup_xmlrpc_set_response(msg, G_TYPE_BOOLEAN, answer); +} + +static void method_entry_function(SoupMessage * msg, GValueArray * params) +{ + ShellModule *module; + GSList *modules; + gchar *module_name, *answer = NULL; + gboolean found = FALSE; + gint entry_number; + MethodParameter method_params[] = { + { G_TYPE_STRING, &module_name }, + { G_TYPE_INT, &entry_number }, + }; + + if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { + return; + } + + for (modules = modules_get_list(); modules; modules = modules->next) { + module = (ShellModule *) modules->data; + + if (!strncmp(module->name, module_name, strlen(module->name))) { + found = TRUE; + break; + } + } + + if (found) { + if (entry_number < g_slist_length(module->entries)) { + GSList *entry_node = g_slist_nth(module->entries, entry_number); + ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; + + if (entry->flags & MODULE_FLAG_NO_REMOTE) { + /* do nothing */ + } else { + module_entry_scan(entry); + answer = module_entry_function(entry); + } + } + } + + if (!answer) { + answer = g_strdup(""); + } + + soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); + g_free(answer); +} + + +static void method_entry_get_note(SoupMessage * msg, GValueArray * params) +{ + ShellModule *module; + GSList *modules; + gchar *module_name, *answer = NULL; + gint entry_number; + gboolean found = FALSE; + MethodParameter method_params[] = { + { G_TYPE_STRING, &module_name }, + { G_TYPE_INT, &entry_number }, + }; + + if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { + return; + } + + for (modules = modules_get_list(); modules; modules = modules->next) { + module = (ShellModule *) modules->data; + + if (!strncmp(module->name, module_name, strlen(module->name))) { + found = TRUE; + break; + } + } + + if (found) { + if (entry_number < g_slist_length(module->entries)) { + GSList *entry_node = g_slist_nth(module->entries, entry_number); + ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; + + if (entry->flags & MODULE_FLAG_NO_REMOTE) { + /* do nothing */ + } else { + answer = g_strdup((gchar *)module_entry_get_note(entry)); + } + } + } + + if (!answer) { + answer = g_strdup(""); + } + + soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); + g_free(answer); +} + +static void method_get_about_info(SoupMessage * msg, GValueArray * params) +{ + ShellModule *module; + GSList *modules; + gchar *module_name; + gboolean found = FALSE; + GValueArray *out; + MethodParameter method_params[] = { + { G_TYPE_STRING, &module_name }, + }; + + if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { + return; + } + + for (modules = modules_get_list(); modules; modules = modules->next) { + module = (ShellModule *) modules->data; + + if (!strncmp(module->name, module_name, strlen(module->name))) { + found = TRUE; + break; + } + } + + out = soup_value_array_new(); + + if (found) { + ModuleAbout *about = module_get_about(module); + + soup_value_array_append(out, G_TYPE_STRING, about->description); + soup_value_array_append(out, G_TYPE_STRING, about->author); + soup_value_array_append(out, G_TYPE_STRING, about->version); + soup_value_array_append(out, G_TYPE_STRING, about->license); + } + + soup_xmlrpc_set_response(msg, G_TYPE_VALUE_ARRAY, out); + g_value_array_free(out); +} + +static void method_call_method(SoupMessage * msg, GValueArray * params) +{ + gchar *method_name, *answer = NULL; + MethodParameter method_params[] = { + { G_TYPE_STRING, &method_name }, + }; + + if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { + return; + } + + if (!(answer = module_call_method(method_name))) { + answer = g_strdup(""); + } + + soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); + g_free(answer); +} + +static void method_call_method_param(SoupMessage * msg, + GValueArray * params) +{ + gchar *method_name, *parameter, *answer = NULL; + MethodParameter method_params[] = { + { G_TYPE_STRING, &method_name }, + { G_TYPE_STRING, ¶meter }, + }; + + if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { + return; + } + + if (!(answer = module_call_method_param(method_name, parameter))) { + answer = g_strdup(""); + } + + soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); + g_free(answer); +} + +static void method_get_api_version(SoupMessage * msg, GValueArray * params) +{ + soup_xmlrpc_set_response(msg, G_TYPE_INT, XMLRPC_SERVER_VERSION); +} + +static void method_shutdown_server(SoupMessage * msg, GValueArray * params) +{ + soup_xmlrpc_set_response(msg, G_TYPE_BOOLEAN, TRUE); + + g_main_loop_quit(loop); +} +#endif /* HAS_LIBSOUP */ + +void xmlrpc_server_init(void) +{ +#ifdef HAS_LIBSOUP + if (!loop) { + DEBUG("creating main loop"); + loop = g_main_loop_new(NULL, FALSE); + } else { + DEBUG("using main loop instance %p", loop); + } + + if (!handlers) { + int i; + handlers = g_hash_table_new(g_str_hash, g_str_equal); + + DEBUG("registering handlers"); + + for (i = 0; handler_table[i].method_name; i++) { + g_hash_table_insert(handlers, + handler_table[i].method_name, + handler_table[i].callback); + } + } +#endif /* HAS_LIBSOUP */ +} + +#ifdef HAS_LIBSOUP +static SoupServer *xmlrpc_server_new(void) +{ + SoupServer *server; + + DEBUG("creating server"); + server = soup_server_new(SOUP_SERVER_SSL_CERT_FILE, NULL, + SOUP_SERVER_SSL_KEY_FILE, NULL, + SOUP_SERVER_ASYNC_CONTEXT, NULL, + SOUP_SERVER_PORT, 4242, NULL); + if (!server) { + return NULL; + } + + soup_server_run_async(server); + + return server; +} + +static void xmlrpc_server_callback(SoupServer * server, + SoupMessage * msg, + const char *path, + GHashTable * query, + SoupClientContext * context, + gpointer data) +{ + if (msg->method == SOUP_METHOD_POST) { + gchar *method_name; + GValueArray *params; + void (*callback) (SoupMessage * msg, GValueArray * params); + + DEBUG("POST %s", path); + + if (!soup_xmlrpc_parse_method_call(msg->request_body->data, + msg->request_body->length, + &method_name, ¶ms)) { + soup_message_set_status(msg, SOUP_STATUS_BAD_REQUEST); + return; + } + + DEBUG("method: %s", method_name); + + if ((callback = g_hash_table_lookup(handlers, method_name))) { + soup_message_set_status(msg, SOUP_STATUS_OK); + + DEBUG("found callback: %p", callback); + callback(msg, params); + } else { + DEBUG("callback not found"); + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); + } + + g_value_array_free(params); + g_free(method_name); + } else { + DEBUG("received request of unknown method"); + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); + } +} + +static void icon_server_callback(SoupServer * server, + SoupMessage * msg, + const char *path, + GHashTable * query, + SoupClientContext * context, + gpointer data) +{ + if (msg->method == SOUP_METHOD_GET) { + path = g_strrstr(path, "/"); + + DEBUG("GET %s", path); + + if (!path || !g_str_has_suffix(path, ".png")) { + DEBUG("not an icon, invalid path, etc"); + soup_message_set_status(msg, SOUP_STATUS_FORBIDDEN); + soup_message_set_response(msg, + "text/plain", + SOUP_MEMORY_STATIC, + "500 :(", 6); + } else { + gchar *file, *icon; + gsize size; + + file = g_build_filename(params.path_data, + "pixmaps", + path + 1, + NULL); + + if (g_file_get_contents(file, &icon, &size, NULL)) { + DEBUG("icon found"); + soup_message_set_status(msg, SOUP_STATUS_OK); + soup_message_set_response(msg, + "image/png", + SOUP_MEMORY_TAKE, + icon, size); + } else { + DEBUG("icon not found"); + soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND); + soup_message_set_response(msg, + "text/plain", + SOUP_MEMORY_STATIC, + "404 :(", 6); + } + + g_free(file); + } + } else { + DEBUG("received request of unknown method"); + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); + } +} +#endif /* HAS_LIBSOUP */ + +void xmlrpc_server_start(GMainLoop *main_loop) +{ +#ifdef HAS_LIBSOUP + SoupServer *server; + + if (main_loop) { + loop = main_loop; + } + + if (!loop || !handlers) { + DEBUG("initializing server"); + xmlrpc_server_init(); + } + + server = xmlrpc_server_new(); + if (!server) { + if (main_loop) { + g_warning("Cannot create XML-RPC server."); + return; + } else { + g_error("Cannot create XML-RPC server. Aborting"); + } + } + + DEBUG("adding soup handlers for /xmlrpc"); + soup_server_add_handler(server, "/xmlrpc", xmlrpc_server_callback, + NULL, NULL); + DEBUG("adding soup handlers for /icon/"); + soup_server_add_handler(server, "/icon/", icon_server_callback, + NULL, NULL); + + DEBUG("starting server"); + g_print("XML-RPC server ready\n"); + g_main_loop_run(loop); + + DEBUG("shutting down server"); + g_main_loop_unref(loop); + soup_server_quit(server); + g_object_unref(server); +#endif /* HAS_LIBSOUP */ +} + +#ifdef XMLRPC_SERVER_TEST +int main(void) +{ +#ifdef HAS_LIBSOUP + g_type_init(); + + xmlrpc_server_init(); + xmlrpc_server_start(); +#endif /* HAS_LIBSOUP */ +} +#endif /* XMLRPC_SERVER_TEST */ diff --git a/hardinfo2/report.c b/hardinfo2/report.c deleted file mode 100644 index fb87ee23..00000000 --- a/hardinfo2/report.c +++ /dev/null @@ -1,890 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2008 Leandro A. F. Pereira - * - * 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 -#include -#include -#include -#include -#include -#include - -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: - http://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, '$') + 1; - - 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, title, g_strdup(value)); - - g_free(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) -{ - if (ctx->output) - g_free(ctx->output); - - ctx->output = - g_strdup_printf - ("\n" - "\n" "HardInfo (%s) System Report\n" - "\n" - "\n" "\n", - VERSION); -} - -static void report_html_footer(ReportContext * ctx) -{ - ctx->output = h_strconcat(ctx->output, - "", NULL); -} - -static void report_html_title(ReportContext * ctx, gchar * text) -{ - if (!ctx->first_table) { - ctx->output = h_strdup_cprintf("", ctx->output); - } - - ctx->output = h_strdup_cprintf("

    %s

    ", 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("", ctx->output); - } else { - ctx->first_table = FALSE; - } - - ctx->output = h_strdup_cprintf("\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("\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; - - if (columns == 2) { - ctx->output = h_strdup_cprintf("" - "\n", - ctx->output, - key, value); - } else { - values = g_strsplit(value, "|", columns); - - ctx->output = h_strdup_cprintf("\n\n", ctx->output, key); - - for (i = columns - 2; i >= 0; i--) { - ctx->output = h_strdup_cprintf("", - ctx->output, - values[i]); - } - - ctx->output = h_strdup_cprintf("\n", ctx->output); - - g_strfreev(values); - } -} - -static void report_text_header(ReportContext * ctx) -{ - if (ctx->output) - 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; - - 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); - - ctx->output = h_strdup_cprintf("%s\t", ctx->output, key); - - for (i = columns - 2; 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; - - 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); - - 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(g_str_hash, g_str_equal); - 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(g_str_hash, g_str_equal); - 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); - 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?"); - gtk_dialog_add_buttons(GTK_DIALOG(dialog), - GTK_STOCK_NO, GTK_RESPONSE_REJECT, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - 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); - - dialog1_vbox = GTK_DIALOG(dialog)->vbox; - gtk_box_set_spacing(GTK_BOX(dialog1_vbox), 5); - gtk_container_set_border_width(GTK_CONTAINER(dialog1_vbox), 4); - gtk_widget_show(dialog1_vbox); - - hbox = gtk_hbox_new(FALSE, 5); - gtk_box_pack_start(GTK_BOX(dialog1_vbox), hbox, FALSE, FALSE, 0); - - label = gtk_label_new("Generate Report\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); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - - 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); - - hbox = gtk_hbox_new(FALSE, 5); - 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); - - vbuttonbox3 = gtk_vbutton_box_new(); - 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); - GTK_WIDGET_SET_FLAGS(button3, GTK_CAN_DEFAULT); - 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); - GTK_WIDGET_SET_FLAGS(button6, GTK_CAN_DEFAULT); - g_signal_connect(button6, "clicked", G_CALLBACK(report_dialog_sel_all), - rd); - - dialog1_action_area = GTK_DIALOG(dialog)->action_area; - gtk_widget_show(dialog1_action_area); - gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog1_action_area), - GTK_BUTTONBOX_END); - - button8 = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - gtk_widget_show(button8); - gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button8, - GTK_RESPONSE_CANCEL); - GTK_WIDGET_SET_FLAGS(button8, GTK_CAN_DEFAULT); - - button7 = gtk_button_new_with_mnemonic("_Generate"); - gtk_widget_show(button7); - gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button7, - GTK_RESPONSE_ACCEPT); - GTK_WIDGET_SET_FLAGS(button7, GTK_CAN_DEFAULT); - - 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/hardinfo2/report.h b/hardinfo2/report.h deleted file mode 100644 index 782621cb..00000000 --- a/hardinfo2/report.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 -#include - -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/hardinfo2/sha1.c b/hardinfo2/sha1.c deleted file mode 100644 index b94ce254..00000000 --- a/hardinfo2/sha1.c +++ /dev/null @@ -1,329 +0,0 @@ -/* -SHA-1 in C -By Steve Reid -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 -#include -#include - -#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 "); - 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/hardinfo2/sha1.h b/hardinfo2/sha1.h deleted file mode 100644 index 573ff8ac..00000000 --- a/hardinfo2/sha1.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SHA-1 in C - * By Steve Reid - * 100% Public Domain - */ - -#ifndef __SHA1_H__ -#define __SHA1_H__ - -#include - -#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/hardinfo2/shell.c b/hardinfo2/shell.c deleted file mode 100644 index 1119c9cf..00000000 --- a/hardinfo2/shell.c +++ /dev/null @@ -1,1961 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 -#include - -#include -#include - -#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 :) ******************************************************************** - */ - -void shell_set_remote_label(Shell *shell, gchar *label) -{ - gchar *tmp; - - tmp = g_strdup_printf("%s ", label); - gtk_label_set_markup(GTK_LABEL(shell->remote_label), tmp); - - g_free(tmp); -} - -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 (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); - } - } -} - -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("RemoteMenuAction", 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); - shell_action_set_enabled("SaveGraphAction", - setting ? shell->view_type == - SHELL_VIEW_PROGRESS : FALSE); -} - -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); - - 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); - - 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); - - hbox = gtk_hbox_new(FALSE, 3); - 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); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_widget_show(vbox); - gtk_container_add(GTK_CONTAINER(shell->window), vbox); - shell->vbox = vbox; - - menu_init(shell); - - hbox = gtk_hbox_new(FALSE, 5); - 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->remote_label = gtk_label_new(""); - gtk_label_set_use_markup(GTK_LABEL(shell->remote_label), TRUE); -#ifdef HAS_LIBSOUP - gtk_widget_show(shell->remote_label); -#else - gtk_widget_hide(shell->remote_label); -#endif - shell_set_remote_label(shell, ""); - gtk_box_pack_end(GTK_BOX(hbox), shell->remote_label, FALSE, FALSE, 0); - - shell->status = gtk_label_new(""); - gtk_misc_set_alignment(GTK_MISC(shell->status), 0.0, 0.5); - gtk_widget_show(shell->status); - gtk_box_pack_start(GTK_BOX(hbox), shell->status, FALSE, FALSE, 5); - - shell->hpaned = gtk_hpaned_new(); - 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); - - vbox = gtk_vbox_new(FALSE, 5); - 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); - - shell->vpaned = gtk_vpaned_new(); - 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 add_module_to_menu(gchar * name, GdkPixbuf * pixbuf) -{ - GtkAction *action; - gchar *about_module = g_strdup_printf("AboutModule%s", name); - 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)); -} - -static GSList *remote_merge_ids = NULL; -static void -add_host_to_view_menu(gchar *hostname) -{ - GtkAction *action; - gint merge_id; - GtkActionEntry entry = { - hostname, /* name */ - HI_STOCK_SERVER, /* stockid */ - hostname, /* label */ - NULL, /* accelerator */ - NULL, /* tooltip */ - (GCallback) cb_connect_host, /* callback */ - }; - - if ((action = gtk_action_group_get_action(shell->action_group, hostname))) { - gtk_action_group_remove_action(shell->action_group, action); - } - - gtk_action_group_add_actions(shell->action_group, &entry, 1, NULL /*data */); - - merge_id = gtk_ui_manager_new_merge_id(shell->ui_manager); - gtk_ui_manager_add_ui(shell->ui_manager, - merge_id, - "/menubar/RemoteMenu/LocalComputer", - hostname, hostname, GTK_UI_MANAGER_AUTO, FALSE); - remote_merge_ids = g_slist_prepend(remote_merge_ids, GINT_TO_POINTER(merge_id)); -} - -void shell_update_remote_menu(void) -{ - GSList *merge_id; - gchar **hosts; - gsize length; - gint i; - - for (merge_id = remote_merge_ids; merge_id; merge_id = merge_id->next) { - gint id = GPOINTER_TO_INT(merge_id->data); - - gtk_ui_manager_remove_ui(shell->ui_manager, id); - } - - hosts = g_key_file_get_groups(shell->hosts, &length); - for (i = length - 1; i >= 0; i--) { - add_host_to_view_menu(g_strdup(hosts[i])); - } - - g_strfreev(hosts); -} - -static void -add_module_entry_to_view_menu(gchar * module, gchar * name, - GdkPixbuf * pixbuf, GtkTreeIter * iter) -{ - GtkAction *action; - 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)); - 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); -} - -void shell_save_hosts_file(void) -{ - gchar *path, *remote_conf; - gsize length; - - DEBUG("saving hosts file"); - - path = g_build_filename(g_get_home_dir(), ".hardinfo", "remote.conf", NULL); - - remote_conf = g_key_file_to_data(shell->hosts, &length, NULL); - g_file_set_contents(path, remote_conf, length, NULL); - - g_chmod(path, 0600); - - g_free(remote_conf); - g_free(path); -} - -ShellSummary *summary_new(void) -{ - ShellSummary *summary; - - summary = g_new0(ShellSummary, 1); - summary->scroll = gtk_scrolled_window_new(NULL, NULL); - summary->view = gtk_vbox_new(FALSE, 5); - 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); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(summary->scroll), - summary->view); - gtk_widget_show_all(summary->scroll); - - return summary; -} - -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("ContextHelpAction", FALSE); - shell_action_set_enabled("RefreshAction", FALSE); - shell_action_set_enabled("CopyAction", FALSE); - shell_action_set_enabled("SaveGraphAction", 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); - - { - gchar *path; - - shell->hosts = g_key_file_new(); - path = g_build_filename(g_get_home_dir(), ".hardinfo", "remote.conf", NULL); - g_key_file_load_from_file(shell->hosts, path, 0, NULL); - g_free(path); - - g_atexit(shell_save_hosts_file); - - shell_update_remote_menu(); - } -#endif -} - -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, atoi(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 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 */ - pos_info_scroll = RANGE_GET_VALUE(info, vscrollbar); - pos_more_scroll = RANGE_GET_VALUE(moreinfo, vscrollbar); - - /* avoid drawing the window while we reload */ - gdk_window_freeze_updates(shell->window->window); - - /* 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 */ - RANGE_SET_VALUE(info, vscrollbar, pos_info_scroll); - RANGE_SET_VALUE(moreinfo, vscrollbar, pos_more_scroll); - } - - /* make the window drawable again */ - gdk_window_thaw_updates(shell->window->window); - } - - /* 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; -} - -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 == NULL || col2 == NULL) { - if (col1 == NULL && col2 == NULL) - return 0; - - ret = (col1 == NULL) ? -1 : 1; - } else { - ret = shell->_order_type ? (atof(col1) < atof(col2)) : - (atof(col1) > atof(col2)); - } - - g_free(col1); - g_free(col2); - - return ret; -} - -static void set_view_type(ShellViewType viewtype, gboolean reload) -{ - if (viewtype < SHELL_VIEW_NORMAL || viewtype >= SHELL_VIEW_N_VIEWS) - viewtype = SHELL_VIEW_NORMAL; - - shell->normalize_percentage = TRUE; - shell->view_type = viewtype; - - /* reset to the default model */ - gtk_tree_view_set_model(GTK_TREE_VIEW(shell->info->view), - shell->info->model); - - /* 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 */ - gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(shell->info->view), FALSE); - - /* turn off the save graphic action */ - shell_action_set_enabled("SaveGraphAction", FALSE); - - 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_page(GTK_NOTEBOOK(shell->notebook), 0); - gtk_widget_show(shell->notebook); - break; - case SHELL_VIEW_LOAD_GRAPH: - gtk_widget_show(shell->info->scroll); - gtk_notebook_set_page(GTK_NOTEBOOK(shell->notebook), 1); - gtk_widget_show(shell->notebook); - load_graph_clear(shell->loadgraph); - - gtk_paned_set_position(GTK_PANED(shell->vpaned), - shell->hpaned->allocation.height - - shell->loadgraph->height - 16); - break; - case SHELL_VIEW_PROGRESS_DUAL: - gtk_widget_show(shell->notebook); - gtk_widget_show(shell->moreinfo->scroll); - - gtk_notebook_set_page(GTK_NOTEBOOK(shell->notebook), 0); - /* fallthrough */ - case SHELL_VIEW_PROGRESS: - gtk_widget_show(shell->info->scroll); - shell_action_set_enabled("SaveGraphAction", TRUE); - - 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_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(strchr(key, '$') + 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 = strchr(key, '$') + 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, - strchr(key, - '$') + 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")) { - gtk_tree_view_set_rules_hint(GTK_TREE_VIEW - (shell->info->view), - g_key_file_get_boolean - (key_file, group, key, NULL)); - } - } - - 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 (strchr(value, '|')) { - 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 = 0, maxp = 0, cur, floatval; - - 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); - maxv = MAX(maxv, cur); - - g_free(tmp); - } while (gtk_tree_model_iter_next(model, &iter)); - } else { - maxv = 100.0f; - } - - /* calculates the relative percentage and finds the maximum percentage */ - if (shell->_order_type == SHELL_ORDER_ASCENDING) { - iter = fiter; - do { - gtk_tree_model_get(model, &iter, INFO_TREE_COL_VALUE, &tmp, -1); - - cur = 100 - 100 * atof(tmp) / maxv; - maxp = MAX(cur, maxp); - - g_free(tmp); - } while (gtk_tree_model_iter_next(model, &iter)); - - maxp = 100 - maxp; - } - - /* fix the maximum relative percentage */ - iter = fiter; - do { - char *strval; - - gtk_tree_model_get(model, &iter, INFO_TREE_COL_VALUE, &tmp, -1); - floatval = atof(tmp); - strval = g_strdup(tmp); - g_free(tmp); - - cur = 100 * floatval / maxv; - - if (shell->_order_type == SHELL_ORDER_ASCENDING) - cur = 100 - cur + maxp; - - if (strchr(strval, ' ')) { - tmp = g_strdup_printf("%.2f%s", floatval, strchr(strval, ' ')); - } else { - tmp = g_strdup_printf("%.2f", floatval); - } - - tmp = strreplacechr(tmp, ",", '.'); - gtk_tree_store_set(store, &iter, INFO_TREE_COL_PROGRESS, cur, - INFO_TREE_COL_VALUE, tmp, -1); - g_free(tmp); - g_free(strval); - } 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 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; - - module_entry_scan(entry); - key_data = module_entry_function(entry); - - /* */ - gdk_window_freeze_updates(shell->info->view->window); - - 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)); - - gdk_window_thaw_updates(shell->info->view->window); - 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); -} - -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) { - 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 (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); - - frame_label_box = gtk_hbox_new(FALSE, 5); - 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); - - alignment = gtk_alignment_new(0.5, 0.5, 1, 1); - gtk_widget_show(alignment); - gtk_container_add(GTK_CONTAINER(frame), alignment); - gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 48, 0); - - content = gtk_label_new(temp); - gtk_misc_set_alignment(GTK_MISC(content), 0.0, 0.5); - gtk_container_add(GTK_CONTAINER(alignment), content); - - 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; - - 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("%s \342\206\222 Summary", 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; - - /* 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? */ - 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); - - title = g_strdup_printf("%s - %s", shell->selected_module->name, entry->name); - shell_set_title(shell, title); - g_free(title); - - if (entry->flags & MODULE_FLAG_HAS_HELP) { - gchar *temp; - - shell_action_set_enabled("ContextHelpAction", TRUE); - - temp = g_strdup_printf("Help on %s \342\206\222 %s", - shell->selected_module->name, - entry->name); - shell_action_set_label("ContextHelpAction", temp); - - g_free(temp); - } else { - shell_action_set_enabled("ContextHelpAction", FALSE); - shell_action_set_label("ContextHelpAction", "Context help"); - } - - 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); - - shell_action_set_enabled("ContextHelpAction", FALSE); - shell_action_set_label("ContextHelpAction", "Context help"); - - 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); - - 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/hardinfo2/shell.h b/hardinfo2/shell.h deleted file mode 100644 index 2eb9e6d2..00000000 --- a/hardinfo2/shell.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 - -#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/hardinfo2/shell/callbacks.c b/hardinfo2/shell/callbacks.c new file mode 100644 index 00000000..021560e2 --- /dev/null +++ b/hardinfo2/shell/callbacks.c @@ -0,0 +1,430 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 +#include + +#include "hardinfo.h" +#include "callbacks.h" +#include "iconcache.h" + +#include "shell.h" +#include "report.h" +#include "remote.h" +#include "syncmanager.h" +#include "help-viewer.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_connect_to() +{ +#ifdef HAS_LIBSOUP + Shell *shell = shell_get_main_shell(); + + connect_dialog_show(shell->window); +#endif /* HAS_LIBSOUP */ +} + +void cb_manage_hosts() +{ +#ifdef HAS_LIBSOUP + Shell *shell = shell_get_main_shell(); + + host_manager_show(shell->window); +#endif /* HAS_LIBSOUP */ +} + +void cb_connect_host(GtkAction * action) +{ +#ifdef HAS_LIBSOUP + Shell *shell = shell_get_main_shell(); + gchar *name; + + g_object_get(G_OBJECT(action), "name", &name, NULL); + + if (remote_connect_host(name)) { + gchar *tmp; + + tmp = g_strdup_printf("Remote: %s", name); + shell_set_remote_label(shell, tmp); + + g_free(tmp); + } else { + cb_local_computer(); + } + + g_free(name); +#endif /* HAS_LIBSOUP */ +} + +static gboolean server_start_helper(gpointer server_loop) +{ +#ifdef HAS_LIBSOUP + GMainLoop *loop = (GMainLoop *)server_loop; + + xmlrpc_server_start(loop); + + return FALSE; +#endif /* HAS_LIBSOUP */ +} + +void cb_act_as_server() +{ +#ifdef HAS_LIBSOUP + gboolean accepting; + static GMainLoop *server_loop = NULL; + + accepting = shell_action_get_active("ActAsServerAction"); + if (accepting) { + server_loop = g_main_loop_new(NULL, FALSE); + g_idle_add(server_start_helper, server_loop); + } else { + g_main_loop_quit(server_loop); + } +#endif /* HAS_LIBSOUP */ +} + +void cb_local_computer() +{ +#ifdef HAS_LIBSOUP + Shell *shell = shell_get_main_shell(); + + shell_status_update("Disconnecting..."); + remote_disconnect_all(TRUE); + + shell_status_update("Unloading modules..."); + module_unload_all(); + + shell_status_update("Loading local modules..."); + shell->tree->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)); + + shell_view_set_enabled(TRUE); + shell_status_update("Done."); + shell_set_remote_label(shell, ""); +#endif /* HAS_LIBSOUP */ +} + +void cb_save_graphic() +{ + Shell *shell = shell_get_main_shell(); + GtkWidget *dialog; + gchar *filename; + + /* save the pixbuf to a png file */ + dialog = gtk_file_chooser_dialog_new("Save Image", + NULL, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, + GTK_RESPONSE_ACCEPT, NULL); + + filename = g_strconcat(shell->selected->name, ".png", NULL); + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename); + g_free(filename); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + gtk_widget_destroy(dialog); + + shell_status_update("Saving image..."); + + tree_view_save_image(filename); + + shell_status_update("Done."); + g_free(filename); + + return; + } + + gtk_widget_destroy(dialog); +} + +void cb_open_web_page() +{ + open_url("http://wiki.hardinfo.org"); +} + +void cb_open_online_docs() +{ + Shell *shell; + + shell = shell_get_main_shell(); + if (shell->help_viewer) { + help_viewer_open_page(shell->help_viewer, "index.hlp"); + } else { + gchar *help_dir; + + help_dir = g_build_filename(params.path_data, "doc", NULL); + shell->help_viewer = help_viewer_new(help_dir, "index.hlp"); + g_free(help_dir); + } +} + +void cb_open_online_docs_context() +{ + Shell *shell; + + shell = shell_get_main_shell(); + + if (shell->selected->flags & MODULE_FLAG_HAS_HELP) { + gchar *temp; + + if (shell->selected_module->dll) { + gchar *name_temp; + + name_temp = (gchar *)g_module_name(shell->selected_module->dll); + name_temp = g_path_get_basename(name_temp); + strend(name_temp, '.'); + + temp = g_strdup_printf("context-help-%s-%d.hlp", + name_temp, + shell->selected->number); + + g_free(name_temp); + } else { + goto no_context_help; + } + + if (shell->help_viewer) { + help_viewer_open_page(shell->help_viewer, temp); + } else { + gchar *help_dir; + + help_dir = g_build_filename(params.path_data, "doc", NULL); + shell->help_viewer = help_viewer_new(help_dir, temp); + g_free(help_dir); + } + + g_free(temp); + } else { + GtkWidget *dialog; + +no_context_help: + dialog = gtk_message_dialog_new(GTK_WINDOW(shell->window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "No context help available."); + + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + } +} + +void cb_report_bug() +{ + open_url("http://wiki.hardinfo.org/BugReports"); +} + +void cb_donate() +{ + open_url("http://wiki.hardinfo.org/Donate"); +} + +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(); + + text = g_strdup_printf("%s Module", sm->name); + gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(about), text); + 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() +{ + GtkWidget *about; + const gchar *authors[] = { + "Author:", + "Leandro A. F. Pereira", + "", + "Contributors:", + "Agney Lopes Roth Ferraz", + "Andrey Esin", + "", + "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_about_dialog_set_name(GTK_ABOUT_DIALOG(about), "HardInfo"); + gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about), VERSION); + gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about), + "Copyright \302\251 2003-2009 " + "Leandro A. F. Pereira"); + 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"); +#if GTK_CHECK_VERSION(2,8,0) + gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(about), TRUE); +#endif + + gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about), authors); + gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(about), artists); + + gtk_dialog_run(GTK_DIALOG(about)); + gtk_widget_destroy(about); +} + +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/hardinfo2/shell/iconcache.c b/hardinfo2/shell/iconcache.c new file mode 100644 index 00000000..74b19b0c --- /dev/null +++ b/hardinfo2/shell/iconcache.c @@ -0,0 +1,100 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 +#include +#include + +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/hardinfo2/shell/loadgraph.c b/hardinfo2/shell/loadgraph.c new file mode 100644 index 00000000..c8503072 --- /dev/null +++ b/hardinfo2/shell/loadgraph.c @@ -0,0 +1,347 @@ +/* + * 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 + * + * 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" + +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); + +#if 0 /* old-style grid */ + gdk_rgb_gc_set_foreground(lg->grid, 0x707070); +#endif + + gdk_gc_set_line_attributes(lg->trace, + 1, GDK_LINE_SOLID, + GDK_CAP_PROJECTING, GDK_JOIN_ROUND); + +#if 0 /* old-style fill */ + gdk_gc_set_line_attributes(lg->fill, + 1, GDK_LINE_SOLID, + GDK_CAP_BUTT, GDK_JOIN_BEVEL); +#endif + + /* 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("%d%s", 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); + +#if 0 /* old-style drawing */ + for (i = 0; i < lg->size; i++) { + gint this = lg->height - lg->data[i] * lg->scale; + gint next = lg->height - lg->data[i + 1] * lg->scale; + gint i4 = i * 4; + + gdk_draw_line(draw, lg->fill, i4, this, i4, lg->height); + gdk_draw_line(draw, lg->fill, i4 + 2, this, i4 + 2, lg->height); + } + + for (i = 0; i < lg->size; i++) { + gint this = lg->height - lg->data[i] * lg->scale; + gint next = lg->height - lg->data[i + 1] * lg->scale; + gint i4 = i * 4; + + gdk_draw_line(draw, lg->trace, i4, this, i4 + 2, + (this + next) / 2); + gdk_draw_line(draw, lg->trace, i4 + 2, (this + next) / 2, + i4 + 4, next); + } +#endif + + gtk_widget_queue_draw(lg->area); +} + +void load_graph_update(LoadGraph * lg, gint value) +{ + gint i; + + if (value < 0) + return; + + /* shift-right our data */ + for (i = 0; i < lg->size; 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); +} + +#ifdef LOADGRAPH_UNIT_TEST +gboolean lg_update(gpointer d) +{ + LoadGraph *lg = (LoadGraph *) d; + + static int i = 0; + static int j = 1; + + if (i > 150) { + j = -1; + } else if (i < 0) { + j = 1; + } + + i += j; + if (rand() % 10 > 8) + i *= 2; + if (rand() % 10 < 2) + i /= 2; + load_graph_update(lg, i + rand() % 50); + + return TRUE; +} + +int main(int argc, char **argv) +{ + LoadGraph *lg; + GtkWidget *window; + + gtk_init(&argc, &argv); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_show(window); + + lg = load_graph_new(50); + gtk_container_add(GTK_CONTAINER(window), load_graph_get_framed(lg)); + gtk_container_set_border_width(GTK_CONTAINER(window), 20); + load_graph_configure_expose(lg); + + lg_update(lg); + + g_timeout_add(100, lg_update, lg); + + gtk_main(); + + return 0; +} +#endif diff --git a/hardinfo2/shell/menu.c b/hardinfo2/shell/menu.c new file mode 100644 index 00000000..6b96e271 --- /dev/null +++ b/hardinfo2/shell/menu.c @@ -0,0 +1,202 @@ +/* + * 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 +#include +#include + +#include + +#include +#include + +#include "uidefs.h" + +static GtkActionEntry entries[] = { + {"InformationMenuAction", NULL, "_Information"}, /* name, stock id, label */ + {"RemoteMenuAction", NULL, "_Remote"}, + {"ViewMenuAction", NULL, "_View"}, + {"HelpMenuAction", NULL, "_Help"}, + {"HelpMenuModulesAction", HI_STOCK_ABOUT_MODULES, "About _Modules"}, + {"MainMenuBarAction", NULL, ""}, + + {"ReportAction", HI_STOCK_REPORT, /* name, stock id */ + "Generate _Report", "R", /* label, accelerator */ + NULL, /* tooltip */ + G_CALLBACK(cb_generate_report)}, + + {"SyncManagerAction", HI_STOCK_SYNC_MENU, + "_Network Updater...", NULL, + NULL, + G_CALLBACK(cb_sync_manager)}, + + {"OpenAction", GTK_STOCK_OPEN, + "_Open...", NULL, + NULL, + G_CALLBACK(cb_sync_manager)}, + + {"ConnectToAction", GTK_STOCK_CONNECT, + "_Connect to...", NULL, + NULL, + G_CALLBACK(cb_connect_to)}, + + {"ManageAction", NULL, + "_Manage hosts...", NULL, + NULL, + G_CALLBACK(cb_manage_hosts)}, + + {"LocalComputerAction", GTK_STOCK_HOME, + "_Local computer", NULL, + NULL, + G_CALLBACK(cb_local_computer)}, + + {"CopyAction", GTK_STOCK_COPY, + "_Copy to Clipboard", "C", + "Copy to clipboard", + G_CALLBACK(cb_copy_to_clipboard)}, + + {"SaveGraphAction", GTK_STOCK_SAVE_AS, + "_Save image as...", "S", + NULL, + G_CALLBACK(cb_save_graphic)}, + + {"RefreshAction", GTK_STOCK_REFRESH, + "_Refresh", "F5", + NULL, + G_CALLBACK(cb_refresh)}, + + {"OnlineDocsAction", GTK_STOCK_HELP, + "Contents", "F1", + NULL, + G_CALLBACK(cb_open_online_docs)}, + + {"ContextHelpAction", NULL, + "Context help", "F1", + NULL, + G_CALLBACK(cb_open_online_docs_context)}, + + {"HomePageAction", HI_STOCK_INTERNET, + "_Open HardInfo Web Site", NULL, + NULL, + G_CALLBACK(cb_open_web_page)}, + + {"ReportBugAction", HI_STOCK_INTERNET, + "_Report bug", NULL, + NULL, + G_CALLBACK(cb_report_bug)}, + + {"DonateAction", HI_STOCK_DONATE, + "_Donate to the project", NULL, + NULL, + G_CALLBACK(cb_donate)}, + + {"AboutAction", GTK_STOCK_ABOUT, + "_About HardInfo", NULL, + "Displays program version information", + G_CALLBACK(cb_about)}, + + {"QuitAction", GTK_STOCK_QUIT, + "_Quit", "Q", + NULL, + G_CALLBACK(cb_quit)} +}; + +static GtkToggleActionEntry toggle_entries[] = { + {"SidePaneAction", NULL, + "_Side Pane", NULL, + "Toggles side pane visibility", + G_CALLBACK(cb_side_pane)}, + {"ToolbarAction", NULL, + "_Toolbar", NULL, + NULL, + G_CALLBACK(cb_toolbar)}, + {"ActAsServerAction", NULL, + "_Accept connections", NULL, + NULL, + G_CALLBACK(cb_act_as_server) } +}; + +/* 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_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/hardinfo2/shell/report.c b/hardinfo2/shell/report.c new file mode 100644 index 00000000..fb87ee23 --- /dev/null +++ b/hardinfo2/shell/report.c @@ -0,0 +1,890 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2008 Leandro A. F. Pereira + * + * 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 +#include +#include +#include +#include +#include +#include + +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: + http://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, '$') + 1; + + 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, title, g_strdup(value)); + + g_free(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) +{ + if (ctx->output) + g_free(ctx->output); + + ctx->output = + g_strdup_printf + ("\n" + "\n" "HardInfo (%s) System Report\n" + "\n" + "\n" "\n", + VERSION); +} + +static void report_html_footer(ReportContext * ctx) +{ + ctx->output = h_strconcat(ctx->output, + "
    %s
    %s
    %s%s
    %s%s
    ", NULL); +} + +static void report_html_title(ReportContext * ctx, gchar * text) +{ + if (!ctx->first_table) { + ctx->output = h_strdup_cprintf("", ctx->output); + } + + ctx->output = h_strdup_cprintf("

    %s

    ", 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("", ctx->output); + } else { + ctx->first_table = FALSE; + } + + ctx->output = h_strdup_cprintf("\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("\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; + + if (columns == 2) { + ctx->output = h_strdup_cprintf("" + "\n", + ctx->output, + key, value); + } else { + values = g_strsplit(value, "|", columns); + + ctx->output = h_strdup_cprintf("\n\n", ctx->output, key); + + for (i = columns - 2; i >= 0; i--) { + ctx->output = h_strdup_cprintf("", + ctx->output, + values[i]); + } + + ctx->output = h_strdup_cprintf("\n", ctx->output); + + g_strfreev(values); + } +} + +static void report_text_header(ReportContext * ctx) +{ + if (ctx->output) + 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; + + 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); + + ctx->output = h_strdup_cprintf("%s\t", ctx->output, key); + + for (i = columns - 2; 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; + + 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); + + 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(g_str_hash, g_str_equal); + 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(g_str_hash, g_str_equal); + 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); + 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?"); + gtk_dialog_add_buttons(GTK_DIALOG(dialog), + GTK_STOCK_NO, GTK_RESPONSE_REJECT, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + 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); + + dialog1_vbox = GTK_DIALOG(dialog)->vbox; + gtk_box_set_spacing(GTK_BOX(dialog1_vbox), 5); + gtk_container_set_border_width(GTK_CONTAINER(dialog1_vbox), 4); + gtk_widget_show(dialog1_vbox); + + hbox = gtk_hbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(dialog1_vbox), hbox, FALSE, FALSE, 0); + + label = gtk_label_new("Generate Report\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); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + + 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); + + hbox = gtk_hbox_new(FALSE, 5); + 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); + + vbuttonbox3 = gtk_vbutton_box_new(); + 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); + GTK_WIDGET_SET_FLAGS(button3, GTK_CAN_DEFAULT); + 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); + GTK_WIDGET_SET_FLAGS(button6, GTK_CAN_DEFAULT); + g_signal_connect(button6, "clicked", G_CALLBACK(report_dialog_sel_all), + rd); + + dialog1_action_area = GTK_DIALOG(dialog)->action_area; + gtk_widget_show(dialog1_action_area); + gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog1_action_area), + GTK_BUTTONBOX_END); + + button8 = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_widget_show(button8); + gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button8, + GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS(button8, GTK_CAN_DEFAULT); + + button7 = gtk_button_new_with_mnemonic("_Generate"); + gtk_widget_show(button7); + gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button7, + GTK_RESPONSE_ACCEPT); + GTK_WIDGET_SET_FLAGS(button7, GTK_CAN_DEFAULT); + + 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/hardinfo2/shell/shell.c b/hardinfo2/shell/shell.c new file mode 100644 index 00000000..1119c9cf --- /dev/null +++ b/hardinfo2/shell/shell.c @@ -0,0 +1,1961 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 +#include + +#include +#include + +#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 :) ******************************************************************** + */ + +void shell_set_remote_label(Shell *shell, gchar *label) +{ + gchar *tmp; + + tmp = g_strdup_printf("%s ", label); + gtk_label_set_markup(GTK_LABEL(shell->remote_label), tmp); + + g_free(tmp); +} + +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 (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); + } + } +} + +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("RemoteMenuAction", 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); + shell_action_set_enabled("SaveGraphAction", + setting ? shell->view_type == + SHELL_VIEW_PROGRESS : FALSE); +} + +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); + + 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); + + 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); + + hbox = gtk_hbox_new(FALSE, 3); + 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); + + vbox = gtk_vbox_new(FALSE, 0); + gtk_widget_show(vbox); + gtk_container_add(GTK_CONTAINER(shell->window), vbox); + shell->vbox = vbox; + + menu_init(shell); + + hbox = gtk_hbox_new(FALSE, 5); + 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->remote_label = gtk_label_new(""); + gtk_label_set_use_markup(GTK_LABEL(shell->remote_label), TRUE); +#ifdef HAS_LIBSOUP + gtk_widget_show(shell->remote_label); +#else + gtk_widget_hide(shell->remote_label); +#endif + shell_set_remote_label(shell, ""); + gtk_box_pack_end(GTK_BOX(hbox), shell->remote_label, FALSE, FALSE, 0); + + shell->status = gtk_label_new(""); + gtk_misc_set_alignment(GTK_MISC(shell->status), 0.0, 0.5); + gtk_widget_show(shell->status); + gtk_box_pack_start(GTK_BOX(hbox), shell->status, FALSE, FALSE, 5); + + shell->hpaned = gtk_hpaned_new(); + 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); + + vbox = gtk_vbox_new(FALSE, 5); + 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); + + shell->vpaned = gtk_vpaned_new(); + 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 add_module_to_menu(gchar * name, GdkPixbuf * pixbuf) +{ + GtkAction *action; + gchar *about_module = g_strdup_printf("AboutModule%s", name); + 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)); +} + +static GSList *remote_merge_ids = NULL; +static void +add_host_to_view_menu(gchar *hostname) +{ + GtkAction *action; + gint merge_id; + GtkActionEntry entry = { + hostname, /* name */ + HI_STOCK_SERVER, /* stockid */ + hostname, /* label */ + NULL, /* accelerator */ + NULL, /* tooltip */ + (GCallback) cb_connect_host, /* callback */ + }; + + if ((action = gtk_action_group_get_action(shell->action_group, hostname))) { + gtk_action_group_remove_action(shell->action_group, action); + } + + gtk_action_group_add_actions(shell->action_group, &entry, 1, NULL /*data */); + + merge_id = gtk_ui_manager_new_merge_id(shell->ui_manager); + gtk_ui_manager_add_ui(shell->ui_manager, + merge_id, + "/menubar/RemoteMenu/LocalComputer", + hostname, hostname, GTK_UI_MANAGER_AUTO, FALSE); + remote_merge_ids = g_slist_prepend(remote_merge_ids, GINT_TO_POINTER(merge_id)); +} + +void shell_update_remote_menu(void) +{ + GSList *merge_id; + gchar **hosts; + gsize length; + gint i; + + for (merge_id = remote_merge_ids; merge_id; merge_id = merge_id->next) { + gint id = GPOINTER_TO_INT(merge_id->data); + + gtk_ui_manager_remove_ui(shell->ui_manager, id); + } + + hosts = g_key_file_get_groups(shell->hosts, &length); + for (i = length - 1; i >= 0; i--) { + add_host_to_view_menu(g_strdup(hosts[i])); + } + + g_strfreev(hosts); +} + +static void +add_module_entry_to_view_menu(gchar * module, gchar * name, + GdkPixbuf * pixbuf, GtkTreeIter * iter) +{ + GtkAction *action; + 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)); + 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); +} + +void shell_save_hosts_file(void) +{ + gchar *path, *remote_conf; + gsize length; + + DEBUG("saving hosts file"); + + path = g_build_filename(g_get_home_dir(), ".hardinfo", "remote.conf", NULL); + + remote_conf = g_key_file_to_data(shell->hosts, &length, NULL); + g_file_set_contents(path, remote_conf, length, NULL); + + g_chmod(path, 0600); + + g_free(remote_conf); + g_free(path); +} + +ShellSummary *summary_new(void) +{ + ShellSummary *summary; + + summary = g_new0(ShellSummary, 1); + summary->scroll = gtk_scrolled_window_new(NULL, NULL); + summary->view = gtk_vbox_new(FALSE, 5); + 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); + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(summary->scroll), + summary->view); + gtk_widget_show_all(summary->scroll); + + return summary; +} + +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("ContextHelpAction", FALSE); + shell_action_set_enabled("RefreshAction", FALSE); + shell_action_set_enabled("CopyAction", FALSE); + shell_action_set_enabled("SaveGraphAction", 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); + + { + gchar *path; + + shell->hosts = g_key_file_new(); + path = g_build_filename(g_get_home_dir(), ".hardinfo", "remote.conf", NULL); + g_key_file_load_from_file(shell->hosts, path, 0, NULL); + g_free(path); + + g_atexit(shell_save_hosts_file); + + shell_update_remote_menu(); + } +#endif +} + +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, atoi(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 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 */ + pos_info_scroll = RANGE_GET_VALUE(info, vscrollbar); + pos_more_scroll = RANGE_GET_VALUE(moreinfo, vscrollbar); + + /* avoid drawing the window while we reload */ + gdk_window_freeze_updates(shell->window->window); + + /* 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 */ + RANGE_SET_VALUE(info, vscrollbar, pos_info_scroll); + RANGE_SET_VALUE(moreinfo, vscrollbar, pos_more_scroll); + } + + /* make the window drawable again */ + gdk_window_thaw_updates(shell->window->window); + } + + /* 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; +} + +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 == NULL || col2 == NULL) { + if (col1 == NULL && col2 == NULL) + return 0; + + ret = (col1 == NULL) ? -1 : 1; + } else { + ret = shell->_order_type ? (atof(col1) < atof(col2)) : + (atof(col1) > atof(col2)); + } + + g_free(col1); + g_free(col2); + + return ret; +} + +static void set_view_type(ShellViewType viewtype, gboolean reload) +{ + if (viewtype < SHELL_VIEW_NORMAL || viewtype >= SHELL_VIEW_N_VIEWS) + viewtype = SHELL_VIEW_NORMAL; + + shell->normalize_percentage = TRUE; + shell->view_type = viewtype; + + /* reset to the default model */ + gtk_tree_view_set_model(GTK_TREE_VIEW(shell->info->view), + shell->info->model); + + /* 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 */ + gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(shell->info->view), FALSE); + + /* turn off the save graphic action */ + shell_action_set_enabled("SaveGraphAction", FALSE); + + 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_page(GTK_NOTEBOOK(shell->notebook), 0); + gtk_widget_show(shell->notebook); + break; + case SHELL_VIEW_LOAD_GRAPH: + gtk_widget_show(shell->info->scroll); + gtk_notebook_set_page(GTK_NOTEBOOK(shell->notebook), 1); + gtk_widget_show(shell->notebook); + load_graph_clear(shell->loadgraph); + + gtk_paned_set_position(GTK_PANED(shell->vpaned), + shell->hpaned->allocation.height - + shell->loadgraph->height - 16); + break; + case SHELL_VIEW_PROGRESS_DUAL: + gtk_widget_show(shell->notebook); + gtk_widget_show(shell->moreinfo->scroll); + + gtk_notebook_set_page(GTK_NOTEBOOK(shell->notebook), 0); + /* fallthrough */ + case SHELL_VIEW_PROGRESS: + gtk_widget_show(shell->info->scroll); + shell_action_set_enabled("SaveGraphAction", TRUE); + + 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_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(strchr(key, '$') + 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 = strchr(key, '$') + 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, + strchr(key, + '$') + 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")) { + gtk_tree_view_set_rules_hint(GTK_TREE_VIEW + (shell->info->view), + g_key_file_get_boolean + (key_file, group, key, NULL)); + } + } + + 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 (strchr(value, '|')) { + 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 = 0, maxp = 0, cur, floatval; + + 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); + maxv = MAX(maxv, cur); + + g_free(tmp); + } while (gtk_tree_model_iter_next(model, &iter)); + } else { + maxv = 100.0f; + } + + /* calculates the relative percentage and finds the maximum percentage */ + if (shell->_order_type == SHELL_ORDER_ASCENDING) { + iter = fiter; + do { + gtk_tree_model_get(model, &iter, INFO_TREE_COL_VALUE, &tmp, -1); + + cur = 100 - 100 * atof(tmp) / maxv; + maxp = MAX(cur, maxp); + + g_free(tmp); + } while (gtk_tree_model_iter_next(model, &iter)); + + maxp = 100 - maxp; + } + + /* fix the maximum relative percentage */ + iter = fiter; + do { + char *strval; + + gtk_tree_model_get(model, &iter, INFO_TREE_COL_VALUE, &tmp, -1); + floatval = atof(tmp); + strval = g_strdup(tmp); + g_free(tmp); + + cur = 100 * floatval / maxv; + + if (shell->_order_type == SHELL_ORDER_ASCENDING) + cur = 100 - cur + maxp; + + if (strchr(strval, ' ')) { + tmp = g_strdup_printf("%.2f%s", floatval, strchr(strval, ' ')); + } else { + tmp = g_strdup_printf("%.2f", floatval); + } + + tmp = strreplacechr(tmp, ",", '.'); + gtk_tree_store_set(store, &iter, INFO_TREE_COL_PROGRESS, cur, + INFO_TREE_COL_VALUE, tmp, -1); + g_free(tmp); + g_free(strval); + } 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 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; + + module_entry_scan(entry); + key_data = module_entry_function(entry); + + /* */ + gdk_window_freeze_updates(shell->info->view->window); + + 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)); + + gdk_window_thaw_updates(shell->info->view->window); + 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); +} + +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) { + 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 (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); + + frame_label_box = gtk_hbox_new(FALSE, 5); + 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); + + alignment = gtk_alignment_new(0.5, 0.5, 1, 1); + gtk_widget_show(alignment); + gtk_container_add(GTK_CONTAINER(frame), alignment); + gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 48, 0); + + content = gtk_label_new(temp); + gtk_misc_set_alignment(GTK_MISC(content), 0.0, 0.5); + gtk_container_add(GTK_CONTAINER(alignment), content); + + 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; + + 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("%s \342\206\222 Summary", 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; + + /* 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? */ + 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); + + title = g_strdup_printf("%s - %s", shell->selected_module->name, entry->name); + shell_set_title(shell, title); + g_free(title); + + if (entry->flags & MODULE_FLAG_HAS_HELP) { + gchar *temp; + + shell_action_set_enabled("ContextHelpAction", TRUE); + + temp = g_strdup_printf("Help on %s \342\206\222 %s", + shell->selected_module->name, + entry->name); + shell_action_set_label("ContextHelpAction", temp); + + g_free(temp); + } else { + shell_action_set_enabled("ContextHelpAction", FALSE); + shell_action_set_label("ContextHelpAction", "Context help"); + } + + 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); + + shell_action_set_enabled("ContextHelpAction", FALSE); + shell_action_set_label("ContextHelpAction", "Context help"); + + 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); + + 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/hardinfo2/shell/stock.c b/hardinfo2/shell/stock.c new file mode 100644 index 00000000..ad1a0135 --- /dev/null +++ b/hardinfo2/shell/stock.c @@ -0,0 +1,91 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 +#include +#include +#include + +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) +{ + 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); +} + +void stock_icon_register_pixbuf(GdkPixbuf * pixbuf, gchar * stock_id) +{ + 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); +} + +void stock_icons_init(void) +{ + gint i; + guint n_stock_icons = G_N_ELEMENTS(stock_icons); + + DEBUG("initializing stock icons"); + + icon_factory = gtk_icon_factory_new(); + + for (i = 0; i < n_stock_icons; i++) { + stock_icon_register(stock_icons[i].filename, + stock_icons[i].stock_id); + } + + gtk_icon_factory_add_default(icon_factory); + + g_object_unref(icon_factory); +} diff --git a/hardinfo2/shell/syncmanager.c b/hardinfo2/shell/syncmanager.c new file mode 100644 index 00000000..496dc348 --- /dev/null +++ b/hardinfo2/shell/syncmanager.c @@ -0,0 +1,758 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 + +#include +#include + +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 "http://hardinfo.berlios.de/xmlrpc/" +#define XMLRPC_SERVER_API_VERSION 1 + +#define LABEL_SYNC_DEFAULT "Synchronize with Central Database\n" \ + "The following information may be synchronized " \ + "with the HardInfo central database." +#define LABEL_SYNC_SYNCING "Synchronizing\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; + } + + if (!soup_xmlrpc_extract_method_response(msg->response_body->data, + msg->response_body->length, + NULL, + G_TYPE_INT, &int_value)) { + SNA_ERROR(2, "Could not parse XML-RPC response"); + } + + 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; + } + + if (!soup_xmlrpc_extract_method_response(msg->response_body->data, + msg->response_body->length, + NULL, + G_TYPE_STRING, &string)) { + SNA_ERROR(2, "Could not parse XML-RPC response"); + } + + bad: + return string; +} + +static gboolean _soup_xmlrpc_call(gchar * method, SyncNetAction * sna, + SoupSessionCallback callback) +{ + SoupMessage *msg; + + sna->error = NULL; + + msg = soup_xmlrpc_request_new(XMLRPC_SERVER_URI, method, + G_TYPE_INVALID); + 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; + GValueArray *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; + + parameters = g_value_array_new(1); + va_start(ap, callback); + while ((argument = va_arg(ap, gchar *))) { + soup_value_array_append(parameters, G_TYPE_STRING, argument); + DEBUG("with parameter: %s", argument); + } + va_end(ap); + + body = soup_xmlrpc_build_method_call(method, parameters->values, + parameters->n_values); + g_value_array_free(parameters); + 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; +} + +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)) { + if (str_data) + g_free(str_data); + + return FALSE; + } + + if (str_data) + 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_async_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 (canceled)", + sna[i].name); + 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("%s", 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("%s (failed)", + sna[i].name); + 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); + + dialog1_vbox = GTK_DIALOG(dialog)->vbox; + gtk_box_set_spacing(GTK_BOX(dialog1_vbox), 5); + gtk_container_set_border_width(GTK_CONTAINER(dialog1_vbox), 4); + gtk_widget_show(dialog1_vbox); + + hbox = gtk_hbox_new(FALSE, 5); + 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); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + + 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); + + dialog1_action_area = GTK_DIALOG(dialog)->action_area; + gtk_widget_show(dialog1_action_area); + gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog1_action_area), + GTK_BUTTONBOX_END); + + button8 = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_widget_show(button8); + gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button8, + GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS(button8, GTK_CAN_DEFAULT); + + button7 = gtk_button_new_with_mnemonic("_Synchronize"); + gtk_widget_show(button7); + gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button7, + GTK_RESPONSE_ACCEPT); + GTK_WIDGET_SET_FLAGS(button7, GTK_CAN_DEFAULT); + + 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); + GTK_WIDGET_SET_FLAGS(button6, GTK_CAN_DEFAULT); + + 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/hardinfo2/socket.c b/hardinfo2/socket.c deleted file mode 100644 index 339df30e..00000000 --- a/hardinfo2/socket.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#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 (sock_ready_to_read(s)) { - gint n; - - n = read(s->sock, buffer, size); - 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/hardinfo2/socket.h b/hardinfo2/socket.h deleted file mode 100644 index 7c44837e..00000000 --- a/hardinfo2/socket.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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/hardinfo2/ssh-conn.c b/hardinfo2/ssh-conn.c deleted file mode 100644 index 7f099d35..00000000 --- a/hardinfo2/ssh-conn.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - Remote Client - HardInfo - Displays System Information - Copyright (C) 2003-2009 Leandro A. F. Pereira - - Based on ssh-method.c from GnomeVFS - Copyright (C) 1999 Free Software Foundation - Original author: Ian McKellar - - ssh-conn.c and ssh-conn.h are 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. - - ssh-conn.c and ssh-con.h are 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 ssh-conn.c and ssh-conn.h; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -#include "config.h" -#ifdef HAS_LIBSOUP -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ssh-conn.h" - -const char *ssh_conn_errors[] = { - "OK", - "No URI specified", - "Unknown protocol", - "Unknown error", - "Cannot spawn SSH", - "Bad parameters", - "Permission denied (invalid credentials)", - "Host key verification failed", - "Connection refused", - "Invalid username or password" -}; - -int ssh_write(SSHConn * conn, - gconstpointer buffer, gint num_bytes, gint * bytes_written) -{ - int written; - int count = 0; - - do { - written = write(conn->fd_write, buffer, (size_t) num_bytes); - if (written == -1 && errno == EINTR) { - count++; - usleep(10); - } - } while (written == -1 && errno == EINTR && count < 5); - - if (written == -1) { - return -1; - } - - *bytes_written = written; - - return 1; -} - -int ssh_read(gint fd, gpointer buffer, gint num_bytes, gint * bytes_read) -{ - int retval; - fd_set fds; - struct timeval tv = { 5, 0 }; - - FD_ZERO(&fds); - FD_SET(fd, &fds); - - *bytes_read = 0; - - if ((retval = select(fd + 1, &fds, NULL, NULL, &tv)) < 0) { - return retval; - } - - if ((retval = read(fd, buffer, (size_t) num_bytes)) > 0) { - *bytes_read = retval; - return 1; - } - - return retval; -} - -void ssh_close(SSHConn * conn) -{ - if (!conn) { - return; - } - - close(conn->fd_read); - close(conn->fd_write); - close(conn->fd_error); - - if (conn->uri) { - soup_uri_free(conn->uri); - } - - kill(conn->pid, SIGINT); - - if (conn->askpass_path) { - DEBUG("unlinking %s", conn->askpass_path); - g_remove(conn->askpass_path); - g_free(conn->askpass_path); - } - - g_free(conn); -} - -static void ssh_conn_setup(gpointer user_data) -{ - gchar *askpass_path = (gchar *) user_data; - int fd; - - if ((fd = open("/dev/tty", O_RDWR)) != -1) { - ioctl(fd, TIOCNOTTY, NULL); - close(fd); - } - - if (askpass_path) { - g_setenv("DISPLAY", "none:0.", TRUE); - g_setenv("SSH_ASKPASS", askpass_path, TRUE); - } else { - g_setenv("SSH_ASKPASS", "/bin/false", TRUE); - } -} - -SSHConnResponse ssh_new(SoupURI * uri, - SSHConn ** conn_return, gchar * command) -{ - int argc, res, bytes_read; - char **argv, *askpass_path = NULL; - GString *cmd_line; - SSHConnResponse response; - SSHConn *connection; - gchar buffer[512]; - - if (!conn_return) { - return SSH_CONN_BAD_PARAMS; - } - - if (!uri) { - return SSH_CONN_NO_URI; - } - - if (!g_str_equal(uri->scheme, "ssh")) { - return SSH_CONN_UNKNOWN_PROTOCOL; - } - - if (uri->password) { - int tmp_askpass; - - askpass_path = - g_build_filename(g_get_home_dir(), ".hardinfo", - "ssh-askpass-XXXXXX", NULL); - tmp_askpass = g_mkstemp(askpass_path); - if (tmp_askpass > 0) { - gchar *tmp; - - g_chmod(askpass_path, 0700); - - tmp = g_strdup_printf("#!/bin/sh\n" - "echo '%s'\n" - "rm -f \"$0\"", uri->password); - write(tmp_askpass, tmp, strlen(tmp)); - close(tmp_askpass); - g_free(tmp); - - DEBUG("using [%s] as ssh-askpass", askpass_path); - } - } - - - cmd_line = g_string_new("ssh -x"); - - if (uri->query && strlen(uri->query)) { - GHashTable *query; - GList *keys, *key; - - query = soup_form_decode(uri->query); - keys = g_hash_table_get_keys(query); - - for (key = keys; key; key = key->next) { - gchar *param; - - g_string_append_printf(cmd_line, " -%s", (gchar *) key->data); - - if ((param = (gchar *) g_hash_table_lookup(query, key->data))) { - g_string_append_printf(cmd_line, "'%s'", param); - } - } - - g_list_free(keys); - g_hash_table_destroy(query); - } - - if (uri->user) { - g_string_append_printf(cmd_line, " -l '%s'", uri->user); - } - - if (uri->port) { - g_string_append_printf(cmd_line, " -p %d", uri->port); - } - - g_string_append_printf(cmd_line, - " %s \"LC_ALL=C %s\"", uri->host, command); - - DEBUG("cmd_line = [%s]", cmd_line->str); - - if (!g_shell_parse_argv(cmd_line->str, &argc, &argv, NULL)) { - response = SSH_CONN_BAD_PARAMS; - goto end; - } - - connection = g_new0(SSHConn, 1); - connection->exit_status = -1; - - DEBUG("spawning SSH"); - - if (!g_spawn_async_with_pipes(NULL, argv, NULL, - G_SPAWN_SEARCH_PATH, - ssh_conn_setup, askpass_path, - &connection->pid, - &connection->fd_write, - &connection->fd_read, - &connection->fd_error, NULL)) { - response = SSH_CONN_CANNOT_SPAWN_SSH; - goto end; - } - - memset(buffer, 0, sizeof(buffer)); - res = ssh_read(connection->fd_error, &buffer, sizeof(buffer), - &bytes_read); - DEBUG("bytes read: %d, result = %d", bytes_read, res); - if (bytes_read > 0 && res == 1) { - DEBUG("Received (error channel): [%s]", buffer); - - if (strstr(buffer, "Permission denied")) { - response = SSH_CONN_PERMISSION_DENIED; - goto end; - } else if (strstr(buffer, "Host key verification failed")) { - response = SSH_CONN_HOST_KEY_CHECK_FAIL; - goto end; - } else if (strstr(buffer, "Connection refused")) { - response = SSH_CONN_REFUSED; - goto end; - } - } - - DEBUG("no error detected; ssh conn established"); - - connection->uri = soup_uri_copy(uri); - response = SSH_CONN_OK; - - end: - g_strfreev(argv); - g_string_free(cmd_line, TRUE); - - if (askpass_path) { - if (connection) { - connection->askpass_path = askpass_path; - } else { - g_free(askpass_path); - } - } - - if (response != SSH_CONN_OK) { - if (connection->uri) { - soup_uri_free(connection->uri); - } - - g_free(connection); - - *conn_return = NULL; - } else { - *conn_return = connection; - } - - DEBUG("response = %d (%s)", response, ssh_conn_errors[response]); - - return response; -} - -#ifdef SSH_TEST -int main(int argc, char **argv) -{ - SSHConn *c; - SSHConnResponse r; - SoupURI *u; - char buffer[256]; - - if (argc < 2) { - g_print("Usage: %s URI command\n", argv[0]); - g_print("Example: %s ssh://user:password@host 'ls -la /'\n", - argv[0]); - return 1; - } - - u = soup_uri_new(argv[1]); - r = ssh_new(u, &c, argv[2]); - g_print("Connection result: %s\n", ssh_conn_errors[r]); - - if (r == SSH_CONN_OK) { - int bytes_read; - - while (ssh_read(c->fd_read, &buffer, sizeof(buffer), - &bytes_read) > 0) { - g_print("Bytes read: %d\n", bytes_read); - g_print("Contents: %s", buffer); - } - - g_print("Finished running remote command\n"); - } - - g_print("Closing SSH [ptr = %p]", c); - ssh_close(c); - - return 0; -} -#endif /* SSH_TEST */ -#endif /* HAS_LIBSOUP */ diff --git a/hardinfo2/ssh-conn.h b/hardinfo2/ssh-conn.h deleted file mode 100644 index b1b0a9ca..00000000 --- a/hardinfo2/ssh-conn.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - Remote Client - HardInfo - Displays System Information - Copyright (C) 2003-2009 Leandro A. F. Pereira - - Based on ssh-method.c from GnomeVFS - Copyright (C) 1999 Free Software Foundation - Original author: Ian McKellar - - 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 - -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/hardinfo2/stock.c b/hardinfo2/stock.c deleted file mode 100644 index ad1a0135..00000000 --- a/hardinfo2/stock.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 -#include -#include -#include - -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) -{ - 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); -} - -void stock_icon_register_pixbuf(GdkPixbuf * pixbuf, gchar * stock_id) -{ - 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); -} - -void stock_icons_init(void) -{ - gint i; - guint n_stock_icons = G_N_ELEMENTS(stock_icons); - - DEBUG("initializing stock icons"); - - icon_factory = gtk_icon_factory_new(); - - for (i = 0; i < n_stock_icons; i++) { - stock_icon_register(stock_icons[i].filename, - stock_icons[i].stock_id); - } - - gtk_icon_factory_add_default(icon_factory); - - g_object_unref(icon_factory); -} diff --git a/hardinfo2/stock.h b/hardinfo2/stock.h deleted file mode 100644 index 706e5c51..00000000 --- a/hardinfo2/stock.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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/hardinfo2/syncmanager.c b/hardinfo2/syncmanager.c deleted file mode 100644 index 496dc348..00000000 --- a/hardinfo2/syncmanager.c +++ /dev/null @@ -1,758 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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 - -#include -#include - -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 "http://hardinfo.berlios.de/xmlrpc/" -#define XMLRPC_SERVER_API_VERSION 1 - -#define LABEL_SYNC_DEFAULT "Synchronize with Central Database\n" \ - "The following information may be synchronized " \ - "with the HardInfo central database." -#define LABEL_SYNC_SYNCING "Synchronizing\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; - } - - if (!soup_xmlrpc_extract_method_response(msg->response_body->data, - msg->response_body->length, - NULL, - G_TYPE_INT, &int_value)) { - SNA_ERROR(2, "Could not parse XML-RPC response"); - } - - 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; - } - - if (!soup_xmlrpc_extract_method_response(msg->response_body->data, - msg->response_body->length, - NULL, - G_TYPE_STRING, &string)) { - SNA_ERROR(2, "Could not parse XML-RPC response"); - } - - bad: - return string; -} - -static gboolean _soup_xmlrpc_call(gchar * method, SyncNetAction * sna, - SoupSessionCallback callback) -{ - SoupMessage *msg; - - sna->error = NULL; - - msg = soup_xmlrpc_request_new(XMLRPC_SERVER_URI, method, - G_TYPE_INVALID); - 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; - GValueArray *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; - - parameters = g_value_array_new(1); - va_start(ap, callback); - while ((argument = va_arg(ap, gchar *))) { - soup_value_array_append(parameters, G_TYPE_STRING, argument); - DEBUG("with parameter: %s", argument); - } - va_end(ap); - - body = soup_xmlrpc_build_method_call(method, parameters->values, - parameters->n_values); - g_value_array_free(parameters); - 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; -} - -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)) { - if (str_data) - g_free(str_data); - - return FALSE; - } - - if (str_data) - 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_async_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 (canceled)", - sna[i].name); - 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("%s", 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("%s (failed)", - sna[i].name); - 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); - - dialog1_vbox = GTK_DIALOG(dialog)->vbox; - gtk_box_set_spacing(GTK_BOX(dialog1_vbox), 5); - gtk_container_set_border_width(GTK_CONTAINER(dialog1_vbox), 4); - gtk_widget_show(dialog1_vbox); - - hbox = gtk_hbox_new(FALSE, 5); - 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); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - - 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); - - dialog1_action_area = GTK_DIALOG(dialog)->action_area; - gtk_widget_show(dialog1_action_area); - gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog1_action_area), - GTK_BUTTONBOX_END); - - button8 = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - gtk_widget_show(button8); - gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button8, - GTK_RESPONSE_CANCEL); - GTK_WIDGET_SET_FLAGS(button8, GTK_CAN_DEFAULT); - - button7 = gtk_button_new_with_mnemonic("_Synchronize"); - gtk_widget_show(button7); - gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button7, - GTK_RESPONSE_ACCEPT); - GTK_WIDGET_SET_FLAGS(button7, GTK_CAN_DEFAULT); - - 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); - GTK_WIDGET_SET_FLAGS(button6, GTK_CAN_DEFAULT); - - 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/hardinfo2/syncmanager.h b/hardinfo2/syncmanager.h deleted file mode 100644 index ae0ed267..00000000 --- a/hardinfo2/syncmanager.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 - -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/hardinfo2/uidefs.h b/hardinfo2/uidefs.h deleted file mode 100644 index a54823ad..00000000 --- a/hardinfo2/uidefs.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef __UIDEFS_H__ -#define __UIDEFS_H__ - -#include "config.h" - -#if RELEASE -#define DEBUG_TOOLBAR_ITEMS -#else /* !RELEASE */ -#define DEBUG_TOOLBAR_ITEMS "" \ - "" -#endif /* !RELEASE */ - -#ifdef HAS_LIBSOUP -#define REMOTE_MENU_ITEMS " " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " - -#define SYNC_MANAGER_ITEMS " " \ -" " - -#else /* !HAS_LIBSOUP */ -#define REMOTE_MENU_ITEMS -#define SYNC_MANAGER_ITEMS -#endif /* !HAS_LIBSOUP */ - -char *uidefs_str = "" \ -" " \ -" " \ -" " \ -" " \ -SYNC_MANAGER_ITEMS -/* - * Save Image is not ready for prime time. Yet. - * "" \ - */ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" "\ -" " \ -" " \ -" " \ -REMOTE_MENU_ITEMS \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -" " \ -DEBUG_TOOLBAR_ITEMS \ -" " \ -" " \ -""; - -#endif /* __UIDEFS_H__ */ diff --git a/hardinfo2/util.c b/hardinfo2/util.c deleted file mode 100644 index 54015b34..00000000 --- a/hardinfo2/util.c +++ /dev/null @@ -1,1287 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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 - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#define KiB 1024 -#define MiB 1048576 -#define GiB 1073741824 - -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[] = { "/bin", "/sbin", - "/usr/bin", "/usr/sbin", - "/usr/local/bin", "/usr/local/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; - - minutes = seconds / 60; - hours = minutes / 60; - minutes %= 60; - days = hours / 24; - hours %= 24; - -#define plural(x) ((x > 1) ? "s" : "") - - if (days < 1) { - if (hours < 1) { - return g_strdup_printf("%d minute%s", minutes, - plural(minutes)); - } else { - return g_strdup_printf("%d hour%s, %d minute%s", - hours, - plural(hours), minutes, - plural(minutes)); - } - } - - return g_strdup_printf("%d day%s, %d hour%s and %d minute%s", - days, plural(days), hours, - plural(hours), minutes, plural(minutes)); -} - -inline 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); - - return g_strdup_printf("%.1f GiB", size / GiB); -} - -inline char *strend(gchar * str, gchar chr) -{ - if (!str) - return NULL; - - char *p; - if ((p = strchr(str, chr))) - *p = 0; - - return str; -} - -inline void remove_quotes(gchar * str) -{ - if (!str) - return; - - while (*str == '"') - *(str++) = ' '; - - strend(str, '"'); -} - -inline void remove_linefeed(gchar * str) -{ - strend(str, '\n'); -} - -void widget_set_cursor(GtkWidget * widget, GdkCursorType cursor_type) -{ - GdkCursor *cursor; - - if ((cursor = gdk_cursor_new(cursor_type))) { - gdk_window_set_cursor(GDK_WINDOW(widget->window), cursor); - gdk_display_flush(gtk_widget_get_display(widget)); - gdk_cursor_unref(cursor); - } - - 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, - "%s\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 **use_modules = NULL; - - static GOptionEntry options[] = { - { - .long_name = "generate-report", - .short_name = 'r', - .arg = G_OPTION_ARG_NONE, - .arg_data = &create_report, - .description = "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 = "chooses a report format (text, html)"}, - { - .long_name = "run-benchmark", - .short_name = 'b', - .arg = G_OPTION_ARG_STRING, - .arg_data = &run_benchmark, - .description = "run benchmark; requires benchmark.so to be loaded"}, - { - .long_name = "list-modules", - .short_name = 'l', - .arg = G_OPTION_ARG_NONE, - .arg_data = &list_modules, - .description = "lists modules"}, - { - .long_name = "load-module", - .short_name = 'm', - .arg = G_OPTION_ARG_STRING_ARRAY, - .arg_data = &use_modules, - .description = "specify module to load"}, - { - .long_name = "autoload-deps", - .short_name = 'a', - .arg = G_OPTION_ARG_NONE, - .arg_data = &autoload_deps, - .description = "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 = "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 = "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->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)); - - strend(name, '.'); - - method_name = g_strdup_printf("%s::%s", name, method.name); - g_hash_table_insert(__module_methods, method_name, - method.function); - g_free(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); - gdk_pixbuf_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; - - tmpicon = g_strdup(filename); - gchar *dot = g_strrstr(tmpicon, "." G_MODULE_SUFFIX); - - *dot = '\0'; - - tmp = g_strdup_printf("%s.png", tmpicon); - module->icon = icon_cache_get_pixbuf(tmp); - - g_free(tmp); - g_free(tmpicon); - } - - 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) { - 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; - 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", filename); - - 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), - GTK_STOCK_NO, - GTK_RESPONSE_REJECT, - GTK_STOCK_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; -} - -void tree_view_save_image(gchar * filename) -{ - /* this is ridiculously complicated :/ why in the hell gtk+ makes this kind of - thing so difficult? */ - - /* FIXME: this does not work if the window (or part of it) isn't visible. does - anyone know how to fix this? :/ */ - Shell *shell = shell_get_main_shell(); - GtkWidget *widget = shell->info->view; - - PangoLayout *layout; - PangoContext *context; - PangoRectangle rect; - - GdkPixmap *pm; - GdkPixbuf *pb; - GdkGC *gc; - GdkColor black = { 0, 0, 0, 0 }; - GdkColor white = { 0, 65535, 65535, 65535 }; - - gint w, h, visible_height; - gchar *tmp; - - gboolean tv_enabled; - - /* present the window */ - gtk_window_present(GTK_WINDOW(shell->window)); - - /* if the treeview is disabled, we need to enable it so we get the - correct colors when saving. we make it insensitive later on if it - was this way before entering this function */ - tv_enabled = GTK_WIDGET_IS_SENSITIVE(widget); - gtk_widget_set_sensitive(widget, TRUE); - - gtk_widget_queue_draw(widget); - - /* unselect things in the information treeview */ - gtk_range_set_value(GTK_RANGE - (GTK_SCROLLED_WINDOW(shell->info->scroll)-> - vscrollbar), 0.0); - gtk_tree_selection_unselect_all(gtk_tree_view_get_selection - (GTK_TREE_VIEW(widget))); - while (gtk_events_pending()) - gtk_main_iteration(); - - /* initialize stuff */ - gc = gdk_gc_new(widget->window); - gdk_gc_set_background(gc, &black); - gdk_gc_set_foreground(gc, &white); - - context = gtk_widget_get_pango_context(widget); - layout = pango_layout_new(context); - - visible_height = tree_view_get_visible_height(GTK_TREE_VIEW(widget)); - - /* draw the title */ - tmp = g_strdup_printf("%s\n%s", - shell->selected->name, - shell->selected->notefunc(shell->selected-> - number)); - pango_layout_set_markup(layout, tmp, -1); - pango_layout_set_width(layout, widget->allocation.width * PANGO_SCALE); - pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); - pango_layout_get_pixel_extents(layout, NULL, &rect); - - w = widget->allocation.width; - h = visible_height + rect.height; - - pm = gdk_pixmap_new(widget->window, w, rect.height, -1); - gdk_draw_rectangle(GDK_DRAWABLE(pm), gc, TRUE, 0, 0, w, rect.height); - gdk_draw_layout_with_colors(GDK_DRAWABLE(pm), gc, 0, 0, layout, - &white, &black); - - /* copy the pixmap from the treeview and from the title */ - pb = gdk_pixbuf_get_from_drawable(NULL, - widget->window, - NULL, 0, 0, 0, 0, w, h); - pb = gdk_pixbuf_get_from_drawable(pb, - pm, - NULL, - 0, 0, - 0, visible_height, w, rect.height); - - /* save the pixbuf to a png file */ - gdk_pixbuf_save(pb, filename, "png", NULL, - "compression", "9", - "tEXt::hardinfo::version", VERSION, - "tEXt::hardinfo::arch", ARCH, NULL); - - /* unref */ - g_object_unref(pb); - g_object_unref(layout); - g_object_unref(pm); - g_object_unref(gc); - g_free(tmp); - - gtk_widget_set_sensitive(widget, tv_enabled); -} - -static gboolean __idle_free_do(gpointer ptr) -{ - if (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; -} - diff --git a/hardinfo2/util/binreloc.c b/hardinfo2/util/binreloc.c new file mode 100644 index 00000000..1d1acfe6 --- /dev/null +++ b/hardinfo2/util/binreloc.c @@ -0,0 +1,672 @@ +/* + * BinReloc - a library for creating relocatable executables + * Written by: Hongli Lai + * 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 +#include +#include +#include +#include +#include +#include +#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; + } + +#ifdef ARCH_x86_64 + dir = g_build_filename(prefix, "lib64", NULL); +#else + dir = g_build_filename(prefix, "lib", NULL); +#endif + + 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/hardinfo2/util/expr.c b/hardinfo2/util/expr.c new file mode 100644 index 00000000..32e303d7 --- /dev/null +++ b/hardinfo2/util/expr.c @@ -0,0 +1,250 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 +#include +#include +#include +#include + +#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/hardinfo2/util/socket.c b/hardinfo2/util/socket.c new file mode 100644 index 00000000..339df30e --- /dev/null +++ b/hardinfo2/util/socket.c @@ -0,0 +1,127 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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 (sock_ready_to_read(s)) { + gint n; + + n = read(s->sock, buffer, size); + 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/hardinfo2/util/util.c b/hardinfo2/util/util.c new file mode 100644 index 00000000..fb995406 --- /dev/null +++ b/hardinfo2/util/util.c @@ -0,0 +1,1292 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira + * + * 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 + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#define KiB 1024 +#define MiB 1048576 +#define GiB 1073741824 + +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[] = { "/bin", "/sbin", + "/usr/bin", "/usr/sbin", + "/usr/local/bin", "/usr/local/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; + + minutes = seconds / 60; + hours = minutes / 60; + minutes %= 60; + days = hours / 24; + hours %= 24; + +#define plural(x) ((x > 1) ? "s" : "") + + if (days < 1) { + if (hours < 1) { + return g_strdup_printf("%d minute%s", minutes, + plural(minutes)); + } else { + return g_strdup_printf("%d hour%s, %d minute%s", + hours, + plural(hours), minutes, + plural(minutes)); + } + } + + return g_strdup_printf("%d day%s, %d hour%s and %d minute%s", + days, plural(days), hours, + plural(hours), minutes, plural(minutes)); +} + +inline 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); + + return g_strdup_printf("%.1f GiB", size / GiB); +} + +inline char *strend(gchar * str, gchar chr) +{ + if (!str) + return NULL; + + char *p; + if ((p = strchr(str, chr))) + *p = 0; + + return str; +} + +inline void remove_quotes(gchar * str) +{ + if (!str) + return; + + while (*str == '"') + *(str++) = ' '; + + strend(str, '"'); +} + +inline void remove_linefeed(gchar * str) +{ + strend(str, '\n'); +} + +void widget_set_cursor(GtkWidget * widget, GdkCursorType cursor_type) +{ + GdkCursor *cursor; + + if ((cursor = gdk_cursor_new(cursor_type))) { + gdk_window_set_cursor(GDK_WINDOW(widget->window), cursor); + gdk_display_flush(gtk_widget_get_display(widget)); + gdk_cursor_unref(cursor); + } + + 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, + "%s\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 **use_modules = NULL; + + static GOptionEntry options[] = { + { + .long_name = "generate-report", + .short_name = 'r', + .arg = G_OPTION_ARG_NONE, + .arg_data = &create_report, + .description = "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 = "chooses a report format (text, html)"}, + { + .long_name = "run-benchmark", + .short_name = 'b', + .arg = G_OPTION_ARG_STRING, + .arg_data = &run_benchmark, + .description = "run benchmark; requires benchmark.so to be loaded"}, + { + .long_name = "list-modules", + .short_name = 'l', + .arg = G_OPTION_ARG_NONE, + .arg_data = &list_modules, + .description = "lists modules"}, + { + .long_name = "load-module", + .short_name = 'm', + .arg = G_OPTION_ARG_STRING_ARRAY, + .arg_data = &use_modules, + .description = "specify module to load"}, + { + .long_name = "autoload-deps", + .short_name = 'a', + .arg = G_OPTION_ARG_NONE, + .arg_data = &autoload_deps, + .description = "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 = "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 = "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->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); + gdk_pixbuf_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) { + 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; + 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), + GTK_STOCK_NO, + GTK_RESPONSE_REJECT, + GTK_STOCK_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; +} + +void tree_view_save_image(gchar * filename) +{ + /* this is ridiculously complicated :/ why in the hell gtk+ makes this kind of + thing so difficult? */ + + /* FIXME: this does not work if the window (or part of it) isn't visible. does + anyone know how to fix this? :/ */ + Shell *shell = shell_get_main_shell(); + GtkWidget *widget = shell->info->view; + + PangoLayout *layout; + PangoContext *context; + PangoRectangle rect; + + GdkPixmap *pm; + GdkPixbuf *pb; + GdkGC *gc; + GdkColor black = { 0, 0, 0, 0 }; + GdkColor white = { 0, 65535, 65535, 65535 }; + + gint w, h, visible_height; + gchar *tmp; + + gboolean tv_enabled; + + /* present the window */ + gtk_window_present(GTK_WINDOW(shell->window)); + + /* if the treeview is disabled, we need to enable it so we get the + correct colors when saving. we make it insensitive later on if it + was this way before entering this function */ + tv_enabled = GTK_WIDGET_IS_SENSITIVE(widget); + gtk_widget_set_sensitive(widget, TRUE); + + gtk_widget_queue_draw(widget); + + /* unselect things in the information treeview */ + gtk_range_set_value(GTK_RANGE + (GTK_SCROLLED_WINDOW(shell->info->scroll)-> + vscrollbar), 0.0); + gtk_tree_selection_unselect_all(gtk_tree_view_get_selection + (GTK_TREE_VIEW(widget))); + while (gtk_events_pending()) + gtk_main_iteration(); + + /* initialize stuff */ + gc = gdk_gc_new(widget->window); + gdk_gc_set_background(gc, &black); + gdk_gc_set_foreground(gc, &white); + + context = gtk_widget_get_pango_context(widget); + layout = pango_layout_new(context); + + visible_height = tree_view_get_visible_height(GTK_TREE_VIEW(widget)); + + /* draw the title */ + tmp = g_strdup_printf("%s\n%s", + shell->selected->name, + shell->selected->notefunc(shell->selected-> + number)); + pango_layout_set_markup(layout, tmp, -1); + pango_layout_set_width(layout, widget->allocation.width * PANGO_SCALE); + pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); + pango_layout_get_pixel_extents(layout, NULL, &rect); + + w = widget->allocation.width; + h = visible_height + rect.height; + + pm = gdk_pixmap_new(widget->window, w, rect.height, -1); + gdk_draw_rectangle(GDK_DRAWABLE(pm), gc, TRUE, 0, 0, w, rect.height); + gdk_draw_layout_with_colors(GDK_DRAWABLE(pm), gc, 0, 0, layout, + &white, &black); + + /* copy the pixmap from the treeview and from the title */ + pb = gdk_pixbuf_get_from_drawable(NULL, + widget->window, + NULL, 0, 0, 0, 0, w, h); + pb = gdk_pixbuf_get_from_drawable(pb, + pm, + NULL, + 0, 0, + 0, visible_height, w, rect.height); + + /* save the pixbuf to a png file */ + gdk_pixbuf_save(pb, filename, "png", NULL, + "compression", "9", + "tEXt::hardinfo::version", VERSION, + "tEXt::hardinfo::arch", ARCH, NULL); + + /* unref */ + g_object_unref(pb); + g_object_unref(layout); + g_object_unref(pm); + g_object_unref(gc); + g_free(tmp); + + gtk_widget_set_sensitive(widget, tv_enabled); +} + +static gboolean __idle_free_do(gpointer ptr) +{ + if (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; +} + diff --git a/hardinfo2/util/vendor.c b/hardinfo2/util/vendor.c new file mode 100644 index 00000000..86dba97a --- /dev/null +++ b/hardinfo2/util/vendor.c @@ -0,0 +1,195 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2009 Leandro A. F. Pereira + * + * 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 +#include + +#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"}, + {"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"}, +}; + +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 g_strdup(v->name); + } + } + + return id; +} + +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 g_strdup(v->url); + } + } + + return NULL; +} diff --git a/hardinfo2/vendor.c b/hardinfo2/vendor.c deleted file mode 100644 index 86dba97a..00000000 --- a/hardinfo2/vendor.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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 -#include - -#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"}, - {"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"}, -}; - -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 g_strdup(v->name); - } - } - - return id; -} - -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 g_strdup(v->url); - } - } - - return NULL; -} diff --git a/hardinfo2/vendor.h b/hardinfo2/vendor.h deleted file mode 100644 index 778e2ea3..00000000 --- a/hardinfo2/vendor.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira - * - * 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/hardinfo2/xmlrpc-client.c b/hardinfo2/xmlrpc-client.c deleted file mode 100644 index d363729b..00000000 --- a/hardinfo2/xmlrpc-client.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * XMLRPC Client - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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 -#include "config.h" -#include "xmlrpc-client.h" - -#ifdef HAS_LIBSOUP -static GMainLoop *loop = NULL; -static SoupSession *session = NULL; -static gboolean lock = FALSE; - -void xmlrpc_init(void) -{ - if (!loop) { - loop = g_main_loop_new(FALSE, FALSE); - } - - if (!session) { - session = soup_session_async_new_with_options(SOUP_SESSION_TIMEOUT, 10, NULL); - } -} - -static void xmlrpc_response_get_integer(SoupSession *s, - SoupMessage *m, - gpointer user_data) -{ - gint *response = user_data; - - *response = -1; - - if (SOUP_STATUS_IS_SUCCESSFUL(m->status_code)) { - soup_xmlrpc_extract_method_response(m->response_body->data, - m->response_body->length, - NULL, - G_TYPE_INT, response); - } - - g_main_quit(loop); - lock = FALSE; -} - -gint xmlrpc_get_integer(gchar *addr, - gchar *method, - const gchar *param_types, - ...) -{ - gint integer; - GValueArray *params; - SoupMessage *msg; - gchar *body; - - msg = soup_message_new("POST", addr); - - params = g_value_array_new(1); - - if (param_types && *param_types) { - va_list ap; - - va_start(ap, param_types); - while (*param_types) { - switch (*param_types) { - case '%': - break; - case 'i': - soup_value_array_append(params, G_TYPE_INT, va_arg(ap, int)); - break; - case 's': - default: - soup_value_array_append(params, G_TYPE_STRING, va_arg(ap, char *)); - break; - } - - param_types++; - } - - va_end(ap); - } - - body = soup_xmlrpc_build_method_call(method, params->values, params->n_values); - g_value_array_free(params); - - soup_message_set_request(msg, "text/xml", - SOUP_MEMORY_TAKE, body, strlen(body)); - - while (lock) - g_main_iteration(FALSE); - - lock = TRUE; - soup_session_queue_message(session, msg, xmlrpc_response_get_integer, &integer); - g_main_run(loop); - - return integer; -} - -static void xmlrpc_response_get_string(SoupSession *s, - SoupMessage *m, - gpointer user_data) -{ - if (SOUP_STATUS_IS_SUCCESSFUL(m->status_code)) { - soup_xmlrpc_extract_method_response(m->response_body->data, - m->response_body->length, - NULL, - G_TYPE_STRING, user_data); - } - - g_main_quit(loop); - lock = FALSE; -} - -gchar *xmlrpc_get_string(gchar *addr, - gchar *method, - const gchar *param_types, - ...) -{ - GValueArray *params; - SoupMessage *msg; - gchar *body, *string = NULL; - - msg = soup_message_new("POST", addr); - - params = g_value_array_new(1); - - if (param_types && *param_types) { - va_list ap; - - va_start(ap, param_types); - while (*param_types) { - switch (*param_types) { - case '%': - break; - case 'i': - soup_value_array_append(params, G_TYPE_INT, va_arg(ap, int)); - break; - case 's': - default: - soup_value_array_append(params, G_TYPE_STRING, va_arg(ap, char *)); - break; - } - - param_types++; - } - - va_end(ap); - } - - body = soup_xmlrpc_build_method_call(method, params->values, params->n_values); - g_value_array_free(params); - - soup_message_set_request(msg, "text/xml", - SOUP_MEMORY_TAKE, body, strlen(body)); - - while (lock) - g_main_iteration(FALSE); - - lock = TRUE; - soup_session_queue_message(session, msg, xmlrpc_response_get_string, &string); - g_main_run(loop); - - return string; -} - -static void xmlrpc_response_get_array(SoupSession *s, - SoupMessage *m, - gpointer user_data) -{ - if (SOUP_STATUS_IS_SUCCESSFUL(m->status_code)) { - soup_xmlrpc_extract_method_response(m->response_body->data, - m->response_body->length, - NULL, - G_TYPE_VALUE_ARRAY, user_data); - } - - g_main_quit(loop); - lock = FALSE; -} - -GValueArray *xmlrpc_get_array(gchar *addr, - gchar *method, - const gchar *param_types, - ...) -{ - GValueArray *params, *answer = NULL; - SoupMessage *msg; - gchar *body; - - msg = soup_message_new("POST", addr); - - params = g_value_array_new(1); - - if (param_types && *param_types) { - va_list ap; - - va_start(ap, param_types); - while (*param_types) { - switch (*param_types) { - case '%': - break; - case 'i': - soup_value_array_append(params, G_TYPE_INT, va_arg(ap, int)); - break; - case 's': - default: - soup_value_array_append(params, G_TYPE_STRING, va_arg(ap, char *)); - break; - } - - param_types++; - } - - va_end(ap); - } - - body = soup_xmlrpc_build_method_call(method, params->values, params->n_values); - g_value_array_free(params); - - soup_message_set_request(msg, "text/xml", - SOUP_MEMORY_TAKE, body, strlen(body)); - - while (lock) - g_main_iteration(FALSE); - - lock = TRUE; - soup_session_queue_message(session, msg, xmlrpc_response_get_array, &answer); - g_main_run(loop); - - return answer; -} - -#endif /* HAS_LIBSOUP */ - diff --git a/hardinfo2/xmlrpc-client.h b/hardinfo2/xmlrpc-client.h deleted file mode 100644 index 32fad08c..00000000 --- a/hardinfo2/xmlrpc-client.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * XMLRPC Client - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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 - -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/hardinfo2/xmlrpc-server.c b/hardinfo2/xmlrpc-server.c deleted file mode 100644 index e953cfd1..00000000 --- a/hardinfo2/xmlrpc-server.c +++ /dev/null @@ -1,782 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * This file is based off xmlrpc-server-test.c from libsoup test suite - * Copyright (C) 2008 Red Hat, Inc. - * - * 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 -#ifdef HAS_LIBSOUP -#include -#include -#include - -#include "shell.h" -#include "hardinfo.h" - -#define XMLRPC_SERVER_VERSION 1 -/* server namespace */ -static void method_get_api_version(SoupMessage * msg, - GValueArray * params); -static void method_shutdown_server(SoupMessage * msg, - GValueArray * params); -/* module namespace */ -static void method_get_module_list(SoupMessage * msg, - GValueArray * params); -static void method_get_entry_list(SoupMessage * msg, GValueArray * params); -static void method_entry_reload(SoupMessage * msg, GValueArray * params); -static void method_entry_scan(SoupMessage * msg, GValueArray * params); -static void method_entry_get_field(SoupMessage * msg, - GValueArray * params); -static void method_entry_get_moreinfo(SoupMessage * msg, - GValueArray * params); -static void method_entry_get_note(SoupMessage * msg, GValueArray * params); -static void method_entry_function(SoupMessage * msg, GValueArray * params); -static void method_get_about_info(SoupMessage * msg, GValueArray * params); -static void method_call_method(SoupMessage * msg, GValueArray * params); -static void method_call_method_param(SoupMessage * msg, - GValueArray * params); - -/* method handler table */ -static const struct { - gchar *method_name; - void *callback; -} handler_table[] = { - /* server namespace */ - { "server.getAPIVersion", method_get_api_version }, - { "server.shutdownServer", method_shutdown_server }, - /* module namespace */ - { "module.getModuleList", method_get_module_list }, - { "module.getEntryList", method_get_entry_list }, - { "module.entryReload", method_entry_reload }, - { "module.entryScan", method_entry_scan }, - { "module.entryFunction", method_entry_function }, - { "module.entryGetNote", method_entry_get_note }, - { "module.entryGetField", method_entry_get_field }, - { "module.entryGetMoreInfo", method_entry_get_moreinfo }, - { "module.getAboutInfo", method_get_about_info }, - { "module.callMethod", method_call_method }, - { "module.callMethodParam", method_call_method_param }, - { NULL } -}; - -static GHashTable *handlers = NULL; -static GMainLoop *loop = NULL; - -typedef struct _MethodParameter MethodParameter; -struct _MethodParameter { - int param_type; - void *variable; -}; - -static void -args_error(SoupMessage * msg, GValueArray * params, int expected) -{ - soup_xmlrpc_set_fault(msg, - SOUP_XMLRPC_FAULT_SERVER_ERROR_INVALID_METHOD_PARAMETERS, - "Wrong number of parameters: expected %d, got %d", - expected, params->n_values); -} - -static void -type_error(SoupMessage * msg, GType expected, GValueArray * params, - int bad_value) -{ - soup_xmlrpc_set_fault(msg, - SOUP_XMLRPC_FAULT_SERVER_ERROR_INVALID_METHOD_PARAMETERS, - "Bad parameter #%d: expected %s, got %s", - bad_value + 1, g_type_name(expected), - g_type_name(G_VALUE_TYPE - (¶ms->values[bad_value]))); -} - -static gboolean validate_parameters(SoupMessage *msg, GValueArray *params, - MethodParameter *method_params, gint n_params) -{ - int i; - - if (params->n_values != n_params) { - args_error(msg, params, n_params); - return FALSE; - } - - for (i = 0; i < n_params; i++) { - if (!soup_value_array_get_nth(params, i, - method_params[i].param_type, - method_params[i].variable)) { - int j; - - type_error(msg, method_params[i].param_type, params, i); - - for (j = 0; j < i; j++) { - if (method_params[j].param_type == G_TYPE_STRING) { - g_free(method_params[j].variable); - } - } - - return FALSE; - } - } - - return TRUE; -} - -static void method_get_module_list(SoupMessage * msg, GValueArray * params) -{ - GValueArray *out; - GSList *modules; - - out = soup_value_array_new(); - - for (modules = modules_get_list(); modules; modules = modules->next) { - ShellModule *module = (ShellModule *) modules->data; - gchar *icon_file, *tmp; - GValueArray *tuple; - - tuple = soup_value_array_new(); - - tmp = g_path_get_basename(g_module_name(module->dll)); - if ((icon_file = g_strrstr(tmp, G_MODULE_SUFFIX))) { - *icon_file = '\0'; - icon_file = g_strconcat(tmp, "png", NULL); - } else { - icon_file = ""; - } - - soup_value_array_append(tuple, G_TYPE_STRING, module->name); - soup_value_array_append(tuple, G_TYPE_STRING, icon_file); - - soup_value_array_append(out, G_TYPE_VALUE_ARRAY, tuple); - - g_value_array_free(tuple); - g_free(tmp); - } - - soup_xmlrpc_set_response(msg, G_TYPE_VALUE_ARRAY, out); - g_value_array_free(out); -} - -static void method_get_entry_list(SoupMessage * msg, GValueArray * params) -{ - ShellModule *module; - ShellModuleEntry *module_entry; - GSList *entry, *modules; - GValueArray *out; - gboolean found = FALSE; - gchar *module_name; - MethodParameter method_params[] = { - { G_TYPE_STRING, &module_name } - }; - - if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { - return; - } - - for (modules = modules_get_list(); modules; modules = modules->next) { - ShellModule *module = (ShellModule *) modules->data; - - if (!strncmp(module->name, module_name, strlen(module->name))) { - found = TRUE; - break; - } - } - - out = soup_value_array_new(); - - if (found) { - module = (ShellModule *) modules->data; - for (entry = module->entries; entry; entry = entry->next) { - GValueArray *tuple; - - module_entry = (ShellModuleEntry *) entry->data; - - if (module_entry->flags & MODULE_FLAG_NO_REMOTE) { - /* do nothing if we're not supposed to */ - } else { - tuple = soup_value_array_new(); - - soup_value_array_append(tuple, G_TYPE_STRING, module_entry->name); - soup_value_array_append(tuple, G_TYPE_STRING, module_entry->icon_file); - - soup_value_array_append(out, G_TYPE_VALUE_ARRAY, tuple); - g_value_array_free(tuple); - } - } - } - - soup_xmlrpc_set_response(msg, G_TYPE_VALUE_ARRAY, out); - g_value_array_free(out); -} - -static void method_entry_get_field(SoupMessage * msg, GValueArray * params) -{ - ShellModule *module; - GSList *modules; - gchar *module_name, *field_name, *answer = NULL; - gint entry_number; - gboolean found = FALSE; - MethodParameter method_params[] = { - { G_TYPE_STRING, &module_name }, - { G_TYPE_INT, &entry_number }, - { G_TYPE_STRING, &field_name } - }; - - if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { - return; - } - - for (modules = modules_get_list(); modules; modules = modules->next) { - module = (ShellModule *) modules->data; - - if (!strncmp(module->name, module_name, strlen(module->name))) { - found = TRUE; - break; - } - } - - if (found) { - if (entry_number < g_slist_length(module->entries)) { - GSList *entry_node = g_slist_nth(module->entries, entry_number); - ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; - - if (entry->flags & MODULE_FLAG_NO_REMOTE) { - /* do nothing */ - } else { - answer = module_entry_get_field(entry, field_name); - } - } - } - - if (!answer) { - answer = g_strdup(""); - } - - soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); - g_free(answer); -} - -static void method_entry_get_moreinfo(SoupMessage * msg, - GValueArray * params) -{ - ShellModule *module; - GSList *modules; - gchar *module_name, *field_name, *answer = NULL; - gint entry_number; - gboolean found = FALSE; - MethodParameter method_params[] = { - { G_TYPE_STRING, &module_name }, - { G_TYPE_INT, &entry_number }, - { G_TYPE_STRING, &field_name }, - }; - - if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { - return; - } - - for (modules = modules_get_list(); modules; modules = modules->next) { - module = (ShellModule *) modules->data; - - if (!strncmp(module->name, module_name, strlen(module->name))) { - found = TRUE; - break; - } - } - - if (found) { - if (entry_number < g_slist_length(module->entries)) { - GSList *entry_node = g_slist_nth(module->entries, entry_number); - ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; - - if (entry->flags & MODULE_FLAG_NO_REMOTE) { - /* do nothing */ - } else { - answer = module_entry_get_moreinfo(entry, field_name); - } - } - } - - if (!answer) { - answer = g_strdup(""); - } - - soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); - g_free(answer); -} - -static void method_entry_reload(SoupMessage * msg, GValueArray * params) -{ - ShellModule *module; - GSList *modules; - gchar *module_name; - gint entry_number; - gboolean found = FALSE, answer = FALSE; - MethodParameter method_params[] = { - { G_TYPE_STRING, &module_name }, - { G_TYPE_INT, &entry_number }, - }; - - if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { - return; - } - - for (modules = modules_get_list(); modules; modules = modules->next) { - module = (ShellModule *) modules->data; - - if (!strncmp(module->name, module_name, strlen(module->name))) { - found = TRUE; - break; - } - } - - if (found) { - if (entry_number < g_slist_length(module->entries)) { - GSList *entry_node = g_slist_nth(module->entries, entry_number); - ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; - - if (entry->flags & MODULE_FLAG_NO_REMOTE) { - /* do nothing */ - } else { - module_entry_reload(entry); - answer = TRUE; - } - } - } - - soup_xmlrpc_set_response(msg, G_TYPE_BOOLEAN, answer); -} - -static void method_entry_scan(SoupMessage * msg, GValueArray * params) -{ - ShellModule *module; - GSList *modules; - gchar *module_name; - gint entry_number; - gboolean found = FALSE, answer = FALSE; - MethodParameter method_params[] = { - { G_TYPE_STRING, &module_name }, - { G_TYPE_INT, &entry_number }, - }; - - if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { - return; - } - - for (modules = modules_get_list(); modules; modules = modules->next) { - module = (ShellModule *) modules->data; - - if (!strncmp(module->name, module_name, strlen(module->name))) { - found = TRUE; - break; - } - } - - if (found) { - if (entry_number < g_slist_length(module->entries)) { - GSList *entry_node = g_slist_nth(module->entries, entry_number); - ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; - - if (entry->flags & MODULE_FLAG_NO_REMOTE) { - /* do nothing */ - } else { - module_entry_scan(entry); - answer = TRUE; - } - } - } - - soup_xmlrpc_set_response(msg, G_TYPE_BOOLEAN, answer); -} - -static void method_entry_function(SoupMessage * msg, GValueArray * params) -{ - ShellModule *module; - GSList *modules; - gchar *module_name, *answer = NULL; - gboolean found = FALSE; - gint entry_number; - MethodParameter method_params[] = { - { G_TYPE_STRING, &module_name }, - { G_TYPE_INT, &entry_number }, - }; - - if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { - return; - } - - for (modules = modules_get_list(); modules; modules = modules->next) { - module = (ShellModule *) modules->data; - - if (!strncmp(module->name, module_name, strlen(module->name))) { - found = TRUE; - break; - } - } - - if (found) { - if (entry_number < g_slist_length(module->entries)) { - GSList *entry_node = g_slist_nth(module->entries, entry_number); - ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; - - if (entry->flags & MODULE_FLAG_NO_REMOTE) { - /* do nothing */ - } else { - module_entry_scan(entry); - answer = module_entry_function(entry); - } - } - } - - if (!answer) { - answer = g_strdup(""); - } - - soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); - g_free(answer); -} - - -static void method_entry_get_note(SoupMessage * msg, GValueArray * params) -{ - ShellModule *module; - GSList *modules; - gchar *module_name, *answer = NULL; - gint entry_number; - gboolean found = FALSE; - MethodParameter method_params[] = { - { G_TYPE_STRING, &module_name }, - { G_TYPE_INT, &entry_number }, - }; - - if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { - return; - } - - for (modules = modules_get_list(); modules; modules = modules->next) { - module = (ShellModule *) modules->data; - - if (!strncmp(module->name, module_name, strlen(module->name))) { - found = TRUE; - break; - } - } - - if (found) { - if (entry_number < g_slist_length(module->entries)) { - GSList *entry_node = g_slist_nth(module->entries, entry_number); - ShellModuleEntry *entry = (ShellModuleEntry *)entry_node->data; - - if (entry->flags & MODULE_FLAG_NO_REMOTE) { - /* do nothing */ - } else { - answer = g_strdup((gchar *)module_entry_get_note(entry)); - } - } - } - - if (!answer) { - answer = g_strdup(""); - } - - soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); - g_free(answer); -} - -static void method_get_about_info(SoupMessage * msg, GValueArray * params) -{ - ShellModule *module; - GSList *modules; - gchar *module_name; - gboolean found = FALSE; - GValueArray *out; - MethodParameter method_params[] = { - { G_TYPE_STRING, &module_name }, - }; - - if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { - return; - } - - for (modules = modules_get_list(); modules; modules = modules->next) { - module = (ShellModule *) modules->data; - - if (!strncmp(module->name, module_name, strlen(module->name))) { - found = TRUE; - break; - } - } - - out = soup_value_array_new(); - - if (found) { - ModuleAbout *about = module_get_about(module); - - soup_value_array_append(out, G_TYPE_STRING, about->description); - soup_value_array_append(out, G_TYPE_STRING, about->author); - soup_value_array_append(out, G_TYPE_STRING, about->version); - soup_value_array_append(out, G_TYPE_STRING, about->license); - } - - soup_xmlrpc_set_response(msg, G_TYPE_VALUE_ARRAY, out); - g_value_array_free(out); -} - -static void method_call_method(SoupMessage * msg, GValueArray * params) -{ - gchar *method_name, *answer = NULL; - MethodParameter method_params[] = { - { G_TYPE_STRING, &method_name }, - }; - - if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { - return; - } - - if (!(answer = module_call_method(method_name))) { - answer = g_strdup(""); - } - - soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); - g_free(answer); -} - -static void method_call_method_param(SoupMessage * msg, - GValueArray * params) -{ - gchar *method_name, *parameter, *answer = NULL; - MethodParameter method_params[] = { - { G_TYPE_STRING, &method_name }, - { G_TYPE_STRING, ¶meter }, - }; - - if (!validate_parameters(msg, params, method_params, G_N_ELEMENTS(method_params))) { - return; - } - - if (!(answer = module_call_method_param(method_name, parameter))) { - answer = g_strdup(""); - } - - soup_xmlrpc_set_response(msg, G_TYPE_STRING, answer); - g_free(answer); -} - -static void method_get_api_version(SoupMessage * msg, GValueArray * params) -{ - soup_xmlrpc_set_response(msg, G_TYPE_INT, XMLRPC_SERVER_VERSION); -} - -static void method_shutdown_server(SoupMessage * msg, GValueArray * params) -{ - soup_xmlrpc_set_response(msg, G_TYPE_BOOLEAN, TRUE); - - g_main_loop_quit(loop); -} -#endif /* HAS_LIBSOUP */ - -void xmlrpc_server_init(void) -{ -#ifdef HAS_LIBSOUP - if (!loop) { - DEBUG("creating main loop"); - loop = g_main_loop_new(NULL, FALSE); - } else { - DEBUG("using main loop instance %p", loop); - } - - if (!handlers) { - int i; - handlers = g_hash_table_new(g_str_hash, g_str_equal); - - DEBUG("registering handlers"); - - for (i = 0; handler_table[i].method_name; i++) { - g_hash_table_insert(handlers, - handler_table[i].method_name, - handler_table[i].callback); - } - } -#endif /* HAS_LIBSOUP */ -} - -#ifdef HAS_LIBSOUP -static SoupServer *xmlrpc_server_new(void) -{ - SoupServer *server; - - DEBUG("creating server"); - server = soup_server_new(SOUP_SERVER_SSL_CERT_FILE, NULL, - SOUP_SERVER_SSL_KEY_FILE, NULL, - SOUP_SERVER_ASYNC_CONTEXT, NULL, - SOUP_SERVER_PORT, 4242, NULL); - if (!server) { - return NULL; - } - - soup_server_run_async(server); - - return server; -} - -static void xmlrpc_server_callback(SoupServer * server, - SoupMessage * msg, - const char *path, - GHashTable * query, - SoupClientContext * context, - gpointer data) -{ - if (msg->method == SOUP_METHOD_POST) { - gchar *method_name; - GValueArray *params; - void (*callback) (SoupMessage * msg, GValueArray * params); - - DEBUG("POST %s", path); - - if (!soup_xmlrpc_parse_method_call(msg->request_body->data, - msg->request_body->length, - &method_name, ¶ms)) { - soup_message_set_status(msg, SOUP_STATUS_BAD_REQUEST); - return; - } - - DEBUG("method: %s", method_name); - - if ((callback = g_hash_table_lookup(handlers, method_name))) { - soup_message_set_status(msg, SOUP_STATUS_OK); - - DEBUG("found callback: %p", callback); - callback(msg, params); - } else { - DEBUG("callback not found"); - soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); - } - - g_value_array_free(params); - g_free(method_name); - } else { - DEBUG("received request of unknown method"); - soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); - } -} - -static void icon_server_callback(SoupServer * server, - SoupMessage * msg, - const char *path, - GHashTable * query, - SoupClientContext * context, - gpointer data) -{ - if (msg->method == SOUP_METHOD_GET) { - path = g_strrstr(path, "/"); - - DEBUG("GET %s", path); - - if (!path || !g_str_has_suffix(path, ".png")) { - DEBUG("not an icon, invalid path, etc"); - soup_message_set_status(msg, SOUP_STATUS_FORBIDDEN); - soup_message_set_response(msg, - "text/plain", - SOUP_MEMORY_STATIC, - "500 :(", 6); - } else { - gchar *file, *icon; - gsize size; - - file = g_build_filename(params.path_data, - "pixmaps", - path + 1, - NULL); - - if (g_file_get_contents(file, &icon, &size, NULL)) { - DEBUG("icon found"); - soup_message_set_status(msg, SOUP_STATUS_OK); - soup_message_set_response(msg, - "image/png", - SOUP_MEMORY_TAKE, - icon, size); - } else { - DEBUG("icon not found"); - soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND); - soup_message_set_response(msg, - "text/plain", - SOUP_MEMORY_STATIC, - "404 :(", 6); - } - - g_free(file); - } - } else { - DEBUG("received request of unknown method"); - soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); - } -} -#endif /* HAS_LIBSOUP */ - -void xmlrpc_server_start(GMainLoop *main_loop) -{ -#ifdef HAS_LIBSOUP - SoupServer *server; - - if (main_loop) { - loop = main_loop; - } - - if (!loop || !handlers) { - DEBUG("initializing server"); - xmlrpc_server_init(); - } - - server = xmlrpc_server_new(); - if (!server) { - if (main_loop) { - g_warning("Cannot create XML-RPC server."); - return; - } else { - g_error("Cannot create XML-RPC server. Aborting"); - } - } - - DEBUG("adding soup handlers for /xmlrpc"); - soup_server_add_handler(server, "/xmlrpc", xmlrpc_server_callback, - NULL, NULL); - DEBUG("adding soup handlers for /icon/"); - soup_server_add_handler(server, "/icon/", icon_server_callback, - NULL, NULL); - - DEBUG("starting server"); - g_print("XML-RPC server ready\n"); - g_main_loop_run(loop); - - DEBUG("shutting down server"); - g_main_loop_unref(loop); - soup_server_quit(server); - g_object_unref(server); -#endif /* HAS_LIBSOUP */ -} - -#ifdef XMLRPC_SERVER_TEST -int main(void) -{ -#ifdef HAS_LIBSOUP - g_type_init(); - - xmlrpc_server_init(); - xmlrpc_server_start(); -#endif /* HAS_LIBSOUP */ -} -#endif /* XMLRPC_SERVER_TEST */ diff --git a/hardinfo2/xmlrpc-server.h b/hardinfo2/xmlrpc-server.h deleted file mode 100644 index e608b711..00000000 --- a/hardinfo2/xmlrpc-server.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 Leandro A. F. Pereira - * - * 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__ */ - -- cgit v1.2.3
    %s
    %s
    %s%s
    %s%s