void xmlrpc_registry_add_method_w_doc(xmlrpc_env *env, xmlrpc_registry *registry, const char *host, const char *method_name, xmlrpc_method method, void *user_data, const char *signature, const char *help) { xmlrpc_value *method_info; XMLRPC_ASSERT_ENV_OK(env); XMLRPC_ASSERT_PTR_OK(registry); XMLRPC_ASSERT(host == NULL); XMLRPC_ASSERT_PTR_OK(method_name); XMLRPC_ASSERT_PTR_OK(method); /* Error-handling preconditions. */ method_info = NULL; /* Store our method and user data into our hash table. */ method_info = xmlrpc_build_value(env, "(ppss)", (void*) method, user_data, signature, help); XMLRPC_FAIL_IF_FAULT(env); xmlrpc_struct_set_value(env, registry->_methods, method_name, method_info); XMLRPC_FAIL_IF_FAULT(env); cleanup: if (method_info) xmlrpc_DECREF(method_info); }
static xmlrpc_value * you_patch_to_xmlrpc (xmlrpc_env *env, RCYouPatch *patch) { RCPackageSpec *spec = RC_PACKAGE_SPEC (patch); xmlrpc_value *xpatch = NULL; xpatch = xmlrpc_struct_new (env); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING (env, xpatch, "name", rc_package_spec_get_name (spec)); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING (env, xpatch, "version", rc_package_spec_version_to_str_static (spec)); XMLRPC_FAIL_IF_FAULT (env); cleanup: if (env->fault_occurred && xpatch != NULL) { xmlrpc_DECREF (xpatch); xpatch = NULL; } return xpatch; }
static xmlrpc_value * service_list (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { ServiceInfo info; info.result = xmlrpc_build_value (env, "()"); XMLRPC_FAIL_IF_FAULT (env); info.env = env; rc_world_multi_foreach_subworld_by_type (RC_WORLD_MULTI (rc_get_world ()), RC_TYPE_WORLD_SERVICE, add_service_cb, &info); XMLRPC_FAIL_IF_FAULT (env); cleanup: if (env->fault_occurred) { xmlrpc_DECREF (info.result); return NULL; } else return info.result; }
static void rcd_transaction_send_log (RCDTransaction *transaction, gboolean successful, const char *message) { xmlrpc_env env; xmlrpc_value *params; xmlrpc_value *transaction_log = NULL; xmlrpc_env_init (&env); transaction_log = transaction_xml (&env, transaction, successful, message); XMLRPC_FAIL_IF_FAULT (&env); params = xmlrpc_build_value (&env, "(V)", transaction_log); XMLRPC_FAIL_IF_FAULT (&env); rcd_xmlrpc_client_foreach_host (TRUE, "rcserver.transaction.log", log_sent_cb, NULL, params); xmlrpc_DECREF (params); cleanup: xmlrpc_env_clean (&env); if (transaction_log) xmlrpc_DECREF (transaction_log); } /* rcd_transaction_send_log */
static xmlrpc_value * convert_params(xmlrpc_env * const envP, const xml_element * const elemP) { /*---------------------------------------------------------------------------- Convert an XML element representing a list of parameters (i.e. a <params> element) to an xmlrpc_value of type array. Note that an array is normally represented in XML by a <value> element. We use type xmlrpc_value to represent the parameter list just for convenience. -----------------------------------------------------------------------------*/ xmlrpc_value *array, *item; int size, i; xml_element **params, *param, *value; XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT(elemP != NULL); /* Set up our error-handling preconditions. */ array = item = NULL; /* Allocate an array to hold our parameters. */ array = xmlrpc_build_value(envP, "()"); XMLRPC_FAIL_IF_FAULT(envP); /* We're responsible for checking our own element name. */ CHECK_NAME(envP, elemP, "params"); /* Iterate over our children. */ size = xml_element_children_size(elemP); params = xml_element_children(elemP); for (i = 0; i < size; ++i) { unsigned int const maxNest = xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID); param = params[i]; CHECK_NAME(envP, param, "param"); CHECK_CHILD_COUNT(envP, param, 1); value = xml_element_children(param)[0]; CHECK_NAME(envP, value, "value"); xmlrpc_parseValue(envP, maxNest, value, &item); XMLRPC_FAIL_IF_FAULT(envP); xmlrpc_array_append_item(envP, array, item); xmlrpc_DECREF(item); item = NULL; XMLRPC_FAIL_IF_FAULT(envP); } cleanup: if (envP->fault_occurred) { if (array) xmlrpc_DECREF(array); if (item) xmlrpc_DECREF(item); return NULL; } return array; }
static xml_element * xmlElementNew(xmlrpc_env * const envP, const char * const name) { /*---------------------------------------------------------------------------- Create a new xml_element. This routine isn't exported, because the arguments are implementation-dependent. -----------------------------------------------------------------------------*/ xml_element * retval; bool nameIsValid; bool cdataIsValid; bool childrenAreValid; XMLRPC_ASSERT_ENV_OK(envP); assert(name != NULL); /* Set up our error-handling preconditions. */ retval = NULL; nameIsValid = cdataIsValid = childrenAreValid = false; MALLOCVAR(retval); XMLRPC_FAIL_IF_NULL(retval, envP, XMLRPC_INTERNAL_ERROR, "Couldn't allocate memory for XML element"); retval->parentP = NULL; /* Copy over the element name. */ retval->name = strdup(name); XMLRPC_FAIL_IF_NULL(retval->name, envP, XMLRPC_INTERNAL_ERROR, "Couldn't allocate memory for XML element"); nameIsValid = true; /* Initialize a block to hold our CDATA. */ XMLRPC_TYPED_MEM_BLOCK_INIT(char, envP, &retval->cdata, 0); XMLRPC_FAIL_IF_FAULT(envP); cdataIsValid = true; /* Initialize a block to hold our child elements. */ XMLRPC_TYPED_MEM_BLOCK_INIT(xml_element *, envP, &retval->children, 0); XMLRPC_FAIL_IF_FAULT(envP); childrenAreValid = true; cleanup: if (envP->fault_occurred) { if (retval) { if (nameIsValid) xmlrpc_strfree(retval->name); if (cdataIsValid) xmlrpc_mem_block_clean(&retval->cdata); if (childrenAreValid) xmlrpc_mem_block_clean(&retval->children); free(retval); } retval = NULL; } return retval; }
static xmlrpc_value * you_license (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { xmlrpc_value *xmlrpc_patches = NULL; RCYouPatchSList *patches = NULL; GSList *licenses = NULL; xmlrpc_value *xmlrpc_licenses = NULL; GSList *iter; xmlrpc_parse_value (env, param_array, "(A)", &xmlrpc_patches); XMLRPC_FAIL_IF_FAULT (env); patches = rc_xmlrpc_array_to_rc_you_patch_slist (xmlrpc_patches, env, RC_YOU_PATCH_FROM_XMLRPC_PATCH); XMLRPC_FAIL_IF_FAULT (env); licenses = rc_you_patch_slist_lookup_licenses (patches); xmlrpc_licenses = xmlrpc_build_value (env, "()"); XMLRPC_FAIL_IF_FAULT (env); for (iter = licenses; iter; iter = iter->next) { xmlrpc_value *xmlrpc_text; xmlrpc_text = xmlrpc_build_value (env, "s", (char *) iter->data); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_array_append_item (env, xmlrpc_licenses, xmlrpc_text); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_DECREF (xmlrpc_text); } cleanup: if (patches) { rc_you_patch_slist_unref (patches); g_slist_free (patches); } g_slist_free (licenses); if (env->fault_occurred) return NULL; return xmlrpc_licenses; }
static xmlrpc_value * license_lookup_from_packages (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { xmlrpc_value *xmlrpc_packages; RCPackageSList *packages = NULL; GSList *licenses = NULL; xmlrpc_value *license_texts = NULL; GSList *iter; xmlrpc_parse_value (env, param_array, "(A)", &xmlrpc_packages); XMLRPC_FAIL_IF_FAULT (env); packages = rcd_xmlrpc_array_to_rc_package_slist (xmlrpc_packages, env, RCD_PACKAGE_FROM_XMLRPC_PACKAGE); XMLRPC_FAIL_IF_FAULT (env); licenses = rcd_license_lookup_from_package_slist (packages); license_texts = xmlrpc_build_value (env, "()"); XMLRPC_FAIL_IF_FAULT (env); for (iter = licenses; iter; iter = iter->next) { xmlrpc_value *xmlrpc_text; xmlrpc_text = xmlrpc_build_value (env, "s", (char *) iter->data); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_array_append_item (env, license_texts, xmlrpc_text); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_DECREF (xmlrpc_text); } cleanup: if (packages) { rc_package_slist_unref (packages); g_slist_free (packages); } g_slist_free (licenses); if (env->fault_occurred) return NULL; return license_texts; }
void xmlrpc_registry_set_preinvoke_method(xmlrpc_env *env, xmlrpc_registry *registry, xmlrpc_preinvoke_method handler, void *user_data) { xmlrpc_value *method_info; XMLRPC_ASSERT_ENV_OK(env); XMLRPC_ASSERT_PTR_OK(registry); XMLRPC_ASSERT_PTR_OK(handler); /* Error-handling preconditions. */ method_info = NULL; /* Store our method and user data into our hash table. */ method_info = xmlrpc_build_value(env, "(pp)", (void*) handler, user_data); XMLRPC_FAIL_IF_FAULT(env); /* Dispose of any pre-existing preinvoke method and install ours. */ if (registry->_preinvoke_method) xmlrpc_DECREF(registry->_preinvoke_method); registry->_preinvoke_method = method_info; cleanup: if (env->fault_occurred) { if (method_info) xmlrpc_DECREF(method_info); } }
static xmlrpc_value * service_remove (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { char *service_identifier; RCWorldService *service; xmlrpc_parse_value (env, param_array, "(s)", &service_identifier); XMLRPC_FAIL_IF_FAULT (env); service = service_lookup (service_identifier); if (!service) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to unmount service for '%s'", service_identifier); goto cleanup; } rc_world_multi_remove_subworld (RC_WORLD_MULTI (rc_get_world ()), RC_WORLD (service)); rcd_services_save (); cleanup: if (env->fault_occurred) return NULL; return xmlrpc_build_value (env, "i", 0); }
/* set cookie function */ void xmlrpc_authcookie_set ( xmlrpc_env *env, const char *username, const char *password ) { char *unencoded; xmlrpc_mem_block *token; static char env_buffer[1024]; const char* block; /* Check asserts. */ XMLRPC_ASSERT_ENV_OK(env); XMLRPC_ASSERT_PTR_OK(username); XMLRPC_ASSERT_PTR_OK(password); /* Clear out memory. */ unencoded = (char *) malloc ( sizeof ( char * ) ); /* Create unencoded string/hash. */ sprintf(unencoded, "%s:%s", username, password); /* Create encoded string. */ token = xmlrpc_base64_encode_without_newlines(env, (unsigned char*)unencoded, strlen(unencoded)); XMLRPC_FAIL_IF_FAULT(env); /* Set HTTP_COOKIE_AUTH to the character representation of the ** encoded string. */ block = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, token); sprintf(env_buffer, "HTTP_COOKIE_AUTH=%s", block); putenv(env_buffer); cleanup: if (token) xmlrpc_mem_block_free(token); }
static xmlrpc_value * service_add (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { char *service_url, *mangled_url; GError *err = NULL; xmlrpc_parse_value (env, param_array, "(s)", &service_url); XMLRPC_FAIL_IF_FAULT (env); /* We always want to download data from the site */ mangled_url = g_strconcat (service_url, "?remote_only=1", NULL); if (!rc_world_multi_mount_service (RC_WORLD_MULTI (rc_get_world ()), mangled_url, &err)) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to mount service for '%s': %s", service_url, err->message); } else rcd_services_save (); g_free (mangled_url); cleanup: if (env->fault_occurred) return NULL; return xmlrpc_build_value (env, "i", 0); }
static xmlrpc_value * users_remove (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { char *username; gboolean rv = FALSE; xmlrpc_value *value = NULL; xmlrpc_parse_value (env, param_array, "(s)", &username); XMLRPC_FAIL_IF_FAULT (env); if (username && *username) { RCDIdentity *identity; identity = rcd_identity_lookup (username); if (identity != NULL) { rv = rcd_identity_remove (identity); rcd_identity_free (identity); } } value = xmlrpc_build_value (env, "i", rv ? 1 : 0); cleanup: return value; }
static void format_out(xmlrpc_env *env, xmlrpc_mem_block *output, char *format_string, ...) { va_list args; char buffer[SMALL_BUFFER_SZ]; int count; XMLRPC_ASSERT_ENV_OK(env); va_start(args, format_string); /* We assume that this function is present and works correctly. Right. */ count = vsnprintf(buffer, SMALL_BUFFER_SZ, format_string, args); /* Old C libraries return -1 if vsnprintf overflows its buffer. ** New C libraries return the number of characters which *would* have ** been printed if the error did not occur. This is impressively vile. ** Thank the C99 committee for this bright idea. But wait! We also ** need to keep track of the trailing NULL. */ if (count < 0 || count >= (SMALL_BUFFER_SZ - 1)) XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, "format_out overflowed internal buffer"); /* Append our new data to our output. */ XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, output, buffer, count); XMLRPC_FAIL_IF_FAULT(env); cleanup: va_end(args); }
xmlrpc_registry * xmlrpc_registry_new(xmlrpc_env *env) { xmlrpc_value *methods; xmlrpc_registry *registry; int registry_valid; XMLRPC_ASSERT_ENV_OK(env); /* Error-handling preconditions. */ methods = NULL; registry = NULL; registry_valid = 0; /* Allocate our memory. */ methods = xmlrpc_struct_new(env); XMLRPC_FAIL_IF_FAULT(env); registry = (xmlrpc_registry*) malloc(sizeof(xmlrpc_registry)); XMLRPC_FAIL_IF_NULL(registry, env, XMLRPC_INTERNAL_ERROR, "Could not allocate memory for registry"); /* Set everything up. */ registry->_introspection_enabled = 1; registry->_methods = methods; registry->_default_method = NULL; registry->_preinvoke_method = NULL; registry_valid = 1; /* Install our system methods. */ install_system_methods(env, registry); XMLRPC_FAIL_IF_FAULT(env); cleanup: if (env->fault_occurred) { if (registry_valid) { xmlrpc_registry_free(registry); } else { if (methods) xmlrpc_DECREF(methods); if (registry) free(registry); } return NULL; } return registry; }
static xmlrpc_value * you_info (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { xmlrpc_value *xmlrpc_patch = NULL; RCYouPatch *patch = NULL; xmlrpc_value *result = NULL; xmlrpc_parse_value (env, param_array, "(V)", &xmlrpc_patch); XMLRPC_FAIL_IF_FAULT (env); patch = rc_xmlrpc_to_rc_you_patch (xmlrpc_patch, env, RC_YOU_PATCH_FROM_XMLRPC_PATCH); XMLRPC_FAIL_IF_FAULT (env); g_assert (patch != NULL); result = xmlrpc_struct_new (env); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING (env, result, "summary", patch->summary); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING (env, result, "description", patch->description); XMLRPC_FAIL_IF_FAULT (env); cleanup: if (env->fault_occurred) { if (patch) rc_you_patch_unref (patch); if (result) xmlrpc_DECREF (result); return NULL; } return result; }
static xmlrpc_mem_block * serialize_fault (int fault_code, const char *fault_string) { xmlrpc_env tmp_env; xmlrpc_env fault; xmlrpc_mem_block *output; xmlrpc_env_init (&tmp_env); xmlrpc_env_init (&fault); output = xmlrpc_mem_block_new (&tmp_env, 0); XMLRPC_FAIL_IF_FAULT (&tmp_env); xmlrpc_env_set_fault (&fault, fault_code, (char *) fault_string); xmlrpc_serialize_fault (&tmp_env, output, &fault); XMLRPC_FAIL_IF_FAULT (&tmp_env); return output; cleanup: return NULL; } /* serialize_fault */
static xmlrpc_value * you_find_latest_version (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { RCWorld *world = (RCWorld *) user_data; char *name = NULL; gboolean subscribed_only; LatestVersionInfo info; xmlrpc_value *result = NULL; xmlrpc_parse_value (env, param_array, "(sb)", &name, &subscribed_only); XMLRPC_FAIL_IF_FAULT (env); info.world = world; info.patch = NULL; info.installed_patch = NULL; info.subscribed_only = subscribed_only; rc_world_multi_foreach_patch_by_name (RC_WORLD_MULTI (world), name, RC_CHANNEL_SYSTEM, find_latest_installed_version, &info); rc_world_multi_foreach_patch_by_name (RC_WORLD_MULTI (world), name, RC_CHANNEL_NON_SYSTEM, find_latest_version, &info); if (!info.patch) { if (info.installed_patch) { /* No version in a channel newer than what is on the system. */ xmlrpc_env_set_fault (env, RCD_RPC_FAULT_PACKAGE_IS_NEWEST, "Installed version is newer than the " "newest available version"); } else { /* Can't find a patch by that name at all. */ xmlrpc_env_set_fault (env, RCD_RPC_FAULT_PACKAGE_NOT_FOUND, "Couldn't find patch"); } return NULL; } result = rc_you_patch_to_xmlrpc (info.patch, env); cleanup: if (env->fault_occurred) return NULL; return result; }
static xmlrpc_value * service_set_url (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { char *service_identifier; char *old_url, *new_url; RCWorldService *service; xmlrpc_parse_value (env, param_array, "(ss)", &service_identifier, &new_url); XMLRPC_FAIL_IF_FAULT (env); service = service_lookup (service_identifier); if (!service) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to unmount service for '%s'", service_identifier); goto cleanup; } old_url = service->url; service->url = g_strdup (new_url); /* FIXME: This is wrong. rc_world_refresh () returns pending only if refresh has not completed yet. Pending needs to be unref'ed when we're done with it as well. It's not a big deal right now as nothing actually calls this anymore. */ if (!rc_world_refresh (RC_WORLD (service))) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to change mirrors for '%s'", service->name); g_free (service->url); service->url = old_url; goto cleanup; } g_free (old_url); rcd_services_save (); cleanup: if (env->fault_occurred) return NULL; return xmlrpc_build_value (env, "i", 0); }
static void get_priv_cb (RCDPrivileges priv, const char *priv_name, gpointer user_data) { struct GetPrivInfo *info = user_data; xmlrpc_value *value; value = xmlrpc_build_value (info->env, "s", priv_name); xmlrpc_array_append_item (info->env, info->array, value); XMLRPC_FAIL_IF_FAULT (info->env); cleanup: xmlrpc_DECREF (value); }
static void notify_port_change (int port) { xmlrpc_env env; xmlrpc_value *value; xmlrpc_env_init (&env); value = xmlrpc_build_value (&env, "(i)", port); XMLRPC_FAIL_IF_FAULT (&env); rcd_xmlrpc_client_foreach_host (TRUE, "rcserver.machine.updatePort", notify_host_cb, NULL, value); xmlrpc_DECREF (value); cleanup: xmlrpc_env_clean (&env); }
static xmlrpc_value * service_get_mirrors (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { char *service_identifier; RCWorldMulti *multi; RCWorldService *service; struct GetAllInfo info; xmlrpc_parse_value (env, param_array, "(s)", &service_identifier); XMLRPC_FAIL_IF_FAULT (env); multi = RC_WORLD_MULTI (rc_get_world ()); service = service_lookup (service_identifier); if (!service || !g_type_is_a (G_TYPE_FROM_INSTANCE (service), RCD_TYPE_WORLD_REMOTE)) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to find service '%s'", service_identifier); goto cleanup; } info.env = env; info.array = xmlrpc_build_value (env, "()"); info.failed = FALSE; rcd_world_remote_foreach_mirror (RCD_WORLD_REMOTE (service), add_mirror_cb, &info); cleanup: if (env->fault_occurred) return NULL; return info.array; }
static xmlrpc_value * rcd_mirror_to_xmlrpc (RCDMirror *mirror, xmlrpc_env *env) { xmlrpc_value *value; g_return_val_if_fail (mirror != NULL, NULL); value = xmlrpc_struct_new (env); XMLRPC_FAIL_IF_FAULT (env); if (mirror->name && *mirror->name) RCD_XMLRPC_STRUCT_SET_STRING (env, value, "name", mirror->name); if (mirror->location && *mirror->location) RCD_XMLRPC_STRUCT_SET_STRING (env, value, "location", mirror->location); if (mirror->url && *mirror->url) RCD_XMLRPC_STRUCT_SET_STRING (env, value, "url", mirror->url); if (mirror->ftp && *mirror->ftp) RCD_XMLRPC_STRUCT_SET_STRING (env, value, "ftp", mirror->ftp); if (mirror->contact && *mirror->contact) RCD_XMLRPC_STRUCT_SET_STRING (env, value, "contact", mirror->contact); cleanup: if (env->fault_occurred) { if (value) xmlrpc_DECREF (value); return NULL; } return value; }
static void get_all_cb (RCDIdentity *id, gpointer user_data) { struct GetAllInfo *info = user_data; char *auth_str; xmlrpc_value *value; auth_str = rcd_privileges_to_string (id->privileges); value = xmlrpc_build_value (info->env, "(ss)", id->username, auth_str); g_free (auth_str); xmlrpc_array_append_item (info->env, info->array, value); XMLRPC_FAIL_IF_FAULT (info->env); cleanup: xmlrpc_DECREF (value); }
static xmlrpc_value * users_has_privilege (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { char *privilege; xmlrpc_value *result = NULL; RCDRPCMethodData *method_data; xmlrpc_parse_value (env, param_array, "(s)", &privilege); XMLRPC_FAIL_IF_FAULT (env); method_data = rcd_rpc_get_method_data (); result = xmlrpc_build_value ( env, "i", rcd_identity_approve_action (method_data->identity, rcd_privileges_from_string (privilege))); cleanup: if (env->fault_occurred) return NULL; else return result; } /* users_has_privilege */
static gboolean add_service_cb (RCWorld *subworld, gpointer user_data) { RCWorldService *service = RC_WORLD_SERVICE (subworld); ServiceInfo *info = user_data; xmlrpc_value *xmlrpc_service; xmlrpc_service = xmlrpc_struct_new (info->env); XMLRPC_FAIL_IF_FAULT (info->env); RCD_XMLRPC_STRUCT_SET_STRING (info->env, xmlrpc_service, "url", service->url); if (service->name) { RCD_XMLRPC_STRUCT_SET_STRING (info->env, xmlrpc_service, "name", service->name); } if (service->unique_id) { RCD_XMLRPC_STRUCT_SET_STRING (info->env, xmlrpc_service, "id", service->unique_id); } RCD_XMLRPC_STRUCT_SET_INT (info->env, xmlrpc_service, "is_sticky", service->is_sticky); RCD_XMLRPC_STRUCT_SET_INT (info->env, xmlrpc_service, "is_invisible", service->is_invisible); RCD_XMLRPC_STRUCT_SET_INT (info->env, xmlrpc_service, "is_singleton", service->is_singleton); if (g_type_is_a (G_TYPE_FROM_INSTANCE (service), RCD_TYPE_WORLD_REMOTE)) { RCDWorldRemote *remote = RCD_WORLD_REMOTE (service); if (remote->distro) { RCD_XMLRPC_STRUCT_SET_STRING (info->env, xmlrpc_service, "distro_name", rc_distro_get_name (remote->distro)); RCD_XMLRPC_STRUCT_SET_STRING (info->env, xmlrpc_service, "distro_version", rc_distro_get_version (remote->distro)); RCD_XMLRPC_STRUCT_SET_STRING (info->env, xmlrpc_service, "distro_target", rc_distro_get_target (remote->distro)); } if (remote->contact_email) { RCD_XMLRPC_STRUCT_SET_STRING (info->env, xmlrpc_service, "contact_email", remote->contact_email); } RCD_XMLRPC_STRUCT_SET_INT (info->env, xmlrpc_service, "premium_service", remote->premium_service); } xmlrpc_array_append_item (info->env, info->result, xmlrpc_service); XMLRPC_FAIL_IF_FAULT (info->env); xmlrpc_DECREF (xmlrpc_service); cleanup: if (info->env->fault_occurred) return FALSE; return TRUE; }
static xmlrpc_value * transaction_xml (xmlrpc_env *env, RCDTransaction *transaction, gboolean successful, const char *message) { xmlrpc_value *xtrans; xmlrpc_value *xmanifests; RCPackageSList *iter; /* Common part for all logs */ xtrans = xmlrpc_struct_new (env); XMLRPC_FAIL_IF_FAULT (env); if (transaction->id) { RCD_XMLRPC_STRUCT_SET_STRING (env, xtrans, "trid", transaction->id); XMLRPC_FAIL_IF_FAULT (env); } RCD_XMLRPC_STRUCT_SET_INT (env, xtrans, "endtime", time (NULL)); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING (env, xtrans, "client", transaction->client_id); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING (env, xtrans, "version", transaction->client_version); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_INT (env, xtrans, "status", successful ? 1 : 0); XMLRPC_FAIL_IF_FAULT (env); if (message) { RCD_XMLRPC_STRUCT_SET_STRING (env, xtrans, "message", message); XMLRPC_FAIL_IF_FAULT (env); } /* Transaction part */ RCD_XMLRPC_STRUCT_SET_STRING (env, xtrans, "log_type", "package"); XMLRPC_FAIL_IF_FAULT (env); if (transaction->rollback) { RCD_XMLRPC_STRUCT_SET_INT (env, xtrans, "rollback", 1); XMLRPC_FAIL_IF_FAULT (env); } if (transaction->flags & RCD_TRANSACTION_FLAGS_DRY_RUN) { RCD_XMLRPC_STRUCT_SET_INT (env, xtrans, "dry_run", 1); XMLRPC_FAIL_IF_FAULT (env); } if (transaction->flags & RCD_TRANSACTION_FLAGS_DOWNLOAD_ONLY) { RCD_XMLRPC_STRUCT_SET_INT (env, xtrans, "preposition", 1); XMLRPC_FAIL_IF_FAULT (env); } xmanifests = xmlrpc_build_value (env, "()"); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_struct_set_value (env, xtrans, "packages", xmanifests); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_DECREF (xmanifests); for (iter = transaction->install_packages; iter; iter = iter->next) { RCPackage *p = iter->data; RCPackage *sys_pkg; const char *action; xmlrpc_value *xmanifest; sys_pkg = rc_world_find_installed_version (rc_get_world (), p); if (sys_pkg) action = "update"; else action = "install"; xmanifest = manifest_xml_node (env, p, sys_pkg, action); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_array_append_item (env, xmanifests, xmanifest); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_DECREF (xmanifest); } for (iter = transaction->remove_packages; iter; iter = iter->next) { RCPackage *p = iter->data; xmlrpc_value *xmanifest; xmanifest = manifest_xml_node (env, p, NULL, "remove"); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_array_append_item (env, xmanifests, xmanifest); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_DECREF (xmanifest); } cleanup: return xtrans; } /* transaction_xml */
static xmlrpc_value * manifest_xml_node(xmlrpc_env *env, RCPackage *new_pkg, RCPackage *old_pkg, const char *action) { xmlrpc_value *xmanifest; xmlrpc_value *xpkg; #if 0 RCPackageUpdate *update; #endif xmanifest = xmlrpc_struct_new (env); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING ( env, xmanifest, "bid", new_pkg->channel ? rc_channel_get_id (new_pkg->channel) : ""); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING( env, xmanifest, "action", action); XMLRPC_FAIL_IF_FAULT (env); xpkg = xmlrpc_struct_new (env); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_struct_set_value (env, xmanifest, "package", xpkg); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_DECREF (xpkg); RCD_XMLRPC_STRUCT_SET_STRING( env, xpkg, "name", g_quark_to_string (new_pkg->spec.nameq)); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_INT( env, xpkg, "epoch", new_pkg->spec.epoch); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING( env, xpkg, "version", new_pkg->spec.version); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING( env, xpkg, "release", new_pkg->spec.release); XMLRPC_FAIL_IF_FAULT (env); #if 0 update = rc_package_get_latest_update (new_pkg); if (update) { RCD_XMLRPC_STRUCT_SET_INT( env, xpkg, "size", update->package_size); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_INT( env, xpkg, "hid", update->hid); XMLRPC_FAIL_IF_FAULT (env); if (new_pkg->channel) { RCD_XMLRPC_STRUCT_SET_STRING( env, xpkg, "channel_id", rc_channel_get_id (new_pkg->channel)); XMLRPC_FAIL_IF_FAULT (env); } if (update->package_url) { RCD_XMLRPC_STRUCT_SET_STRING( env, xpkg, "url", update->package_url); XMLRPC_FAIL_IF_FAULT (env); } } #endif if (old_pkg) { xpkg = xmlrpc_struct_new (env); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_struct_set_value (env, xmanifest, "oldpackage", xpkg); XMLRPC_FAIL_IF_FAULT (env); xmlrpc_DECREF (xpkg); RCD_XMLRPC_STRUCT_SET_STRING( env, xpkg, "name", g_quark_to_string (new_pkg->spec.nameq)); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_INT( env, xpkg, "epoch", old_pkg->spec.epoch); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING( env, xpkg, "version", old_pkg->spec.version); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_SET_STRING( env, xpkg, "release", old_pkg->spec.release); XMLRPC_FAIL_IF_FAULT (env); } cleanup: return xmanifest; } /* manifest_xml_node */
static xmlrpc_value * users_update (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { char *username, *password, *privileges; RCDRPCMethodData *method_data; RCDPrivileges req_priv; gboolean is_superuser; RCDIdentity *id = NULL; gboolean success = FALSE; xmlrpc_value *ret_value = NULL; xmlrpc_parse_value (env, param_array, "(sss)", &username, &password, &privileges); XMLRPC_FAIL_IF_FAULT (env); if (! rcd_identity_well_formed_username (username)) goto cleanup; if (! rcd_identity_well_formed_password (password) && strcmp (password, "-*-unchanged-*-")) goto cleanup; method_data = rcd_rpc_get_method_data (); req_priv = rcd_privileges_from_string ("superuser"); is_superuser = rcd_identity_approve_action (method_data->identity, req_priv); if (!is_superuser && strcmp (method_data->identity->username, username)) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_PERMISSION_DENIED, "User '%s' may not change this user", method_data->identity->username); goto cleanup; } id = rcd_identity_new (); id->username = g_strdup (username); if (strcmp (password, "-*-unchanged-*-")) id->password = g_strdup (password); else id->password = NULL; if (strcmp (privileges, "-*-unchanged-*-")) { RCDPrivileges new_privs; new_privs = rcd_privileges_from_string (privileges); if (new_privs != method_data->identity->privileges && !is_superuser) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_PERMISSION_DENIED, "User '%s' may not change user " "privileges", method_data->identity->username); goto cleanup; } id->privileges = rcd_privileges_from_string (privileges); } else id->privileges = RCD_PRIVILEGES_UNCHANGED; success = rcd_identity_update (id); cleanup: if (! env->fault_occurred) { ret_value = xmlrpc_build_value (env, "i", success ? 1 : 0); if (env->fault_occurred) ret_value = NULL; } rcd_identity_free (id); return ret_value; }
static xmlrpc_value * service_activate (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { xmlrpc_value *activation_info; char *activation_code; char *email = NULL, *service_identifier = NULL, *alias = NULL; RCWorldService *service; char *err_msg; xmlrpc_parse_value (env, param_array, "(V)", &activation_info); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_GET_STRING (env, activation_info, "activation_code", activation_code); if (xmlrpc_struct_has_key (env, activation_info, "email")) { RCD_XMLRPC_STRUCT_GET_STRING (env, activation_info, "email", email); } if (xmlrpc_struct_has_key (env, activation_info, "alias")) { RCD_XMLRPC_STRUCT_GET_STRING (env, activation_info, "alias", alias); } if (xmlrpc_struct_has_key (env, activation_info, "service")) { RCD_XMLRPC_STRUCT_GET_STRING (env, activation_info, "service", service_identifier); service = service_lookup (service_identifier); if (!service || !g_type_is_a (G_TYPE_FROM_INSTANCE (service), RCD_TYPE_WORLD_REMOTE)) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to find service '%s'", service_identifier); goto cleanup; } } else { service = NULL; if (rc_world_multi_foreach_subworld_by_type ( RC_WORLD_MULTI (rc_get_world ()), RCD_TYPE_WORLD_REMOTE, get_singleton_remote_cb, &service) < 0) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "You must specify a specific service"); goto cleanup; } } if (!rcd_world_remote_activate (RCD_WORLD_REMOTE (service), activation_code, email, alias, &err_msg)) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_CANT_ACTIVATE, "%s", err_msg); g_free (err_msg); goto cleanup; } cleanup: if (env->fault_occurred) return NULL; return xmlrpc_build_value (env, "i", 0); }