#include <glib.h>

int bus_status(int argc, char** argv);
int bus_list(void);
int bus_property_get(int argc, char **argv);
int bus_property_set(int argc, char **argv);
int bus_introspect(int argc, char** argv);
int bus_emit(void);
int bus_call(int argc, char** argv);

/*
emit OBJECT INTERFACE SIGNAL [SIGNATURE [ARGUMENT...]]
                           Emit a signal
get-property SERVICE OBJECT INTERFACE PROPERTY...
                           Get property value
set-property SERVICE OBJECT INTERFACE PROPERTY SIGNATURE ARGUMENT...
                           Set property value
help                     Show this help

*/


struct bus_call_struct { 
    void (*bus_void_func) (void);
    void (*bus_arg_func) (int argc, char** args);
    char *bus_comand_name;
};

struct bus_call_struct command[] = {
    {bus_list, NULL, "list"},
    {NULL, bus_call, "call"},
    {NULL, bus_introspect, "introspect"},
    {NULL, bus_status, "status"},
    {NULL, bus_property_get, "get-property"},
    {NULL, bus_property_set, "set-property"},
    {bus_emit, NULL, "emit"},
};

struct bus_call_struct FindCommand(char *arg_command){
    struct bus_call_struct res = {NULL, NULL, NULL};
    int n = sizeof(command) / sizeof(struct bus_call_struct);
    
    for(int i = 0; i < n; i++){
        if(strcmp(command[i].bus_comand_name, arg_command) == 0){
            res = command[i];
            break;
        };
            
    }
    return res;
}

char** shl(int argc, char **args){
    for(int i = 0; i < argc; i++){
        args[i] = args[i+1];
    }
    return args;
}


int main (int argc, char **argv){
    if(argc == 1)
        return 0;
    
    struct bus_call_struct comm = FindCommand(argv[1]);

    if(comm.bus_comand_name == NULL){
        return -1;
    }

    if(comm.bus_void_func != NULL){
        comm.bus_void_func();
    }else{
        argc--;
        char* new_argc = shl(argc, argv);
        comm.bus_arg_func(argc, argv);
    }
}

/*
monitor [SERVICE...]     Show bus traffic
capture [SERVICE...]     Capture bus traffic as pcap
tree [SERVICE...]        Show object tree of service
*/
#include <glib.h>
#include <gio/gio.h>

#include "g_lib_to_work.h"

static
void Get_Args(gchar **obj_name,gchar **obj_path, gchar **i_name, gchar** prop_name, char **argv)
{   
    *obj_name = argv[1];
    *obj_path = argv[2];
    *i_name = argv[3];
    if(argv[4] != NULL){
        *prop_name = argv[4];
    }
}


static
void PrintGetAll(GVariant* result){
    GVariant* sub_res = g_variant_get_child_value(result, 0);
    GVariantIter* iter = g_variant_iter_new(sub_res);
    gchar* key;
    GVariant* val;
    while(g_variant_iter_next(iter, "{sv}", &key, &val)){
        g_print("%s :", key);
        PrintVariant(val, NULL);
    }
}

static
GVariant* Get(GDBusProxy* proxy, gchar* i_name, gchar* prop_name, GError** error){
    GVariant* res;
    res = g_dbus_proxy_call_sync(proxy, "Get", 
                                    g_variant_new("(ss)", i_name, prop_name), G_DBUS_CALL_FLAGS_NONE, 
                                    -1, NULL, error);
    return res;
}

static
GVariant* GetAll(GDBusProxy* proxy, gchar* i_name, GError** error){
    GVariant* res;
    
    res = g_dbus_proxy_call_sync(proxy, "GetAll", 
                                    g_variant_new("(s)", i_name), G_DBUS_CALL_FLAGS_NONE, 
                                    -1, NULL, error);
    return res;
}

int bus_property_get(int argc, char **argv){
    gchar* name;
    gchar* path;
    gchar* interface;
    gchar* prop_name = NULL;
    if(argc < 4){
        g_print("To Few Arguments for get-property");
        return 2;
    }
    
    Get_Args(&name, &path, &interface, &prop_name, argv);
    GDBusProxy *proxy;
    GVariant *result = NULL;
    GError *error = NULL;
    gchar *call_method_interface = "org.freedesktop.DBus.Properties";        
    
    proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, 0, NULL, name, 
                                                path, call_method_interface,  
                                                NULL, &error);
    
    if(IsError(error)){
        PrintError(error, "NULL");
        FreeError(error);
        return 2;
    }
    
    if(prop_name != NULL){
        result = Get(proxy, interface, prop_name, &error);
        g_print("%s : ", prop_name);
        PrintVariant(result, NULL);
    }else{
        result = GetAll(proxy, interface, &error);
        PrintGetAll(result);
    }
    
    if(IsError(error)){
        PrintError(error, "NULL");
        FreeError(error);
        g_object_unref(proxy);
        return 2;
    }
    
    g_object_unref(proxy);  
}
int bus_property_set(int argc, char **argv){
    gchar* name;
    gchar* path;
    gchar* interface;
    gchar* prop_name = NULL;
    gchar* val = NULL;
    
    if(argc < 6){
        g_print("To Few Arguments for set-property");
        return 2;
    }
    
    Get_Args(&name, &path, &interface, &prop_name, argv);
    val = argv[5];

    GDBusProxy *proxy;
    GVariant *result = NULL;
    GError *error = NULL;
    gchar *call_method_interface = "org.freedesktop.DBus.Properties";
      
    proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, 0, NULL, name, 
                                                path, call_method_interface,  
                                                NULL, &error);
    
    
    result = g_dbus_proxy_call_sync(proxy, "Set", 
                                    g_variant_new("(ssv)", interface, prop_name, val), G_DBUS_CALL_FLAGS_NONE, 
                                    -1, NULL, error);
                         
    if(IsError(error)){
        PrintError(error, "NULL");
        FreeError(error);
        return 2;
    }
    
    PrintVariant(result, NULL);

    g_object_unref(proxy);  
    return 0;
}


#include <glib.h>
#include <gio/gio.h>
#include "g_lib_to_work.h"

static
void FirstPrintDBusList(GVariant *result){
    const gchar* const* names = NULL;
    g_variant_get(result, "(^as)", &names);
    for(int i = 0; names[i] != NULL; i++){
        g_print("Obj name:  %s \n", names[i]);
    }

}

static
void SecondPrintDBusList(GVariant *result){
    gchar** sec_names = NULL;
    g_variant_get(result, "(^as)", &sec_names);
    for(gchar **p = sec_names ; *p; ++p){
        g_print("Obj name:  %s \n", *p);
    }
}

int bus_list(void){

    GVariant *result;
    GDBusProxy *bus_proxy;
    GError *error = NULL;

    bus_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, 0, NULL, "org.freedesktop.DBus", 
                                                "/org/freedesktop/DBus", "org.freedesktop.DBus",
                                                NULL, &error);

    if(error != NULL){
        g_print("Error %s \n", error->message);
        return 1;
    }

    result = g_dbus_proxy_call_sync(bus_proxy, "ListNames", 
                                    NULL, G_DBUS_CALL_FLAGS_NONE, 
                                    -1, NULL, &error);

    PrintVariant(result, NULL);
    
    if(error != NULL){
        g_print("Error %s \n", error->message);
        return 1;
    }

    SecondPrintDBusList(result);
    
    g_variant_unref(result);
    g_object_unref(bus_proxy);
    

    return 0;
}   
#include <glib.h>
#include <gio/gio.h>
#include "g_lib_to_work.h"

static
void PrintArg(GDBusArgInfo** args, gchar* pattern){
    if(args[0]){
        gchar* res = "";
        for(int i = 0; args[i] != NULL; i++){
            if(args[i] !=NULL){
                
                gchar* m_name = (args[i]->name) ? args[i]->name : "";
                gchar* sign = (args[i]->signature) ? args[i]->signature : "";
                if(sign)
                    sign = g_strconcat(":", sign, NULL);
                
                res = g_strconcat(res, m_name, sign, NULL);
                if(args[i + 1]){
                    res = g_strconcat(res, ",", NULL);
                }
            }
        }
        g_print(pattern, res); //"(%s)"
    }
}

static
void PrintMethods(GDBusMethodInfo ** m_info){
    printf("--Methods:\n");
    for (int j = 0; m_info[j] != NULL; j++) {
        if(m_info[j])
            g_print("  %s ", m_info[j]->name);
        
        PrintArg(m_info[j]->in_args, "(%s)");
        PrintArg(m_info[j]->in_args, " out [%s]");
        g_print("\n");
    }
}

static
void PrintPropertys(GDBusPropertyInfo **p_info){
    printf("--Properties:\n");
    for (int k = 0; p_info[k] != NULL; k++) {
        if(p_info[k])
            g_print("  %s (%s)\n", p_info[k]->name, p_info[k]->signature);
    }
}

static
void PrintSignals(GDBusSignalInfo **s_info){
    printf("--Signals:\n");
    for (int z = 0; s_info[z] != NULL ; z++) {
        if(s_info[z]){
            g_print("%s ", s_info[z]->name);
            PrintArg(s_info[z]->args, "(%s)");
        }
    }
}

int bus_introspect(int argc, char** argv){
    
    GDBusProxy *proxy;
    GVariant *result = NULL;
    GError *error = NULL;
    
    gchar *obj_name = "org.freedesktop.systemd1"; //"org.freedesktop.DBus"; //
    gchar *obj_path = "/org/freedesktop/systemd1";//"/org/freedesktop/DBus"///
    gchar *i_name = "org.freedesktop.DBus.Introspectable";

    proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, 0, NULL, obj_name, 
                                                obj_path, i_name, 
                                                NULL, &error);


    result = g_dbus_proxy_call_sync(proxy, "Introspect", 
                                    NULL, G_DBUS_CALL_FLAGS_NONE, 
                                    -1, NULL, &error);
    g_object_unref(proxy);
    

    GVariantIter *interfaces = g_variant_iter_new(result);
    
    g_variant_unref(result);

    const gchar *interface_names;
    g_variant_iter_next(interfaces, "s", &interface_names, NULL);


    g_print(interface_names);
    GDBusNodeInfo *node_info = g_dbus_node_info_new_for_xml(interface_names, NULL);
    if(node_info == NULL)
        return 2;

    for (int i = 0; node_info->interfaces[i] != NULL; i++) {
        GDBusInterfaceInfo *interface_info = node_info->interfaces[i];
        printf("Interface: %s\n", interface_info->name);
        
        if(interface_info->methods[0] != NULL){
            PrintMethods(interface_info->methods);
        }
        
        if(interface_info->properties[0] != NULL){        
            PrintPropertys(interface_info->properties);
        }
        if(interface_info->signals[0] != NULL){
            PrintSignals(interface_info->signals);
        }
    }
    g_dbus_node_info_unref(node_info);
    return 0;
}

#include <glib.h>
#include <gio/gio.h>
#include "g_lib_to_work.h"

//call SERVICE OBJECT INTERFACE METHOD [SIGNATURE [ARGUMENT...]]

static
void Get_Call_Args(gchar **obj_name, gchar **obj_path, gchar **i_name, gchar** method_name, char **argv){   
        *obj_name = argv[1];
        *obj_path = argv[2];
        *i_name = argv[3];
        if(argv[4] != NULL){
            *method_name = argv[4];
        }
        return 0;
}

int bus_call(int argc, char** argv){  

    

    GDBusProxy *proxy;
    GVariant *result;
    GError *error = NULL;

    
    gchar *obj_name;
    gchar *obj_path; 
    gchar *i_name; 
    gchar *method_name;

    Get_Call_Args(&obj_name, &obj_path, &i_name, &method_name, argv);
    

    proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION, 0, NULL, obj_name, 
                                                obj_path, i_name, 
                                                NULL, &error);

    result = g_dbus_proxy_call_sync(proxy, method_name, 
                                    NULL, G_DBUS_CALL_FLAGS_NONE, 
                                    -1, NULL, &error);
    
    if(IsError(error)){
        g_object_unref(proxy);
        g_object_unref(result);
        FreeError(error);
        g_print("Error message %s \n", error->message);
        return 0;
    }

    GVariantIter *interfaces = g_variant_iter_new(result);
    const gchar *interface_name;

    g_variant_iter_next(interfaces, "s", &interface_name, NULL);
    printf(interface_name);

    g_object_unref(proxy);
    g_variant_unref(result);
    
    return 0;
}
Это код нескольких файлов приложения которое я сделал для диплома, сделай подробное описание кода, с дополнительной информацией примерно на 10 страниц