BVB Source Codes

cockpit Show cockpitdbusmeta.c Source code

Return Download cockpit: download cockpitdbusmeta.c Source code - Download cockpit Source code - Type:.c
  1. /*
  2.  * This file is part of Cockpit.
  3.  *
  4.  * Copyright (C) 2016 Red Hat, Inc.
  5.  *
  6.  * Cockpit is free software; you can redistribute it and/or modify it
  7.  * under the terms of the GNU Lesser General Public License as published by
  8.  * the Free Software Foundation; either version 2.1 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * Cockpit is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public License
  17.  * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
  18.  */
  19.  
  20. #include "config.h"
  21.  
  22. #include "cockpitdbusmeta.h"
  23.  
  24. #include "common/cockpitjson.h"
  25.  
  26. #include <string.h>
  27.  
  28. static JsonArray *
  29. build_meta_arguments (GDBusArgInfo **args)
  30. {
  31.   JsonArray *arguments = json_array_new ();
  32.   while (*args)
  33.     {
  34.       json_array_add_string_element (arguments, (*args)->signature);
  35.       args++;
  36.     }
  37.   return arguments;
  38. }
  39.  
  40. static JsonObject *
  41. build_meta_method (GDBusMethodInfo *meth)
  42. {
  43.   JsonObject *method = json_object_new ();
  44.   if (meth->in_args)
  45.     {
  46.       json_object_set_array_member (method, "in",
  47.                                     build_meta_arguments (meth->in_args));
  48.     }
  49.   if (meth->out_args)
  50.     {
  51.       json_object_set_array_member (method, "out",
  52.                                     build_meta_arguments (meth->out_args));
  53.     }
  54.   return method;
  55. }
  56.  
  57. static JsonObject *
  58. build_meta_signal (GDBusSignalInfo *sig)
  59. {
  60.   JsonObject *signal = json_object_new ();
  61.   if (sig->args)
  62.     {
  63.       json_object_set_array_member (signal, "in",
  64.                                     build_meta_arguments (sig->args));
  65.     }
  66.   return signal;
  67. }
  68.  
  69. static JsonObject *
  70. build_meta_property (GDBusPropertyInfo *prop)
  71. {
  72.   JsonObject *property = json_object_new ();;
  73.   GString *flags = g_string_new ("");
  74.  
  75.   if (prop->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)
  76.     g_string_append_c (flags, 'r');
  77.   if (prop->flags & G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE)
  78.     g_string_append_c (flags, 'w');
  79.   json_object_set_string_member (property, "flags", flags->str);
  80.   if (prop->signature)
  81.     json_object_set_string_member (property, "type", prop->signature);
  82.   g_string_free (flags, TRUE);
  83.   return property;
  84. }
  85.  
  86. JsonObject *
  87. cockpit_dbus_meta_build (GDBusInterfaceInfo *iface)
  88. {
  89.   JsonObject *interface;
  90.   JsonObject *methods;
  91.   JsonObject *properties;
  92.   JsonObject *signals;
  93.   guint i;
  94.  
  95.   g_return_val_if_fail (iface != NULL, NULL);
  96.  
  97.   interface = json_object_new ();
  98.  
  99.   if (iface->methods)
  100.     {
  101.       methods = json_object_new ();
  102.       for (i = 0; iface->methods[i] != NULL; i++)
  103.         {
  104.           json_object_set_object_member (methods, iface->methods[i]->name,
  105.                                          build_meta_method (iface->methods[i]));
  106.         }
  107.       json_object_set_object_member (interface, "methods", methods);
  108.     }
  109.  
  110.   if (iface->properties)
  111.     {
  112.       properties = json_object_new ();
  113.       for (i = 0; iface->properties[i] != NULL; i++)
  114.         {
  115.           json_object_set_object_member (properties, iface->properties[i]->name,
  116.                                          build_meta_property (iface->properties[i]));
  117.         }
  118.       json_object_set_object_member (interface, "properties", properties);
  119.     }
  120.  
  121.   if (iface->signals)
  122.     {
  123.       signals = json_object_new ();
  124.       for (i = 0; iface->signals[i] != NULL; i++)
  125.         {
  126.           json_object_set_object_member (signals, iface->signals[i]->name,
  127.                                          build_meta_signal (iface->signals[i]));
  128.         }
  129.       json_object_set_object_member (interface, "signals", signals);
  130.     }
  131.  
  132.   return interface;
  133. }
  134.  
  135. static GDBusArgInfo **
  136. parse_meta_arguments (JsonArray *arguments,
  137.                       GError **error)
  138. {
  139.   const gchar *signature;
  140.   GDBusArgInfo *arg;
  141.   GPtrArray *args;
  142.   guint i, length;
  143.   JsonNode *node;
  144.  
  145.   args = g_ptr_array_new ();
  146.   g_ptr_array_set_free_func (args, (GDestroyNotify)g_dbus_arg_info_unref);
  147.  
  148.   length = json_array_get_length (arguments);
  149.   for (i = 0; i < length; i++)
  150.     {
  151.       node = json_array_get_element (arguments, i);
  152.       if (!JSON_NODE_HOLDS_VALUE(node) || json_node_get_value_type (node) != G_TYPE_STRING)
  153.         {
  154.           g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  155.                        "invalid argument in dbus meta field");
  156.           break;
  157.         }
  158.  
  159.       signature = json_node_get_string (node);
  160.       if (!g_variant_is_signature (signature))
  161.         {
  162.           g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  163.                        "argument in dbus meta field has invalid signature: %s", signature);
  164.           break;
  165.         }
  166.  
  167.       arg = g_new0 (GDBusArgInfo, 1);
  168.       arg->ref_count = 1;
  169.       arg->name = g_strdup_printf ("argument_%u", i);
  170.       arg->signature = g_strdup (signature);
  171.       g_ptr_array_add (args, arg);
  172.     }
  173.  
  174.   if (i != length)
  175.     {
  176.       g_ptr_array_free (args, TRUE);
  177.       return NULL;
  178.     }
  179.   else
  180.     {
  181.       g_ptr_array_add (args, NULL);
  182.       return (GDBusArgInfo **)g_ptr_array_free (args, FALSE);
  183.     }
  184. }
  185.  
  186. static GDBusMethodInfo *
  187. parse_meta_method (const gchar *method_name,
  188.                    JsonObject *method,
  189.                    GError **error)
  190. {
  191.   GDBusMethodInfo *ret = NULL;
  192.   GDBusMethodInfo *meth;
  193.   JsonArray *args;
  194.  
  195.   meth = g_new0 (GDBusMethodInfo, 1);
  196.   meth->ref_count = 1;
  197.   meth->name = g_strdup (method_name);
  198.  
  199.   if (!cockpit_json_get_array (method, "in", NULL, &args))
  200.     {
  201.       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  202.                    "invalid \"in\" field in dbus meta method: %s", method_name);
  203.       goto out;
  204.     }
  205.  
  206.   if (args && json_array_get_length (args) > 0)
  207.     {
  208.       meth->in_args = parse_meta_arguments (args, error);
  209.       if (!meth->in_args)
  210.         goto out;
  211.     }
  212.  
  213.   if (!cockpit_json_get_array (method, "out", NULL, &args))
  214.     {
  215.       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  216.                    "invalid \"out\" field in dbus meta method: %s", method_name);
  217.       goto out;
  218.     }
  219.  
  220.   if (args && json_array_get_length (args) > 0)
  221.     {
  222.       meth->out_args = parse_meta_arguments (args, error);
  223.       if (!meth->out_args)
  224.         goto out;
  225.     }
  226.  
  227.   ret = meth;
  228.   meth = NULL;
  229.  
  230. out:
  231.   if (meth)
  232.     g_dbus_method_info_unref (meth);
  233.   return ret;
  234. }
  235.  
  236. static GDBusSignalInfo *
  237. parse_meta_signal (const gchar *signal_name,
  238.                    JsonObject *signal,
  239.                    GError **error)
  240. {
  241.   GDBusSignalInfo *ret = NULL;
  242.   GDBusSignalInfo *sig;
  243.   JsonArray *args;
  244.  
  245.   sig = g_new0 (GDBusSignalInfo, 1);
  246.   sig->ref_count = 1;
  247.   sig->name = g_strdup (signal_name);
  248.  
  249.   if (!cockpit_json_get_array (signal, "in", NULL, &args))
  250.     {
  251.       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  252.                    "invalid \"in\" field in dbus meta signal: %s", signal_name);
  253.       goto out;
  254.     }
  255.  
  256.   if (args && json_array_get_length (args) > 0)
  257.     {
  258.       sig->args = parse_meta_arguments (args, error);
  259.       if (!sig->args)
  260.         goto out;
  261.     }
  262.  
  263.   ret = sig;
  264.   sig = NULL;
  265.  
  266. out:
  267.   if (sig)
  268.     g_dbus_signal_info_unref (sig);
  269.   return ret;
  270. }
  271.  
  272. static GDBusPropertyInfo *
  273. parse_meta_property (const gchar *property_name,
  274.                      JsonObject *property,
  275.                      GError **error)
  276. {
  277.   GDBusPropertyInfo *prop;
  278.   GDBusPropertyInfo *ret = NULL;
  279.   const gchar *flags;
  280.   const gchar *type;
  281.  
  282.   prop = g_new0 (GDBusPropertyInfo, 1);
  283.   prop->ref_count = 1;
  284.   prop->name = g_strdup (property_name);
  285.  
  286.   if (!cockpit_json_get_string (property, "flags", NULL, &flags))
  287.     {
  288.       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  289.                    "invalid \"flags\" field in dbus property: %s", property_name);
  290.       goto out;
  291.     }
  292.  
  293.   if (flags && strchr (flags, 'r'))
  294.     prop->flags |= G_DBUS_PROPERTY_INFO_FLAGS_READABLE;
  295.   if (flags && strchr (flags, 'w'))
  296.     prop->flags |= G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE;
  297.  
  298.   if (!cockpit_json_get_string (property, "type", NULL, &type))
  299.     {
  300.       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  301.                    "invalid \"type\" field in dbus property: %s", property_name);
  302.       goto out;
  303.     }
  304.   else if (!type)
  305.     {
  306.       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  307.                    "missing \"type\" field in dbus property: %s", property_name);
  308.       goto out;
  309.     }
  310.   else if (!g_variant_is_signature (type))
  311.     {
  312.       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  313.                    "the \"type\" field in dbus property is not a dbus signature: %s", type);
  314.       goto out;
  315.     }
  316.  
  317.   prop->signature = g_strdup (type);
  318.  
  319.   ret = prop;
  320.   prop = NULL;
  321.  
  322. out:
  323.   if (prop)
  324.     g_dbus_property_info_unref (prop);
  325.   return ret;
  326. }
  327.  
  328. GDBusInterfaceInfo *
  329. cockpit_dbus_meta_parse (const gchar *iface_name,
  330.                          JsonObject *interface,
  331.                          GError **error)
  332. {
  333.   GDBusInterfaceInfo *ret = NULL;
  334.   GDBusInterfaceInfo *iface;
  335.   GDBusMethodInfo *meth;
  336.   GDBusSignalInfo *sig;
  337.   GDBusPropertyInfo *prop;
  338.   JsonObject *methods;
  339.   JsonObject *method;
  340.   JsonObject *signals;
  341.   JsonObject *signal;
  342.   JsonObject *properties;
  343.   JsonObject *property;
  344.   GPtrArray *array = NULL;
  345.   GList *names = NULL, *l;
  346.  
  347.   g_return_val_if_fail (iface_name != NULL, NULL);
  348.   g_return_val_if_fail (interface != NULL, NULL);
  349.   g_return_val_if_fail (!error || !*error, NULL);
  350.  
  351.   iface = g_new0 (GDBusInterfaceInfo, 1);
  352.   iface->name = g_strdup (iface_name);
  353.   iface->ref_count = 1;
  354.  
  355.   if (!cockpit_json_get_object (interface, "methods", NULL, &methods))
  356.     {
  357.       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  358.                    "invalid \"methods\" field in dbus meta structure");
  359.       goto out;
  360.     }
  361.  
  362.   if (methods)
  363.     {
  364.       array = g_ptr_array_new ();
  365.       g_ptr_array_set_free_func (array, (GDestroyNotify)g_dbus_method_info_unref);
  366.  
  367.       names = json_object_get_members (methods);
  368.       for (l = names; l != NULL; l = g_list_next (l))
  369.         {
  370.           if (!cockpit_json_get_object (methods, l->data, NULL, &method))
  371.             {
  372.               g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  373.                            "invalid method field in dbus meta structure: %s",
  374.                            (const gchar *)l->data);
  375.               goto out;
  376.             }
  377.  
  378.           g_assert (method != NULL);
  379.           meth = parse_meta_method (l->data, method, error);
  380.           if (!meth)
  381.             goto out;
  382.  
  383.           g_ptr_array_add (array, meth);
  384.         }
  385.  
  386.       g_list_free (names);
  387.       names = NULL;
  388.  
  389.       g_ptr_array_add (array, NULL);
  390.       iface->methods = (GDBusMethodInfo **)g_ptr_array_free (array, FALSE);
  391.       array = NULL;
  392.     }
  393.  
  394.   if (!cockpit_json_get_object (interface, "signals", NULL, &signals))
  395.     {
  396.       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  397.                    "invalid \"signals\" field in dbus meta structure");
  398.       goto out;
  399.     }
  400.  
  401.   if (signals)
  402.     {
  403.       array = g_ptr_array_new ();
  404.       g_ptr_array_set_free_func (array, (GDestroyNotify)g_dbus_signal_info_unref);
  405.  
  406.       names = json_object_get_members (signals);
  407.       for (l = names; l != NULL; l = g_list_next (l))
  408.         {
  409.           if (!cockpit_json_get_object (signals, l->data, NULL, &signal))
  410.             {
  411.               g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  412.                            "invalid signal field in dbus meta structure: %s",
  413.                            (const gchar *)l->data);
  414.               goto out;
  415.             }
  416.  
  417.           g_assert (signal != NULL);
  418.           sig = parse_meta_signal (l->data, signal, error);
  419.           if (!sig)
  420.             goto out;
  421.  
  422.           g_ptr_array_add (array, sig);
  423.         }
  424.  
  425.       g_list_free (names);
  426.       names = NULL;
  427.  
  428.       g_ptr_array_add (array, NULL);
  429.       iface->signals = (GDBusSignalInfo **)g_ptr_array_free (array, FALSE);
  430.       array = NULL;
  431.     }
  432.  
  433.   if (!cockpit_json_get_object (interface, "properties", NULL, &properties))
  434.     {
  435.       g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  436.                    "invalid \"properties\" field in dbus meta structure");
  437.       goto out;
  438.     }
  439.  
  440.   if (properties)
  441.     {
  442.       array = g_ptr_array_new ();
  443.       g_ptr_array_set_free_func (array, (GDestroyNotify)g_dbus_property_info_unref);
  444.  
  445.       names = json_object_get_members (properties);
  446.       for (l = names; l != NULL; l = g_list_next (l))
  447.         {
  448.           if (!cockpit_json_get_object (properties, l->data, NULL, &property))
  449.             {
  450.               g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  451.                            "invalid property field in dbus meta structure: %s",
  452.                            (const gchar *)l->data);
  453.               goto out;
  454.             }
  455.  
  456.           g_assert (property != NULL);
  457.           prop = parse_meta_property (l->data, property, error);
  458.           if (!prop)
  459.             goto out;
  460.  
  461.           g_ptr_array_add (array, prop);
  462.         }
  463.  
  464.       g_list_free (names);
  465.       names = NULL;
  466.  
  467.       g_ptr_array_add (array, NULL);
  468.       iface->properties = (GDBusPropertyInfo **)g_ptr_array_free (array, FALSE);
  469.       array = NULL;
  470.     }
  471.  
  472.   ret = iface;
  473.   iface = NULL;
  474.  
  475. out:
  476.   if (iface)
  477.     g_dbus_interface_info_unref (iface);
  478.   if (array)
  479.     g_ptr_array_free (array, TRUE);
  480.   if (names)
  481.     g_list_free (names);
  482.   return ret;
  483. }
  484.  
downloadcockpitdbusmeta.c Source code - Download cockpit Source code
Related Source Codes/Software:
elasticsearch-kopf - web admin interface for elasticsearch 2017-05-07
xunlei-lixian - Thunderbolt offline download script 2017-05-07
xadmin - Drop-in replacement of Django admin comes with lot... 2017-05-07
p2pspider - DHT Spider + BitTorrent Client = P2P Spider 2017-05-07
Backbone.localStorage - A localStorage adapter for Backbone.j 2017-05-07
phenomic - 2017-05-07
shoulda - Makes tests easy on the fingers and the eyes ... 2017-05-07
mio - Metal IO library for Rust 2017-05-07
nova - OpenStack Compute (Nova) ht... 2017-05-07
gobyexample - Go by Example https://gobye... 2017-05-07
react-boilerplate - 2017-06-07
webtorrent - Streaming torrent client for the web ... 2017-06-06
machine-learning-for-software-engineers - A complete daily plan for studying to become a mac... 2017-06-06
upterm - A terminal emulator for the 21st century. 2017-06-06
huginn - Create agents that monitor and act on your behalf.... 2017-06-06
system-design-primer - Learn how to design large-scale systems. Prep for ... 2017-06-06
design-patterns-for-humans - Design Patterns for Humans - An ultra-simplified e... 2017-06-06
developer-roadmap - Roadmap to becoming a web developer in 2017 2017-06-06
nylas-mail - 2017-06-06

 Back to top