code cleanup and openrc script

master
Chris Cromer 2 years ago
parent fb70d11f2b
commit 6b771cfa98
Signed by: cromer
GPG Key ID: 39CC813FF3C8708A
  1. 1
      contrib/meson.build
  2. 19
      contrib/openrc/meson.build
  3. 4
      contrib/openrc/permission.sh
  4. 4
      contrib/openrc/tufmanager.in
  5. 6
      data/dbus/meson.build
  6. 30
      data/dbus/org.tuf.manager.server.conf
  7. 2
      data/dbus/org.tuf.manager.server.service.in
  8. 18
      data/gschema/meson.build
  9. 94
      data/gschema/org.tuf.manager.gschema.xml
  10. 16
      data/meson.build
  11. 16
      data/polkit/meson.build
  12. 26
      data/polkit/org.tuf.manager.policy.in
  13. 78
      docs/meson.build
  14. 32
      meson.build
  15. 46
      meson_options.txt
  16. 12
      po/meson.build
  17. 2
      script/meson.build
  18. 884
      src/cli.vala
  19. 296
      src/common.vala
  20. 68
      src/config.vala.in
  21. 50
      src/error.vala
  22. 478
      src/gui-window.vala
  23. 74
      src/gui.vala
  24. 40
      src/main.vala.in
  25. 168
      src/meson.build
  26. 123
      src/server-interface.vala
  27. 151
      src/server-main.vala
  28. 1103
      src/server.vala

@ -0,0 +1 @@
subdir('openrc')

@ -0,0 +1,19 @@
openrc_config_data = configuration_data()
openrc_config_data.set('SBINDIR', join_paths(get_option('prefix'), get_option('sbindir')))
openrc_config_data.set('LIBEXECDIR', join_paths(get_option('prefix'), get_option('libexecdir'), meson.project_name()))
openrc_config_data_file = configure_file(
input: 'tufmanager.in',
output: 'tufmanager',
configuration: openrc_config_data
)
if openrc
install_data(
openrc_config_data_file,
install_dir: join_paths(get_option('sysconfdir'), 'init.d')
)
permissions = find_program('chmod')
meson.add_install_script('permission.sh', join_paths(get_option('sysconfdir'), 'init.d'))
endif

@ -0,0 +1,4 @@
#!/bin/sh -eu
echo "Make OpenRC script executable..."
chmod 755 "${DESTDIR}${1}/tufmanager"

@ -11,11 +11,11 @@
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
command=@PKG_PREFIX@/libexec/tuf-manager/tuf-server
command=@LIBEXECDIR@/tuf-server
pidfile=/var/run/tufmanager/tufmanager.pid
name="TUF Manager daemon"
depend()
{
need dbus
need dbus
}

@ -1,10 +1,10 @@
dbus_config_data = configuration_data()
dbus_config_data.set('LIBEXEC_DIR', join_paths(get_option('prefix'), get_option('libexecdir'), meson.project_name()))
dbus_config_data.set('LIBEXECDIR', join_paths(get_option('prefix'), get_option('libexecdir'), meson.project_name()))
dbus_config_data_file = configure_file(
input: 'org.tuf.manager.server.service.in',
output: 'org.tuf.manager.server.service',
configuration: dbus_config_data
output: 'org.tuf.manager.server.service',
configuration: dbus_config_data
)
install_data(

@ -2,22 +2,22 @@
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Only root can own the service -->
<policy user="root">
<allow own="org.tuf.manager.server"/>
</policy>
<!-- Only root can own the service -->
<policy user="root">
<allow own="org.tuf.manager.server"/>
</policy>
<!-- Allow anyone to invoke methods on the interfaces -->
<policy context="default">
<allow send_destination="org.tuf.manager.server"
send_interface="org.tuf.manager.server"/>
<!-- Allow anyone to invoke methods on the interfaces -->
<policy context="default">
<allow send_destination="org.tuf.manager.server"
send_interface="org.tuf.manager.server"/>
<allow send_destination="org.tuf.manager.server"
send_interface="org.freedesktop.DBus.Introspectable"/>
<allow send_destination="org.tuf.manager.server"
send_interface="org.freedesktop.DBus.Peer"/>
<allow send_destination="org.tuf.manager.server"
send_interface="org.freedesktop.DBus.Properties"/>
</policy>
<allow send_destination="org.tuf.manager.server"
send_interface="org.freedesktop.DBus.Introspectable"/>
<allow send_destination="org.tuf.manager.server"
send_interface="org.freedesktop.DBus.Peer"/>
<allow send_destination="org.tuf.manager.server"
send_interface="org.freedesktop.DBus.Properties"/>
</policy>
</busconfig>

@ -1,4 +1,4 @@
[D-BUS Service]
Name=org.tuf.manager.server
Exec=@LIBEXEC_DIR@/tuf-server
Exec=@LIBEXECDIR@/tuf-server
User=root

@ -1,12 +1,12 @@
# server doesn't need gschema, only gui or cli
if build_gui or build_cli
gnome = import('gnome')
gschemas = files(
'org.tuf.manager.gschema.xml'
)
gnome.compile_schemas(
build_by_default: true,
depend_files: gschemas
)
install_data('org.tuf.manager.gschema.xml', install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'glib-2.0', 'schemas'))
gnome = import('gnome')
gschemas = files(
'org.tuf.manager.gschema.xml'
)
gnome.compile_schemas(
build_by_default: true,
depend_files: gschemas
)
install_data('org.tuf.manager.gschema.xml', install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'glib-2.0', 'schemas'))
endif

@ -1,49 +1,49 @@
<schemalist>
<schema id="org.tuf.manager" path="/org/tuf/manager/" gettext-domain="tuf-manager">
<key name="restore" type="b">
<default>false</default>
<summary>Should TUF Manager restore previous settings when run</summary>
<description>
Should TUF Manager restore previous settings when run
</description>
</key>
<key name="fan-mode" type="i">
<default>0</default>
<summary>Fan mode</summary>
<description>
The saved fan mode
0 is balanced
1 is turbo
2 is silent
</description>
</key>
<key name="keyboard-mode" type="i">
<default>0</default>
<summary>Keyboard mode</summary>
<description>
The saved keyboard mode
0 is static
1 is breathing
2 is color cycle
3 is strobing
</description>
</key>
<key name="keyboard-speed" type="i">
<default>0</default>
<summary>Keyboard speed</summary>
<description>
The saved keyboard speed
0 is slow
1 is medium
2 is fast
</description>
</key>
<key name="keyboard-color" type="s">
<default>"rgb(255,0,0)"</default>
<summary>Keyboard color</summary>
<description>
The saved keyboard color in rgb format
</description>
</key>
</schema>
<schema id="org.tuf.manager" path="/org/tuf/manager/" gettext-domain="tuf-manager">
<key name="restore" type="b">
<default>false</default>
<summary>Should TUF Manager restore previous settings when run</summary>
<description>
Should TUF Manager restore previous settings when run
</description>
</key>
<key name="fan-mode" type="i">
<default>0</default>
<summary>Fan mode</summary>
<description>
The saved fan mode
0 is balanced
1 is turbo
2 is silent
</description>
</key>
<key name="keyboard-mode" type="i">
<default>0</default>
<summary>Keyboard mode</summary>
<description>
The saved keyboard mode
0 is static
1 is breathing
2 is color cycle
3 is strobing
</description>
</key>
<key name="keyboard-speed" type="i">
<default>0</default>
<summary>Keyboard speed</summary>
<description>
The saved keyboard speed
0 is slow
1 is medium
2 is fast
</description>
</key>
<key name="keyboard-color" type="s">
<default>"rgb(255,0,0)"</default>
<summary>Keyboard color</summary>
<description>
The saved keyboard color in rgb format
</description>
</key>
</schema>
</schemalist>

@ -1,12 +1,12 @@
if build_gui
i18n.merge_file(
input: 'tuf-manager.desktop.in',
output: 'tuf-manager.desktop',
po_dir: join_paths(meson.source_root(), 'po'),
type: 'desktop',
install: true,
install_dir: join_paths(get_option('datadir'), 'applications')
)
i18n.merge_file(
input: 'tuf-manager.desktop.in',
output: 'tuf-manager.desktop',
po_dir: join_paths(meson.source_root(), 'po'),
type: 'desktop',
install: true,
install_dir: join_paths(get_option('datadir'), 'applications')
)
endif
subdir('dbus')

@ -1,10 +1,10 @@
if not always_authenticated
i18n.merge_file(
input: 'org.tuf.manager.policy.in',
output: 'org.tuf.manager.policy',
po_dir: join_paths(meson.source_root(), 'po'),
type: 'xml',
install: true,
install_dir: join_paths(get_option('datadir'), 'polkit-1', 'actions')
)
i18n.merge_file(
input: 'org.tuf.manager.policy.in',
output: 'org.tuf.manager.policy',
po_dir: join_paths(meson.source_root(), 'po'),
type: 'xml',
install: true,
install_dir: join_paths(get_option('datadir'), 'polkit-1', 'actions')
)
endif

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<policyconfig>
<vendor>TUF Manager</vendor>
<vendor_url>https://git.cromer.cl/cromer/tuf-manager/</vendor_url>
<icon_name>package-x-generic</icon_name>
<action id="org.tuf.manager.save">
<message>Authentication is required</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<vendor>TUF Manager</vendor>
<vendor_url>https://git.cromer.cl/cromer/tuf-manager/</vendor_url>
<icon_name>tuf-manager</icon_name>
<action id="org.tuf.manager.save">
<message>Authentication is required</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
</policyconfig>

@ -1,44 +1,44 @@
docs_enabled = get_option('valadocs')
if docs_enabled
valadoc = find_program('valadoc', required: docs_enabled)
vala_doc_sources = server_vala_sources
if build_cli
vala_doc_sources += cli_vala_sources
endif
if build_gui
vala_doc_sources += gui_vala_sources
endif
vala_doc_sources += error_vala_sources
vala_doc_sources += config_data_file
valadocs_deps = get_option('valadocs-deps')
docs_deps = [
'--pkg=polkit-gobject-1',
'--pkg=posix',
'--pkg=gtk+-3.0'
]
if valadocs_deps
docs_deps += ['--deps']
endif
custom_target(
'valadoc',
input: vala_doc_sources,
output: 'valadoc',
command: [ valadoc,
docs_deps,
'--doclet=html',
'--internal',
'--private',
'--force',
'--package-name=@0@'.format(meson.project_name()),
'--package-version=@0@'.format(meson.project_version()),
'--vapidir=@0@'.format(join_paths(meson.source_root(), 'vapi')),
'--directory=@OUTDIR@/valadoc',
vala_doc_sources
],
build_by_default: true,
install: true,
install_dir: join_paths(get_option('datadir'), 'doc', meson.project_name())
)
valadoc = find_program('valadoc', required: docs_enabled)
vala_doc_sources = server_vala_sources
if build_cli
vala_doc_sources += cli_vala_sources
endif
if build_gui
vala_doc_sources += gui_vala_sources
endif
vala_doc_sources += error_vala_sources
vala_doc_sources += config_data_file
valadocs_deps = get_option('valadocs-deps')
docs_deps = [
'--pkg=polkit-gobject-1',
'--pkg=posix',
'--pkg=gtk+-3.0'
]
if valadocs_deps
docs_deps += ['--deps']
endif
custom_target(
'valadoc',
input: vala_doc_sources,
output: 'valadoc',
command: [ valadoc,
docs_deps,
'--doclet=html',
'--internal',
'--private',
'--force',
'--package-name=@0@'.format(meson.project_name()),
'--package-version=@0@'.format(meson.project_version()),
'--vapidir=@0@'.format(join_paths(meson.source_root(), 'vapi')),
'--directory=@OUTDIR@/valadoc',
vala_doc_sources
],
build_by_default: true,
install: true,
install_dir: join_paths(get_option('datadir'), 'doc', meson.project_name())
)
endif
install_data('../LICENSE', install_dir: join_paths(get_option('datadir'), 'doc', meson.project_name()))

@ -1,29 +1,31 @@
project(
'tuf-manager',
[
'c',
'vala'
],
version: '0.1.0',
license: 'BSD-3',
default_options:
[
'b_ndebug=if-release',
'c_std=c18',
'warning_level=3'
]
'tuf-manager',
[
'c',
'vala'
],
version: '0.1.0',
license: 'BSD-3',
default_options:
[
'b_ndebug=if-release',
'c_std=c18',
'warning_level=3'
]
)
add_global_arguments(
'-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()),
language: 'c'
'-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()),
language: 'c'
)
always_authenticated = get_option('always-authenticated')
build_cli = get_option('build-cli')
build_gui = get_option('build-gui')
openrc = get_option('openrc')
subdir('po')
subdir('data')
subdir('src')
subdir('docs')
subdir('script')
subdir('contrib')

@ -1,30 +1,36 @@
option(
'valadocs',
type: 'boolean',
value: true,
description: 'Build valadocs'
'valadocs',
type: 'boolean',
value: true,
description: 'Build valadocs'
)
option(
'valadocs-deps',
type: 'boolean',
value: false,
description: 'Build the valadocs of the dependencies'
'valadocs-deps',
type: 'boolean',
value: false,
description: 'Build the valadocs of the dependencies'
)
option(
'build-cli',
type : 'boolean',
value: true,
description: 'Build the command line interface to TUF Manager'
'build-cli',
type : 'boolean',
value: true,
description: 'Build the command line interface to TUF Manager'
)
option(
'build-gui',
type : 'boolean',
value: true,
description: 'Build the graphical user interface to TUF Manager'
'build-gui',
type : 'boolean',
value: true,
description: 'Build the graphical user interface to TUF Manager'
)
option(
'always-authenticated',
type : 'boolean',
value: true,
description: 'User is always authenticated, so no password is necessary'
'always-authenticated',
type : 'boolean',
value: true,
description: 'User is always authenticated, so no password is necessary'
)
option(
'openrc',
type : 'boolean',
value: false,
description: 'Install OpenRC script'
)

@ -1,9 +1,9 @@
i18n = import('i18n')
i18n.gettext(
meson.project_name(),
args:
[
'--directory=' + meson.source_root(),
'--from-code=UTF-8'
]
meson.project_name(),
args:
[
'--directory=' + meson.source_root(),
'--from-code=UTF-8'
]
)

@ -1,5 +1,5 @@
# only gui or cli need gschema
if build_gui or build_cli
valadoc = find_program('glib-compile-schemas')
glib_compile_schemas = find_program('glib-compile-schemas')
meson.add_install_script('compile_schemas.sh')
endif

@ -16,406 +16,524 @@
* The TUF Manager namespace
*/
namespace TUFManager {
/**
* The CLI namespace handles all command line related usage
*/
namespace CLI {
public class TUFManagerApp : Application {
/**
* The CLI namespace handles all command line related usage
*/
namespace CLI {
/**
* This class contains the app that runs on the command line
*/
public class TUFManagerApp : Application {
#if ALWAYS_AUTHENTICATED
#else
/**
* The subprocess that will contain our tty polkit agent
*/
Subprocess? pkttyagent = null;
/**
* The subprocess that will contain our tty polkit agent
*/
Subprocess? pkttyagent = null;
#endif
private enum FanMode {
BALANCED,
TURBO,
SILENT
}
private enum KeyboardMode {
STATIC,
BREATHING,
COLOR_CYCLE,
STROBING
}
private enum KeyboardSpeed {
SLOW,
MEDIUM,
FAST
}
private bool invalid = false;
private bool help = false;
private bool info = false;
private bool version = false;
private bool fan = false;
private FanMode? fan_mode = null;
private bool lighting = false;
private KeyboardMode? keyboard_mode = null;
private bool speed = false;
private KeyboardSpeed? keyboard_speed = null;
private bool color = false;
private Gdk.RGBA? rgba = null;
public TUFManagerApp () {
Object (application_id: "cl.cromer.tuf.manager", flags: ApplicationFlags.HANDLES_COMMAND_LINE);
set_inactivity_timeout (1000);
}
public override void activate () {
this.hold ();
this.release ();
}
private int _command_line (ApplicationCommandLine command_line) {
try {
connect_dbus ();
}
catch (TUFError e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
string[] args = command_line.get_arguments ();
if (args.length == 1) {
help = true;
}
else if (args.length > 1) {
switch (args[1]) {
case "version":
version = true;
check_second_argument (args);
break;
case "help":
help = true;
check_second_argument (args);
break;
case "info":
info = true;
check_second_argument (args);
break;
case "fan":
fan = true;
break;
case "lighting":
lighting = true;
break;
case "speed":
speed = true;
break;
case "color":
color = true;
break;
default:
invalid = true;
break;
}
if (args.length > 2) {
if (fan) {
switch (args[2]) {
case "balanced":
fan_mode = FanMode.BALANCED;
break;
case "turbo":
fan_mode = FanMode.TURBO;
break;
case "silent":
fan_mode = FanMode.SILENT;
break;
default:
invalid = true;
break;
}
}
if (lighting) {
switch (args[2]) {
case "static":
keyboard_mode = KeyboardMode.STATIC;
break;
case "breath":
keyboard_mode = KeyboardMode.BREATHING;
break;
case "cycle":
keyboard_mode = KeyboardMode.COLOR_CYCLE;
break;
case "strobe":
keyboard_mode = KeyboardMode.STROBING;
break;
default:
invalid = true;
break;
}
}
if (speed) {
switch (args[2]) {
case "slow":
keyboard_speed = KeyboardSpeed.SLOW;
break;
case "medium":
keyboard_speed = KeyboardSpeed.MEDIUM;
break;
case "fast":
keyboard_speed = KeyboardSpeed.FAST;
break;
default:
invalid = true;
break;
}
}
if (color) {
try {
// Make sure it's a valid hex color
Regex regex = new Regex ("^#[0-9A-F]{6}$");
if (!regex.match (args[2].up ())) {
invalid = true;
}
}
catch (RegexError e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
finally {
rgba = Gdk.RGBA ();
rgba.parse (args[2]);
}
}
}
if (fan && fan_mode == null) {
invalid = true;
}
if (lighting && keyboard_mode == null) {
invalid = true;
}
if (speed && keyboard_speed == null) {
invalid = true;
}
if (color && rgba == null) {
invalid = true;
}
}
if (invalid) {
command_line.printerr (_ ("Invalid arguments!\n\n"));
print_usage (command_line);
release_cli ();
return 1;
}
else if (version) {
command_line.print (_ ("Version: ") + VERSION + "\n");
release_cli ();
return 0;
}
else if (help) {
print_usage (command_line);
release_cli ();
return 0;
}
else if (info) {
command_line.print (_ ("Client version: ") + VERSION + "\n");
command_line.print (_ ("Server version: ") + get_server_version () + "\n");
var current_setting = get_fan_mode ();
switch (current_setting) {
case 0:
command_line.print (_ ("Current fan mode: Balanced\n"));
break;
case 1:
command_line.print (_ ("Current fan mode: Turbo\n"));
break;
case 2:
command_line.print (_ ("Current fan mode: Silent\n"));
break;
default:
command_line.printerr (_ ("Error: Could not get current fan mode!\n"));
break;
}
current_setting = get_keyboard_mode ();
switch (current_setting) {
case 0:
command_line.print (_ ("Current keyboard lighting: Static\n"));
break;
case 1:
command_line.print (_ ("Current keyboard lighting: Breathing\n"));
break;
case 2:
command_line.print (_ ("Current keyboard lighting: Color Cycle\n"));
break;
case 3:
command_line.print (_ ("Current keyboard lighting: Strobing\n"));
break;
default:
command_line.printerr (_ ("Error: Could not get current keyboard mode!\n"));
break;
}
current_setting = get_keyboard_speed ();
switch (current_setting) {
case 0:
command_line.print (_ ("Current keyboard speed: Slow\n"));
break;
case 1:
command_line.print (_ ("Current keyboard speed: Medium\n"));
break;
case 2:
command_line.print (_ ("Current keyboard speed: Fast\n"));
break;
default:
command_line.printerr (_ ("Error: Could not get current fan mode!\n"));
break;
}
var current_color = get_keyboard_color ();
var color_hex = "#%02x%02x%02x".printf (
(uint) (Math.round (current_color.red * 255)),
(uint) (Math.round (current_color.green * 255)),
(uint) (Math.round (current_color.blue * 255))
).up ();
command_line.print (_ ("Current keyboard color: " + color_hex + "\n"));
release_cli ();
return 0;
}
else if (fan) {
/**
* The possible modes the fan can be in
*/
private enum FanMode {
/**
* This is the default fan mode
*/
BALANCED,
/**
* This mode makes the fans run at full power
*/
TURBO,
/**
* This mode trys to keep the fans as quiet as possible
*/
SILENT
}
/**
* The possible modes the keyboard lighting can be set to
*/
private enum KeyboardMode {
/**
* This mode makes the keyboard lights stay a constant color
*/
STATIC,
/**
* This mode makes the keyboard lights turn on and off at a variable speed
*/
BREATHING,
/**
* This mode makes the keyboard lights cycle through various colors at a variable speed
*/
COLOR_CYCLE,
/**
* This modes makes the keyboad lights strobe fast
*/
STROBING
}
/**
* The possible speeds that can bet set for the keyboard
*/
private enum KeyboardSpeed {
/**
* Slow speed
*/
SLOW,
/**
* Medium speed
*/
MEDIUM,
/**
* Fast speed
*/
FAST
}
/**
* This flag is set if the command line arguments are invalid
*/
private bool invalid = false;
/**
* This flag is set if the user wants to see help
*/
private bool help = false;
/**
* This flag is set if the user wants to see info
*/
private bool info = false;
/**
* This flag is set if the user wants to see the version
*/
private bool version = false;
/**
* This flag is set if the user wants to set the fan mode
*/
private bool fan = false;
/**
* This contains the mode the user want to set for the fan
*/
private FanMode? fan_mode = null;
/**
* This flag is set if the user wants to set the keyboard lighting mode
*/
private bool lighting = false;
/**
* This contains the mode the user want to set for the keyboard
*/
private KeyboardMode? keyboard_mode = null;
/**
* This flag is set if the user wants to change the speed of the lights on the keyboard
*/
private bool speed = false;
/**
* This contains the speed of the lights on the keyboard that the user wants to set
*/
private KeyboardSpeed? keyboard_speed = null;
/**
* This flag is set if the user wants to change the keyboard color
*/
private bool color = false;
/**
* This contains the color in rgba format to set
*/
private Gdk.RGBA? rgba = null;
/**
* Initializes the command line app and sets a timeout so that the process can finish before return is called
*/
public TUFManagerApp () {
Object (application_id: "cl.cromer.tuf.manager", flags: ApplicationFlags.HANDLES_COMMAND_LINE);
set_inactivity_timeout (1000);
}
/**
* This is called when the application gets activated
*/
public override void activate () {
this.hold ();
this.release ();
}
/**
* This is the logic that controls the command lines options used
*
* @param command_line The command line that is in use
* @return Returns 0 on success or an error code if failure
*/
private int _command_line (ApplicationCommandLine command_line) {
try {
connect_tuf_server ();
}
catch (TUFError e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
string[] args = command_line.get_arguments ();
if (args.length == 1) {
// If no arguments are passed show help
help = true;
}
else if (args.length > 1) {
// Find out what the first argument is
switch (args[1]) {
case "version":
version = true;
check_second_argument (args);
break;
case "help":
help = true;
check_second_argument (args);
break;
case "info":
info = true;
check_second_argument (args);
break;
case "fan":
fan = true;
break;
case "lighting":
lighting = true;
break;
case "speed":
speed = true;
break;
case "color":
color = true;
break;
default:
invalid = true;
break;
}
if (args.length > 2) {
// If the first argument requires a second argument, look for it here
if (fan) {
switch (args[2]) {
case "balanced":
fan_mode = FanMode.BALANCED;
break;
case "turbo":
fan_mode = FanMode.TURBO;
break;
case "silent":
fan_mode = FanMode.SILENT;
break;
default:
invalid = true;
break;
}
}
if (lighting) {
switch (args[2]) {
case "static":
keyboard_mode = KeyboardMode.STATIC;
break;
case "breath":
keyboard_mode = KeyboardMode.BREATHING;
break;
case "cycle":
keyboard_mode = KeyboardMode.COLOR_CYCLE;
break;
case "strobe":
keyboard_mode = KeyboardMode.STROBING;
break;
default:
invalid = true;
break;
}
}
if (speed) {
switch (args[2]) {
case "slow":
keyboard_speed = KeyboardSpeed.SLOW;
break;
case "medium":
keyboard_speed = KeyboardSpeed.MEDIUM;
break;
case "fast":
keyboard_speed = KeyboardSpeed.FAST;
break;
default:
invalid = true;
break;
}
}
if (color) {
try {
// Make sure it's a valid hex color
Regex regex = new Regex ("^#[0-9A-F]{6}$");
if (!regex.match (args[2].up ())) {
invalid = true;
}
}
catch (RegexError e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
finally {
rgba = Gdk.RGBA ();
rgba.parse (args[2]);
}
}
}
if (fan && fan_mode == null) {
invalid = true;
}
if (lighting && keyboard_mode == null) {
invalid = true;
}
if (speed && keyboard_speed == null) {
invalid = true;
}
if (color && rgba == null) {
invalid = true;
}
}
if (invalid) {
command_line.printerr (_ ("Invalid arguments!\n\n"));
print_usage (command_line);
release_cli ();
return 1;
}
else if (version) {
command_line.print (_ ("Version: ") + VERSION + "\n");
release_cli ();
return 0;
}
else if (help) {
print_usage (command_line);
release_cli ();
return 0;
}
else if (info) {
command_line.print (_ ("Client version: ") + VERSION + "\n");
command_line.print (_ ("Server version: ") + get_server_version () + "\n");
var current_setting = get_fan_mode ();
switch (current_setting) {
case 0:
command_line.print (_ ("Current fan mode: Balanced\n"));
break;
case 1:
command_line.print (_ ("Current fan mode: Turbo\n"));
break;
case 2:
command_line.print (_ ("Current fan mode: Silent\n"));
break;
default:
command_line.printerr (_ ("Error: Could not get current fan mode!\n"));
break;
}
current_setting = get_keyboard_mode ();
switch (current_setting) {
case 0:
command_line.print (_ ("Current keyboard lighting: Static\n"));
break;
case 1:
command_line.print (_ ("Current keyboard lighting: Breathing\n"));
break;
case 2:
command_line.print (_ ("Current keyboard lighting: Color Cycle\n"));
break;
case 3:
command_line.print (_ ("Current keyboard lighting: Strobing\n"));
break;
default:
command_line.printerr (_ ("Error: Could not get current keyboard mode!\n"));
break;
}
current_setting = get_keyboard_speed ();
switch (current_setting) {
case 0:
command_line.print (_ ("Current keyboard speed: Slow\n"));
break;
case 1:
command_line.print (_ ("Current keyboard speed: Medium\n"));
break;
case 2:
command_line.print (_ ("Current keyboard speed: Fast\n"));
break;
default:
command_line.printerr (_ ("Error: Could not get current fan mode!\n"));
break;
}
var current_color = get_keyboard_color ();
var color_hex = "#%02x%02x%02x".printf (
(uint) (Math.round (current_color.red * 255)),
(uint) (Math.round (current_color.green * 255)),
(uint) (Math.round (current_color.blue * 255))
).up ();
command_line.print (_ ("Current keyboard color: " + color_hex + "\n"));
release_cli ();
return 0;
}
else if (fan) {
#if ALWAYS_AUTHENTICATED
int mode = fan_mode;
tuf_server.procedure_finished.connect (release_cli);
set_fan_mode (mode);
int mode = fan_mode;
tuf_server.procedure_finished.connect (release_cli);
set_fan_mode (mode);
#else
try {
pkttyagent = new Subprocess.newv ({"pkttyagent"}, SubprocessFlags.NONE);
Timeout.add (200, () => {
int mode = fan_mode;
tuf_server.procedure_finished.connect (release_cli);
set_fan_mode (mode);
return false;
});
}
catch (Error e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
try {
pkttyagent = new Subprocess.newv ({"pkttyagent"}, SubprocessFlags.NONE);
Timeout.add (200, () => {
int mode = fan_mode;
tuf_server.procedure_finished.connect (release_cli);
set_fan_mode (mode);
return false;
});
}
catch (Error e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
#endif
return 0;
}
else if (lighting) {
return 0;
}
else if (lighting) {
#if ALWAYS_AUTHENTICATED
int mode = keyboard_mode;
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_mode (mode);
int mode = keyboard_mode;
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_mode (mode);
#else
try {
pkttyagent = new Subprocess.newv ({"pkttyagent"}, SubprocessFlags.NONE);
Timeout.add (200, () => {
int mode = keyboard_mode;
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_mode (mode);
return false;
});
}
catch (Error e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
try {
pkttyagent = new Subprocess.newv ({"pkttyagent"}, SubprocessFlags.NONE);
Timeout.add (200, () => {
int mode = keyboard_mode;
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_mode (mode);
return false;
});
}
catch (Error e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
#endif
return 0;
}
else if (speed) {
return 0;
}
else if (speed) {
#if ALWAYS_AUTHENTICATED
int set_speed = keyboard_speed;
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_speed (set_speed);
int set_speed = keyboard_speed;
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_speed (set_speed);
#else
try {
pkttyagent = new Subprocess.newv ({"pkttyagent"}, SubprocessFlags.NONE);
Timeout.add (200, () => {
int set_speed = keyboard_speed;
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_speed (set_speed);
return false;
});
}
catch (Error e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
#endif
return 0;
}
else if (color) {
try {
pkttyagent = new Subprocess.newv ({"pkttyagent"}, SubprocessFlags.NONE);
Timeout.add (200, () => {
int set_speed = keyboard_speed;
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_speed (set_speed);
return false;
});
}
catch (Error e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
#endif
return 0;
}
else if (color) {
#if ALWAYS_AUTHENTICATED
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_color (rgba);
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_color (rgba);
#else
try {
pkttyagent = new Subprocess.newv ({"pkttyagent"}, SubprocessFlags.NONE);
Timeout.add (200, () => {
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_color (rgba);
return false;
});
}
catch (Error e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
try {
pkttyagent = new Subprocess.newv ({"pkttyagent"}, SubprocessFlags.NONE);
Timeout.add (200, () => {
tuf_server.procedure_finished.connect (release_cli);
set_keyboard_color (rgba);
return false;
});
}
catch (Error e) {
command_line.printerr (_ ("Error: ") + e.message + "\n");
}
#endif
return 0;
}
return 0;
}
private void check_second_argument (string[] args) {
if (args.length > 2) {
invalid = true;
}
}
private void print_usage (ApplicationCommandLine command_line) {
command_line.print ("Usage: tuf-cli COMMAND [SUBCOMMAND] ...\n\n");
command_line.print (" version Print the version of tuf-cli\n");
command_line.print (" help Show this help screen\n");
command_line.print (" fan [balanced, turbo, silent] Set the fan mode\n");
command_line.print (" lighting [static, breath, cycle, stobe] Set the keyboard lighting\n");
command_line.print (" speed [slow, medium, fast] Set the keyboard lighting speed\n");
command_line.print (" color [\"#XXXXXX\"] Set the keyboard color\n");
command_line.print (" info Show the current config\n\n");
command_line.print ("Examples:\n");
command_line.print (" Silence fan: tuf-cli fan silent\n");
command_line.print (" Change RGB color: tuf-cli color \"#FF0000\"\n");
}
/**
* This method releases the command line program from it's loop
*/
public void release_cli () {
return 0;
}
return 0;
}
/**
* If there are more arguments than there should be we need to invalidate
* TODO: Change this to something better later
*
* @param args The arguments to check the length on
*/
private void check_second_argument (string[] args) {
if (args.length > 2) {
invalid = true;
}
}
/**
* Print the usage for the user if help is called or they do something invalid
*
* @param command_line The command line currently in use to print to
*/
private void print_usage (ApplicationCommandLine command_line) {
command_line.print ("Usage: tuf-cli COMMAND [SUBCOMMAND] ...\n\n");
command_line.print (" version Print the version of tuf-cli\n");
command_line.print (" help Show this help screen\n");
command_line.print (" fan [balanced, turbo, silent] Set the fan mode\n");
command_line.print (" lighting [static, breath, cycle, stobe] Set the keyboard lighting\n");
command_line.print (" speed [slow, medium, fast] Set the keyboard lighting speed\n");
command_line.print (" color [\"#XXXXXX\"] Set the keyboard color\n");
command_line.print (" info Show the current config\n\n");
command_line.print ("Examples:\n");
command_line.print (" Silence fan: tuf-cli fan silent\n");
command_line.print (" Change RGB color: tuf-cli color \"#FF0000\"\n");
}
/**
* This method releases the command line program from it's hold
* This will should be called when by a signal from the server to release the program
*/
public void release_cli () {
#if ALWAYS_AUTHENTICATED
#else
if (pkttyagent != null) {
pkttyagent.force_exit ();
}
if (pkttyagent != null) {
pkttyagent.force_exit ();
}
#endif
this.release ();
}
public override int command_line (ApplicationCommandLine command_line) {
// keep the application running until we are done with this commandline
this.hold ();
int res = _command_line (command_line);
return res;
}
}
}
this.release ();
}
/**
* The command line application starts here, we hold it in a loop until
* the serve responds and releases
*
* @param command_line The command line that is going to be used
* @return Returns the status code from our command line program
*/
public override int command_line (ApplicationCommandLine command_line) {
// keep the application running until we are done with this commandline
this.hold ();
int res = _command_line (command_line);
return res;
}
}
}
}

@ -16,133 +16,193 @@
* The TUF Manager namespace
*/
namespace TUFManager {
private TUFServerInterface tuf_server;
private BusName bus_name;
/**
* The TUF Server interface that is running in the background
*/
private TUFServerInterface tuf_server;
private void connect_dbus () throws TUFError {
bus_name = new BusName ("org.tuf.manager");
connect_tuf_server ();
if (get_server_version () != VERSION) {
throw new TUFError.UNMATCHED_VERSIONS ("The server and client versions do not match!");
}
}
/**
* The bus name to send to the server to identify itself
*/
private BusName bus_name;
private void connect_tuf_server () {
try {
tuf_server = Bus.get_proxy_sync (BusType.SYSTEM, "org.tuf.manager.server", "/org/tuf/manager/server");
}
catch (IOError e) {
stderr.printf ("Error: %s\n", e.message);
}
}
/**
* Connect to the TUF Server daemon via dbus
*
* @throws TUFError Thrown when the server and the client versions don't match
*/
private void connect_tuf_server () throws TUFError {
bus_name = new BusName ("org.tuf.manager");
private string? get_server_version () {
try {
return tuf_server.get_server_version ();
}
catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
return null;
}
try {
tuf_server = Bus.get_proxy_sync (BusType.SYSTEM, "org.tuf.manager.server", "/org/tuf/manager/server");
}
catch (IOError e) {
stderr.printf (_ ("Error: %s\n"), e.message);
}
private int get_fan_mode () {
try {
return tuf_server.get_fan_mode ();
}
catch (TUFError e) {
stderr.printf ("Error: %s\n", e.message);
}
catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
return -3;
}
string? server_version = get_server_version ();
if (server_version == null) {
return;
}
private void set_fan_mode (int mode) {
try {
tuf_server.set_fan_mode (mode, bus_name);
}
catch (TUFError e) {
stderr.printf ("Error: %s\n", e.message);
}
catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
}
if (server_version != VERSION) {
throw new TUFError.UNMATCHED_VERSIONS (_ ("The server and client versions do not match!"));
}
}
private Gdk.RGBA get_keyboard_color () {
try {