forked from eclipse-bluechi/bluechi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add list-unit-files command to bluechictl
Fixes: eclipse-bluechi#889 Signed-off-by: tallison <[email protected]>
- Loading branch information
tallison
committed
Jul 23, 2024
1 parent
959bd81
commit 5cc576a
Showing
8 changed files
with
356 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
/* | ||
* Copyright Contributors to the Eclipse BlueChi project | ||
* | ||
* SPDX-License-Identifier: LGPL-2.1-or-later | ||
*/ | ||
#include <stdarg.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#include "client.h" | ||
#include "method-list-unit-files.h" | ||
|
||
#include "libbluechi/common/math-util.h" | ||
#include "libbluechi/common/opt.h" | ||
#include "libbluechi/common/string-util.h" | ||
|
||
typedef void (*print_unit_file_list_fn)(UnitFileList *unit_file_list, const char *glob_filter); | ||
|
||
struct UnitFileList { | ||
int ref_count; | ||
|
||
LIST_FIELDS(UnitFileList, node_units); | ||
|
||
LIST_HEAD(UnitFileInfo, unit_files); | ||
}; | ||
|
||
UnitFileList *new_unit_file_list(); | ||
void unit_file_list_unref(UnitFileList *unit_file_list); | ||
|
||
DEFINE_CLEANUP_FUNC(UnitFileList, unit_file_list_unref) | ||
#define _cleanup_unit_file_list_ _cleanup_(unit_file_list_unrefp) | ||
|
||
static int fetch_unit_file_list(sd_bus *api_bus, | ||
const char *node_name, | ||
const char *object_path, | ||
const char *interface, | ||
const char *typestring, | ||
int (*parse_unit_file_info)(sd_bus_message *, UnitFileInfo *), | ||
UnitFileList *unit_file_list) { | ||
int r = 0; | ||
_cleanup_sd_bus_error_ sd_bus_error error = SD_BUS_ERROR_NULL; | ||
_cleanup_sd_bus_message_ sd_bus_message *message = NULL; | ||
|
||
r = sd_bus_call_method( | ||
api_bus, | ||
BC_INTERFACE_BASE_NAME, | ||
object_path, interface, | ||
"ListUnitFiles", | ||
&error, | ||
&message, | ||
""); | ||
if (r < 0) { | ||
fprintf(stderr, "Failed to issue method call: %s\n", error.message); | ||
return r; | ||
} | ||
|
||
r = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, typestring); | ||
if (r < 0) { | ||
fprintf(stderr, "Failed to read sd-bus message: %s\n", strerror(-r)); | ||
return r; | ||
} | ||
|
||
for (;;) { | ||
_cleanup_unit_file_ UnitFileInfo *info = new_unit_file(); | ||
|
||
r = (*parse_unit_file_info)(message, info); | ||
if (r < 0) { | ||
fprintf(stderr, "Failed to parse unit file info: %s\n", strerror(-r)); | ||
return r; | ||
} | ||
if (r == 0) { | ||
break; | ||
} | ||
if (node_name != NULL) { | ||
info->node = strdup(node_name); | ||
} | ||
|
||
LIST_APPEND(unit_files, unit_file_list->unit_files, unit_file_ref(info)); | ||
} | ||
|
||
return r; | ||
} | ||
|
||
static int method_list_unit_files_on_all(sd_bus *api_bus, print_unit_file_list_fn print, const char *glob_filter) { | ||
_cleanup_unit_file_list_ UnitFileList *unit_file_list = new_unit_file_list(); | ||
|
||
int r = fetch_unit_file_list( | ||
api_bus, | ||
NULL, | ||
BC_OBJECT_PATH, | ||
CONTROLLER_INTERFACE, | ||
"(sss)", | ||
&bus_parse_unit_file_on_node_info, | ||
unit_file_list); | ||
if (r < 0) { | ||
return r; | ||
} | ||
|
||
print(unit_file_list, glob_filter); | ||
|
||
return 0; | ||
} | ||
|
||
static int method_list_unit_files_on( | ||
sd_bus *api_bus, const char *node_name, print_unit_file_list_fn print, const char *glob_filter) { | ||
int r = 0; | ||
_cleanup_unit_file_list_ UnitFileList *unit_file_list = new_unit_file_list(); | ||
|
||
_cleanup_free_ char *object_path = NULL; | ||
r = assemble_object_path_string(NODE_OBJECT_PATH_PREFIX, node_name, &object_path); | ||
if (r < 0) { | ||
return r; | ||
} | ||
|
||
r = fetch_unit_file_list( | ||
api_bus, | ||
node_name, | ||
object_path, | ||
NODE_INTERFACE, | ||
"(ss)", | ||
&bus_parse_unit_file_info, | ||
unit_file_list); | ||
if (r < 0) { | ||
return r; | ||
} | ||
|
||
print(unit_file_list, glob_filter); | ||
|
||
return 0; | ||
} | ||
|
||
|
||
/**************************** | ||
******** UnitFileList ****** | ||
****************************/ | ||
|
||
UnitFileList *new_unit_file_list() { | ||
_cleanup_unit_file_list_ UnitFileList *unit_file_list = malloc0(sizeof(UnitFileList)); | ||
|
||
if (unit_file_list == NULL) { | ||
return NULL; | ||
} | ||
|
||
unit_file_list->ref_count = 1; | ||
LIST_HEAD_INIT(unit_file_list->unit_files); | ||
|
||
return steal_pointer(&unit_file_list); | ||
} | ||
|
||
void unit_file_list_unref(UnitFileList *unit_file_list) { | ||
unit_file_list->ref_count--; | ||
if (unit_file_list->ref_count != 0) { | ||
return; | ||
} | ||
|
||
UnitFileInfo *unit_file = NULL, *next_unit_file = NULL; | ||
LIST_FOREACH_SAFE(unit_files, unit_file, next_unit_file, unit_file_list->unit_files) { | ||
unit_file_unref(unit_file); | ||
} | ||
free(unit_file_list); | ||
} | ||
|
||
void print_unit_file_list_simple(UnitFileList *unit_file_list, const char *glob_filter) { | ||
UnitFileInfo *unit_file = NULL; | ||
const unsigned int FMT_STR_MAX_LEN = 255; | ||
char fmt_str[FMT_STR_MAX_LEN]; | ||
const char node_title[] = "NODE"; | ||
const char path_title[] = "PATH"; | ||
const char enablment_title[] = "IS-ENABLED"; | ||
const char col_sep[] = " | "; | ||
|
||
unsigned long max_node_len = strlen(node_title); | ||
unsigned long max_path_len = strlen(path_title); | ||
unsigned long max_enablement_len = strlen(enablment_title); | ||
unsigned long sep_len = strlen(col_sep); | ||
|
||
LIST_FOREACH(unit_files, unit_file, unit_file_list->unit_files) { | ||
max_node_len = umaxl(max_node_len, strlen(unit_file->node)); | ||
max_path_len = umaxl(max_path_len, strlen(unit_file->unit_path)); | ||
max_enablement_len = umaxl(max_enablement_len, strlen(unit_file->enablement_status)); | ||
} | ||
|
||
unsigned long max_line_len = max_node_len + sep_len + max_path_len + sep_len + max_enablement_len; | ||
char sep_line[max_line_len + 1]; | ||
|
||
snprintf(fmt_str, | ||
FMT_STR_MAX_LEN, | ||
"%%-%lus%s%%-%lus%s%%-%lus\n", | ||
max_node_len, | ||
col_sep, | ||
max_path_len, | ||
col_sep, | ||
max_enablement_len); | ||
|
||
printf(fmt_str, "NODE", "PATH", "IS-ENABLED"); | ||
memset(&sep_line, '=', sizeof(char) * max_line_len); | ||
sep_line[max_line_len] = '\0'; | ||
printf("%s\n", sep_line); | ||
|
||
LIST_FOREACH(unit_files, unit_file, unit_file_list->unit_files) { | ||
if (glob_filter == NULL /*|| match_glob(unit_file->)*/) { | ||
printf(fmt_str, unit_file->node, unit_file->unit_path, unit_file->enablement_status); | ||
} | ||
} | ||
} | ||
|
||
int method_list_unit_files(Command *command, void *userdata) { | ||
Client *client = (Client *) userdata; | ||
char *filter_glob = command_get_option(command, ARG_FILTER_SHORT); | ||
if (command->opargc == 0) { | ||
return method_list_unit_files_on_all(client->api_bus, print_unit_file_list_simple, filter_glob); | ||
} | ||
return method_list_unit_files_on( | ||
client->api_bus, command->opargv[0], print_unit_file_list_simple, filter_glob); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/* | ||
* Copyright Contributors to the Eclipse BlueChi project | ||
* | ||
* SPDX-License-Identifier: LGPL-2.1-or-later | ||
*/ | ||
#include "libbluechi/cli/command.h" | ||
|
||
int method_list_unit_files(Command *command, void *userdata); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,4 @@ | |
|
||
typedef struct Client Client; | ||
typedef struct UnitList UnitList; | ||
typedef struct UnitFileList UnitFileList; |
Oops, something went wrong.