summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Alexeev <e.alekseev@k-soft-spb.ru>2022-10-06 11:27:10 +0300
committerEvgeniy Alexeev <e.alekseev@k-soft-spb.ru>2022-10-06 11:27:10 +0300
commit96569d5f9c7f245fd82545919a1910828c1058d9 (patch)
tree526a282ac190d2bb2b43719aeca97fde5eb4a114
parentec32cc9ceb8d8f5cb1003360417e5d26f885b8a5 (diff)
downloadsila-shell-96569d5f9c7f245fd82545919a1910828c1058d9.tar.xz
Add sdbus, server power commands
-rw-r--r--meson.build7
-rw-r--r--src/commands.c10
-rw-r--r--src/commands.h4
-rw-r--r--src/main.c42
-rw-r--r--src/power_commands.c116
-rw-r--r--src/power_commands.h8
-rw-r--r--src/sd_bus.c118
-rw-r--r--src/sd_bus.h19
-rw-r--r--src/shell.c3
-rw-r--r--src/utils.h24
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
}
diff --git a/src/main.c b/src/main.c
index e186215..3bf2e5a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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 = &top;
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
}