diff options
author | Evgeniy Alexeev <e.alekseev@k-soft-spb.ru> | 2022-10-06 11:27:10 +0300 |
---|---|---|
committer | Evgeniy Alexeev <e.alekseev@k-soft-spb.ru> | 2022-10-06 11:27:10 +0300 |
commit | 96569d5f9c7f245fd82545919a1910828c1058d9 (patch) | |
tree | 526a282ac190d2bb2b43719aeca97fde5eb4a114 | |
parent | ec32cc9ceb8d8f5cb1003360417e5d26f885b8a5 (diff) | |
download | sila-shell-96569d5f9c7f245fd82545919a1910828c1058d9.tar.xz |
Add sdbus, server power commands
-rw-r--r-- | meson.build | 7 | ||||
-rw-r--r-- | src/commands.c | 10 | ||||
-rw-r--r-- | src/commands.h | 4 | ||||
-rw-r--r-- | src/main.c | 42 | ||||
-rw-r--r-- | src/power_commands.c | 116 | ||||
-rw-r--r-- | src/power_commands.h | 8 | ||||
-rw-r--r-- | src/sd_bus.c | 118 | ||||
-rw-r--r-- | src/sd_bus.h | 19 | ||||
-rw-r--r-- | src/shell.c | 3 | ||||
-rw-r--r-- | src/utils.h | 24 |
10 files changed, 346 insertions, 5 deletions
diff --git a/meson.build b/meson.build index cdff7ab..7990c18 100644 --- a/meson.build +++ b/meson.build @@ -9,14 +9,17 @@ src = [ 'src/completion.c', 'src/utils.c', 'src/shell.c', - 'src/users.c' + 'src/users.c', + 'src/sd_bus.c', + 'src/power_commands.c' ] readline = dependency('readline') +libsystemd = dependency('libsystemd') executable('sila-shell', sources : src, include_directories: incdir, - dependencies : readline, + dependencies : [ readline, libsystemd ], install : true, install_dir : '/bin' ) diff --git a/src/commands.c b/src/commands.c index b52a5a1..59e7988 100644 --- a/src/commands.c +++ b/src/commands.c @@ -125,6 +125,16 @@ int com_users( char *arg ) return( 0 ); } +int com_server( char *arg ) +{ + if( !arg ) arg = ""; + + current = &server; + + initialize_readline(); + return( 0 ); +} + int com_top( char *arg ) { if( !arg ) arg = ""; diff --git a/src/commands.h b/src/commands.h index 2c16c74..a378aad 100644 --- a/src/commands.h +++ b/src/commands.h @@ -27,6 +27,8 @@ extern COMMAND_LIST top; extern COMMAND_LIST shell; extern COMMAND_LIST users; +extern COMMAND_LIST server; + extern COMMAND_LIST *current; extern void too_dangerous( char *caller ); @@ -39,7 +41,7 @@ extern int com_quit( char *arg ); extern int com_shell( char *arg ); extern int com_users( char *arg ); extern int com_top( char *arg ); - +extern int com_server( char *arg ); #ifdef __cplusplus } @@ -20,6 +20,8 @@ #include <shell.h> #include <users.h> +#include <power_commands.h> +#include <sd_bus.h> char *progname; /* The name of this program, as taken from argv[0]. */ int done; /* When non-zero, this global means the user is done using this program. */ @@ -31,15 +33,18 @@ static sigset_t blockmask; COMMAND top_admin_list[] = { { "help", com_help, "Display this text" }, { "?", com_help, "Synonym for `help'" }, + { "server", com_server, "Server commands" }, { "shell", com_shell, "Activate submenu shell" }, { "users", com_users, "Activate submenu users" }, { "quit", com_quit, "Quit using SILA Shell" }, + { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } }; COMMAND top_operator_list[] = { { "help", com_help, "Display this text" }, { "?", com_help, "Synonym for `help'" }, + { "server", com_server, "Server commands" }, { "shell", com_shell, "Activate submenu shell" }, { "users", com_users, "Activate submenu users" }, { "quit", com_quit, "Quit using SILA Shell" }, @@ -49,6 +54,7 @@ COMMAND top_operator_list[] = { COMMAND top_user_list[] = { { "help", com_help, "Display this text" }, { "?", com_help, "Synonym for `help'" }, + { "server", com_server, "Server commands" }, { "shell", com_shell, "Activate submenu shell" }, { "users", com_users, "Activate submenu users" }, { "quit", com_quit, "Quit using SILA Shell" }, @@ -73,6 +79,7 @@ COMMAND shell_admin_list[] = { { "more", com_more, "View the contents of FILE" }, { "vi", com_vi, "Edit the contents of text FILE" }, { "poweroff", com_poweroff, "Turn off the BMC power" }, + { "get_string", cmd_get_string, "GetProperty" }, { "..", com_top, "Return to top menu" }, { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } }; @@ -91,6 +98,7 @@ COMMAND shell_operator_list[] = { { "stat", com_stat, "Print out statistics on FILE" }, { "more", com_more, "View the contents of FILE" }, { "vi", com_vi, "Edit the contents of text FILE" }, + { "get_string", cmd_get_string, "GetProperty" }, { "..", com_top, "Return to top menu" }, { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } }; @@ -109,6 +117,7 @@ COMMAND shell_user_list[] = { { "stat", com_stat, "Print out statistics on FILE" }, { "more", com_more, "View the contents of FILE" }, { "vi", com_vi, "Edit the contents of text FILE" }, + { "get_string", cmd_get_string, "GetProperty" }, { "..", com_top, "Return to top menu" }, { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } }; @@ -151,6 +160,35 @@ COMMAND users_user_list[] = { COMMAND_LIST users; +COMMAND server_admin_list[] = { + { "help", com_help, "Display this text" }, + { "?", com_help, "Synonym for `help'" }, + { "power", com_power, "Return to top menu" }, + { "..", com_top, "Return to top menu" }, + { "quit", com_quit, "Quit using SILA Shell" }, + { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } +}; + +COMMAND server_operator_list[] = { + { "help", com_help, "Display this text" }, + { "?", com_help, "Synonym for `help'" }, + { "power", com_power, "Return to top menu" }, + { "..", com_top, "Return to top menu" }, + { "quit", com_quit, "Quit using SILA Shell" }, + { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } +}; + +COMMAND server_user_list[] = { + { "help", com_help, "Display this text" }, + { "?", com_help, "Synonym for `help'" }, + { "power", com_power, "Return to top menu" }, + { "..", com_top, "Return to top menu" }, + { "quit", com_quit, "Quit using SILA Shell" }, + { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } +}; + +COMMAND_LIST server = {"server", NULL}; + COMMAND_LIST *current; @@ -235,24 +273,28 @@ void cmd_lists_init( gid_t gid ) top.name = "top"; shell.name = "shell"; users.name = "users"; + server.name = "server"; if( privileges == ADMIN || gid == 0 ) { top.list = &top_admin_list[0]; shell.list = &shell_admin_list[0]; users.list = &users_admin_list[0]; + server.list = &server_admin_list[0]; } else if( privileges == OPERATOR ) { top.list = &top_operator_list[0]; shell.list = &shell_operator_list[0]; users.list = &users_operator_list[0]; + server.list = &server_operator_list[0]; } else { top.list = &top_user_list[0]; shell.list = &shell_user_list[0]; users.list = &users_user_list[0]; + server.list = &server_user_list[0]; } current = ⊤ diff --git a/src/power_commands.c b/src/power_commands.c new file mode 100644 index 0000000..aa6c27f --- /dev/null +++ b/src/power_commands.c @@ -0,0 +1,116 @@ +#include <string.h> + +#include<sd_bus.h> +#include "power_commands.h" +#include "errno.h" + +typedef struct +{ const char* first; + const char* second; +}string_pair_t; + +typedef struct +{ const char* first; + const char* second; + const char* third; + const char* fourth; +}string_quadruple_t; + +const string_quadruple_t chassis_dbus = { + "xyz.openbmc_project.State.Chassis", + "/xyz/openbmc_project/state/chassis0", + "xyz.openbmc_project.State.Chassis", + "RequestedPowerTransition"}; + +const string_quadruple_t host_dbus = { + "xyz.openbmc_project.State.Host", + "/xyz/openbmc_project/state/host0", + "xyz.openbmc_project.State.Host", + "RequestedPowerTransition"}; + +typedef enum +{ + POWER_UNKNOWN=-1, + POWER_ON_GRACEFUL=100, + POWER_ON_FORCE, + POWER_OFF_GRACEFUL, + POWER_OFF_FORCE, + POWER_RESET_GRACEFUL, + POWER_RESET_FORCE +}power_command_t; + +static power_command_t parse_power_command(const char* command) +{ + if(strcmp(command,"on-graceful")==0) + return POWER_ON_GRACEFUL; + if(strcmp(command,"on")==0) + return POWER_ON_GRACEFUL; + if(strcmp(command,"on-force")==0) + return POWER_ON_FORCE; + if(strcmp(command,"off-graceful")==0) + return POWER_OFF_GRACEFUL; + if(strcmp(command,"off")==0) + return POWER_OFF_GRACEFUL; + if(strcmp(command,"off-force")==0) + return POWER_OFF_FORCE; + if(strcmp(command,"reset-graceful")==0) + return POWER_RESET_GRACEFUL; + if(strcmp(command,"reset")==0) + return POWER_RESET_GRACEFUL; + if(strcmp(command,"reset-force")==0) + return POWER_RESET_FORCE; + return POWER_UNKNOWN; +} + +const string_quadruple_t* get_dbus_power_interface(power_command_t cmd) +{ + switch(cmd) + { + case POWER_OFF_FORCE: return &chassis_dbus;break; + + case POWER_ON_GRACEFUL: + case POWER_ON_FORCE: + case POWER_OFF_GRACEFUL: + case POWER_RESET_GRACEFUL: + case POWER_RESET_FORCE: + return &host_dbus;break; + default: return NULL; + } +} + +const char* get_dbus_power_property_value(power_command_t cmd) +{ + switch(cmd) + { + case POWER_ON_GRACEFUL: + case POWER_ON_FORCE: + return "xyz.openbmc_project.State.Host.Transition.On";break; + case POWER_OFF_GRACEFUL: + return "xyz.openbmc_project.State.Host.Transition.Off";break; + case POWER_OFF_FORCE: + return "xyz.openbmc_project.State.Chassis.Transition.Off";break; + case POWER_RESET_GRACEFUL: + return "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";break; + case POWER_RESET_FORCE: + return "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";break; + default: return NULL; + } +} + +int com_power( char *arg ) +{ + power_command_t cmd = parse_power_command(arg); + if(cmd==POWER_UNKNOWN) return -EOPNOTSUPP; + const string_quadruple_t* dbus_power_interface = get_dbus_power_interface(cmd); + if(!dbus_power_interface) + return -EOPNOTSUPP; + const char* property_val = get_dbus_power_property_value(cmd); + if(!property_val) + return -EOPNOTSUPP; + return dbus_set_property_string(dbus_power_interface->first, + dbus_power_interface->second, + dbus_power_interface->third, + dbus_power_interface->fourth, + property_val); + return 0; +} diff --git a/src/power_commands.h b/src/power_commands.h new file mode 100644 index 0000000..8bd6bf4 --- /dev/null +++ b/src/power_commands.h @@ -0,0 +1,8 @@ +#ifndef POWER_H +#define POWER_H + + + +int com_power( char *arg ); + +#endif // POWER_H diff --git a/src/sd_bus.c b/src/sd_bus.c new file mode 100644 index 0000000..3dc3eb0 --- /dev/null +++ b/src/sd_bus.c @@ -0,0 +1,118 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> + +#include <systemd/sd-bus.h> + +#include <utils.h> +#include <sd_bus.h> + + +int dbus_set_property_string(const char *destination, + const char *path, + const char *interface, + const char *member, const char* value) +{ + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_bus_unref_ sd_bus *bus = NULL; + + int r; + + /* Connect to the system bus */ + r = sd_bus_open_system(&bus); + if (r >= 0) + { + + r = sd_bus_set_property( + bus, + destination, + path, + interface, + member, + &error, + "s", + value); + + } + if (r < 0) + { + fprintf(stderr, "Failed to issue dbus call: %d %s\n", r, error.message); + } + + return (r>0?(0):(r)); +} + +const char* dbus_get_property_string(const char *destination, + const char *path, + const char *interface, + const char *member) +{ + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_bus_unref_ sd_bus *bus = NULL; + const char *state = NULL; + int r; + + /* Connect to the system bus */ + r = sd_bus_open_system(&bus); + if (r >= 0) + { + + r = sd_bus_get_property_string( + bus, + destination, + path, + interface, + member, + &error, + &state); + if (r >= 0) + { + printf("Result: %s\n", state); + } + /* Issue the method call and store the respons message in m */ + } + if (r < 0) + { + fprintf(stderr, "Failed to issue dbus call: %d %s\n", r, error.message); + } + + return (r>=0?(state):(NULL)); +} + +int cmd_get_string() +{ + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_bus_unref_ sd_bus *bus = NULL; + _cleanup_free_ char *state = NULL; + int r; + + /* Connect to the system bus */ + r = sd_bus_open_system(&bus); + if (r >= 0) + { + + r = sd_bus_get_property_string( + bus, + "org.bluez", + "/org/bluez/hci0", + "org.bluez.Adapter1", + "Alias", + &error, + &state); + if (r >= 0) + { + printf("Result: %s\n", state); + } + /* Issue the method call and store the respons message in m */ + } + if (r < 0) + { + fprintf(stderr, "Failed to issue dbus call: %d %s\n", r, error.message); + } + + return (r>0?(0):(r)); +} diff --git a/src/sd_bus.h b/src/sd_bus.h new file mode 100644 index 0000000..ff72b92 --- /dev/null +++ b/src/sd_bus.h @@ -0,0 +1,19 @@ +#ifndef __SD_BUS_COMMANDS_H +#define __SD_BUS_COMMANDS_H + +#ifdef __cplusplus +extern "C" { +#endif + +int cmd_get_string(); + +int dbus_set_property_string(const char *destination, + const char *path, + const char *interface, + const char *member, const char* value); + +#ifdef __cplusplus +} +#endif + +#endif //__SD_BUS_COMMANDS_H diff --git a/src/shell.c b/src/shell.c index af5d649..94ad78c 100644 --- a/src/shell.c +++ b/src/shell.c @@ -21,7 +21,6 @@ #include <shell.h> #include <users.h> - /* **************************************************************** */ /* */ /* SILA Shell Commands */ @@ -94,7 +93,7 @@ int com_stat( char *arg ) finfo.st_nlink, (finfo.st_nlink == 1) ? "" : "s", finfo.st_size, - (finfo.st_size == 1) ? "" : "s"); + (finfo.st_size == 1) ? "" : "s#include <systemd/sd-bus.h>"); printf( "Inode Last Change at: %s", ctime( &finfo.st_ctime ) ); printf( " Last access at: %s", ctime( &finfo.st_atime ) ); printf( " Last modified at: %s", ctime( &finfo.st_mtime ) ); diff --git a/src/utils.h b/src/utils.h index e56fe14..92ff61d 100644 --- a/src/utils.h +++ b/src/utils.h @@ -2,6 +2,8 @@ #ifndef __UTILS_H #define __UTILS_H +#include <stdint.h> +#include <stdlib.h> #ifdef __cplusplus extern "C" { @@ -15,6 +17,28 @@ extern void *xrealloc( void *, size_t ); extern char *dupstr( char *s ); +static inline void freep(void **p) +{ + if (*p) + free(*p); +} + +#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \ + static inline void func##p(type *p) \ + { \ + if (*p) \ + *p = func(*p); \ + } + +#define _cleanup_(_some_) __attribute__((__cleanup__(_some_))) +#define _cleanup_bus_unref_ _cleanup_(sd_bus_unrefp) +#define _cleanup_bus_close_unref_ _cleanup_(sd_bus_close_unrefp) +#define _cleanup_bus_slot_unref_ _cleanup_(sd_bus_slot_unrefp) +#define _cleanup_bus_message_unref_ _cleanup_(sd_bus_message_unrefp) +#define _cleanup_bus_creds_unref_ _cleanup_(sd_bus_creds_unrefp) +#define _cleanup_bus_track_unref_ _cleanup_(sd_bus_slot_unrefp) +#define _cleanup_bus_error_free_ _cleanup_(sd_bus_error_free) +#define _cleanup_free_ _cleanup_(freep) #ifdef __cplusplus } |