pax_global_header 0000666 0000000 0000000 00000000064 13557106175 0014524 g ustar 00root root 0000000 0000000 52 comment=ac0e878fd61d0054399755062d972105d43943a4
chkservice-0.3/ 0000775 0000000 0000000 00000000000 13557106175 0013514 5 ustar 00root root 0000000 0000000 chkservice-0.3/.gitignore 0000664 0000000 0000000 00000000424 13557106175 0015504 0 ustar 00root root 0000000 0000000 build
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
chkservice-0.3/.travis.yml 0000664 0000000 0000000 00000000636 13557106175 0015632 0 ustar 00root root 0000000 0000000 sudo: true
# After a few years
dist: xenial
language: c++
env:
- DEBUG=1
addons:
apt:
sources:
- deadsnakes
- ubuntu-toolchain-r-test
install:
- sudo apt-get update -qq
# - sudo do-release-upgrade -p -f DistUpgradeViewNonInteractive
- sudo apt-get --yes install systemd cmake catch libsystemd-dev libncurses5-dev g++ ssh
script:
- mkdir build; cd build; cmake ../; make; sudo make Test
chkservice-0.3/CMakeLists.txt 0000664 0000000 0000000 00000004053 13557106175 0016256 0 ustar 00root root 0000000 0000000 project(chkservice)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if ($ENV{DEBUG})
message(STATUS "DEBUG mode enabled")
set (CMAKE_CXX_FLAGS "-g -Wall")
else()
message(STATUS "DEBUG mode disabled")
set (CMAKE_CXX_FLAGS "-O2")
endif()
if ($ENV{TRAVIS})
message(STATUS "Travis-CI build.")
else()
message(STATUS "Local build")
endif()
include_directories("${PROJECT_SOURCE_DIR}/include")
find_package(PkgConfig REQUIRED)
pkg_check_modules(SYSTEMD libsystemd REQUIRED)
include_directories(${SYSTEMD_INCLUDE_DIRS})
set(LIBS ${LIBS} ${SYSTEMD_LIBRARIES})
pkg_check_modules(NCURSES ncurses REQUIRED)
include_directories(${NCURSES_INCLUDE_DIRS})
set(LIBS ${LIBS} ${NCURSES_LIBRARIES})
add_subdirectory(${PROJECT_SOURCE_DIR}/src)
if ($ENV{DEBUG})
message(STATUS "Build testing support")
add_subdirectory(${PROJECT_SOURCE_DIR}/tests)
endif()
SET(MAJOR_VERSION 0)
SET(MINOR_VERSION 3)
SET(PATCH_VERSION 0)
IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
INCLUDE(InstallRequiredSystemLibraries)
SET(CPACK_SET_DESTDIR "on")
SET(CPACK_PACKAGING_INSTALL_PREFIX "/tmp")
SET(CPACK_INSTALL_PREFIX "/usr")
SET(CPACK_GENERATOR "DEB;RPM")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Ncurses based gui for systemd")
SET(CPACK_PACKAGE_VENDOR "Svetlana Linuxenko")
SET(CPACK_PACKAGE_CONTACT "-")
SET(CPACK_PACKAGE_VERSION_MAJOR "${MAJOR_VERSION}")
SET(CPACK_PACKAGE_VERSION_MINOR "${MINOR_VERSION}")
SET(CPACK_PACKAGE_VERSION_PATCH "${PATCH_VERSION}")
SET(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}_${MAJOR_VERSION}.${MINOR_VERSION}.${CPACK_PACKAGE_VERSION_PATCH}")
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}_${MAJOR_VERSION}.${MINOR_VERSION}.${CPACK_PACKAGE_VERSION_PATCH}")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libncurses5 (>=5), libsystemd0 (>= 222)")
SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
SET(CPACK_DEBIAN_PACKAGE_SECTION "utils")
SET(CPACK_DEBIAN_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
SET(CPACK_COMPONENTS_ALL Libraries ApplicationData)
INCLUDE(CPack)
ENDIF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") chkservice-0.3/LICENSE 0000664 0000000 0000000 00000001405 13557106175 0014521 0 ustar 00root root 0000000 0000000 chkservice is a tool for managing systemd units.
more infomration at https://github.com/linuxenko/chkservice
Copyright (C) 2017 Svetlana Linuxenko
chkservice 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.
chkservice 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 .
chkservice-0.3/PKGBUILD 0000664 0000000 0000000 00000001324 13557106175 0014640 0 ustar 00root root 0000000 0000000 pkgname=chkservice
pkgver=0.3
pkgrel=1
pkgdesc="Ncurses based gui for systemd"
url="https://github.com/linuxenko/chkservice"
arch=('any')
license=('gpl')
depends=('ncurses'
'libsystemd'
)
optdepends=()
makedepends=('pkg-config'
'cmake')
_gitsrc="https://github.com/linuxenko/chkservice.git"
build() {
cd "${srcdir}"
git clone ${_gitsrc}
# start the build
mkdir "${srcdir}/${pkgname}/build" -p
cd "${srcdir}/${pkgname}/build"
msg "Starting cmake..."
cmake -DCMAKE_INSTALL_PREFIX=/usr ../
msg "Starting make..."
make
}
package() {
cd "${srcdir}/${pkgname}/build"
mkdir -p ${pkgdir}/usr/bin
install -Dm755 ${srcdir}/${pkgname}/build/src/chkservice ${pkgdir}/usr/bin
}
chkservice-0.3/README.md 0000664 0000000 0000000 00000003760 13557106175 0015001 0 ustar 00root root 0000000 0000000 ## chkservice
[](https://travis-ci.org/linuxenko/chkservice)
[](https://raw.githubusercontent.com/linuxenko/linuxenko.github.io/master/media/chkservice/chkservice.png)
> chkservice is a tool for managing systemd units in terminal.
[](https://repology.org/metapackage/chkservice)
### Installation
Debian >= 10
```
sudo apt install chkservice
```
Ubuntu
```
sudo add-apt-repository ppa:linuxenko/chkservice
sudo apt-get update
sudo apt-get install chkservice
```
Arch
```
git clone https://aur.archlinux.org/chkservice.git
cd chkservice
makepkg -si
```
Fedora
```
dnf copr enable srakitnican/default
dnf install chkservice
```
### Usage
`chkservice` require super user privileges to make changes into unit states or sysv scripts. For user it works read-only.
### Dependencies
Package dependencies:
* libncurses5
* libsystemd0 ( >= 222 )
Build dependencies:
* pkg-config
* libncurses5-dev
* libsystemd-dev ( >= 222 )
### Build
Build and install debian package.
```
git clone https://github.com/linuxenko/chkservice.git
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr ../
cpack
dpkg -i chkservice-x.x.x.deb
```
Build release version.
```
git clone https://github.com/linuxenko/chkservice.git
mkdir build
cd build
cmake ../
make
```
To build debug version, `DEBUG` environment should be set
```
export DEBUG=1
cmake ....
make Test
```
### Changelog
* v0.3 - Search using `/` key added
* v0.3 - Emacs key bindings implemented
* v0.2 - Integration with Travis was fixed
* v0.2 - Window resize supoport added by Gilles Talis
### License
GNU General Public License
chkservice is a tool for managing systemd units.
more infomration at https://github.com/linuxenko/chkservice
chkservice-0.3/debian/ 0000775 0000000 0000000 00000000000 13557106175 0014736 5 ustar 00root root 0000000 0000000 chkservice-0.3/debian/changelog 0000664 0000000 0000000 00000001243 13557106175 0016610 0 ustar 00root root 0000000 0000000 chkservice (0.1.0.2ppa0ubuntu3) xenial; urgency=medium
* Check of sysv status
-- Svetlana Linuxenko Thu, 14 Sep 2017 15:53:23 +0300
chkservice (0.1.0.2ppa0ubuntu2) xenial; urgency=medium
* Updated launchpad build dependencies
-- Svetlana Linuxenko Wed, 30 Aug 2017 14:38:21 +0300
chkservice (0.1.0.1ppa0ubuntu1) xenial; urgency=medium
* Reupload first try
-- Svetlana Linuxenko Wed, 30 Aug 2017 14:27:35 +0300
chkservice (0.1.0.0ppa0) sveta; urgency=medium
* Initial release. (Closes: #XXXXXX)
-- Svetlana Linuxenko Wed, 30 Aug 2017 13:36:50 +0300
chkservice-0.3/debian/chkservice.8 0000664 0000000 0000000 00000001426 13557106175 0017160 0 ustar 00root root 0000000 0000000 .\" Hey, EMACS: -*- nroff -*-
.\" (C) Copyright 2017 Ana Custura ,
.\"
.TH Chkservice 8 "October 11 2017"
.SH NAME
chkservice \- tool for managing systemd units in terminal
.SH SYNOPSIS
.B chkservice
.SH DESCRIPTION
This manual page documents briefly the
.B chkservice
utility
.PP
\fBchkservice\fP is a tool for managing systemd units from the terminal.
.SH OPTIONS
.TP
.B ?
Show summary of options.
.TP
.B space
Enable/disable service.
.TP
.B q
Exits chkservice
.TP
.B s
Start/stop unit
.TP
.B r
Reloads the service.
.TP
.B Up/k
Moves cursor up
.TP
.B Down/j
Moves cursor down
.TP
.B PgUp/b
Moves cursor down
.TP
.B PgDown/f
Moves page down
.TP
.SH COPYRIGHT
This manual was adapted for Debian by Ana Custura .
chkservice-0.3/debian/control 0000664 0000000 0000000 00000000515 13557106175 0016342 0 ustar 00root root 0000000 0000000 Source: chkservice
Section: devel
Priority: optional
Maintainer: Svetlana Linuxenko
Build-Depends: pkg-config, cmake, build-essential, libncurses5-dev, libsystemd-dev
Homepage: https://github.com/linuxenko/chkservice
Package: chkservice
Architecture: any
Depends: libncurses5, libsystemd0
Description: Ncurses based gui for systemd
chkservice-0.3/debian/copyright 0000664 0000000 0000000 00000001405 13557106175 0016671 0 ustar 00root root 0000000 0000000 chkservice is a tool for managing systemd units.
more infomration at https://github.com/linuxenko/chkservice
Copyright (C) 2017 Svetlana Linuxenko
chkservice 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.
chkservice 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 .
chkservice-0.3/debian/rules 0000775 0000000 0000000 00000001046 13557106175 0016017 0 ustar 00root root 0000000 0000000 #!/usr/bin/make -f
BUILDDIR = build_dir
# secondly called by launchpad
build:
mkdir $(BUILDDIR);
cd $(BUILDDIR); cmake -DCMAKE_INSTALL_PREFIX=../debian/tmp/usr ..
make -C $(BUILDDIR)
# thirdly called by launchpad
binary: binary-indep binary-arch
binary-indep:
# nothing to be done
binary-arch:
cd $(BUILDDIR); cmake -P cmake_install.cmake
mkdir debian/tmp/DEBIAN
dpkg-gencontrol -pchkservice
dpkg --build debian/tmp ..
# firstly called by launchpad
clean:
rm -f build
rm -rf $(BUILDDIR)
.PHONY: binary binary-arch binary-indep clean
chkservice-0.3/include/ 0000775 0000000 0000000 00000000000 13557106175 0015137 5 ustar 00root root 0000000 0000000 chkservice-0.3/include/chk-ctl.h 0000664 0000000 0000000 00000003464 13557106175 0016644 0 ustar 00root root 0000000 0000000 /*
* chkservice is a tool for managing systemd units.
* more infomration at https://github.com/linuxenko/chkservice
*
* Copyright (C) 2017 Svetlana Linuxenko
*
* chkservice 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.
*
* chkservice 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 .
*/
#ifndef _CHK_CTL_H
#define _CHK_CTL_H
#include "chk-systemd.h"
typedef struct UnitItem {
std::string id;
std::string target;
std::string description;
int sub;
int state;
} UnitItem;
enum {
UNIT_STATE_DISABLED = 0x01,
UNIT_STATE_ENABLED = 0x02,
UNIT_STATE_STATIC = 0x03,
UNIT_STATE_BAD = 0x04,
UNIT_STATE_MASKED = 0x05,
UNIT_STATE_TMP = 0x06
};
enum {
UNIT_SUBSTATE_RUNNING = 0x1a,
UNIT_SUBSTATE_CONNECTED = 0x2a,
UNIT_SUBSTATE_INVALID = 0x3a,
UNIT_SUBSTATE_TMP = 0x4a
};
class ChkCTL {
public:
ChkCTL();
~ChkCTL();
ChkBus *bus;
std::vector getItemsSorted();
std::vector getByTarget(const char *target);
std::vector getItems();
void toggleUnitState(UnitItem *item);
void toggleUnitSubState(UnitItem *item);
void fetch();
private:
std::vector items;
void pushItem(UnitInfo *unit);
void sortByName(std::vector *sortable);
};
#endif
chkservice-0.3/include/chk-systemd.h 0000664 0000000 0000000 00000004777 13557106175 0017562 0 ustar 00root root 0000000 0000000 /*
* chkservice is a tool for managing systemd units.
* more infomration at https://github.com/linuxenko/chkservice
*
* Copyright (C) 2017 Svetlana Linuxenko
*
* chkservice 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.
*
* chkservice 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 .
*/
#ifndef _CHK_SYSTEMD_H
#define _CHK_SYSTEMD_H
#include
#include
#include
#include
#define ERR_PREFIX "Failed: "
#define SYSV_INSTALL_EXEC "/lib/systemd/systemd-sysv-install"
enum STATE_FLAGS {
STATE_FLAGS_ENABLE,
STATE_FLAGS_DISABLE,
STATE_FLAGS_DISABLE_ISO
};
typedef struct UnitInfo {
const char *id;
const char *description;
const char *loadState;
const char *activeState;
const char *subState;
const char *unitPath;
const char *state;
} UnitInfo;
class ChkBus {
public:
ChkBus();
~ChkBus();
bool connect();
void disconnect();
bool isConnected();
void setErrorMessage(int status);
void setErrorMessage(const char *message);
std::vector getUnits();
std::vector getUnitFiles();
std::vector getAllUnits();
void disableUnit(const char *name);
void enableUnit(const char *name);
void disableUnits(std::set *ids);
void enableUnits(std::set *ids);
void startUnit(const char *name);
void stopUnit(const char *name);
void startUnits(std::set *ids);
void stopUnits(std::set *ids);
static void freeUnitInfo(UnitInfo *unit);
void reloadDaemon();
private:
sd_bus* bus = NULL;
std::string errorMessage;
const char* getState(const char *name);
void applyUnitState(const char *method, char **names, int flags);
void applyUnitSub(const char *name, const char *method);
void checkDisabledStatus(char **names);
};
int busParseUnit(sd_bus_message *message, UnitInfo *u);
void applySYSv(const char *state, const char **names);
#endif
chkservice-0.3/include/chk-ui.h 0000664 0000000 0000000 00000004674 13557106175 0016503 0 ustar 00root root 0000000 0000000 /*
* chkservice is a tool for managing systemd units.
* more infomration at https://github.com/linuxenko/chkservice
*
* Copyright (C) 2017 Svetlana Linuxenko
*
* chkservice 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.
*
* chkservice 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 .
*/
#ifndef _CHK_UI_H
#define _CHK_UI_H
#include
#include "chk-ctl.h"
enum _INPUT_FOR {
INPUT_FOR_LIST,
INPUT_FOR_SEARCH
};
/*
* Makros that helps get control key combinations work properly
*/
#ifndef CTRL
#define CTRL(c) ((c) & 037)
#endif
typedef struct RECTANGLE {
int x;
int y;
int w;
int h;
} RECTANGLE;
class MainWindow {
public:
WINDOW *win;
MainWindow();
~MainWindow();
void createMenu();
private:
RECTANGLE *screenSize = new RECTANGLE();
RECTANGLE *winSize = new RECTANGLE();
RECTANGLE *padding = new RECTANGLE();
ChkCTL *ctl = new ChkCTL;
std::vector units;
int selected = 0;
int start = 0;
int totalUnits();
unsigned char inputFor = 0;
void createWindow();
void resize();
void setSize();
void moveUp();
void moveDown();
void movePageUp();
void movePageDown();
void movePageEnd();
void moveTo(int position);
void drawUnits();
void drawItem(UnitItem *unit, int y);
void drawStatus(int position, const char *text, int color);
void drawInfo();
void toggleUnitState();
void toggleUnitSubState();
void updateUnits();
void error(char *err);
void reloadAll();
void listInput(int key);
/*
* Status bar
*/
char searchString[BUFSIZ] = "";
int lastFound = 0;
void drawSearch();
void searchInput(int key);
void searchNext();
};
void startCurses();
void stopCurses();
void printInMiddle(WINDOW *win, int starty, int startx, int width,
char *string, chtype color, char *sp);
void aboutWindow(RECTANGLE *parent);
#endif
chkservice-0.3/include/chk.h 0000664 0000000 0000000 00000002677 13557106175 0016071 0 ustar 00root root 0000000 0000000 /*
* chkservice is a tool for managing systemd units.
* more infomration at https://github.com/linuxenko/chkservice
*
* Copyright (C) 2017 Svetlana Linuxenko
*
* chkservice 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.
*
* chkservice 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 .
*/
#ifndef _CHK_H
#define _CHK_H
#define VERSION "0.3"
#define ABOUT_INFO "\n\
chkservice %s \n\
\n\
Units list information:\n\
\n\
[x] - enabled unit. [ ] - disabled unit \n\
[s] - static unit. -m- - masked unit \n\
\n\
Navigation keys:\n\
\n\
Up/k - move cursor up. Down/j - move cursor down.\n\
PgUp/b - move page up. PgDown/f - move page down.\n\
/ - for search.\n\
\n\
Action keys:\n\
\n\
r - reload/update. q - exit.\n\
Space - enable/disable. s - start/stop unit.\n\
\n\
License:\n\
GPLv3 (c) Svetlana Linuxenko"
#endif
chkservice-0.3/src/ 0000775 0000000 0000000 00000000000 13557106175 0014303 5 ustar 00root root 0000000 0000000 chkservice-0.3/src/CMakeLists.txt 0000664 0000000 0000000 00000000704 13557106175 0017044 0 ustar 00root root 0000000 0000000 add_library(CHKSYSTEMD chk-systemd.cpp chk-systemd-utils.cpp)
target_link_libraries(CHKSYSTEMD ${LIBS})
add_library(CHKCTL chk-ctl.cpp)
target_link_libraries(CHKCTL ${LIBS} CHKSYSTEMD)
add_library(CHKUI chk-wmain.cpp chk-wutils.cpp)
target_link_libraries(CHKUI ${LIBS} CHKSYSTEMD CHKCTL)
add_executable(chkservice chkservice.cpp)
target_link_libraries(chkservice ${LIBS} CHKSYSTEMD CHKCTL CHKUI)
install(TARGETS chkservice RUNTIME DESTINATION bin)
chkservice-0.3/src/chk-ctl.cpp 0000664 0000000 0000000 00000012510 13557106175 0016333 0 ustar 00root root 0000000 0000000 /*
* chkservice is a tool for managing systemd units.
* more infomration at https://github.com/linuxenko/chkservice
*
* Copyright (C) 2017 Svetlana Linuxenko
*
* chkservice 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.
*
* chkservice 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 .
*/
#include
#include "chk-ctl.h"
#include "chk-systemd.h"
ChkCTL::ChkCTL() {
bus = new ChkBus();
items.clear();
}
ChkCTL::~ChkCTL() {
delete bus;
items.clear();
}
std::vector ChkCTL::getItems() {
sortByName(&items);
return items;
}
std::vector ChkCTL::getByTarget(const char *target) {
std::vector found;
std::string pattern = target == NULL ? "" : target;
for (UnitItem *item : items) {
if (item->target.find(pattern) == 0) {
found.push_back(item);
}
}
return found;
}
void ChkCTL::fetch() {
std::vector sysUnits;
for (auto item : items) {
delete item;
}
items.clear();
items.shrink_to_fit();
try {
sysUnits = bus->getAllUnits();
} catch (std::string &err) {
throw err;
}
for (auto unit : sysUnits) {
if (unit->id) {
pushItem(unit);
}
delete unit;
}
sysUnits.clear();
sysUnits.shrink_to_fit();
}
void ChkCTL::sortByName(std::vector *sortable) {
std::sort(sortable->begin(), sortable->end(), [](const UnitItem *a, const UnitItem *b) {
const char* s1 = a->id.c_str();
const char* s2 = b->id.c_str();
while(true) {
if ( std::toupper(*s1) < std::toupper(*s2) ) return true;
if ( std::toupper(*s1) > std::toupper(*s2) ) return false;
if ( *s1 == 0 && *s2 == 0 ) return false;
if ( *s1 > *s2) return false;
if ( *s1 < *s2) return true;
++s1; ++s2;
}
});
}
void ChkCTL::pushItem(UnitInfo *unit) {
UnitItem *item = new UnitItem();
std::string id(unit->id);
item->id = id;
item->target = id.substr(id.find_last_of('.') + 1, id.length());
item->description = std::string((unit->description == NULL ?
unit->unitPath : unit->description));
if (unit->state != NULL) {
std::string state(unit->state);
std::string sub(unit->subState == NULL ? "" : unit->subState);
if (state.find("enabled") == 0) {
item->state = UNIT_STATE_ENABLED;
} else if (state.find("mask") == 0) {
item->state = UNIT_STATE_MASKED;
} else if (state.find("static") == 0) {
item->state = UNIT_STATE_STATIC;
} else if (state.find("bad") == 0 || state.find("removed") == 0) {
item->state = UNIT_STATE_BAD;
} else {
item->state = UNIT_STATE_DISABLED;
}
if (!sub.empty()) {
if (sub.find("running") == 0) {
item->sub = UNIT_SUBSTATE_RUNNING;
} else {
item->sub = UNIT_SUBSTATE_CONNECTED;
}
} else {
item->sub = UNIT_SUBSTATE_INVALID;
}
} else {
item->state = UNIT_STATE_MASKED;
}
bus->freeUnitInfo(unit);
items.push_back(item);
};
std::vector ChkCTL::getItemsSorted() {
std::vector orderedTargets;
std::vector sunits;
bool alreadyHasTarget = false;
orderedTargets.push_back("service");
orderedTargets.push_back("timer");
orderedTargets.push_back("socket");
for (const auto unit : items) {
alreadyHasTarget = false;
for (auto t : orderedTargets) {
if (t.find(unit->target) == 0) {
alreadyHasTarget = true;
break;
}
}
if (!alreadyHasTarget) {
orderedTargets.push_back(unit->target);
}
}
bool isFirst = false;
for (std::string target : orderedTargets) {
auto targetedUnits = getByTarget(target.c_str());
sortByName(&targetedUnits);
if (isFirst) {
UnitItem *separatorTitle = new UnitItem();
UnitItem *separator = new UnitItem();
separatorTitle->target = target;
sunits.push_back(separator);
sunits.push_back(separatorTitle);
sunits.push_back(separator);
}
sunits.insert(sunits.end(), targetedUnits.begin(), targetedUnits.end());
isFirst = true;
}
return sunits;
}
void ChkCTL::toggleUnitState(UnitItem *item) {
try {
if (item->state == UNIT_STATE_ENABLED || item->state == UNIT_STATE_STATIC) {
if (item->sub == UNIT_SUBSTATE_RUNNING || item->sub == UNIT_SUBSTATE_CONNECTED) {
bus->stopUnit(item->id.c_str());
}
bus->disableUnit(item->id.c_str());
} else if (item->state == UNIT_STATE_DISABLED) {
bus->enableUnit(item->id.c_str());
}
item->state = UNIT_STATE_TMP;
} catch (std::string &err) {
throw err;
}
}
void ChkCTL::toggleUnitSubState(UnitItem *item) {
try {
if (item->sub != UNIT_SUBSTATE_RUNNING) {
bus->startUnit(item->id.c_str());
} else {
bus->stopUnit(item->id.c_str());
}
item->sub = UNIT_SUBSTATE_TMP;
} catch (std::string &err) {
throw err;
}
}
chkservice-0.3/src/chk-systemd-utils.cpp 0000664 0000000 0000000 00000003464 13557106175 0020407 0 ustar 00root root 0000000 0000000 /*
* chkservice is a tool for managing systemd units.
* more infomration at https://github.com/linuxenko/chkservice
*
* Copyright (C) 2017 Svetlana Linuxenko
*
* chkservice 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.
*
* chkservice 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 .
*/
#include "chk-systemd.h"
#include
#include
#include
int busParseUnit(sd_bus_message *message, UnitInfo *u) {
assert(message);
assert(u);
return sd_bus_message_read(
message,
"(ssssssouso)",
&u->id,
&u->description,
&u->loadState,
&u->activeState,
&u->subState,
NULL,
&u->unitPath,
NULL,
NULL,
NULL);
}
void applySYSv(const char *state, const char **names) {
int pid = fork();
int status;
if (pid == 0) {
for (int i = 0; names[i] != NULL; i++) {
std::string unitName(names[i]);
std::string sysvCMD = SYSV_INSTALL_EXEC;
unitName = unitName.substr(0, unitName.find_last_of('.'));
sysvCMD += " ";
sysvCMD += state;
sysvCMD += " ";
sysvCMD += unitName;
sysvCMD += " > /dev/null 2>&1";
if ((status = system(sysvCMD.c_str())) == -1) {
break;
}
}
exit(status);
} else {
waitpid(pid, NULL, 0);
}
}
chkservice-0.3/src/chk-systemd.cpp 0000664 0000000 0000000 00000027671 13557106175 0017257 0 ustar 00root root 0000000 0000000 /*
* chkservice is a tool for managing systemd units.
* more infomration at https://github.com/linuxenko/chkservice
*
* Copyright (C) 2017 Svetlana Linuxenko
*
* chkservice 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.
*
* chkservice 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 .
*/
#include
#include
#include
#include "chk-systemd.h"
ChkBus::ChkBus() {
}
ChkBus::~ChkBus() {
disconnect();
}
bool ChkBus::connect() {
int status;
errorMessage.clear();
if (isConnected()) {
disconnect();
}
status = sd_bus_open_system(&bus);
if (status < 0) {
setErrorMessage(status);
disconnect();
throw std::string(errorMessage);
}
return isConnected();
}
void ChkBus::disconnect() {
if (bus != NULL) {
sd_bus_unref(bus);
bus = NULL;
}
}
bool ChkBus::isConnected() {
return bus == NULL ? false : true;
}
void ChkBus::setErrorMessage(int status) {
errorMessage = (char *)ERR_PREFIX;
if (status < 0) {
status = -status;
}
errorMessage += strerror(status);
}
void ChkBus::setErrorMessage(const char *message) {
errorMessage = (char *)ERR_PREFIX;
errorMessage += message;
}
const char *ChkBus::getState(const char *name) {
int status;
const char *state;
errorMessage.clear();
if (!isConnected()) {
connect();
}
sd_bus_message *busMessage = NULL;
sd_bus_error error = SD_BUS_ERROR_NULL;
status = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"GetUnitFileState",
&error,
&busMessage,
"s",
name);
if (status < 0) {
setErrorMessage(error.message);
goto finish;
}
status = sd_bus_message_read(busMessage, "s", &state);
if (status < 0) {
setErrorMessage(status);
goto finish;
}
finish:
sd_bus_error_free(&error);
sd_bus_message_unref(busMessage);
if (state < 0) {
throw std::string(errorMessage);
}
return status < 0 ? NULL : strdup(state);
}
std::vector ChkBus::getUnitFiles() {
int status;
const char *state;
char *path;
std::vector units;
sd_bus_message* busMessage = NULL;
sd_bus_message* reply = NULL;
sd_bus_error error = SD_BUS_ERROR_NULL;
errorMessage.clear();
if (!isConnected()) {
connect();
}
status = sd_bus_message_new_method_call(
bus,
&busMessage,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"ListUnitFiles");
if (status < 0) {
setErrorMessage(status);
goto finish;
}
status = sd_bus_call(bus, busMessage, 0, &error, &reply);
if (status < 0) {
setErrorMessage(error.message);
goto finish;
}
status = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
if (status < 0) {
setErrorMessage(status);
goto finish;
}
while ((status = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
UnitInfo *unit = new UnitInfo();
unit->unitPath = strdup(path);
unit->state = strdup(state);
std::string p = std::string(unit->unitPath);
unit->id = strdup(p.substr(p.find_last_of("/") + 1, p.length()).c_str());
units.push_back(unit);
path = NULL;
state = NULL;
}
status = sd_bus_message_exit_container(reply);
if (status < 0) {
setErrorMessage(status);
goto finish;
}
finish:
sd_bus_error_free(&error);
sd_bus_message_unref(busMessage);
sd_bus_message_unref(reply);
disconnect();
if (status < 0) {
throw std::string(errorMessage);
}
return units;
}
std::vector ChkBus::getUnits() {
int status;
UnitInfo unit;
std::vector units;
sd_bus_message* busMessage = NULL;
sd_bus_message* reply = NULL;
sd_bus_error error = SD_BUS_ERROR_NULL;
errorMessage.clear();
if (!isConnected()) {
connect();
}
status = sd_bus_message_new_method_call(
bus,
&busMessage,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"ListUnits"
);
if (status < 0) {
setErrorMessage(status);
goto finish;
}
status = sd_bus_call(bus, busMessage, 0, &error, &reply);
if (status < 0) {
setErrorMessage(error.message);
goto finish;
}
status = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
if (status < 0) {
setErrorMessage(status);
goto finish;
}
while ((status = busParseUnit(reply, &unit)) > 0) {
UnitInfo *u = new UnitInfo();
u->id = strdup(unit.id);
u->description = strdup(unit.description);
u->loadState = strdup(unit.loadState);
u->subState = strdup(unit.subState);
u->unitPath = strdup(unit.unitPath);
try {
u->state = getState(unit.id);
} catch (std::string &err) {
break;
}
units.push_back(u);
}
status = sd_bus_message_exit_container(reply);
if (status < 0) {
setErrorMessage(status);
goto finish;
}
finish:
sd_bus_error_free(&error);
sd_bus_message_unref(busMessage);
sd_bus_message_unref(reply);
disconnect();
if (status < 0) {
throw std::string(errorMessage);
}
return units;
}
void ChkBus::freeUnitInfo(UnitInfo *unit) {
free((void *)unit->id);
free((void *)unit->unitPath);
free((void *)unit->description);
free((void *)unit->loadState);
free((void *)unit->subState);
}
std::vector ChkBus::getAllUnits() {
std::vector files;
std::vector units;
try {
files = getUnitFiles();
units = getUnits();
} catch(std::string &err) {
throw err;
}
for (auto unit : units) {
int idx = 0;
bool found = false;
for (auto file : files) {
std::string uid(unit->id);
std::string fid(file->id);
if (uid.find(fid) == 0) {
freeUnitInfo(files[idx]);
files[idx]->id = unit->id;
files[idx]->unitPath = unit->unitPath;
files[idx]->description = unit->description;
files[idx]->loadState = unit->loadState;
files[idx]->subState = unit->subState;
found = true;
break;
}
idx++;
}
if (!found) {
files.push_back(unit);
} else {
delete unit;
}
}
units.clear();
units.shrink_to_fit();
return files;
}
void ChkBus::reloadDaemon() {
int status;
sd_bus_message* busMessage = NULL;
sd_bus_error error = SD_BUS_ERROR_NULL;
if (!isConnected()) {
connect();
}
status = sd_bus_message_new_method_call(
bus,
&busMessage,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"Reload"
);
if (status < 0) {
setErrorMessage(status);
goto finish;
}
sd_bus_call(bus, busMessage, 1000, &error, NULL);
finish:
sd_bus_error_free(&error);
sd_bus_message_unref(busMessage);
disconnect();
if (status < 0) {
throw std::string(errorMessage);
}
}
void ChkBus::applyUnitState(const char *method, char **names, int flags) {
int status;
bool checkState = false;
sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus_message *busMessage = NULL;
if (!isConnected()) {
connect();
}
status = sd_bus_message_new_method_call(
bus,
&busMessage,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
method);
if (status < 0) {
setErrorMessage(status);
goto finish;
}
status = sd_bus_message_append_strv(busMessage, names);
if (status < 0) {
setErrorMessage(status);
goto finish;
}
switch(flags) {
case STATE_FLAGS_ENABLE:
status = sd_bus_message_append(busMessage, "bb", true, true);
break;
case STATE_FLAGS_DISABLE:
status = sd_bus_message_append(busMessage, "b", true);
checkState = true;
break;
case STATE_FLAGS_DISABLE_ISO:
status = sd_bus_message_append(busMessage, "b", false);
checkState = true;
break;
default:
break;
}
if (status < 0) {
setErrorMessage(status);
goto finish;
}
status = sd_bus_call(bus, busMessage, 0, &error, NULL);
if (status < 0) {
setErrorMessage(error.message);
goto finish;
}
if (flags == STATE_FLAGS_ENABLE) {
applySYSv("enable", (const char **)names);
} else if (flags == STATE_FLAGS_DISABLE) {
applySYSv("disable", (const char **)names);
}
finish:
sd_bus_error_free(&error);
sd_bus_message_unref(busMessage);
disconnect();
if (status < 0) {
throw std::string(errorMessage);
}
if (checkState) {
checkDisabledStatus(names);
}
}
void ChkBus::checkDisabledStatus(char **names) {
try {
for (int i = 0; names[i] != NULL; i++) {
const char *name = names[i];
const char *state = getState(name);
if (std::string(state).find("enabled") == 0) {
applyUnitState("DisableUnitFiles", names, STATE_FLAGS_DISABLE_ISO);
applyUnitState("DisableUnitFiles", names, STATE_FLAGS_DISABLE);
}
if (state != NULL) {
free((void *)state);
}
}
} catch(std::string &err) {
throw err;
}
}
void ChkBus::applyUnitSub(const char *name, const char *method) {
int status;
sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus_message *busMessage = NULL;
sd_bus_message *reply = NULL;
if (!isConnected()) {
connect();
}
status = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
method,
&error,
&reply,
"ss",
name,
"replace-irreversibly");
if (status < 0) {
setErrorMessage(error.message);
goto finish;
}
finish:
sd_bus_error_free(&error);
sd_bus_message_unref(busMessage);
disconnect();
if (status < 0) {
throw std::string(errorMessage);
}
}
void ChkBus::enableUnits(std::set *ids) {
int i = 0;
if (ids->size() < 1) {
return;
}
char *names[ids->size()];
for (auto id : (*ids)) {
names[i] = (char *) id.c_str();
i++;
}
names[i] = NULL;
try {
applyUnitState("EnableUnitFiles", names, STATE_FLAGS_ENABLE);
} catch (std::string &err) {
throw err;
}
}
void ChkBus::disableUnits(std::set *ids) {
int i = 0;
if (ids->size() < 1) {
return;
}
char *names[ids->size()];
for (auto id : (*ids)) {
names[i] = (char *) id.c_str();
i++;
}
names[i] = NULL;
try {
applyUnitState("DisableUnitFiles", names, STATE_FLAGS_DISABLE);
} catch (std::string &err) {
throw err;
}
}
void ChkBus::enableUnit(const char *name) {
try {
std::set id;
id.insert(name);
enableUnits(&id);
} catch (std::string &err) {
throw err;
}
}
void ChkBus::disableUnit(const char *name) {
try {
std::set id;
id.insert(name);
disableUnits(&id);
} catch (std::string &err) {
throw err;
}
}
void ChkBus::stopUnits(std::set *ids) {
try {
for (auto id : (*ids)) {
applyUnitSub(id.c_str(), "StopUnit");
}
} catch (std::string &err) {
throw err;
}
}
void ChkBus::startUnits(std::set *ids) {
try {
for (auto id : (*ids)) {
applyUnitSub(id.c_str(), "StartUnit");
}
} catch (std::string &err) {
throw err;
}
}
void ChkBus::stopUnit(const char *name) {
try {
applyUnitSub(name, "StopUnit");
} catch (std::string &err) {
throw err;
}
}
void ChkBus::startUnit(const char *name) {
try {
applyUnitSub(name, "StartUnit");
} catch (std::string &err) {
throw err;
}
}
chkservice-0.3/src/chk-wmain.cpp 0000664 0000000 0000000 00000026655 13557106175 0016703 0 ustar 00root root 0000000 0000000 /*
* chkservice is a tool for managing systemd units.
* more infomration at https://github.com/linuxenko/chkservice
*
* Copyright (C) 2017 Svetlana Linuxenko
*
* chkservice 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.
*
* chkservice 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 .
*/
#include "chk.h"
#include "chk-ui.h"
#include "chk-systemd.h"
#include
#include
#include
#include
#include
MainWindow::MainWindow() {
setSize();
padding->x = 2;
padding->y = 2;
}
MainWindow::~MainWindow() {
delwin(win);
}
void MainWindow::resize() {
// Tear current window down
endwin();
wrefresh(stdscr);
clear();
delwin(win);
// Bring up a new one
setSize();
createWindow();
// This case handles resizing to smaller window
// We need to make sure that currently selected line
// will appear in newly created window.
// If selected line number is greater than newly created window height,
// we make this line the first line at the top of this new window.
if ((selected + 1 + padding->x) >= screenSize->h) {
start = start + selected;
selected = 0;
}
drawUnits();
}
void MainWindow::createWindow() {
win = newwin(screenSize->h, screenSize->w, 0, 0);
}
void MainWindow::createMenu() {
createWindow();
while(1) {
drawUnits();
int key = wgetch(stdscr);
error(NULL);
switch(inputFor) {
case INPUT_FOR_SEARCH:
searchInput(key);
break;
default:
listInput(key);
break;
}
}
}
void MainWindow::listInput(int key) {
switch(key) {
case '/':
inputFor = INPUT_FOR_SEARCH;
break;
case 'k':
case 'p':
case KEY_UP:
case CTRL('p'):
moveUp();
break;
case 'j':
case 'n':
case KEY_DOWN:
case CTRL('n'):
moveDown();
break;
case 'f':
case KEY_NPAGE:
case CTRL('f'):
movePageDown();
break;
case 'b':
case KEY_PPAGE:
case CTRL('b'):
movePageUp();
break;
case 'q':
stopCurses();
delwin(win);
exit(0);
break;
case ' ':
toggleUnitState();
break;
case 's':
toggleUnitSubState();
break;
case 'r':
updateUnits();
drawUnits();
error((char *)"Updated..");
break;
case 'G':
movePageEnd();
break;
case 'g':
start = 0;
selected = 0;
moveUp();
break;
case '?':
aboutWindow(screenSize);
break;
case KEY_RESIZE:
resize();
break;
default:
break;
}
}
void MainWindow::searchInput(int key) {
int slen;
switch(key) {
case 27: // ESC
memset(searchString, 0, BUFSIZ);
inputFor = INPUT_FOR_LIST;
break;
case KEY_ENTER: // Ctrl-M
case 10: // Enter
searchNext();
break;
case KEY_BACKSPACE:
slen = strlen(searchString);
if (slen > 0) {
searchString[slen - 1] = 0;
} else {
inputFor = INPUT_FOR_LIST;
}
break;
default:
/*
* A new search
*/
if (lastFound != 0) {
memset(searchString, 0, BUFSIZ);
lastFound = 0;
}
/*
* Using something that looks like a string for search
*/
if (key > 10 && key < 128) {
sprintf(searchString, "%s%c", searchString, key);
}
break;
}
}
void MainWindow::drawSearch() {
/*
* Lets indicate it is a search input
*/
char text[BUFSIZ] = "/";
if (lastFound == 0) {
sprintf(text, "%s%s", text, searchString);
}
/*
* Draw it using any visible, light color
*/
drawStatus(1, text, 0);
}
/*
* Looking for a next match
*/
void MainWindow::searchNext() {
int position = 0;
for (auto unit : units) {
if (unit->id.size() == 0) {
continue;
}
if (lastFound < position && unit->id.rfind(searchString) != std::string::npos) {
inputFor = INPUT_FOR_LIST;
lastFound = position;
moveTo(position);
return;
}
position++;
}
/*
* Nothing found
*/
inputFor = INPUT_FOR_LIST;
/*
* Nothing at all
*/
if (lastFound == 0) {
memset(searchString, 0, BUFSIZ);
return;
}
/*
* Repeat search
*/
lastFound = 0;
searchNext();
}
void MainWindow::setSize() {
getmaxyx(stdscr, screenSize->h, screenSize->w);
}
void MainWindow::moveTo(int position) {
start = selected = 0;
for (int i = 0; i < position; i++) {
moveDown();
}
}
void MainWindow::moveUp() {
int ps = winSize->h - (padding->y + 1);
if (start > 0 && selected < ps / 2) {
start--;
} else if (selected > 0) {
selected--;
}
if (units[start + selected]->id.size() == 0) {
moveUp();
}
}
void MainWindow::moveDown() {
int offset = start + selected;
int ps = winSize->h - (padding->y + 1);
int max = units.size() - 1;
if ((start + ps) < max) {
if (selected < ps / 2) {
selected++;
} else {
start++;
}
} else if (offset < max) {
selected++;
}
if (offset >= max) {
selected = ps;
}
if (units[start + selected]->id.size() == 0) {
moveDown();
}
}
void MainWindow::movePageUp() {
int ps = winSize->h - (padding->y + 1);
if (start > 0) {
start -= ps;
}
if (start < 0) {
start = 0;
selected = 0;
}
if (units[start + selected]->id.size() == 0) {
moveUp();
}
}
void MainWindow::movePageDown() {
int ps = winSize->h - 3;
int max = units.size() - 1;
if ((start + ps / 2) < max) {
start += ps;
}
if ((start + ps) > max) {
start = max - ps;
selected = ps;
}
if (units[start + selected]->id.size() == 0) {
moveDown();
}
}
void MainWindow::movePageEnd() {
int ps = winSize->h - 3;
int max = units.size() - 1;
start = max - ps;
selected = ps;
if (units[start + selected]->id.size() == 0) {
moveDown();
}
}
void MainWindow::reloadAll() {
try {
ctl->bus->reloadDaemon();
updateUnits();
} catch (std::string &err) {
error((char *)err.c_str());
}
}
void MainWindow::updateUnits() {
units.clear();
units.shrink_to_fit();
try {
ctl->fetch();
units = ctl->getItemsSorted();
} catch(std::string &err) {
error((char *)err.c_str());
}
}
void MainWindow::drawUnits() {
if (units.empty()) {
updateUnits();
}
getmaxyx(win, winSize->h, winSize->w);
winSize->h -= padding->y;
for (int i = 0; i < (winSize->h - padding->y); i++) {
if ((i + start) > (int)units.size() - 1) {
break;
}
UnitItem *unit = units[start + i];
if (i == selected) {
wattron(win, A_REVERSE);
}
drawItem(unit, i + padding->y);
wattroff(win, A_REVERSE);
}
if (inputFor == INPUT_FOR_LIST) {
drawInfo();
} else {
drawSearch();
}
refresh();
wrefresh(win);
}
void MainWindow::drawItem(UnitItem *unit, int y) {
if (unit->id.size() == 0) {
if (unit->target.size() == 0) {
printInMiddle(win, y, 0, winSize->w, (char *)"", COLOR_PAIR(3), (char *)' ');
} else {
std::string title(unit->target);
title += "s";
title[0] = std::toupper(title[0]);
printInMiddle(win, y, 0, winSize->w, (char *)"", COLOR_PAIR(3), (char *)' ');
printInMiddle(win, y, 0, winSize->w / 2, (char *)title.c_str(),
COLOR_PAIR(3), (char *)' ');
}
return;
}
if (unit->state == UNIT_STATE_ENABLED) {
wattron(win, COLOR_PAIR(2));
mvwprintw(win, y, padding->x, "[x]");
wattroff(win, COLOR_PAIR(2));
} else if (unit->state == UNIT_STATE_DISABLED) {
wattron(win, COLOR_PAIR(5));
mvwprintw(win, y, padding->x, "[ ]");
wattroff(win, COLOR_PAIR(5));
} else if (unit->state == UNIT_STATE_STATIC) {
wattron(win, COLOR_PAIR(5));
mvwprintw(win, y, padding->x, "[s]");
wattroff(win, COLOR_PAIR(5));
} else if (unit->state == UNIT_STATE_BAD) {
wattron(win, COLOR_PAIR(1));
mvwprintw(win, y, padding->x, "-b-");
wattroff(win, COLOR_PAIR(1));
} else if (unit->state == UNIT_STATE_MASKED) {
wattron(win, COLOR_PAIR(3));
mvwprintw(win, y, padding->x, "-m-");
wattroff(win, COLOR_PAIR(3));
}
if (unit->sub == UNIT_SUBSTATE_RUNNING) {
wattron(win, COLOR_PAIR(3));
mvwprintw(win, y, padding->x + 3, " > ");
wattroff(win, COLOR_PAIR(3));
} else if (unit->sub == UNIT_SUBSTATE_CONNECTED) {
wattron(win, COLOR_PAIR(5));
mvwprintw(win, y, padding->x + 3, " = ");
wattroff(win, COLOR_PAIR(5));
} else {
wattron(win, COLOR_PAIR(5));
mvwprintw(win, y, padding->x + 3, " ");
wattroff(win, COLOR_PAIR(5));
}
unsigned int leftPad = padding->x + 8;
unsigned int rightPad = (winSize->w - leftPad);
if (unit->id.size() > (rightPad - padding->x)) {
unit->id.resize(rightPad - padding->x);
}
std::stringstream sline;
unit->description.resize(winSize->w / 2, ' ');
sline << std::string(unit->id.size(), ' ') << " "
<< std::setw(rightPad - unit->id.size())
<< unit->description;
std::string cline(sline.str());
std::string name(unit->id);
name.resize(cline.find_first_of(unit->description[0]), ' ');
if (cline.size() > rightPad) {
cline.resize(rightPad - 2 );
}
wattron(win, COLOR_PAIR(4));
mvwprintw(win, y, leftPad, "%s", cline.c_str());
wattroff(win, COLOR_PAIR(4));
mvwprintw(win, y, leftPad, "%s", name.c_str());
}
/*
* Status line has a great potential for interaction with user.
* We can change it anytime just playing with arguments that could help with:
* - position the first character of the string
* - text itself, that can contain everything displayable
* - color it with any color we like
*/
void MainWindow::drawStatus(int position, const char *text, int color) {
char emptyStr[winSize->w + 1];
memset(&emptyStr, 0x20, winSize->w);
/*
* Clear it first
*/
mvwprintw(win, winSize->h + 1, 0, emptyStr);
/*
* Then draw
*/
wattron(win, COLOR_PAIR(color));
mvwprintw(win, winSize->h + 1, position, text);
wattroff(win, COLOR_PAIR(color));
}
void MainWindow::drawInfo() {
std::stringstream position;
int count = 0;
int countUntilNow = start + selected;
for (auto unit : units) {
if (unit->id.size() == 0) {
if (countUntilNow > count) {
countUntilNow--;
}
continue;
}
count++;
}
position << countUntilNow + 1 << "/" << count;
drawStatus((winSize->w / 2), (const char *)position.str().c_str(), 5);
}
int MainWindow::totalUnits() {
int count = 0;
for (auto unit : units) {
if (unit->id.size() == 0) {
continue;
}
count++;
}
return count;
}
void MainWindow::error(char *err) {
mvwprintw(win, 0, 0, std::string(winSize->w, ' ').c_str());
if (err) {
mvwprintw(win, 0, 1, err);
}
}
void MainWindow::toggleUnitState() {
try {
ctl->toggleUnitState(units[start + selected]);
reloadAll();
} catch (std::string &err) {
error((char *)err.c_str());
}
}
void MainWindow::toggleUnitSubState() {
try {
ctl->toggleUnitSubState(units[start + selected]);
reloadAll();
} catch (std::string &err) {
error((char *)err.c_str());
}
}
chkservice-0.3/src/chk-wutils.cpp 0000664 0000000 0000000 00000004341 13557106175 0017103 0 ustar 00root root 0000000 0000000 /*
* chkservice is a tool for managing systemd units.
* more infomration at https://github.com/linuxenko/chkservice
*
* Copyright (C) 2017 Svetlana Linuxenko
*
* chkservice 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.
*
* chkservice 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 .
*/
#include "chk-ui.h"
#include "chk.h"
void startCurses() {
initscr();
start_color();
noecho();
cbreak();
curs_set(false);
init_pair(1, COLOR_RED, COLOR_BLACK);
init_pair(2, COLOR_GREEN, COLOR_BLACK);
init_pair(3, COLOR_BLUE, COLOR_BLACK);
init_pair(4, COLOR_CYAN, COLOR_BLACK);
init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
keypad(stdscr, true);
}
void stopCurses() {
endwin();
}
void printInMiddle(WINDOW *win, int starty, int startx, int width,
char *string, chtype color, char *sp) {
int length, x, y;
float temp;
if(win == NULL)
win = stdscr;
getyx(win, y, x);
if(startx != 0)
x = startx;
if(starty != 0)
y = starty;
if(width == 0)
width = 80;
length = strlen(string);
temp = (width - length)/ 2;
x = startx + (int)temp;
wattron(win, color);
if (sp) {
for (int i = startx; i < width; i++) {
mvwprintw(win, y, i, "%c", sp);
}
}
mvwprintw(win, y, x, "%s", string);
wattroff(win, color);
}
void aboutWindow(RECTANGLE *parent) {
const int winH = 22;
const int winW = 60;
WINDOW *aboutwin = newwin(winH, winW,
(parent->h / 2) - (winH / 2),
(parent->w / 2) - (winW / 2)
);
wattron(aboutwin, COLOR_PAIR(2));
mvwprintw(aboutwin, 0, 0, ABOUT_INFO, VERSION);
wattroff(aboutwin, COLOR_PAIR(2));
refresh();
wrefresh(aboutwin);
getch();
delwin(aboutwin);
clear();
refresh();
}
chkservice-0.3/src/chkservice.cpp 0000664 0000000 0000000 00000002335 13557106175 0017140 0 ustar 00root root 0000000 0000000 /*
* chkservice is a tool for managing systemd units.
* more infomration at https://github.com/linuxenko/chkservice
*
* Copyright (C) 2017 Svetlana Linuxenko
*
* chkservice 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.
*
* chkservice 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 .
*/
#include
#include "chk-systemd.h"
#include "chk-ctl.h"
#include "chk-ui.h"
#include "chk.h"
using namespace std;
int main(int ac, char **av) {
if (ac > 1) {
fprintf(stdout, ABOUT_INFO, VERSION);
return 0;
}
startCurses();
MainWindow *mainWindow = new MainWindow();
mainWindow->createMenu();
delete mainWindow;
stopCurses();
return 0;
}
chkservice-0.3/tests/ 0000775 0000000 0000000 00000000000 13557106175 0014656 5 ustar 00root root 0000000 0000000 chkservice-0.3/tests/CMakeLists.txt 0000664 0000000 0000000 00000000313 13557106175 0017413 0 ustar 00root root 0000000 0000000 add_executable(RunTests main-test.cpp chksystemd-test.cpp chkctl-test.cpp chkui-test.cpp)
target_link_libraries(RunTests ${LIBS} CHKSYSTEMD CHKCTL CHKUI)
add_custom_target(Test COMMAND sudo ./RunTests)
chkservice-0.3/tests/chkctl-test.cpp 0000664 0000000 0000000 00000003347 13557106175 0017616 0 ustar 00root root 0000000 0000000 #include
#include
#include "chk-ctl.h"
using namespace std;
TEST_CASE("should create object ctl", "[ChkCTL]") {
ChkCTL *ctl = new ChkCTL();
REQUIRE(ctl != NULL);
delete ctl;
}
TEST_CASE("should return sorted items", "[ChkCTL]") {
ChkCTL *ctl = new ChkCTL();
REQUIRE_NOTHROW(ctl->fetch());
auto units = ctl->getItems();
REQUIRE(tolower(units[0]->id[0]) < tolower(units[units.size() - 1]->id[0]));
units = ctl->getByTarget("service");
REQUIRE(tolower(units[0]->id[0]) < tolower(units[units.size() - 1]->id[0]));
delete ctl;
}
TEST_CASE("should get system units against saved items ", "[ChkCTL]") {
ChkCTL *ctl = new ChkCTL();
ctl->fetch();
auto items = ctl->getItemsSorted();
REQUIRE(items.size() > 0);
delete ctl;
}
TEST_CASE("should fetch units and prepare", "[ChkCTL]") {
ChkCTL *ctl = new ChkCTL();
ctl->fetch();
bool filtered = true;
for (auto unit : ctl->getByTarget("service")) {
if (unit->target.find("service") != 0) {
filtered = false;
}
}
for (auto unit : ctl->getByTarget("device")) {
if (unit->target.find("device") != 0) {
filtered = false;
}
}
REQUIRE(filtered == true);
delete ctl;
}
TEST_CASE("should fetch items sorted by target", "[ChkCTL]") {
ChkCTL *ctl = new ChkCTL();
ctl->fetch();
vector units = ctl->getItemsSorted();
string lastTarget;
int targetChanged = 0;
std::set targets;
for (const auto unit : units) {
targets.insert((*unit).target);
}
for (auto unit : units) {
if (unit->id.size() != 0 && unit->target.compare(lastTarget) != 0) {
lastTarget = unit->target;
targetChanged++;
}
}
REQUIRE(targetChanged == (targets.size() - 1));
delete ctl;
}
chkservice-0.3/tests/chksystemd-test.cpp 0000664 0000000 0000000 00000005762 13557106175 0020527 0 ustar 00root root 0000000 0000000 #include
#include
#include