Add formatting/static analysis (#486)

* Reform source with clang-format.

Rules applied with:
    $ find . -iname *.h -o -iname *.cc | xargs clang-format \
        -style=file -i -fallback-style=google

* Add clang-format and analyze to build.

Based on the excellent work at: https://github.com/ttroy50/cmake-examples

* Clean up CMake stuff on macOS.

* Remove vim/emacs modelines.

* Update copyright dates.

* Build fixes.

* Build fixes.

* Build fixes.

* Build fixes.

* Build fixes.

* Build fixes.
This commit is contained in:
Brenden Matthews
2018-05-12 12:03:00 -04:00
committed by GitHub
parent b20d83b747
commit eebc8c653b
180 changed files with 28420 additions and 28996 deletions

107
.clang-format Normal file
View File

@@ -0,0 +1,107 @@
---
Language: Cpp
# BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: true
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 2
UseTab: Never
...

7
.editorconfig Normal file
View File

@@ -0,0 +1,7 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
intend_size = 2

View File

@@ -1,29 +1,75 @@
language: cpp
compiler:
- gcc
addons:
apt:
packages:
- cmake
- libxdamage-dev
- libx11-dev
- libxft-dev
- libxext-dev
- libglib2.0-dev
- libxml2-dev
- libcurl4-gnutls-dev
- liblua5.1-0-dev
- libtolua++5.1-dev
- libcairo2-dev
- libimlib2-dev
- libxinerama-dev
- gawk
dist: trusty
matrix:
include:
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
packages:
- g++-7
- cmake
- libxdamage-dev
- libx11-dev
- libxft-dev
- libxext-dev
- libglib2.0-dev
- libxml2-dev
- libcurl4-gnutls-dev
- liblua5.1-0-dev
- libtolua++5.1-dev
- libcairo2-dev
- libimlib2-dev
- libxinerama-dev
- gawk
- clang-5.0
- clang-format-5.0
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
packages:
- cmake
- libxdamage-dev
- libx11-dev
- libxft-dev
- libxext-dev
- libglib2.0-dev
- libxml2-dev
- libcurl4-gnutls-dev
- liblua5.1-0-dev
- libtolua++5.1-dev
- libcairo2-dev
- libimlib2-dev
- libxinerama-dev
- gawk
- clang-5.0
- clang-format-5.0
env:
- MATRIX_EVAL="CC=clang && CXX=clang++"
before_install:
- eval "${MATRIX_EVAL}"
before_script:
- mkdir build && cd build && cmake .. && cd ..
- mkdir build-no-x11 && cd build-no-x11 && cmake -DBUILD_X11=OFF .. && cd ..
- mkdir build
- cd build
- scan-build --use-cc=$CC --use-c++=$CXX -o scanbuildout cmake -DCHECK_CODE_FORMAT=ON ..
- travis_wait 30 make format-check
- cd ..
- mkdir build-no-x11
- cd build-no-x11
- scan-build --use-cc=$CC --use-c++=$CXX -o scanbuildout cmake -DCHECK_CODE_FORMAT=ON -DBUILD_X11=OFF ..
- cd ..
script:
- cd build && make -j4 && cd ..
- cd build-no-x11 && make -j4 && cd ..
- cd build
- scan-build --use-cc=$CC --use-c++=$CXX -o scanbuildout make -j4
- cd ../build-no-x11
- scan-build --use-cc=$CC --use-c++=$CXX -o scanbuildout make -j4
branches:
only:
- master

View File

@@ -1,10 +1,9 @@
# vim: ts=4 sw=4 noet ai cindent syntax=cmake
#
# Conky, a system monitor, based on torsmo
#
# Please see COPYING for details
#
# Copyright (c) 2005-2010 Brenden Matthews, et. al. (see AUTHORS)
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
@@ -20,7 +19,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 3.5)
project(conky)
@@ -39,10 +38,22 @@ include(ConkyPlatformChecks)
# CPack module for installation tasks
include(ConkyCPackSetup)
if(CHECK_CODE_FORMAT)
# Set up clang-format
set(CLANG_FORMAT_BIN_NAME clang-format clang-format-5.0)
set(CLANG_FORMAT_EXCLUDE_PATTERNS "build/" ${CMAKE_BINARY_DIR})
find_package(ClangFormat)
endif(CHECK_CODE_FORMAT)
# setup our configuration headers
configure_file(${CMAKE_MODULE_PATH}/config.h.in ${CMAKE_BINARY_DIR}/config.h)
configure_file(${CMAKE_MODULE_PATH}/build.h.in ${CMAKE_BINARY_DIR}/build.h)
set(conky_sources
${CMAKE_BINARY_DIR}/config.h
${CMAKE_BINARY_DIR}/build.h
)
# Finally, add some code
add_subdirectory(lua)
add_subdirectory(data)
@@ -50,7 +61,7 @@ add_subdirectory(doc)
add_subdirectory(src)
IF(NOT DEFINED DOC_PATH)
set(DOC_PATH "share/doc/${CPACK_PACKAGE_NAME}-${VERSION}")
set(DOC_PATH "share/doc/${CPACK_PACKAGE_NAME}-${VERSION}")
ENDIF(NOT DEFINED DOC_PATH)
set(DOC_FILES extras/convert.lua data/conky_no_x11.conf data/conky.conf)
@@ -61,12 +72,12 @@ set(MAN_PATH "share/man/man1")
set(MAN_FILES doc/conky.1)
install(FILES ${DOC_FILES}
DESTINATION ${DOC_PATH})
DESTINATION ${DOC_PATH})
if(MAINTAINER_MODE)
install(FILES ${HTML_FILES}
DESTINATION ${HTML_PATH})
install(FILES ${HTML_FILES}
DESTINATION ${HTML_PATH})
install(FILES ${MAN_FILES}
DESTINATION ${MAN_PATH})
install(FILES ${MAN_FILES}
DESTINATION ${MAN_PATH})
endif(MAINTAINER_MODE)

View File

@@ -1,5 +1,5 @@
Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
All rights reserved.
Redistribution and use in source and binary forms, with or without

5
apply-clang-format.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
find . -iname "*.h" -o -iname "*.cc" -o -iname "*.hh" \
| xargs clang-format \
-style=file -i -fallback-style=google

View File

@@ -1,10 +1,9 @@
# vim: ts=4 sw=4 noet ai cindent syntax=cmake
#
# Conky, a system monitor, based on torsmo
#
# Please see COPYING for details
#
# Copyright (c) 2005-2010 Brenden Matthews, et. al. (see AUTHORS)
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
@@ -24,40 +23,40 @@
# Set system vars
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(OS_LINUX true)
set(OS_LINUX true)
endif(CMAKE_SYSTEM_NAME MATCHES "Linux")
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
set(OS_FREEBSD true)
set(OS_FREEBSD true)
endif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
if(CMAKE_SYSTEM_NAME MATCHES "DragonFly")
set(OS_DRAGONFLY true)
set(OS_DRAGONFLY true)
endif(CMAKE_SYSTEM_NAME MATCHES "DragonFly")
if(CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
set(OS_OPENBSD true)
set(OS_OPENBSD true)
endif(CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
if(CMAKE_SYSTEM_NAME MATCHES "SunOS")
set(OS_SOLARIS true)
set(OS_SOLARIS true)
endif(CMAKE_SYSTEM_NAME MATCHES "SunOS")
if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
set(OS_NETBSD true)
set(OS_NETBSD true)
endif(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
if(CMAKE_SYSTEM_NAME MATCHES "Haiku")
set(OS_HAIKU true)
set(OS_HAIKU true)
endif(CMAKE_SYSTEM_NAME MATCHES "Haiku")
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
set(OS_DARWIN true)
set(OS_DARWIN true)
endif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
if(NOT OS_LINUX AND NOT OS_FREEBSD AND NOT OS_OPENBSD AND NOT OS_DRAGONFLY
AND NOT OS_SOLARIS AND NOT OS_HAIKU AND NOT OS_DARWIN)
message(FATAL_ERROR "Your platform, '${CMAKE_SYSTEM_NAME}', is not currently supported. Patches are welcome.")
AND NOT OS_SOLARIS AND NOT OS_HAIKU AND NOT OS_DARWIN)
message(FATAL_ERROR "Your platform, '${CMAKE_SYSTEM_NAME}', is not currently supported. Patches are welcome.")
endif(NOT OS_LINUX AND NOT OS_FREEBSD AND NOT OS_OPENBSD AND NOT OS_DRAGONFLY
AND NOT OS_SOLARIS AND NOT OS_HAIKU AND NOT OS_DARWIN)
@@ -72,18 +71,18 @@ set(conky_includes ${CMAKE_BINARY_DIR})
# Thus disable this and _LARGEFILE64_SOURCE isnt needed, it is already used on macOS.
#
if(NOT OS_DARWIN)
add_definitions(-D_LARGEFILE64_SOURCE -D_POSIX_C_SOURCE=200809L) # Standard definitions
set(CMAKE_REQUIRED_DEFINITIONS
"${CMAKE_REQUIRED_DEFINITIONS} -D_LARGEFILE64_SOURCE -D_POSIX_C_SOURCE=200809L")
add_definitions(-D_LARGEFILE64_SOURCE -D_POSIX_C_SOURCE=200809L) # Standard definitions
set(CMAKE_REQUIRED_DEFINITIONS
"${CMAKE_REQUIRED_DEFINITIONS} -D_LARGEFILE64_SOURCE -D_POSIX_C_SOURCE=200809L")
endif(NOT OS_DARWIN)
if(OS_DRAGONFLY)
set(conky_libs ${conky_libs} -L/usr/pkg/lib)
set(conky_includes ${conky_includes} -I/usr/pkg/include)
set(conky_libs ${conky_libs} -L/usr/pkg/lib)
set(conky_includes ${conky_includes} -I/usr/pkg/include)
endif(OS_DRAGONFLY)
if(OS_SOLARIS)
set(conky_libs ${conky_libs} -L/usr/local/lib)
set(conky_libs ${conky_libs} -L/usr/local/lib)
endif(OS_SOLARIS)
# Do version stuff
@@ -93,30 +92,30 @@ set(VERSION_PATCH "9")
find_program(APP_AWK awk)
if(NOT APP_AWK)
message(FATAL_ERROR "Unable to find program 'awk'")
message(FATAL_ERROR "Unable to find program 'awk'")
endif(NOT APP_AWK)
find_program(APP_WC wc)
if(NOT APP_WC)
message(FATAL_ERROR "Unable to find program 'wc'")
message(FATAL_ERROR "Unable to find program 'wc'")
endif(NOT APP_WC)
find_program(APP_DATE date)
if(NOT APP_DATE)
message(FATAL_ERROR "Unable to find program 'date'")
message(FATAL_ERROR "Unable to find program 'date'")
endif(NOT APP_DATE)
find_program(APP_UNAME uname)
if(NOT APP_UNAME)
message(FATAL_ERROR "Unable to find program 'uname'")
message(FATAL_ERROR "Unable to find program 'uname'")
endif(NOT APP_UNAME)
if(NOT RELEASE)
find_program(APP_GIT git)
if(NOT APP_GIT)
message(FATAL_ERROR "Unable to find program 'git'")
endif(NOT APP_GIT)
mark_as_advanced(APP_GIT)
find_program(APP_GIT git)
if(NOT APP_GIT)
message(FATAL_ERROR "Unable to find program 'git'")
endif(NOT APP_GIT)
mark_as_advanced(APP_GIT)
endif(NOT RELEASE)
mark_as_advanced(APP_AWK APP_WC APP_DATE APP_UNAME)
@@ -124,37 +123,37 @@ mark_as_advanced(APP_AWK APP_WC APP_DATE APP_UNAME)
#BUILD_DATE=$(LANG=en_US LC_ALL=en_US LOCALE=en_US date)
#BUILD_ARCH="$(uname -sr) ($(uname -m))"
execute_process(COMMAND ${APP_DATE} RESULT_VARIABLE RETVAL OUTPUT_VARIABLE
BUILD_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
BUILD_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${APP_UNAME} -srm RESULT_VARIABLE RETVAL
OUTPUT_VARIABLE BUILD_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
OUTPUT_VARIABLE BUILD_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
if(RELEASE)
set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
else(RELEASE)
set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}_pre${COMMIT_COUNT}")
set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}_pre${COMMIT_COUNT}")
endif(RELEASE)
set(COPYRIGHT "Copyright Brenden Matthews, et al, 2005-2015")
set(COPYRIGHT "Copyright Brenden Matthews, et al, 2005-2018")
macro(AC_SEARCH_LIBS FUNCTION_NAME INCLUDES TARGET_VAR)
if("${TARGET_VAR}" MATCHES "^${TARGET_VAR}$")
unset(AC_SEARCH_LIBS_TMP CACHE)
check_symbol_exists(${FUNCTION_NAME} ${INCLUDES} AC_SEARCH_LIBS_TMP)
if(${AC_SEARCH_LIBS_TMP})
set(${TARGET_VAR} "" CACHE INTERNAL "Library containing ${FUNCTION_NAME}")
else(${AC_SEARCH_LIBS_TMP})
foreach(LIB ${ARGN})
unset(AC_SEARCH_LIBS_TMP CACHE)
unset(AC_SEARCH_LIBS_FOUND CACHE)
find_library(AC_SEARCH_LIBS_TMP ${LIB})
check_library_exists(${LIB} ${FUNCTION_NAME} ${AC_SEARCH_LIBS_TMP}
AC_SEARCH_LIBS_FOUND)
if(${AC_SEARCH_LIBS_FOUND})
set(${TARGET_VAR} ${AC_SEARCH_LIBS_TMP} CACHE INTERNAL
"Library containing ${FUNCTION_NAME}")
break()
endif(${AC_SEARCH_LIBS_FOUND})
endforeach(LIB)
endif(${AC_SEARCH_LIBS_TMP})
endif("${TARGET_VAR}" MATCHES "^${TARGET_VAR}$")
if("${TARGET_VAR}" MATCHES "^${TARGET_VAR}$")
unset(AC_SEARCH_LIBS_TMP CACHE)
check_symbol_exists(${FUNCTION_NAME} ${INCLUDES} AC_SEARCH_LIBS_TMP)
if(${AC_SEARCH_LIBS_TMP})
set(${TARGET_VAR} "" CACHE INTERNAL "Library containing ${FUNCTION_NAME}")
else(${AC_SEARCH_LIBS_TMP})
foreach(LIB ${ARGN})
unset(AC_SEARCH_LIBS_TMP CACHE)
unset(AC_SEARCH_LIBS_FOUND CACHE)
find_library(AC_SEARCH_LIBS_TMP ${LIB})
check_library_exists(${LIB} ${FUNCTION_NAME} ${AC_SEARCH_LIBS_TMP}
AC_SEARCH_LIBS_FOUND)
if(${AC_SEARCH_LIBS_FOUND})
set(${TARGET_VAR} ${AC_SEARCH_LIBS_TMP} CACHE INTERNAL
"Library containing ${FUNCTION_NAME}")
break()
endif(${AC_SEARCH_LIBS_FOUND})
endforeach(LIB)
endif(${AC_SEARCH_LIBS_TMP})
endif("${TARGET_VAR}" MATCHES "^${TARGET_VAR}$")
endmacro(AC_SEARCH_LIBS)

View File

@@ -1,10 +1,9 @@
# vim: ts=4 sw=4 noet ai cindent syntax=cmake
#
# Conky, a system monitor, based on torsmo
#
# Please see COPYING for details
#
# Copyright (c) 2005-2010 Brenden Matthews, et. al. (see AUTHORS)
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
@@ -179,3 +178,5 @@ option(BUILD_CMUS "Enable support for cmus music player" false)
option(BUILD_JOURNAL "Enable support for reading from the systemd journal" false)
option(BUILD_PULSEAUDIO "Enable support for Pulseaudio's default sink and source" false)
option(CHECK_CODE_FORMAT "Check code formatting with clang-format" false)

View File

@@ -1,10 +1,9 @@
# vim: ts=4 sw=4 noet ai cindent syntax=cmake
#
# Conky, a system monitor, based on torsmo
#
# Please see COPYING for details
#
# Copyright (c) 2005-2010 Brenden Matthews, et. al. (see AUTHORS)
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify

View File

@@ -1,10 +1,9 @@
# vim: ts=4 sw=4 noet ai cindent syntax=cmake
#
# Conky, a system monitor, based on torsmo
#
# Please see COPYING for details
#
# Copyright (c) 2005-2010 Brenden Matthews, et. al. (see AUTHORS)
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
@@ -38,18 +37,18 @@ check_symbol_exists(pipe2 "unistd.h" HAVE_PIPE2)
check_symbol_exists(O_CLOEXEC "fcntl.h" HAVE_O_CLOEXEC)
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
check_symbol_exists(statfs64 "sys/mount.h" HAVE_STATFS64)
check_symbol_exists(statfs64 "sys/mount.h" HAVE_STATFS64)
else(CMAKE_SYSTEM_NAME MATCHES "Darwin")
check_symbol_exists(statfs64 "sys/statfs.h" HAVE_STATFS64)
check_symbol_exists(statfs64 "sys/statfs.h" HAVE_STATFS64)
endif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
AC_SEARCH_LIBS(clock_gettime "time.h" CLOCK_GETTIME_LIB "rt")
if(NOT DEFINED CLOCK_GETTIME_LIB)
if(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
message(FATAL_ERROR "clock_gettime not found.")
endif(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
if(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
message(FATAL_ERROR "clock_gettime not found.")
endif(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
else(NOT DEFINED CLOCK_GETTIME_LIB)
set(HAVE_CLOCK_GETTIME 1)
set(HAVE_CLOCK_GETTIME 1)
endif(NOT DEFINED CLOCK_GETTIME_LIB)
set(conky_libs ${conky_libs} ${CLOCK_GETTIME_LIB})
@@ -58,258 +57,275 @@ set(INCLUDE_SEARCH_PATH /usr/include /usr/local/include)
# Set system vars
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(OS_LINUX true)
set(OS_LINUX true)
endif(CMAKE_SYSTEM_NAME MATCHES "Linux")
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
set(OS_FREEBSD true)
set(conky_libs ${conky_libs} -lkvm -ldevstat -lbsd)
set(OS_FREEBSD true)
set(conky_libs ${conky_libs} -lkvm -ldevstat -lbsd)
endif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
if(CMAKE_SYSTEM_NAME MATCHES "DragonFly")
set(OS_DRAGONFLY true)
set(conky_libs ${conky_libs} -ldevstat)
set(OS_DRAGONFLY true)
set(conky_libs ${conky_libs} -ldevstat)
endif(CMAKE_SYSTEM_NAME MATCHES "DragonFly")
if(CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
set(OS_OPENBSD true)
set(OS_OPENBSD true)
endif(CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
if(CMAKE_SYSTEM_NAME MATCHES "SunOS")
set(OS_SOLARIS true)
set(conky_libs ${conky_libs} -lkstat)
set(OS_SOLARIS true)
set(conky_libs ${conky_libs} -lkstat)
endif(CMAKE_SYSTEM_NAME MATCHES "SunOS")
if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
set(OS_NETBSD true)
set(OS_NETBSD true)
endif(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
if(CMAKE_SYSTEM_NAME MATCHES "Haiku")
set(OS_HAIKU true)
set(conky_libs ${conky_libs} -lnetwork -lintl)
set(OS_HAIKU true)
set(conky_libs ${conky_libs} -lnetwork -lintl)
endif(CMAKE_SYSTEM_NAME MATCHES "Haiku")
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
set(OS_DARWIN true)
set(OS_DARWIN true)
endif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
if(NOT OS_LINUX AND NOT OS_FREEBSD AND NOT OS_OPENBSD AND NOT OS_DRAGONFLY
AND NOT OS_SOLARIS AND NOT OS_HAIKU AND NOT OS_DARWIN)
message(FATAL_ERROR "Your platform, '${CMAKE_SYSTEM_NAME}', is not currently supported. Patches are welcome.")
if(NOT OS_LINUX AND NOT OS_FREEBSD AND NOT OS_OPENBSD AND NOT OS_DRAGONFLY
AND NOT OS_SOLARIS AND NOT OS_HAIKU AND NOT OS_DARWIN)
message(FATAL_ERROR "Your platform, '${CMAKE_SYSTEM_NAME}', is not currently supported. Patches are welcome.")
endif(NOT OS_LINUX AND NOT OS_FREEBSD AND NOT OS_OPENBSD AND NOT OS_DRAGONFLY
AND NOT OS_SOLARIS AND NOT OS_HAIKU AND NOT OS_DARWIN)
# Check for soundcard header
if(OS_LINUX)
check_include_files("linux/soundcard.h" HAVE_SOME_SOUNDCARD_H)
check_include_files("linux/soundcard.h" HAVE_LINUX_SOUNDCARD_H)
check_include_files("linux/soundcard.h" HAVE_SOME_SOUNDCARD_H)
check_include_files("linux/soundcard.h" HAVE_LINUX_SOUNDCARD_H)
elseif(OS_OPENBSD)
check_include_files("soundcard.h" HAVE_SOME_SOUNDCARD_H)
check_include_files("soundcard.h" HAVE_SOME_SOUNDCARD_H)
else(OS_LINUX)
check_include_files("sys/soundcard.h" HAVE_SOME_SOUNDCARD_H)
check_include_files("sys/soundcard.h" HAVE_SOME_SOUNDCARD_H)
endif(OS_LINUX)
if(BUILD_I18N AND OS_DRAGONFLY)
set(conky_libs ${conky_libs} -lintl)
set(conky_libs ${conky_libs} -lintl)
endif(BUILD_I18N AND OS_DRAGONFLY)
if(BUILD_I18N AND OS_DARWIN)
set(conky_libs ${conky_libs} -lintl)
find_path(LIBINTL_H_N libintl.h PATHS
/usr/local/opt/gettext/include
/usr/include
/usr/local/include
/usr/local/opt/include
)
if(LIBINTL_H_N)
include_directories(${LIBINTL_H_N})
else(LIBINTL_H_N)
message(FATAL_ERROR "Unable to find libintl.h (try `brew install gettext`)")
endif(LIBINTL_H_N)
find_library(INTL_LIB NAMES intl PATHS
/usr/local/opt/gettext/lib
/usr/lib
/usr/local/lib
/usr/local/opt/lib
)
set(conky_libs ${conky_libs} ${INTL_LIB})
endif(BUILD_I18N AND OS_DARWIN)
if(BUILD_NCURSES AND OS_DARWIN)
set(conky_libs ${conky_libs} -lncurses)
set(conky_libs ${conky_libs} -lncurses)
endif(BUILD_NCURSES AND OS_DARWIN)
if(BUILD_MATH)
set(conky_libs ${conky_libs} -lm)
set(conky_libs ${conky_libs} -lm)
endif(BUILD_MATH)
if(BUILD_ICAL)
check_include_files(libical/ical.h ICAL_H_)
if(NOT ICAL_H_)
message(FATAL_ERROR "Unable to find libical")
endif(NOT ICAL_H_)
set(conky_libs ${conky_libs} -lical)
check_include_files(libical/ical.h ICAL_H_)
if(NOT ICAL_H_)
message(FATAL_ERROR "Unable to find libical")
endif(NOT ICAL_H_)
set(conky_libs ${conky_libs} -lical)
endif(BUILD_ICAL)
if(BUILD_IRC)
find_path(IRC_H_N libircclient.h PATHS /usr/include/libircclient)
find_path(IRC_H_S libircclient.h PATHS /usr/include)
if(IRC_H_N)
include_directories(${IRC_H_N})
endif(IRC_H_N)
if(IRC_H_N OR IRC_H_S)
set(IRC_H_ true)
else()
message(FATAL_ERROR "Unable to find libircclient")
endif(IRC_H_N OR IRC_H_S)
set(conky_libs ${conky_libs} -lircclient)
find_path(IRC_H_N libircclient.h PATHS /usr/include/libircclient)
find_path(IRC_H_S libircclient.h PATHS /usr/include)
if(IRC_H_N)
include_directories(${IRC_H_N})
endif(IRC_H_N)
if(IRC_H_N OR IRC_H_S)
set(IRC_H_ true)
else()
message(FATAL_ERROR "Unable to find libircclient")
endif(IRC_H_N OR IRC_H_S)
set(conky_libs ${conky_libs} -lircclient)
endif(BUILD_IRC)
if(BUILD_IPV6)
find_file(IF_INET6 if_inet6 PATHS /proc/net)
if(NOT IF_INET6)
message(WARNING "/proc/net/if_inet6 unavailable")
endif(NOT IF_INET6)
find_file(IF_INET6 if_inet6 PATHS /proc/net)
if(NOT IF_INET6)
message(WARNING "/proc/net/if_inet6 unavailable")
endif(NOT IF_INET6)
endif(BUILD_IPV6)
if(BUILD_HTTP)
find_file(HTTP_H_ microhttpd.h)
#I'm not using check_include_files because microhttpd.h seems to need a lot of different headers and i'm not sure which...
if(NOT HTTP_H_)
message(FATAL_ERROR "Unable to find libmicrohttpd")
endif(NOT HTTP_H_)
set(conky_libs ${conky_libs} -lmicrohttpd)
find_file(HTTP_H_ microhttpd.h)
#I'm not using check_include_files because microhttpd.h seems to need a lot of different headers and i'm not sure which...
if(NOT HTTP_H_)
message(FATAL_ERROR "Unable to find libmicrohttpd")
endif(NOT HTTP_H_)
set(conky_libs ${conky_libs} -lmicrohttpd)
endif(BUILD_HTTP)
if(BUILD_NCURSES)
include(FindCurses)
if(NOT CURSES_FOUND)
message(FATAL_ERROR "Unable to find ncurses library")
endif(NOT CURSES_FOUND)
set(conky_libs ${conky_libs} ${CURSES_LIBRARIES})
set(conky_includes ${conky_includes} ${CURSES_INCLUDE_DIR})
include(FindCurses)
if(NOT CURSES_FOUND)
message(FATAL_ERROR "Unable to find ncurses library")
endif(NOT CURSES_FOUND)
set(conky_libs ${conky_libs} ${CURSES_LIBRARIES})
set(conky_includes ${conky_includes} ${CURSES_INCLUDE_DIR})
endif(BUILD_NCURSES)
if(BUILD_MYSQL)
find_path(mysql_INCLUDE_PATH mysql.h ${INCLUDE_SEARCH_PATH} /usr/include/mysql /usr/local/include/mysql)
if(NOT mysql_INCLUDE_PATH)
message(FATAL_ERROR "Unable to find mysql.h")
endif(NOT mysql_INCLUDE_PATH)
set(conky_includes ${conky_includes} ${mysql_INCLUDE_PATH})
find_library(MYSQLCLIENT_LIB NAMES mysqlclient)
if(NOT MYSQLCLIENT_LIB)
message(FATAL_ERROR "Unable to find mysqlclient library")
endif(NOT MYSQLCLIENT_LIB)
set(conky_libs ${conky_libs} ${MYSQLCLIENT_LIB})
find_path(mysql_INCLUDE_PATH mysql.h ${INCLUDE_SEARCH_PATH} /usr/include/mysql /usr/local/include/mysql)
if(NOT mysql_INCLUDE_PATH)
message(FATAL_ERROR "Unable to find mysql.h")
endif(NOT mysql_INCLUDE_PATH)
set(conky_includes ${conky_includes} ${mysql_INCLUDE_PATH})
find_library(MYSQLCLIENT_LIB NAMES mysqlclient)
if(NOT MYSQLCLIENT_LIB)
message(FATAL_ERROR "Unable to find mysqlclient library")
endif(NOT MYSQLCLIENT_LIB)
set(conky_libs ${conky_libs} ${MYSQLCLIENT_LIB})
endif(BUILD_MYSQL)
if(BUILD_WLAN)
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
check_include_files(iwlib.h IWLIB_H)
if(NOT IWLIB_H)
message(FATAL_ERROR "Unable to find iwlib.h")
endif(NOT IWLIB_H)
find_library(IWLIB_LIB NAMES iw)
if(NOT IWLIB_LIB)
message(FATAL_ERROR "Unable to find libiw.so")
endif(NOT IWLIB_LIB)
set(conky_libs ${conky_libs} ${IWLIB_LIB})
check_function_exists(iw_sockets_open IWLIB_SOCKETS_OPEN_FUNC)
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
check_include_files(iwlib.h IWLIB_H)
if(NOT IWLIB_H)
message(FATAL_ERROR "Unable to find iwlib.h")
endif(NOT IWLIB_H)
find_library(IWLIB_LIB NAMES iw)
if(NOT IWLIB_LIB)
message(FATAL_ERROR "Unable to find libiw.so")
endif(NOT IWLIB_LIB)
set(conky_libs ${conky_libs} ${IWLIB_LIB})
check_function_exists(iw_sockets_open IWLIB_SOCKETS_OPEN_FUNC)
endif(BUILD_WLAN)
if(BUILD_PORT_MONITORS)
check_function_exists(getnameinfo HAVE_GETNAMEINFO)
if(NOT HAVE_GETNAMEINFO)
message(FATAL_ERROR "could not find getnameinfo()")
endif(NOT HAVE_GETNAMEINFO)
check_include_files("netdb.h;netinet/in.h;netinet/tcp.h;sys/socket.h;arpa/inet.h" HAVE_PORTMON_HEADERS)
if(NOT HAVE_PORTMON_HEADERS)
message(FATAL_ERROR "missing needed network header(s) for port monitoring")
endif(NOT HAVE_PORTMON_HEADERS)
check_function_exists(getnameinfo HAVE_GETNAMEINFO)
if(NOT HAVE_GETNAMEINFO)
message(FATAL_ERROR "could not find getnameinfo()")
endif(NOT HAVE_GETNAMEINFO)
check_include_files("netdb.h;netinet/in.h;netinet/tcp.h;sys/socket.h;arpa/inet.h" HAVE_PORTMON_HEADERS)
if(NOT HAVE_PORTMON_HEADERS)
message(FATAL_ERROR "missing needed network header(s) for port monitoring")
endif(NOT HAVE_PORTMON_HEADERS)
endif(BUILD_PORT_MONITORS)
# Check for iconv
if(BUILD_ICONV)
check_include_files(iconv.h HAVE_ICONV_H)
find_library(ICONV_LIBRARY NAMES iconv)
if(NOT ICONV_LIBRARY)
# maybe iconv() is provided by libc
set(ICONV_LIBRARY "" CACHE FILEPATH "Path to the iconv library, if iconv is not provided by libc" FORCE)
endif(NOT ICONV_LIBRARY)
set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARY})
check_function_exists(iconv ICONV_FUNC)
if(HAVE_ICONV_H AND ICONV_FUNC)
set(conky_includes ${conky_includes} ${ICONV_INCLUDE_DIR})
set(conky_libs ${conky_libs} ${ICONV_LIBRARY})
else(HAVE_ICONV_H AND ICONV_FUNC)
message(FATAL_ERROR "Unable to find iconv library")
endif(HAVE_ICONV_H AND ICONV_FUNC)
check_include_files(iconv.h HAVE_ICONV_H)
find_library(ICONV_LIBRARY NAMES iconv)
if(NOT ICONV_LIBRARY)
# maybe iconv() is provided by libc
set(ICONV_LIBRARY "" CACHE FILEPATH "Path to the iconv library, if iconv is not provided by libc" FORCE)
endif(NOT ICONV_LIBRARY)
set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARY})
check_function_exists(iconv ICONV_FUNC)
if(HAVE_ICONV_H AND ICONV_FUNC)
set(conky_includes ${conky_includes} ${ICONV_INCLUDE_DIR})
set(conky_libs ${conky_libs} ${ICONV_LIBRARY})
else(HAVE_ICONV_H AND ICONV_FUNC)
message(FATAL_ERROR "Unable to find iconv library")
endif(HAVE_ICONV_H AND ICONV_FUNC)
endif(BUILD_ICONV)
# check for Xlib
if(BUILD_X11)
include(FindX11)
find_package(X11)
if(X11_FOUND)
set(conky_includes ${conky_includes} ${X11_INCLUDE_DIR})
set(conky_libs ${conky_libs} ${X11_LIBRARIES})
include(FindX11)
find_package(X11)
if(X11_FOUND)
set(conky_includes ${conky_includes} ${X11_INCLUDE_DIR})
set(conky_libs ${conky_libs} ${X11_LIBRARIES})
# check for Xdamage
if(BUILD_XDAMAGE)
if(NOT X11_Xdamage_FOUND)
message(FATAL_ERROR "Unable to find Xdamage library")
endif(NOT X11_Xdamage_FOUND)
if(NOT X11_Xfixes_FOUND)
message(FATAL_ERROR "Unable to find Xfixes library")
endif(NOT X11_Xfixes_FOUND)
set(conky_libs ${conky_libs} ${X11_Xdamage_LIB} ${X11_Xfixes_LIB})
endif(BUILD_XDAMAGE)
# check for Xdamage
if(BUILD_XDAMAGE)
if(NOT X11_Xdamage_FOUND)
message(FATAL_ERROR "Unable to find Xdamage library")
endif(NOT X11_Xdamage_FOUND)
if(NOT X11_Xfixes_FOUND)
message(FATAL_ERROR "Unable to find Xfixes library")
endif(NOT X11_Xfixes_FOUND)
set(conky_libs ${conky_libs} ${X11_Xdamage_LIB} ${X11_Xfixes_LIB})
endif(BUILD_XDAMAGE)
if(BUILD_XSHAPE)
if(NOT X11_Xshape_FOUND)
message(FATAL_ERROR "Unable to find Xshape library")
endif(NOT X11_Xshape_FOUND)
set(conky_libs ${conky_libs} ${X11_Xshape_LIB} )
endif(BUILD_XSHAPE)
if(BUILD_XSHAPE)
if(NOT X11_Xshape_FOUND)
message(FATAL_ERROR "Unable to find Xshape library")
endif(NOT X11_Xshape_FOUND)
set(conky_libs ${conky_libs} ${X11_Xshape_LIB} )
endif(BUILD_XSHAPE)
# check for Xft
if(BUILD_XFT)
find_path(freetype_INCLUDE_PATH config/ftconfig.h ${INCLUDE_SEARCH_PATH}
/usr/include/freetype2
/usr/local/include/freetype2
/usr/pkg/include/freetype2)
if(freetype_INCLUDE_PATH)
set(freetype_FOUND true)
set(conky_includes ${conky_includes} ${freetype_INCLUDE_PATH})
else(freetype_INCLUDE_PATH)
find_path(freetype_INCLUDE_PATH freetype/config/ftconfig.h ${INCLUDE_SEARCH_PATH}
/usr/include/freetype2
/usr/local/include/freetype2
/usr/pkg/include/freetype2)
if(freetype_INCLUDE_PATH)
set(freetype_FOUND true)
set(conky_includes ${conky_includes} ${freetype_INCLUDE_PATH})
else(freetype_INCLUDE_PATH)
message(FATAL_ERROR "Unable to find freetype library")
endif(freetype_INCLUDE_PATH)
endif(freetype_INCLUDE_PATH)
if(NOT X11_Xft_FOUND)
message(FATAL_ERROR "Unable to find Xft library")
endif(NOT X11_Xft_FOUND)
set(conky_libs ${conky_libs} ${X11_Xft_LIB})
endif(BUILD_XFT)
# check for Xft
if(BUILD_XFT)
find_path(freetype_INCLUDE_PATH config/ftconfig.h ${INCLUDE_SEARCH_PATH}
/usr/include/freetype2
/usr/local/include/freetype2
/usr/pkg/include/freetype2)
if(freetype_INCLUDE_PATH)
set(freetype_FOUND true)
set(conky_includes ${conky_includes} ${freetype_INCLUDE_PATH})
else(freetype_INCLUDE_PATH)
find_path(freetype_INCLUDE_PATH freetype/config/ftconfig.h ${INCLUDE_SEARCH_PATH}
/usr/include/freetype2
/usr/local/include/freetype2
/usr/pkg/include/freetype2)
if(freetype_INCLUDE_PATH)
set(freetype_FOUND true)
set(conky_includes ${conky_includes} ${freetype_INCLUDE_PATH})
else(freetype_INCLUDE_PATH)
message(FATAL_ERROR "Unable to find freetype library")
endif(freetype_INCLUDE_PATH)
endif(freetype_INCLUDE_PATH)
if(NOT X11_Xft_FOUND)
message(FATAL_ERROR "Unable to find Xft library")
endif(NOT X11_Xft_FOUND)
set(conky_libs ${conky_libs} ${X11_Xft_LIB})
endif(BUILD_XFT)
# check for Xdbe
if(BUILD_XDBE)
if(NOT X11_Xext_FOUND)
message(FATAL_ERROR "Unable to find Xext library (needed for Xdbe)")
endif(NOT X11_Xext_FOUND)
set(conky_libs ${conky_libs} ${X11_Xext_LIB})
endif(BUILD_XDBE)
else(X11_FOUND)
message(FATAL_ERROR "Unable to find X11 library")
endif(X11_FOUND)
# check for Xdbe
if(BUILD_XDBE)
if(NOT X11_Xext_FOUND)
message(FATAL_ERROR "Unable to find Xext library (needed for Xdbe)")
endif(NOT X11_Xext_FOUND)
set(conky_libs ${conky_libs} ${X11_Xext_LIB})
endif(BUILD_XDBE)
else(X11_FOUND)
message(FATAL_ERROR "Unable to find X11 library")
endif(X11_FOUND)
endif(BUILD_X11)
# Check whether we want Lua bindings
if(BUILD_LUA_CAIRO OR BUILD_LUA_IMLIB2 OR BUILD_LUA_RSVG)
set(WANT_TOLUA true)
set(WANT_TOLUA true)
endif(BUILD_LUA_CAIRO OR BUILD_LUA_IMLIB2 OR BUILD_LUA_RSVG)
# Check for Lua itself
if(WANT_TOLUA)
# If we need tolua++, we must compile against Lua 5.1
pkg_search_module(LUA REQUIRED lua5.1 lua-5.1 lua51 lua)
if(NOT LUA_VERSION VERSION_LESS 5.2.0)
message(FATAL_ERROR "Unable to find Lua 5.1.x")
endif(NOT LUA_VERSION VERSION_LESS 5.2.0)
# If we need tolua++, we must compile against Lua 5.1
pkg_search_module(LUA REQUIRED lua5.1 lua-5.1 lua51 lua)
if(NOT LUA_VERSION VERSION_LESS 5.2.0)
message(FATAL_ERROR "Unable to find Lua 5.1.x")
endif(NOT LUA_VERSION VERSION_LESS 5.2.0)
else(WANT_TOLUA)
# Otherwise, use the most recent Lua version
pkg_search_module(LUA REQUIRED lua>=5.3 lua5.3 lua-5.3 lua53 lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua51 lua>=5.1)
# Otherwise, use the most recent Lua version
pkg_search_module(LUA REQUIRED lua>=5.3 lua5.3 lua-5.3 lua53 lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua51 lua>=5.1)
endif(WANT_TOLUA)
set(conky_libs ${conky_libs} ${LUA_LIBRARIES})
set(conky_includes ${conky_includes} ${LUA_INCLUDE_DIRS})
@@ -317,183 +333,183 @@ link_directories(${LUA_LIBRARY_DIRS})
# Check for libraries used by Lua bindings
if(BUILD_LUA_CAIRO)
pkg_check_modules(CAIRO REQUIRED cairo cairo-xlib)
set(luacairo_libs ${CAIRO_LIBRARIES} ${LUA_LIBRARIES})
set(luacairo_includes ${CAIRO_INCLUDE_DIRS} ${LUA_INCLUDE_DIRS})
find_program(APP_PATCH patch)
if(NOT APP_PATCH)
message(FATAL_ERROR "Unable to find program 'patch'")
endif(NOT APP_PATCH)
pkg_check_modules(CAIRO REQUIRED cairo cairo-xlib)
set(luacairo_libs ${CAIRO_LIBRARIES} ${LUA_LIBRARIES})
set(luacairo_includes ${CAIRO_INCLUDE_DIRS} ${LUA_INCLUDE_DIRS})
find_program(APP_PATCH patch)
if(NOT APP_PATCH)
message(FATAL_ERROR "Unable to find program 'patch'")
endif(NOT APP_PATCH)
endif(BUILD_LUA_CAIRO)
if(BUILD_LUA_IMLIB2)
pkg_search_module(IMLIB2 REQUIRED imlib2 Imlib2)
set(luaimlib2_libs ${IMLIB2_LIB} ${LUA_LIBRARIES})
set(luaimlib2_includes ${IMLIB2_INCLUDE_PATH} ${LUA_INCLUDE_DIRS})
pkg_search_module(IMLIB2 REQUIRED imlib2 Imlib2)
set(luaimlib2_libs ${IMLIB2_LIB} ${LUA_LIBRARIES})
set(luaimlib2_includes ${IMLIB2_INCLUDE_PATH} ${LUA_INCLUDE_DIRS})
endif(BUILD_LUA_IMLIB2)
if(BUILD_LUA_RSVG)
pkg_check_modules(RSVG REQUIRED librsvg-2.0)
set(luarsvg_libs ${RSVG_LIBRARIES} ${LUA_LIBRARIES})
set(luarsvg_includes ${RSVG_INCLUDE_DIRS} ${LUA_INCLUDE_DIRS})
pkg_check_modules(RSVG REQUIRED librsvg-2.0)
set(luarsvg_libs ${RSVG_LIBRARIES} ${LUA_LIBRARIES})
set(luarsvg_includes ${RSVG_INCLUDE_DIRS} ${LUA_INCLUDE_DIRS})
endif(BUILD_LUA_RSVG)
if(BUILD_AUDACIOUS)
set(WANT_GLIB true)
pkg_check_modules(NEW_AUDACIOUS audacious>=1.4.0)
if(NEW_AUDACIOUS_FOUND)
pkg_check_modules(AUDACIOUS REQUIRED audclient>=1.4.0)
pkg_check_modules(DBUS_GLIB REQUIRED dbus-glib-1)
else(NEW_AUDACIOUS_FOUND)
pkg_check_modules(AUDACIOUS REQUIRED audacious<1.4.0)
endif(NEW_AUDACIOUS_FOUND)
set(conky_libs ${conky_libs} ${AUDACIOUS_LIBRARIES} ${DBUS_GLIB_LIBRARIES})
set(conky_includes ${conky_includes} ${AUDACIOUS_INCLUDE_DIRS} ${DBUS_GLIB_INCLUDE_DIRS})
set(WANT_GLIB true)
pkg_check_modules(NEW_AUDACIOUS audacious>=1.4.0)
if(NEW_AUDACIOUS_FOUND)
pkg_check_modules(AUDACIOUS REQUIRED audclient>=1.4.0)
pkg_check_modules(DBUS_GLIB REQUIRED dbus-glib-1)
else(NEW_AUDACIOUS_FOUND)
pkg_check_modules(AUDACIOUS REQUIRED audacious<1.4.0)
endif(NEW_AUDACIOUS_FOUND)
set(conky_libs ${conky_libs} ${AUDACIOUS_LIBRARIES} ${DBUS_GLIB_LIBRARIES})
set(conky_includes ${conky_includes} ${AUDACIOUS_INCLUDE_DIRS} ${DBUS_GLIB_INCLUDE_DIRS})
endif(BUILD_AUDACIOUS)
if(BUILD_BMPX)
pkg_check_modules(BMPX REQUIRED bmp-2.0>=0.14.0)
set(conky_libs ${conky_libs} ${BMPX_LIBRARIES})
set(conky_includes ${conky_includes} ${BMPX_INCLUDE_DIRS})
pkg_check_modules(BMPX REQUIRED bmp-2.0>=0.14.0)
set(conky_libs ${conky_libs} ${BMPX_LIBRARIES})
set(conky_includes ${conky_includes} ${BMPX_INCLUDE_DIRS})
endif(BUILD_BMPX)
if(BUILD_XMMS2)
pkg_check_modules(XMMS2 REQUIRED xmms2-client>=0.6)
set(conky_libs ${conky_libs} ${XMMS2_LIBRARIES})
set(conky_includes ${conky_includes} ${XMMS2_INCLUDE_DIRS})
pkg_check_modules(XMMS2 REQUIRED xmms2-client>=0.6)
set(conky_libs ${conky_libs} ${XMMS2_LIBRARIES})
set(conky_includes ${conky_includes} ${XMMS2_INCLUDE_DIRS})
endif(BUILD_XMMS2)
if(BUILD_EVE)
set(WANT_CURL true)
set(WANT_LIBXML2 true)
set(WANT_CURL true)
set(WANT_LIBXML2 true)
endif(BUILD_EVE)
if(BUILD_CURL)
set(WANT_CURL true)
set(WANT_CURL true)
endif(BUILD_CURL)
if(BUILD_RSS)
set(WANT_CURL true)
set(WANT_LIBXML2 true)
set(WANT_CURL true)
set(WANT_LIBXML2 true)
endif(BUILD_RSS)
if(BUILD_WEATHER_METAR)
set(WANT_CURL true)
set(BUILD_WEATHER true)
set(WANT_CURL true)
set(BUILD_WEATHER true)
endif(BUILD_WEATHER_METAR)
if(BUILD_WEATHER_XOAP)
set(WANT_LIBXML2 true)
set(WANT_CURL true)
set(BUILD_XOAP true)
set(BUILD_WEATHER true)
set(WANT_LIBXML2 true)
set(WANT_CURL true)
set(BUILD_XOAP true)
set(BUILD_WEATHER true)
endif(BUILD_WEATHER_XOAP)
if(BUILD_NVIDIA)
find_path(XNVCtrl_INCLUDE_PATH NVCtrl/NVCtrl.h ${INCLUDE_SEARCH_PATH})
find_library(XNVCtrl_LIB NAMES XNVCtrl)
if(XNVCtrl_INCLUDE_PATH AND XNVCtrl_LIB)
set(XNVCtrl_FOUND true)
set(conky_libs ${conky_libs} ${XNVCtrl_LIB})
set(conky_includes ${conky_includes} ${XNVCtrl_INCLUDE_PATH})
else(XNVCtrl_INCLUDE_PATH AND XNVCtrl_LIB)
message(FATAL_ERROR "Unable to find XNVCtrl library")
endif(XNVCtrl_INCLUDE_PATH AND XNVCtrl_LIB)
find_path(XNVCtrl_INCLUDE_PATH NVCtrl/NVCtrl.h ${INCLUDE_SEARCH_PATH})
find_library(XNVCtrl_LIB NAMES XNVCtrl)
if(XNVCtrl_INCLUDE_PATH AND XNVCtrl_LIB)
set(XNVCtrl_FOUND true)
set(conky_libs ${conky_libs} ${XNVCtrl_LIB})
set(conky_includes ${conky_includes} ${XNVCtrl_INCLUDE_PATH})
else(XNVCtrl_INCLUDE_PATH AND XNVCtrl_LIB)
message(FATAL_ERROR "Unable to find XNVCtrl library")
endif(XNVCtrl_INCLUDE_PATH AND XNVCtrl_LIB)
endif(BUILD_NVIDIA)
if(BUILD_IMLIB2)
pkg_search_module(IMLIB2 REQUIRED imlib2 Imlib2)
set(conky_libs ${conky_libs} ${IMLIB2_LIB} ${IMLIB2_LDFLAGS})
set(conky_includes ${conky_includes} ${IMLIB2_INCLUDE_PATH})
pkg_search_module(IMLIB2 REQUIRED imlib2 Imlib2)
set(conky_libs ${conky_libs} ${IMLIB2_LIB} ${IMLIB2_LDFLAGS})
set(conky_includes ${conky_includes} ${IMLIB2_INCLUDE_PATH})
endif(BUILD_IMLIB2)
if(BUILD_JOURNAL)
pkg_search_module(SYSTEMD REQUIRED libsystemd)
set(conky_libs ${conky_libs} ${SYSTEMD_LIB} ${SYSTEMD_LDFLAGS})
set(conky_includes ${conky_includes} ${SYSTEMD_INCLUDE_PATH})
pkg_search_module(SYSTEMD REQUIRED libsystemd)
set(conky_libs ${conky_libs} ${SYSTEMD_LIB} ${SYSTEMD_LDFLAGS})
set(conky_includes ${conky_includes} ${SYSTEMD_INCLUDE_PATH})
endif(BUILD_JOURNAL)
if(BUILD_PULSEAUDIO)
pkg_check_modules(PULSEAUDIO REQUIRED libpulse)
set(conky_libs ${conky_libs} ${PULSEAUDIO_LIBRARIES})
set(conky_includes ${conky_includes} ${PULSEAUDIO_INCLUDE_DIRS})
pkg_check_modules(PULSEAUDIO REQUIRED libpulse)
set(conky_libs ${conky_libs} ${PULSEAUDIO_LIBRARIES})
set(conky_includes ${conky_includes} ${PULSEAUDIO_INCLUDE_DIRS})
endif(BUILD_PULSEAUDIO)
# Common libraries
if(WANT_GLIB)
pkg_check_modules(GLIB REQUIRED glib-2.0)
set(conky_libs ${conky_libs} ${GLIB_LIBRARIES})
set(conky_includes ${conky_includes} ${GLIB_INCLUDE_DIRS})
pkg_check_modules(GLIB REQUIRED glib-2.0)
set(conky_libs ${conky_libs} ${GLIB_LIBRARIES})
set(conky_includes ${conky_includes} ${GLIB_INCLUDE_DIRS})
endif(WANT_GLIB)
if(WANT_CURL)
pkg_check_modules(CURL REQUIRED libcurl)
set(conky_libs ${conky_libs} ${CURL_LIBRARIES})
set(conky_includes ${conky_includes} ${CURL_INCLUDE_DIRS})
pkg_check_modules(CURL REQUIRED libcurl)
set(conky_libs ${conky_libs} ${CURL_LIBRARIES})
set(conky_includes ${conky_includes} ${CURL_INCLUDE_DIRS})
endif(WANT_CURL)
if(WANT_LIBXML2)
pkg_check_modules(LIBXML2 REQUIRED libxml-2.0)
set(conky_libs ${conky_libs} ${LIBXML2_LIBRARIES})
set(conky_includes ${conky_includes} ${LIBXML2_INCLUDE_DIRS})
pkg_check_modules(LIBXML2 REQUIRED libxml-2.0)
set(conky_libs ${conky_libs} ${LIBXML2_LIBRARIES})
set(conky_includes ${conky_includes} ${LIBXML2_INCLUDE_DIRS})
endif(WANT_LIBXML2)
if(WANT_TOLUA)
find_program(APP_TOLUA NAMES toluapp tolua++ tolua++5.1 tolua++-5.1)
if(NOT APP_TOLUA)
message(FATAL_ERROR "Unable to find program 'tolua++'")
endif(NOT APP_TOLUA)
find_library(TOLUA_LIBS NAMES toluapp tolua++ tolua++5.1 tolua++-5.1)
find_path(TOLUA_INCLUDE_PATH tolua++.h ${INCLUDE_SEARCH_PATH})
if(TOLUA_INCLUDE_PATH AND TOLUA_LIBS)
set(TOLUA_FOUND true)
else(TOLUA_INCLUDE_PATH AND TOLUA_LIBS)
message(FATAL_ERROR "Unable to find tolua++ library")
endif(TOLUA_INCLUDE_PATH AND TOLUA_LIBS)
mark_as_advanced(APP_TOLUA TOLUA_INCLUDE_PATH TOLUA_LIBS)
set(conky_includes ${conky_includes} ${TOLUA_INCLUDE_PATH})
set(conky_libs ${conky_libs} ${TOLUA_LIBS})
set(LUA_EXTRAS true)
find_program(APP_TOLUA NAMES toluapp tolua++ tolua++5.1 tolua++-5.1)
if(NOT APP_TOLUA)
message(FATAL_ERROR "Unable to find program 'tolua++'")
endif(NOT APP_TOLUA)
find_library(TOLUA_LIBS NAMES toluapp tolua++ tolua++5.1 tolua++-5.1)
find_path(TOLUA_INCLUDE_PATH tolua++.h ${INCLUDE_SEARCH_PATH})
if(TOLUA_INCLUDE_PATH AND TOLUA_LIBS)
set(TOLUA_FOUND true)
else(TOLUA_INCLUDE_PATH AND TOLUA_LIBS)
message(FATAL_ERROR "Unable to find tolua++ library")
endif(TOLUA_INCLUDE_PATH AND TOLUA_LIBS)
mark_as_advanced(APP_TOLUA TOLUA_INCLUDE_PATH TOLUA_LIBS)
set(conky_includes ${conky_includes} ${TOLUA_INCLUDE_PATH})
set(conky_libs ${conky_libs} ${TOLUA_LIBS})
set(LUA_EXTRAS true)
endif(WANT_TOLUA)
# Look for doc generation programs
if(MAINTAINER_MODE)
# Used for doc generation
find_program(APP_DB2X_XSLTPROC db2x_xsltproc)
if(NOT APP_DB2X_XSLTPROC)
message(FATAL_ERROR "Unable to find program 'db2x_xsltproc'")
endif(NOT APP_DB2X_XSLTPROC)
find_program(APP_DB2X_MANXML db2x_manxml)
if(NOT APP_DB2X_MANXML)
message(FATAL_ERROR "Unable to find program 'db2x_manxml'")
endif(NOT APP_DB2X_MANXML)
find_program(APP_XSLTPROC xsltproc)
if(NOT APP_XSLTPROC)
message(FATAL_ERROR "Unable to find program 'xsltproc'")
endif(NOT APP_XSLTPROC)
find_program(APP_MAN man)
if(NOT APP_MAN)
message(FATAL_ERROR "Unable to find program 'man'")
endif(NOT APP_MAN)
find_program(APP_LESS less)
if(NOT APP_LESS)
message(FATAL_ERROR "Unable to find program 'less'")
endif(NOT APP_LESS)
find_program(APP_SED sed)
if(NOT APP_SED)
message(FATAL_ERROR "Unable to find program 'sed'")
endif(NOT APP_SED)
mark_as_advanced(APP_DB2X_XSLTPROC APP_DB2X_MANXML APP_XSLTPROC APP_MAN APP_SED APP_LESS)
# Used for doc generation
find_program(APP_DB2X_XSLTPROC db2x_xsltproc)
if(NOT APP_DB2X_XSLTPROC)
message(FATAL_ERROR "Unable to find program 'db2x_xsltproc'")
endif(NOT APP_DB2X_XSLTPROC)
find_program(APP_DB2X_MANXML db2x_manxml)
if(NOT APP_DB2X_MANXML)
message(FATAL_ERROR "Unable to find program 'db2x_manxml'")
endif(NOT APP_DB2X_MANXML)
find_program(APP_XSLTPROC xsltproc)
if(NOT APP_XSLTPROC)
message(FATAL_ERROR "Unable to find program 'xsltproc'")
endif(NOT APP_XSLTPROC)
find_program(APP_MAN man)
if(NOT APP_MAN)
message(FATAL_ERROR "Unable to find program 'man'")
endif(NOT APP_MAN)
find_program(APP_LESS less)
if(NOT APP_LESS)
message(FATAL_ERROR "Unable to find program 'less'")
endif(NOT APP_LESS)
find_program(APP_SED sed)
if(NOT APP_SED)
message(FATAL_ERROR "Unable to find program 'sed'")
endif(NOT APP_SED)
mark_as_advanced(APP_DB2X_XSLTPROC APP_DB2X_MANXML APP_XSLTPROC APP_MAN APP_SED APP_LESS)
endif(MAINTAINER_MODE)
if(CMAKE_BUILD_TYPE MATCHES "Debug")
set(DEBUG true)
set(DEBUG true)
endif(CMAKE_BUILD_TYPE MATCHES "Debug")
# The version numbers are simply derived from the date and number of commits
# since start of month
if(DEBUG)
execute_process(COMMAND
${APP_GIT} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git log
--since=${VERSION_MAJOR}-${VERSION_MINOR}-01 --pretty=oneline COMMAND
${APP_WC} -l COMMAND ${APP_AWK} "{print $1}" RESULT_VARIABLE RETVAL
OUTPUT_VARIABLE COMMIT_COUNT OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND
${APP_GIT} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git log
--since=${VERSION_MAJOR}-${VERSION_MINOR}-01 --pretty=oneline COMMAND
${APP_WC} -l COMMAND ${APP_AWK} "{print $1}" RESULT_VARIABLE RETVAL
OUTPUT_VARIABLE COMMIT_COUNT OUTPUT_STRIP_TRAILING_WHITESPACE)
endif(DEBUG)

View File

@@ -1,10 +1,9 @@
# vim: ts=4 sw=4 noet ai cindent syntax=cmake
#
# Conky, a system monitor, based on torsmo
#
# Please see COPYING for details
#
# Copyright (c) 2005-2010 Brenden Matthews, et. al. (see AUTHORS)
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify

View File

@@ -0,0 +1,34 @@
# Find Clang format
#
#
if(NOT CLANG_FORMAT_BIN_NAME)
set(CLANG_FORMAT_BIN_NAME clang-format)
endif()
# if custom path check there first
if(CLANG_FORMAT_ROOT_DIR)
find_program(CLANG_FORMAT_BIN
NAMES
${CLANG_FORMAT_BIN_NAME}
PATHS
"${CLANG_FORMAT_ROOT_DIR}"
NO_DEFAULT_PATH)
endif()
find_program(CLANG_FORMAT_BIN NAMES ${CLANG_FORMAT_BIN_NAME})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
CLANG_FORMAT
DEFAULT_MSG
CLANG_FORMAT_BIN)
mark_as_advanced(
CLANG_FORMAT_BIN)
if(CLANG_FORMAT_FOUND)
# A CMake script to find all source files and setup clang-format targets for them
include(clang-format)
else()
message("clang-format not found. Not setting up format targets")
endif()

View File

@@ -1,10 +1,9 @@
# vim: ts=4 sw=4 noet ai cindent syntax=cmake
#
# Conky, a system monitor, based on torsmo
#
# Please see COPYING for details
#
# Copyright (c) 2005-2010 Brenden Matthews, et. al. (see AUTHORS)
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify

62
cmake/clang-format.cmake Normal file
View File

@@ -0,0 +1,62 @@
# A CMake script to find all source files and setup clang-format targets for them
# Find all source files
set(CLANG_FORMAT_CXX_FILE_EXTENSIONS ${CLANG_FORMAT_CXX_FILE_EXTENSIONS} *.cpp *.h *.cxx *.hxx *.hpp *.cc *.ipp)
file(GLOB_RECURSE ALL_SOURCE_FILES ${CLANG_FORMAT_CXX_FILE_EXTENSIONS})
# Don't include some common build folders
set(CLANG_FORMAT_EXCLUDE_PATTERNS ${CLANG_FORMAT_EXCLUDE_PATTERNS} "/CMakeFiles/" "cmake")
# get all project files file
foreach (SOURCE_FILE ${ALL_SOURCE_FILES})
foreach (EXCLUDE_PATTERN ${CLANG_FORMAT_EXCLUDE_PATTERNS})
string(FIND ${SOURCE_FILE} ${EXCLUDE_PATTERN} EXCLUDE_FOUND)
if (NOT ${EXCLUDE_FOUND} EQUAL -1)
list(REMOVE_ITEM ALL_SOURCE_FILES ${SOURCE_FILE})
endif ()
endforeach ()
endforeach ()
add_custom_target(format
COMMENT "Running clang-format to change files"
COMMAND ${CLANG_FORMAT_BIN}
-style=file
-i
${ALL_SOURCE_FILES}
)
add_custom_target(format-check
COMMENT "Checking clang-format changes"
# Use ! to negate the result for correct output
COMMAND !
${CLANG_FORMAT_BIN}
-style=file
-output-replacements-xml
${ALL_SOURCE_FILES}
| grep -q "replacement offset"
)
# Get the path to this file
get_filename_component(_clangcheckpath ${CMAKE_CURRENT_LIST_FILE} PATH)
# have at least one here by default
set(CHANGED_FILE_EXTENSIONS ".cpp")
foreach(EXTENSION ${CLANG_FORMAT_CXX_FILE_EXTENSIONS})
set(CHANGED_FILE_EXTENSIONS "${CHANGED_FILE_EXTENSIONS},${EXTENSION}" )
endforeach()
set(EXCLUDE_PATTERN_ARGS)
foreach(EXCLUDE_PATTERN ${CLANG_FORMAT_EXCLUDE_PATTERNS})
list(APPEND EXCLUDE_PATTERN_ARGS "--exclude=${EXCLUDE_PATTERN}")
endforeach()
# call the script to chech changed files in git
add_custom_target(format-check-changed
COMMENT "Checking changed files in git"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${_clangcheckpath}/../scripts/clang-format-check-changed.py
--file-extensions \"${CHANGED_FILE_EXTENSIONS}\"
${EXCLUDE_PATTERN_ARGS}
--clang-format-bin ${CLANG_FORMAT_BIN}
)

View File

@@ -0,0 +1,18 @@
#!/bin/bash
# Required because cmake root isn't git root in this example
CLANG_FORMAT_BIN=$1
GIT_ROOT=`git rev-parse --show-toplevel`
pushd ${GIT_ROOT} > /dev/null
git status --porcelain \
| egrep '*\.cpp|*\.h|*\.cxx|*\.hxx|*\.hpp|*\.cc' \
| awk -F " " '{print $NF}' \
| xargs -r ${CLANG_FORMAT_BIN} -style=file -output-replacements-xml \
| grep "replacement offset" 2>&1 > /dev/null
RET=$?
popd > /dev/null
exit ${RET}

View File

@@ -0,0 +1,163 @@
#!/usr/bin/env python
import argparse
import os
import sys
import subprocess
def check_file(filename, excludes, extensions):
"""
Check if a file should be included in our check
"""
name, ext = os.path.splitext(filename)
if len(ext) > 0 and ext in extensions:
if len(excludes) == 0:
return True
for exclude in excludes:
if exclude in filename:
return False
return True
return False
def check_directory(directory, excludes, extensions):
output = []
if len(excludes) > 0:
for exclude in excludes:
if exclude in directory:
directory_excluded = False
return output
for root, _, files in os.walk(directory):
for file in files:
filename = os.path.join(root, file)
if check_file(filename, excludes, extensions):
print("Will check file [{}]".format(filename))
output.append(filename)
return output
def get_git_root(git_bin):
cmd = [git_bin, "rev-parse", "--show-toplevel"]
try:
return subprocess.check_output(cmd).strip()
except subprocess.CalledProcessError, e:
print("Error calling git [{}]".format(e))
raise
def clean_git_filename(line):
"""
Takes a line from git status --porcelain and returns the filename
"""
file = None
git_status = line[:2]
# Not an exhaustive list of git status output but should
# be enough for this case
# check if this is a delete
if 'D' in git_status:
return None
# ignored file
if '!' in git_status:
return None
# Covers renamed files
if '->' in line:
file = line[3:].split('->')[-1].strip()
else:
file = line[3:].strip()
return file
def get_changed_files(git_bin, excludes, file_extensions):
"""
Run git status and return the list of changed files
"""
extensions = file_extensions.split(",")
# arguments coming from cmake will be *.xx. We want to remove the *
for i, extension in enumerate(extensions):
if extension[0] == '*':
extensions[i] = extension[1:]
git_root = get_git_root(git_bin)
cmd = [git_bin, "status", "--porcelain", "--ignore-submodules"]
print("git cmd = {}".format(cmd))
output = []
returncode = 0
try:
cmd_output = subprocess.check_output(cmd)
for line in cmd_output.split('\n'):
if len(line) > 0:
file = clean_git_filename(line)
if not file:
continue
file = os.path.join(git_root, file)
if file[-1] == "/":
directory_files = check_directory(
file, excludes, file_extensions)
output = output + directory_files
else:
if check_file(file, excludes, file_extensions):
print("Will check file [{}]".format(file))
output.append(file)
except subprocess.CalledProcessError, e:
print("Error calling git [{}]".format(e))
returncode = e.returncode
return output, returncode
def run_clang_format(clang_format_bin, changed_files):
"""
Run clang format on a list of files
@return 0 if formatted correctly.
"""
if len(changed_files) == 0:
return 0
cmd = [clang_format_bin, "-style=file",
"-output-replacements-xml"] + changed_files
print("clang-format cmd = {}".format(cmd))
try:
cmd_output = subprocess.check_output(cmd)
if "replacement offset" in cmd_output:
print("ERROR: Changed files don't match format")
return 1
except subprocess.CalledProcessError, e:
print("Error calling clang-format [{}]".format(e))
return e.returncode
return 0
def cli():
# global params
parser = argparse.ArgumentParser(prog='clang-format-check-changed',
description='Checks if files chagned in git match the .clang-format specification')
parser.add_argument("--file-extensions", type=str,
default=".cpp,.h,.cxx,.hxx,.hpp,.cc,.ipp",
help="Comma seperated list of file extensions to check")
parser.add_argument('--exclude', action='append', default=[],
help='Will not match the files / directories with these in the name')
parser.add_argument('--clang-format-bin', type=str, default="clang-format",
help="The clang format binary")
parser.add_argument('--git-bin', type=str, default="git",
help="The git binary")
args = parser.parse_args()
# Run gcovr to get the .gcda files form .gcno
changed_files, returncode = get_changed_files(
args.git_bin, args.exclude, args.file_extensions)
if returncode != 0:
return returncode
return run_clang_format(args.clang_format_bin, changed_files)
if __name__ == '__main__':
sys.exit(cli())

View File

@@ -1,10 +1,9 @@
# vim: ts=4 sw=4 noet ai cindent syntax=cmake
#
# Conky, a system monitor, based on torsmo
#
# Please see COPYING for details
#
# Copyright (c) 2005-2012 Brenden Matthews, et. al. (see AUTHORS)
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify

View File

@@ -1,31 +0,0 @@
# -*- mode: Makefile; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
#
# Conky, a system monitor, based on torsmo
#
# Any original torsmo code is licensed under the BSD license
#
# All code written since the fork of torsmo is licensed under the GPL
#
# Please see COPYING for details
#
# Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
# Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
# All rights reserved.
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#
configdir = ${sysconfdir}/conky
dist_config_DATA = conky.conf conky_no_x11.conf
# vi:set ts=4 sw=4 noet ai nocindent syntax=automake:

View File

@@ -1,4 +1,3 @@
-- vim: ts=4 sw=4 noet ai cindent syntax=lua
--[[
Conky, a system monitor, based on torsmo
@@ -9,7 +8,7 @@ All code written since the fork of torsmo is licensed under the GPL
Please see COPYING for details
Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
All rights reserved.
This program is free software: you can redistribute it and/or modify

View File

@@ -1,4 +1,3 @@
-- vim: ts=4 sw=4 noet ai cindent syntax=lua
--[[
Conky, a system monitor, based on torsmo
@@ -9,7 +8,7 @@ All code written since the fork of torsmo is licensed under the GPL
Please see COPYING for details
Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
All rights reserved.
This program is free software: you can redistribute it and/or modify

View File

@@ -7,7 +7,7 @@
-- Please see COPYING for details
-- Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
-- Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
-- Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
-- All rights reserved.
-- This program is free software: you can redistribute it and/or modify

View File

@@ -1,10 +1,9 @@
# vim: ts=4 sw=4 noet ai cindent syntax=cmake
#
# Conky, a system monitor, based on torsmo
#
# Please see COPYING for details
#
# Copyright (c) 2005-2012 Brenden Matthews, et. al. (see AUTHORS)
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify

View File

@@ -303,7 +303,7 @@
</refsect1>
<refsect1>
<title>Copying</title>
<para>Copyright (c) 2005-2012 Brenden Matthews, Philip
<para>Copyright (c) 2005-2018 Brenden Matthews, Philip
Kovacs, et. al. Any original torsmo code is licensed under
the BSD license (see LICENSE.BSD for a copy). All code
written since the fork of torsmo is licensed under the GPL

View File

@@ -1,10 +1,9 @@
# vim: ts=4 sw=4 noet ai cindent syntax=cmake
#
# Conky, a system monitor, based on torsmo
#
# Please see COPYING for details
#
# Copyright (c) 2005-2012 Brenden Matthews, et. al. (see AUTHORS)
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify

View File

@@ -1,10 +1,10 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -28,15 +28,15 @@
#include <cairo.h>
cairo_text_extents_t *create_cairo_text_extents_t(void) {
return calloc(1, sizeof(cairo_text_extents_t));
return calloc(1, sizeof(cairo_text_extents_t));
}
cairo_font_extents_t *create_cairo_font_extents_t(void) {
return calloc(1, sizeof(cairo_font_extents_t));
return calloc(1, sizeof(cairo_font_extents_t));
}
cairo_matrix_t *create_cairo_matrix_t(void) {
return calloc(1, sizeof(cairo_matrix_t));
return calloc(1, sizeof(cairo_matrix_t));
}
#endif /* _LIBCAIRO_HELPER_H_ */

View File

@@ -1,10 +1,10 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -25,22 +25,22 @@
#ifndef _LIBCAIRO_IMAGE_HELPER_H_
#define _LIBCAIRO_IMAGE_HELPER_H_
#include <cairo.h>
#include <Imlib2.h>
#include <cairo.h>
void
cairo_draw_image(const char * file, cairo_surface_t * cs, int x, int y,
double scale_x, double scale_y,
double * return_scale_w, double * return_scale_h)
{
Imlib_Image * image = imlib_load_image(file);
if (! image) { return; }
void cairo_draw_image(const char *file, cairo_surface_t *cs, int x, int y,
double scale_x, double scale_y, double *return_scale_w,
double *return_scale_h) {
Imlib_Image *image = imlib_load_image(file);
if (!image) {
return;
}
imlib_context_set_image(image);
int w = imlib_image_get_width(), h = imlib_image_get_height();
double scaled_w = *return_scale_w = scale_x * (double)w
, scaled_h = *return_scale_h = scale_y * (double)h;
double scaled_w = *return_scale_w = scale_x * (double)w,
scaled_h = *return_scale_h = scale_y * (double)h;
/* create temporary image */
Imlib_Image premul = imlib_create_image(scaled_w, scaled_h);
@@ -59,11 +59,11 @@ cairo_draw_image(const char * file, cairo_surface_t * cs, int x, int y,
imlib_image_copy_alpha_to_image(image, 0, 0);
/* now pass the result to cairo */
cairo_surface_t * result = cairo_image_surface_create_for_data(
(void *) imlib_image_get_data_for_reading_only(),
CAIRO_FORMAT_ARGB32, scaled_w, scaled_h, sizeof(DATA32) * scaled_w);
cairo_surface_t *result = cairo_image_surface_create_for_data(
(void *)imlib_image_get_data_for_reading_only(), CAIRO_FORMAT_ARGB32,
scaled_w, scaled_h, sizeof(DATA32) * scaled_w);
cairo_t * cr = cairo_create(cs);
cairo_t *cr = cairo_create(cs);
cairo_set_source_surface(cr, result, x, y);
cairo_paint(cr);

View File

@@ -1,10 +1,10 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -26,19 +26,15 @@
#define _LIBRSVG_HELPER_H_
#include <glib.h>
#include <stdlib.h>
#include <librsvg/rsvg.h>
#include <stdlib.h>
RsvgDimensionData *
rsvgDimensionDataCreate(void)
{
RsvgDimensionData *rsvgDimensionDataCreate(void) {
return (RsvgDimensionData *)calloc(1, sizeof(RsvgDimensionData));
}
void
rsvgDimensionDataGet(RsvgDimensionData * dd,
int * width, int * height, double * em, double * ex)
{
void rsvgDimensionDataGet(RsvgDimensionData *dd, int *width, int *height,
double *em, double *ex) {
if (dd) {
*width = dd->width;
*height = dd->height;
@@ -47,51 +43,40 @@ rsvgDimensionDataGet(RsvgDimensionData * dd,
}
}
RsvgPositionData *
rsvgPositionDataCreate(void)
{
RsvgPositionData *rsvgPositionDataCreate(void) {
return (RsvgPositionData *)calloc(1, sizeof(RsvgPositionData));
}
void
rsvgPositionDataGet(RsvgPositionData * pd, int * x, int * y)
{
void rsvgPositionDataGet(RsvgPositionData *pd, int *x, int *y) {
if (pd) {
*x = pd->x;
*y = pd->y;
}
}
RsvgHandle *
rsvg_create_handle_from_file(const char * filename)
{
GError * error = NULL;
RsvgHandle * handle = rsvg_handle_new_from_file(filename, &error);
RsvgHandle *rsvg_create_handle_from_file(const char *filename) {
GError *error = NULL;
RsvgHandle *handle = rsvg_handle_new_from_file(filename, &error);
if (error) {
g_object_unref(error);
if (handle)
g_object_unref(handle);
if (handle) g_object_unref(handle);
handle = NULL;
}
return handle;
}
int
rsvg_destroy_handle(RsvgHandle * handle)
{
int rsvg_destroy_handle(RsvgHandle *handle) {
int status = 0;
if (handle) {
GError * error = NULL;
GError *error = NULL;
status = rsvg_handle_close(handle, &error);
if (status)
g_object_unref(handle);
if (status) g_object_unref(handle);
if (error)
g_object_unref(error);
if (error) g_object_unref(error);
}
return status;

View File

@@ -1,10 +1,9 @@
# vim: ts=4 sw=4 noet ai cindent syntax=cmake
#
# Conky, a system monitor, based on torsmo
#
# Please see COPYING for details
#
# Copyright (c) 2005-2012 Brenden Matthews, et. al. (see AUTHORS)
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
@@ -22,199 +21,310 @@
include_directories(${conky_includes})
if(BUILD_BUILTIN_CONFIG OR BUILD_OLD_CONFIG)
# include config output dir
include_directories(${CMAKE_BINARY_DIR}/data)
# include config output dir
include_directories(${CMAKE_BINARY_DIR}/data)
endif(BUILD_BUILTIN_CONFIG OR BUILD_OLD_CONFIG)
# ensure build.h and config.h aren't in the way
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/config.h)
message(FATAL_ERROR "You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/config.h' in order to build with CMake.")
message(FATAL_ERROR "You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/config.h' in order to build with CMake.")
endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/config.h)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/build.h)
message(FATAL_ERROR "You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/build.h' in order to build with CMake.")
message(FATAL_ERROR "You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/build.h' in order to build with CMake.")
endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/build.h)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/defconfig.h)
message(FATAL_ERROR "You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/defconfig.h' in order to build with CMake.")
message(FATAL_ERROR "You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/defconfig.h' in order to build with CMake.")
endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/defconfig.h)
set(conky_sources c++wrap.cc colours.cc combine.cc common.cc conky.cc core.cc
diskio.cc entropy.cc exec.cc fs.cc mail.cc net_stat.cc template.cc
mboxscan.cc read_tcpip.cc scroll.cc specials.cc tailhead.cc temphelper.cc
text_object.cc timeinfo.cc top.cc algebra.cc prioqueue.cc proc.cc user.cc
luamm.cc data-source.cc lua-config.cc setting.cc llua.cc update-cb.cc)
set(conky_sources
${conky_sources}
c++wrap.cc c++wrap.hh
colours.cc colours.h
combine.cc combine.h
common.cc common.h
conky.cc conky.h
core.cc core.h
diskio.cc diskio.h
entropy.cc entropy.h
exec.cc exec.h
fs.cc fs.h
mail.cc mail.h
net_stat.cc net_stat.h
template.cc template.h
mboxscan.cc mboxscan.h
read_tcpip.cc read_tcpip.h
scroll.cc scroll.h
specials.cc specials.h
tailhead.cc tailhead.h
temphelper.cc temphelper.h
text_object.cc text_object.h
timeinfo.cc timeinfo.h
top.cc top.h
algebra.cc algebra.h
prioqueue.cc prioqueue.h
proc.cc proc.h
user.cc user.h
luamm.cc luamm.hh
data-source.cc data-source.hh
lua-config.cc lua-config.hh
setting.cc setting.hh
llua.cc llua.h
update-cb.cc update-cb.hh
logging.h
semaphore.hh
)
# Platform specific sources
if(OS_LINUX)
set(linux linux.cc users.cc sony.cc i8k.cc)
set(optional_sources ${optional_sources} ${linux})
set(linux
linux.cc linux.h
users.cc users.h
sony.cc sony.h
i8k.cc i8k.h
)
set(optional_sources ${optional_sources} ${linux})
endif(OS_LINUX)
if(OS_FREEBSD)
set(freebsd freebsd.cc bsdapm.cc)
set(optional_sources ${optional_sources} ${freebsd})
set(freebsd
freebsd.cc freebsd.h
bsdapm.cc bsdapm.h
)
set(optional_sources ${optional_sources} ${freebsd})
endif(OS_FREEBSD)
if(OS_DRAGONFLY)
set(dragonfly dragonfly.cc bsdapm.cc)
set(optional_sources ${optional_sources} ${dragonfly})
set(dragonfly
dragonfly.cc dragonfly.h
bsdapm.cc bsdapm.h
)
set(optional_sources ${optional_sources} ${dragonfly})
endif(OS_DRAGONFLY)
if(OS_OPENBSD)
set(openbsd openbsd.cc bsdapm.cc)
set(optional_sources ${optional_sources} ${openbsd})
set(openbsd
openbsd.cc openbsd.h
bsdapm.cc bsdapm.h
)
set(optional_sources ${optional_sources} ${openbsd})
endif(OS_OPENBSD)
# These below are not actually supported. No idea what their status is.
if(OS_SOLARIS)
set(solaris solaris.cc)
set(optional_sources ${optional_sources} ${solaris})
set(solaris
solaris.cc solaris.h
)
set(optional_sources ${optional_sources} ${solaris})
endif(OS_SOLARIS)
if(OS_NETBSD)
set(netbsd netbsd.cc)
set(optional_sources ${optional_sources} ${netbsd})
set(netbsd
netbsd.cc netbsd.h
)
set(optional_sources ${optional_sources} ${netbsd})
endif(OS_NETBSD)
if(OS_HAIKU)
set(haiku haiku.cc)
set(optional_sources ${optional_sources} ${haiku})
set(haiku
haiku.cc haiku.h
)
set(optional_sources ${optional_sources} ${haiku})
endif(OS_HAIKU)
if(OS_DARWIN)
set(darwin darwin.cc)
set(optional_sources ${optional_sources} ${darwin})
set(darwin
darwin.cc darwin.h
darwin_sip.h
i18n.h
)
set(optional_sources ${optional_sources} ${darwin})
endif(OS_DARWIN)
# Optional sources
if(HAVE_SOME_SOUNDCARD_H)
set(mixer mixer.cc)
set(optional_sources ${optional_sources} ${mixer})
set(mixer
mixer.cc mixer.h
)
set(optional_sources ${optional_sources} ${mixer})
endif(HAVE_SOME_SOUNDCARD_H)
if(BUILD_AUDACIOUS)
set(audacious audacious.cc)
set(optional_sources ${optional_sources} ${audacious})
set(audacious
audacious.cc audacious.h
)
set(optional_sources ${optional_sources} ${audacious})
endif(BUILD_AUDACIOUS)
if(BUILD_BMPX)
set(bmpx bmpx.cc)
set(optional_sources ${optional_sources} ${bmpx})
set(bmpx
bmpx.cc bmpx.h
)
set(optional_sources ${optional_sources} ${bmpx})
endif(BUILD_BMPX)
if(BUILD_IBM)
set(ibm ibm.cc smapi.cc)
set(optional_sources ${optional_sources} ${ibm})
set(ibm
ibm.cc ibm.h
smapi.cc smapi.h
)
set(optional_sources ${optional_sources} ${ibm})
endif(BUILD_IBM)
if(BUILD_MPD)
set(mpd mpd.cc libmpdclient.cc)
set(optional_sources ${optional_sources} ${mpd})
set(mpd
mpd.cc mpd.h
libmpdclient.cc libmpdclient.h
)
set(optional_sources ${optional_sources} ${mpd})
endif(BUILD_MPD)
if(BUILD_MYSQL)
set(mysql mysql.cc)
set(optional_sources ${optional_sources} ${mysql})
set(mysql
mysql.cc mysql.h
)
set(optional_sources ${optional_sources} ${mysql})
endif(BUILD_MYSQL)
if(BUILD_MOC)
set(moc moc.cc)
set(optional_sources ${optional_sources} ${moc})
set(moc
moc.cc moc.h
)
set(optional_sources ${optional_sources} ${moc})
endif(BUILD_MOC)
if(BUILD_CMUS)
set(cmus cmus.cc)
set(optional_sources ${optional_sources} ${cmus})
set(cmus
cmus.cc cmus.h
)
set(optional_sources ${optional_sources} ${cmus})
endif(BUILD_CMUS)
if(BUILD_JOURNAL)
set(journal journal.cc)
set(optional_sources ${optional_sources} ${journal})
set(journal
journal.cc journal.h
)
set(optional_sources ${optional_sources} ${journal})
endif(BUILD_JOURNAL)
if(BUILD_XMMS2)
set(xmms2 xmms2.cc)
set(optional_sources ${optional_sources} ${xmms2})
set(xmms2
xmms2.cc xmms2.h
)
set(optional_sources ${optional_sources} ${xmms2})
endif(BUILD_XMMS2)
if(BUILD_PORT_MONITORS)
add_library(tcp-portmon libtcp-portmon.cc)
set(conky_libs ${conky_libs} tcp-portmon)
set(port_monitors tcp-portmon.cc)
set(optional_sources ${optional_sources} ${port_monitors})
add_library(tcp-portmon libtcp-portmon.cc libtcp-portmon.h)
set(conky_libs ${conky_libs} tcp-portmon)
set(port_monitors
tcp-portmon.cc tcp-portmon.h
)
set(optional_sources ${optional_sources} ${port_monitors})
endif(BUILD_PORT_MONITORS)
if(BUILD_X11)
set(x11 x11.cc fonts.cc)
set(optional_sources ${optional_sources} ${x11})
set(x11
x11.cc x11.h
fonts.cc fonts.h
)
set(optional_sources ${optional_sources} ${x11})
if(BUILD_XINERAMA)
find_package(Xinerama REQUIRED)
set(conky_libs ${conky_libs} ${Xinerama_LIBRARIES})
endif(BUILD_XINERAMA)
if(BUILD_XINERAMA)
find_package(Xinerama REQUIRED)
set(conky_libs ${conky_libs} ${Xinerama_LIBRARIES})
endif(BUILD_XINERAMA)
endif(BUILD_X11)
if(BUILD_HDDTEMP)
set(hddtemp hddtemp.cc)
set(optional_sources ${optional_sources} ${hddtemp})
set(hddtemp
hddtemp.cc hddtemp.h
)
set(optional_sources ${optional_sources} ${hddtemp})
endif(BUILD_HDDTEMP)
if(BUILD_EVE)
set(eve eve.cc)
set(optional_sources ${optional_sources} ${eve})
set(eve
eve.cc eve.h
)
set(optional_sources ${optional_sources} ${eve})
endif(BUILD_EVE)
if(BUILD_CURL)
set(ccurl_thread ccurl_thread.cc)
set(optional_sources ${optional_sources} ${ccurl_thread})
set(ccurl_thread
ccurl_thread.cc ccurl_thread.h
)
set(optional_sources ${optional_sources} ${ccurl_thread})
endif(BUILD_CURL)
if(BUILD_RSS)
set(rss rss.cc prss.cc)
set(optional_sources ${optional_sources} ${rss})
set(rss
rss.cc rss.h
prss.cc prss.h
)
set(optional_sources ${optional_sources} ${rss})
endif(BUILD_RSS)
if(BUILD_WEATHER)
set(weather weather.cc)
set(optional_sources ${optional_sources} ${weather})
set(weather
weather.cc weather.h
)
set(optional_sources ${optional_sources} ${weather})
endif(BUILD_WEATHER)
if(BUILD_NVIDIA)
set(nvidia nvidia.cc)
set(optional_sources ${optional_sources} ${nvidia})
set(nvidia
nvidia.cc nvidia.h
)
set(optional_sources ${optional_sources} ${nvidia})
endif(BUILD_NVIDIA)
if(BUILD_IMLIB2)
set(imlib2 imlib2.cc)
set(optional_sources ${optional_sources} ${imlib2})
set(imlib2
imlib2.cc imlib2.h
)
set(optional_sources ${optional_sources} ${imlib2})
endif(BUILD_IMLIB2)
if(BUILD_APCUPSD)
set(apcupsd apcupsd.cc)
set(optional_sources ${optional_sources} ${apcupsd})
set(apcupsd
apcupsd.cc apcupsd.h
)
set(optional_sources ${optional_sources} ${apcupsd})
endif(BUILD_APCUPSD)
if(BUILD_ICAL)
set(ical ical.cc)
set(optional_sources ${optional_sources} ${ical})
set(ical
ical.cc ical.h
)
set(optional_sources ${optional_sources} ${ical})
endif(BUILD_ICAL)
if(BUILD_IRC)
set(irc irc.cc)
set(optional_sources ${optional_sources} ${irc})
set(irc
irc.cc irc.h
)
set(optional_sources ${optional_sources} ${irc})
endif(BUILD_IRC)
if(BUILD_ICONV)
set(iconv iconv_tools.cc)
set(optional_sources ${optional_sources} ${iconv})
set(iconv
iconv_tools.cc iconv_tools.h
)
set(optional_sources ${optional_sources} ${iconv})
endif(BUILD_ICONV)
if(BUILD_NCURSES)
set(optional_sources ${optional_sources} nc.cc)
set(ncurses_srcs
nc.cc nc.h
)
set(optional_sources ${optional_sources} ${ncurses_srcs})
endif(BUILD_NCURSES)
if(BUILD_PULSEAUDIO)
set(pulseaudio pulseaudio.cc)
set(optional_sources ${optional_sources} ${pulseaudio})
set(pulseaudio
pulseaudio.cc pulseaudio.h
)
set(optional_sources ${optional_sources} ${pulseaudio})
endif(BUILD_PULSEAUDIO)
add_executable(conky ${conky_sources} ${optional_sources})
@@ -223,8 +333,8 @@ target_link_libraries(conky ${conky_libs})
# Install libtcp-portmon too?
install(TARGETS
conky
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
conky
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -27,250 +26,227 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include "conky.h"
#include "algebra.h"
#include "logging.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory>
#include "config.h"
#include "conky.h"
#include "logging.h"
/* find the operand in the given expression
* returns the index of the first op character or -1 on error
*/
int find_match_op(const char *expr)
{
unsigned int idx;
int find_match_op(const char *expr) {
unsigned int idx;
for (idx = 0; idx < strlen(expr); idx++) {
switch (expr[idx]) {
case '=':
case '!':
if (expr[idx + 1] != '=')
return -1;
/* fall through */
case '<':
case '>':
return idx;
break;
}
}
return -1;
for (idx = 0; idx < strlen(expr); idx++) {
switch (expr[idx]) {
case '=':
case '!':
if (expr[idx + 1] != '=') return -1;
/* fall through */
case '<':
case '>':
return idx;
break;
}
}
return -1;
}
int get_match_type(const char *expr)
{
int idx;
const char *str;
int get_match_type(const char *expr) {
int idx;
const char *str;
if ((idx = find_match_op(expr)) == -1)
return -1;
str = expr + idx;
if ((idx = find_match_op(expr)) == -1) return -1;
str = expr + idx;
if (*str == '=' && *(str + 1) == '=')
return OP_EQ;
else if (*str == '!' && *(str + 1) == '=')
return OP_NEQ;
else if (*str == '>') {
if (*(str + 1) == '=')
return OP_GEQ;
return OP_GT;
} else if (*str == '<') {
if (*(str + 1) == '=')
return OP_LEQ;
return OP_LT;
}
return -1;
if (*str == '=' && *(str + 1) == '=')
return OP_EQ;
else if (*str == '!' && *(str + 1) == '=')
return OP_NEQ;
else if (*str == '>') {
if (*(str + 1) == '=') return OP_GEQ;
return OP_GT;
} else if (*str == '<') {
if (*(str + 1) == '=') return OP_LEQ;
return OP_LT;
}
return -1;
}
/* generic compare function
*
* v is actually the difference of the compared values. For strings
* this is equal to the output of str(n)cmp(). Use a macro here, as
* it's type-independent.
*/
#define COMPARE(v, t) \
switch (t) { \
case OP_GT: return (v > 0); \
case OP_LT: return (v < 0); \
case OP_EQ: return (v == 0); \
case OP_GEQ: return (v >= 0); \
case OP_LEQ: return (v <= 0); \
case OP_NEQ: return (v != 0); \
} \
return 0
#define COMPARE(v, t) \
switch (t) { \
case OP_GT: \
return (v > 0); \
case OP_LT: \
return (v < 0); \
case OP_EQ: \
return (v == 0); \
case OP_GEQ: \
return (v >= 0); \
case OP_LEQ: \
return (v <= 0); \
case OP_NEQ: \
return (v != 0); \
} \
return 0
int lcompare(long a, enum match_type mtype, long b)
{
DBGP2("comparing longs '%ld' and '%ld'", a, b);
COMPARE((a - b), mtype);
int lcompare(long a, enum match_type mtype, long b) {
DBGP2("comparing longs '%ld' and '%ld'", a, b);
COMPARE((a - b), mtype);
}
int dcompare(double a, enum match_type mtype, double b)
{
DBGP2("comparing doubles '%.lf' and '%.lf'", a, b);
COMPARE((a - b), mtype);
int dcompare(double a, enum match_type mtype, double b) {
DBGP2("comparing doubles '%.lf' and '%.lf'", a, b);
COMPARE((a - b), mtype);
}
int scompare(const char *a, enum match_type mtype, const char *b)
{
DBGP2("comparing strings '%s' and '%s'", a, b);
COMPARE(strcmp(a, b), mtype);
int scompare(const char *a, enum match_type mtype, const char *b) {
DBGP2("comparing strings '%s' and '%s'", a, b);
COMPARE(strcmp(a, b), mtype);
}
enum arg_type get_arg_type(const char *arg)
{
const char *p, *e;
enum arg_type get_arg_type(const char *arg) {
const char *p, *e;
p = arg;
e = arg + strlen(arg)-1;
p = arg;
e = arg + strlen(arg) - 1;
while (p != e && *e && *e == ' ')
e--;
while (p != e && *p == ' ')
p++;
while (p != e && *e && *e == ' ') e--;
while (p != e && *p == ' ') p++;
if (*p == '"' && *e == '"')
return ARG_STRING;
if (*p == '"' && *e == '"') return ARG_STRING;
if (*p == '-') //allow negative values
p++;
while (p <= e) {
if (!isdigit(*p))
break;
p++;
}
if (p == e+1)
return ARG_LONG;
if (*p == '.') {
p++;
while (p <= e) {
if (!isdigit(*p))
return ARG_BAD;
p++;
}
return ARG_DOUBLE;
}
return ARG_BAD;
if (*p == '-') // allow negative values
p++;
while (p <= e) {
if (!isdigit(*p)) break;
p++;
}
if (p == e + 1) return ARG_LONG;
if (*p == '.') {
p++;
while (p <= e) {
if (!isdigit(*p)) return ARG_BAD;
p++;
}
return ARG_DOUBLE;
}
return ARG_BAD;
}
char *arg_to_string(const char *arg)
{
const char *start;
int len;
char *arg_to_string(const char *arg) {
const char *start;
int len;
start = arg;
len = 0;
while (*start && *start == ' ')
start++;
if (!(*(start++) == '"'))
return NULL;
while (start[len] != '"')
len++;
return strndup(start, len);
start = arg;
len = 0;
while (*start && *start == ' ') start++;
if (!(*(start++) == '"')) return NULL;
while (start[len] != '"') len++;
return strndup(start, len);
}
double arg_to_double(const char *arg)
{
double d;
if (sscanf(arg, "%lf", &d) != 1) {
NORM_ERR("converting '%s' to double failed", arg);
return 0.0;
}
return d;
double arg_to_double(const char *arg) {
double d;
if (sscanf(arg, "%lf", &d) != 1) {
NORM_ERR("converting '%s' to double failed", arg);
return 0.0;
}
return d;
}
long arg_to_long(const char *arg)
{
long l;
if (sscanf(arg, "%ld", &l) != 1) {
NORM_ERR("converting '%s' to long failed", arg);
return 0;
}
return l;
long arg_to_long(const char *arg) {
long l;
if (sscanf(arg, "%ld", &l) != 1) {
NORM_ERR("converting '%s' to long failed", arg);
return 0;
}
return l;
}
int compare(const char *expr)
{
char *expr_dup;
int idx, mtype;
enum arg_type type1, type2;
long lng_a, lng_b;
double dbl_a, dbl_b;
int compare(const char *expr) {
char *expr_dup;
int idx, mtype;
enum arg_type type1, type2;
long lng_a, lng_b;
double dbl_a, dbl_b;
idx = find_match_op(expr);
mtype = get_match_type(expr);
idx = find_match_op(expr);
mtype = get_match_type(expr);
if (!idx || mtype == -1) {
NORM_ERR("failed to parse compare string '%s'", expr);
return -2;
}
if (!idx || mtype == -1) {
NORM_ERR("failed to parse compare string '%s'", expr);
return -2;
}
expr_dup = strdup(expr);
expr_dup[idx] = '\0';
if (expr_dup[idx + 1] == '=')
expr_dup[++idx] = '\0';
expr_dup = strdup(expr);
expr_dup[idx] = '\0';
if (expr_dup[idx + 1] == '=') expr_dup[++idx] = '\0';
type1 = get_arg_type(expr_dup);
type2 = get_arg_type(expr_dup + idx + 1);
if (type1 == ARG_BAD || type2 == ARG_BAD) {
NORM_ERR("Bad arguments: '%s' and '%s'", expr_dup, (expr_dup + idx + 1));
free(expr_dup);
return -2;
}
if (type1 == ARG_LONG && type2 == ARG_DOUBLE)
type1 = ARG_DOUBLE;
if (type1 == ARG_DOUBLE && type2 == ARG_LONG)
type2 = ARG_DOUBLE;
if (type1 != type2) {
NORM_ERR("trying to compare args '%s' and '%s' of different type",
expr_dup, (expr_dup + idx + 1));
free(expr_dup);
return -2;
}
switch (type1) {
case ARG_STRING:
{
char *a, *b;
a = arg_to_string(expr_dup);
b = arg_to_string(expr_dup + idx + 1);
idx = scompare(a, (enum match_type) mtype, b);
free(a);
free(b);
free(expr_dup);
return idx;
}
case ARG_LONG:
lng_a = arg_to_long(expr_dup);
lng_b = arg_to_long(expr_dup + idx + 1);
free(expr_dup);
return lcompare(lng_a, (enum match_type) mtype, lng_b);
case ARG_DOUBLE:
dbl_a = arg_to_double(expr_dup);
dbl_b = arg_to_double(expr_dup + idx + 1);
free(expr_dup);
return dcompare(dbl_a, (enum match_type) mtype, dbl_b);
case ARG_BAD: /* make_gcc_happy() */;
}
/* not reached */
free(expr_dup);
return -2;
type1 = get_arg_type(expr_dup);
type2 = get_arg_type(expr_dup + idx + 1);
if (type1 == ARG_BAD || type2 == ARG_BAD) {
NORM_ERR("Bad arguments: '%s' and '%s'", expr_dup, (expr_dup + idx + 1));
free(expr_dup);
return -2;
}
if (type1 == ARG_LONG && type2 == ARG_DOUBLE) type1 = ARG_DOUBLE;
if (type1 == ARG_DOUBLE && type2 == ARG_LONG) type2 = ARG_DOUBLE;
if (type1 != type2) {
NORM_ERR("trying to compare args '%s' and '%s' of different type", expr_dup,
(expr_dup + idx + 1));
free(expr_dup);
return -2;
}
switch (type1) {
case ARG_STRING: {
char *a, *b;
a = arg_to_string(expr_dup);
b = arg_to_string(expr_dup + idx + 1);
idx = scompare(a, (enum match_type)mtype, b);
free(a);
free(b);
free(expr_dup);
return idx;
}
case ARG_LONG:
lng_a = arg_to_long(expr_dup);
lng_b = arg_to_long(expr_dup + idx + 1);
free(expr_dup);
return lcompare(lng_a, (enum match_type)mtype, lng_b);
case ARG_DOUBLE:
dbl_a = arg_to_double(expr_dup);
dbl_b = arg_to_double(expr_dup + idx + 1);
free(expr_dup);
return dcompare(dbl_a, (enum match_type)mtype, dbl_b);
case ARG_BAD: /* make_gcc_happy() */;
}
/* not reached */
free(expr_dup);
return -2;
}
int check_if_match(struct text_object *obj)
{
std::unique_ptr<char []> expression(new char[max_user_text.get(*state)]);
int val;
int result = 1;
int check_if_match(struct text_object *obj) {
std::unique_ptr<char[]> expression(new char[max_user_text.get(*state)]);
int val;
int result = 1;
generate_text_internal(expression.get(), max_user_text.get(*state), *obj->sub);
DBGP("parsed arg into '%s'", expression.get());
generate_text_internal(expression.get(), max_user_text.get(*state),
*obj->sub);
DBGP("parsed arg into '%s'", expression.get());
val = compare(expression.get());
if (val == -2) {
NORM_ERR("compare failed for expression '%s'", expression.get());
} else if (!val) {
result = 0;
}
return result;
val = compare(expression.get());
if (val == -2) {
NORM_ERR("compare failed for expression '%s'", expression.get());
} else if (!val) {
result = 0;
}
return result;
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=c
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -31,19 +30,19 @@
#define _ALGEBRA_H
enum match_type {
OP_LT = 1, /* < */
OP_GT = 2, /* > */
OP_EQ = 3, /* == */
OP_LEQ = 4, /* <= */
OP_GEQ = 5, /* >= */
OP_NEQ = 6 /* != */
OP_LT = 1, /* < */
OP_GT = 2, /* > */
OP_EQ = 3, /* == */
OP_LEQ = 4, /* <= */
OP_GEQ = 5, /* >= */
OP_NEQ = 6 /* != */
};
enum arg_type {
ARG_BAD = 0, /* something strange */
ARG_STRING = 1, /* "asdf" */
ARG_LONG = 2, /* 123456 */
ARG_DOUBLE = 3 /* 12.456 */
ARG_BAD = 0, /* something strange */
ARG_STRING = 1, /* "asdf" */
ARG_LONG = 2, /* 123456 */
ARG_DOUBLE = 3 /* 12.456 */
};
int compare(const char *);

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* apcupsd.c: conky module for APC UPS daemon monitoring
*
@@ -22,260 +21,254 @@
*
*/
#include "conky.h"
#include "apcupsd.h"
#include "conky.h"
#include "logging.h"
#include "text_object.h"
#include <errno.h>
#include <netinet/in.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <unistd.h>
enum _apcupsd_items {
APCUPSD_NAME,
APCUPSD_MODEL,
APCUPSD_UPSMODE,
APCUPSD_CABLE,
APCUPSD_STATUS,
APCUPSD_LINEV,
APCUPSD_LOAD,
APCUPSD_CHARGE,
APCUPSD_TIMELEFT,
APCUPSD_TEMP,
APCUPSD_LASTXFER,
_APCUPSD_COUNT
APCUPSD_NAME,
APCUPSD_MODEL,
APCUPSD_UPSMODE,
APCUPSD_CABLE,
APCUPSD_STATUS,
APCUPSD_LINEV,
APCUPSD_LOAD,
APCUPSD_CHARGE,
APCUPSD_TIMELEFT,
APCUPSD_TEMP,
APCUPSD_LASTXFER,
_APCUPSD_COUNT
};
/* type for data exchange with main thread */
#define APCUPSD_MAXSTR 32
typedef struct apcupsd_s {
char items[_APCUPSD_COUNT][APCUPSD_MAXSTR+1]; /* e.g. items[APCUPSD_STATUS] */
char host[64];
int port;
char items[_APCUPSD_COUNT]
[APCUPSD_MAXSTR + 1]; /* e.g. items[APCUPSD_STATUS] */
char host[64];
int port;
} APCUPSD_S, *PAPCUPSD_S;
static APCUPSD_S apcupsd;
//
// encapsulated recv()
//
static int net_recv_ex(int sock, void *buf, int size, struct timeval *tv)
{
fd_set fds;
int res;
static int net_recv_ex(int sock, void *buf, int size, struct timeval *tv) {
fd_set fds;
int res;
// wait for some data to be read
do {
errno = 0;
FD_ZERO(&fds);
FD_SET(sock, &fds);
res = select(sock + 1, &fds, NULL, NULL, tv);
} while (res < 0 && errno == EINTR);
if (res < 0) return 0;
if (res == 0) {
// timeout
errno = ETIMEDOUT; // select was succesfull, errno is now 0
return 0;
}
// wait for some data to be read
do {
errno = 0;
FD_ZERO(&fds);
FD_SET(sock, &fds);
res = select(sock + 1, &fds, NULL, NULL, tv);
} while (res < 0 && errno == EINTR);
if (res < 0) return 0;
if (res == 0) {
// timeout
errno = ETIMEDOUT; // select was succesfull, errno is now 0
return 0;
}
// socket ready, read the data
do {
errno = 0;
res = recv(sock, (char*)buf, size, 0);
} while (res < 0 && errno == EINTR);
if (res < 0) return 0;
if (res == 0) {
// orderly shutdown
errno = ENOTCONN;
return 0;
}
// socket ready, read the data
do {
errno = 0;
res = recv(sock, (char *)buf, size, 0);
} while (res < 0 && errno == EINTR);
if (res < 0) return 0;
if (res == 0) {
// orderly shutdown
errno = ENOTCONN;
return 0;
}
return res;
return res;
}
//
// read whole buffer or fail
//
static int net_recv(int sock, void* buf, int size)
{
int todo = size;
int off = 0;
int len;
struct timeval tv = { 0, 250000 };
static int net_recv(int sock, void *buf, int size) {
int todo = size;
int off = 0;
int len;
struct timeval tv = {0, 250000};
while (todo) {
len = net_recv_ex(sock, (char*)buf + off, todo, &tv);
if (!len) return 0;
todo -= len;
off += len;
}
return 1;
while (todo) {
len = net_recv_ex(sock, (char *)buf + off, todo, &tv);
if (!len) return 0;
todo -= len;
off += len;
}
return 1;
}
//
// get one response line
//
static int get_line(int sock, char line[], short linesize)
{
// get the line length
short sz;
if (!net_recv(sock, &sz, sizeof(sz))) return -1;
sz = ntohs(sz);
if (!sz) return 0;
static int get_line(int sock, char line[], short linesize) {
// get the line length
short sz;
if (!net_recv(sock, &sz, sizeof(sz))) return -1;
sz = ntohs(sz);
if (!sz) return 0;
// get the line
while (sz >= linesize) {
// this is just a hack (being lazy), this should not happen anyway
net_recv(sock, line, linesize);
sz -= linesize;
}
if (!net_recv(sock, line, sz)) return 0;
line[sz] = 0;
return sz;
// get the line
while (sz >= linesize) {
// this is just a hack (being lazy), this should not happen anyway
net_recv(sock, line, linesize);
sz -= linesize;
}
if (!net_recv(sock, line, sz)) return 0;
line[sz] = 0;
return sz;
}
#define FILL(NAME,FIELD,FIRST) \
if (!strncmp(NAME, line, sizeof(NAME)-1)) { \
strncpy(apc->items[FIELD], line+11, APCUPSD_MAXSTR); \
/* remove trailing newline and assure termination */ \
apc->items[FIELD][len-11 > APCUPSD_MAXSTR ? APCUPSD_MAXSTR : len-12] = 0; \
if (FIRST) { \
char* c; \
for (c = apc->items[FIELD]; *c; ++c) \
if (*c == ' ' && c > apc->items[FIELD]+2) { \
*c = 0; \
break; \
} \
} \
}
#define FILL(NAME, FIELD, FIRST) \
if (!strncmp(NAME, line, sizeof(NAME) - 1)) { \
strncpy(apc->items[FIELD], line + 11, APCUPSD_MAXSTR); \
/* remove trailing newline and assure termination */ \
apc->items[FIELD][len - 11 > APCUPSD_MAXSTR ? APCUPSD_MAXSTR : len - 12] = \
0; \
if (FIRST) { \
char *c; \
for (c = apc->items[FIELD]; *c; ++c) \
if (*c == ' ' && c > apc->items[FIELD] + 2) { \
*c = 0; \
break; \
} \
} \
}
//
// fills in the data received from a socket
//
static int fill_items(int sock, PAPCUPSD_S apc)
{
char line[512];
int len;
while ((len = get_line(sock, line, sizeof(line)))) {
// fill the right types in
FILL("UPSNAME", APCUPSD_NAME, FALSE);
FILL("MODEL", APCUPSD_MODEL, FALSE);
FILL("UPSMODE", APCUPSD_UPSMODE, FALSE);
FILL("CABLE", APCUPSD_CABLE, FALSE);
FILL("STATUS", APCUPSD_STATUS, FALSE);
FILL("LINEV", APCUPSD_LINEV, TRUE);
FILL("LOADPCT", APCUPSD_LOAD, TRUE);
FILL("BCHARGE", APCUPSD_CHARGE, TRUE);
FILL("TIMELEFT", APCUPSD_TIMELEFT, TRUE);
FILL("ITEMP", APCUPSD_TEMP, TRUE);
FILL("LASTXFER", APCUPSD_LASTXFER, FALSE);
}
static int fill_items(int sock, PAPCUPSD_S apc) {
char line[512];
int len;
while ((len = get_line(sock, line, sizeof(line)))) {
// fill the right types in
FILL("UPSNAME", APCUPSD_NAME, FALSE);
FILL("MODEL", APCUPSD_MODEL, FALSE);
FILL("UPSMODE", APCUPSD_UPSMODE, FALSE);
FILL("CABLE", APCUPSD_CABLE, FALSE);
FILL("STATUS", APCUPSD_STATUS, FALSE);
FILL("LINEV", APCUPSD_LINEV, TRUE);
FILL("LOADPCT", APCUPSD_LOAD, TRUE);
FILL("BCHARGE", APCUPSD_CHARGE, TRUE);
FILL("TIMELEFT", APCUPSD_TIMELEFT, TRUE);
FILL("ITEMP", APCUPSD_TEMP, TRUE);
FILL("LASTXFER", APCUPSD_LASTXFER, FALSE);
}
return len == 0;
return len == 0;
}
//
// Conky update function for apcupsd data
//
int update_apcupsd(void)
{
int i;
APCUPSD_S apc;
int sock;
int update_apcupsd(void) {
int i;
APCUPSD_S apc;
int sock;
for (i = 0; i < _APCUPSD_COUNT; ++i)
memcpy(apc.items[i], "N/A", 4); // including \0
for (i = 0; i < _APCUPSD_COUNT; ++i)
memcpy(apc.items[i], "N/A", 4); // including \0
do {
struct addrinfo hints;
struct addrinfo *ai, *rp;
int res;
short sz = 0;
char portbuf[8];
//
// connect to apcupsd daemon
//
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
snprintf(portbuf, 8, "%d", apcupsd.port);
res = getaddrinfo(apcupsd.host, portbuf, &hints, &ai);
if (res != 0) {
NORM_ERR("APCUPSD getaddrinfo: %s", gai_strerror(res));
break;
}
for (rp = ai; rp != NULL; rp = rp->ai_next) {
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sock == -1) {
continue;
}
if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) {
break;
}
close(sock);
}
freeaddrinfo(ai);
if (rp == NULL) {
// no error reporting, the daemon is probably not running
break;
}
do {
struct addrinfo hints;
struct addrinfo *ai, *rp;
int res;
short sz = 0;
char portbuf[8];
//
// connect to apcupsd daemon
//
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
snprintf(portbuf, 8, "%d", apcupsd.port);
res = getaddrinfo(apcupsd.host, portbuf, &hints, &ai);
if (res != 0) {
NORM_ERR("APCUPSD getaddrinfo: %s", gai_strerror(res));
break;
}
for (rp = ai; rp != NULL; rp = rp->ai_next) {
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sock == -1) {
continue;
}
if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) {
break;
}
close(sock);
}
freeaddrinfo(ai);
if (rp == NULL) {
// no error reporting, the daemon is probably not running
break;
}
//
// send status request - "status" - 6B
//
sz = htons(6);
// no waiting to become writeable is really needed
if (send(sock, &sz, sizeof(sz), 0) != sizeof(sz) || send(sock, "status", 6, 0) != 6) {
perror("send");
break;
}
//
// send status request - "status" - 6B
//
sz = htons(6);
// no waiting to become writeable is really needed
if (send(sock, &sz, sizeof(sz), 0) != sizeof(sz) ||
send(sock, "status", 6, 0) != 6) {
perror("send");
break;
}
//
// read the lines of output and put them into the info structure
//
if (!fill_items(sock, &apc)) break;
//
// read the lines of output and put them into the info structure
//
if (!fill_items(sock, &apc)) break;
} while (0);
} while (0);
close(sock);
close(sock);
//
// "atomically" copy the data into working set
//
memcpy(apcupsd.items, apc.items, sizeof(apcupsd.items));
return 0;
//
// "atomically" copy the data into working set
//
memcpy(apcupsd.items, apc.items, sizeof(apcupsd.items));
return 0;
}
int apcupsd_scan_arg(const char *arg)
{
char host[64];
int port;
if (sscanf(arg, "%63s %d", host, &port) != 2)
return 1;
int apcupsd_scan_arg(const char *arg) {
char host[64];
int port;
if (sscanf(arg, "%63s %d", host, &port) != 2) return 1;
apcupsd.port = port;
strncpy(apcupsd.host, host, sizeof(apcupsd.host));
return 0;
apcupsd.port = port;
strncpy(apcupsd.host, host, sizeof(apcupsd.host));
return 0;
}
double apcupsd_loadbarval(struct text_object *obj)
{
(void)obj;
double apcupsd_loadbarval(struct text_object *obj) {
(void)obj;
return atof(apcupsd.items[APCUPSD_LOAD]);
return atof(apcupsd.items[APCUPSD_LOAD]);
}
#define APCUPSD_PRINT_GENERATOR(name, idx) \
void print_apcupsd_##name(struct text_object *obj, char *p, int p_max_size) \
{ \
(void)obj; \
snprintf(p, p_max_size, "%s", apcupsd.items[APCUPSD_##idx]); \
}
#define APCUPSD_PRINT_GENERATOR(name, idx) \
void print_apcupsd_##name(struct text_object *obj, char *p, \
int p_max_size) { \
(void)obj; \
snprintf(p, p_max_size, "%s", apcupsd.items[APCUPSD_##idx]); \
}
APCUPSD_PRINT_GENERATOR(name, NAME)
APCUPSD_PRINT_GENERATOR(model, MODEL)

View File

@@ -1,5 +1,4 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=c
/*
*
* apcupsd.h: conky module for APC UPS daemon monitoring
*

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* audacious.c: conky support for audacious music player
*
@@ -26,219 +25,213 @@
#include <cmath>
#include <mutex>
#include "audacious.h"
#include "conky.h"
#include "logging.h"
#include "audacious.h"
#include <mutex>
#include "update-cb.hh"
#include <glib.h>
#ifdef NEW_AUDACIOUS_FOUND
#include <glib-object.h>
#include <audacious/audctrl.h>
#include <audacious/dbus.h>
#include <glib-object.h>
#else /* NEW_AUDACIOUS_FOUND */
#include <audacious/beepctrl.h>
#define audacious_remote_is_running(x) \
xmms_remote_is_running(x)
#define audacious_remote_is_paused(x) \
xmms_remote_is_paused(x)
#define audacious_remote_is_playing(x) \
xmms_remote_is_playing(x)
#define audacious_remote_get_playlist_pos(x) \
xmms_remote_get_playlist_pos(x)
#define audacious_remote_get_playlist_title(x, y) \
xmms_remote_get_playlist_title(x, y)
#define audacious_remote_get_playlist_time(x, y) \
xmms_remote_get_playlist_time(x, y)
#define audacious_remote_get_output_time(x) \
xmms_remote_get_output_time(x)
#define audacious_remote_get_info(w, x, y, z) \
xmms_remote_get_info(w, x, y, z)
#define audacious_remote_get_playlist_file(x, y) \
xmms_remote_get_playlist_file(x, y)
#define audacious_remote_get_playlist_length(x) \
xmms_remote_get_playlist_length(x)
#define audacious_remote_is_running(x) xmms_remote_is_running(x)
#define audacious_remote_is_paused(x) xmms_remote_is_paused(x)
#define audacious_remote_is_playing(x) xmms_remote_is_playing(x)
#define audacious_remote_get_playlist_pos(x) xmms_remote_get_playlist_pos(x)
#define audacious_remote_get_playlist_title(x, y) \
xmms_remote_get_playlist_title(x, y)
#define audacious_remote_get_playlist_time(x, y) \
xmms_remote_get_playlist_time(x, y)
#define audacious_remote_get_output_time(x) xmms_remote_get_output_time(x)
#define audacious_remote_get_info(w, x, y, z) xmms_remote_get_info(w, x, y, z)
#define audacious_remote_get_playlist_file(x, y) \
xmms_remote_get_playlist_file(x, y)
#define audacious_remote_get_playlist_length(x) \
xmms_remote_get_playlist_length(x)
#endif /* NEW_AUDACIOUS_FOUND */
namespace {
enum aud_status { AS_NOT_RUNNING, AS_PAUSED, AS_PLAYING, AS_STOPPED };
const char * const as_message[] = { "Not running", "Paused", "Playing", "Stopped" };
enum aud_status { AS_NOT_RUNNING, AS_PAUSED, AS_PLAYING, AS_STOPPED };
const char *const as_message[] = {"Not running", "Paused", "Playing",
"Stopped"};
struct aud_result {
std::string title;
std::string filename;
int length; // in ms
int position; // in ms
int bitrate;
int frequency;
int channels;
int playlist_length;
int playlist_position;
int main_volume;
aud_status status;
struct aud_result {
std::string title;
std::string filename;
int length; // in ms
int position; // in ms
int bitrate;
int frequency;
int channels;
int playlist_length;
int playlist_position;
int main_volume;
aud_status status;
aud_result()
: length(0), position(0), bitrate(0), frequency(0), channels(0), playlist_length(0),
playlist_position(0), main_volume(0), status(AS_NOT_RUNNING)
{}
};
aud_result()
: length(0),
position(0),
bitrate(0),
frequency(0),
channels(0),
playlist_length(0),
playlist_position(0),
main_volume(0),
status(AS_NOT_RUNNING) {}
};
class audacious_cb: public conky::callback<aud_result> {
typedef conky::callback<aud_result> Base;
class audacious_cb : public conky::callback<aud_result> {
typedef conky::callback<aud_result> Base;
#ifdef NEW_AUDACIOUS_FOUND
DBusGProxy *session;
DBusGProxy *session;
#else
gint session;
gint session;
#endif
protected:
virtual void work();
protected:
virtual void work();
public:
audacious_cb(uint32_t period)
: Base(period, false, Tuple())
{
public:
audacious_cb(uint32_t period) : Base(period, false, Tuple()) {
#ifdef NEW_AUDACIOUS_FOUND
g_type_init();
DBusGConnection *connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
if (!connection)
throw std::runtime_error("unable to establish dbus connection");
g_type_init();
DBusGConnection *connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
if (!connection)
throw std::runtime_error("unable to establish dbus connection");
session = dbus_g_proxy_new_for_name(connection, AUDACIOUS_DBUS_SERVICE,
AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE);
if (!session)
throw std::runtime_error("unable to create dbus proxy");
session = dbus_g_proxy_new_for_name(connection, AUDACIOUS_DBUS_SERVICE,
AUDACIOUS_DBUS_PATH,
AUDACIOUS_DBUS_INTERFACE);
if (!session) throw std::runtime_error("unable to create dbus proxy");
#else
session = 0;
session = 0;
#endif /* NEW_AUDACIOUS_FOUND */
}
}
#ifdef NEW_AUDACIOUS_FOUND
~audacious_cb()
{
/* release reference to dbus proxy */
g_object_unref(session);
}
~audacious_cb() {
/* release reference to dbus proxy */
g_object_unref(session);
}
#endif
};
};
/* ---------------------------------------------------
* Worker thread function for audacious data sampling.
* --------------------------------------------------- */
void audacious_cb::work()
{
aud_result tmp;
gchar *psong, *pfilename;
psong = NULL;
pfilename = NULL;
/* ---------------------------------------------------
* Worker thread function for audacious data sampling.
* --------------------------------------------------- */
void audacious_cb::work() {
aud_result tmp;
gchar *psong, *pfilename;
psong = NULL;
pfilename = NULL;
do {
if (!audacious_remote_is_running(session)) {
tmp.status = AS_NOT_RUNNING;
break;
}
do {
if (!audacious_remote_is_running(session)) {
tmp.status = AS_NOT_RUNNING;
break;
}
/* Player status */
if (audacious_remote_is_paused(session)) {
tmp.status = AS_PAUSED;
} else if (audacious_remote_is_playing(session)) {
tmp.status = AS_PLAYING;
} else {
tmp.status = AS_STOPPED;
}
/* Player status */
if (audacious_remote_is_paused(session)) {
tmp.status = AS_PAUSED;
} else if (audacious_remote_is_playing(session)) {
tmp.status = AS_PLAYING;
} else {
tmp.status = AS_STOPPED;
}
/* Current song title */
tmp.playlist_position = audacious_remote_get_playlist_pos(session);
psong = audacious_remote_get_playlist_title(session, tmp.playlist_position);
if (psong) {
tmp.title = psong;
g_free(psong);
}
/* Current song title */
tmp.playlist_position = audacious_remote_get_playlist_pos(session);
psong = audacious_remote_get_playlist_title(session, tmp.playlist_position);
if (psong) {
tmp.title = psong;
g_free(psong);
}
/* Current song length */
tmp.length = audacious_remote_get_playlist_time(session, tmp.playlist_position);
/* Current song length */
tmp.length =
audacious_remote_get_playlist_time(session, tmp.playlist_position);
/* Current song position */
tmp.position = audacious_remote_get_output_time(session);
/* Current song position */
tmp.position = audacious_remote_get_output_time(session);
/* Current song bitrate, frequency, channels */
audacious_remote_get_info(session, &tmp.bitrate, &tmp.frequency, &tmp.channels);
/* Current song bitrate, frequency, channels */
audacious_remote_get_info(session, &tmp.bitrate, &tmp.frequency,
&tmp.channels);
/* Current song filename */
pfilename = audacious_remote_get_playlist_file(session, tmp.playlist_position);
if (pfilename) {
tmp.filename = pfilename;
g_free(pfilename);
}
/* Current song filename */
pfilename =
audacious_remote_get_playlist_file(session, tmp.playlist_position);
if (pfilename) {
tmp.filename = pfilename;
g_free(pfilename);
}
/* Length of the Playlist (number of songs) */
tmp.playlist_length = audacious_remote_get_playlist_length(session);
/* Length of the Playlist (number of songs) */
tmp.playlist_length = audacious_remote_get_playlist_length(session);
/* Main volume */
tmp.main_volume = audacious_remote_get_main_volume(session);
} while (0);
{
/* Deliver the refreshed items array to audacious_items. */
std::lock_guard<std::mutex> lock(result_mutex);
result = tmp;
}
}
aud_result get_res()
{
uint32_t period = std::max(
lround(music_player_interval.get(*state)/active_update_interval()), 1l
);
return conky::register_cb<audacious_cb>(period)->get_result_copy();
}
/* Main volume */
tmp.main_volume = audacious_remote_get_main_volume(session);
} while (0);
{
/* Deliver the refreshed items array to audacious_items. */
std::lock_guard<std::mutex> lock(result_mutex);
result = tmp;
}
}
void print_audacious_status(struct text_object *, char *p, int p_max_size)
{
const aud_result &res = get_res();
snprintf(p, p_max_size, "%s", as_message[res.status]);
aud_result get_res() {
uint32_t period = std::max(
lround(music_player_interval.get(*state) / active_update_interval()), 1l);
return conky::register_cb<audacious_cb>(period)->get_result_copy();
}
} // namespace
void print_audacious_status(struct text_object *, char *p, int p_max_size) {
const aud_result &res = get_res();
snprintf(p, p_max_size, "%s", as_message[res.status]);
}
void print_audacious_title(struct text_object *obj, char *p, int p_max_size)
{
snprintf(p, std::min(obj->data.i, p_max_size), "%s", get_res().title.c_str());
void print_audacious_title(struct text_object *obj, char *p, int p_max_size) {
snprintf(p, std::min(obj->data.i, p_max_size), "%s", get_res().title.c_str());
}
void print_audacious_filename(struct text_object *obj, char *p, int p_max_size)
{
snprintf(p, std::min(obj->data.i, p_max_size), "%s", get_res().filename.c_str());
void print_audacious_filename(struct text_object *obj, char *p,
int p_max_size) {
snprintf(p, std::min(obj->data.i, p_max_size), "%s",
get_res().filename.c_str());
}
double audacious_barval(struct text_object *)
{
const aud_result &res = get_res();
return (double)res.position / res.length;
double audacious_barval(struct text_object *) {
const aud_result &res = get_res();
return (double)res.position / res.length;
}
#define AUDACIOUS_TIME_GENERATOR(name) \
void print_audacious_##name(struct text_object *, char *p, int p_max_size) \
{ \
const aud_result &res = get_res(); \
int sec = res.name / 1000; \
snprintf(p, p_max_size, "%d:%.2d", sec/60, sec%60); \
} \
\
void print_audacious_##name##_seconds(struct text_object *, char *p, int p_max_size) \
{ \
snprintf(p, p_max_size, "%d", get_res().name); \
}
#define AUDACIOUS_TIME_GENERATOR(name) \
void print_audacious_##name(struct text_object *, char *p, int p_max_size) { \
const aud_result &res = get_res(); \
int sec = res.name / 1000; \
snprintf(p, p_max_size, "%d:%.2d", sec / 60, sec % 60); \
} \
\
void print_audacious_##name##_seconds(struct text_object *, char *p, \
int p_max_size) { \
snprintf(p, p_max_size, "%d", get_res().name); \
}
AUDACIOUS_TIME_GENERATOR(length)
AUDACIOUS_TIME_GENERATOR(position)
#define AUDACIOUS_INT_GENERATOR(name, offset) \
void print_audacious_##name(struct text_object *, char *p, int p_max_size) \
{ \
snprintf(p, p_max_size, "%d", get_res().name + offset); \
}
#define AUDACIOUS_INT_GENERATOR(name, offset) \
void print_audacious_##name(struct text_object *, char *p, int p_max_size) { \
snprintf(p, p_max_size, "%d", get_res().name + offset); \
}
AUDACIOUS_INT_GENERATOR(bitrate, 0)
AUDACIOUS_INT_GENERATOR(frequency, 0)

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* audacious.h: conky support for audacious music player
*

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -9,7 +8,7 @@
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -31,11 +30,11 @@
#include "conky.h"
#include "logging.h"
#include <bmp/dbus.hh>
#include <dbus/dbus-glib.h>
#include <bmp/dbus.hh>
#define DBUS_TYPE_G_STRING_VALUE_HASHTABLE \
(dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
(dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
static DBusGConnection *bus;
static DBusGProxy *remote_object;
@@ -44,105 +43,103 @@ static char *unknown = "unknown";
void fail(GError *error, struct information *);
void update_bmpx()
{
GError *error = NULL;
struct information *current_info = &info;
gint current_track;
GHashTable *metadata;
void update_bmpx() {
GError *error = NULL;
struct information *current_info = &info;
gint current_track;
GHashTable *metadata;
if (connected == 0) {
g_type_init();
dbus_g_type_specialized_init();
if (connected == 0) {
g_type_init();
dbus_g_type_specialized_init();
bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
if (bus == NULL) {
NORM_ERR("BMPx error 1: %s\n", error->message);
fail(error, current_info);
return;
}
bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
if (bus == NULL) {
NORM_ERR("BMPx error 1: %s\n", error->message);
fail(error, current_info);
return;
}
remote_object = dbus_g_proxy_new_for_name(bus, BMP_DBUS_SERVICE,
BMP_DBUS_PATH__BMP, BMP_DBUS_INTERFACE__BMP);
if (!remote_object) {
NORM_ERR("BMPx error 2: %s\n", error->message);
fail(error, current_info);
return;
}
remote_object = dbus_g_proxy_new_for_name(
bus, BMP_DBUS_SERVICE, BMP_DBUS_PATH__BMP, BMP_DBUS_INTERFACE__BMP);
if (!remote_object) {
NORM_ERR("BMPx error 2: %s\n", error->message);
fail(error, current_info);
return;
}
connected = 1;
}
connected = 1;
}
if (connected == 1) {
if (dbus_g_proxy_call(remote_object, "GetCurrentTrack", &error,
G_TYPE_INVALID, G_TYPE_INT, &current_track, G_TYPE_INVALID)) {
} else {
NORM_ERR("BMPx error 3: %s\n", error->message);
fail(error, current_info);
return;
}
if (connected == 1) {
if (dbus_g_proxy_call(remote_object, "GetCurrentTrack", &error,
G_TYPE_INVALID, G_TYPE_INT, &current_track,
G_TYPE_INVALID)) {
} else {
NORM_ERR("BMPx error 3: %s\n", error->message);
fail(error, current_info);
return;
}
if (dbus_g_proxy_call(remote_object, "GetMetadataForListItem", &error,
G_TYPE_INT, current_track, G_TYPE_INVALID,
DBUS_TYPE_G_STRING_VALUE_HASHTABLE, &metadata,
G_TYPE_INVALID)) {
free_and_zero(current_info->bmpx.title);
free_and_zero(current_info->bmpx.artist);
free_and_zero(current_info->bmpx.album);
current_info->bmpx.title =
g_value_dup_string(g_hash_table_lookup(metadata, "title"));
current_info->bmpx.artist =
g_value_dup_string(g_hash_table_lookup(metadata, "artist"));
current_info->bmpx.album =
g_value_dup_string(g_hash_table_lookup(metadata, "album"));
current_info->bmpx.bitrate =
g_value_get_int(g_hash_table_lookup(metadata, "bitrate"));
current_info->bmpx.track =
g_value_get_int(g_hash_table_lookup(metadata, "track-number"));
current_info->bmpx.uri =
g_value_get_string(g_hash_table_lookup(metadata, "location"));
} else {
NORM_ERR("BMPx error 4: %s\n", error->message);
fail(error, current_info);
return;
}
if (dbus_g_proxy_call(remote_object, "GetMetadataForListItem", &error,
G_TYPE_INT, current_track, G_TYPE_INVALID,
DBUS_TYPE_G_STRING_VALUE_HASHTABLE, &metadata,
G_TYPE_INVALID)) {
free_and_zero(current_info->bmpx.title);
free_and_zero(current_info->bmpx.artist);
free_and_zero(current_info->bmpx.album);
current_info->bmpx.title =
g_value_dup_string(g_hash_table_lookup(metadata, "title"));
current_info->bmpx.artist =
g_value_dup_string(g_hash_table_lookup(metadata, "artist"));
current_info->bmpx.album =
g_value_dup_string(g_hash_table_lookup(metadata, "album"));
current_info->bmpx.bitrate =
g_value_get_int(g_hash_table_lookup(metadata, "bitrate"));
current_info->bmpx.track =
g_value_get_int(g_hash_table_lookup(metadata, "track-number"));
current_info->bmpx.uri =
g_value_get_string(g_hash_table_lookup(metadata, "location"));
} else {
NORM_ERR("BMPx error 4: %s\n", error->message);
fail(error, current_info);
return;
}
g_hash_table_destroy(metadata);
} else {
fail(error, current_info);
}
g_hash_table_destroy(metadata);
} else {
fail(error, current_info);
}
}
void fail(GError *error, struct information *current_info)
{
if (error) {
g_error_free(error);
}
if (current_info->bmpx.title) {
g_free(current_info->bmpx.title);
current_info->bmpx.title = 0;
}
if (current_info->bmpx.artist) {
g_free(current_info->bmpx.artist);
current_info->bmpx.artist = 0;
}
if (current_info->bmpx.album) {
g_free(current_info->bmpx.album);
current_info->bmpx.album = 0;
}
current_info->bmpx.title = unknown;
current_info->bmpx.artist = unknown;
current_info->bmpx.album = unknown;
current_info->bmpx.bitrate = 0;
current_info->bmpx.track = 0;
void fail(GError *error, struct information *current_info) {
if (error) {
g_error_free(error);
}
if (current_info->bmpx.title) {
g_free(current_info->bmpx.title);
current_info->bmpx.title = 0;
}
if (current_info->bmpx.artist) {
g_free(current_info->bmpx.artist);
current_info->bmpx.artist = 0;
}
if (current_info->bmpx.album) {
g_free(current_info->bmpx.album);
current_info->bmpx.album = 0;
}
current_info->bmpx.title = unknown;
current_info->bmpx.artist = unknown;
current_info->bmpx.album = unknown;
current_info->bmpx.bitrate = 0;
current_info->bmpx.track = 0;
}
#define BMPX_PRINT_GENERATOR(name, fmt) \
void print_bmpx_##name(struct text_object *obj, char *p, int p_max_size) \
{ \
(void)obj; \
snprintf(p, p_max_size, fmt, info.bmpx.name); \
}
#define BMPX_PRINT_GENERATOR(name, fmt) \
void print_bmpx_##name(struct text_object *obj, char *p, int p_max_size) { \
(void)obj; \
snprintf(p, p_max_size, fmt, info.bmpx.name); \
}
BMPX_PRINT_GENERATOR(title, "%s")
BMPX_PRINT_GENERATOR(artist, "%s")
@@ -152,4 +149,3 @@ BMPX_PRINT_GENERATOR(track, "%i")
BMPX_PRINT_GENERATOR(bitrate, "%i")
#undef BMPX_PRINT_GENERATOR

View File

@@ -1,11 +1,10 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=c
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -28,12 +27,12 @@
void update_bmpx(void);
struct bmpx_s {
char *title;
char *artist;
char *album;
char *uri;
int bitrate;
int track;
char *title;
char *artist;
char *album;
char *uri;
int bitrate;
int track;
};
void print_bmpx_title(struct text_object *, char *, int);

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -27,184 +26,178 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <fcntl.h>
#include <machine/apm_bios.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "config.h"
#include "conky.h"
#include "text_object.h"
#include <fcntl.h>
#include <sys/ioctl.h>
#include <machine/apm_bios.h>
#include <unistd.h>
#define APMDEV "/dev/apm"
#define APM_UNKNOWN 255
#define APMDEV "/dev/apm"
#define APM_UNKNOWN 255
#ifndef APM_AC_OFF
# define APM_AC_OFF 0
#define APM_AC_OFF 0
#endif
#ifndef APM_AC_ON
# define APM_AC_ON 1
#define APM_AC_ON 1
#endif
#ifndef APM_BATT_CHARGING
# define APM_BATT_CHARGING 3
#define APM_BATT_CHARGING 3
#endif
static int apm_getinfo(int fd, apm_info_t aip)
{
static int apm_getinfo(int fd, apm_info_t aip) {
#ifdef __OpenBSD__
if (ioctl(fd, APM_IOC_GETPOWER, aip) == -1) {
if (ioctl(fd, APM_IOC_GETPOWER, aip) == -1) {
#else
if (ioctl(fd, APMIO_GETINFO, aip) == -1) {
if (ioctl(fd, APMIO_GETINFO, aip) == -1) {
#endif
return -1;
}
return -1;
}
return 0;
return 0;
}
void print_apm_adapter(struct text_object *obj, char *p, int p_max_size)
{
int fd;
const char *out;
void print_apm_adapter(struct text_object *obj, char *p, int p_max_size) {
int fd;
const char *out;
#ifdef __OpenBSD__
struct apm_power_info a_info;
struct apm_power_info a_info;
#else
struct apm_info a_info;
struct apm_info a_info;
#endif
(void)obj;
(void)obj;
fd = open(APMDEV, O_RDONLY);
if (fd < 0) {
snprintf(p, p_max_size, "ERR");
return;
}
fd = open(APMDEV, O_RDONLY);
if (fd < 0) {
snprintf(p, p_max_size, "ERR");
return;
}
if (apm_getinfo(fd, &a_info) != 0) {
close(fd);
snprintf(p, p_max_size, "ERR");
return;
}
close(fd);
if (apm_getinfo(fd, &a_info) != 0) {
close(fd);
snprintf(p, p_max_size, "ERR");
return;
}
close(fd);
#ifdef __OpenBSD__
# define ai_acline ac_state
#define ai_acline ac_state
#endif
switch (a_info.ai_acline) {
case APM_AC_OFF:
out = "off-line";
break;
case APM_AC_ON:
switch (a_info.ai_acline) {
case APM_AC_OFF:
out = "off-line";
break;
case APM_AC_ON:
#ifdef __OpenBSD__
# define ai_batt_stat battery_state
#define ai_batt_stat battery_state
#endif
if (a_info.ai_batt_stat
== APM_BATT_CHARGING) {
out = "charging";
} else {
out = "on-line";
}
break;
default:
out = "unknown";
break;
}
snprintf(p, p_max_size, "%s", out);
if (a_info.ai_batt_stat == APM_BATT_CHARGING) {
out = "charging";
} else {
out = "on-line";
}
break;
default:
out = "unknown";
break;
}
snprintf(p, p_max_size, "%s", out);
}
void print_apm_battery_life(struct text_object *obj, char *p, int p_max_size)
{
int fd;
u_int batt_life;
const char *out;
void print_apm_battery_life(struct text_object *obj, char *p, int p_max_size) {
int fd;
u_int batt_life;
const char *out;
#ifdef __OpenBSD__
struct apm_power_info a_info;
struct apm_power_info a_info;
#else
struct apm_info a_info;
struct apm_info a_info;
#endif
(void)obj;
(void)obj;
fd = open(APMDEV, O_RDONLY);
if (fd < 0) {
snprintf(p, p_max_size, "ERR");
return;
}
fd = open(APMDEV, O_RDONLY);
if (fd < 0) {
snprintf(p, p_max_size, "ERR");
return;
}
if (apm_getinfo(fd, &a_info) != 0) {
close(fd);
snprintf(p, p_max_size, "ERR");
return;
}
close(fd);
if (apm_getinfo(fd, &a_info) != 0) {
close(fd);
snprintf(p, p_max_size, "ERR");
return;
}
close(fd);
#ifdef __OpenBSD__
# define ai_batt_life battery_life
#define ai_batt_life battery_life
#endif
batt_life = a_info.ai_batt_life;
if (batt_life == APM_UNKNOWN) {
out = "unknown";
} else if (batt_life <= 100) {
snprintf(p, p_max_size, "%d%%", batt_life);
return;
} else {
out = "ERR";
}
batt_life = a_info.ai_batt_life;
if (batt_life == APM_UNKNOWN) {
out = "unknown";
} else if (batt_life <= 100) {
snprintf(p, p_max_size, "%d%%", batt_life);
return;
} else {
out = "ERR";
}
snprintf(p, p_max_size, "%s", out);
snprintf(p, p_max_size, "%s", out);
}
void print_apm_battery_time(struct text_object *obj, char *p, int p_max_size)
{
int fd;
int batt_time;
void print_apm_battery_time(struct text_object *obj, char *p, int p_max_size) {
int fd;
int batt_time;
#ifdef __OpenBSD__
int h, m;
struct apm_power_info a_info;
int h, m;
struct apm_power_info a_info;
#else
int h, m, s;
struct apm_info a_info;
int h, m, s;
struct apm_info a_info;
#endif
(void)obj;
(void)obj;
fd = open(APMDEV, O_RDONLY);
if (fd < 0) {
snprintf(p, p_max_size, "ERR");
return;
}
fd = open(APMDEV, O_RDONLY);
if (fd < 0) {
snprintf(p, p_max_size, "ERR");
return;
}
if (apm_getinfo(fd, &a_info) != 0) {
close(fd);
snprintf(p, p_max_size, "ERR");
return;
}
close(fd);
if (apm_getinfo(fd, &a_info) != 0) {
close(fd);
snprintf(p, p_max_size, "ERR");
return;
}
close(fd);
#ifdef __OpenBSD__
# define ai_batt_time minutes_left
#define ai_batt_time minutes_left
#endif
batt_time = a_info.ai_batt_time;
if (batt_time == -1) {
snprintf(p, p_max_size, "unknown");
} else
batt_time = a_info.ai_batt_time;
if (batt_time == -1) {
snprintf(p, p_max_size, "unknown");
} else
#ifdef __OpenBSD__
{
h = batt_time / 60;
m = batt_time % 60;
snprintf(p, p_max_size, "%2d:%02d", h, m);
}
{
h = batt_time / 60;
m = batt_time % 60;
snprintf(p, p_max_size, "%2d:%02d", h, m);
}
#else
{
h = batt_time;
s = h % 60;
h /= 60;
m = h % 60;
h /= 60;
snprintf(p, p_max_size, "%2d:%02d:%02d", h, m, s);
}
{
h = batt_time;
s = h % 60;
h /= 60;
m = h % 60;
h /= 60;
snprintf(p, p_max_size, "%2d:%02d:%02d", h, m, s);
}
#endif
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=c
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -25,8 +24,8 @@
#include "c++wrap.hh"
#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
/* force use of POSIX strerror_r instead of non-portable GNU specific */
#ifdef _GNU_SOURCE
@@ -42,47 +41,41 @@
#include <fcntl.h>
namespace {
int pipe2_emulate(int pipefd[2], int flags)
{
if(pipe(pipefd) == -1)
return -1;
int pipe2_emulate(int pipefd[2], int flags) {
if (pipe(pipefd) == -1) return -1;
if(flags & O_CLOEXEC) {
// we emulate O_CLOEXEC if the system does not have it
// not very thread-safe, but at least it works
if (flags & O_CLOEXEC) {
// we emulate O_CLOEXEC if the system does not have it
// not very thread-safe, but at least it works
for(int i = 0; i < 2; ++i) {
int r = fcntl(pipefd[i], F_GETFD);
if(r == -1)
return -1;
for (int i = 0; i < 2; ++i) {
int r = fcntl(pipefd[i], F_GETFD);
if (r == -1) return -1;
if(fcntl(pipefd[i], F_SETFD, r | FD_CLOEXEC) == -1)
return -1;
}
}
if (fcntl(pipefd[i], F_SETFD, r | FD_CLOEXEC) == -1) return -1;
}
}
return 0;
}
int (* const pipe2_ptr)(int[2], int) = &pipe2_emulate;
return 0;
}
int (*const pipe2_ptr)(int[2], int) = &pipe2_emulate;
} // namespace
#else
int (* const pipe2_ptr)(int[2], int) = &pipe2;
int (*const pipe2_ptr)(int[2], int) = &pipe2;
#endif
std::string strerror_r(int errnum)
{
static thread_local char buf[100];
if (strerror_r(errnum, buf, sizeof buf) != 0)
snprintf(buf, sizeof buf, "Unknown error %i", errnum);
return buf;
std::string strerror_r(int errnum) {
static thread_local char buf[100];
if (strerror_r(errnum, buf, sizeof buf) != 0)
snprintf(buf, sizeof buf, "Unknown error %i", errnum);
return buf;
}
std::pair<int, int> pipe2(int flags)
{
int fd[2];
if(pipe2_ptr(fd, flags) == -1)
throw errno_error("pipe2");
else
return std::pair<int, int>(fd[0], fd[1]);
std::pair<int, int> pipe2(int flags) {
int fd[2];
if (pipe2_ptr(fd, flags) == -1)
throw errno_error("pipe2");
else
return std::pair<int, int>(fd[0], fd[1]);
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -38,15 +37,14 @@ enum { O_CLOEXEC = 02000000 };
std::string strerror_r(int errnum);
std::pair<int, int> pipe2(int flags);
class errno_error: public std::runtime_error {
typedef std::runtime_error Base;
class errno_error : public std::runtime_error {
typedef std::runtime_error Base;
public:
errno_error(const std::string &prefix, int err_ = errno)
: Base(prefix + ": " + strerror_r(err_)), err(err_)
{}
public:
errno_error(const std::string &prefix, int err_ = errno)
: Base(prefix + ": " + strerror_r(err_)), err(err_) {}
const int err;
const int err;
};
#endif /* CPPWRAP_HH */

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -23,12 +22,12 @@
*
*/
#include "conky.h"
#include "logging.h"
#include "ccurl_thread.h"
#include "text_object.h"
#include <cmath>
#include <mutex>
#include "conky.h"
#include "logging.h"
#include "text_object.h"
#ifdef DEBUG
#include <assert.h>
@@ -44,178 +43,169 @@
*/
namespace priv {
/* callback used by curl for parsing the header data */
size_t curl_internal::parse_header_cb(void *ptr, size_t size, size_t nmemb, void *data)
{
curl_internal *obj = static_cast<curl_internal *>(data);
const char *value = static_cast<const char *>(ptr);
size_t realsize = size * nmemb;
/* callback used by curl for parsing the header data */
size_t curl_internal::parse_header_cb(void *ptr, size_t size, size_t nmemb,
void *data) {
curl_internal *obj = static_cast<curl_internal *>(data);
const char *value = static_cast<const char *>(ptr);
size_t realsize = size * nmemb;
if(realsize > 0 && (value[realsize-1] == '\r' || value[realsize-1] == 0))
--realsize;
if (realsize > 0 && (value[realsize - 1] == '\r' || value[realsize - 1] == 0))
--realsize;
if (strncmp(value, "Last-Modified: ", 15) == EQUAL) {
obj->last_modified = std::string(value + 15, realsize - 15);
} else if (strncmp(value,"ETag: ", 6) == EQUAL) {
obj->etag = std::string(value + 6, realsize - 6);
}
if (strncmp(value, "Last-Modified: ", 15) == EQUAL) {
obj->last_modified = std::string(value + 15, realsize - 15);
} else if (strncmp(value, "ETag: ", 6) == EQUAL) {
obj->etag = std::string(value + 6, realsize - 6);
}
return size*nmemb;
}
/* callback used by curl for writing the received data */
size_t curl_internal::write_cb(void *ptr, size_t size, size_t nmemb, void *data)
{
curl_internal *obj = static_cast<curl_internal *>(data);
const char *value = static_cast<const char *>(ptr);
size_t realsize = size * nmemb;
obj->data += std::string(value, realsize);
return realsize;
}
curl_internal::curl_internal(const std::string &url)
: curl(curl_easy_init())
{
if(not curl)
throw std::runtime_error("curl_easy_init() failed");
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, this);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parse_header_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-curl/1.1");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1000);
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 60);
// curl's usage of alarm()+longjmp() is a really bad idea for multi-threaded applications
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
}
/* fetch our datums */
void curl_internal::do_work()
{
CURLcode res;
struct headers_ {
struct curl_slist *h;
headers_() : h(NULL) {}
~headers_() { curl_slist_free_all(h); }
} headers;
data.clear();
if (not last_modified.empty()) {
headers.h = curl_slist_append(headers.h, ("If-Modified-Since: " + last_modified).c_str());
last_modified.clear();
}
if (not etag.empty()) {
headers.h = curl_slist_append(headers.h, ("If-None-Match: " + etag).c_str());
etag.clear();
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.h);
res = curl_easy_perform(curl);
if (res == CURLE_OK) {
long http_status_code;
if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status_code) == CURLE_OK) {
switch (http_status_code) {
case 200:
process_data();
break;
case 304:
break;
default:
NORM_ERR("curl: no data from server, got HTTP status %ld",
http_status_code);
break;
}
} else {
NORM_ERR("curl: no HTTP status from server");
}
} else {
NORM_ERR("curl: could not retrieve data from server");
}
}
return size * nmemb;
}
/* callback used by curl for writing the received data */
size_t curl_internal::write_cb(void *ptr, size_t size, size_t nmemb,
void *data) {
curl_internal *obj = static_cast<curl_internal *>(data);
const char *value = static_cast<const char *>(ptr);
size_t realsize = size * nmemb;
obj->data += std::string(value, realsize);
return realsize;
}
curl_internal::curl_internal(const std::string &url) : curl(curl_easy_init()) {
if (not curl) throw std::runtime_error("curl_easy_init() failed");
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, this);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parse_header_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-curl/1.1");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1000);
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 60);
// curl's usage of alarm()+longjmp() is a really bad idea for multi-threaded
// applications
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
}
/* fetch our datums */
void curl_internal::do_work() {
CURLcode res;
struct headers_ {
struct curl_slist *h;
headers_() : h(NULL) {}
~headers_() { curl_slist_free_all(h); }
} headers;
data.clear();
if (not last_modified.empty()) {
headers.h = curl_slist_append(
headers.h, ("If-Modified-Since: " + last_modified).c_str());
last_modified.clear();
}
if (not etag.empty()) {
headers.h =
curl_slist_append(headers.h, ("If-None-Match: " + etag).c_str());
etag.clear();
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.h);
res = curl_easy_perform(curl);
if (res == CURLE_OK) {
long http_status_code;
if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status_code) ==
CURLE_OK) {
switch (http_status_code) {
case 200:
process_data();
break;
case 304:
break;
default:
NORM_ERR("curl: no data from server, got HTTP status %ld",
http_status_code);
break;
}
} else {
NORM_ERR("curl: no HTTP status from server");
}
} else {
NORM_ERR("curl: could not retrieve data from server");
}
}
} // namespace priv
namespace {
class simple_curl_cb: public curl_callback<std::string> {
typedef curl_callback<std::string> Base;
class simple_curl_cb : public curl_callback<std::string> {
typedef curl_callback<std::string> Base;
protected:
virtual void process_data()
{
std::lock_guard<std::mutex> lock(result_mutex);
result = data;
}
public:
simple_curl_cb(uint32_t period, const std::string &uri)
: Base(period, Tuple(uri))
{}
};
}
protected:
virtual void process_data() {
std::lock_guard<std::mutex> lock(result_mutex);
result = data;
}
public:
simple_curl_cb(uint32_t period, const std::string &uri)
: Base(period, Tuple(uri)) {}
};
} // namespace
/*
* This is where the $curl section begins.
*/
struct curl_data {
char uri[128];
float interval;
char uri[128];
float interval;
};
/* prints result data to text buffer, used by $curl */
void ccurl_process_info(char *p, int p_max_size, const std::string &uri, int interval)
{
uint32_t period = std::max(lround(interval/active_update_interval()), 1l);
auto cb = conky::register_cb<simple_curl_cb>(period, uri);
void ccurl_process_info(char *p, int p_max_size, const std::string &uri,
int interval) {
uint32_t period = std::max(lround(interval / active_update_interval()), 1l);
auto cb = conky::register_cb<simple_curl_cb>(period, uri);
strncpy(p, cb->get_result_copy().c_str(), p_max_size);
strncpy(p, cb->get_result_copy().c_str(), p_max_size);
}
void curl_parse_arg(struct text_object *obj, const char *arg)
{
int argc;
struct curl_data *cd;
float interval = 0;
void curl_parse_arg(struct text_object *obj, const char *arg) {
int argc;
struct curl_data *cd;
float interval = 0;
cd = (struct curl_data*)malloc(sizeof(struct curl_data));
memset(cd, 0, sizeof(struct curl_data));
cd = (struct curl_data *)malloc(sizeof(struct curl_data));
memset(cd, 0, sizeof(struct curl_data));
argc = sscanf(arg, "%127s %f", cd->uri, &interval);
if (argc < 1) {
free(cd);
NORM_ERR("wrong number of arguments for $curl");
return;
}
if (argc == 1)
cd->interval = 15*60;
else
cd->interval = interval > 0 ? interval * 60 : active_update_interval();
obj->data.opaque = cd;
argc = sscanf(arg, "%127s %f", cd->uri, &interval);
if (argc < 1) {
free(cd);
NORM_ERR("wrong number of arguments for $curl");
return;
}
if (argc == 1)
cd->interval = 15 * 60;
else
cd->interval = interval > 0 ? interval * 60 : active_update_interval();
obj->data.opaque = cd;
}
void curl_print(struct text_object *obj, char *p, int p_max_size)
{
struct curl_data *cd = (struct curl_data *)obj->data.opaque;
void curl_print(struct text_object *obj, char *p, int p_max_size) {
struct curl_data *cd = (struct curl_data *)obj->data.opaque;
if (!cd || !cd->uri) {
NORM_ERR("error processing Curl data");
return;
}
ccurl_process_info(p, p_max_size, cd->uri, cd->interval);
if (!cd || !cd->uri) {
NORM_ERR("error processing Curl data");
return;
}
ccurl_process_info(p, p_max_size, cd->uri, cd->interval);
}
void curl_obj_free(struct text_object *obj)
{
free_and_zero(obj->data.opaque);
}
void curl_obj_free(struct text_object *obj) { free_and_zero(obj->data.opaque); }

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -31,55 +30,56 @@
#include "update-cb.hh"
namespace priv {
// factored out stuff that does not depend on the template parameters
struct curl_internal {
std::string last_modified;
std::string etag;
std::string data;
CURL *curl;
// factored out stuff that does not depend on the template parameters
struct curl_internal {
std::string last_modified;
std::string etag;
std::string data;
CURL *curl;
static size_t parse_header_cb(void *ptr, size_t size, size_t nmemb, void *data);
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data);
static size_t parse_header_cb(void *ptr, size_t size, size_t nmemb,
void *data);
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data);
void do_work();
void do_work();
// called by do_work() after downloading data from the uri
// it should populate the result variable
virtual void process_data() = 0;
// called by do_work() after downloading data from the uri
// it should populate the result variable
virtual void process_data() = 0;
curl_internal(const std::string &url);
virtual ~curl_internal() { if(curl) curl_easy_cleanup(curl); }
};
}
curl_internal(const std::string &url);
virtual ~curl_internal() {
if (curl) curl_easy_cleanup(curl);
}
};
} // namespace priv
/*
* Curl callback class template
* the key is an url
*/
template<typename Result, typename... Keys>
class curl_callback: public conky::callback<Result, std::string, Keys...>,
protected priv::curl_internal {
typedef conky::callback<Result, std::string, Keys...> Base1;
typedef priv::curl_internal Base2;
template <typename Result, typename... Keys>
class curl_callback : public conky::callback<Result, std::string, Keys...>,
protected priv::curl_internal {
typedef conky::callback<Result, std::string, Keys...> Base1;
typedef priv::curl_internal Base2;
protected:
virtual void work()
{
DBGP("reading curl data from '%s'", std::get<0>(Base1::tuple).c_str());
do_work();
}
protected:
virtual void work() {
DBGP("reading curl data from '%s'", std::get<0>(Base1::tuple).c_str());
do_work();
}
public:
curl_callback(uint32_t period, const typename Base1::Tuple &tuple)
: Base1(period, false, tuple), Base2(std::get<0>(tuple))
{}
public:
curl_callback(uint32_t period, const typename Base1::Tuple &tuple)
: Base1(period, false, tuple), Base2(std::get<0>(tuple)) {}
};
/* $curl exports begin */
/* runs instance of $curl */
void ccurl_process_info(char *p, int p_max_size, const std::string &uri, int interval);
void ccurl_process_info(char *p, int p_max_size, const std::string &uri,
int interval);
void curl_parse_arg(struct text_object *, const char *);
void curl_print(struct text_object *, char *, int);
@@ -88,4 +88,3 @@ void curl_obj_free(struct text_object *);
/* $curl exports end */
#endif /* _CURL_THREAD_H_ */

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* CMUS Conky integration
*
@@ -25,134 +24,129 @@
#include "logging.h"
#include "text_object.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cmath>
#include <mutex>
#include <math.h>
#include "update-cb.hh"
namespace {
struct cmus_result {
std::string state;
std::string file;
std::string title;
std::string artist;
std::string album;
std::string totaltime;
std::string curtime;
std::string random;
std::string repeat;
std::string aaa;
std::string track;
std::string genre;
std::string date;
float progress;
float timeleft;
};
struct cmus_result {
std::string state;
std::string file;
std::string title;
std::string artist;
std::string album;
std::string totaltime;
std::string curtime;
std::string random;
std::string repeat;
std::string aaa;
std::string track;
std::string genre;
std::string date;
float progress;
float timeleft;
};
class cmus_cb: public conky::callback<cmus_result> {
typedef conky::callback<cmus_result> Base;
class cmus_cb : public conky::callback<cmus_result> {
typedef conky::callback<cmus_result> Base;
protected:
virtual void work();
protected:
virtual void work();
public:
cmus_cb(uint32_t period)
: Base(period, false, Tuple())
{}
};
public:
cmus_cb(uint32_t period) : Base(period, false, Tuple()) {}
};
void cmus_cb::work()
{
cmus_result cmus;
FILE *fp;
void cmus_cb::work() {
cmus_result cmus;
FILE *fp;
fp = popen("cmus-remote -Q 2>/dev/null", "r");
if (!fp) {
cmus.state = "Can't run 'cmus-remote -Q'";
} else {
while (1) {
char line[255];
char *p;
fp = popen("cmus-remote -Q 2>/dev/null", "r");
if (!fp) {
cmus.state = "Can't run 'cmus-remote -Q'";
} else {
while (1) {
char line[255];
char *p;
/* Read a line from the pipe and strip the possible '\n'. */
if (!fgets(line, 255, fp))
break;
if ((p = strrchr(line, '\n')))
*p = '\0';
/* Read a line from the pipe and strip the possible '\n'. */
if (!fgets(line, 255, fp)) break;
if ((p = strrchr(line, '\n'))) *p = '\0';
/* Parse infos. */
if (strncmp(line, "status ", 7) == 0)
cmus.state = line + 7;
/* Parse infos. */
if (strncmp(line, "status ", 7) == 0)
cmus.state = line + 7;
else if (strncmp(line, "file ", 5) == 0)
cmus.file = line + 5;
else if (strncmp(line, "file ", 5) == 0)
cmus.file = line + 5;
else if (strncmp(line, "tag artist ", 11) == 0)
cmus.artist = line + 11;
else if (strncmp(line, "tag artist ", 11) == 0)
cmus.artist = line + 11;
else if (strncmp(line, "tag title ", 10) == 0)
cmus.title = line + 10;
else if (strncmp(line, "tag title ", 10) == 0)
cmus.title = line + 10;
else if (strncmp(line, "tag album ", 10) == 0)
cmus.album = line + 10;
else if (strncmp(line, "tag album ", 10) == 0)
cmus.album = line + 10;
else if (strncmp(line, "duration ", 9) == 0)
cmus.totaltime = line + 9;
else if (strncmp(line, "duration ", 9) == 0)
cmus.totaltime = line + 9;
else if (strncmp(line, "position ", 9) == 0)
{
cmus.curtime = line + 9;
cmus.timeleft = atoi(cmus.totaltime.c_str()) - atoi(cmus.curtime.c_str());
if (cmus.curtime.size() > 0)
cmus.progress = (float) atoi(cmus.curtime.c_str()) / atoi(cmus.totaltime.c_str());
else
cmus.progress = 0;
}
else if (strncmp(line, "position ", 9) == 0) {
cmus.curtime = line + 9;
cmus.timeleft =
atoi(cmus.totaltime.c_str()) - atoi(cmus.curtime.c_str());
if (cmus.curtime.size() > 0)
cmus.progress =
(float)atoi(cmus.curtime.c_str()) / atoi(cmus.totaltime.c_str());
else
cmus.progress = 0;
}
else if (strncmp(line, "set shuffle ", 12) == 0)
cmus.random = (strncmp(line+12, "true", 4) == 0 ?
"on" : "off" );
else if (strncmp(line, "set shuffle ", 12) == 0)
cmus.random = (strncmp(line + 12, "true", 4) == 0 ? "on" : "off");
else if (strncmp(line, "set repeat ", 11) == 0)
cmus.repeat = (strncmp((line+11), "true", 4) == 0 ?
"all" : "off" );
else if (strncmp(line, "set repeat ", 11) == 0)
cmus.repeat = (strncmp((line + 11), "true", 4) == 0 ? "all" : "off");
else if (strncmp(line, "set repeat_current ", 19) == 0)
cmus.repeat = (strncmp((line + 19), "true", 4) == 0 ?
"song" : cmus.repeat );
else if (strncmp(line, "set aaa_mode ", 13) == 0)
cmus.aaa = line + 13;
else if (strncmp(line, "set repeat_current ", 19) == 0)
cmus.repeat =
(strncmp((line + 19), "true", 4) == 0 ? "song" : cmus.repeat);
else if (strncmp(line, "set aaa_mode ", 13) == 0)
cmus.aaa = line + 13;
else if (strncmp(line, "tag tracknumber ", 16) == 0)
cmus.track = line + 16;
else if (strncmp(line, "tag genre ", 10) == 0)
cmus.genre = line + 10;
else if (strncmp(line, "tag date ", 9) == 0)
cmus.date = line + 9;
}
}
else if (strncmp(line, "tag tracknumber ", 16) == 0)
cmus.track = line + 16;
else if (strncmp(line, "tag genre ", 10) == 0)
cmus.genre = line + 10;
else if (strncmp(line, "tag date ", 9) == 0)
cmus.date = line + 9;
}
}
pclose(fp);
pclose(fp);
std::lock_guard<std::mutex> l(result_mutex);
result = cmus;
}
std::lock_guard<std::mutex> l(result_mutex);
result = cmus;
}
} // namespace
#define CMUS_PRINT_GENERATOR(type, alt) \
void print_cmus_##type(struct text_object *obj, char *p, int p_max_size) \
{ \
(void)obj; \
uint32_t period = std::max( \
lround(music_player_interval.get(*state)/active_update_interval()), 1l \
); \
const cmus_result &cmus = conky::register_cb<cmus_cb>(period)->get_result_copy(); \
snprintf(p, p_max_size, "%s", (cmus.type.length() ? cmus.type.c_str() : alt)); \
}
#define CMUS_PRINT_GENERATOR(type, alt) \
void print_cmus_##type(struct text_object *obj, char *p, int p_max_size) { \
(void)obj; \
uint32_t period = std::max( \
lround(music_player_interval.get(*state) / active_update_interval()), \
1l); \
const cmus_result &cmus = \
conky::register_cb<cmus_cb>(period)->get_result_copy(); \
snprintf(p, p_max_size, "%s", \
(cmus.type.length() ? cmus.type.c_str() : alt)); \
}
CMUS_PRINT_GENERATOR(state, "Off")
CMUS_PRINT_GENERATOR(file, "no file")
@@ -166,50 +160,50 @@ CMUS_PRINT_GENERATOR(track, "no track")
CMUS_PRINT_GENERATOR(genre, "")
CMUS_PRINT_GENERATOR(date, "")
uint8_t cmus_percent(struct text_object *obj)
{
(void)obj;
uint32_t period = std::max(
lround(music_player_interval.get(*state)/active_update_interval()), 1l);
const cmus_result &cmus = conky::register_cb<cmus_cb>(period)->get_result_copy();
return (uint8_t) round(cmus.progress * 100.0f);
uint8_t cmus_percent(struct text_object *obj) {
(void)obj;
uint32_t period = std::max(
lround(music_player_interval.get(*state) / active_update_interval()), 1l);
const cmus_result &cmus =
conky::register_cb<cmus_cb>(period)->get_result_copy();
return (uint8_t)round(cmus.progress * 100.0f);
}
double cmus_progress(struct text_object *obj)
{
(void)obj;
uint32_t period = std::max(
lround(music_player_interval.get(*state)/active_update_interval()), 1l);
const cmus_result &cmus = conky::register_cb<cmus_cb>(period)->get_result_copy();
return (double) cmus.progress;
double cmus_progress(struct text_object *obj) {
(void)obj;
uint32_t period = std::max(
lround(music_player_interval.get(*state) / active_update_interval()), 1l);
const cmus_result &cmus =
conky::register_cb<cmus_cb>(period)->get_result_copy();
return (double)cmus.progress;
}
void print_cmus_totaltime(struct text_object *obj, char *p, int p_max_size)
{
(void)obj;
uint32_t period = std::max(
lround(music_player_interval.get(*state)/active_update_interval()), 1l);
const cmus_result &cmus = conky::register_cb<cmus_cb>(period)->get_result_copy();
format_seconds_short(p, p_max_size, atol(cmus.totaltime.c_str()));
void print_cmus_totaltime(struct text_object *obj, char *p, int p_max_size) {
(void)obj;
uint32_t period = std::max(
lround(music_player_interval.get(*state) / active_update_interval()), 1l);
const cmus_result &cmus =
conky::register_cb<cmus_cb>(period)->get_result_copy();
format_seconds_short(p, p_max_size, atol(cmus.totaltime.c_str()));
}
void print_cmus_timeleft(struct text_object *obj, char *p, int p_max_size)
{
(void)obj;
uint32_t period = std::max(
lround(music_player_interval.get(*state)/active_update_interval()), 1l);
const cmus_result &cmus = conky::register_cb<cmus_cb>(period)->get_result_copy();
//format_seconds_short(p, p_max_size, atol(cmus.timeleft.c_str()));
format_seconds_short(p, p_max_size, (long)cmus.timeleft);
void print_cmus_timeleft(struct text_object *obj, char *p, int p_max_size) {
(void)obj;
uint32_t period = std::max(
lround(music_player_interval.get(*state) / active_update_interval()), 1l);
const cmus_result &cmus =
conky::register_cb<cmus_cb>(period)->get_result_copy();
// format_seconds_short(p, p_max_size, atol(cmus.timeleft.c_str()));
format_seconds_short(p, p_max_size, (long)cmus.timeleft);
}
void print_cmus_curtime(struct text_object *obj, char *p, int p_max_size)
{
(void)obj;
uint32_t period = std::max(
lround(music_player_interval.get(*state)/active_update_interval()), 1l);
const cmus_result &cmus = conky::register_cb<cmus_cb>(period)->get_result_copy();
format_seconds_short(p, p_max_size, atol(cmus.curtime.c_str()));
void print_cmus_curtime(struct text_object *obj, char *p, int p_max_size) {
(void)obj;
uint32_t period = std::max(
lround(music_player_interval.get(*state) / active_update_interval()), 1l);
const cmus_result &cmus =
conky::register_cb<cmus_cb>(period)->get_result_copy();
format_seconds_short(p, p_max_size, atol(cmus.curtime.c_str()));
}
#undef CMUS_PRINT_GENERATOR

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* CMUS Conky integration
*
@@ -43,4 +42,3 @@ double cmus_progress(struct text_object *obj);
uint8_t cmus_percent(struct text_object *obj);
#endif /* CMUS_H_ */

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -40,156 +39,156 @@
static short colour_depth = 0;
static long redmask, greenmask, bluemask;
static void set_up_gradient(void)
{
int i;
static void set_up_gradient(void) {
int i;
#ifdef BUILD_X11
if (out_to_x.get(*state)) {
colour_depth = DisplayPlanes(display, screen);
} else
if (out_to_x.get(*state)) {
colour_depth = DisplayPlanes(display, screen);
} else
#endif /* BUILD_X11 */
{
colour_depth = 16;
}
if (colour_depth != 24 && colour_depth != 16) {
NORM_ERR("using non-standard colour depth, gradients may look like a "
"lolly-pop");
}
{
colour_depth = 16;
}
if (colour_depth != 24 && colour_depth != 16) {
NORM_ERR(
"using non-standard colour depth, gradients may look like a "
"lolly-pop");
}
redmask = 0;
greenmask = 0;
bluemask = 0;
for (i = (colour_depth / 3) - 1; i >= 0; i--) {
redmask |= 1 << i;
greenmask |= 1 << i;
bluemask |= 1 << i;
}
if (colour_depth % 3 == 1) {
greenmask |= 1 << (colour_depth / 3);
}
redmask = redmask << (2 * colour_depth / 3 + colour_depth % 3);
greenmask = greenmask << (colour_depth / 3);
redmask = 0;
greenmask = 0;
bluemask = 0;
for (i = (colour_depth / 3) - 1; i >= 0; i--) {
redmask |= 1 << i;
greenmask |= 1 << i;
bluemask |= 1 << i;
}
if (colour_depth % 3 == 1) {
greenmask |= 1 << (colour_depth / 3);
}
redmask = redmask << (2 * colour_depth / 3 + colour_depth % 3);
greenmask = greenmask << (colour_depth / 3);
}
/* adjust colour values depending on colour depth */
unsigned int adjust_colours(unsigned int colour)
{
double r, g, b;
unsigned int adjust_colours(unsigned int colour) {
double r, g, b;
if (colour_depth == 0) {
set_up_gradient();
}
if (colour_depth == 16) {
r = (colour & 0xff0000) >> 16;
g = (colour & 0xff00) >> 8;
b = colour & 0xff;
colour = (int) (r * CONST_8_TO_5_BITS) << 11;
colour |= (int) (g * CONST_8_TO_6_BITS) << 5;
colour |= (int) (b * CONST_8_TO_5_BITS);
}
return colour;
if (colour_depth == 0) {
set_up_gradient();
}
if (colour_depth == 16) {
r = (colour & 0xff0000) >> 16;
g = (colour & 0xff00) >> 8;
b = colour & 0xff;
colour = (int)(r * CONST_8_TO_5_BITS) << 11;
colour |= (int)(g * CONST_8_TO_6_BITS) << 5;
colour |= (int)(b * CONST_8_TO_5_BITS);
}
return colour;
}
/* this function returns the next colour between two colours for a gradient */
unsigned long *do_gradient(int width, unsigned long first_colour, unsigned long last_colour)
{
int red1, green1, blue1; // first colour
int red2, green2, blue2; // last colour
int reddiff, greendiff, bluediff; // difference
short redshift = (2 * colour_depth / 3 + colour_depth % 3);
short greenshift = (colour_depth / 3);
unsigned long *colours = (unsigned long*)malloc(width * sizeof(unsigned long));
int i;
unsigned long *do_gradient(int width, unsigned long first_colour,
unsigned long last_colour) {
int red1, green1, blue1; // first colour
int red2, green2, blue2; // last colour
int reddiff, greendiff, bluediff; // difference
short redshift = (2 * colour_depth / 3 + colour_depth % 3);
short greenshift = (colour_depth / 3);
unsigned long *colours =
(unsigned long *)malloc(width * sizeof(unsigned long));
int i;
if (colour_depth == 0) {
set_up_gradient();
}
red1 = (first_colour & redmask) >> redshift;
green1 = (first_colour & greenmask) >> greenshift;
blue1 = first_colour & bluemask;
red2 = (last_colour & redmask) >> redshift;
green2 = (last_colour & greenmask) >> greenshift;
blue2 = last_colour & bluemask;
reddiff = abs(red1 - red2);
greendiff = abs(green1 - green2);
bluediff = abs(blue1 - blue2);
if (colour_depth == 0) {
set_up_gradient();
}
red1 = (first_colour & redmask) >> redshift;
green1 = (first_colour & greenmask) >> greenshift;
blue1 = first_colour & bluemask;
red2 = (last_colour & redmask) >> redshift;
green2 = (last_colour & greenmask) >> greenshift;
blue2 = last_colour & bluemask;
reddiff = abs(red1 - red2);
greendiff = abs(green1 - green2);
bluediff = abs(blue1 - blue2);
#ifdef HAVE_OPENMP
#pragma omp parallel for schedule(dynamic,10) shared(colours)
#pragma omp parallel for schedule(dynamic, 10) shared(colours)
#endif /* HAVE_OPENMP */
for (i = 0; i < width; i++) {
int red3 = 0, green3 = 0, blue3 = 0; // colour components
for (i = 0; i < width; i++) {
int red3 = 0, green3 = 0, blue3 = 0; // colour components
float factor = ((float) i / (width - 1));
float factor = ((float)i / (width - 1));
/* the '+ 0.5' bit rounds our floats to ints properly */
if (red1 >= red2) {
red3 = -(factor * reddiff) - 0.5;
} else if (red1 < red2) {
red3 = factor * reddiff + 0.5;
}
if (green1 >= green2) {
green3 = -(factor * greendiff) - 0.5;
} else if (green1 < green2) {
green3 = factor * greendiff + 0.5;
}
if (blue1 >= blue2) {
blue3 = -(factor * bluediff) - 0.5;
} else if (blue1 < blue2) {
blue3 = factor * bluediff + 0.5;
}
red3 += red1;
green3 += green1;
blue3 += blue1;
if (red3 < 0) {
red3 = 0;
}
if (green3 < 0) {
green3 = 0;
}
if (blue3 < 0) {
blue3 = 0;
}
if (red3 > bluemask) {
red3 = bluemask;
}
if (green3 > bluemask) {
green3 = bluemask;
}
if (blue3 > bluemask) {
blue3 = bluemask;
}
colours[i] = (red3 << redshift) | (green3 << greenshift) | blue3;
}
return colours;
/* the '+ 0.5' bit rounds our floats to ints properly */
if (red1 >= red2) {
red3 = -(factor * reddiff) - 0.5;
} else if (red1 < red2) {
red3 = factor * reddiff + 0.5;
}
if (green1 >= green2) {
green3 = -(factor * greendiff) - 0.5;
} else if (green1 < green2) {
green3 = factor * greendiff + 0.5;
}
if (blue1 >= blue2) {
blue3 = -(factor * bluediff) - 0.5;
} else if (blue1 < blue2) {
blue3 = factor * bluediff + 0.5;
}
red3 += red1;
green3 += green1;
blue3 += blue1;
if (red3 < 0) {
red3 = 0;
}
if (green3 < 0) {
green3 = 0;
}
if (blue3 < 0) {
blue3 = 0;
}
if (red3 > bluemask) {
red3 = bluemask;
}
if (green3 > bluemask) {
green3 = bluemask;
}
if (blue3 > bluemask) {
blue3 = bluemask;
}
colours[i] = (red3 << redshift) | (green3 << greenshift) | blue3;
}
return colours;
}
#ifdef BUILD_X11
long get_x11_color(const char *name)
{
XColor color;
long get_x11_color(const char *name) {
XColor color;
color.pixel = 0;
if (!XParseColor(display, DefaultColormap(display, screen), name, &color)) {
/* lets check if it's a hex colour with the # missing in front
* if yes, then do something about it */
char newname[DEFAULT_TEXT_BUFFER_SIZE];
color.pixel = 0;
if (!XParseColor(display, DefaultColormap(display, screen), name, &color)) {
/* lets check if it's a hex colour with the # missing in front
* if yes, then do something about it */
char newname[DEFAULT_TEXT_BUFFER_SIZE];
newname[0] = '#';
strncpy(&newname[1], name, DEFAULT_TEXT_BUFFER_SIZE - 1);
/* now lets try again */
if (!XParseColor(display, DefaultColormap(display, screen), &newname[0],
&color)) {
NORM_ERR("can't parse X color '%s'", name);
return 0xFF00FF;
}
}
if (!XAllocColor(display, DefaultColormap(display, screen), &color)) {
NORM_ERR("can't allocate X color '%s'", name);
}
newname[0] = '#';
strncpy(&newname[1], name, DEFAULT_TEXT_BUFFER_SIZE - 1);
/* now lets try again */
if (!XParseColor(display, DefaultColormap(display, screen), &newname[0],
&color)) {
NORM_ERR("can't parse X color '%s'", name);
return 0xFF00FF;
}
}
if (!XAllocColor(display, DefaultColormap(display, screen), &color)) {
NORM_ERR("can't allocate X color '%s'", name);
}
return (long) color.pixel;
return (long)color.pixel;
}
long get_x11_color(const std::string &colour)
{ return get_x11_color(colour.c_str()); }
long get_x11_color(const std::string &colour) {
return get_x11_color(colour.c_str());
}
#endif

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -30,6 +29,8 @@
#ifndef _COLOURS_H
#define _COLOURS_H
#include <string>
unsigned int adjust_colours(unsigned int);
unsigned long *do_gradient(int, unsigned long, unsigned long);

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -35,155 +34,159 @@
#include "text_object.h"
struct combine_data {
char *left;
char *seperation;
char *right;
char *left;
char *seperation;
char *right;
};
void parse_combine_arg(struct text_object *obj, const char *arg)
{
struct combine_data *cd;
unsigned int i,j;
unsigned int indenting = 0; //vars can be used as args for other vars
int startvar[2];
int endvar[2];
startvar[0] = endvar[0] = startvar[1] = endvar[1] = -1;
j=0;
for (i=0; arg[i] != 0 && j < 2; i++) {
if(startvar[j] == -1) {
if(arg[i] == '$') {
startvar[j] = i;
}
}else if(endvar[j] == -1) {
if(arg[i] == '{') {
indenting++;
}else if(arg[i] == '}') {
indenting--;
}
if (indenting == 0 && arg[i+1] < 48) { //<48 has 0, $, and the most used chars not used in varnames but not { or }
endvar[j]=i+1;
j++;
}
}
}
if(startvar[0] >= 0 && endvar[0] >= 0 && startvar[1] >= 0 && endvar[1] >= 0) {
cd = (struct combine_data*)malloc(sizeof(struct combine_data));
memset(cd, 0, sizeof(struct combine_data));
void parse_combine_arg(struct text_object *obj, const char *arg) {
struct combine_data *cd;
unsigned int i, j;
unsigned int indenting = 0; // vars can be used as args for other vars
int startvar[2];
int endvar[2];
startvar[0] = endvar[0] = startvar[1] = endvar[1] = -1;
j = 0;
for (i = 0; arg[i] != 0 && j < 2; i++) {
if (startvar[j] == -1) {
if (arg[i] == '$') {
startvar[j] = i;
}
} else if (endvar[j] == -1) {
if (arg[i] == '{') {
indenting++;
} else if (arg[i] == '}') {
indenting--;
}
if (indenting == 0 &&
arg[i + 1] < 48) { //<48 has 0, $, and the most used chars not used
// in varnames but not { or }
endvar[j] = i + 1;
j++;
}
}
}
if (startvar[0] >= 0 && endvar[0] >= 0 && startvar[1] >= 0 &&
endvar[1] >= 0) {
cd = (struct combine_data *)malloc(sizeof(struct combine_data));
memset(cd, 0, sizeof(struct combine_data));
cd->left = (char*)malloc(endvar[0]-startvar[0] + 1);
cd->seperation = (char*)malloc(startvar[1] - endvar[0] + 1);
cd->right= (char*)malloc(endvar[1]-startvar[1] + 1);
cd->left = (char *)malloc(endvar[0] - startvar[0] + 1);
cd->seperation = (char *)malloc(startvar[1] - endvar[0] + 1);
cd->right = (char *)malloc(endvar[1] - startvar[1] + 1);
strncpy(cd->left, arg + startvar[0], endvar[0] - startvar[0]);
cd->left[endvar[0] - startvar[0]] = 0;
strncpy(cd->left, arg + startvar[0], endvar[0] - startvar[0]);
cd->left[endvar[0] - startvar[0]] = 0;
strncpy(cd->seperation, arg + endvar[0], startvar[1] - endvar[0]);
cd->seperation[startvar[1] - endvar[0]] = 0;
strncpy(cd->seperation, arg + endvar[0], startvar[1] - endvar[0]);
cd->seperation[startvar[1] - endvar[0]] = 0;
strncpy(cd->right, arg + startvar[1], endvar[1] - startvar[1]);
cd->right[endvar[1] - startvar[1]] = 0;
strncpy(cd->right, arg + startvar[1], endvar[1] - startvar[1]);
cd->right[endvar[1] - startvar[1]] = 0;
obj->sub = (struct text_object*)malloc(sizeof(struct text_object));
extract_variable_text_internal(obj->sub, cd->left);
obj->sub->sub = (struct text_object*)malloc(sizeof(struct text_object));
extract_variable_text_internal(obj->sub->sub, cd->right);
obj->data.opaque = cd;
} else {
throw combine_needs_2_args_error();
}
obj->sub = (struct text_object *)malloc(sizeof(struct text_object));
extract_variable_text_internal(obj->sub, cd->left);
obj->sub->sub = (struct text_object *)malloc(sizeof(struct text_object));
extract_variable_text_internal(obj->sub->sub, cd->right);
obj->data.opaque = cd;
} else {
throw combine_needs_2_args_error();
}
}
void print_combine(struct text_object *obj, char *p, int p_max_size)
{
struct combine_data *cd = (struct combine_data *)obj->data.opaque;
std::vector<std::vector<char>> buf;
buf.resize(2);
buf[0].resize(max_user_text.get(*state));
buf[1].resize(max_user_text.get(*state));
int i, j;
long longest=0;
int nextstart;
int nr_rows[2];
struct llrows {
char* row;
struct llrows* next;
};
struct llrows *ll_rows[2], *current[2];
struct text_object * objsub = obj->sub;
void print_combine(struct text_object *obj, char *p, int p_max_size) {
struct combine_data *cd = (struct combine_data *)obj->data.opaque;
std::vector<std::vector<char>> buf;
buf.resize(2);
buf[0].resize(max_user_text.get(*state));
buf[1].resize(max_user_text.get(*state));
int i, j;
long longest = 0;
int nextstart;
int nr_rows[2];
struct llrows {
char *row;
struct llrows *next;
};
struct llrows *ll_rows[2], *current[2];
struct text_object *objsub = obj->sub;
if (!cd || !p_max_size)
return;
if (!cd || !p_max_size) return;
p[0]=0;
for(i=0; i<2; i++) {
nr_rows[i] = 1;
nextstart = 0;
ll_rows[i] = (struct llrows*)malloc(sizeof(struct llrows));
current[i] = ll_rows[i];
for(j=0; j<i; j++) objsub = objsub->sub;
generate_text_internal(&(buf[i][0]), max_user_text.get(*state), *objsub);
for(j=0; buf[i][j] != 0; j++) {
if(buf[i][j] == '\t') buf[i][j] = ' ';
if(buf[i][j] == '\n') buf[i][j] = 0; //the vars inside combine may not have a \n at the end
if(buf[i][j] == 2) { // \002 is used instead of \n to separate lines inside a var
buf[i][j] = 0;
current[i]->row = strdup(&(buf[i][0])+nextstart);
if(i==0 && (long)strlen(current[i]->row) > longest) longest = (long)strlen(current[i]->row);
current[i]->next = (struct llrows*)malloc(sizeof(struct llrows));
current[i] = current[i]->next;
nextstart = j + 1;
nr_rows[i]++;
}
}
current[i]->row = strdup(&(buf[i][0])+nextstart);
if(i==0 && (long)strlen(current[i]->row) > longest) longest = (long)strlen(current[i]->row);
current[i]->next = NULL;
current[i] = ll_rows[i];
}
for(j=0; j < (nr_rows[0] > nr_rows[1] ? nr_rows[0] : nr_rows[1] ); j++) {
if(current[0]) {
strcat(p, current[0]->row);
i=strlen(current[0]->row);
}else i = 0;
while(i < longest) {
strcat(p, " ");
i++;
}
if(current[1]) {
strcat(p, cd->seperation);
strcat(p, current[1]->row);
}
strcat(p, "\n");
p[0] = 0;
for (i = 0; i < 2; i++) {
nr_rows[i] = 1;
nextstart = 0;
ll_rows[i] = (struct llrows *)malloc(sizeof(struct llrows));
current[i] = ll_rows[i];
for (j = 0; j < i; j++) objsub = objsub->sub;
generate_text_internal(&(buf[i][0]), max_user_text.get(*state), *objsub);
for (j = 0; buf[i][j] != 0; j++) {
if (buf[i][j] == '\t') buf[i][j] = ' ';
if (buf[i][j] == '\n')
buf[i][j] = 0; // the vars inside combine may not have a \n at the end
if (buf[i][j] ==
2) { // \002 is used instead of \n to separate lines inside a var
buf[i][j] = 0;
current[i]->row = strdup(&(buf[i][0]) + nextstart);
if (i == 0 && (long)strlen(current[i]->row) > longest)
longest = (long)strlen(current[i]->row);
current[i]->next = (struct llrows *)malloc(sizeof(struct llrows));
current[i] = current[i]->next;
nextstart = j + 1;
nr_rows[i]++;
}
}
current[i]->row = strdup(&(buf[i][0]) + nextstart);
if (i == 0 && (long)strlen(current[i]->row) > longest)
longest = (long)strlen(current[i]->row);
current[i]->next = NULL;
current[i] = ll_rows[i];
}
for (j = 0; j < (nr_rows[0] > nr_rows[1] ? nr_rows[0] : nr_rows[1]); j++) {
if (current[0]) {
strcat(p, current[0]->row);
i = strlen(current[0]->row);
} else
i = 0;
while (i < longest) {
strcat(p, " ");
i++;
}
if (current[1]) {
strcat(p, cd->seperation);
strcat(p, current[1]->row);
}
strcat(p, "\n");
#ifdef HAVE_OPENMP
#pragma omp parallel for schedule(dynamic,10)
#pragma omp parallel for schedule(dynamic, 10)
#endif /* HAVE_OPENMP */
for(i=0; i<2; i++) if(current[i]) current[i]=current[i]->next;
}
for (i = 0; i < 2; i++)
if (current[i]) current[i] = current[i]->next;
}
#ifdef HAVE_OPENMP
#pragma omp parallel for schedule(dynamic,10)
#pragma omp parallel for schedule(dynamic, 10)
#endif /* HAVE_OPENMP */
for(i=0; i<2; i++) {
while(ll_rows[i] != NULL) {
current[i]=ll_rows[i];
free(current[i]->row);
ll_rows[i]=current[i]->next;
free(current[i]);
}
}
for (i = 0; i < 2; i++) {
while (ll_rows[i] != NULL) {
current[i] = ll_rows[i];
free(current[i]->row);
ll_rows[i] = current[i]->next;
free(current[i]);
}
}
}
void free_combine(struct text_object *obj)
{
struct combine_data *cd = (struct combine_data *)obj->data.opaque;
void free_combine(struct text_object *obj) {
struct combine_data *cd = (struct combine_data *)obj->data.opaque;
if (!cd)
return;
free(cd->left);
free(cd->seperation);
free(cd->right);
free_text_objects(obj->sub->sub);
free_and_zero(obj->sub->sub);
free_text_objects(obj->sub);
free_and_zero(obj->sub);
free_and_zero(obj->data.opaque);
if (!cd) return;
free(cd->left);
free(cd->seperation);
free(cd->right);
free_text_objects(obj->sub->sub);
free_and_zero(obj->sub->sub);
free_text_objects(obj->sub);
free_and_zero(obj->sub);
free_and_zero(obj->data.opaque);
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -28,13 +27,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <sys/socket.h>
#include "text_object.h"
#include <string>
#include "setting.hh"
#include "text_object.h"
char* readfile(const char* filename, int* total_read, char showerror);
char *readfile(const char *filename, int *total_read, char showerror);
void print_to_bytes(struct text_object *, char *, int);
@@ -60,7 +59,8 @@ void get_cpu_count(void);
double get_time(void);
/* Converts '~/...' paths to '/home/blah/...'
* It's similar to variable_substitute, except only cheques for $HOME and ~/ in path */
* It's similar to variable_substitute, except only cheques for $HOME and ~/ in
* path */
std::string to_real_path(const std::string &source);
FILE *open_file(const char *file, int *reported);
int open_fifo(const char *file, int *reported);
@@ -77,7 +77,8 @@ extern conky::simple_config_setting<bool> no_buffers;
int open_acpi_temperature(const char *name);
double get_acpi_temperature(int fd);
void get_acpi_ac_adapter(char *p_client_buffer, size_t client_buffer_size, const char *adapter);
void get_acpi_ac_adapter(char *p_client_buffer, size_t client_buffer_size,
const char *adapter);
void get_acpi_fan(char *, size_t);
void get_battery_stuff(char *buf, unsigned int n, const char *bat, int item);
int get_battery_perct(const char *bat);
@@ -123,7 +124,6 @@ void print_sysname(struct text_object *, char *, int);
void print_version(struct text_object *obj, char *p, int p_max_size);
#endif
void print_uptime(struct text_object *, char *, int);
void print_uptime_short(struct text_object *, char *, int);

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -33,11 +32,11 @@
#define __STDC_FORMAT_MACROS
#include <config.h> /* defines */
#include "common.h" /* at least for struct dns_data */
#include <sys/utsname.h> /* struct uname_s */
#include <arpa/inet.h>
#include <config.h> /* defines */
#include <sys/utsname.h> /* struct uname_s */
#include <memory>
#include "common.h" /* at least for struct dns_data */
#include "luamm.hh"
#if defined(HAS_MCHECK_H)
@@ -47,14 +46,14 @@
#undef EQUAL
#undef FALSE
#undef TRUE
#define EQUAL 0 //returnvalue of strcmp-variants when strings are equal
#define EQUAL 0 // returnvalue of strcmp-variants when strings are equal
#define FALSE 0
#define TRUE 1
#define DEFAULT_BAR_WIDTH_NO_X 10
#if !defined(__GNUC__)
# define __attribute__(x) /* nothing */
#define __attribute__(x) /* nothing */
#endif
#ifndef HAVE_STRNDUP
@@ -120,38 +119,38 @@ struct text_object;
extern conky::range_config_setting<unsigned int> text_buffer_size;
struct usr_info {
char *names;
char *times;
char *ctime;
char *terms;
int number;
char *names;
char *times;
char *ctime;
char *terms;
int number;
};
#ifdef BUILD_X11
struct monitor_info {
int number;
int current;
int number;
int current;
};
struct desktop_info {
int current;
int number;
std::string all_names;
std::string name;
int current;
int number;
std::string all_names;
std::string name;
};
struct x11_info {
struct monitor_info monitor;
struct desktop_info desktop;
struct monitor_info monitor;
struct desktop_info desktop;
};
#endif /* BUILD_X11 */
struct conftree {
char* string;
struct conftree* horz_next;
struct conftree* vert_next;
struct conftree* back;
char *string;
struct conftree *horz_next;
struct conftree *vert_next;
struct conftree *back;
};
void load_config_file();
@@ -164,96 +163,93 @@ char **get_templates(void);
/* get_battery_stuff() item selector
* needed by conky.c, linux.c and freebsd.c */
enum {
BATTERY_STATUS,
BATTERY_TIME
};
enum { BATTERY_STATUS, BATTERY_TIME };
struct information {
unsigned int mask;
unsigned int mask;
struct utsname uname_s;
struct utsname uname_s;
#if defined(__DragonFly__)
char uname_v[256]; /* with git version */
char uname_v[256]; /* with git version */
#endif
char freq[10];
char freq[10];
double uptime;
double uptime;
/* memory information in kilobytes */
unsigned long long mem, memwithbuffers, memeasyfree, memfree, memmax, memdirty;
unsigned long long swap, swapfree, swapmax;
unsigned long long bufmem, buffers, cached;
/* memory information in kilobytes */
unsigned long long mem, memwithbuffers, memeasyfree, memfree, memmax,
memdirty;
unsigned long long swap, swapfree, swapmax;
unsigned long long bufmem, buffers, cached;
unsigned short procs;
unsigned short run_procs;
unsigned short threads;
unsigned short run_threads;
unsigned short procs;
unsigned short run_procs;
unsigned short threads;
unsigned short run_threads;
float *cpu_usage;
/* struct cpu_stat cpu_summed; what the hell is this? */
int cpu_count;
float *cpu_usage;
/* struct cpu_stat cpu_summed; what the hell is this? */
int cpu_count;
float loadavg[3];
float loadavg[3];
#ifdef BUILD_XMMS2
struct xmms2_s xmms2;
struct xmms2_s xmms2;
#endif /* BUILD_XMMS2 */
#ifdef BUILD_BMPX
struct bmpx_s bmpx;
struct bmpx_s bmpx;
#endif /* BUILD_BMPX */
struct usr_info users;
struct process *cpu[10];
struct process *memu[10];
struct process *time[10];
struct usr_info users;
struct process *cpu[10];
struct process *memu[10];
struct process *time[10];
#ifdef BUILD_IOSTATS
struct process *io[10];
struct process *io[10];
#endif /* BUILD_IOSTATS */
struct process *first_process;
unsigned long looped;
struct process *first_process;
unsigned long looped;
#ifdef BUILD_X11
struct x11_info x11;
struct x11_info x11;
#endif /* BUILD_X11 */
short kflags; /* kernel settings, see enum KFLAG */
short kflags; /* kernel settings, see enum KFLAG */
#if defined(__APPLE__) && defined(__MACH__)
/* System Integrity Protection related */
struct csr_config_flags {
bool csr_allow_untrusted_kexts;
bool csr_allow_unrestricted_fs;
bool csr_allow_task_for_pid;
bool csr_allow_kernel_debugger;
bool csr_allow_apple_internal;
bool csr_allow_unrestricted_dtrace;
bool csr_allow_unrestricted_nvram;
bool csr_allow_device_configuration;
bool csr_allow_any_recovery_os;
bool csr_allow_user_approved_kexts;
};
/* SIP typedefs */
typedef csr_config_flags csr_config_flags_t;
typedef uint32_t csr_config_t;
/* SIP variables */
csr_config_t csr_config;
csr_config_flags_t csr_config_flags;
/* System Integrity Protection related */
struct csr_config_flags {
bool csr_allow_untrusted_kexts;
bool csr_allow_unrestricted_fs;
bool csr_allow_task_for_pid;
bool csr_allow_kernel_debugger;
bool csr_allow_apple_internal;
bool csr_allow_unrestricted_dtrace;
bool csr_allow_unrestricted_nvram;
bool csr_allow_device_configuration;
bool csr_allow_any_recovery_os;
bool csr_allow_user_approved_kexts;
};
/* SIP typedefs */
typedef csr_config_flags csr_config_flags_t;
typedef uint32_t csr_config_t;
/* SIP variables */
csr_config_t csr_config;
csr_config_flags_t csr_config_flags;
#endif /* defined(__APPLE__) && defined(__MACH__) */
};
class music_player_interval_setting: public conky::simple_config_setting<double> {
typedef conky::simple_config_setting<double> Base;
class music_player_interval_setting
: public conky::simple_config_setting<double> {
typedef conky::simple_config_setting<double> Base;
protected:
virtual void lua_setter(lua::state &l, bool init);
protected:
virtual void lua_setter(lua::state &l, bool init);
public:
music_player_interval_setting()
: Base("music_player_interval", 0, true)
{}
public:
music_player_interval_setting() : Base("music_player_interval", 0, true) {}
};
extern music_player_interval_setting music_player_interval;
@@ -263,31 +259,35 @@ extern conky::range_config_setting<int> diskio_avg_samples;
/* needed by linux.c and top.c -> outsource somewhere */
enum {
/* set to true if kernel uses "long" format for /proc/stats */
KFLAG_IS_LONGSTAT = 0x01,
/* set to true if kernel shows # of threads for the proc value
* in sysinfo() call */
KFLAG_PROC_IS_THREADS = 0x02
/* bits 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 available for future use */
/* KFLAG_NEXT_ONE = 0x04 */
/* set to true if kernel uses "long" format for /proc/stats */
KFLAG_IS_LONGSTAT = 0x01,
/* set to true if kernel shows # of threads for the proc value
* in sysinfo() call */
KFLAG_PROC_IS_THREADS = 0x02
/* bits 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 available for future use */
/* KFLAG_NEXT_ONE = 0x04 */
};
#define KFLAG_SETON(a) info.kflags |= a
#define KFLAG_SETOFF(a) info.kflags &= (~a)
#define KFLAG_FLIP(a) info.kflags ^= a
#define KFLAG_ISSET(a) info.kflags & a
#define KFLAG_ISSET(a) info.kflags &a
#if !defined(MAX)
#define MAX(x,y) \
({ __typeof__ (x) _x = (x); \
__typeof__ (y) _y = (y); \
_x > _y ? _x : _y;})
#define MAX(x, y) \
({ \
__typeof__(x) _x = (x); \
__typeof__(y) _y = (y); \
_x > _y ? _x : _y; \
})
#endif
#if !defined(MIN)
#define MIN(x,y) \
({ __typeof__ (x) _x = (x); \
__typeof__ (y) _y = (y); \
_x < _y ? _x : _y;})
#define MIN(x, y) \
({ \
__typeof__(x) _x = (x); \
__typeof__(y) _y = (y); \
_x < _y ? _x : _y; \
})
#endif
/* defined in conky.c, needed by top.c */
@@ -308,7 +308,7 @@ extern conky::range_config_setting<double> update_interval;
extern conky::range_config_setting<double> update_interval_on_battery;
double active_update_interval();
extern conky::range_config_setting<char> stippled_borders;
extern conky::range_config_setting<char> stippled_borders;
void set_current_text_color(long colour);
long get_current_text_color(void);
@@ -319,7 +319,7 @@ int get_total_updates(void);
/* defined in conky.c */
int spaced_print(char *, int, const char *, int, ...)
__attribute__((format(printf, 3, 5)));
__attribute__((format(printf, 3, 5)));
extern int inotify_fd;
/* defined in conky.c
@@ -353,20 +353,20 @@ extern std::string current_config;
#define NOBATTERY 0
/* to get rid of 'unused variable' warnings */
#define UNUSED(a) (void)a
#define UNUSED_ATTR __attribute__ ((unused))
#define UNUSED(a) (void)a
#define UNUSED_ATTR __attribute__((unused))
template <class T>
void free_and_zero(T *&ptr) {
if(ptr) {
free(ptr);
ptr = NULL;
}
if (ptr) {
free(ptr);
ptr = NULL;
}
}
extern std::unique_ptr<lua::state> state;
extern int argc_copy;
extern char** argv_copy;
extern char **argv_copy;
#endif /* _conky_h_ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -33,12 +32,14 @@
#include "conky.h"
struct text_object *construct_text_object(const char *s, const char *arg, long
line, void **ifblock_opaque, void *free_at_crash);
struct text_object *construct_text_object(const char *s, const char *arg,
long line, void **ifblock_opaque,
void *free_at_crash);
size_t remove_comments(char *string);
int extract_variable_text_internal(struct text_object *retval, const char *const_p);
int extract_variable_text_internal(struct text_object *retval,
const char *const_p);
void free_text_objects(struct text_object *root);

File diff suppressed because it is too large Load Diff

View File

@@ -26,10 +26,10 @@
#ifndef DARWIN_H
#define DARWIN_H
#include <sys/param.h>
#include <sys/mount.h>
#include <strings.h>
#include <stdio.h>
#include <strings.h>
#include <sys/mount.h>
#include <sys/param.h>
/*
* on versions prior to Sierra clock_gettime is not implemented.
@@ -38,10 +38,10 @@
/* only CLOCK_REALTIME and CLOCK_MONOTONIC are emulated */
#ifndef CLOCK_REALTIME
# define CLOCK_REALTIME 0
#define CLOCK_REALTIME 0
#endif
#ifndef CLOCK_MONOTONIC
# define CLOCK_MONOTONIC 1
#define CLOCK_MONOTONIC 1
#endif
int clock_gettime(int clock_id, struct timespec *ts);

View File

@@ -25,40 +25,38 @@
//
// Defines for System Integrity Protection monitoring
// based on csrstat tool by Pike R. Alpha. https://github.com/Piker-Alpha/csrstat
// based on csrstat tool by Pike R. Alpha.
// https://github.com/Piker-Alpha/csrstat
//
#ifndef DARWIN_SIP_H
#define DARWIN_SIP_H
/* Rootless configuration flags */
#define CSR_ALLOW_UNTRUSTED_KEXTS (1 << 0) // 1
#define CSR_ALLOW_UNRESTRICTED_FS (1 << 1) // 2
#define CSR_ALLOW_TASK_FOR_PID (1 << 2) // 4
#define CSR_ALLOW_KERNEL_DEBUGGER (1 << 3) // 8
#define CSR_ALLOW_APPLE_INTERNAL (1 << 4) // 16
#define CSR_ALLOW_UNRESTRICTED_DTRACE (1 << 5) // 32
#define CSR_ALLOW_UNRESTRICTED_NVRAM (1 << 6) // 64
#define CSR_ALLOW_DEVICE_CONFIGURATION (1 << 7) // 128
#define CSR_ALLOW_ANY_RECOVERY_OS (1 << 8) // 256
#define CSR_ALLOW_UNAPPROVED_KEXTS (1 << 9) // 512
#define CSR_ALLOW_UNTRUSTED_KEXTS (1 << 0) // 1
#define CSR_ALLOW_UNRESTRICTED_FS (1 << 1) // 2
#define CSR_ALLOW_TASK_FOR_PID (1 << 2) // 4
#define CSR_ALLOW_KERNEL_DEBUGGER (1 << 3) // 8
#define CSR_ALLOW_APPLE_INTERNAL (1 << 4) // 16
#define CSR_ALLOW_UNRESTRICTED_DTRACE (1 << 5) // 32
#define CSR_ALLOW_UNRESTRICTED_NVRAM (1 << 6) // 64
#define CSR_ALLOW_DEVICE_CONFIGURATION (1 << 7) // 128
#define CSR_ALLOW_ANY_RECOVERY_OS (1 << 8) // 256
#define CSR_ALLOW_UNAPPROVED_KEXTS (1 << 9) // 512
#define CSR_VALID_FLAGS (CSR_ALLOW_UNTRUSTED_KEXTS | \
CSR_ALLOW_UNRESTRICTED_FS | \
CSR_ALLOW_TASK_FOR_PID | \
CSR_ALLOW_KERNEL_DEBUGGER | \
CSR_ALLOW_APPLE_INTERNAL | \
CSR_ALLOW_UNRESTRICTED_DTRACE | \
CSR_ALLOW_UNRESTRICTED_NVRAM | \
CSR_ALLOW_DEVICE_CONFIGURATION | \
CSR_ALLOW_ANY_RECOVERY_OS | \
CSR_ALLOW_UNAPPROVED_KEXTS)
#define CSR_VALID_FLAGS \
(CSR_ALLOW_UNTRUSTED_KEXTS | CSR_ALLOW_UNRESTRICTED_FS | \
CSR_ALLOW_TASK_FOR_PID | CSR_ALLOW_KERNEL_DEBUGGER | \
CSR_ALLOW_APPLE_INTERNAL | CSR_ALLOW_UNRESTRICTED_DTRACE | \
CSR_ALLOW_UNRESTRICTED_NVRAM | CSR_ALLOW_DEVICE_CONFIGURATION | \
CSR_ALLOW_ANY_RECOVERY_OS | CSR_ALLOW_UNAPPROVED_KEXTS)
/* Syscalls */
// mark these symbols as weakly linked, as they may not be available
// at runtime on older OS X versions.
extern "C" {
int csr_get_active_config(information::csr_config_t* config) __attribute__((weak_import));
int csr_get_active_config(information::csr_config_t* config)
__attribute__((weak_import));
};
#endif

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -30,136 +29,140 @@
#include <unordered_map>
namespace conky {
namespace {
/*
* Returned when there is no data available.
* An alternative would be to throw an exception, but if we don't want to react too
* aggresively when the user e.g. uses a nonexisting variable, then returning NaN will do
* just fine.
*/
float NaN = std::numeric_limits<float>::quiet_NaN();
namespace {
/*
* Returned when there is no data available.
* An alternative would be to throw an exception, but if we don't want to react
* too aggresively when the user e.g. uses a nonexisting variable, then
* returning NaN will do just fine.
*/
float NaN = std::numeric_limits<float>::quiet_NaN();
typedef std::unordered_map<std::string, lua::cpp_function> data_sources_t;
typedef std::unordered_map<std::string, lua::cpp_function> data_sources_t;
/*
* We cannot construct this object statically, because order of object construction in
* different modules is not defined, so register_source could be called before this
* object is constructed. Therefore, we create it on the first call to register_source.
*/
data_sources_t *data_sources;
/*
* We cannot construct this object statically, because order of object
* construction in different modules is not defined, so register_source could be
* called before this object is constructed. Therefore, we create it on the
* first call to register_source.
*/
data_sources_t *data_sources;
data_source_base& get_data_source(lua::state *l)
{
if(l->gettop() != 1)
throw std::runtime_error("Wrong number of parameters");
data_source_base &get_data_source(lua::state *l) {
if (l->gettop() != 1) throw std::runtime_error("Wrong number of parameters");
l->rawgetfield(lua::REGISTRYINDEX, priv::data_source_metatable);
if(not l->getmetatable(-2) or not l->rawequal(-1, -2))
throw std::runtime_error("Invalid parameter");
l->rawgetfield(lua::REGISTRYINDEX, priv::data_source_metatable);
if (not l->getmetatable(-2) or not l->rawequal(-1, -2))
throw std::runtime_error("Invalid parameter");
return *static_cast<data_source_base *>(l->touserdata(1));
}
int data_source_asnumber(lua::state *l)
{
double x = get_data_source(l).get_number();
l->pushnumber(x);
return 1;
}
int data_source_astext(lua::state *l)
{
std::string x = get_data_source(l).get_text();
l->pushstring(x);
return 1;
}
const char data_source__index[] =
"local table, key = ...;\n"
"if key == 'num' then\n"
" return conky.asnumber(table);\n"
"elseif key == 'text' then\n"
" return conky.astext(table);\n"
"else\n"
" print(string.format([[Invalid data source operation: '%s']], key));\n"
" return 0/0;\n"
"end\n";
}
namespace priv {
void do_register_data_source(const std::string &name, const lua::cpp_function &fn)
{
struct data_source_constructor {
data_source_constructor() { data_sources = new data_sources_t(); }
~data_source_constructor() { delete data_sources; data_sources = NULL; }
};
static data_source_constructor constructor;
bool inserted = data_sources->insert({name, fn}).second;
if(not inserted)
throw std::logic_error("Data source with name '" + name + "' already registered");
}
disabled_data_source::disabled_data_source(lua::state *l, const std::string &name,
const std::string &setting)
: simple_numeric_source<float>(l, name, &NaN)
{
// XXX some generic way of reporting errors? NORM_ERR?
std::cerr << "Support for variable '" << name
<< "' has been disabled during compilation. Please recompile with '"
<< setting << "'" << std::endl;
}
}
double data_source_base::get_number() const
{ return NaN; }
std::string data_source_base::get_text() const
{
std::ostringstream s;
s << get_number();
return s.str();
}
register_disabled_data_source::register_disabled_data_source(const std::string &name,
const std::string &setting)
: register_data_source<priv::disabled_data_source>(name, setting)
{}
// at least one data source should always be registered, so data_sources will not be null
void export_data_sources(lua::state &l)
{
lua::stack_sentry s(l);
l.checkstack(2);
l.newmetatable(priv::data_source_metatable); {
l.pushboolean(false);
l.rawsetfield(-2, "__metatable");
l.pushdestructor<data_source_base>();
l.rawsetfield(-2, "__gc");
l.loadstring(data_source__index);
l.rawsetfield(-2, "__index");
} l.pop();
l.newtable(); {
for(auto i = data_sources->begin(); i != data_sources->end(); ++i) {
l.pushfunction(i->second);
l.rawsetfield(-2, i->first.c_str());
}
} l.rawsetfield(-2, "variables");
l.pushfunction(data_source_asnumber);
l.rawsetfield(-2, "asnumber");
l.pushfunction(data_source_astext);
l.rawsetfield(-2, "astext");
}
return *static_cast<data_source_base *>(l->touserdata(1));
}
/////////// example data sources, remove after real data sources are available ///////
int data_source_asnumber(lua::state *l) {
double x = get_data_source(l).get_number();
l->pushnumber(x);
return 1;
}
int data_source_astext(lua::state *l) {
std::string x = get_data_source(l).get_text();
l->pushstring(x);
return 1;
}
const char data_source__index[] =
"local table, key = ...;\n"
"if key == 'num' then\n"
" return conky.asnumber(table);\n"
"elseif key == 'text' then\n"
" return conky.astext(table);\n"
"else\n"
" print(string.format([[Invalid data source operation: '%s']], key));\n"
" return 0/0;\n"
"end\n";
} // namespace
namespace priv {
void do_register_data_source(const std::string &name,
const lua::cpp_function &fn) {
struct data_source_constructor {
data_source_constructor() { data_sources = new data_sources_t(); }
~data_source_constructor() {
delete data_sources;
data_sources = NULL;
}
};
static data_source_constructor constructor;
bool inserted = data_sources->insert({name, fn}).second;
if (not inserted)
throw std::logic_error("Data source with name '" + name +
"' already registered");
}
disabled_data_source::disabled_data_source(lua::state *l,
const std::string &name,
const std::string &setting)
: simple_numeric_source<float>(l, name, &NaN) {
// XXX some generic way of reporting errors? NORM_ERR?
std::cerr << "Support for variable '" << name
<< "' has been disabled during compilation. Please recompile with '"
<< setting << "'" << std::endl;
}
} // namespace priv
double data_source_base::get_number() const { return NaN; }
std::string data_source_base::get_text() const {
std::ostringstream s;
s << get_number();
return s.str();
}
register_disabled_data_source::register_disabled_data_source(
const std::string &name, const std::string &setting)
: register_data_source<priv::disabled_data_source>(name, setting) {}
// at least one data source should always be registered, so data_sources will
// not be null
void export_data_sources(lua::state &l) {
lua::stack_sentry s(l);
l.checkstack(2);
l.newmetatable(priv::data_source_metatable);
{
l.pushboolean(false);
l.rawsetfield(-2, "__metatable");
l.pushdestructor<data_source_base>();
l.rawsetfield(-2, "__gc");
l.loadstring(data_source__index);
l.rawsetfield(-2, "__index");
}
l.pop();
l.newtable();
{
for (auto i = data_sources->begin(); i != data_sources->end(); ++i) {
l.pushfunction(i->second);
l.rawsetfield(-2, i->first.c_str());
}
}
l.rawsetfield(-2, "variables");
l.pushfunction(data_source_asnumber);
l.rawsetfield(-2, "asnumber");
l.pushfunction(data_source_astext);
l.rawsetfield(-2, "astext");
}
} // namespace conky
/////////// example data sources, remove after real data sources are available
//////////
int asdf_ = 47;
conky::register_data_source<conky::simple_numeric_source<int>> asdf("asdf", &asdf_);
conky::register_data_source<conky::simple_numeric_source<int>> asdf("asdf",
&asdf_);
conky::register_disabled_data_source zxcv("zxcv", "BUILD_ZXCV");

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -32,107 +31,112 @@
namespace conky {
/*
* A base class for all data sources.
* API consists of two functions:
* - get_number should return numeric representation of the data (if available). This can
* then be used when drawing graphs, bars, ... The default implementation returns NaN.
* - get_text should return textual representation of the data. This is used when simple
* displaying the value of the data source. The default implementation converts
* get_number() to a string, but you can override to return anything (e.g. add units)
*/
class data_source_base {
public:
const std::string name;
/*
* A base class for all data sources.
* API consists of two functions:
* - get_number should return numeric representation of the data (if available).
* This can then be used when drawing graphs, bars, ... The default
* implementation returns NaN.
* - get_text should return textual representation of the data. This is used
* when simple displaying the value of the data source. The default
* implementation converts get_number() to a string, but you can override to
* return anything (e.g. add units)
*/
class data_source_base {
public:
const std::string name;
data_source_base(const std::string &name_)
: name(name_)
{}
data_source_base(const std::string &name_) : name(name_) {}
virtual ~data_source_base() {}
virtual double get_number() const;
virtual std::string get_text() const;
};
virtual ~data_source_base() {}
virtual double get_number() const;
virtual std::string get_text() const;
};
/*
* A simple data source that returns the value of some variable. It ignores the lua table.
* The source variable can be specified as a fixed parameter to the register_data_source
* constructor, or one can create a subclass and then set the source from the subclass
* constructor.
*/
template<typename T>
class simple_numeric_source: public data_source_base {
static_assert(std::is_convertible<T, double>::value, "T must be convertible to double");
/*
* A simple data source that returns the value of some variable. It ignores the
* lua table. The source variable can be specified as a fixed parameter to the
* register_data_source constructor, or one can create a subclass and then set
* the source from the subclass constructor.
*/
template <typename T>
class simple_numeric_source : public data_source_base {
static_assert(std::is_convertible<T, double>::value,
"T must be convertible to double");
const T *source;
public:
simple_numeric_source(lua::state *, const std::string &name_, const T *source_)
: data_source_base(name_), source(source_)
{}
const T *source;
virtual double get_number() const
{ return *source; }
};
public:
simple_numeric_source(lua::state *, const std::string &name_,
const T *source_)
: data_source_base(name_), source(source_) {}
/*
* This is a part of the implementation, but it cannot be in .cc file because the template
* functions below call it
*/
namespace priv {
const char data_source_metatable[] = "conky::data_source_metatable";
virtual double get_number() const { return *source; }
};
void do_register_data_source(const std::string &name, const lua::cpp_function &fn);
/*
* This is a part of the implementation, but it cannot be in .cc file because
* the template functions below call it
*/
namespace priv {
const char data_source_metatable[] = "conky::data_source_metatable";
class disabled_data_source: public simple_numeric_source<float> {
public:
disabled_data_source(lua::state *l, const std::string &name,
const std::string &setting);
};
void do_register_data_source(const std::string &name,
const lua::cpp_function &fn);
}
class disabled_data_source : public simple_numeric_source<float> {
public:
disabled_data_source(lua::state *l, const std::string &name,
const std::string &setting);
};
/*
* Declaring an object of this type at global scope will register a data source with the
* given name. Any additional parameters are passed on to the data source constructor.
*/
template<typename T>
class register_data_source {
template<typename... Args>
static int factory(lua::state *l, const std::string &name, const Args&... args)
{
T *t = static_cast<T *>(l->newuserdata(sizeof(T)));
l->insert(1);
new(t) T(l, name, args...);
l->settop(1);
l->rawgetfield(lua::REGISTRYINDEX, priv::data_source_metatable);
l->setmetatable(-2);
return 1;
}
} // namespace priv
public:
template<typename... Args>
register_data_source(const std::string &name, Args&&... args)
{
priv::do_register_data_source( name, std::bind(&factory<Args...>,
std::placeholders::_1, name, args...
));
}
};
/*
* Declaring an object of this type at global scope will register a data source
* with the given name. Any additional parameters are passed on to the data
* source constructor.
*/
template <typename T>
class register_data_source {
template <typename... Args>
static int factory(lua::state *l, const std::string &name,
const Args &... args) {
T *t = static_cast<T *>(l->newuserdata(sizeof(T)));
l->insert(1);
new (t) T(l, name, args...);
l->settop(1);
l->rawgetfield(lua::REGISTRYINDEX, priv::data_source_metatable);
l->setmetatable(-2);
return 1;
}
/*
* Use this to declare a data source that has been disabled during compilation. We can then
* print a nice error message telling the used which setting to enable.
*/
class register_disabled_data_source: public register_data_source<priv::disabled_data_source> {
public:
register_disabled_data_source(const std::string &name, const std::string &setting);
};
public:
template <typename... Args>
register_data_source(const std::string &name, Args &&... args) {
priv::do_register_data_source(
name,
std::bind(&factory<Args...>, std::placeholders::_1, name, args...));
}
};
/*
* It expects to have a table at the top of lua stack. It then exports all the data sources
* into that table (actually, into a "variables" subtable).
*/
void export_data_sources(lua::state &l);
}
/*
* Use this to declare a data source that has been disabled during compilation.
* We can then print a nice error message telling the used which setting to
* enable.
*/
class register_disabled_data_source
: public register_data_source<priv::disabled_data_source> {
public:
register_disabled_data_source(const std::string &name,
const std::string &setting);
};
/*
* It expects to have a table at the top of lua stack. It then exports all the
* data sources into that table (actually, into a "variables" subtable).
*/
void export_data_sources(lua::state &l);
} // namespace conky
#endif /* DATA_SOURCE_HH */

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -28,99 +27,100 @@
*
*/
#include "config.h"
#include "conky.h" /* text_buffer_size */
#include "core.h"
#include "logging.h"
#include "diskio.h"
#include "common.h"
#include "specials.h"
#include "text_object.h"
#include <stdlib.h>
#include <sys/stat.h>
#include <vector>
#include "common.h"
#include "config.h"
#include "conky.h" /* text_buffer_size */
#include "core.h"
#include "logging.h"
#include "specials.h"
#include "text_object.h"
/* this is the root of all per disk stats,
* also containing the totals. */
struct diskio_stat stats;
void clear_diskio_stats(void)
{
struct diskio_stat *cur;
while (stats.next) {
cur = stats.next;
stats.next = stats.next->next;
free_and_zero(cur->dev);
free(cur);
}
void clear_diskio_stats(void) {
struct diskio_stat *cur;
while (stats.next) {
cur = stats.next;
stats.next = stats.next->next;
free_and_zero(cur->dev);
free(cur);
}
}
struct diskio_stat *prepare_diskio_stat(const char *s)
{
struct stat sb;
std::vector<char> stat_name(text_buffer_size.get(*state)), device_name(text_buffer_size.get(*state)), device_s(text_buffer_size.get(*state));
struct diskio_stat *cur = &stats;
char * rpbuf;
struct diskio_stat *prepare_diskio_stat(const char *s) {
struct stat sb;
std::vector<char> stat_name(text_buffer_size.get(*state)),
device_name(text_buffer_size.get(*state)),
device_s(text_buffer_size.get(*state));
struct diskio_stat *cur = &stats;
char *rpbuf;
if (!s) {
return &stats;
}
if (!s) {
return &stats;
}
if (strncmp(s, "label:", 6) == 0) {
snprintf(&(device_name[0]), text_buffer_size.get(*state), "/dev/disk/by-label/%s", s+6);
rpbuf = realpath(&device_name[0], NULL);
} else {
rpbuf = realpath(s, NULL);
}
if (strncmp(s, "label:", 6) == 0) {
snprintf(&(device_name[0]), text_buffer_size.get(*state),
"/dev/disk/by-label/%s", s + 6);
rpbuf = realpath(&device_name[0], NULL);
} else {
rpbuf = realpath(s, NULL);
}
if (rpbuf) {
strncpy(&device_s[0], rpbuf, text_buffer_size.get(*state));
free(rpbuf);
} else {
strncpy(&device_s[0], s, text_buffer_size.get(*state));
}
if (rpbuf) {
strncpy(&device_s[0], rpbuf, text_buffer_size.get(*state));
free(rpbuf);
} else {
strncpy(&device_s[0], s, text_buffer_size.get(*state));
}
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__linux__)
if (strncmp(&device_s[0], "/dev/", 5) == 0) {
device_s.erase(device_s.begin(), device_s.begin()+5);
}
if (strncmp(&device_s[0], "/dev/", 5) == 0) {
device_s.erase(device_s.begin(), device_s.begin() + 5);
}
#endif
strncpy(&(device_name[0]), &device_s[0], text_buffer_size.get(*state));
strncpy(&(device_name[0]), &device_s[0], text_buffer_size.get(*state));
#if !defined(__sun)
/*
* On Solaris we currently don't use the name of disk's special file so
* this test is useless.
*/
snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s", &(device_name[0]));
/*
* On Solaris we currently don't use the name of disk's special file so
* this test is useless.
*/
snprintf(&(stat_name[0]), text_buffer_size.get(*state), "/dev/%s",
&(device_name[0]));
if (stat(&(stat_name[0]), &sb) || !S_ISBLK(sb.st_mode)) {
NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
}
if (stat(&(stat_name[0]), &sb) || !S_ISBLK(sb.st_mode)) {
NORM_ERR("diskio device '%s' does not exist", &device_s[0]);
}
#endif
/* lookup existing */
while (cur->next) {
cur = cur->next;
if (!strcmp(cur->dev, &(device_name[0]))) {
return cur;
}
}
/* lookup existing */
while (cur->next) {
cur = cur->next;
if (!strcmp(cur->dev, &(device_name[0]))) {
return cur;
}
}
/* no existing found, make a new one */
cur->next = new diskio_stat;
cur = cur->next;
cur->dev = strndup(&(device_s[0]), text_buffer_size.get(*state));
cur->last = UINT_MAX;
cur->last_read = UINT_MAX;
cur->last_write = UINT_MAX;
/* no existing found, make a new one */
cur->next = new diskio_stat;
cur = cur->next;
cur->dev = strndup(&(device_s[0]), text_buffer_size.get(*state));
cur->last = UINT_MAX;
cur->last_read = UINT_MAX;
cur->last_write = UINT_MAX;
return cur;
return cur;
}
void parse_diskio_arg(struct text_object *obj, const char *arg)
{
obj->data.opaque = prepare_diskio_stat(arg);
void parse_diskio_arg(struct text_object *obj, const char *arg) {
obj->data.opaque = prepare_diskio_stat(arg);
}
/* dir indicates the direction:
@@ -128,113 +128,103 @@ void parse_diskio_arg(struct text_object *obj, const char *arg)
* 0: read + write
* 1: write
*/
static void print_diskio_dir(struct text_object *obj, int dir, char *p, int p_max_size)
{
struct diskio_stat *diskio = (struct diskio_stat *)obj->data.opaque;
double val;
static void print_diskio_dir(struct text_object *obj, int dir, char *p,
int p_max_size) {
struct diskio_stat *diskio = (struct diskio_stat *)obj->data.opaque;
double val;
if (!diskio)
return;
if (!diskio) return;
if (dir < 0)
val = diskio->current_read;
else if (dir == 0)
val = diskio->current;
else
val = diskio->current_write;
if (dir < 0)
val = diskio->current_read;
else if (dir == 0)
val = diskio->current;
else
val = diskio->current_write;
/* TODO: move this correction from kB to kB/s elsewhere
* (or get rid of it??) */
human_readable((val / active_update_interval()) * 1024LL, p, p_max_size);
/* TODO: move this correction from kB to kB/s elsewhere
* (or get rid of it??) */
human_readable((val / active_update_interval()) * 1024LL, p, p_max_size);
}
void print_diskio(struct text_object *obj, char *p, int p_max_size)
{
print_diskio_dir(obj, 0, p, p_max_size);
void print_diskio(struct text_object *obj, char *p, int p_max_size) {
print_diskio_dir(obj, 0, p, p_max_size);
}
void print_diskio_read(struct text_object *obj, char *p, int p_max_size)
{
print_diskio_dir(obj, -1, p, p_max_size);
void print_diskio_read(struct text_object *obj, char *p, int p_max_size) {
print_diskio_dir(obj, -1, p, p_max_size);
}
void print_diskio_write(struct text_object *obj, char *p, int p_max_size)
{
print_diskio_dir(obj, 1, p, p_max_size);
void print_diskio_write(struct text_object *obj, char *p, int p_max_size) {
print_diskio_dir(obj, 1, p, p_max_size);
}
#ifdef BUILD_X11
void parse_diskiograph_arg(struct text_object *obj, const char *arg)
{
char *buf = 0;
buf = scan_graph(obj, arg, 0);
void parse_diskiograph_arg(struct text_object *obj, const char *arg) {
char *buf = 0;
buf = scan_graph(obj, arg, 0);
obj->data.opaque = prepare_diskio_stat(dev_name(buf));
free_and_zero(buf);
obj->data.opaque = prepare_diskio_stat(dev_name(buf));
free_and_zero(buf);
}
double diskiographval(struct text_object *obj)
{
struct diskio_stat *diskio = (struct diskio_stat *)obj->data.opaque;
double diskiographval(struct text_object *obj) {
struct diskio_stat *diskio = (struct diskio_stat *)obj->data.opaque;
return (diskio ? diskio->current : 0);
return (diskio ? diskio->current : 0);
}
double diskiographval_read(struct text_object *obj)
{
struct diskio_stat *diskio = (struct diskio_stat *)obj->data.opaque;
double diskiographval_read(struct text_object *obj) {
struct diskio_stat *diskio = (struct diskio_stat *)obj->data.opaque;
return (diskio ? diskio->current_read : 0);
return (diskio ? diskio->current_read : 0);
}
double diskiographval_write(struct text_object *obj)
{
struct diskio_stat *diskio = (struct diskio_stat *)obj->data.opaque;
double diskiographval_write(struct text_object *obj) {
struct diskio_stat *diskio = (struct diskio_stat *)obj->data.opaque;
return (diskio ? diskio->current_write : 0);
return (diskio ? diskio->current_write : 0);
}
#endif /* BUILD_X11 */
void update_diskio_values(struct diskio_stat *ds,
unsigned int reads, unsigned int writes)
{
int i;
double sum=0, sum_r=0, sum_w=0;
void update_diskio_values(struct diskio_stat *ds, unsigned int reads,
unsigned int writes) {
int i;
double sum = 0, sum_r = 0, sum_w = 0;
if (reads < ds->last_read || writes < ds->last_write) {
/* counter overflow or reset - rebase to sane values */
ds->last = reads+writes;
ds->last_read = reads;
ds->last_write = writes;
}
/* since the values in /proc/diskstats are absolute, we have to subtract
* our last reading. The numbers stand for "sectors read", and we therefore
* have to divide by two to get KB */
ds->sample_read[0] = (reads - ds->last_read) / 2;
ds->sample_write[0] = (writes - ds->last_write) / 2;
ds->sample[0] = ds->sample_read[0] + ds->sample_write[0];
if (reads < ds->last_read || writes < ds->last_write) {
/* counter overflow or reset - rebase to sane values */
ds->last = reads + writes;
ds->last_read = reads;
ds->last_write = writes;
}
/* since the values in /proc/diskstats are absolute, we have to subtract
* our last reading. The numbers stand for "sectors read", and we therefore
* have to divide by two to get KB */
ds->sample_read[0] = (reads - ds->last_read) / 2;
ds->sample_write[0] = (writes - ds->last_write) / 2;
ds->sample[0] = ds->sample_read[0] + ds->sample_write[0];
/* compute averages */
int samples = diskio_avg_samples.get(*state);
for (i = 0; i < samples; i++) {
sum += ds->sample[i];
sum_r += ds->sample_read[i];
sum_w += ds->sample_write[i];
}
ds->current = sum / (double) samples;
ds->current_read = sum_r / (double) samples;
ds->current_write = sum_w / (double) samples;
/* compute averages */
int samples = diskio_avg_samples.get(*state);
for (i = 0; i < samples; i++) {
sum += ds->sample[i];
sum_r += ds->sample_read[i];
sum_w += ds->sample_write[i];
}
ds->current = sum / (double)samples;
ds->current_read = sum_r / (double)samples;
ds->current_write = sum_w / (double)samples;
/* shift sample history */
for (i = samples-1; i > 0; i--) {
ds->sample[i] = ds->sample[i-1];
ds->sample_read[i] = ds->sample_read[i-1];
ds->sample_write[i] = ds->sample_write[i-1];
}
/* shift sample history */
for (i = samples - 1; i > 0; i--) {
ds->sample[i] = ds->sample[i - 1];
ds->sample_read[i] = ds->sample_read[i - 1];
ds->sample_write[i] = ds->sample_write[i - 1];
}
/* save last */
ds->last_read = reads;
ds->last_write = writes;
ds->last = ds->last_read + ds->last_write;
/* save last */
ds->last_read = reads;
ds->last_write = writes;
ds->last = ds->last_read + ds->last_write;
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -32,32 +31,33 @@
#define DISKIO_H_
#include <limits.h>
#include <cstring>
struct diskio_stat {
diskio_stat() :
next(NULL),
current(0),
current_read(0),
current_write(0),
last(UINT_MAX),
last_read(UINT_MAX),
last_write(UINT_MAX)
{
memset(sample, 0, sizeof(sample) / sizeof(sample[0]));
memset(sample_read, 0, sizeof(sample_read) / sizeof(sample_read[0]));
memset(sample_write, 0, sizeof(sample_write) / sizeof(sample_write[0]));
}
struct diskio_stat *next;
char *dev;
double sample[15];
double sample_read[15];
double sample_write[15];
double current;
double current_read;
double current_write;
double last;
double last_read;
double last_write;
diskio_stat()
: next(nullptr),
current(0),
current_read(0),
current_write(0),
last(UINT_MAX),
last_read(UINT_MAX),
last_write(UINT_MAX) {
std::memset(sample, 0, sizeof(sample) / sizeof(sample[0]));
std::memset(sample_read, 0, sizeof(sample_read) / sizeof(sample_read[0]));
std::memset(sample_write, 0,
sizeof(sample_write) / sizeof(sample_write[0]));
}
struct diskio_stat *next;
char *dev;
double sample[15];
double sample_read[15];
double sample_write[15];
double current;
double current_read;
double current_write;
double last;
double last_read;
double last_write;
};
extern struct diskio_stat stats;

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,14 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*- */
/* */
#ifndef DRAGONFLY_H_
#define DRAGONFLY_H_
#include "common.h"
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/ucred.h>
#include <fcntl.h>
#include <kvm.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/ucred.h>
#include "common.h"
#if (defined(i386) || defined(__i386__))
#include <machine/apm_bios.h>
#endif /* i386 || __i386__ */

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -50,41 +49,36 @@
#endif
struct _entropy {
_entropy() : avail(0), poolsize(0) {}
unsigned int avail;
unsigned int poolsize;
_entropy() : avail(0), poolsize(0) {}
unsigned int avail;
unsigned int poolsize;
};
static _entropy entropy;
int update_entropy(void)
{
get_entropy_avail(&entropy.avail);
get_entropy_poolsize(&entropy.poolsize);
return 0;
int update_entropy(void) {
get_entropy_avail(&entropy.avail);
get_entropy_poolsize(&entropy.poolsize);
return 0;
}
void print_entropy_avail(struct text_object *obj, char *p, int p_max_size)
{
(void)obj;
snprintf(p, p_max_size, "%u", entropy.avail);
void print_entropy_avail(struct text_object *obj, char *p, int p_max_size) {
(void)obj;
snprintf(p, p_max_size, "%u", entropy.avail);
}
uint8_t entropy_percentage(struct text_object *obj)
{
(void)obj;
return round_to_int((double)entropy.avail * 100.0 / (double)entropy.poolsize);
uint8_t entropy_percentage(struct text_object *obj) {
(void)obj;
return round_to_int((double)entropy.avail * 100.0 / (double)entropy.poolsize);
}
void print_entropy_poolsize(struct text_object *obj, char *p, int p_max_size)
{
(void)obj;
snprintf(p, p_max_size, "%u", entropy.poolsize);
void print_entropy_poolsize(struct text_object *obj, char *p, int p_max_size) {
(void)obj;
snprintf(p, p_max_size, "%u", entropy.poolsize);
}
double entropy_barval(struct text_object *obj)
{
(void)obj;
double entropy_barval(struct text_object *obj) {
(void)obj;
return (double)entropy.avail / entropy.poolsize;
return (double)entropy.avail / entropy.poolsize;
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*

View File

@@ -1,10 +1,9 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Copyright (c) 2008 Asbjørn Zweidorff Kjær
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -23,17 +22,17 @@
*/
#include "eve.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <utime.h>
#include <string>
#include "config.h"
#include "logging.h"
#include "text_object.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <utime.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
@@ -50,420 +49,402 @@
#define EVE_UPDATE_DELAY 60
typedef struct {
char *charid;
char *skillname;
char *time;
char *lastOutput;
char *charid;
char *skillname;
char *time;
char *lastOutput;
struct tm ends;
struct tm cache;
struct tm ends;
struct tm cache;
time_t delay;
time_t delay;
int isTraining;
int isTraining;
int level;
int skill;
int level;
int skill;
} Character;
struct xmlData {
char *data;
size_t size;
char *data;
size_t size;
};
struct eve_data {
char apiVCode[65];
char charid[21];
char apiKeyID[21];
char apiVCode[65];
char charid[21];
char apiKeyID[21];
};
int num_chars = 0;
Character eveCharacters[MAXCHARS];
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
size_t realsize = 0;
struct xmlData *data = 0;
data = (struct xmlData *)stream;
realsize = size * nmemb;
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) {
size_t realsize = 0;
struct xmlData *data = 0;
data = (struct xmlData *)stream;
realsize = size * nmemb;
data->data = (char *)realloc(data->data, data->size + realsize + 1);
if (data->data) {
memcpy(&(data->data[data->size]), ptr, realsize);
data->size += realsize;
data->data[data->size] = '\0';
}
data->data = (char *)realloc(data->data, data->size + realsize + 1);
if (data->data) {
memcpy(&(data->data[data->size]), ptr, realsize);
data->size += realsize;
data->data[data->size] = '\0';
}
return realsize;
return realsize;
}
int parseTrainingXml(char *data, Character * s)
{
char *skill, *level, *ends, *cache, *isTraining;
xmlNodePtr n;
xmlDocPtr doc = 0;
xmlNodePtr root = 0;
struct tm end_tm, cache_tm;
int parseTrainingXml(char *data, Character *s) {
char *skill, *level, *ends, *cache, *isTraining;
xmlNodePtr n;
xmlDocPtr doc = 0;
xmlNodePtr root = 0;
struct tm end_tm, cache_tm;
// initialize the time structs
time_t now = time(NULL);
localtime_r(&now, &end_tm);
localtime_r(&now, &cache_tm);
// initialize the time structs
time_t now = time(NULL);
localtime_r(&now, &end_tm);
localtime_r(&now, &cache_tm);
if (!data)
return 1;
if (!data) return 1;
doc = xmlReadMemory(data, strlen(data), "", NULL, XML_PARSE_RECOVER);
root = xmlDocGetRootElement(doc);
doc = xmlReadMemory(data, strlen(data), "", NULL, XML_PARSE_RECOVER);
root = xmlDocGetRootElement(doc);
for (n = root->children; n; n = n->next) {
if (n->type == XML_ELEMENT_NODE) {
if (!strcasecmp((const char *)n->name, "error")) {
return 1;
} else if (!strcasecmp((const char *)n->name, "result")) {
xmlNodePtr c;
for (c = n->children; c; c = c->next) {
if (!strcasecmp((const char *)c->name, "SkillInTraining")) {
isTraining = (char *)c->children->content;
} else if (!strcasecmp((const char *)c->name, "trainingEndTime")) {
ends = (char *)c->children->content;
} else if (!strcasecmp((const char *)c->name, "trainingTypeID")) {
if (c->children->content)
skill = (char *)c->children->content;
} else if (!strcasecmp((const char *)c->name, "trainingToLevel")) {
level = (char *)c->children->content;
}
}
} else if (!strcasecmp((const char *)n->name, "cachedUntil")) {
cache = (char *)n->children->content;
}
}
}
for (n = root->children; n; n = n->next) {
if (n->type == XML_ELEMENT_NODE) {
if (!strcasecmp((const char *)n->name, "error")) {
return 1;
} else if (!strcasecmp((const char *)n->name, "result")) {
xmlNodePtr c;
for (c = n->children; c; c = c->next) {
if (!strcasecmp((const char *)c->name, "SkillInTraining")) {
isTraining = (char *)c->children->content;
} else if (!strcasecmp((const char *)c->name, "trainingEndTime")) {
ends = (char *)c->children->content;
} else if (!strcasecmp((const char *)c->name, "trainingTypeID")) {
if (c->children->content) skill = (char *)c->children->content;
} else if (!strcasecmp((const char *)c->name, "trainingToLevel")) {
level = (char *)c->children->content;
}
}
} else if (!strcasecmp((const char *)n->name, "cachedUntil")) {
cache = (char *)n->children->content;
}
}
}
s->isTraining = atoi(isTraining);
s->skill = atoi(skill);
s->level = atoi(level);
s->isTraining = atoi(isTraining);
s->skill = atoi(skill);
s->level = atoi(level);
strptime(cache, "%Y-%m-%d %H:%M:%S", &cache_tm);
s->cache = cache_tm;
strptime(cache, "%Y-%m-%d %H:%M:%S", &cache_tm);
s->cache = cache_tm;
if (s->isTraining) {
strptime(ends, "%Y-%m-%d %H:%M:%S", &end_tm);
s->ends = end_tm;
}
if (s->isTraining) {
strptime(ends, "%Y-%m-%d %H:%M:%S", &end_tm);
s->ends = end_tm;
}
xmlFreeDoc(doc);
return 0;
xmlFreeDoc(doc);
return 0;
}
static char *getXmlFromAPI(const char *apiKeyID, const char *apiVCode, const char *charid, const char *url)
{
struct curl_httppost *post = NULL;
struct curl_httppost *last = NULL;
struct xmlData chr;
char *content;
CURL *curl_handle;
int rc = 0;
static char *getXmlFromAPI(const char *apiKeyID, const char *apiVCode,
const char *charid, const char *url) {
struct curl_httppost *post = NULL;
struct curl_httppost *last = NULL;
struct xmlData chr;
char *content;
CURL *curl_handle;
int rc = 0;
chr.data = NULL;
chr.size = 0;
chr.data = NULL;
chr.size = 0;
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chr);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chr);
std::string real_url = std::string(url, strlen(url));
if (apiKeyID && apiVCode && charid) {
real_url += "?keyID=";
real_url += curl_easy_escape(curl_handle, apiKeyID, strlen(apiKeyID));
real_url += "&vCode=";
real_url += curl_easy_escape(curl_handle, apiVCode, strlen(apiVCode));
real_url += "&characterID=";
real_url += curl_easy_escape(curl_handle, charid, strlen(charid));
}
std::string real_url = std::string(url, strlen(url));
if (apiKeyID && apiVCode && charid) {
real_url += "?keyID=";
real_url += curl_easy_escape(curl_handle, apiKeyID, strlen(apiKeyID));
real_url += "&vCode=";
real_url += curl_easy_escape(curl_handle, apiVCode, strlen(apiVCode));
real_url += "&characterID=";
real_url += curl_easy_escape(curl_handle, charid, strlen(charid));
}
curl_easy_setopt(curl_handle, CURLOPT_URL, real_url.c_str());
curl_easy_setopt(curl_handle, CURLOPT_URL, real_url.c_str());
rc = curl_easy_perform(curl_handle);
rc = curl_easy_perform(curl_handle);
if (chr.data == NULL) {
return NULL;
}
if (chr.data == NULL) {
return NULL;
}
content = strdup(chr.data);
curl_easy_cleanup(curl_handle);
content = strdup(chr.data);
curl_easy_cleanup(curl_handle);
return content;
return content;
}
static void init_eve(void)
{
int i;
static void init_eve(void) {
int i;
for (i = 0; i < MAXCHARS; i++) {
eveCharacters[i].charid = NULL;
eveCharacters[i].skillname = NULL;
eveCharacters[i].time = NULL;
eveCharacters[i].level = 0;
eveCharacters[i].skill = 0;
eveCharacters[i].delay = 0;
}
for (i = 0; i < MAXCHARS; i++) {
eveCharacters[i].charid = NULL;
eveCharacters[i].skillname = NULL;
eveCharacters[i].time = NULL;
eveCharacters[i].level = 0;
eveCharacters[i].skill = 0;
eveCharacters[i].delay = 0;
}
}
static int isCacheValid(struct tm cached)
{
//struct timeval tv;
//struct timezone tz;
double offset = 0;
time_t now = time(NULL);
time_t cache = 0;
double diff = 0;
static int isCacheValid(struct tm cached) {
// struct timeval tv;
// struct timezone tz;
double offset = 0;
time_t now = time(NULL);
time_t cache = 0;
double diff = 0;
//gettimeofday(&tv, &tz);
//tzset();
struct tm * lt = localtime(&now);
// gettimeofday(&tv, &tz);
// tzset();
struct tm *lt = localtime(&now);
offset = (double)(-lt->tm_gmtoff);
cache = mktime(&cached);
diff = difftime(cache, now);
offset = (double)(-lt->tm_gmtoff);
cache = mktime(&cached);
diff = difftime(cache, now);
if (diff < offset)
return 0;
else
return 1;
if (diff < offset)
return 0;
else
return 1;
}
static char *formatTime(struct tm *ends)
{
//struct timeval tv;
//struct timezone tz;
double offset = 0;
time_t now = time(NULL);
time_t tEnds = 0;
long lin = 0;
long lie = 0;
long diff = 0;
//gettimeofday(&tv, &tz);
struct tm * lt = localtime(&now);
static char *formatTime(struct tm *ends) {
// struct timeval tv;
// struct timezone tz;
double offset = 0;
time_t now = time(NULL);
time_t tEnds = 0;
long lin = 0;
long lie = 0;
long diff = 0;
offset = (double)(-lt->tm_gmtoff);
tEnds = mktime(ends);
lin = (long)now;
lin += (long)offset;
lie = (long)tEnds;
diff = (lie - lin);
// gettimeofday(&tv, &tz);
struct tm *lt = localtime(&now);
if (diff > 0) {
int days = (int)(diff / 60 / 60 / 24);
int hours = (int)((diff / 60 / 60) - (days * 24));
int minutes = (int)((diff / 60) - ((hours * 60) + (days * 60 * 24)));
int seconds = (int)(diff - ((minutes * 60) + (hours * 60 * 60) + (days * 60 * 60 * 24)));
char *output = (char*) malloc(100 * sizeof(char));
offset = (double)(-lt->tm_gmtoff);
tEnds = mktime(ends);
lin = (long)now;
lin += (long)offset;
lie = (long)tEnds;
diff = (lie - lin);
if (days > 0)
sprintf(output, "%dd %dh %02dm %02ds", days, hours, minutes, seconds);
else if (hours > 0)
sprintf(output, "%dh %02dm %02ds", hours, minutes, seconds);
else
sprintf(output, "%02dm %02ds", minutes, seconds);
if (diff > 0) {
int days = (int)(diff / 60 / 60 / 24);
int hours = (int)((diff / 60 / 60) - (days * 24));
int minutes = (int)((diff / 60) - ((hours * 60) + (days * 60 * 24)));
int seconds = (int)(diff - ((minutes * 60) + (hours * 60 * 60) +
(days * 60 * 60 * 24)));
char *output = (char *)malloc(100 * sizeof(char));
return output;
} else {
char *output = strdup("Done");
return output;
}
if (days > 0)
sprintf(output, "%dd %dh %02dm %02ds", days, hours, minutes, seconds);
else if (hours > 0)
sprintf(output, "%dh %02dm %02ds", hours, minutes, seconds);
else
sprintf(output, "%02dm %02ds", minutes, seconds);
return output;
} else {
char *output = strdup("Done");
return output;
}
}
static void writeSkilltree(char *content, const char *filename)
{
FILE *fp = fopen(filename, "w");
if (fwrite(content, sizeof(char), strlen(content), fp) < strlen(content))
NORM_ERR("skill tree write failed");
fclose(fp);
static void writeSkilltree(char *content, const char *filename) {
FILE *fp = fopen(filename, "w");
if (fwrite(content, sizeof(char), strlen(content), fp) < strlen(content))
NORM_ERR("skill tree write failed");
fclose(fp);
}
static char *getSkillname(const char *file, int skillid)
{
char *skilltree;
char *skill = NULL;
xmlNodePtr n;
xmlDocPtr doc = 0;
xmlNodePtr root = 0;
static char *getSkillname(const char *file, int skillid) {
char *skilltree;
char *skill = NULL;
xmlNodePtr n;
xmlDocPtr doc = 0;
xmlNodePtr root = 0;
skilltree = getXmlFromAPI(NULL, NULL, NULL, EVEURL_SKILLTREE);
if(skilltree)
{
writeSkilltree(skilltree, file);
free(skilltree);
}
skilltree = getXmlFromAPI(NULL, NULL, NULL, EVEURL_SKILLTREE);
if (skilltree) {
writeSkilltree(skilltree, file);
free(skilltree);
}
doc = xmlReadFile(file, NULL, XML_PARSE_RECOVER);
unlink(file);
if (!doc)
return NULL;
doc = xmlReadFile(file, NULL, XML_PARSE_RECOVER);
unlink(file);
if (!doc) return NULL;
root = xmlDocGetRootElement(doc);
root = xmlDocGetRootElement(doc);
for (n = root->children; n; n = n->next) {
xmlNodePtr o;
for (o = n->children; o; o = o->next) {
xmlNodePtr p;
for (p = o->children; p; p = p->next) {
xmlNodePtr q;
for (q = p->children; q; q = q->next) {
xmlNodePtr r;
for (r = q->children; r; r = r->next) {
xmlElementPtr ele = (xmlElementPtr) r;
xmlAttrPtr attr = (xmlAttrPtr) ele->attributes;
char *mySkill = NULL;
int id;
for (n = root->children; n; n = n->next) {
xmlNodePtr o;
for (o = n->children; o; o = o->next) {
xmlNodePtr p;
for (p = o->children; p; p = p->next) {
xmlNodePtr q;
for (q = p->children; q; q = q->next) {
xmlNodePtr r;
for (r = q->children; r; r = r->next) {
xmlElementPtr ele = (xmlElementPtr)r;
xmlAttrPtr attr = (xmlAttrPtr)ele->attributes;
char *mySkill = NULL;
int id;
while (attr != NULL) {
if (!strcasecmp((const char *)attr->name, "typeName")) {
mySkill = strdup((const char *)attr->children->content);
} else if (!strcasecmp((const char *)attr->name, "typeID")) {
id = atoi((const char *)attr->children->content);
}
attr = attr->next;
}
while (attr != NULL) {
if (!strcasecmp((const char *)attr->name, "typeName")) {
mySkill = strdup((const char *)attr->children->content);
} else if (!strcasecmp((const char *)attr->name, "typeID")) {
id = atoi((const char *)attr->children->content);
}
attr = attr->next;
}
if (id == skillid) {
skill = mySkill;
goto END;
}
if (id == skillid) {
skill = mySkill;
goto END;
}
free(mySkill);
}
}
}
}
}
END:
xmlFreeDoc(doc);
free(mySkill);
}
}
}
}
}
END:
xmlFreeDoc(doc);
return skill;
return skill;
}
static char *eve(char *apiKeyID, char *apiVCode, char *charid)
{
Character *chr = NULL;
char skillfile[] = "/tmp/.cesfXXXXXX";
int i = 0;
char *output = 0;
char *timel = 0;
char *skill = 0;
char *content = 0;
time_t now = 0;
char *error = 0;
int tmp_fd, old_umask;
static char *eve(char *apiKeyID, char *apiVCode, char *charid) {
Character *chr = NULL;
char skillfile[] = "/tmp/.cesfXXXXXX";
int i = 0;
char *output = 0;
char *timel = 0;
char *skill = 0;
char *content = 0;
time_t now = 0;
char *error = 0;
int tmp_fd, old_umask;
for (i = 0; i < num_chars; i++) {
if (eveCharacters[i].charid != NULL) {
if (strcasecmp(eveCharacters[i].charid, charid) == 0) {
chr = &eveCharacters[i];
break;
}
}
}
for (i = 0; i < num_chars; i++) {
if (eveCharacters[i].charid != NULL) {
if (strcasecmp(eveCharacters[i].charid, charid) == 0) {
chr = &eveCharacters[i];
break;
}
}
}
if (!chr) {
if (num_chars == MAXCHARS - 1) return NULL;
chr = &eveCharacters[num_chars];
memset(chr, 0, sizeof(Character));
chr->charid = strdup(charid);
num_chars++;
}
if (!chr) {
if (num_chars == MAXCHARS - 1)
return NULL;
chr = &eveCharacters[num_chars];
memset(chr, 0, sizeof(Character));
chr->charid = strdup(charid);
num_chars++;
}
if (chr->delay > 0) {
now = time(NULL);
if (now < chr->delay) {
output = strdup("Server error");
return output;
} else
chr->delay = 0;
}
if (chr->delay > 0) {
now = time(NULL);
if (now < chr->delay) {
output = strdup("Server error");
return output;
} else
chr->delay = 0;
}
if (isCacheValid(chr->cache)) {
if (chr->isTraining) {
output = (char *)malloc(200 * sizeof(char));
timel = strdup(formatTime(&chr->ends));
sprintf(output, EVE_OUTPUT_FORMAT, chr->skillname, chr->level, timel);
free(timel);
return output;
} else {
return strdup(TRAINING_INACTIVE);
}
} else {
content = getXmlFromAPI(apiKeyID, apiVCode, charid, EVEURL_TRAINING);
if (content == NULL) {
error = strdup("Server error");
now = time(NULL);
now += (time_t)1800;
chr->delay = now;
return error;
}
if (isCacheValid(chr->cache)) {
if (chr->isTraining) {
output = (char *)malloc(200 * sizeof(char));
timel = strdup(formatTime(&chr->ends));
sprintf(output, EVE_OUTPUT_FORMAT, chr->skillname, chr->level, timel);
free(timel);
return output;
} else {
return strdup(TRAINING_INACTIVE);
}
} else {
content = getXmlFromAPI(apiKeyID, apiVCode, charid, EVEURL_TRAINING);
if (content == NULL) {
error = strdup("Server error");
now = time(NULL);
now += (time_t) 1800;
chr->delay = now;
return error;
}
if (parseTrainingXml(content, chr)) {
output = strdup("API error");
return output;
}
if (parseTrainingXml(content, chr)) {
output = strdup("API error");
return output;
}
timel = formatTime(&chr->ends);
old_umask = umask(0066);
tmp_fd = mkstemp(skillfile);
umask(old_umask);
if (tmp_fd == -1) {
error = strdup("Cannot create temporary file");
return error;
}
close(tmp_fd);
timel = formatTime(&chr->ends);
old_umask = umask(0066);
tmp_fd = mkstemp(skillfile);
umask(old_umask);
if (tmp_fd == -1) {
error = strdup("Cannot create temporary file");
return error;
}
close(tmp_fd);
skill = getSkillname(skillfile, chr->skill);
if (skill) {
chr->skillname = strdup(skill);
output = (char *)malloc(200 * sizeof(char));
sprintf(output, EVE_OUTPUT_FORMAT, chr->skillname, chr->level, timel);
free(skill);
return output;
} else {
return strdup(TRAINING_INACTIVE);
}
}
skill = getSkillname(skillfile, chr->skill);
if (skill) {
chr->skillname = strdup(skill);
output = (char *)malloc(200 * sizeof(char));
sprintf(output, EVE_OUTPUT_FORMAT, chr->skillname, chr->level, timel);
free(skill);
return output;
} else {
return strdup(TRAINING_INACTIVE);
}
}
}
void scan_eve(struct text_object *obj, const char *arg)
{
int argc;
struct eve_data *ed;
void scan_eve(struct text_object *obj, const char *arg) {
int argc;
struct eve_data *ed;
ed = (struct eve_data *) malloc(sizeof(struct eve_data));
memset(ed, 0, sizeof(struct eve_data));
ed = (struct eve_data *)malloc(sizeof(struct eve_data));
memset(ed, 0, sizeof(struct eve_data));
argc = sscanf(arg, "%20s %64s %20s", ed->apiKeyID, ed->apiVCode, ed->charid);
argc = sscanf(arg, "%20s %64s %20s", ed->apiKeyID, ed->apiVCode, ed->charid);
init_eve();
obj->data.opaque = ed;
init_eve();
obj->data.opaque = ed;
}
void print_eve(struct text_object *obj, char *p, int p_max_size)
{
struct eve_data *ed = (struct eve_data *) obj->data.opaque;
void print_eve(struct text_object *obj, char *p, int p_max_size) {
struct eve_data *ed = (struct eve_data *)obj->data.opaque;
if (!ed)
return;
if (!ed) return;
snprintf(p, p_max_size, "%s", eve(ed->apiKeyID, ed->apiVCode, ed->charid));
snprintf(p, p_max_size, "%s", eve(ed->apiKeyID, ed->apiVCode, ed->charid));
}
void free_eve(struct text_object *obj)
{
free_and_zero(obj->data.opaque);
num_chars = 0;
void free_eve(struct text_object *obj) {
free_and_zero(obj->data.opaque);
num_chars = 0;
}

View File

@@ -1,10 +1,9 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Copyright (c) 2008 Asbjørn Zweidorff Kjær
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -25,7 +24,8 @@
#ifndef _EVE_H
#define _EVE_H
#define EVEURL_TRAINING "https://api.eveonline.com/char/SkillInTraining.xml.aspx"
#define EVEURL_TRAINING \
"https://api.eveonline.com/char/SkillInTraining.xml.aspx"
#define EVEURL_SKILLTREE "https://api.eveonline.com/eve/Skilltree.xml.aspx"
#define EVE_OUTPUT_FORMAT "%s %d in %s"

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -28,78 +27,79 @@
*
*/
#include "conky.h"
#include "core.h"
#include "exec.h"
#include "logging.h"
#include "specials.h"
#include "text_object.h"
#include "update-cb.hh"
#include <cmath>
#include <mutex>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <cmath>
#include <mutex>
#include "conky.h"
#include "core.h"
#include "logging.h"
#include "specials.h"
#include "text_object.h"
#include "update-cb.hh"
struct execi_data {
float interval;
char *cmd;
execi_data() : interval(0), cmd(0) {}
float interval;
char *cmd;
execi_data() : interval(0), cmd(0) {}
};
//our own implementation of popen, the difference : the value of 'childpid' will be filled with
//the pid of the running 'command'. This is useful if want to kill it when it hangs while reading
//or writing to it. We have to kill it because pclose will wait until the process dies by itself
static FILE* pid_popen(const char *command, const char *mode, pid_t *child) {
int ends[2];
int parentend, childend;
// our own implementation of popen, the difference : the value of 'childpid'
// will be filled with the pid of the running 'command'. This is useful if want
// to kill it when it hangs while reading or writing to it. We have to kill it
// because pclose will wait until the process dies by itself
static FILE *pid_popen(const char *command, const char *mode, pid_t *child) {
int ends[2];
int parentend, childend;
//by running pipe after the strcmp's we make sure that we don't have to create a pipe
//and close the ends if mode is something illegal
if (strcmp(mode, "r") == 0) {
if (pipe(ends) != 0) {
return NULL;
}
parentend = ends[0];
childend = ends[1];
} else if (strcmp(mode, "w") == 0) {
if (pipe(ends) != 0) {
return NULL;
}
parentend = ends[1];
childend = ends[0];
} else {
return NULL;
}
// by running pipe after the strcmp's we make sure that we don't have to
// create a pipe and close the ends if mode is something illegal
if (strcmp(mode, "r") == 0) {
if (pipe(ends) != 0) {
return NULL;
}
parentend = ends[0];
childend = ends[1];
} else if (strcmp(mode, "w") == 0) {
if (pipe(ends) != 0) {
return NULL;
}
parentend = ends[1];
childend = ends[0];
} else {
return NULL;
}
*child = fork();
if (*child == -1) {
close(parentend);
close(childend);
return NULL;
} else if (*child > 0) {
close(childend);
waitpid(*child, NULL, 0);
} else {
//don't read from both stdin and pipe or write to both stdout and pipe
if (childend == ends[0]) {
close(0);
} else {
close(1);
}
close(parentend);
*child = fork();
if (*child == -1) {
close(parentend);
close(childend);
return NULL;
} else if (*child > 0) {
close(childend);
waitpid(*child, NULL, 0);
} else {
// don't read from both stdin and pipe or write to both stdout and pipe
if (childend == ends[0]) {
close(0);
} else {
close(1);
}
close(parentend);
//by dupping childend, the returned fd will have close-on-exec turned off
if (dup(childend) == -1)
perror("dup()");
close(childend);
// by dupping childend, the returned fd will have close-on-exec turned off
if (dup(childend) == -1) perror("dup()");
close(childend);
execl("/bin/sh", "sh", "-c", command, (char *) NULL);
_exit(EXIT_FAILURE); //child should die here, (normally execl will take care of this but it can fail)
}
execl("/bin/sh", "sh", "-c", command, (char *)NULL);
_exit(EXIT_FAILURE); // child should die here, (normally execl will take
// care of this but it can fail)
}
return fdopen(parentend, mode);
return fdopen(parentend, mode);
}
/**
@@ -113,43 +113,45 @@ static FILE* pid_popen(const char *command, const char *mode, pid_t *child) {
* results, use the stored callback to call get_result_copy(), which
* returns a std::string.
*/
void exec_cb::work()
{
pid_t childpid;
std::string buf;
std::shared_ptr<FILE> fp;
char b[0x1000];
void exec_cb::work() {
pid_t childpid;
std::string buf;
std::shared_ptr<FILE> fp;
char b[0x1000];
if (FILE *t = pid_popen(std::get<0>(tuple).c_str(), "r", &childpid))
fp.reset(t, fclose);
else
return;
if (FILE *t = pid_popen(std::get<0>(tuple).c_str(), "r", &childpid))
fp.reset(t, fclose);
else
return;
while (!feof(fp.get()) && !ferror(fp.get())) {
int length = fread(b, 1, sizeof b, fp.get());
buf.append(b, length);
}
while (!feof(fp.get()) && !ferror(fp.get())) {
int length = fread(b, 1, sizeof b, fp.get());
buf.append(b, length);
}
if (*buf.rbegin() == '\n')
buf.resize(buf.size()-1);
if (*buf.rbegin() == '\n') buf.resize(buf.size() - 1);
std::lock_guard<std::mutex> l(result_mutex);
result = buf;
std::lock_guard<std::mutex> l(result_mutex);
result = buf;
}
//remove backspaced chars, example: "dog^H^H^Hcat" becomes "cat"
//string has to end with \0 and it's length should fit in a int
// remove backspaced chars, example: "dog^H^H^Hcat" becomes "cat"
// string has to end with \0 and it's length should fit in a int
#define BACKSPACE 8
static void remove_deleted_chars(char *string){
int i = 0;
while (string[i] != 0) {
if (string[i] == BACKSPACE) {
if (i != 0) {
strcpy( &(string[i-1]), &(string[i+1]) );
i--;
} else strcpy( &(string[i]), &(string[i+1]) ); //necessary for ^H's at the start of a string
} else i++;
}
static void remove_deleted_chars(char *string) {
int i = 0;
while (string[i] != 0) {
if (string[i] == BACKSPACE) {
if (i != 0) {
strcpy(&(string[i - 1]), &(string[i + 1]));
i--;
} else
strcpy(
&(string[i]),
&(string[i + 1])); // necessary for ^H's at the start of a string
} else
i++;
}
}
/**
@@ -159,22 +161,23 @@ static void remove_deleted_chars(char *string){
* @param[in] buf output of a command executed by an exec_cb object
* @return number between 0.0 and 100.0
*/
static inline double get_barnum(const char *buf)
{
double barnum;
static inline double get_barnum(const char *buf) {
double barnum;
if (sscanf(buf, "%lf", &barnum) != 1) {
NORM_ERR("reading exec value failed (perhaps it's not the "
"correct format?)");
return 0.0;
}
if (barnum > 100.0 || barnum < 0.0) {
NORM_ERR("your exec value is not between 0 and 100, "
"therefore it will be ignored");
return 0.0;
}
if (sscanf(buf, "%lf", &barnum) != 1) {
NORM_ERR(
"reading exec value failed (perhaps it's not the "
"correct format?)");
return 0.0;
}
if (barnum > 100.0 || barnum < 0.0) {
NORM_ERR(
"your exec value is not between 0 and 100, "
"therefore it will be ignored");
return 0.0;
}
return barnum;
return barnum;
}
/**
@@ -186,67 +189,71 @@ static inline double get_barnum(const char *buf)
* @param[out] p the string in which we store command output
* @param[in] p_max_size the maximum size of p...
*/
void fill_p(const char *buffer, struct text_object *obj, char *p, int p_max_size) {
if (obj->parse == true) {
evaluate(buffer, p, p_max_size);
} else {
snprintf(p, p_max_size, "%s", buffer);
}
void fill_p(const char *buffer, struct text_object *obj, char *p,
int p_max_size) {
if (obj->parse == true) {
evaluate(buffer, p, p_max_size);
} else {
snprintf(p, p_max_size, "%s", buffer);
}
remove_deleted_chars(p);
remove_deleted_chars(p);
}
/**
* Parses arg to find the command to be run, as well as special options
* like height, width, color, and update interval
*
* @param[out] obj stores the command and an execi_data structure (if applicable)
* @param[out] obj stores the command and an execi_data structure (if
* applicable)
* @param[in] arg the argument to an ${exec*} object
* @param[in] execflag bitwise flag used to specify the exec variant we need to process
* @param[in] execflag bitwise flag used to specify the exec variant we need to
* process
*/
void scan_exec_arg(struct text_object *obj, const char *arg, unsigned int execflag)
{
const char *cmd = arg;
struct execi_data *ed;
void scan_exec_arg(struct text_object *obj, const char *arg,
unsigned int execflag) {
const char *cmd = arg;
struct execi_data *ed;
/* in case we have an execi object, we need to parse out the interval */
if (execflag & EF_EXECI) {
ed = new execi_data;
int n;
/* in case we have an execi object, we need to parse out the interval */
if (execflag & EF_EXECI) {
ed = new execi_data;
int n;
/* store the interval in ed->interval */
if (sscanf(arg, "%f %n", &ed->interval, &n) <= 0) {
NORM_ERR("missing execi interval: ${execi* <interval> command}");
delete ed;
ed = NULL;
return;
}
/* store the interval in ed->interval */
if (sscanf(arg, "%f %n", &ed->interval, &n) <= 0) {
NORM_ERR("missing execi interval: ${execi* <interval> command}");
delete ed;
ed = NULL;
return;
}
/* set cmd to everything after the interval */
cmd = strndup(arg + n, text_buffer_size.get(*state));
}
/* set cmd to everything after the interval */
cmd = strndup(arg + n, text_buffer_size.get(*state));
}
/* parse any special options for the graphical exec types */
if (execflag & EF_BAR) {
cmd = scan_bar(obj, cmd, 100);
/* parse any special options for the graphical exec types */
if (execflag & EF_BAR) {
cmd = scan_bar(obj, cmd, 100);
#ifdef BUILD_X11
} else if (execflag & EF_GAUGE) {
cmd = scan_gauge(obj, cmd, 100);
} else if (execflag & EF_GRAPH) {
cmd = scan_graph(obj, cmd, 100);
if (!cmd) {
NORM_ERR("error parsing arguments to execgraph object");
}
} else if (execflag & EF_GAUGE) {
cmd = scan_gauge(obj, cmd, 100);
} else if (execflag & EF_GRAPH) {
cmd = scan_graph(obj, cmd, 100);
if (!cmd) {
NORM_ERR("error parsing arguments to execgraph object");
}
#endif /* BUILD_X11 */
}
}
/* finally, store the resulting command, or an empty string if something went wrong */
if (execflag & EF_EXEC) {
obj->data.s = strndup(cmd ? cmd : "", text_buffer_size.get(*state));
} else if (execflag & EF_EXECI) {
ed->cmd = strndup(cmd ? cmd : "", text_buffer_size.get(*state));
obj->data.opaque = ed;
}
/* finally, store the resulting command, or an empty string if something went
* wrong */
if (execflag & EF_EXEC) {
obj->data.s = strndup(cmd ? cmd : "", text_buffer_size.get(*state));
} else if (execflag & EF_EXECI) {
ed->cmd = strndup(cmd ? cmd : "", text_buffer_size.get(*state));
obj->data.opaque = ed;
}
}
/**
@@ -254,14 +261,13 @@ void scan_exec_arg(struct text_object *obj, const char *arg, unsigned int execfl
*
* @param[out] obj stores the callback handle
*/
void register_exec(struct text_object *obj)
{
if (obj->data.s && obj->data.s[0]) {
obj->exec_handle = new conky::callback_handle<exec_cb>(
conky::register_cb<exec_cb>(1, true, obj->data.s));
} else {
DBGP("unable to register exec callback");
}
void register_exec(struct text_object *obj) {
if (obj->data.s && obj->data.s[0]) {
obj->exec_handle = new conky::callback_handle<exec_cb>(
conky::register_cb<exec_cb>(1, true, obj->data.s));
} else {
DBGP("unable to register exec callback");
}
}
/**
@@ -272,17 +278,17 @@ void register_exec(struct text_object *obj)
*
* @param[out] obj stores the callback handle
*/
void register_execi(struct text_object *obj)
{
struct execi_data *ed = (struct execi_data *)obj->data.opaque;
void register_execi(struct text_object *obj) {
struct execi_data *ed = (struct execi_data *)obj->data.opaque;
if (ed && ed->cmd && ed->cmd[0]) {
uint32_t period = std::max(lround(ed->interval/active_update_interval()), 1l);
obj->exec_handle = new conky::callback_handle<exec_cb>(
conky::register_cb<exec_cb>(period, !obj->thread, ed->cmd));
} else {
DBGP("unable to register execi callback");
}
if (ed && ed->cmd && ed->cmd[0]) {
uint32_t period =
std::max(lround(ed->interval / active_update_interval()), 1l);
obj->exec_handle = new conky::callback_handle<exec_cb>(
conky::register_cb<exec_cb>(period, !obj->thread, ed->cmd));
} else {
DBGP("unable to register execi callback");
}
}
/**
@@ -292,11 +298,10 @@ void register_execi(struct text_object *obj)
* @param[out] p the string in which we store command output
* @param[in] p_max_size the maximum size of p...
*/
void print_exec(struct text_object *obj, char *p, int p_max_size)
{
if (obj->exec_handle) {
fill_p((*obj->exec_handle)->get_result_copy().c_str(), obj, p, p_max_size);
}
void print_exec(struct text_object *obj, char *p, int p_max_size) {
if (obj->exec_handle) {
fill_p((*obj->exec_handle)->get_result_copy().c_str(), obj, p, p_max_size);
}
}
/**
@@ -305,13 +310,12 @@ void print_exec(struct text_object *obj, char *p, int p_max_size)
* @param[in] obj hold an exec_handle, assuming one was registered
* @return a value between 0.0 and 100.0
*/
double execbarval(struct text_object *obj)
{
if (obj->exec_handle) {
return get_barnum((*obj->exec_handle)->get_result_copy().c_str());
} else {
return 0.0;
}
double execbarval(struct text_object *obj) {
if (obj->exec_handle) {
return get_barnum((*obj->exec_handle)->get_result_copy().c_str());
} else {
return 0.0;
}
}
/**
@@ -319,11 +323,10 @@ double execbarval(struct text_object *obj)
*
* @param[in] obj holds the data that we need to free up
*/
void free_exec(struct text_object *obj)
{
free_and_zero(obj->data.s);
delete obj->exec_handle;
obj->exec_handle = NULL;
void free_exec(struct text_object *obj) {
free_and_zero(obj->data.s);
delete obj->exec_handle;
obj->exec_handle = NULL;
}
/**
@@ -331,19 +334,17 @@ void free_exec(struct text_object *obj)
*
* @param[in] obj holds the data that we need to free up
*/
void free_execi(struct text_object *obj)
{
struct execi_data *ed = (struct execi_data *)obj->data.opaque;
void free_execi(struct text_object *obj) {
struct execi_data *ed = (struct execi_data *)obj->data.opaque;
/* if ed is NULL, there is nothing to do */
if (!ed)
return;
/* if ed is NULL, there is nothing to do */
if (!ed) return;
delete obj->exec_handle;
obj->exec_handle = NULL;
delete obj->exec_handle;
obj->exec_handle = NULL;
free_and_zero(ed->cmd);
delete ed;
ed = NULL;
obj->data.opaque = NULL;
free_and_zero(ed->cmd);
delete ed;
ed = NULL;
obj->data.opaque = NULL;
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -31,7 +30,7 @@
#ifndef _EXEC_H
#define _EXEC_H
#include "text_object.h"
#include "update-cb.hh"
/**
* A callback that executes a command and stores the output as a std::string.
@@ -48,16 +47,15 @@
* command will in fact run on every update interval, rather than every
* ten seconds as one would expect.
*/
class exec_cb: public conky::callback<std::string, std::string> {
typedef conky::callback<std::string, std::string> Base;
class exec_cb : public conky::callback<std::string, std::string> {
typedef conky::callback<std::string, std::string> Base;
protected:
virtual void work();
protected:
virtual void work();
public:
exec_cb(uint32_t period, bool wait, const std::string &cmd)
: Base(period, wait, Base::Tuple(cmd))
{}
public:
exec_cb(uint32_t period, bool wait, const std::string &cmd)
: Base(period, wait, Base::Tuple(cmd)) {}
};
/**
@@ -67,11 +65,11 @@ class exec_cb: public conky::callback<std::string, std::string> {
* as the last argument to scan_exec_arg().
*/
enum {
EF_EXEC = (1 << 0),
EF_EXECI = (1 << 1),
EF_BAR = (1 << 2),
EF_GRAPH = (1 << 3),
EF_GAUGE = (1 << 4)
EF_EXEC = (1 << 0),
EF_EXECI = (1 << 1),
EF_BAR = (1 << 2),
EF_GRAPH = (1 << 3),
EF_GAUGE = (1 << 4)
};
void scan_exec_arg(struct text_object *, const char *, unsigned int);

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -27,7 +26,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "conky.h"
#include "fonts.h"
#include "logging.h"
@@ -35,171 +34,166 @@ int selected_font = 0;
std::vector<font_list> fonts;
char fontloaded = 0;
void font_setting::lua_setter(lua::state &l, bool init)
{
lua::stack_sentry s(l, -2);
void font_setting::lua_setter(lua::state &l, bool init) {
lua::stack_sentry s(l, -2);
Base::lua_setter(l, init);
Base::lua_setter(l, init);
if(init && out_to_x.get(*state)) {
if(fonts.size() == 0)
fonts.resize(1);
fonts[0].name = do_convert(l, -1).first;
}
if (init && out_to_x.get(*state)) {
if (fonts.size() == 0) fonts.resize(1);
fonts[0].name = do_convert(l, -1).first;
}
++s;
++s;
}
font_setting font;
#ifdef BUILD_XFT
namespace {
class xftalpha_setting: public conky::simple_config_setting<float> {
typedef conky::simple_config_setting<float> Base;
class xftalpha_setting : public conky::simple_config_setting<float> {
typedef conky::simple_config_setting<float> Base;
protected:
virtual void lua_setter(lua::state &l, bool init)
{
lua::stack_sentry s(l, -2);
protected:
virtual void lua_setter(lua::state &l, bool init) {
lua::stack_sentry s(l, -2);
Base::lua_setter(l, init);
Base::lua_setter(l, init);
if(init && out_to_x.get(*state)) {
fonts[0].font_alpha = do_convert(l, -1).first * 0xffff;
}
if (init && out_to_x.get(*state)) {
fonts[0].font_alpha = do_convert(l, -1).first * 0xffff;
}
++s;
}
++s;
}
public:
xftalpha_setting()
: Base("xftalpha", 1.0, false)
{}
};
public:
xftalpha_setting() : Base("xftalpha", 1.0, false) {}
};
xftalpha_setting xftalpha;
}
xftalpha_setting xftalpha;
} // namespace
#endif /* BUILD_XFT */
void set_font(void)
{
void set_font(void) {
#ifdef BUILD_XFT
if (use_xft.get(*state)) return;
if (use_xft.get(*state)) return;
#endif /* BUILD_XFT */
if (fonts[selected_font].font) {
XSetFont(display, window.gc, fonts[selected_font].font->fid);
}
if (fonts[selected_font].font) {
XSetFont(display, window.gc, fonts[selected_font].font->fid);
}
}
void setup_fonts(void)
{
if (not out_to_x.get(*state)) {
return;
}
void setup_fonts(void) {
if (not out_to_x.get(*state)) {
return;
}
#ifdef BUILD_XFT
if (use_xft.get(*state)) {
if (window.xftdraw) {
XftDrawDestroy(window.xftdraw);
window.xftdraw = 0;
}
window.xftdraw = XftDrawCreate(display, window.drawable,
window.visual, window.colourmap);
}
if (use_xft.get(*state)) {
if (window.xftdraw) {
XftDrawDestroy(window.xftdraw);
window.xftdraw = 0;
}
window.xftdraw = XftDrawCreate(display, window.drawable, window.visual,
window.colourmap);
}
#endif /* BUILD_XFT */
set_font();
set_font();
}
int add_font(const char *data_in)
{
if (not out_to_x.get(*state)) {
return 0;
}
fonts.push_back(font_list());
fonts.rbegin()->name = data_in;
int add_font(const char *data_in) {
if (not out_to_x.get(*state)) {
return 0;
}
fonts.push_back(font_list());
fonts.rbegin()->name = data_in;
return fonts.size()-1;
return fonts.size() - 1;
}
void free_fonts(bool utf8) {
if (not out_to_x.get(*state)) {
return;
}
for (size_t i = 0; i < fonts.size(); i++) {
if (not out_to_x.get(*state)) {
return;
}
for (size_t i = 0; i < fonts.size(); i++) {
#ifdef BUILD_XFT
if (use_xft.get(*state)) {
/*
* Do we not need to close fonts with Xft? Unsure. Not freeing the
* fonts seems to incur a slight memory leak, but it also prevents
* a crash.
*
* XftFontClose(display, fonts[i].xftfont);
*/
} else
if (use_xft.get(*state)) {
/*
* Do we not need to close fonts with Xft? Unsure. Not freeing the
* fonts seems to incur a slight memory leak, but it also prevents
* a crash.
*
* XftFontClose(display, fonts[i].xftfont);
*/
} else
#endif /* BUILD_XFT */
{
if (fonts[i].font) {
XFreeFont(display, fonts[i].font);
}
if (utf8 && fonts[i].fontset) {
XFreeFontSet(display, fonts[i].fontset);
}
}
}
fonts.clear();
selected_font = 0;
{
if (fonts[i].font) {
XFreeFont(display, fonts[i].font);
}
if (utf8 && fonts[i].fontset) {
XFreeFontSet(display, fonts[i].fontset);
}
}
}
fonts.clear();
selected_font = 0;
#ifdef BUILD_XFT
if (window.xftdraw) {
XftDrawDestroy(window.xftdraw);
window.xftdraw = 0;
}
if (window.xftdraw) {
XftDrawDestroy(window.xftdraw);
window.xftdraw = 0;
}
#endif /* BUILD_XFT */
}
void load_fonts(bool utf8) {
if (not out_to_x.get(*state))
return;
for (size_t i = 0; i < fonts.size(); i++) {
if (not out_to_x.get(*state)) return;
for (size_t i = 0; i < fonts.size(); i++) {
#ifdef BUILD_XFT
/* load Xft font */
if (use_xft.get(*state)) {
if(not fonts[i].xftfont)
fonts[i].xftfont = XftFontOpenName(display, screen, fonts[i].name.c_str());
/* load Xft font */
if (use_xft.get(*state)) {
if (not fonts[i].xftfont)
fonts[i].xftfont =
XftFontOpenName(display, screen, fonts[i].name.c_str());
if (fonts[i].xftfont) {
continue;
}
if (fonts[i].xftfont) {
continue;
}
NORM_ERR("can't load Xft font '%s'", fonts[i].name.c_str());
if ((fonts[i].xftfont = XftFontOpenName(display, screen,
"courier-12")) != NULL) {
continue;
}
NORM_ERR("can't load Xft font '%s'", fonts[i].name.c_str());
if ((fonts[i].xftfont = XftFontOpenName(display, screen, "courier-12")) !=
NULL) {
continue;
}
CRIT_ERR(NULL, NULL, "can't load Xft font '%s'", "courier-12");
CRIT_ERR(NULL, NULL, "can't load Xft font '%s'", "courier-12");
continue;
}
continue;
}
#endif
if(utf8 && fonts[i].fontset == NULL) {
char** missing;
int missingnum;
char* missingdrawn;
fonts[i].fontset = XCreateFontSet(display, fonts[i].name.c_str(), &missing, &missingnum, &missingdrawn);
XFreeStringList(missing);
if(fonts[i].fontset == NULL) {
NORM_ERR("can't load font '%s'", fonts[i].name.c_str());
fonts[i].fontset = XCreateFontSet(display, "fixed", &missing, &missingnum, &missingdrawn);
if(fonts[i].fontset == NULL) {
CRIT_ERR(NULL, NULL, "can't load font '%s'", "fixed");
}
}
}
/* load normal font */
if (!fonts[i].font && (fonts[i].font = XLoadQueryFont(display, fonts[i].name.c_str())) == NULL) {
NORM_ERR("can't load font '%s'", fonts[i].name.c_str());
if ((fonts[i].font = XLoadQueryFont(display, "fixed")) == NULL) {
CRIT_ERR(NULL, NULL, "can't load font '%s'", "fixed");
}
}
}
if (utf8 && fonts[i].fontset == NULL) {
char **missing;
int missingnum;
char *missingdrawn;
fonts[i].fontset = XCreateFontSet(display, fonts[i].name.c_str(),
&missing, &missingnum, &missingdrawn);
XFreeStringList(missing);
if (fonts[i].fontset == NULL) {
NORM_ERR("can't load font '%s'", fonts[i].name.c_str());
fonts[i].fontset = XCreateFontSet(display, "fixed", &missing,
&missingnum, &missingdrawn);
if (fonts[i].fontset == NULL) {
CRIT_ERR(NULL, NULL, "can't load font '%s'", "fixed");
}
}
}
/* load normal font */
if (!fonts[i].font && (fonts[i].font = XLoadQueryFont(
display, fonts[i].name.c_str())) == NULL) {
NORM_ERR("can't load font '%s'", fonts[i].name.c_str());
if ((fonts[i].font = XLoadQueryFont(display, "fixed")) == NULL) {
CRIT_ERR(NULL, NULL, "can't load font '%s'", "fixed");
}
}
}
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -27,49 +26,57 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef BUILD_X11
#ifndef _FONTS_H
#define _FONTS_H
#include <vector>
#include "conky.h"
#include "x11.h"
/* for fonts */
struct font_list {
std::string name;
XFontStruct *font;
XFontSet fontset;
std::string name;
XFontStruct *font;
XFontSet fontset;
#ifdef BUILD_XFT
XftFont *xftfont;
int font_alpha;
XftFont *xftfont;
int font_alpha;
#endif
font_list()
: name(), font(NULL), fontset(NULL)
font_list()
: name(),
font(NULL),
fontset(NULL)
#ifdef BUILD_XFT
, xftfont(NULL), font_alpha(0xffff)
,
xftfont(NULL),
font_alpha(0xffff)
#endif
{}
{
}
};
#ifdef BUILD_XFT
#define font_height() (use_xft.get(*state) ? (fonts[selected_font].xftfont->ascent + \
fonts[selected_font].xftfont->descent) \
: (fonts[selected_font].font->max_bounds.ascent + \
fonts[selected_font].font->max_bounds.descent))
#define font_ascent() (use_xft.get(*state) ? fonts[selected_font].xftfont->ascent \
: fonts[selected_font].font->max_bounds.ascent)
#define font_descent() (use_xft.get(*state) ? fonts[selected_font].xftfont->descent \
: fonts[selected_font].font->max_bounds.descent)
#define font_height() \
(use_xft.get(*state) ? (fonts[selected_font].xftfont->ascent + \
fonts[selected_font].xftfont->descent) \
: (fonts[selected_font].font->max_bounds.ascent + \
fonts[selected_font].font->max_bounds.descent))
#define font_ascent() \
(use_xft.get(*state) ? fonts[selected_font].xftfont->ascent \
: fonts[selected_font].font->max_bounds.ascent)
#define font_descent() \
(use_xft.get(*state) ? fonts[selected_font].xftfont->descent \
: fonts[selected_font].font->max_bounds.descent)
#else
#define font_height() (fonts[selected_font].font->max_bounds.ascent + \
fonts[selected_font].font->max_bounds.descent)
#define font_height() \
(fonts[selected_font].font->max_bounds.ascent + \
fonts[selected_font].font->max_bounds.descent)
#define font_ascent() fonts[selected_font].font->max_bounds.ascent
#define font_descent() fonts[selected_font].font->max_bounds.descent
@@ -85,19 +92,16 @@ int add_font(const char *);
void free_fonts(bool utf8);
void load_fonts(bool utf8);
class font_setting: public conky::simple_config_setting<std::string> {
typedef conky::simple_config_setting<std::string> Base;
class font_setting : public conky::simple_config_setting<std::string> {
typedef conky::simple_config_setting<std::string> Base;
protected:
virtual void lua_setter(lua::state &l, bool init);
protected:
virtual void lua_setter(lua::state &l, bool init);
public:
font_setting()
: Base("font", "6x10", false)
{}
public:
font_setting() : Base("font", "6x10", false) {}
};
extern font_setting font;
#endif /* _FONTS_H */
#endif /* BUILD_X11 */

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,15 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*- */
/* */
#ifndef FREEBSD_H_
#define FREEBSD_H_
#include "common.h"
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/ucred.h>
#include <strings.h>
#include <fcntl.h>
#include <kvm.h>
#include <strings.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/ucred.h>
#include "common.h"
#if (defined(i386) || defined(__i386__))
#include <machine/apm_bios.h>
#endif /* i386 || __i386__ */

347
src/fs.cc
View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -28,24 +27,24 @@
*
*/
#include "fs.h"
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include "conky.h"
#include "logging.h"
#include "fs.h"
#include "specials.h"
#include "text_object.h"
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#if defined(__sun)
#include <sys/types.h>
#include <sys/statvfs.h>
#include <sys/types.h>
#endif
#if defined(__FreeBSD__)
@@ -58,11 +57,9 @@
#include "darwin.h"
#endif
#if !defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) && \
!defined (__OpenBSD__) && !defined(__FreeBSD__) && \
!defined(__DragonFly__) && !defined(__sun) && !defined(__HAIKU__) && \
!(defined(__APPLE__) && defined(__MACH__))
#if !defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) && !defined(__OpenBSD__) && \
!defined(__FreeBSD__) && !defined(__DragonFly__) && !defined(__sun) && \
!defined(__HAIKU__) && !(defined(__APPLE__) && defined(__MACH__))
#include <mntent.h>
#endif
@@ -75,222 +72,200 @@ static void update_fs_stat(struct fs_stat *fs);
void get_fs_type(const char *path, char *result);
int update_fs_stats(void)
{
unsigned i;
static double last_fs_update = 0.0;
int update_fs_stats(void) {
unsigned i;
static double last_fs_update = 0.0;
if (current_update_time - last_fs_update < 13)
return 0;
if (current_update_time - last_fs_update < 13) return 0;
for (i = 0; i < MAX_FS_STATS; ++i) {
if (fs_stats[i].set) {
update_fs_stat(&fs_stats[i]);
}
}
last_fs_update = current_update_time;
return 0;
for (i = 0; i < MAX_FS_STATS; ++i) {
if (fs_stats[i].set) {
update_fs_stat(&fs_stats[i]);
}
}
last_fs_update = current_update_time;
return 0;
}
void clear_fs_stats(void)
{
unsigned i;
for (i = 0; i < MAX_FS_STATS; ++i) {
memset(&fs_stats[i], 0, sizeof(struct fs_stat));
}
void clear_fs_stats(void) {
unsigned i;
for (i = 0; i < MAX_FS_STATS; ++i) {
memset(&fs_stats[i], 0, sizeof(struct fs_stat));
}
}
struct fs_stat *prepare_fs_stat(const char *s)
{
struct fs_stat *next = 0;
unsigned i;
struct fs_stat *prepare_fs_stat(const char *s) {
struct fs_stat *next = 0;
unsigned i;
/* lookup existing or get new */
for (i = 0; i < MAX_FS_STATS; ++i) {
if (fs_stats[i].set) {
if (strncmp(fs_stats[i].path, s, DEFAULT_TEXT_BUFFER_SIZE) == 0) {
return &fs_stats[i];
}
} else {
next = &fs_stats[i];
}
}
/* new path */
if (!next) {
NORM_ERR("too many fs stats");
return 0;
}
strncpy(next->path, s, DEFAULT_TEXT_BUFFER_SIZE);
next->set = 1;
update_fs_stat(next);
return next;
/* lookup existing or get new */
for (i = 0; i < MAX_FS_STATS; ++i) {
if (fs_stats[i].set) {
if (strncmp(fs_stats[i].path, s, DEFAULT_TEXT_BUFFER_SIZE) == 0) {
return &fs_stats[i];
}
} else {
next = &fs_stats[i];
}
}
/* new path */
if (!next) {
NORM_ERR("too many fs stats");
return 0;
}
strncpy(next->path, s, DEFAULT_TEXT_BUFFER_SIZE);
next->set = 1;
update_fs_stat(next);
return next;
}
static void update_fs_stat(struct fs_stat *fs)
{
static void update_fs_stat(struct fs_stat *fs) {
#if defined(__sun)
struct statvfs s;
struct statvfs s;
if (statvfs(fs->path, &s) == 0) {
fs->size = (long long)s.f_blocks * s.f_frsize;
fs->avail = (long long)s.f_bavail * s.f_frsize;
fs->free = (long long)s.f_bfree * s.f_frsize;
(void) strncpy(fs->type, s.f_basetype, sizeof (fs->type));
if (statvfs(fs->path, &s) == 0) {
fs->size = (long long)s.f_blocks * s.f_frsize;
fs->avail = (long long)s.f_bavail * s.f_frsize;
fs->free = (long long)s.f_bfree * s.f_frsize;
(void)strncpy(fs->type, s.f_basetype, sizeof(fs->type));
#else
struct statfs64 s;
struct statfs64 s;
if (statfs64(fs->path, &s) == 0) {
fs->size = (long long)s.f_blocks * s.f_bsize;
/* bfree (root) or bavail (non-roots) ? */
fs->avail = (long long)s.f_bavail * s.f_bsize;
fs->free = (long long)s.f_bfree * s.f_bsize;
get_fs_type(fs->path, fs->type);
if (statfs64(fs->path, &s) == 0) {
fs->size = (long long)s.f_blocks * s.f_bsize;
/* bfree (root) or bavail (non-roots) ? */
fs->avail = (long long)s.f_bavail * s.f_bsize;
fs->free = (long long)s.f_bfree * s.f_bsize;
get_fs_type(fs->path, fs->type);
#endif
} else {
NORM_ERR("statfs64 '%s': %s", fs->path, strerror(errno));
fs->size = 0;
fs->avail = 0;
fs->free = 0;
strncpy(fs->type, "unknown", DEFAULT_TEXT_BUFFER_SIZE);
}
} else {
NORM_ERR("statfs64 '%s': %s", fs->path, strerror(errno));
fs->size = 0;
fs->avail = 0;
fs->free = 0;
strncpy(fs->type, "unknown", DEFAULT_TEXT_BUFFER_SIZE);
}
}
void get_fs_type(const char *path, char *result)
{
void get_fs_type(const char *path, char *result) {
#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) || defined(__FreeBSD__) || \
defined(__OpenBSD__) || defined(__DragonFly__) || defined(__HAIKU__) || \
(defined(__APPLE__) && defined(__MACH__))
#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) || \
defined(__FreeBSD__) || defined (__OpenBSD__) || defined(__DragonFly__) || defined(__HAIKU__) || (defined(__APPLE__) && defined(__MACH__))
struct statfs64 s;
if (statfs64(path, &s) == 0) {
strncpy(result, s.f_fstypename, DEFAULT_TEXT_BUFFER_SIZE);
} else {
NORM_ERR("statfs64 '%s': %s", path, strerror(errno));
}
return;
struct statfs64 s;
if (statfs64(path, &s) == 0) {
strncpy(result, s.f_fstypename, DEFAULT_TEXT_BUFFER_SIZE);
} else {
NORM_ERR("statfs64 '%s': %s", path, strerror(errno));
}
return;
#elif defined(__sun)
assert(0); /* not used - see update_fs_stat() */
#else /* HAVE_STRUCT_STATFS_F_FSTYPENAME */
assert(0); /* not used - see update_fs_stat() */
#else /* HAVE_STRUCT_STATFS_F_FSTYPENAME */
struct mntent *me;
FILE *mtab = setmntent("/proc/mounts", "r");
char *search_path;
int match;
char *slash;
struct mntent *me;
FILE *mtab = setmntent("/proc/mounts", "r");
char *search_path;
int match;
char *slash;
if (mtab == NULL) {
NORM_ERR("setmntent /proc/mounts: %s", strerror(errno));
strncpy(result, "unknown", DEFAULT_TEXT_BUFFER_SIZE);
return;
}
if (mtab == NULL) {
NORM_ERR("setmntent /proc/mounts: %s", strerror(errno));
strncpy(result, "unknown", DEFAULT_TEXT_BUFFER_SIZE);
return;
}
me = getmntent(mtab);
me = getmntent(mtab);
// find our path in the mtab
search_path = strdup(path);
do {
while ((match = strcmp(search_path, me->mnt_dir))
&& getmntent(mtab));
if (!match)
break;
fseek(mtab, 0, SEEK_SET);
slash = strrchr(search_path, '/');
if (slash == NULL)
CRIT_ERR(NULL, NULL, "invalid path '%s'", path);
if (strlen(slash) == 1) /* trailing slash */
*(slash) = '\0';
else if (strlen(slash) > 1)
*(slash + 1) = '\0';
else
CRIT_ERR(NULL, NULL, "found a crack in the matrix!");
} while (strlen(search_path) > 0);
free(search_path);
// find our path in the mtab
search_path = strdup(path);
do {
while ((match = strcmp(search_path, me->mnt_dir)) && getmntent(mtab))
;
if (!match) break;
fseek(mtab, 0, SEEK_SET);
slash = strrchr(search_path, '/');
if (slash == NULL) CRIT_ERR(NULL, NULL, "invalid path '%s'", path);
if (strlen(slash) == 1) /* trailing slash */
*(slash) = '\0';
else if (strlen(slash) > 1)
*(slash + 1) = '\0';
else
CRIT_ERR(NULL, NULL, "found a crack in the matrix!");
} while (strlen(search_path) > 0);
free(search_path);
endmntent(mtab);
endmntent(mtab);
if (me && !match) {
strncpy(result, me->mnt_type, DEFAULT_TEXT_BUFFER_SIZE);
return;
}
#endif /* HAVE_STRUCT_STATFS_F_FSTYPENAME */
strncpy(result, "unknown", DEFAULT_TEXT_BUFFER_SIZE);
if (me && !match) {
strncpy(result, me->mnt_type, DEFAULT_TEXT_BUFFER_SIZE);
return;
}
#endif /* HAVE_STRUCT_STATFS_F_FSTYPENAME */
strncpy(result, "unknown", DEFAULT_TEXT_BUFFER_SIZE);
}
void init_fs_bar(struct text_object *obj, const char *arg)
{
arg = scan_bar(obj, arg, 1);
if (arg) {
while (isspace(*arg)) {
arg++;
}
if (*arg == '\0') {
arg = "/";
}
} else {
arg = "/";
}
obj->data.opaque = prepare_fs_stat(arg);
void init_fs_bar(struct text_object *obj, const char *arg) {
arg = scan_bar(obj, arg, 1);
if (arg) {
while (isspace(*arg)) {
arg++;
}
if (*arg == '\0') {
arg = "/";
}
} else {
arg = "/";
}
obj->data.opaque = prepare_fs_stat(arg);
}
static double get_fs_perc(struct text_object *obj, bool get_free)
{
struct fs_stat *fs = static_cast<struct fs_stat *>(obj->data.opaque);
double ret = 0.0;
static double get_fs_perc(struct text_object *obj, bool get_free) {
struct fs_stat *fs = static_cast<struct fs_stat *>(obj->data.opaque);
double ret = 0.0;
if(fs && fs->size) {
if(get_free)
ret = fs->avail;
else
ret = fs->size - fs->free;
ret /= fs->size;
}
if (fs && fs->size) {
if (get_free)
ret = fs->avail;
else
ret = fs->size - fs->free;
ret /= fs->size;
}
return ret;
return ret;
}
double fs_barval(struct text_object *obj)
{
return get_fs_perc(obj, false);
double fs_barval(struct text_object *obj) { return get_fs_perc(obj, false); }
double fs_free_barval(struct text_object *obj) {
return get_fs_perc(obj, true);
}
double fs_free_barval(struct text_object *obj)
{
return get_fs_perc(obj, true);
void init_fs(struct text_object *obj, const char *arg) {
obj->data.opaque = prepare_fs_stat(arg ? arg : "/");
}
void init_fs(struct text_object *obj, const char *arg)
{
obj->data.opaque = prepare_fs_stat(arg ? arg : "/");
uint8_t fs_free_percentage(struct text_object *obj) {
return get_fs_perc(obj, true) * 100;
}
uint8_t fs_free_percentage(struct text_object *obj)
{
return get_fs_perc(obj, true) * 100;
uint8_t fs_used_percentage(struct text_object *obj) {
return get_fs_perc(obj, false) * 100;
}
uint8_t fs_used_percentage(struct text_object *obj)
{
return get_fs_perc(obj, false) * 100;
}
#define HUMAN_PRINT_FS_GENERATOR(name, expr) \
void print_fs_##name(struct text_object *obj, char *p, int p_max_size) \
{ \
struct fs_stat *fs = (struct fs_stat *)obj->data.opaque; \
if (fs) \
human_readable(expr, p, p_max_size); \
}
#define HUMAN_PRINT_FS_GENERATOR(name, expr) \
void print_fs_##name(struct text_object *obj, char *p, int p_max_size) { \
struct fs_stat *fs = (struct fs_stat *)obj->data.opaque; \
if (fs) human_readable(expr, p, p_max_size); \
}
HUMAN_PRINT_FS_GENERATOR(free, fs->avail)
HUMAN_PRINT_FS_GENERATOR(size, fs->size)
HUMAN_PRINT_FS_GENERATOR(used, fs->size - fs->free)
void print_fs_type(struct text_object *obj, char *p, int p_max_size)
{
struct fs_stat *fs = (struct fs_stat *)obj->data.opaque;
void print_fs_type(struct text_object *obj, char *p, int p_max_size) {
struct fs_stat *fs = (struct fs_stat *)obj->data.opaque;
if (fs)
snprintf(p, p_max_size, "%s", fs->type);
if (fs) snprintf(p, p_max_size, "%s", fs->type);
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -31,16 +30,16 @@
#ifndef _FS_H
#define _FS_H
#include "conky.h" /* DEFAULT_TEXT_BUFFER_SIZE */
#include "conky.h" /* DEFAULT_TEXT_BUFFER_SIZE */
/* needed here and by fs.c */
struct fs_stat {
char path[DEFAULT_TEXT_BUFFER_SIZE];
char type[DEFAULT_TEXT_BUFFER_SIZE];
long long size;
long long avail;
long long free;
char set;
char path[DEFAULT_TEXT_BUFFER_SIZE];
char type[DEFAULT_TEXT_BUFFER_SIZE];
long long size;
long long avail;
long long free;
char set;
};
/* forward declare to make gcc happy (fs.h <-> text_object.h include) */

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -30,257 +29,223 @@
#include <OS.h>
#include "haiku.h"
#include "conky.h"
#include "haiku.h"
#include "net_stat.h"
#include "top.h"
static short cpu_setup = 0;
void prepare_update()
{
void prepare_update() {}
int update_uptime() {
info.uptime = (double)system_time() / 1000000.0;
return 0;
}
int update_uptime()
{
info.uptime = (double)system_time() / 1000000.0;
return 0;
int check_mount(struct text_object *obj) {
/* stub */
(void)obj;
return 0;
}
int check_mount(struct text_object *obj)
{
/* stub */
(void)obj;
return 0;
int update_meminfo() {
system_info si;
if (get_system_info(&si) != B_OK) {
fprintf(stderr, "Cannot get_system_info\n");
return 1;
}
info.memmax = si.max_pages * (B_PAGE_SIZE >> 10);
info.mem = si.used_pages * (B_PAGE_SIZE >> 10);
// TODO: we have some more info...
info.memwithbuffers = info.mem;
info.memeasyfree = info.memfree = info.memmax - info.mem;
info.swapmax = si.max_swap_pages * (B_PAGE_SIZE >> 10);
info.swapfree = si.free_swap_pages * (B_PAGE_SIZE >> 10);
info.swap = (info.swapmax - info.swapfree);
return 0;
}
int update_meminfo()
{
system_info si;
if (get_system_info(&si) != B_OK) {
fprintf(stderr, "Cannot get_system_info\n");
return 1;
}
info.memmax = si.max_pages * (B_PAGE_SIZE >> 10);
info.mem = si.used_pages * (B_PAGE_SIZE >> 10);
// TODO: we have some more info...
info.memwithbuffers = info.mem;
info.memeasyfree = info.memfree = info.memmax - info.mem;
info.swapmax = si.max_swap_pages * (B_PAGE_SIZE >> 10);
info.swapfree = si.free_swap_pages * (B_PAGE_SIZE >> 10);
info.swap = (info.swapmax - info.swapfree);
return 0;
int update_net_stats() {
// TODO
return 1;
}
int update_net_stats()
{
// TODO
return 1;
int update_total_processes() {
// TODO
return 1;
}
int update_total_processes()
{
// TODO
return 1;
int update_running_processes() {
// TODO
return 1;
}
int update_running_processes()
{
// TODO
return 1;
void get_cpu_count(void) {
system_info si;
if (get_system_info(&si) != B_OK) {
fprintf(stderr, "Cannot get_system_info\n");
info.cpu_count = 0;
return;
}
info.cpu_count = si.cpu_count;
info.cpu_usage = (float *)malloc((info.cpu_count + 1) * sizeof(float));
if (info.cpu_usage == NULL) {
CRIT_ERR(NULL, NULL, "malloc");
}
}
void get_cpu_count(void)
{
system_info si;
int update_cpu_usage() {
// TODO
static bigtime_t prev = 0;
static cpu_info *prev_cpuinfo = NULL;
bigtime_t now;
cpu_info *cpuinfo;
if (get_system_info(&si) != B_OK) {
fprintf(stderr, "Cannot get_system_info\n");
info.cpu_count = 0;
return;
}
info.cpu_count = si.cpu_count;
/* add check for !info.cpu_usage since that mem is freed on a SIGUSR1 */
if ((cpu_setup == 0) || (!info.cpu_usage)) {
get_cpu_count();
cpu_setup = 1;
}
info.cpu_usage = (float *) malloc((info.cpu_count + 1) * sizeof(float));
if (info.cpu_usage == NULL) {
CRIT_ERR(NULL, NULL, "malloc");
}
int malloc_cpu_size = sizeof(cpu_info) * (info.cpu_count + 1);
if (!prev_cpuinfo) {
prev_cpuinfo = (cpu_info *)malloc(malloc_cpu_size);
if (prev_cpuinfo == NULL) {
CRIT_ERR(NULL, NULL, "malloc");
}
memset(prev_cpuinfo, 0, malloc_cpu_size);
}
cpuinfo = (cpu_info *)malloc(malloc_cpu_size);
memset(cpuinfo, 0, malloc_cpu_size);
if (cpuinfo == NULL) {
CRIT_ERR(NULL, NULL, "malloc");
}
now = system_time();
if (get_cpu_info(0, info.cpu_count, &cpuinfo[1]) == B_OK) {
for (int i = 1; i <= info.cpu_count; i++)
cpuinfo[0].active_time += cpuinfo[i].active_time;
cpuinfo[0].active_time /= info.cpu_count;
for (int i = 0; i <= info.cpu_count; i++) {
double period = (double)(now - prev);
info.cpu_usage[i] =
((double)(cpuinfo[i].active_time - prev_cpuinfo[i].active_time)) /
period;
}
}
memcpy(prev_cpuinfo, cpuinfo, malloc_cpu_size);
prev = now;
free(cpuinfo);
return 1;
}
int update_cpu_usage()
{
// TODO
static bigtime_t prev = 0;
static cpu_info *prev_cpuinfo = NULL;
bigtime_t now;
cpu_info *cpuinfo;
/* add check for !info.cpu_usage since that mem is freed on a SIGUSR1 */
if ((cpu_setup == 0) || (!info.cpu_usage)) {
get_cpu_count();
cpu_setup = 1;
}
int malloc_cpu_size = sizeof(cpu_info) * (info.cpu_count + 1);
if (!prev_cpuinfo) {
prev_cpuinfo = (cpu_info *)malloc(malloc_cpu_size);
if (prev_cpuinfo == NULL) {
CRIT_ERR(NULL, NULL, "malloc");
}
memset(prev_cpuinfo, 0, malloc_cpu_size);
}
cpuinfo = (cpu_info *)malloc(malloc_cpu_size);
memset(cpuinfo, 0, malloc_cpu_size);
if (cpuinfo == NULL) {
CRIT_ERR(NULL, NULL, "malloc");
}
now = system_time();
if (get_cpu_info(0, info.cpu_count, &cpuinfo[1]) == B_OK) {
for (int i = 1; i <= info.cpu_count; i++)
cpuinfo[0].active_time += cpuinfo[i].active_time;
cpuinfo[0].active_time /= info.cpu_count;
for (int i = 0; i <= info.cpu_count; i++) {
double period = (double)(now - prev);
info.cpu_usage[i] = ((double)
(cpuinfo[i].active_time - prev_cpuinfo[i].active_time)) /
period;
}
}
memcpy(prev_cpuinfo, cpuinfo, malloc_cpu_size);
prev = now;
free(cpuinfo);
return 1;
int update_load_average() {
// TODO
return 1;
}
int update_load_average()
{
// TODO
return 1;
double get_acpi_temperature(int fd) { return -1; }
void get_battery_stuff(char *buf, unsigned int n, const char *bat, int item) {
// TODO
}
double get_acpi_temperature(int fd)
{
return -1;
int get_battery_perct(const char *bat) {
/*
int batcapacity;
get_battery_stats(NULL, &batcapacity, NULL, NULL);
return batcapacity;
*/
// TODO
return 0;
}
void get_battery_stuff(char *buf, unsigned int n, const char *bat, int item)
{
// TODO
double get_battery_perct_bar(struct text_object *obj) {
int batperct = get_battery_perct(obj->data.s);
return batperct;
}
int get_battery_perct(const char *bat)
{
/*
int batcapacity;
int open_acpi_temperature(const char *name) { return -1; }
get_battery_stats(NULL, &batcapacity, NULL, NULL);
return batcapacity;
*/
// TODO
return 0;
}
void get_acpi_ac_adapter(char *p_client_buffer, size_t client_buffer_size,
const char *adapter) {
(void)adapter; // only linux uses this
double get_battery_perct_bar(struct text_object *obj)
{
int batperct = get_battery_perct(obj->data.s);
return batperct;
}
if (!p_client_buffer || client_buffer_size <= 0) {
return;
}
int open_acpi_temperature(const char *name)
{
return -1;
}
void get_acpi_ac_adapter(char *p_client_buffer, size_t client_buffer_size, const char *adapter)
{
(void) adapter; // only linux uses this
if (!p_client_buffer || client_buffer_size <= 0) {
return;
}
/* not implemented */
memset(p_client_buffer, 0, client_buffer_size);
/* not implemented */
memset(p_client_buffer, 0, client_buffer_size);
}
/* char *get_acpi_fan() */
void get_acpi_fan(char *p_client_buffer, size_t client_buffer_size)
{
if (!p_client_buffer || client_buffer_size <= 0) {
return;
}
void get_acpi_fan(char *p_client_buffer, size_t client_buffer_size) {
if (!p_client_buffer || client_buffer_size <= 0) {
return;
}
/* not implemented */
memset(p_client_buffer, 0, client_buffer_size);
/* not implemented */
memset(p_client_buffer, 0, client_buffer_size);
}
/* void */
char get_freq(char *p_client_buffer, size_t client_buffer_size, const char *p_format,
int divisor, unsigned int cpu)
{
int freq;
char *freq_sysctl;
char get_freq(char *p_client_buffer, size_t client_buffer_size,
const char *p_format, int divisor, unsigned int cpu) {
int freq;
char *freq_sysctl;
if (!p_client_buffer || client_buffer_size <= 0 || !p_format
|| divisor <= 0) {
return 0;
}
return 0;
// TODO
// return 1;
if (!p_client_buffer || client_buffer_size <= 0 || !p_format ||
divisor <= 0) {
return 0;
}
return 0;
// TODO
// return 1;
}
int update_diskio(void)
{
return 1;
int update_diskio(void) { return 1; }
void get_top_info(void) {
int32 tmcookie = 0;
team_info tm;
struct process *proc;
while (get_next_team_info(&tmcookie, &tm) == B_NO_ERROR) {
team_usage_info ti;
if (get_team_usage_info(tm.team, B_TEAM_USAGE_SELF, &ti) != B_OK) continue;
proc = get_process(tm.team);
proc->time_stamp = g_time;
proc->name = strndup(tm.args, sizeof(tm.args));
proc->basename = strndup(tm.args, sizeof(tm.args));
// proc->amount = 100.0 * p[i].ki_pctcpu / FSCALE;
proc->vsize = 0;
proc->rss = 0;
/* bigtime_t is in microseconds, total_cpu_time in centiseconds.
* Therefore we divide by 10000. */
proc->total_cpu_time = (ti.user_time + ti.kernel_time) / 10000;
}
}
void get_top_info(void)
{
int32 tmcookie = 0;
team_info tm;
struct process *proc;
while (get_next_team_info(&tmcookie, &tm) == B_NO_ERROR) {
team_usage_info ti;
if (get_team_usage_info(tm.team, B_TEAM_USAGE_SELF, &ti) != B_OK)
continue;
proc = get_process(tm.team);
proc->time_stamp = g_time;
proc->name = strndup(tm.args, sizeof(tm.args));
proc->basename = strndup(tm.args, sizeof(tm.args));
//proc->amount = 100.0 * p[i].ki_pctcpu / FSCALE;
proc->vsize = 0;
proc->rss = 0;
/* bigtime_t is in microseconds, total_cpu_time in centiseconds.
* Therefore we divide by 10000. */
proc->total_cpu_time = (ti.user_time + ti.kernel_time) / 10000;
}
void get_battery_short_status(char *buffer, unsigned int n, const char *bat) {
// TODO
}
void get_battery_short_status(char *buffer, unsigned int n, const char *bat)
{
// TODO
}
int get_entropy_avail(unsigned int *val) { return 1; }
int get_entropy_avail(unsigned int *val)
{
return 1;
}
int get_entropy_poolsize(unsigned int *val)
{
return 1;
}
int get_entropy_poolsize(unsigned int *val) { return 1; }

View File

@@ -1,37 +1,35 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*- */
/* */
#ifndef HAIKU_H_
#define HAIKU_H_
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <err.h>
#include <fcntl.h>
#include <limits.h>
#include <paths.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <kernel/fs_info.h>
#include "conky.h"
#include "common.h"
#include "conky.h"
int get_entropy_avail(unsigned int *);
int get_entropy_poolsize(unsigned int *);
/* let's just mimic statfs64 */
struct statfs : public fs_info {};
inline int statfs(const char *path, struct statfs *buf)
{
return fs_stat_dev(dev_for_path(path), buf);
inline int statfs(const char *path, struct statfs *buf) {
return fs_stat_dev(dev_for_path(path), buf);
}
#define f_blocks total_blocks
@@ -40,5 +38,4 @@ inline int statfs(const char *path, struct statfs *buf)
#define f_bfree free_blocks
#define f_fstypename fsh_name
#endif /*HAIKU_H_*/

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -28,114 +27,107 @@
*
*/
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>
#include "conky.h"
#include "logging.h"
#include "temphelper.h"
#include "text_object.h"
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define BUFLEN 512
static conky::simple_config_setting<std::string> hddtemp_host("hddtemp_host", "localhost", false);
static conky::simple_config_setting<std::string> hddtemp_port("hddtemp_port", "7634", false);
static conky::simple_config_setting<std::string> hddtemp_host("hddtemp_host",
"localhost",
false);
static conky::simple_config_setting<std::string> hddtemp_port("hddtemp_port",
"7634", false);
struct hdd_info {
hdd_info() : next(0) {}
struct hdd_info *next;
char *dev;
short temp;
char unit;
hdd_info() : next(0) {}
struct hdd_info *next;
char *dev;
short temp;
char unit;
};
struct hdd_info hdd_info_head;
static void __free_hddtemp_info(struct hdd_info *hdi)
{
if (hdi->next)
__free_hddtemp_info(hdi->next);
free(hdi->dev);
delete hdi;
static void __free_hddtemp_info(struct hdd_info *hdi) {
if (hdi->next) __free_hddtemp_info(hdi->next);
free(hdi->dev);
delete hdi;
}
static void free_hddtemp_info(void)
{
DBGP("free_hddtemp_info() called");
if (!hdd_info_head.next)
return;
__free_hddtemp_info(hdd_info_head.next);
hdd_info_head.next = NULL;
static void free_hddtemp_info(void) {
DBGP("free_hddtemp_info() called");
if (!hdd_info_head.next) return;
__free_hddtemp_info(hdd_info_head.next);
hdd_info_head.next = NULL;
}
static void add_hddtemp_info(char *dev, short temp, char unit)
{
struct hdd_info *hdi = &hdd_info_head;
static void add_hddtemp_info(char *dev, short temp, char unit) {
struct hdd_info *hdi = &hdd_info_head;
DBGP("add_hddtemp_info(%s, %d, %c) being called", dev, temp, unit);
while (hdi->next)
hdi = hdi->next;
DBGP("add_hddtemp_info(%s, %d, %c) being called", dev, temp, unit);
while (hdi->next) hdi = hdi->next;
hdi->next = new hdd_info;
memset(hdi->next, 0, sizeof(struct hdd_info));
hdi->next->dev = strdup(dev);
hdi->next->temp = temp;
hdi->next->unit = unit;
hdi->next = new hdd_info;
memset(hdi->next, 0, sizeof(struct hdd_info));
hdi->next->dev = strdup(dev);
hdi->next->temp = temp;
hdi->next->unit = unit;
}
static char *fetch_hddtemp_output(void)
{
int sockfd;
char *buf = NULL;
int buflen, offset = 0, rlen;
struct addrinfo hints, *result, *rp;
int i;
static char *fetch_hddtemp_output(void) {
int sockfd;
char *buf = NULL;
int buflen, offset = 0, rlen;
struct addrinfo hints, *result, *rp;
int i;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; /* XXX: hddtemp has no ipv6 support (yet?) */
hints.ai_socktype = SOCK_STREAM;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; /* XXX: hddtemp has no ipv6 support (yet?) */
hints.ai_socktype = SOCK_STREAM;
if ((i = getaddrinfo(hddtemp_host.get(*state).c_str(),
hddtemp_port.get(*state).c_str(), &hints, &result))) {
NORM_ERR("getaddrinfo(): %s", gai_strerror(i));
return NULL;
}
if ((i = getaddrinfo(hddtemp_host.get(*state).c_str(),
hddtemp_port.get(*state).c_str(), &hints, &result))) {
NORM_ERR("getaddrinfo(): %s", gai_strerror(i));
return NULL;
}
for (rp = result; rp; rp = rp->ai_next) {
sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sockfd == -1)
continue;
if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) != -1)
break;
close(sockfd);
}
if (!rp) {
NORM_ERR("could not connect to hddtemp host");
goto GET_OUT;
}
for (rp = result; rp; rp = rp->ai_next) {
sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sockfd == -1) continue;
if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) != -1) break;
close(sockfd);
}
if (!rp) {
NORM_ERR("could not connect to hddtemp host");
goto GET_OUT;
}
buflen = 1024;
buf = (char*)malloc(buflen);
while ((rlen = recv(sockfd, buf + offset, buflen - offset - 1, 0)) > 0) {
offset += rlen;
if (buflen - offset < 1) {
buflen += 1024;
buf = (char*)realloc(buf, buflen);
}
}
if (rlen < 0)
perror("recv");
buflen = 1024;
buf = (char *)malloc(buflen);
while ((rlen = recv(sockfd, buf + offset, buflen - offset - 1, 0)) > 0) {
offset += rlen;
if (buflen - offset < 1) {
buflen += 1024;
buf = (char *)realloc(buf, buflen);
}
}
if (rlen < 0) perror("recv");
buf[offset] = '\0';
buf[offset] = '\0';
close(sockfd);
close(sockfd);
GET_OUT:
freeaddrinfo(result);
return buf;
freeaddrinfo(result);
return buf;
}
/* this is an iterator:
@@ -144,111 +136,98 @@ GET_OUT:
* is not being freed!
*/
static int read_hdd_val(const char *line, char **dev, short *val, char *unit,
char **saveptr)
{
char *line_s, *cval, *endptr;
static char *p = 0;
char **saveptr) {
char *line_s, *cval, *endptr;
static char *p = 0;
if (line) {
*saveptr = strdup(line);
p = *saveptr;
}
line_s = *saveptr;
if (line) {
*saveptr = strdup(line);
p = *saveptr;
}
line_s = *saveptr;
again:
if(!*p)
goto out_fail;
/* read the device */
*dev = ++p;
if (!(p = strchr(p, line_s[0])))
goto out_fail;
*(p++) = '\0';
/* jump over the devname */
if (!(p = strchr(p, line_s[0])))
goto out_fail;
/* read the value */
cval = ++p;
if (!(p = strchr(p, line_s[0])))
goto out_fail;
*(p++) = '\0';
*unit = *(p++);
*val = strtol(cval, &endptr, 10);
if (*endptr) {
if (!(p = strchr(p, line_s[0])))
goto out_fail;
if (!*p) goto out_fail;
/* read the device */
*dev = ++p;
if (!(p = strchr(p, line_s[0]))) goto out_fail;
*(p++) = '\0';
/* jump over the devname */
if (!(p = strchr(p, line_s[0]))) goto out_fail;
/* read the value */
cval = ++p;
if (!(p = strchr(p, line_s[0]))) goto out_fail;
*(p++) = '\0';
*unit = *(p++);
*val = strtol(cval, &endptr, 10);
if (*endptr) {
if (!(p = strchr(p, line_s[0]))) goto out_fail;
p++;
goto again;
}
/* preset p for next call */
p++;
p++;
goto again;
}
return 0;
/* preset p for next call */
p++;
return 0;
out_fail:
free(*saveptr);
return 1;
free(*saveptr);
return 1;
}
int update_hddtemp(void) {
char *data, *dev, unit, *saveptr;
short val;
static double last_hddtemp_update = 0.0;
char *data, *dev, unit, *saveptr;
short val;
static double last_hddtemp_update = 0.0;
/* limit tcp connection overhead */
if (current_update_time - last_hddtemp_update < 5)
return 0;
last_hddtemp_update = current_update_time;
/* limit tcp connection overhead */
if (current_update_time - last_hddtemp_update < 5) return 0;
last_hddtemp_update = current_update_time;
free_hddtemp_info();
free_hddtemp_info();
if (!(data = fetch_hddtemp_output()))
return 0;
if (!(data = fetch_hddtemp_output())) return 0;
if (read_hdd_val(data, &dev, &val, &unit, &saveptr)) {
free(data);
return 0;
}
do {
add_hddtemp_info(dev, val, unit);
} while (!read_hdd_val(NULL, &dev, &val, &unit, &saveptr));
free(data);
return 0;
if (read_hdd_val(data, &dev, &val, &unit, &saveptr)) {
free(data);
return 0;
}
do {
add_hddtemp_info(dev, val, unit);
} while (!read_hdd_val(NULL, &dev, &val, &unit, &saveptr));
free(data);
return 0;
}
void free_hddtemp(struct text_object *obj)
{
free_hddtemp_info();
free_and_zero(obj->data.s);
void free_hddtemp(struct text_object *obj) {
free_hddtemp_info();
free_and_zero(obj->data.s);
}
static int get_hddtemp_info(const char *dev, short *val, char *unit)
{
struct hdd_info *hdi = hdd_info_head.next;
static int get_hddtemp_info(const char *dev, short *val, char *unit) {
struct hdd_info *hdi = hdd_info_head.next;
/* if no dev is given, just use hdd_info_head->next */
while(dev && hdi) {
if (!strcmp(dev, hdi->dev))
break;
hdi = hdi->next;
}
if (!hdi)
return 1;
*val = hdi->temp;
*unit = hdi->unit;
return 0;
/* if no dev is given, just use hdd_info_head->next */
while (dev && hdi) {
if (!strcmp(dev, hdi->dev)) break;
hdi = hdi->next;
}
if (!hdi) return 1;
*val = hdi->temp;
*unit = hdi->unit;
return 0;
}
void print_hddtemp(struct text_object *obj, char *p, int p_max_size)
{
short val;
char unit;
void print_hddtemp(struct text_object *obj, char *p, int p_max_size) {
short val;
char unit;
if (get_hddtemp_info(obj->data.s, &val, &unit)) {
snprintf(p, p_max_size, "N/A");
} else {
temp_print(p, p_max_size, (double)val,
(unit == 'C' ? TEMP_CELSIUS : TEMP_FAHRENHEIT));
}
if (get_hddtemp_info(obj->data.s, &val, &unit)) {
snprintf(p, p_max_size, "N/A");
} else {
temp_print(p, p_max_size, (double)val,
(unit == 'C' ? TEMP_CELSIUS : TEMP_FAHRENHEIT));
}
}

View File

@@ -1,12 +1,11 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2007 Toni Spets
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -11,7 +10,7 @@
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2007 Toni Spets
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -38,117 +37,113 @@
#include "text_object.h"
struct _i8k {
char *version;
char *bios;
char *serial;
char *cpu_temp;
char *left_fan_status;
char *right_fan_status;
char *left_fan_rpm;
char *right_fan_rpm;
char *ac_status;
char *buttons_status;
char *version;
char *bios;
char *serial;
char *cpu_temp;
char *left_fan_status;
char *right_fan_status;
char *left_fan_rpm;
char *right_fan_rpm;
char *ac_status;
char *buttons_status;
} i8k;
/* FIXME: there should be an ioctl interface to request specific data */
#define PROC_I8K "/proc/i8k"
#define I8K_DELIM " "
static char *i8k_procbuf = NULL;
int update_i8k(void)
{
FILE *fp;
int update_i8k(void) {
FILE *fp;
if (!i8k_procbuf) {
i8k_procbuf = (char *) malloc(128 * sizeof(char));
}
if ((fp = fopen(PROC_I8K, "r")) == NULL) {
free_and_zero(i8k_procbuf);
/*THREAD_CRIT_ERR(NULL, NULL, "/proc/i8k doesn't exist! use insmod to make sure the kernel "
"driver is loaded...");*/
NORM_ERR("/proc/i8k doesn't exist! use insmod to make sure the kernel driver is loaded...");
clean_up_without_threads(NULL, NULL);
return 1;
}
if (!i8k_procbuf) {
i8k_procbuf = (char *)malloc(128 * sizeof(char));
}
if ((fp = fopen(PROC_I8K, "r")) == NULL) {
free_and_zero(i8k_procbuf);
/*THREAD_CRIT_ERR(NULL, NULL, "/proc/i8k doesn't exist! use insmod to make
sure the kernel " "driver is loaded...");*/
NORM_ERR(
"/proc/i8k doesn't exist! use insmod to make sure the kernel driver is "
"loaded...");
clean_up_without_threads(NULL, NULL);
return 1;
}
memset(&i8k_procbuf[0], 0, 128);
if (fread(&i8k_procbuf[0], sizeof(char), 128, fp) == 0) {
NORM_ERR("something wrong with /proc/i8k...");
}
memset(&i8k_procbuf[0], 0, 128);
if (fread(&i8k_procbuf[0], sizeof(char), 128, fp) == 0) {
NORM_ERR("something wrong with /proc/i8k...");
}
fclose(fp);
fclose(fp);
DBGP("read `%s' from /proc/i8k\n", i8k_procbuf);
DBGP("read `%s' from /proc/i8k\n", i8k_procbuf);
i8k.version = strtok(&i8k_procbuf[0], I8K_DELIM);
i8k.bios = strtok(NULL, I8K_DELIM);
i8k.serial = strtok(NULL, I8K_DELIM);
i8k.cpu_temp = strtok(NULL, I8K_DELIM);
i8k.left_fan_status = strtok(NULL, I8K_DELIM);
i8k.right_fan_status = strtok(NULL, I8K_DELIM);
i8k.left_fan_rpm = strtok(NULL, I8K_DELIM);
i8k.right_fan_rpm = strtok(NULL, I8K_DELIM);
i8k.ac_status = strtok(NULL, I8K_DELIM);
i8k.buttons_status = strtok(NULL, I8K_DELIM);
return 0;
i8k.version = strtok(&i8k_procbuf[0], I8K_DELIM);
i8k.bios = strtok(NULL, I8K_DELIM);
i8k.serial = strtok(NULL, I8K_DELIM);
i8k.cpu_temp = strtok(NULL, I8K_DELIM);
i8k.left_fan_status = strtok(NULL, I8K_DELIM);
i8k.right_fan_status = strtok(NULL, I8K_DELIM);
i8k.left_fan_rpm = strtok(NULL, I8K_DELIM);
i8k.right_fan_rpm = strtok(NULL, I8K_DELIM);
i8k.ac_status = strtok(NULL, I8K_DELIM);
i8k.buttons_status = strtok(NULL, I8K_DELIM);
return 0;
}
static void print_i8k_fan_status(char *p, int p_max_size, const char *status)
{
static const char *status_arr[] = { "off", "low", "high", "error" };
static void print_i8k_fan_status(char *p, int p_max_size, const char *status) {
static const char *status_arr[] = {"off", "low", "high", "error"};
int i = status ? atoi(status) : 3;
if(i < 0 || i > 3)
i = 3;
int i = status ? atoi(status) : 3;
if (i < 0 || i > 3) i = 3;
snprintf(p, p_max_size, "%s", status_arr[i]);
snprintf(p, p_max_size, "%s", status_arr[i]);
}
void print_i8k_left_fan_status(struct text_object *obj, char *p, int p_max_size)
{
(void)obj;
print_i8k_fan_status(p, p_max_size, i8k.left_fan_status);
void print_i8k_left_fan_status(struct text_object *obj, char *p,
int p_max_size) {
(void)obj;
print_i8k_fan_status(p, p_max_size, i8k.left_fan_status);
}
void print_i8k_cpu_temp(struct text_object *obj, char *p, int p_max_size)
{
int cpu_temp;
void print_i8k_cpu_temp(struct text_object *obj, char *p, int p_max_size) {
int cpu_temp;
(void)obj;
(void)obj;
sscanf(i8k.cpu_temp, "%d", &cpu_temp);
temp_print(p, p_max_size, (double)cpu_temp, TEMP_CELSIUS);
sscanf(i8k.cpu_temp, "%d", &cpu_temp);
temp_print(p, p_max_size, (double)cpu_temp, TEMP_CELSIUS);
}
void print_i8k_right_fan_status(struct text_object *obj, char *p, int p_max_size)
{
(void)obj;
print_i8k_fan_status(p, p_max_size, i8k.right_fan_status);
void print_i8k_right_fan_status(struct text_object *obj, char *p,
int p_max_size) {
(void)obj;
print_i8k_fan_status(p, p_max_size, i8k.right_fan_status);
}
void print_i8k_ac_status(struct text_object *obj, char *p, int p_max_size)
{
int ac_status;
void print_i8k_ac_status(struct text_object *obj, char *p, int p_max_size) {
int ac_status;
(void)obj;
(void)obj;
sscanf(i8k.ac_status, "%d", &ac_status);
if (ac_status == -1) {
snprintf(p, p_max_size, "disabled (read i8k docs)");
}
if (ac_status == 0) {
snprintf(p, p_max_size, "off");
}
if (ac_status == 1) {
snprintf(p, p_max_size, "on");
}
sscanf(i8k.ac_status, "%d", &ac_status);
if (ac_status == -1) {
snprintf(p, p_max_size, "disabled (read i8k docs)");
}
if (ac_status == 0) {
snprintf(p, p_max_size, "off");
}
if (ac_status == 1) {
snprintf(p, p_max_size, "on");
}
}
#define I8K_PRINT_GENERATOR(name) \
void print_i8k_##name(struct text_object *obj, char *p, int p_max_size) \
{ \
(void)obj; \
snprintf(p, p_max_size, "%s", i8k.name); \
}
#define I8K_PRINT_GENERATOR(name) \
void print_i8k_##name(struct text_object *obj, char *p, int p_max_size) { \
(void)obj; \
snprintf(p, p_max_size, "%s", i8k.name); \
}
I8K_PRINT_GENERATOR(version)
I8K_PRINT_GENERATOR(bios)

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -11,7 +10,7 @@
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2007 Toni Spets
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -11,7 +10,7 @@
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2007 Toni Spets
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -29,16 +28,16 @@
*
*/
#include "conky.h"
#include "config.h"
#include "ibm.h"
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "conky.h"
#include "logging.h"
#include "temphelper.h"
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
static int ibm_acpi_temps[8];
@@ -73,39 +72,40 @@ speed: 2944
commands: enable, disable
* Peter Tarjan (ptarjan@citromail.hu) */
void get_ibm_acpi_fan(struct text_object *obj, char *p, int p_max_size)
{
FILE *fp;
unsigned int speed = 0;
char fan[128];
void get_ibm_acpi_fan(struct text_object *obj, char *p, int p_max_size) {
FILE *fp;
unsigned int speed = 0;
char fan[128];
(void)obj;
(void)obj;
if (!p || p_max_size <= 0) {
return;
}
if (!p || p_max_size <= 0) {
return;
}
snprintf(fan, 127, "%s/fan", IBM_ACPI_DIR);
snprintf(fan, 127, "%s/fan", IBM_ACPI_DIR);
fp = fopen(fan, "r");
if (fp != NULL) {
while (!feof(fp)) {
char line[256];
fp = fopen(fan, "r");
if (fp != NULL) {
while (!feof(fp)) {
char line[256];
if (fgets(line, 255, fp) == NULL) {
break;
}
if (sscanf(line, "speed: %u", &speed)) {
break;
}
}
} else {
CRIT_ERR(NULL, NULL, "can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
"ibm* from your " PACKAGE_NAME" config file.", fan, strerror(errno));
}
if (fgets(line, 255, fp) == NULL) {
break;
}
if (sscanf(line, "speed: %u", &speed)) {
break;
}
}
} else {
CRIT_ERR(NULL, NULL,
"can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
"ibm* from your " PACKAGE_NAME " config file.",
fan, strerror(errno));
}
fclose(fp);
snprintf(p, p_max_size, "%d", speed);
fclose(fp);
snprintf(p, p_max_size, "%d", speed);
}
/* get the measured temperatures from the temperature sensors
@@ -129,36 +129,36 @@ void get_ibm_acpi_fan(struct text_object *obj, char *p, int p_max_size)
temperatures: 41 43 31 46 33 -128 29 -128
* Peter Tarjan (ptarjan@citromail.hu) */
int get_ibm_acpi_temps(void)
{
int get_ibm_acpi_temps(void) {
FILE *fp;
char thermal[128];
FILE *fp;
char thermal[128];
snprintf(thermal, 127, "%s/thermal", IBM_ACPI_DIR);
fp = fopen(thermal, "r");
snprintf(thermal, 127, "%s/thermal", IBM_ACPI_DIR);
fp = fopen(thermal, "r");
if (fp != NULL) {
while (!feof(fp)) {
char line[256];
if (fp != NULL) {
while (!feof(fp)) {
char line[256];
if (fgets(line, 255, fp) == NULL) {
break;
}
if (sscanf(line, "temperatures: %d %d %d %d %d %d %d %d",
&ibm_acpi_temps[0], &ibm_acpi_temps[1], &ibm_acpi_temps[2],
&ibm_acpi_temps[3], &ibm_acpi_temps[4], &ibm_acpi_temps[5],
&ibm_acpi_temps[6], &ibm_acpi_temps[7])) {
break;
}
}
} else {
CRIT_ERR(NULL, NULL,
"can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
"ibm* from your " PACKAGE_NAME " config file.",
thermal, strerror(errno));
}
if (fgets(line, 255, fp) == NULL) {
break;
}
if (sscanf(line, "temperatures: %d %d %d %d %d %d %d %d",
&ibm_acpi_temps[0], &ibm_acpi_temps[1], &ibm_acpi_temps[2],
&ibm_acpi_temps[3], &ibm_acpi_temps[4], &ibm_acpi_temps[5],
&ibm_acpi_temps[6], &ibm_acpi_temps[7])) {
break;
}
}
} else {
CRIT_ERR(NULL, NULL, "can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
"ibm* from your " PACKAGE_NAME" config file.", thermal, strerror(errno));
}
fclose(fp);
return 0;
fclose(fp);
return 0;
}
/* get volume (0-14) on IBM/Lenovo laptops running the ibm acpi.
@@ -171,49 +171,50 @@ commands: up, down, mute
commands: level <level> (<level> is 0-15)
* Peter Tarjan (ptarjan@citromail.hu) */
void get_ibm_acpi_volume(struct text_object *obj, char *p, int p_max_size)
{
FILE *fp;
char volume[128];
unsigned int vol = -1;
char mute[3] = "";
void get_ibm_acpi_volume(struct text_object *obj, char *p, int p_max_size) {
FILE *fp;
char volume[128];
unsigned int vol = -1;
char mute[3] = "";
(void)obj;
(void)obj;
if (!p || p_max_size <= 0) {
return;
}
if (!p || p_max_size <= 0) {
return;
}
snprintf(volume, 127, "%s/volume", IBM_ACPI_DIR);
snprintf(volume, 127, "%s/volume", IBM_ACPI_DIR);
fp = fopen(volume, "r");
if (fp != NULL) {
while (!feof(fp)) {
char line[256];
unsigned int read_vol = -1;
fp = fopen(volume, "r");
if (fp != NULL) {
while (!feof(fp)) {
char line[256];
unsigned int read_vol = -1;
if (fgets(line, 255, fp) == NULL) {
break;
}
if (sscanf(line, "level: %u", &read_vol)) {
vol = read_vol;
continue;
}
if (sscanf(line, "mute: %s", mute)) {
break;
}
}
} else {
CRIT_ERR(NULL, NULL, "can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
"ibm* from your " PACKAGE_NAME" config file.", volume, strerror(errno));
}
if (fgets(line, 255, fp) == NULL) {
break;
}
if (sscanf(line, "level: %u", &read_vol)) {
vol = read_vol;
continue;
}
if (sscanf(line, "mute: %s", mute)) {
break;
}
}
} else {
CRIT_ERR(NULL, NULL,
"can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
"ibm* from your " PACKAGE_NAME " config file.",
volume, strerror(errno));
}
fclose(fp);
fclose(fp);
if (strcmp(mute, "on") == 0)
snprintf(p, p_max_size, "%s", "mute");
else
snprintf(p, p_max_size, "%d", vol);
if (strcmp(mute, "on") == 0)
snprintf(p, p_max_size, "%s", "mute");
else
snprintf(p, p_max_size, "%d", vol);
}
/* static FILE *fp = NULL; */
@@ -225,40 +226,41 @@ commands: up, down
commands: level <level> (<level> is 0-7)
* Peter Tarjan (ptarjan@citromail.hu) */
void get_ibm_acpi_brightness(struct text_object *obj, char *p, int p_max_size)
{
FILE *fp;
unsigned int brightness = 0;
char filename[128];
void get_ibm_acpi_brightness(struct text_object *obj, char *p, int p_max_size) {
FILE *fp;
unsigned int brightness = 0;
char filename[128];
(void)obj;
(void)obj;
if (!p || p_max_size <= 0) {
return;
}
if (!p || p_max_size <= 0) {
return;
}
snprintf(filename, 127, "%s/brightness", IBM_ACPI_DIR);
snprintf(filename, 127, "%s/brightness", IBM_ACPI_DIR);
fp = fopen(filename, "r");
if (fp != NULL) {
while (!feof(fp)) {
char line[256];
fp = fopen(filename, "r");
if (fp != NULL) {
while (!feof(fp)) {
char line[256];
if (fgets(line, 255, fp) == NULL) {
break;
}
if (sscanf(line, "level: %u", &brightness)) {
break;
}
}
} else {
CRIT_ERR(NULL, NULL, "can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
"ibm* from your " PACKAGE_NAME" config file.", filename, strerror(errno));
}
if (fgets(line, 255, fp) == NULL) {
break;
}
if (sscanf(line, "level: %u", &brightness)) {
break;
}
}
} else {
CRIT_ERR(NULL, NULL,
"can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
"ibm* from your " PACKAGE_NAME " config file.",
filename, strerror(errno));
}
fclose(fp);
fclose(fp);
snprintf(p, p_max_size, "%d", brightness);
snprintf(p, p_max_size, "%d", brightness);
}
/* get ThinkLight status on IBM/Lenovo laptops running the ibm acpi.
@@ -269,53 +271,52 @@ commands: on, off
* get "unknown" for a few models that do not make the status available.
* Lluis Esquerda (eskerda@gmail.com) */
void get_ibm_acpi_thinklight(struct text_object *obj, char *p, int p_max_size)
{
FILE *fp;
char thinklight[8];
char filename[128];
void get_ibm_acpi_thinklight(struct text_object *obj, char *p, int p_max_size) {
FILE *fp;
char thinklight[8];
char filename[128];
(void)obj;
(void)obj;
if (!p || p_max_size <= 0) {
return;
}
if (!p || p_max_size <= 0) {
return;
}
snprintf(filename, 127, "%s/light", IBM_ACPI_DIR);
snprintf(filename, 127, "%s/light", IBM_ACPI_DIR);
fp = fopen(filename, "r");
if (fp != NULL) {
while (!feof(fp)) {
char line[256];
fp = fopen(filename, "r");
if (fp != NULL) {
while (!feof(fp)) {
char line[256];
if (fgets(line, 255, fp) == NULL) {
break;
}
if (sscanf(line, "status: %s", thinklight)) {
break;
}
}
} else {
CRIT_ERR(NULL, NULL, "can't open '%s': %s\nYou are not using the IBM "
"ACPI. Remove ibm* from your " PACKAGE_NAME" config file.",
filename, strerror(errno));
}
if (fgets(line, 255, fp) == NULL) {
break;
}
if (sscanf(line, "status: %s", thinklight)) {
break;
}
}
} else {
CRIT_ERR(NULL, NULL,
"can't open '%s': %s\nYou are not using the IBM "
"ACPI. Remove ibm* from your " PACKAGE_NAME " config file.",
filename, strerror(errno));
}
fclose(fp);
snprintf(p, p_max_size, "%s", thinklight);
fclose(fp);
snprintf(p, p_max_size, "%s", thinklight);
}
void parse_ibm_temps_arg(struct text_object *obj, const char *arg)
{
if (!isdigit(arg[0]) || strlen(arg) > 1 || atoi(&arg[0]) >= 8) {
obj->data.l = 0;
NORM_ERR("Invalid temperature sensor! Sensor number must be 0 to 7. "
"Using 0 (CPU temp sensor).");
} else
obj->data.l = atoi(arg);
void parse_ibm_temps_arg(struct text_object *obj, const char *arg) {
if (!isdigit(arg[0]) || strlen(arg) > 1 || atoi(&arg[0]) >= 8) {
obj->data.l = 0;
NORM_ERR(
"Invalid temperature sensor! Sensor number must be 0 to 7. "
"Using 0 (CPU temp sensor).");
} else
obj->data.l = atoi(arg);
}
void print_ibm_temps(struct text_object *obj, char *p, int p_max_size)
{
temp_print(p, p_max_size, ibm_acpi_temps[obj->data.l], TEMP_CELSIUS);
void print_ibm_temps(struct text_object *obj, char *p, int p_max_size) {
temp_print(p, p_max_size, ibm_acpi_temps[obj->data.l], TEMP_CELSIUS);
}

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -28,157 +27,168 @@
#include "logging.h"
struct ical_event {
icaltimetype start;
icalcomponent *event;
ical_event *next, *prev;
icaltimetype start;
icalcomponent *event;
ical_event *next, *prev;
};
struct obj_ical {
struct ical_event *list;
icalcomponent *comps;
icalparser *parser;
unsigned int num;
struct ical_event *list;
icalcomponent *comps;
icalparser *parser;
unsigned int num;
};
char* read_stream(char *s, size_t size, void *d) {
return fgets(s, size, (FILE*) d);
char *read_stream(char *s, size_t size, void *d) {
return fgets(s, size, (FILE *)d);
}
struct ical_event *add_event(struct ical_event *listend, icalcomponent *new_ev) {
struct ical_event *ev_new, *ev_cur;
icaltimetype start;
struct ical_event *add_event(struct ical_event *listend,
icalcomponent *new_ev) {
struct ical_event *ev_new, *ev_cur;
icaltimetype start;
start = icalcomponent_get_dtstart(new_ev);
if(icaltime_compare(start, icaltime_from_timet_with_zone(time(NULL), 0, NULL)) <= 0) {
icalproperty *rrule = icalcomponent_get_first_property(new_ev, ICAL_RRULE_PROPERTY);
if(rrule) {
icalrecur_iterator* ritr = icalrecur_iterator_new(icalproperty_get_rrule(rrule), start);
icaltimetype nexttime = icalrecur_iterator_next(ritr);
while (!icaltime_is_null_time(nexttime)) {
if(icaltime_compare(nexttime, icaltime_from_timet_with_zone(time(NULL), 0, NULL)) > 0) {
start = nexttime;
break;
}
nexttime = icalrecur_iterator_next(ritr);
}
icalrecur_iterator_free(ritr);
} else return NULL;
}
ev_new = (struct ical_event *) malloc(sizeof(struct ical_event));
memset(ev_new, 0, sizeof(struct ical_event));
ev_new->event = new_ev;
ev_new->start = start;
if(listend) { //list already contains events
ev_cur = listend;
while(icaltime_compare(ev_new->start, ev_cur->start) <= 0) {
if( ! ev_cur->prev) { //ev_new starts first
ev_new->next = ev_cur;
ev_cur->prev = ev_new;
return listend;
}
ev_cur = ev_cur->prev;
}
if(ev_cur == listend) { //ev_new starts last
ev_cur->next = ev_new;
ev_new->prev = ev_cur;
return ev_new;
}
//ev_new somewhere in the middle
ev_new->prev = ev_cur;
ev_new->next = ev_cur->next;
ev_cur->next->prev = ev_new;
ev_cur->next = ev_new;
return listend;
}
return ev_new;
start = icalcomponent_get_dtstart(new_ev);
if (icaltime_compare(
start, icaltime_from_timet_with_zone(time(NULL), 0, NULL)) <= 0) {
icalproperty *rrule =
icalcomponent_get_first_property(new_ev, ICAL_RRULE_PROPERTY);
if (rrule) {
icalrecur_iterator *ritr =
icalrecur_iterator_new(icalproperty_get_rrule(rrule), start);
icaltimetype nexttime = icalrecur_iterator_next(ritr);
while (!icaltime_is_null_time(nexttime)) {
if (icaltime_compare(nexttime, icaltime_from_timet_with_zone(
time(NULL), 0, NULL)) > 0) {
start = nexttime;
break;
}
nexttime = icalrecur_iterator_next(ritr);
}
icalrecur_iterator_free(ritr);
} else
return NULL;
}
ev_new = (struct ical_event *)malloc(sizeof(struct ical_event));
memset(ev_new, 0, sizeof(struct ical_event));
ev_new->event = new_ev;
ev_new->start = start;
if (listend) { // list already contains events
ev_cur = listend;
while (icaltime_compare(ev_new->start, ev_cur->start) <= 0) {
if (!ev_cur->prev) { // ev_new starts first
ev_new->next = ev_cur;
ev_cur->prev = ev_new;
return listend;
}
ev_cur = ev_cur->prev;
}
if (ev_cur == listend) { // ev_new starts last
ev_cur->next = ev_new;
ev_new->prev = ev_cur;
return ev_new;
}
// ev_new somewhere in the middle
ev_new->prev = ev_cur;
ev_new->next = ev_cur->next;
ev_cur->next->prev = ev_new;
ev_cur->next = ev_new;
return listend;
}
return ev_new;
}
void parse_ical_args(struct text_object *obj, const char* arg, void *free_at_crash, void *free_at_crash2) {
char *filename = strdup(arg);
FILE *file;
icalparser *parser;
icalcomponent *allc, *curc;
struct ical_event *ll_start, *ll_end, *ll_new;
struct obj_ical *opaque;
unsigned int num;
void parse_ical_args(struct text_object *obj, const char *arg,
void *free_at_crash, void *free_at_crash2) {
char *filename = strdup(arg);
FILE *file;
icalparser *parser;
icalcomponent *allc, *curc;
struct ical_event *ll_start, *ll_end, *ll_new;
struct obj_ical *opaque;
unsigned int num;
if(sscanf(arg , "%d %s", &num, filename) != 2) {
free(filename);
free(obj);
CRIT_ERR(free_at_crash, free_at_crash2, "wrong number of arguments for $ical");
}
file = fopen(filename, "r");
if( ! file) {
free(obj);
free(free_at_crash);
CRIT_ERR(filename, free_at_crash2, "Can't read file %s", filename);
return;
}
free(filename);
parser = icalparser_new();
icalparser_set_gen_data(parser, file);
allc = icalparser_parse(parser, read_stream);
fclose(file);
curc = icalcomponent_get_first_component(allc, ICAL_VEVENT_COMPONENT);
if(!curc) {
icalparser_free(parser);
icalcomponent_free(allc);
NORM_ERR("No ical events available");
return;
}
ll_start = add_event(NULL, curc);
ll_end = ll_start;
while(1) {
curc = icalcomponent_get_next_component(allc, ICAL_VEVENT_COMPONENT);
if(!curc) break;
ll_new = add_event(ll_end, curc);
if( ! ll_start) { //first component was not added
ll_start = ll_new;
ll_end = ll_new;
}else if( ll_start->prev ) {
ll_start = ll_start->prev;
}else if( ll_end->next ) {
ll_end = ll_end->next;
}
}
opaque = (struct obj_ical *) malloc(sizeof(struct obj_ical));
opaque->list = ll_start;
opaque->parser = parser;
opaque->comps = allc;
opaque->num = num;
obj->data.opaque = opaque;
if (sscanf(arg, "%d %s", &num, filename) != 2) {
free(filename);
free(obj);
CRIT_ERR(free_at_crash, free_at_crash2,
"wrong number of arguments for $ical");
}
file = fopen(filename, "r");
if (!file) {
free(obj);
free(free_at_crash);
CRIT_ERR(filename, free_at_crash2, "Can't read file %s", filename);
return;
}
free(filename);
parser = icalparser_new();
icalparser_set_gen_data(parser, file);
allc = icalparser_parse(parser, read_stream);
fclose(file);
curc = icalcomponent_get_first_component(allc, ICAL_VEVENT_COMPONENT);
if (!curc) {
icalparser_free(parser);
icalcomponent_free(allc);
NORM_ERR("No ical events available");
return;
}
ll_start = add_event(NULL, curc);
ll_end = ll_start;
while (1) {
curc = icalcomponent_get_next_component(allc, ICAL_VEVENT_COMPONENT);
if (!curc) break;
ll_new = add_event(ll_end, curc);
if (!ll_start) { // first component was not added
ll_start = ll_new;
ll_end = ll_new;
} else if (ll_start->prev) {
ll_start = ll_start->prev;
} else if (ll_end->next) {
ll_end = ll_end->next;
}
}
opaque = (struct obj_ical *)malloc(sizeof(struct obj_ical));
opaque->list = ll_start;
opaque->parser = parser;
opaque->comps = allc;
opaque->num = num;
obj->data.opaque = opaque;
}
void print_ical(struct text_object *obj, char *p, int p_max_size) {
struct obj_ical *ical_obj = (struct obj_ical *) obj->data.opaque;
struct ical_event *ll_current;
struct obj_ical *ical_obj = (struct obj_ical *)obj->data.opaque;
struct ical_event *ll_current;
if( ! ical_obj) return;
ll_current = ical_obj->list;
unsigned int i=1;
while(1) {
if( ! ll_current) return;
if(i > ical_obj->num) return;
if(i == ical_obj->num) break;
if(i < ical_obj->num) {
ll_current = ll_current->next;
i++;
}
}
snprintf(p, p_max_size, "%s", icalproperty_get_summary(icalcomponent_get_first_property(ll_current->event, ICAL_SUMMARY_PROPERTY)));
if (!ical_obj) return;
ll_current = ical_obj->list;
unsigned int i = 1;
while (1) {
if (!ll_current) return;
if (i > ical_obj->num) return;
if (i == ical_obj->num) break;
if (i < ical_obj->num) {
ll_current = ll_current->next;
i++;
}
}
snprintf(p, p_max_size, "%s",
icalproperty_get_summary(icalcomponent_get_first_property(
ll_current->event, ICAL_SUMMARY_PROPERTY)));
}
void free_ical(struct text_object *obj) {
struct obj_ical *ical_free_me = (struct obj_ical *) obj->data.opaque;
struct obj_ical *ical_free_me = (struct obj_ical *)obj->data.opaque;
if( ! ical_free_me) return;
icalcomponent_free(ical_free_me->comps);
icalparser_free(ical_free_me->parser);
while(ical_free_me->list) {
if(ical_free_me->list->next) {
ical_free_me->list = ical_free_me->list->next;
free_and_zero(ical_free_me->list->prev);
} else free_and_zero(ical_free_me->list);
}
free(obj->data.opaque);
if (!ical_free_me) return;
icalcomponent_free(ical_free_me->comps);
icalparser_free(ical_free_me->parser);
while (ical_free_me->list) {
if (ical_free_me->list->next) {
ical_free_me->list = ical_free_me->list->next;
free_and_zero(ical_free_me->list->prev);
} else
free_and_zero(ical_free_me->list);
}
free(obj->data.opaque);
}

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -26,7 +25,7 @@
#ifndef ICAL_H_
#define ICAL_H_
void parse_ical_args(struct text_object *, const char*, void*, void*);
void parse_ical_args(struct text_object *, const char *, void *, void *);
void print_ical(struct text_object *, char *, int);
void free_ical(struct text_object *);

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -28,13 +27,13 @@
*
*/
#include "config.h"
#include "logging.h"
#include "text_object.h"
#include <iconv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "logging.h"
#include "text_object.h"
#define ICONV_CODEPAGE_LENGTH 20
@@ -43,120 +42,112 @@ static long iconv_count = 0;
static char iconv_converting = 0;
static iconv_t **iconv_cd = 0;
int register_iconv(iconv_t *new_iconv)
{
iconv_cd = (void ***) realloc(iconv_cd, sizeof(iconv_t *) * (iconv_count + 1));
if (!iconv_cd) {
CRIT_ERR(NULL, NULL, "Out of memory");
}
iconv_cd[iconv_count] = (void **) malloc(sizeof(iconv_t));
if (!iconv_cd[iconv_count]) {
CRIT_ERR(NULL, NULL, "Out of memory");
}
memcpy(iconv_cd[iconv_count], new_iconv, sizeof(iconv_t));
iconv_count++;
return iconv_count;
int register_iconv(iconv_t *new_iconv) {
iconv_cd = (void ***)realloc(iconv_cd, sizeof(iconv_t *) * (iconv_count + 1));
if (!iconv_cd) {
CRIT_ERR(NULL, NULL, "Out of memory");
}
iconv_cd[iconv_count] = (void **)malloc(sizeof(iconv_t));
if (!iconv_cd[iconv_count]) {
CRIT_ERR(NULL, NULL, "Out of memory");
}
memcpy(iconv_cd[iconv_count], new_iconv, sizeof(iconv_t));
iconv_count++;
return iconv_count;
}
void free_iconv(struct text_object *obj)
{
long i;
void free_iconv(struct text_object *obj) {
long i;
(void)obj;
(void)obj;
if (!iconv_cd)
return;
if (!iconv_cd) return;
for (i = 0; i < iconv_count; i++) {
if (iconv_cd[i]) {
iconv_close(*iconv_cd[i]);
free(iconv_cd[i]);
}
}
free(iconv_cd);
iconv_cd = 0;
for (i = 0; i < iconv_count; i++) {
if (iconv_cd[i]) {
iconv_close(*iconv_cd[i]);
free(iconv_cd[i]);
}
}
free(iconv_cd);
iconv_cd = 0;
}
void iconv_convert(size_t *a, char *buff_in, char *p, size_t p_max_size)
{
int bytes;
size_t dummy1, dummy2;
void iconv_convert(size_t *a, char *buff_in, char *p, size_t p_max_size) {
int bytes;
size_t dummy1, dummy2;
#if defined(__FreeBSD__) || defined(__DragonFly__)
const char *ptr = buff_in;
const char *ptr = buff_in;
#else
char *ptr = buff_in;
char *ptr = buff_in;
#endif
char *outptr = p;
char *outptr = p;
if (*a <= 0 || !iconv_converting || iconv_selected <= 0
|| iconv_cd[iconv_selected - 1] == (iconv_t) (-1))
return;
if (*a <= 0 || !iconv_converting || iconv_selected <= 0 ||
iconv_cd[iconv_selected - 1] == (iconv_t)(-1))
return;
dummy1 = dummy2 = *a;
dummy1 = dummy2 = *a;
strncpy(buff_in, p, p_max_size);
strncpy(buff_in, p, p_max_size);
iconv(*iconv_cd[iconv_selected - 1], NULL, NULL, NULL, NULL);
while (dummy1 > 0) {
bytes = iconv(*iconv_cd[iconv_selected - 1], &ptr, &dummy1,
&outptr, &dummy2);
if (bytes == -1) {
NORM_ERR("Iconv codeset conversion failed");
break;
}
}
iconv(*iconv_cd[iconv_selected - 1], NULL, NULL, NULL, NULL);
while (dummy1 > 0) {
bytes =
iconv(*iconv_cd[iconv_selected - 1], &ptr, &dummy1, &outptr, &dummy2);
if (bytes == -1) {
NORM_ERR("Iconv codeset conversion failed");
break;
}
}
/* It is nessecary when we are converting from multibyte to
* singlebyte codepage */
//a = outptr - p;
//(*a) = *a - dummy2;
(*a) = outptr - p;
/* It is nessecary when we are converting from multibyte to
* singlebyte codepage */
// a = outptr - p;
//(*a) = *a - dummy2;
(*a) = outptr - p;
}
void init_iconv_start(struct text_object *obj, void *free_at_crash, const char *arg)
{
char iconv_from[ICONV_CODEPAGE_LENGTH];
char iconv_to[ICONV_CODEPAGE_LENGTH];
void init_iconv_start(struct text_object *obj, void *free_at_crash,
const char *arg) {
char iconv_from[ICONV_CODEPAGE_LENGTH];
char iconv_to[ICONV_CODEPAGE_LENGTH];
if (iconv_converting) {
CRIT_ERR(obj, free_at_crash, "You must stop your last iconv conversion before "
"starting another");
}
if (sscanf(arg, "%s %s", iconv_from, iconv_to) != 2) {
CRIT_ERR(obj, free_at_crash, "Invalid arguments for iconv_start");
} else {
iconv_t new_iconv;
if (iconv_converting) {
CRIT_ERR(obj, free_at_crash,
"You must stop your last iconv conversion before "
"starting another");
}
if (sscanf(arg, "%s %s", iconv_from, iconv_to) != 2) {
CRIT_ERR(obj, free_at_crash, "Invalid arguments for iconv_start");
} else {
iconv_t new_iconv;
new_iconv = iconv_open(iconv_to, iconv_from);
if (new_iconv == (iconv_t) (-1)) {
NORM_ERR("Can't convert from %s to %s.", iconv_from, iconv_to);
} else {
obj->data.i = register_iconv(&new_iconv);
iconv_converting = 1;
}
}
new_iconv = iconv_open(iconv_to, iconv_from);
if (new_iconv == (iconv_t)(-1)) {
NORM_ERR("Can't convert from %s to %s.", iconv_from, iconv_to);
} else {
obj->data.i = register_iconv(&new_iconv);
iconv_converting = 1;
}
}
}
void init_iconv_stop(void)
{
iconv_converting = 0;
void init_iconv_stop(void) { iconv_converting = 0; }
void print_iconv_start(struct text_object *obj, char *p, int p_max_size) {
(void)p;
(void)p_max_size;
iconv_converting = 1;
iconv_selected = obj->data.i;
}
void print_iconv_start(struct text_object *obj, char *p, int p_max_size)
{
(void)p;
(void)p_max_size;
void print_iconv_stop(struct text_object *obj, char *p, int p_max_size) {
(void)obj;
(void)p;
(void)p_max_size;
iconv_converting = 1;
iconv_selected = obj->data.i;
}
void print_iconv_stop(struct text_object *obj, char *p, int p_max_size)
{
(void)obj;
(void)p;
(void)p_max_size;
iconv_converting = 0;
iconv_selected = 0;
iconv_converting = 0;
iconv_selected = 0;
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=c
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, et. al.
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -22,29 +21,29 @@
*
*/
#include "imlib2.h"
#include "config.h"
#include "conky.h"
#include "logging.h"
#include "text_object.h"
#include "imlib2.h"
#include <Imlib2.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <time.h>
#include "x11.h"
struct image_list_s {
char name[1024];
Imlib_Image image;
int x, y, w, h;
int wh_set;
char no_cache;
int flush_interval;
struct image_list_s *next;
char name[1024];
Imlib_Image image;
int x, y, w, h;
int wh_set;
char no_cache;
int flush_interval;
struct image_list_s *next;
};
struct image_list_s *image_list_start, *image_list_end;
@@ -55,231 +54,224 @@ Imlib_Updates updates, current_update;
Imlib_Image buffer, image;
namespace {
Imlib_Context context;
Imlib_Context context;
conky::range_config_setting<unsigned int> imlib_cache_flush_interval(
"imlib_cache_flush_interval", 0,
std::numeric_limits<unsigned int>::max(), 0, true
);
conky::range_config_setting<unsigned int> imlib_cache_flush_interval(
"imlib_cache_flush_interval", 0, std::numeric_limits<unsigned int>::max(),
0, true);
unsigned int cimlib_cache_flush_last = 0;
unsigned int cimlib_cache_flush_last = 0;
} // namespace
void imlib_cache_size_setting::lua_setter(lua::state &l, bool init) {
lua::stack_sentry s(l, -2);
Base::lua_setter(l, init);
if (init && out_to_x.get(l)) {
image_list_start = image_list_end = NULL;
context = imlib_context_new();
imlib_context_push(context);
imlib_set_cache_size(do_convert(l, -1).first);
/* set the maximum number of colors to allocate for 8bpp and less to 256 */
imlib_set_color_usage(256);
/* dither for depths < 24bpp */
imlib_context_set_dither(1);
/* set the display , visual, colormap and drawable we are using */
imlib_context_set_display(display);
imlib_context_set_visual(window.visual);
imlib_context_set_colormap(window.colourmap);
imlib_context_set_drawable(window.drawable);
}
++s;
}
void imlib_cache_size_setting::lua_setter(lua::state &l, bool init)
{
lua::stack_sentry s(l, -2);
void imlib_cache_size_setting::cleanup(lua::state &l) {
lua::stack_sentry s(l, -1);
Base::lua_setter(l, init);
if(init && out_to_x.get(l)) {
image_list_start = image_list_end = NULL;
context = imlib_context_new();
imlib_context_push(context);
imlib_set_cache_size(do_convert(l, -1).first);
/* set the maximum number of colors to allocate for 8bpp and less to 256 */
imlib_set_color_usage(256);
/* dither for depths < 24bpp */
imlib_context_set_dither(1);
/* set the display , visual, colormap and drawable we are using */
imlib_context_set_display(display);
imlib_context_set_visual(window.visual);
imlib_context_set_colormap(window.colourmap);
imlib_context_set_drawable(window.drawable);
}
++s;
if (out_to_x.get(l)) {
cimlib_cleanup();
imlib_context_disconnect_display();
imlib_context_pop();
imlib_context_free(context);
}
}
void imlib_cache_size_setting::cleanup(lua::state &l)
{
lua::stack_sentry s(l, -1);
if(out_to_x.get(l)) {
cimlib_cleanup();
imlib_context_disconnect_display();
imlib_context_pop();
imlib_context_free(context);
}
void cimlib_cleanup(void) {
struct image_list_s *cur = image_list_start, *last = NULL;
while (cur) {
last = cur;
cur = last->next;
free(last);
}
image_list_start = image_list_end = NULL;
}
void cimlib_cleanup(void)
{
struct image_list_s *cur = image_list_start, *last = NULL;
while (cur) {
last = cur;
cur = last->next;
free(last);
}
image_list_start = image_list_end = NULL;
void cimlib_add_image(const char *args) {
struct image_list_s *cur = NULL;
const char *tmp;
cur = (struct image_list_s *)malloc(sizeof(struct image_list_s));
memset(cur, 0, sizeof(struct image_list_s));
if (!sscanf(args, "%1023s", cur->name)) {
NORM_ERR(
"Invalid args for $image. Format is: '<path to image> (-p"
"x,y) (-s WxH) (-n) (-f interval)' (got '%s')",
args);
free(cur);
return;
}
strncpy(cur->name, to_real_path(cur->name).c_str(), 1024);
cur->name[1023] = 0;
//
// now we check for optional args
tmp = strstr(args, "-p ");
if (tmp) {
tmp += 3;
sscanf(tmp, "%i,%i", &cur->x, &cur->y);
}
tmp = strstr(args, "-s ");
if (tmp) {
tmp += 3;
if (sscanf(tmp, "%ix%i", &cur->w, &cur->h)) {
cur->wh_set = 1;
}
}
tmp = strstr(args, "-n");
if (tmp) {
cur->no_cache = 1;
}
tmp = strstr(args, "-f ");
if (tmp) {
tmp += 3;
if (sscanf(tmp, "%d", &cur->flush_interval)) {
cur->no_cache = 0;
}
}
if (cur->flush_interval < 0) {
NORM_ERR("Imlib2: flush interval should be >= 0");
cur->flush_interval = 0;
}
if (image_list_end) {
image_list_end->next = cur;
image_list_end = cur;
} else {
image_list_start = image_list_end = cur;
}
}
void cimlib_add_image(const char *args)
{
struct image_list_s *cur = NULL;
const char *tmp;
static void cimlib_draw_image(struct image_list_s *cur, int *clip_x,
int *clip_y, int *clip_x2, int *clip_y2) {
int w, h;
time_t now = time(NULL);
static int rep = 0;
cur = (struct image_list_s *)malloc(sizeof(struct image_list_s));
memset(cur, 0, sizeof(struct image_list_s));
if (imlib_context_get_drawable() != window.drawable) {
imlib_context_set_drawable(window.drawable);
}
if (!sscanf(args, "%1023s", cur->name)) {
NORM_ERR("Invalid args for $image. Format is: '<path to image> (-p"
"x,y) (-s WxH) (-n) (-f interval)' (got '%s')", args);
free(cur);
return;
}
strncpy(cur->name, to_real_path(cur->name).c_str(), 1024);
cur->name[1023] = 0;
//
// now we check for optional args
tmp = strstr(args, "-p ");
if (tmp) {
tmp += 3;
sscanf(tmp, "%i,%i", &cur->x, &cur->y);
}
tmp = strstr(args, "-s ");
if (tmp) {
tmp += 3;
if (sscanf(tmp, "%ix%i", &cur->w, &cur->h)) {
cur->wh_set = 1;
}
}
image = imlib_load_image(cur->name);
if (!image) {
if (!rep) NORM_ERR("Unable to load image '%s'", cur->name);
rep = 1;
return;
}
rep = 0; /* reset so disappearing images are reported */
tmp = strstr(args, "-n");
if (tmp) {
cur->no_cache = 1;
}
DBGP(
"Drawing image '%s' at (%i,%i) scaled to %ix%i, "
"caching interval set to %i (with -n opt %i)",
cur->name, cur->x, cur->y, cur->w, cur->h, cur->flush_interval,
cur->no_cache);
tmp = strstr(args, "-f ");
if (tmp) {
tmp += 3;
if (sscanf(tmp, "%d", &cur->flush_interval)) {
cur->no_cache = 0;
}
}
if (cur->flush_interval < 0) {
NORM_ERR("Imlib2: flush interval should be >= 0");
cur->flush_interval = 0;
}
if (image_list_end) {
image_list_end->next = cur;
image_list_end = cur;
} else {
image_list_start = image_list_end = cur;
}
imlib_context_set_image(image);
/* turn alpha channel on */
imlib_image_set_has_alpha(1);
w = imlib_image_get_width();
h = imlib_image_get_height();
if (!cur->wh_set) {
cur->w = w;
cur->h = h;
}
imlib_context_set_image(buffer);
imlib_blend_image_onto_image(image, 1, 0, 0, w, h, cur->x, cur->y, cur->w,
cur->h);
imlib_context_set_image(image);
if (cur->no_cache ||
(cur->flush_interval && now % cur->flush_interval == 0)) {
imlib_free_image_and_decache();
} else {
imlib_free_image();
}
if (cur->x < *clip_x) *clip_x = cur->x;
if (cur->y < *clip_y) *clip_y = cur->y;
if (cur->x + cur->w > *clip_x2) *clip_x2 = cur->x + cur->w;
if (cur->y + cur->h > *clip_y2) *clip_y2 = cur->y + cur->h;
}
static void cimlib_draw_image(struct image_list_s *cur, int *clip_x, int
*clip_y, int *clip_x2, int *clip_y2)
{
int w, h;
time_t now = time(NULL);
static int rep = 0;
if (imlib_context_get_drawable() != window.drawable) {
imlib_context_set_drawable(window.drawable);
}
image = imlib_load_image(cur->name);
if (!image) {
if (!rep)
NORM_ERR("Unable to load image '%s'", cur->name);
rep = 1;
return;
}
rep = 0; /* reset so disappearing images are reported */
DBGP("Drawing image '%s' at (%i,%i) scaled to %ix%i, "
"caching interval set to %i (with -n opt %i)",
cur->name, cur->x, cur->y, cur->w, cur->h,
cur->flush_interval, cur->no_cache);
imlib_context_set_image(image);
/* turn alpha channel on */
imlib_image_set_has_alpha(1);
w = imlib_image_get_width();
h = imlib_image_get_height();
if (!cur->wh_set) {
cur->w = w;
cur->h = h;
}
imlib_context_set_image(buffer);
imlib_blend_image_onto_image(image, 1, 0, 0, w, h,
cur->x, cur->y, cur->w, cur->h);
imlib_context_set_image(image);
if (cur->no_cache || (cur->flush_interval &&
now % cur->flush_interval == 0)) {
imlib_free_image_and_decache();
} else {
imlib_free_image();
}
if (cur->x < *clip_x) *clip_x = cur->x;
if (cur->y < *clip_y) *clip_y = cur->y;
if (cur->x + cur->w > *clip_x2) *clip_x2 = cur->x + cur->w;
if (cur->y + cur->h > *clip_y2) *clip_y2 = cur->y + cur->h;
static void cimlib_draw_all(int *clip_x, int *clip_y, int *clip_x2,
int *clip_y2) {
struct image_list_s *cur = image_list_start;
while (cur) {
cimlib_draw_image(cur, clip_x, clip_y, clip_x2, clip_y2);
cur = cur->next;
}
}
static void cimlib_draw_all(int *clip_x, int *clip_y, int *clip_x2, int *clip_y2)
{
struct image_list_s *cur = image_list_start;
while (cur) {
cimlib_draw_image(cur, clip_x, clip_y, clip_x2, clip_y2);
cur = cur->next;
}
void cimlib_render(int x, int y, int width, int height) {
int clip_x = INT_MAX, clip_y = INT_MAX;
int clip_x2 = 0, clip_y2 = 0;
time_t now;
if (!image_list_start) return; /* are we actually drawing anything? */
/* cheque if it's time to flush our cache */
now = time(NULL);
if (imlib_cache_flush_interval.get(*state) &&
now - imlib_cache_flush_interval.get(*state) > cimlib_cache_flush_last) {
int size = imlib_get_cache_size();
imlib_set_cache_size(0);
imlib_set_cache_size(size);
cimlib_cache_flush_last = now;
DBGP("Flushing Imlib2 cache (%li)\n", now);
}
/* take all the little rectangles to redraw and merge them into
* something sane for rendering */
buffer = imlib_create_image(width, height);
/* clear our buffer */
imlib_context_set_image(buffer);
imlib_image_clear();
/* we can blend stuff now */
imlib_context_set_blend(1);
/* turn alpha channel on */
imlib_image_set_has_alpha(1);
cimlib_draw_all(&clip_x, &clip_y, &clip_x2, &clip_y2);
/* set the buffer image as our current image */
imlib_context_set_image(buffer);
/* setup our clip rect */
if (clip_x == INT_MAX) clip_x = 0;
if (clip_y == INT_MAX) clip_y = 0;
/* render the image at 0, 0 */
imlib_render_image_part_on_drawable_at_size(
clip_x, clip_y, clip_x2 - clip_x, clip_y2 - clip_y, x + clip_x,
y + clip_y, clip_x2 - clip_x, clip_y2 - clip_y);
/* don't need that temporary buffer image anymore */
imlib_free_image();
}
void cimlib_render(int x, int y, int width, int height)
{
int clip_x = INT_MAX, clip_y = INT_MAX;
int clip_x2 = 0, clip_y2 = 0;
time_t now;
void print_image_callback(struct text_object *obj, char *p, int p_max_size) {
(void)p;
(void)p_max_size;
if (!image_list_start) return; /* are we actually drawing anything? */
/* cheque if it's time to flush our cache */
now = time(NULL);
if (imlib_cache_flush_interval.get(*state) &&
now - imlib_cache_flush_interval.get(*state) > cimlib_cache_flush_last) {
int size = imlib_get_cache_size();
imlib_set_cache_size(0);
imlib_set_cache_size(size);
cimlib_cache_flush_last = now;
DBGP("Flushing Imlib2 cache (%li)\n", now);
}
/* take all the little rectangles to redraw and merge them into
* something sane for rendering */
buffer = imlib_create_image(width, height);
/* clear our buffer */
imlib_context_set_image(buffer);
imlib_image_clear();
/* we can blend stuff now */
imlib_context_set_blend(1);
/* turn alpha channel on */
imlib_image_set_has_alpha(1);
cimlib_draw_all(&clip_x, &clip_y, &clip_x2, &clip_y2);
/* set the buffer image as our current image */
imlib_context_set_image(buffer);
/* setup our clip rect */
if (clip_x == INT_MAX) clip_x = 0;
if (clip_y == INT_MAX) clip_y = 0;
/* render the image at 0, 0 */
imlib_render_image_part_on_drawable_at_size(clip_x, clip_y, clip_x2 - clip_x,
clip_y2 - clip_y, x + clip_x, y + clip_y, clip_x2 - clip_x,
clip_y2 - clip_y);
/* don't need that temporary buffer image anymore */
imlib_free_image();
}
void print_image_callback(struct text_object *obj, char *p, int p_max_size)
{
(void)p;
(void)p_max_size;
cimlib_add_image(obj->data.s);
cimlib_add_image(obj->data.s);
}

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, et. al.
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -25,6 +24,8 @@
#ifndef _CONKY_IMBLI2_H_
#define _CONKY_IMBLI2_H_
#include "conky.h"
#include <X11/Xlib.h>
void cimlib_add_image(const char *name);
@@ -35,18 +36,18 @@ void cimlib_cleanup(void);
void print_image_callback(struct text_object *, char *, int);
class imlib_cache_size_setting: public conky::range_config_setting<unsigned long> {
typedef conky::range_config_setting<unsigned long> Base;
class imlib_cache_size_setting
: public conky::range_config_setting<unsigned long> {
typedef conky::range_config_setting<unsigned long> Base;
protected:
virtual void lua_setter(lua::state &l, bool init);
virtual void cleanup(lua::state &l);
protected:
virtual void lua_setter(lua::state &l, bool init);
virtual void cleanup(lua::state &l);
public:
imlib_cache_size_setting()
: Base("imlib_cache_size", 0,
std::numeric_limits<unsigned long>::max(), 4096*1024, true)
{}
public:
imlib_cache_size_setting()
: Base("imlib_cache_size", 0, std::numeric_limits<unsigned long>::max(),
4096 * 1024, true) {}
};
#endif /* _CONKY_IMBLI2_H_ */

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -23,100 +22,108 @@
*
*/
#include "conky.h"
#include "logging.h"
#include <libircclient.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include "conky.h"
#include "logging.h"
#include "text_object.h"
#include <libircclient.h>
struct ll_text {
char *text;
struct ll_text *next;
char *text;
struct ll_text *next;
};
struct obj_irc {
pthread_t *thread;
irc_session_t *session;
char *arg;
pthread_t *thread;
irc_session_t *session;
char *arg;
};
struct ctx {
char *chan;
int max_msg_lines;
struct ll_text *messages;
char *chan;
int max_msg_lines;
struct ll_text *messages;
};
void ev_connected(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count) {
struct ctx *ctxptr = (struct ctx *) irc_get_ctx(session);
if(irc_cmd_join(session, ctxptr->chan, NULL) != 0) {
NORM_ERR("irc: %s", irc_strerror(irc_errno(session)));
}
if(event || origin || params || count) {} //fix gcc warnings
void ev_connected(irc_session_t *session, const char *event, const char *origin,
const char **params, unsigned int count) {
struct ctx *ctxptr = (struct ctx *)irc_get_ctx(session);
if (irc_cmd_join(session, ctxptr->chan, NULL) != 0) {
NORM_ERR("irc: %s", irc_strerror(irc_errno(session)));
}
if (event || origin || params || count) {
} // fix gcc warnings
}
void addmessage(struct ctx *ctxptr, char *nick, const char *text) {
struct ll_text *lastmsg = ctxptr->messages;
struct ll_text *newmsg = (struct ll_text*) malloc(sizeof(struct ll_text));
newmsg->text = (char*) malloc(strlen(nick) + strlen(text) + 4); //4 = ": \n"
sprintf(newmsg->text, "%s: %s\n", nick, text);
newmsg->next = NULL;
int msgcnt = 1;
if(!lastmsg) {
ctxptr->messages = newmsg;
} else {
msgcnt++;
while(lastmsg->next) {
lastmsg = lastmsg->next;
msgcnt++;
if(msgcnt<0) {
NORM_ERR("irc: too many messages, discarding the last one.");
free(newmsg->text);
free(newmsg);
return;
}
}
lastmsg->next = newmsg;
}
if(ctxptr->max_msg_lines>0) {
newmsg = ctxptr->messages;
msgcnt -= ctxptr->max_msg_lines;
while((msgcnt>0) && (ctxptr->messages)) {
msgcnt--;
newmsg = ctxptr->messages->next;
free(ctxptr->messages->text);
free(ctxptr->messages);
ctxptr->messages = newmsg;
}
}
struct ll_text *lastmsg = ctxptr->messages;
struct ll_text *newmsg = (struct ll_text *)malloc(sizeof(struct ll_text));
newmsg->text = (char *)malloc(strlen(nick) + strlen(text) + 4); // 4 = ": \n"
sprintf(newmsg->text, "%s: %s\n", nick, text);
newmsg->next = NULL;
int msgcnt = 1;
if (!lastmsg) {
ctxptr->messages = newmsg;
} else {
msgcnt++;
while (lastmsg->next) {
lastmsg = lastmsg->next;
msgcnt++;
if (msgcnt < 0) {
NORM_ERR("irc: too many messages, discarding the last one.");
free(newmsg->text);
free(newmsg);
return;
}
}
lastmsg->next = newmsg;
}
if (ctxptr->max_msg_lines > 0) {
newmsg = ctxptr->messages;
msgcnt -= ctxptr->max_msg_lines;
while ((msgcnt > 0) && (ctxptr->messages)) {
msgcnt--;
newmsg = ctxptr->messages->next;
free(ctxptr->messages->text);
free(ctxptr->messages);
ctxptr->messages = newmsg;
}
}
}
void ev_talkinchan(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count) {
char nickname[64];
struct ctx *ctxptr = (struct ctx *) irc_get_ctx(session);
void ev_talkinchan(irc_session_t *session, const char *event,
const char *origin, const char **params,
unsigned int count) {
char nickname[64];
struct ctx *ctxptr = (struct ctx *)irc_get_ctx(session);
irc_target_get_nick(origin, nickname, sizeof(nickname));
addmessage(ctxptr, nickname, params[1]);
if(session || event || count) {} //fix gcc warnings
irc_target_get_nick(origin, nickname, sizeof(nickname));
addmessage(ctxptr, nickname, params[1]);
if (session || event || count) {
} // fix gcc warnings
}
void ev_num(irc_session_t *session, unsigned int event, const char *origin, const char **params, unsigned int count) {
char attachment[4]="_00";
void ev_num(irc_session_t *session, unsigned int event, const char *origin,
const char **params, unsigned int count) {
char attachment[4] = "_00";
if(event == 433) { //nick in use
char *newnick = (char*) malloc(strlen(params[1]) + 4);
strcpy(newnick, params[1]);
attachment[1] += rand() % 10;
attachment[2] += rand() % 10;
strcat(newnick, attachment);
irc_cmd_nick(session, newnick);
free(newnick);
}
if(origin || count) {} //fix gcc warnings
if (event == 433) { // nick in use
char *newnick = (char *)malloc(strlen(params[1]) + 4);
strcpy(newnick, params[1]);
attachment[1] += rand() % 10;
attachment[2] += rand() % 10;
strcat(newnick, attachment);
irc_cmd_nick(session, newnick);
free(newnick);
}
if (origin || count) {
} // fix gcc warnings
}
#define IRCSYNTAX "The correct syntax is ${irc server(:port) #channel (max_msg_lines)}"
#define IRCSYNTAX \
"The correct syntax is ${irc server(:port) #channel (max_msg_lines)}"
#define IRCPORT 6667
#define IRCNICK "conky"
#define IRCSERVERPASS NULL
@@ -124,123 +131,124 @@ void ev_num(irc_session_t *session, unsigned int event, const char *origin, cons
#define IRCREAL NULL
void *ircclient(void *ptr) {
struct obj_irc *ircobj = (struct obj_irc *) ptr;
struct ctx *ctxptr = (struct ctx *) malloc(sizeof(struct ctx));
irc_callbacks_t callbacks;
char *server;
char *strport;
char *str_max_msg_lines;
unsigned int port;
struct obj_irc *ircobj = (struct obj_irc *)ptr;
struct ctx *ctxptr = (struct ctx *)malloc(sizeof(struct ctx));
irc_callbacks_t callbacks;
char *server;
char *strport;
char *str_max_msg_lines;
unsigned int port;
memset (&callbacks, 0, sizeof(callbacks));
callbacks.event_connect = ev_connected;
callbacks.event_channel = ev_talkinchan;
callbacks.event_numeric = ev_num;
ircobj->session = irc_create_session(&callbacks);
server = strtok(ircobj->arg , " ");
ctxptr->chan = strtok(NULL , " ");
if( ! ctxptr->chan) {
NORM_ERR("irc: %s", IRCSYNTAX);
}
str_max_msg_lines = strtok(NULL, " ");
if(str_max_msg_lines) {
ctxptr->max_msg_lines = strtol(str_max_msg_lines, NULL, 10);
}
ctxptr->messages = NULL;
irc_set_ctx(ircobj->session, ctxptr);
server = strtok(server, ":");
strport = strtok(NULL, ":");
if(strport) {
port = strtol(strport, NULL, 10);
if(port < 1 || port > 65535)
port = IRCPORT;
} else {
port = IRCPORT;
}
int err = irc_connect(ircobj->session, server, port, IRCSERVERPASS, IRCNICK, IRCUSER, IRCREAL);
if(err != 0) {
err = irc_errno(ircobj->session);
}
memset(&callbacks, 0, sizeof(callbacks));
callbacks.event_connect = ev_connected;
callbacks.event_channel = ev_talkinchan;
callbacks.event_numeric = ev_num;
ircobj->session = irc_create_session(&callbacks);
server = strtok(ircobj->arg, " ");
ctxptr->chan = strtok(NULL, " ");
if (!ctxptr->chan) {
NORM_ERR("irc: %s", IRCSYNTAX);
}
str_max_msg_lines = strtok(NULL, " ");
if (str_max_msg_lines) {
ctxptr->max_msg_lines = strtol(str_max_msg_lines, NULL, 10);
}
ctxptr->messages = NULL;
irc_set_ctx(ircobj->session, ctxptr);
server = strtok(server, ":");
strport = strtok(NULL, ":");
if (strport) {
port = strtol(strport, NULL, 10);
if (port < 1 || port > 65535) port = IRCPORT;
} else {
port = IRCPORT;
}
int err = irc_connect(ircobj->session, server, port, IRCSERVERPASS, IRCNICK,
IRCUSER, IRCREAL);
if (err != 0) {
err = irc_errno(ircobj->session);
}
#ifdef BUILD_IPV6
if(err == LIBIRC_ERR_RESOLV) {
err = irc_connect6(ircobj->session, server, port, IRCSERVERPASS, IRCNICK, IRCUSER, IRCREAL);
if(err != 0) {
err = irc_errno(ircobj->session);
}
}
if (err == LIBIRC_ERR_RESOLV) {
err = irc_connect6(ircobj->session, server, port, IRCSERVERPASS, IRCNICK,
IRCUSER, IRCREAL);
if (err != 0) {
err = irc_errno(ircobj->session);
}
}
#endif /* BUILD_IPV6 */
if(err != 0) {
NORM_ERR("irc: %s", irc_strerror(err));
}
if(irc_run(ircobj->session) != 0) {
int ircerror = irc_errno(ircobj->session);
if(irc_is_connected(ircobj->session)) {
NORM_ERR("irc: %s", irc_strerror(ircerror));
} else {
NORM_ERR("irc: disconnected");
}
}
free(ircobj->arg);
free(ctxptr);
return NULL;
if (err != 0) {
NORM_ERR("irc: %s", irc_strerror(err));
}
if (irc_run(ircobj->session) != 0) {
int ircerror = irc_errno(ircobj->session);
if (irc_is_connected(ircobj->session)) {
NORM_ERR("irc: %s", irc_strerror(ircerror));
} else {
NORM_ERR("irc: disconnected");
}
}
free(ircobj->arg);
free(ctxptr);
return NULL;
}
void parse_irc_args(struct text_object *obj, const char* arg) {
struct obj_irc* opaque = (struct obj_irc *) malloc(sizeof(struct obj_irc));
opaque->thread = (pthread_t *) malloc(sizeof(pthread_t));
srand(time(NULL));
opaque->session = NULL;
opaque->arg = strdup(arg);
pthread_create(opaque->thread, NULL, ircclient, opaque);
obj->data.opaque = opaque;
void parse_irc_args(struct text_object *obj, const char *arg) {
struct obj_irc *opaque = (struct obj_irc *)malloc(sizeof(struct obj_irc));
opaque->thread = (pthread_t *)malloc(sizeof(pthread_t));
srand(time(NULL));
opaque->session = NULL;
opaque->arg = strdup(arg);
pthread_create(opaque->thread, NULL, ircclient, opaque);
obj->data.opaque = opaque;
}
void print_irc(struct text_object *obj, char *p, int p_max_size) {
struct obj_irc *ircobj = (struct obj_irc *) obj->data.opaque;
struct ctx *ctxptr;
struct ll_text *nextmsg, *curmsg;
struct obj_irc *ircobj = (struct obj_irc *)obj->data.opaque;
struct ctx *ctxptr;
struct ll_text *nextmsg, *curmsg;
if( ! ircobj->session) return;
if( ! irc_is_connected(ircobj->session)) return;
ctxptr = (struct ctx *) irc_get_ctx(ircobj->session);
curmsg = ctxptr->messages;
while(curmsg) {
nextmsg = curmsg->next;
strncat(p, curmsg->text, p_max_size - strlen(p) - 1);
if(!ctxptr->max_msg_lines) {
free(curmsg->text);
free(curmsg);
}
curmsg = nextmsg;
}
if(p[0] != 0) {
p[strlen(p) - 1] = 0;
}
if(!ctxptr->max_msg_lines) {
ctxptr->messages = NULL;
}
if (!ircobj->session) return;
if (!irc_is_connected(ircobj->session)) return;
ctxptr = (struct ctx *)irc_get_ctx(ircobj->session);
curmsg = ctxptr->messages;
while (curmsg) {
nextmsg = curmsg->next;
strncat(p, curmsg->text, p_max_size - strlen(p) - 1);
if (!ctxptr->max_msg_lines) {
free(curmsg->text);
free(curmsg);
}
curmsg = nextmsg;
}
if (p[0] != 0) {
p[strlen(p) - 1] = 0;
}
if (!ctxptr->max_msg_lines) {
ctxptr->messages = NULL;
}
}
void free_irc(struct text_object *obj) {
struct obj_irc *ircobj = (struct obj_irc *) obj->data.opaque;
struct ctx *ctxptr;
struct ll_text *nextmsg, *curmsg = NULL;
struct obj_irc *ircobj = (struct obj_irc *)obj->data.opaque;
struct ctx *ctxptr;
struct ll_text *nextmsg, *curmsg = NULL;
if(ircobj->session) {
if( irc_is_connected(ircobj->session)) {
ctxptr = (struct ctx *) irc_get_ctx(ircobj->session);
curmsg = ctxptr->messages;
irc_disconnect(ircobj->session);
}
pthread_join(*(ircobj->thread), NULL);
irc_destroy_session(ircobj->session);
}
free(ircobj->thread);
free(obj->data.opaque);
while(curmsg) {
nextmsg = curmsg->next;
free(curmsg->text);
free(curmsg);
curmsg = nextmsg;
}
if (ircobj->session) {
if (irc_is_connected(ircobj->session)) {
ctxptr = (struct ctx *)irc_get_ctx(ircobj->session);
curmsg = ctxptr->messages;
irc_disconnect(ircobj->session);
}
pthread_join(*(ircobj->thread), NULL);
irc_destroy_session(ircobj->session);
}
free(ircobj->thread);
free(obj->data.opaque);
while (curmsg) {
nextmsg = curmsg->next;
free(curmsg->text);
free(curmsg);
curmsg = nextmsg;
}
}

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -26,7 +25,7 @@
#ifndef IRC_H_
#define IRC_H_
void parse_irc_args(struct text_object *, const char*);
void parse_irc_args(struct text_object *, const char *);
void print_irc(struct text_object *, char *, int);
void free_irc(struct text_object *);

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -28,144 +27,139 @@
*
*/
#include "conky.h"
#include "config.h"
#include "common.h"
#include "text_object.h"
#include "logging.h"
#include <ctype.h>
#include <string.h>
#include <systemd/sd-journal.h>
#include <unistd.h>
#include <memory>
#include <systemd/sd-journal.h>
#include "common.h"
#include "config.h"
#include "conky.h"
#include "logging.h"
#include "text_object.h"
#define MAX_JOURNAL_LINES 200
struct journal {
int wantedlines;
int flags;
journal()
: wantedlines(0), flags(SD_JOURNAL_LOCAL_ONLY)
{}
int wantedlines;
int flags;
journal() : wantedlines(0), flags(SD_JOURNAL_LOCAL_ONLY) {}
};
void free_journal(struct text_object *obj)
{
struct journal *j = (struct journal *)obj->data.opaque;
obj->data.opaque = NULL;
delete j;
void free_journal(struct text_object *obj) {
struct journal *j = (struct journal *)obj->data.opaque;
obj->data.opaque = NULL;
delete j;
}
void init_journal(const char* type, const char* arg, struct text_object *obj, void* free_at_crash) {
unsigned int args;
struct journal *j = new journal;
void init_journal(const char *type, const char *arg, struct text_object *obj,
void *free_at_crash) {
unsigned int args;
struct journal *j = new journal;
std::unique_ptr<char []> tmp(new char[DEFAULT_TEXT_BUFFER_SIZE]);
memset(tmp.get(), 0, DEFAULT_TEXT_BUFFER_SIZE);
std::unique_ptr<char[]> tmp(new char[DEFAULT_TEXT_BUFFER_SIZE]);
memset(tmp.get(), 0, DEFAULT_TEXT_BUFFER_SIZE);
args = sscanf(arg, "%d %6s", &j->wantedlines, tmp.get());
if (args < 1 || args > 2) {
free_journal(obj);
CRIT_ERR(obj, free_at_crash, "%s a number of lines as 1st argument and optionally a journal type as 2nd argument", type);
}
if (j->wantedlines > 0 && j->wantedlines <= MAX_JOURNAL_LINES) {
if(args > 1) {
if(strcmp(tmp.get(), "system") == 0) {
j->flags |= SD_JOURNAL_SYSTEM;
} else if(strcmp(tmp.get(), "user") == 0) {
j->flags |= SD_JOURNAL_CURRENT_USER;
} else {
free_journal(obj);
CRIT_ERR(obj, free_at_crash, "invalid arg for %s, type must be 'system' or 'user'", type);
}
}
args = sscanf(arg, "%d %6s", &j->wantedlines, tmp.get());
if (args < 1 || args > 2) {
free_journal(obj);
CRIT_ERR(obj, free_at_crash,
"%s a number of lines as 1st argument and optionally a journal "
"type as 2nd argument",
type);
}
if (j->wantedlines > 0 && j->wantedlines <= MAX_JOURNAL_LINES) {
if (args > 1) {
if (strcmp(tmp.get(), "system") == 0) {
j->flags |= SD_JOURNAL_SYSTEM;
} else if (strcmp(tmp.get(), "user") == 0) {
j->flags |= SD_JOURNAL_CURRENT_USER;
} else {
free_journal(obj);
CRIT_ERR(obj, free_at_crash,
"invalid arg for %s, type must be 'system' or 'user'", type);
}
}
} else {
free_journal(obj);
CRIT_ERR(obj, free_at_crash, "invalid arg for %s, number of lines must be between 1 and %d", type, MAX_JOURNAL_LINES);
}
obj->data.opaque = j;
} else {
free_journal(obj);
CRIT_ERR(obj, free_at_crash,
"invalid arg for %s, number of lines must be between 1 and %d",
type, MAX_JOURNAL_LINES);
}
obj->data.opaque = j;
}
static int print_field(sd_journal *jh, const char *field, char spacer, size_t *read, char *p, int p_max_size) {
const void *get;
size_t length;
size_t fieldlen = strlen(field)+1;
static int print_field(sd_journal *jh, const char *field, char spacer,
size_t *read, char *p, int p_max_size) {
const void *get;
size_t length;
size_t fieldlen = strlen(field) + 1;
int ret = sd_journal_get_data(jh, field, &get, &length);
if(ret == -ENOENT)
goto out;
int ret = sd_journal_get_data(jh, field, &get, &length);
if (ret == -ENOENT) goto out;
if(ret < 0 || length + *read > p_max_size)
return -1;
if (ret < 0 || length + *read > p_max_size) return -1;
memcpy(p + *read, (const char*)get+fieldlen, length-fieldlen);
*read += length-fieldlen;
memcpy(p + *read, (const char *)get + fieldlen, length - fieldlen);
*read += length - fieldlen;
out:
if(spacer)
p[(*read)++] = spacer;
return length ? length-fieldlen : 0;
if (spacer) p[(*read)++] = spacer;
return length ? length - fieldlen : 0;
}
void print_journal(struct text_object *obj, char *p, int p_max_size) {
size_t read = 0, length;
struct journal *j = (struct journal *)obj->data.opaque;
sd_journal *jh = NULL;
size_t read = 0, length;
struct journal *j = (struct journal *)obj->data.opaque;
sd_journal *jh = NULL;
struct tm *tm;
time_t time;
uint64_t timestamp;
struct tm *tm;
time_t time;
uint64_t timestamp;
if(sd_journal_open(&jh, j->flags) != 0) {
NORM_ERR("unable to open journal");
goto out;
}
if (!j)
return;
if (sd_journal_open(&jh, j->flags) != 0) {
NORM_ERR("unable to open journal");
goto out;
}
if (!j) return;
if(sd_journal_seek_tail(jh) < 0)
{
NORM_ERR("unable to seek to end of journal");
goto out;
}
if(sd_journal_previous_skip(jh, j->wantedlines) < 0) {
NORM_ERR("unable to seek back %d lines", j->wantedlines);
goto out;
}
if (sd_journal_seek_tail(jh) < 0) {
NORM_ERR("unable to seek to end of journal");
goto out;
}
if (sd_journal_previous_skip(jh, j->wantedlines) < 0) {
NORM_ERR("unable to seek back %d lines", j->wantedlines);
goto out;
}
do {
if(sd_journal_get_realtime_usec(jh, &timestamp) < 0)
break;
time = timestamp / 1000000;
tm = localtime(&time);
do {
if (sd_journal_get_realtime_usec(jh, &timestamp) < 0) break;
time = timestamp / 1000000;
tm = localtime(&time);
if((length = strftime(p+read, p_max_size-read, "%b %d %H:%M:%S", tm)) <= 0)
break;
read += length;
p[read++] = ' ';
if ((length =
strftime(p + read, p_max_size - read, "%b %d %H:%M:%S", tm)) <= 0)
break;
read += length;
p[read++] = ' ';
if(print_field(jh, "_HOSTNAME", ' ', &read, p, p_max_size) < 0)
break;
if (print_field(jh, "_HOSTNAME", ' ', &read, p, p_max_size) < 0) break;
if(print_field(jh, "SYSLOG_IDENTIFIER", '[', &read, p, p_max_size) < 0)
break;
if (print_field(jh, "SYSLOG_IDENTIFIER", '[', &read, p, p_max_size) < 0)
break;
if(print_field(jh, "_PID", ']', &read, p, p_max_size) < 0)
break;
if (print_field(jh, "_PID", ']', &read, p, p_max_size) < 0) break;
p[read++] = ':';
p[read++] = ' ';
p[read++] = ':';
p[read++] = ' ';
if(print_field(jh, "MESSAGE", '\n', &read, p, p_max_size) < 0)
break;
} while(sd_journal_next(jh));
if (print_field(jh, "MESSAGE", '\n', &read, p, p_max_size) < 0) break;
} while (sd_journal_next(jh));
out:
if(jh)
sd_journal_close(jh);
p[read] = '\0';
return;
if (jh) sd_journal_close(jh);
p[read] = '\0';
return;
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
@@ -10,7 +9,7 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=c
/*
*
* libmpdclient
* (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com)
@@ -36,93 +35,93 @@
#define LIBMPDCLIENT_H
#ifdef WIN32
# define __W32API_USE_DLLIMPORT__ 1
#define __W32API_USE_DLLIMPORT__ 1
#endif
#include <sys/time.h>
#include <stdarg.h>
#define MPD_BUFFER_MAX_LENGTH 50000
#define MPD_ERRORSTR_MAX_LENGTH 1000
#define MPD_WELCOME_MESSAGE "OK MPD "
#include <sys/time.h>
#define MPD_BUFFER_MAX_LENGTH 50000
#define MPD_ERRORSTR_MAX_LENGTH 1000
#define MPD_WELCOME_MESSAGE "OK MPD "
#define MPD_ERROR_TIMEOUT 10 /* timeout trying to talk to mpd */
#define MPD_ERROR_SYSTEM 11 /* system error */
#define MPD_ERROR_UNKHOST 12 /* unknown host */
#define MPD_ERROR_CONNPORT 13 /* problems connecting to port on host */
#define MPD_ERROR_NOTMPD 14 /* mpd not running on port at host */
#define MPD_ERROR_NORESPONSE 15 /* no response on attempting to connect */
#define MPD_ERROR_SENDING 16 /* error sending command */
#define MPD_ERROR_CONNCLOSED 17 /* connection closed by mpd */
#define MPD_ERROR_ACK 18 /* ACK returned! */
#define MPD_ERROR_BUFFEROVERRUN 19 /* Buffer was overrun! */
#define MPD_ERROR_TIMEOUT 10 /* timeout trying to talk to mpd */
#define MPD_ERROR_SYSTEM 11 /* system error */
#define MPD_ERROR_UNKHOST 12 /* unknown host */
#define MPD_ERROR_CONNPORT 13 /* problems connecting to port on host */
#define MPD_ERROR_NOTMPD 14 /* mpd not running on port at host */
#define MPD_ERROR_NORESPONSE 15 /* no response on attempting to connect */
#define MPD_ERROR_SENDING 16 /* error sending command */
#define MPD_ERROR_CONNCLOSED 17 /* connection closed by mpd */
#define MPD_ERROR_ACK 18 /* ACK returned! */
#define MPD_ERROR_BUFFEROVERRUN 19 /* Buffer was overrun! */
#define MPD_ACK_ERROR_UNK -1
#define MPD_ERROR_AT_UNK -1
#define MPD_ACK_ERROR_UNK -1
#define MPD_ERROR_AT_UNK -1
#define MPD_ACK_ERROR_NOT_LIST 1
#define MPD_ACK_ERROR_ARG 2
#define MPD_ACK_ERROR_PASSWORD 3
#define MPD_ACK_ERROR_PERMISSION 4
#define MPD_ACK_ERROR_UNKNOWN_CMD 5
#define MPD_ACK_ERROR_NOT_LIST 1
#define MPD_ACK_ERROR_ARG 2
#define MPD_ACK_ERROR_PASSWORD 3
#define MPD_ACK_ERROR_PERMISSION 4
#define MPD_ACK_ERROR_UNKNOWN_CMD 5
#define MPD_ACK_ERROR_NO_EXIST 50
#define MPD_ACK_ERROR_PLAYLIST_MAX 51
#define MPD_ACK_ERROR_SYSTEM 52
#define MPD_ACK_ERROR_PLAYLIST_LOAD 53
#define MPD_ACK_ERROR_UPDATE_ALREADY 54
#define MPD_ACK_ERROR_PLAYER_SYNC 55
#define MPD_ACK_ERROR_EXIST 56
#define MPD_ACK_ERROR_NO_EXIST 50
#define MPD_ACK_ERROR_PLAYLIST_MAX 51
#define MPD_ACK_ERROR_SYSTEM 52
#define MPD_ACK_ERROR_PLAYLIST_LOAD 53
#define MPD_ACK_ERROR_UPDATE_ALREADY 54
#define MPD_ACK_ERROR_PLAYER_SYNC 55
#define MPD_ACK_ERROR_EXIST 56
typedef enum mpd_TagItems {
MPD_TAG_ITEM_ARTIST,
MPD_TAG_ITEM_ALBUMARTIST,
MPD_TAG_ITEM_ALBUM,
MPD_TAG_ITEM_TITLE,
MPD_TAG_ITEM_TRACK,
MPD_TAG_ITEM_NAME,
MPD_TAG_ITEM_GENRE,
MPD_TAG_ITEM_DATE,
MPD_TAG_ITEM_COMPOSER,
MPD_TAG_ITEM_PERFORMER,
MPD_TAG_ITEM_COMMENT,
MPD_TAG_ITEM_DISC,
MPD_TAG_ITEM_FILENAME,
MPD_TAG_ITEM_ANY,
MPD_TAG_NUM_OF_ITEM_TYPES
MPD_TAG_ITEM_ARTIST,
MPD_TAG_ITEM_ALBUMARTIST,
MPD_TAG_ITEM_ALBUM,
MPD_TAG_ITEM_TITLE,
MPD_TAG_ITEM_TRACK,
MPD_TAG_ITEM_NAME,
MPD_TAG_ITEM_GENRE,
MPD_TAG_ITEM_DATE,
MPD_TAG_ITEM_COMPOSER,
MPD_TAG_ITEM_PERFORMER,
MPD_TAG_ITEM_COMMENT,
MPD_TAG_ITEM_DISC,
MPD_TAG_ITEM_FILENAME,
MPD_TAG_ITEM_ANY,
MPD_TAG_NUM_OF_ITEM_TYPES
} mpd_TagItems;
extern const char *mpdTagItemKeys[MPD_TAG_NUM_OF_ITEM_TYPES];
/* internal stuff don't touch this struct */
typedef struct _mpd_ReturnElement {
char *name;
char *value;
char *name;
char *value;
} mpd_ReturnElement;
/* mpd_Connection
* holds info about connection to mpd
* use error, and errorStr to detect errors */
typedef struct _mpd_Connection {
/* use this to check the version of mpd */
int version[3];
/* IMPORTANT, you want to get the error messages from here */
char errorStr[MPD_ERRORSTR_MAX_LENGTH + 1];
int errorCode;
int errorAt;
/* this will be set to MPD_ERROR_* if there is an error, 0 if not */
int error;
/* DON'T TOUCH any of the rest of this stuff */
int sock;
char buffer[MPD_BUFFER_MAX_LENGTH + 1];
int buflen;
int bufstart;
int doneProcessing;
int listOks;
int doneListOk;
int commandList;
mpd_ReturnElement *returnElement;
struct timeval timeout;
char *request;
/* use this to check the version of mpd */
int version[3];
/* IMPORTANT, you want to get the error messages from here */
char errorStr[MPD_ERRORSTR_MAX_LENGTH + 1];
int errorCode;
int errorAt;
/* this will be set to MPD_ERROR_* if there is an error, 0 if not */
int error;
/* DON'T TOUCH any of the rest of this stuff */
int sock;
char buffer[MPD_BUFFER_MAX_LENGTH + 1];
int buflen;
int bufstart;
int doneProcessing;
int listOks;
int doneListOk;
int commandList;
mpd_ReturnElement *returnElement;
struct timeval timeout;
char *request;
} mpd_Connection;
/* mpd_newConnection
@@ -145,53 +144,53 @@ void mpd_clearError(mpd_Connection *connection);
/* STATUS STUFF */
/* use these with status.state to determine what state the player is in */
#define MPD_STATUS_STATE_UNKNOWN 0
#define MPD_STATUS_STATE_STOP 1
#define MPD_STATUS_STATE_PLAY 2
#define MPD_STATUS_STATE_PAUSE 3
#define MPD_STATUS_STATE_UNKNOWN 0
#define MPD_STATUS_STATE_STOP 1
#define MPD_STATUS_STATE_PLAY 2
#define MPD_STATUS_STATE_PAUSE 3
/* use this with status.volume to determine if mpd has volume support */
#define MPD_STATUS_NO_VOLUME -1
#define MPD_STATUS_NO_VOLUME -1
/* mpd_Status
* holds info return from status command */
typedef struct mpd_Status {
/* 0-100, or MPD_STATUS_NO_VOLUME when there is no volume support */
int volume;
/* 1 if repeat is on, 0 otherwise */
int repeat;
/* 1 if random is on, 0 otherwise */
int random;
/* playlist length */
int playlistLength;
/* playlist, use this to determine when the playlist has changed */
long long playlist;
/* use with MPD_STATUS_STATE_* to determine state of player */
int state;
/* crossfade setting in seconds */
int crossfade;
/* if a song is currently selected (always the case when state is PLAY
* or PAUSE), this is the position of the currently playing song in the
* playlist, beginning with 0 */
int song;
/* Song ID of the currently selected song */
int songid;
/* time in seconds that have elapsed in the currently playing/paused song */
int elapsedTime;
/* length in seconds of the currently playing/paused song */
int totalTime;
/* current bit rate in kbs */
int bitRate;
/* audio sample rate */
unsigned int sampleRate;
/* audio bits */
int bits;
/* audio channels */
int channels;
/* 1 if mpd is updating, 0 otherwise */
int updatingDb;
/* error */
char *error;
/* 0-100, or MPD_STATUS_NO_VOLUME when there is no volume support */
int volume;
/* 1 if repeat is on, 0 otherwise */
int repeat;
/* 1 if random is on, 0 otherwise */
int random;
/* playlist length */
int playlistLength;
/* playlist, use this to determine when the playlist has changed */
long long playlist;
/* use with MPD_STATUS_STATE_* to determine state of player */
int state;
/* crossfade setting in seconds */
int crossfade;
/* if a song is currently selected (always the case when state is PLAY
* or PAUSE), this is the position of the currently playing song in the
* playlist, beginning with 0 */
int song;
/* Song ID of the currently selected song */
int songid;
/* time in seconds that have elapsed in the currently playing/paused song */
int elapsedTime;
/* length in seconds of the currently playing/paused song */
int totalTime;
/* current bit rate in kbs */
int bitRate;
/* audio sample rate */
unsigned int sampleRate;
/* audio bits */
int bits;
/* audio channels */
int channels;
/* 1 if mpd is updating, 0 otherwise */
int updatingDb;
/* error */
char *error;
} mpd_Status;
void mpd_sendStatusCommand(mpd_Connection *connection);
@@ -206,18 +205,18 @@ mpd_Status *mpd_getStatus(mpd_Connection *connection);
void mpd_freeStatus(mpd_Status *status);
typedef struct _mpd_Stats {
int numberOfArtists;
int numberOfAlbums;
int numberOfSongs;
unsigned long uptime;
unsigned long dbUpdateTime;
unsigned long playTime;
unsigned long dbPlayTime;
int numberOfArtists;
int numberOfAlbums;
int numberOfSongs;
unsigned long uptime;
unsigned long dbUpdateTime;
unsigned long playTime;
unsigned long dbPlayTime;
} mpd_Stats;
typedef struct _mpd_SearchStats {
int numberOfSongs;
unsigned long playTime;
int numberOfSongs;
unsigned long playTime;
} mpd_SearchStats;
void mpd_sendStatsCommand(mpd_Connection *connection);
@@ -232,50 +231,50 @@ void mpd_freeSearchStats(mpd_SearchStats *stats);
/* SONG STUFF */
#define MPD_SONG_NO_TIME -1
#define MPD_SONG_NO_NUM -1
#define MPD_SONG_NO_ID -1
#define MPD_SONG_NO_TIME -1
#define MPD_SONG_NO_NUM -1
#define MPD_SONG_NO_ID -1
/* mpd_Song
* for storing song info returned by mpd */
typedef struct _mpd_Song {
/* filename of song */
char *file;
/* artist, maybe NULL if there is no tag */
char *artist;
/* albumartist, maybe NULL if there is no tag */
char *albumartist;
/* title, maybe NULL if there is no tag */
char *title;
/* album, maybe NULL if there is no tag */
char *album;
/* track, maybe NULL if there is no tag */
char *track;
/* name, maybe NULL if there is no tag; it's the name of the current song,
* f.e. the icyName of the stream */
char *name;
/* date */
char *date;
/* filename of song */
char *file;
/* artist, maybe NULL if there is no tag */
char *artist;
/* albumartist, maybe NULL if there is no tag */
char *albumartist;
/* title, maybe NULL if there is no tag */
char *title;
/* album, maybe NULL if there is no tag */
char *album;
/* track, maybe NULL if there is no tag */
char *track;
/* name, maybe NULL if there is no tag; it's the name of the current song,
* f.e. the icyName of the stream */
char *name;
/* date */
char *date;
/* added by qball */
/* Genre */
char *genre;
/* Composer */
char *composer;
/* Performer */
char *performer;
/* Disc */
char *disc;
/* Comment */
char *comment;
/* added by qball */
/* Genre */
char *genre;
/* Composer */
char *composer;
/* Performer */
char *performer;
/* Disc */
char *disc;
/* Comment */
char *comment;
/* length of song in seconds, check that it is not MPD_SONG_NO_TIME */
int time;
/* if plchanges/playlistinfo/playlistid used, is the position of the song
* in the playlist */
int pos;
/* song id for a song in the playlist */
int id;
/* length of song in seconds, check that it is not MPD_SONG_NO_TIME */
int time;
/* if plchanges/playlistinfo/playlistid used, is the position of the song
* in the playlist */
int pos;
/* song id for a song in the playlist */
int id;
} mpd_Song;
/* mpd_newSong
@@ -301,7 +300,7 @@ mpd_Song *mpd_songDup(mpd_Song *song);
/* mpd_Directory
* used to store info from directory (right now just the path) */
typedef struct _mpd_Directory {
char *path;
char *path;
} mpd_Directory;
/* mpd_newDirectory
@@ -323,7 +322,7 @@ mpd_Directory *mpd_directoryDup(mpd_Directory *directory);
/* mpd_PlaylistFile
* stores info about playlist file returned by lsinfo */
typedef struct _mpd_PlaylistFile {
char *path;
char *path;
} mpd_PlaylistFile;
/* mpd_newPlaylistFile
@@ -344,22 +343,22 @@ mpd_PlaylistFile *mpd_playlistFileDup(mpd_PlaylistFile *playlist);
/* the type of entity returned from one of the commands that generates info
* use in conjunction with mpd_InfoEntity.type */
#define MPD_INFO_ENTITY_TYPE_DIRECTORY 0
#define MPD_INFO_ENTITY_TYPE_SONG 1
#define MPD_INFO_ENTITY_TYPE_PLAYLISTFILE 2
#define MPD_INFO_ENTITY_TYPE_DIRECTORY 0
#define MPD_INFO_ENTITY_TYPE_SONG 1
#define MPD_INFO_ENTITY_TYPE_PLAYLISTFILE 2
/* mpd_InfoEntity
* stores info on stuff returned info commands */
typedef struct mpd_InfoEntity {
/* the type of entity, use with MPD_INFO_ENTITY_TYPE_* to determine
* what this entity is (song, directory, etc...) */
int type;
/* the actual data you want, mpd_Song, mpd_Directory, etc */
union {
mpd_Directory *directory;
mpd_Song *song;
mpd_PlaylistFile *playlistFile;
} info;
/* the type of entity, use with MPD_INFO_ENTITY_TYPE_* to determine
* what this entity is (song, directory, etc...) */
int type;
/* the actual data you want, mpd_Song, mpd_Directory, etc */
union {
mpd_Directory *directory;
mpd_Song *song;
mpd_PlaylistFile *playlistFile;
} info;
} mpd_InfoEntity;
mpd_InfoEntity *mpd_newInfoEntity(void);
@@ -391,7 +390,7 @@ void mpd_sendPlChangesCommand(mpd_Connection *connection, long long playlist);
* A more bandwidth efficient version of the mpd_sendPlChangesCommand.
* It only returns the pos+id of the changes song. */
void mpd_sendPlChangesPosIdCommand(mpd_Connection *connection,
long long playlist);
long long playlist);
/* recursively fetches all songs/dir/playlists in "dir*
* (no metadata is returned) */
@@ -403,16 +402,16 @@ void mpd_sendListallInfoCommand(mpd_Connection *connection, const char *dir);
/* non-recursive version of ListallInfo */
void mpd_sendLsInfoCommand(mpd_Connection *connection, const char *dir);
#define MPD_TABLE_ARTIST MPD_TAG_ITEM_ARTIST
#define MPD_TABLE_ALBUM MPD_TAG_ITEM_ALBUM
#define MPD_TABLE_TITLE MPD_TAG_ITEM_TITLE
#define MPD_TABLE_FILENAME MPD_TAG_ITEM_FILENAME
#define MPD_TABLE_ARTIST MPD_TAG_ITEM_ARTIST
#define MPD_TABLE_ALBUM MPD_TAG_ITEM_ALBUM
#define MPD_TABLE_TITLE MPD_TAG_ITEM_TITLE
#define MPD_TABLE_FILENAME MPD_TAG_ITEM_FILENAME
void mpd_sendSearchCommand(mpd_Connection *connection, int table,
const char *str);
const char *str);
void mpd_sendFindCommand(mpd_Connection *connection, int table,
const char *str);
const char *str);
/* LIST TAG COMMANDS */
@@ -430,7 +429,7 @@ char *mpd_getNextTag(mpd_Connection *connection, int type);
* arg1 should be set to the artist if listing albums by a artist
* otherwise NULL for listing all artists or albums */
void mpd_sendListCommand(mpd_Connection *connection, int table,
const char *arg1);
const char *arg1);
/* SIMPLE COMMANDS */
@@ -449,14 +448,14 @@ void mpd_sendLoadCommand(mpd_Connection *connection, const char *name);
void mpd_sendRmCommand(mpd_Connection *connection, const char *name);
void mpd_sendRenameCommand(mpd_Connection *connection, const char *from,
const char *to);
const char *to);
void mpd_sendShuffleCommand(mpd_Connection *connection);
void mpd_sendClearCommand(mpd_Connection *connection);
/* use this to start playing at the beginning, useful when in random mode */
#define MPD_PLAY_AT_BEGINNING -1
#define MPD_PLAY_AT_BEGINNING -1
void mpd_sendPlayCommand(mpd_Connection *connection, int songNum);
@@ -517,9 +516,9 @@ void mpd_sendCommandListEnd(mpd_Connection *connection);
int mpd_nextListOkCommand(mpd_Connection *connection);
typedef struct _mpd_OutputEntity {
int id;
char *name;
int enabled;
int id;
char *name;
int enabled;
} mpd_OutputEntity;
void mpd_sendOutputsCommand(mpd_Connection *connection);
@@ -588,7 +587,7 @@ void mpd_startSearch(mpd_Connection *connection, int exact);
* @param type
* @param name */
void mpd_addConstraintSearch(mpd_Connection *connection, int type,
const char *name);
const char *name);
/**
* @param connection a #mpd_Connection */
@@ -624,12 +623,12 @@ void mpd_startStatsSearch(mpd_Connection *connection);
void mpd_sendPlaylistClearCommand(mpd_Connection *connection, char *path);
void mpd_sendPlaylistAddCommand(mpd_Connection *connection, char *playlist,
char *path);
char *path);
void mpd_sendPlaylistMoveCommand(mpd_Connection *connection, char *playlist,
int from, int to);
int from, int to);
void mpd_sendPlaylistDeleteCommand(mpd_Connection *connection, char *playlist,
int pos);
int pos);
#endif

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* libtcp-portmon.c: tcp port monitoring library.
*
@@ -30,8 +29,8 @@
#include <cstdio>
#include <cstring>
#include <vector>
#include <unordered_map>
#include <vector>
/* -------------------------------------------------------------------
* IMPLEMENTATION INTERFACE
@@ -42,330 +41,321 @@
* ------------------------------------------------------------------- */
namespace {
/* ------------------------------------------------------------------------
* A single tcp connection
* ------------------------------------------------------------------------ */
struct tcp_connection_t {
/* connection's key in monitor hash */
struct in6_addr local_addr;
struct in6_addr remote_addr;
in_port_t local_port;
in_port_t remote_port;
};
/* ------------------------------------------------------------------------
* A single tcp connection
* ------------------------------------------------------------------------ */
struct tcp_connection_t {
/* connection's key in monitor hash */
struct in6_addr local_addr;
struct in6_addr remote_addr;
in_port_t local_port;
in_port_t remote_port;
};
/* hash function for tcp connections */
struct tcp_connection_hash {
size_t operator()(const tcp_connection_t &a) const
{
size_t hash = 0;
size_t i;
/* hash function for tcp connections */
struct tcp_connection_hash {
size_t operator()(const tcp_connection_t &a) const {
size_t hash = 0;
size_t i;
hash = hash*47 + a.local_port;
hash = hash*47 + a.remote_port;
for(i = 0; i < sizeof(a.local_addr.s6_addr); ++i)
hash = hash*47 + a.local_addr.s6_addr[i];
for(i = 0; i < sizeof(a.remote_addr.s6_addr); ++i)
hash = hash*47 + a.remote_addr.s6_addr[i];
hash = hash * 47 + a.local_port;
hash = hash * 47 + a.remote_port;
for (i = 0; i < sizeof(a.local_addr.s6_addr); ++i)
hash = hash * 47 + a.local_addr.s6_addr[i];
for (i = 0; i < sizeof(a.remote_addr.s6_addr); ++i)
hash = hash * 47 + a.remote_addr.s6_addr[i];
return hash;
}
};
/* comparison function for tcp connections */
bool operator==(const tcp_connection_t &a, const tcp_connection_t &b)
{
return a.local_port == b.local_port && a.remote_port == b.remote_port &&
! std::memcmp(&a.local_addr, &b.local_addr, sizeof(a.local_addr)) &&
! std::memcmp(&a.remote_addr.s6_addr, &b.remote_addr, sizeof(a.remote_addr));
}
/* ------------------------------------------------------------------------
* A hash table containing tcp connection
*
* The second parameter provides the mechanism for removing connections if
* they are not seen again in subsequent update cycles.
* ------------------------------------------------------------------------ */
typedef std::unordered_map<tcp_connection_t, int, tcp_connection_hash> connection_hash_t;
/* start and end of port monitor range. Set start=end to monitor a single port */
typedef std::pair<in_port_t, in_port_t> port_range_t;
/* hash function for port ranges */
struct port_range_hash {
size_t operator()(const port_range_t &a) const
{
return a.first*47 + a.second;
}
};
typedef std::unordered_map<port_range_t,
tcp_port_monitor_t,
port_range_hash> monitor_hash_t;
return hash;
}
};
/* comparison function for tcp connections */
bool operator==(const tcp_connection_t &a, const tcp_connection_t &b) {
return a.local_port == b.local_port && a.remote_port == b.remote_port &&
!std::memcmp(&a.local_addr, &b.local_addr, sizeof(a.local_addr)) &&
!std::memcmp(&a.remote_addr.s6_addr, &b.remote_addr,
sizeof(a.remote_addr));
}
/* ------------------------------------------------------------------------
* A hash table containing tcp connection
*
* The second parameter provides the mechanism for removing connections if
* they are not seen again in subsequent update cycles.
* ------------------------------------------------------------------------ */
typedef std::unordered_map<tcp_connection_t, int, tcp_connection_hash>
connection_hash_t;
/* start and end of port monitor range. Set start=end to monitor a single port
*/
typedef std::pair<in_port_t, in_port_t> port_range_t;
/* hash function for port ranges */
struct port_range_hash {
size_t operator()(const port_range_t &a) const {
return a.first * 47 + a.second;
}
};
typedef std::unordered_map<port_range_t, tcp_port_monitor_t, port_range_hash>
monitor_hash_t;
} // namespace
/* --------------
* A port monitor
* -------------- */
struct _tcp_port_monitor_t {
/* hash table of pointers into connection list */
connection_hash_t hash;
/* array of connection pointers for O(1) peeking
* these point into the hash table*/
std::vector<const tcp_connection_t *> p_peek;
/* hash table of pointers into connection list */
connection_hash_t hash;
/* array of connection pointers for O(1) peeking
* these point into the hash table*/
std::vector<const tcp_connection_t *> p_peek;
_tcp_port_monitor_t(int max_connections)
: hash(), p_peek(max_connections, static_cast<const tcp_connection_t *>(NULL))
{ }
_tcp_port_monitor_t(int max_connections)
: hash(),
p_peek(max_connections, static_cast<const tcp_connection_t *>(NULL)) {}
_tcp_port_monitor_t(const _tcp_port_monitor_t &other)
: hash(other.hash), p_peek(other.p_peek.size(), static_cast<const tcp_connection_t *>(NULL))
{
// we must rebuild the peek table because the pointers are no longer valid
rebuild_peek_table();
}
_tcp_port_monitor_t(const _tcp_port_monitor_t &other)
: hash(other.hash),
p_peek(other.p_peek.size(),
static_cast<const tcp_connection_t *>(NULL)) {
// we must rebuild the peek table because the pointers are no longer valid
rebuild_peek_table();
}
void rebuild_peek_table()
{
/* Run through the monitor's connections and rebuild the peek table of
* connection pointers. This is done so peeking into the monitor can be
* done in O(1) time instead of O(n) time for each peek. */
void rebuild_peek_table() {
/* Run through the monitor's connections and rebuild the peek table of
* connection pointers. This is done so peeking into the monitor can be
* done in O(1) time instead of O(n) time for each peek. */
/* zero out the peek array */
std::fill(p_peek.begin(), p_peek.end(), static_cast<tcp_connection_t *>(NULL));
/* zero out the peek array */
std::fill(p_peek.begin(), p_peek.end(),
static_cast<tcp_connection_t *>(NULL));
size_t i = 0;
for (connection_hash_t::iterator j = hash.begin(); j != hash.end(); ++j, ++i ) {
p_peek[i] = &j->first;
}
}
size_t i = 0;
for (connection_hash_t::iterator j = hash.begin(); j != hash.end();
++j, ++i) {
p_peek[i] = &j->first;
}
}
private:
// we don't need this atm
const _tcp_port_monitor_t& operator=(const _tcp_port_monitor_t &);
private:
// we don't need this atm
const _tcp_port_monitor_t &operator=(const _tcp_port_monitor_t &);
};
/* -----------------------------
* A tcp port monitor collection
* ----------------------------- */
struct _tcp_port_monitor_collection_t {
/* hash table of monitors */
monitor_hash_t hash;
/* hash table of monitors */
monitor_hash_t hash;
};
namespace {
/* ---------------------------------------
* A port monitor utility function typedef
* --------------------------------------- */
typedef void (*tcp_port_monitor_function_ptr_t)(monitor_hash_t::value_type &monitor,
void *p_void);
/* ---------------------------------------
* A port monitor utility function typedef
* --------------------------------------- */
typedef void (*tcp_port_monitor_function_ptr_t)(
monitor_hash_t::value_type &monitor, void *p_void);
void age_tcp_port_monitor(monitor_hash_t::value_type &monitor, void *p_void)
{
/* Run through the monitor's connections and decrement the age variable.
* If the age goes negative, we remove the connection from the monitor.
* Function takes O(n) time on the number of connections. */
void age_tcp_port_monitor(monitor_hash_t::value_type &monitor, void *p_void) {
/* Run through the monitor's connections and decrement the age variable.
* If the age goes negative, we remove the connection from the monitor.
* Function takes O(n) time on the number of connections. */
if (p_void) { /* p_void should be NULL in this context */
return;
}
if (p_void) { /* p_void should be NULL in this context */
return;
}
for (connection_hash_t::iterator i = monitor.second.hash.begin();
i != monitor.second.hash.end(); ) {
if (--i->second >= 0)
++i;
else {
/* connection is old. remove connection from the hash. */
/* erase shouldn't invalidate iterators */
monitor.second.hash.erase(i++);
}
}
}
void rebuild_tcp_port_monitor_peek_table(monitor_hash_t::value_type &monitor,
void *p_void)
{
if (p_void) { /* p_void should be NULL in this context */
return;
}
monitor.second.rebuild_peek_table();
}
void show_connection_to_tcp_port_monitor(monitor_hash_t::value_type &monitor,
void *p_void)
{
/* The monitor gets to look at each connection to see if it falls within
* the monitor's port range of interest. Connections of interest are first
* looked up in the hash to see if they are already there. If they are, we
* reset the age of the connection so it is not deleted. If the connection
* is not in the hash, we add it, but only if we haven't exceeded the
* maximum connection limit for the monitor.
* The function takes O(1) time. */
tcp_connection_t *p_connection;
if (!p_void) {
return;
}
/* This p_connection is on caller's stack and not the heap.
* If we are interested, we will create a copy of the connection
* (on the heap) and add it to our list. */
p_connection = (tcp_connection_t *) p_void;
/* inspect the local port number of the connection to see if we're
* interested. */
if ((monitor.first.first <= p_connection->local_port)
&& (p_connection->local_port <= monitor.first.second)) {
/* the connection is in the range of the monitor. */
/* first check the hash to see if the connection is already there. */
connection_hash_t::iterator i = monitor.second.hash.find(*p_connection);
if (i != monitor.second.hash.end()) {
/* it's already in the hash. reset the age of the connection. */
i->second = TCP_CONNECTION_STARTING_AGE;
return;
}
/* Connection is not yet in the hash.
* Add it if max_connections not exceeded. */
if (monitor.second.hash.size() < monitor.second.p_peek.size()) {
monitor.second.hash.insert(connection_hash_t::value_type(*p_connection,
TCP_CONNECTION_STARTING_AGE));
}
}
}
/* ------------------------------------------------------------------------
* Apply a tcp_port_monitor_function_ptr_t function to each port monitor in
* the collection.
* ------------------------------------------------------------------------ */
void for_each_tcp_port_monitor_in_collection(
tcp_port_monitor_collection_t *p_collection,
tcp_port_monitor_function_ptr_t p_function, void *p_function_args)
{
if (!p_collection || !p_function) {
return;
}
/* for each monitor in the collection */
for (monitor_hash_t::iterator i = p_collection->hash.begin();
i != p_collection->hash.end(); ++i) {
/* apply the function with the given arguments */
p_function(*i, p_function_args);
}
}
const unsigned char prefix_4on6[] = {
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff
};
union sockaddr_in46 {
struct sockaddr_in sa4;
struct sockaddr_in6 sa6;
struct sockaddr sa;
};
/* checks whether the address is a IPv4-mapped IPv6 address */
bool is_4on6(const struct in6_addr *addr)
{
return ! std::memcmp(&addr->s6_addr, prefix_4on6, sizeof(prefix_4on6));
}
/* converts the address to appropriate textual representation (IPv6, IPv4 or fqdn) */
void print_host(char *p_buffer, size_t buffer_size, const struct in6_addr *addr, int fqdn)
{
union sockaddr_in46 sa;
socklen_t slen;
std::memset(&sa, 0, sizeof(sa));
if(is_4on6(addr)) {
sa.sa4.sin_family = AF_INET;
std::memcpy(&sa.sa4.sin_addr.s_addr, &addr->s6_addr[12], 4);
slen = sizeof(sa.sa4);
} else {
sa.sa6.sin6_family = AF_INET6;
std::memcpy(&sa.sa6.sin6_addr, addr, sizeof(struct in6_addr));
slen = sizeof(sa.sa6);
}
getnameinfo(&sa.sa, slen, p_buffer, buffer_size, NULL, 0, fqdn?0:NI_NUMERICHOST);
}
/* converts the textual representation of an IPv4 or IPv6 address to struct in6_addr */
void string_to_addr(struct in6_addr *addr, const char *p_buffer)
{
size_t i;
if(std::strlen(p_buffer) < 32) { //IPv4 address
i = sizeof(prefix_4on6);
std::memcpy(addr->s6_addr, prefix_4on6, i);
} else {
i = 0;
}
for( ; i < sizeof(addr->s6_addr); i+=4, p_buffer+=8) {
std::sscanf(p_buffer, "%8x", (unsigned *)&addr->s6_addr[i]);
}
}
/* adds connections from file to the collection */
void process_file(tcp_port_monitor_collection_t *p_collection, const char *file)
{
std::FILE *fp;
char buf[256];
char local_addr[40];
char remote_addr[40];
tcp_connection_t conn;
unsigned long inode, uid, state;
if ((fp = std::fopen(file, "r")) == NULL) {
return;
}
/* ignore field name line */
if(std::fgets(buf, 255, fp) == NULL) {
std::fclose(fp);
return;
}
/* read all tcp connections */
while (std::fgets(buf, sizeof(buf), fp) != NULL) {
if (std::sscanf(buf,
"%*d: %39[0-9a-fA-F]:%hx %39[0-9a-fA-F]:%hx %lx %*x:%*x %*x:%*x %*x %lu %*d %lu",
local_addr, &conn.local_port,
remote_addr, &conn.remote_port,
(unsigned long *) &state, (unsigned long *) &uid,
(unsigned long *) &inode) != 7) {
std::fprintf(stderr, "%s: bad file format\n", file);
}
/** TCP_ESTABLISHED equals 1, but is not (always??) included **/
//if ((inode == 0) || (state != TCP_ESTABLISHED)) {
if((inode == 0) || (state != 1)) {
continue;
}
string_to_addr(&conn.local_addr, local_addr);
string_to_addr(&conn.remote_addr, remote_addr);
/* show the connection to each port monitor. */
for_each_tcp_port_monitor_in_collection(p_collection,
&show_connection_to_tcp_port_monitor, (void *) &conn);
}
std::fclose(fp);
}
for (connection_hash_t::iterator i = monitor.second.hash.begin();
i != monitor.second.hash.end();) {
if (--i->second >= 0)
++i;
else {
/* connection is old. remove connection from the hash. */
/* erase shouldn't invalidate iterators */
monitor.second.hash.erase(i++);
}
}
}
void rebuild_tcp_port_monitor_peek_table(monitor_hash_t::value_type &monitor,
void *p_void) {
if (p_void) { /* p_void should be NULL in this context */
return;
}
monitor.second.rebuild_peek_table();
}
void show_connection_to_tcp_port_monitor(monitor_hash_t::value_type &monitor,
void *p_void) {
/* The monitor gets to look at each connection to see if it falls within
* the monitor's port range of interest. Connections of interest are first
* looked up in the hash to see if they are already there. If they are, we
* reset the age of the connection so it is not deleted. If the connection
* is not in the hash, we add it, but only if we haven't exceeded the
* maximum connection limit for the monitor.
* The function takes O(1) time. */
tcp_connection_t *p_connection;
if (!p_void) {
return;
}
/* This p_connection is on caller's stack and not the heap.
* If we are interested, we will create a copy of the connection
* (on the heap) and add it to our list. */
p_connection = (tcp_connection_t *)p_void;
/* inspect the local port number of the connection to see if we're
* interested. */
if ((monitor.first.first <= p_connection->local_port) &&
(p_connection->local_port <= monitor.first.second)) {
/* the connection is in the range of the monitor. */
/* first check the hash to see if the connection is already there. */
connection_hash_t::iterator i = monitor.second.hash.find(*p_connection);
if (i != monitor.second.hash.end()) {
/* it's already in the hash. reset the age of the connection. */
i->second = TCP_CONNECTION_STARTING_AGE;
return;
}
/* Connection is not yet in the hash.
* Add it if max_connections not exceeded. */
if (monitor.second.hash.size() < monitor.second.p_peek.size()) {
monitor.second.hash.insert(connection_hash_t::value_type(
*p_connection, TCP_CONNECTION_STARTING_AGE));
}
}
}
/* ------------------------------------------------------------------------
* Apply a tcp_port_monitor_function_ptr_t function to each port monitor in
* the collection.
* ------------------------------------------------------------------------ */
void for_each_tcp_port_monitor_in_collection(
tcp_port_monitor_collection_t *p_collection,
tcp_port_monitor_function_ptr_t p_function, void *p_function_args) {
if (!p_collection || !p_function) {
return;
}
/* for each monitor in the collection */
for (monitor_hash_t::iterator i = p_collection->hash.begin();
i != p_collection->hash.end(); ++i) {
/* apply the function with the given arguments */
p_function(*i, p_function_args);
}
}
const unsigned char prefix_4on6[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff};
union sockaddr_in46 {
struct sockaddr_in sa4;
struct sockaddr_in6 sa6;
struct sockaddr sa;
};
/* checks whether the address is a IPv4-mapped IPv6 address */
bool is_4on6(const struct in6_addr *addr) {
return !std::memcmp(&addr->s6_addr, prefix_4on6, sizeof(prefix_4on6));
}
/* converts the address to appropriate textual representation (IPv6, IPv4 or
* fqdn) */
void print_host(char *p_buffer, size_t buffer_size, const struct in6_addr *addr,
int fqdn) {
union sockaddr_in46 sa;
socklen_t slen;
std::memset(&sa, 0, sizeof(sa));
if (is_4on6(addr)) {
sa.sa4.sin_family = AF_INET;
std::memcpy(&sa.sa4.sin_addr.s_addr, &addr->s6_addr[12], 4);
slen = sizeof(sa.sa4);
} else {
sa.sa6.sin6_family = AF_INET6;
std::memcpy(&sa.sa6.sin6_addr, addr, sizeof(struct in6_addr));
slen = sizeof(sa.sa6);
}
getnameinfo(&sa.sa, slen, p_buffer, buffer_size, NULL, 0,
fqdn ? 0 : NI_NUMERICHOST);
}
/* converts the textual representation of an IPv4 or IPv6 address to struct
* in6_addr */
void string_to_addr(struct in6_addr *addr, const char *p_buffer) {
size_t i;
if (std::strlen(p_buffer) < 32) { // IPv4 address
i = sizeof(prefix_4on6);
std::memcpy(addr->s6_addr, prefix_4on6, i);
} else {
i = 0;
}
for (; i < sizeof(addr->s6_addr); i += 4, p_buffer += 8) {
std::sscanf(p_buffer, "%8x", (unsigned *)&addr->s6_addr[i]);
}
}
/* adds connections from file to the collection */
void process_file(tcp_port_monitor_collection_t *p_collection,
const char *file) {
std::FILE *fp;
char buf[256];
char local_addr[40];
char remote_addr[40];
tcp_connection_t conn;
unsigned long inode, uid, state;
if ((fp = std::fopen(file, "r")) == NULL) {
return;
}
/* ignore field name line */
if (std::fgets(buf, 255, fp) == NULL) {
std::fclose(fp);
return;
}
/* read all tcp connections */
while (std::fgets(buf, sizeof(buf), fp) != NULL) {
if (std::sscanf(buf,
"%*d: %39[0-9a-fA-F]:%hx %39[0-9a-fA-F]:%hx %lx %*x:%*x "
"%*x:%*x %*x %lu %*d %lu",
local_addr, &conn.local_port, remote_addr,
&conn.remote_port, (unsigned long *)&state,
(unsigned long *)&uid, (unsigned long *)&inode) != 7) {
std::fprintf(stderr, "%s: bad file format\n", file);
}
/** TCP_ESTABLISHED equals 1, but is not (always??) included **/
// if ((inode == 0) || (state != TCP_ESTABLISHED)) {
if ((inode == 0) || (state != 1)) {
continue;
}
string_to_addr(&conn.local_addr, local_addr);
string_to_addr(&conn.remote_addr, remote_addr);
/* show the connection to each port monitor. */
for_each_tcp_port_monitor_in_collection(
p_collection, &show_connection_to_tcp_port_monitor, (void *)&conn);
}
std::fclose(fp);
}
} // namespace
/* ----------------------------------------------------------------------
* CLIENT INTERFACE
*
@@ -381,81 +371,88 @@ namespace {
* The requested monitor value is copied into a client-supplied char buffer.
* Returns 0 on success, -1 otherwise. */
int peek_tcp_port_monitor(const tcp_port_monitor_t *p_monitor, int item,
int connection_index, char *p_buffer, size_t buffer_size)
{
struct sockaddr_in sa;
int connection_index, char *p_buffer,
size_t buffer_size) {
struct sockaddr_in sa;
if (!p_monitor || !p_buffer || connection_index < 0) {
return -1;
}
if (!p_monitor || !p_buffer || connection_index < 0) {
return -1;
}
std::memset(p_buffer, 0, buffer_size);
std::memset(&sa, 0, sizeof(sa));
std::memset(p_buffer, 0, buffer_size);
std::memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
/* if the connection index is out of range, we simply return with no error,
* having first cleared the client-supplied buffer. */
if ( (item != COUNT) && (connection_index >= ssize_t(p_monitor->hash.size())) ) {
return 0;
}
sa.sin_family = AF_INET;
switch (item) {
/* if the connection index is out of range, we simply return with no error,
* having first cleared the client-supplied buffer. */
if ((item != COUNT) &&
(connection_index >= ssize_t(p_monitor->hash.size()))) {
return 0;
}
case COUNT:
switch (item) {
case COUNT:
std::snprintf(p_buffer, buffer_size, "%u", unsigned(p_monitor->hash.size()));
break;
std::snprintf(p_buffer, buffer_size, "%u",
unsigned(p_monitor->hash.size()));
break;
case REMOTEIP:
case REMOTEIP:
print_host(p_buffer, buffer_size, &p_monitor->p_peek[connection_index]->remote_addr, 0);
break;
print_host(p_buffer, buffer_size,
&p_monitor->p_peek[connection_index]->remote_addr, 0);
break;
case REMOTEHOST:
case REMOTEHOST:
print_host(p_buffer, buffer_size, &p_monitor->p_peek[connection_index]->remote_addr, 1);
break;
print_host(p_buffer, buffer_size,
&p_monitor->p_peek[connection_index]->remote_addr, 1);
break;
case REMOTEPORT:
case REMOTEPORT:
std::snprintf(p_buffer, buffer_size, "%d",
p_monitor->p_peek[connection_index]->remote_port);
break;
std::snprintf(p_buffer, buffer_size, "%d",
p_monitor->p_peek[connection_index]->remote_port);
break;
case REMOTESERVICE:
case REMOTESERVICE:
sa.sin_port=htons(p_monitor->p_peek[connection_index]->remote_port);
getnameinfo((struct sockaddr *) &sa, sizeof(struct sockaddr_in), NULL, 0, p_buffer, buffer_size, NI_NUMERICHOST);
break;
sa.sin_port = htons(p_monitor->p_peek[connection_index]->remote_port);
getnameinfo((struct sockaddr *)&sa, sizeof(struct sockaddr_in), NULL, 0,
p_buffer, buffer_size, NI_NUMERICHOST);
break;
case LOCALIP:
case LOCALIP:
print_host(p_buffer, buffer_size, &p_monitor->p_peek[connection_index]->local_addr, 0);
break;
print_host(p_buffer, buffer_size,
&p_monitor->p_peek[connection_index]->local_addr, 0);
break;
case LOCALHOST:
case LOCALHOST:
print_host(p_buffer, buffer_size, &p_monitor->p_peek[connection_index]->local_addr, 1);
break;
print_host(p_buffer, buffer_size,
&p_monitor->p_peek[connection_index]->local_addr, 1);
break;
case LOCALPORT:
case LOCALPORT:
std::snprintf(p_buffer, buffer_size, "%d",
p_monitor->p_peek[connection_index]->local_port);
break;
std::snprintf(p_buffer, buffer_size, "%d",
p_monitor->p_peek[connection_index]->local_port);
break;
case LOCALSERVICE:
case LOCALSERVICE:
sa.sin_port=htons(p_monitor->p_peek[connection_index]->local_port);
getnameinfo((struct sockaddr *) &sa, sizeof(struct sockaddr_in), NULL, 0, p_buffer, buffer_size, NI_NUMERICHOST);
break;
sa.sin_port = htons(p_monitor->p_peek[connection_index]->local_port);
getnameinfo((struct sockaddr *)&sa, sizeof(struct sockaddr_in), NULL, 0,
p_buffer, buffer_size, NI_NUMERICHOST);
break;
default:
return -1;
}
default:
return -1;
}
return 0;
return 0;
}
/* --------------------------------
@@ -463,70 +460,63 @@ int peek_tcp_port_monitor(const tcp_port_monitor_t *p_monitor, int item,
* -------------------------------- */
/* Create a monitor collection. Do this one first. */
tcp_port_monitor_collection_t *create_tcp_port_monitor_collection(void)
{
return new tcp_port_monitor_collection_t();
tcp_port_monitor_collection_t *create_tcp_port_monitor_collection(void) {
return new tcp_port_monitor_collection_t();
}
/* Destroy the monitor collection (and the monitors inside).
* Do this one last. */
void destroy_tcp_port_monitor_collection(
tcp_port_monitor_collection_t *p_collection)
{
delete p_collection;
tcp_port_monitor_collection_t *p_collection) {
delete p_collection;
}
/* Updates the tcp statistics for all monitors within a collection */
void update_tcp_port_monitor_collection(
tcp_port_monitor_collection_t *p_collection)
{
if (!p_collection) {
return;
}
tcp_port_monitor_collection_t *p_collection) {
if (!p_collection) {
return;
}
process_file(p_collection, "/proc/net/tcp");
process_file(p_collection, "/proc/net/tcp6");
process_file(p_collection, "/proc/net/tcp");
process_file(p_collection, "/proc/net/tcp6");
/* age the connections in all port monitors. */
for_each_tcp_port_monitor_in_collection(p_collection,
&age_tcp_port_monitor, NULL);
/* age the connections in all port monitors. */
for_each_tcp_port_monitor_in_collection(p_collection, &age_tcp_port_monitor,
NULL);
/* rebuild the connection peek tables of all monitors
* so clients can peek in O(1) time */
for_each_tcp_port_monitor_in_collection(p_collection,
&rebuild_tcp_port_monitor_peek_table, NULL);
/* rebuild the connection peek tables of all monitors
* so clients can peek in O(1) time */
for_each_tcp_port_monitor_in_collection(
p_collection, &rebuild_tcp_port_monitor_peek_table, NULL);
}
/* Creation of reduntant monitors is silently ignored */
int insert_new_tcp_port_monitor_into_collection(
tcp_port_monitor_collection_t *p_collection, in_port_t port_range_begin,
in_port_t port_range_end, tcp_port_monitor_args_t *p_creation_args)
{
tcp_port_monitor_collection_t *p_collection, in_port_t port_range_begin,
in_port_t port_range_end, tcp_port_monitor_args_t *p_creation_args) {
if (!p_collection) {
return -1;
}
if (!p_collection) {
return -1;
}
p_collection->hash.insert(monitor_hash_t::value_type(
port_range_t(port_range_begin, port_range_end),
tcp_port_monitor_t(p_creation_args->max_port_monitor_connections)));
p_collection->hash.insert( monitor_hash_t::value_type(
port_range_t(port_range_begin, port_range_end),
tcp_port_monitor_t(p_creation_args->max_port_monitor_connections)
) );
return 0;
return 0;
}
/* Clients need a way to find monitors */
tcp_port_monitor_t *find_tcp_port_monitor(
tcp_port_monitor_collection_t *p_collection,
in_port_t port_range_begin, in_port_t port_range_end)
{
if (!p_collection) {
return NULL;
}
tcp_port_monitor_collection_t *p_collection, in_port_t port_range_begin,
in_port_t port_range_end) {
if (!p_collection) {
return NULL;
}
/* is monitor in hash? */
monitor_hash_t::iterator i = p_collection->hash.find(
port_range_t(port_range_begin, port_range_end) );
/* is monitor in hash? */
monitor_hash_t::iterator i =
p_collection->hash.find(port_range_t(port_range_begin, port_range_end));
return i == p_collection->hash.end() ? NULL : &i->second;
return i == p_collection->hash.end() ? NULL : &i->second;
}

View File

@@ -1,5 +1,4 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* libtcp-portmon.h: tcp port monitoring library.
*
@@ -23,8 +22,8 @@
#ifndef LIBTCP_PORTMON_H
#define LIBTCP_PORTMON_H
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
@@ -47,15 +46,15 @@
/* The inventory of peekable items within the port monitor. */
enum tcp_port_monitor_peekables {
COUNT = 0,
REMOTEIP,
REMOTEHOST,
REMOTEPORT,
REMOTESERVICE,
LOCALIP,
LOCALHOST,
LOCALPORT,
LOCALSERVICE
COUNT = 0,
REMOTEIP,
REMOTEHOST,
REMOTEPORT,
REMOTESERVICE,
LOCALIP,
LOCALHOST,
LOCALPORT,
LOCALSERVICE
};
/* ------------------------------------------------------------
@@ -82,8 +81,8 @@ typedef struct _tcp_port_monitor_collection_t tcp_port_monitor_collection_t;
/* struct to hold monitor creation arguments */
typedef struct _tcp_port_monitor_args_t {
/* monitor supports tracking at most this many connections */
int max_port_monitor_connections;
/* monitor supports tracking at most this many connections */
int max_port_monitor_connections;
} tcp_port_monitor_args_t;
/* ----------------------------------
@@ -94,15 +93,16 @@ typedef struct _tcp_port_monitor_args_t {
* the indicated port monitor.
* The requested monitor value is copied into a client-supplied char buffer.
* Returns 0 on success, -1 otherwise. */
int peek_tcp_port_monitor(const tcp_port_monitor_t *p_monitor,
/* (item of interest, from tcp_port_monitor_peekables enum) */
int item,
/* (0 to number of connections in monitor - 1) */
int connection_index,
/* buffer to receive requested value */
char *p_buffer,
/* size of p_buffer */
size_t buffer_size);
int peek_tcp_port_monitor(
const tcp_port_monitor_t *p_monitor,
/* (item of interest, from tcp_port_monitor_peekables enum) */
int item,
/* (0 to number of connections in monitor - 1) */
int connection_index,
/* buffer to receive requested value */
char *p_buffer,
/* size of p_buffer */
size_t buffer_size);
/* --------------------------------
* Client operations on collections
@@ -114,21 +114,21 @@ tcp_port_monitor_collection_t *create_tcp_port_monitor_collection(void);
/* Destroy the monitor collection (and everything it contains).
* Do this one last. */
void destroy_tcp_port_monitor_collection(
tcp_port_monitor_collection_t *p_collection);
tcp_port_monitor_collection_t *p_collection);
/* Updates the tcp statitics for all monitors within a collection */
void update_tcp_port_monitor_collection(
tcp_port_monitor_collection_t *p_collection);
tcp_port_monitor_collection_t *p_collection);
/* Creation of reduntant monitors is silently ignored
* Returns 0 on success, -1 otherwise. */
int insert_new_tcp_port_monitor_into_collection(
tcp_port_monitor_collection_t *p_collection, in_port_t port_range_begin,
in_port_t port_range_end, tcp_port_monitor_args_t *p_creation_args);
tcp_port_monitor_collection_t *p_collection, in_port_t port_range_begin,
in_port_t port_range_end, tcp_port_monitor_args_t *p_creation_args);
/* Clients need a way to find monitors */
tcp_port_monitor_t *find_tcp_port_monitor(
tcp_port_monitor_collection_t *p_collection,
in_port_t port_range_begin, in_port_t port_range_end);
tcp_port_monitor_collection_t *p_collection, in_port_t port_range_begin,
in_port_t port_range_end);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,10 @@
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
/*
*
* Conky, a system monitor, based on torsmo
*
* Please see COPYING for details
*
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
@@ -45,7 +44,7 @@ void get_powerbook_batt_info(struct text_object *, char *, int);
void parse_i2c_sensor(struct text_object *, const char *);
void parse_hwmon_sensor(struct text_object *, const char *);
void parse_platform_sensor(struct text_object *, const char *);
void print_sysfs_sensor(struct text_object *, char *, int );
void print_sysfs_sensor(struct text_object *, char *, int);
void free_sysfs_sensor(struct text_object *);
int get_entropy_avail(unsigned int *);

Some files were not shown because too many files have changed in this diff Show More