/*- * $Id: rr-message-startrpy.c,v 1.9 2002/11/08 12:35:28 jonas Exp $ * * See the file LICENSE for redistribution information. * If you have not received a copy of the license, please contact CodeFactory * by email at info@codefactory.se, or on the web at http://www.codefactory.se/ * You may also write to: CodeFactory AB, SE-903 47, Umeå, Sweden. * * Copyright (c) 2002 Jonas Borgström * Copyright (c) 2002 Daniel Lundin * Copyright (c) 2002 CodeFactory AB. All rights reserved. */ #include #include #include #include static GObjectClass *parent_class = NULL; static void finalize (GObject *object); static RRFrame *get_frame (RRMessage *stat, gsize max_size); static gboolean process_frame (RRMessage *message, RRFrame *frame, GError **error); static void finalize (GObject *object) { RRMessageStartRpy *rpy = (RRMessageStartRpy *)object; if (rpy->uri) { g_free (rpy->uri); } if (rpy->piggyback) { g_free (rpy->piggyback); } if (rpy->channel_to_activate) rpy->channel_to_activate->disabled = FALSE; parent_class->finalize (object); } static void rr_message_startrpy_init (GObject *object) { RRMessage *msg = (RRMessage *)object; msg->type = RR_FRAME_TYPE_RPY; } static void rr_message_startrpy_class_init (GObjectClass *klass) { RRMessageClass *msg_class = (RRMessageClass *)klass; klass->finalize = finalize; msg_class->get_frame = get_frame; msg_class->process_frame = process_frame; parent_class = g_type_class_peek_parent (klass); } GType rr_message_startrpy_get_type (void) { static GType rr_type = 0; if (!rr_type) { static GTypeInfo type_info = { sizeof (RRMessageStartRpyClass), NULL, NULL, (GClassInitFunc) rr_message_startrpy_class_init, NULL, NULL, sizeof (RRMessageStartRpy), 16, (GInstanceInitFunc) rr_message_startrpy_init }; rr_type = g_type_register_static (RR_TYPE_MESSAGE, "RRMessageStartRpy", &type_info, 0); } return rr_type; } RRMessageStartRpy * rr_message_startrpy_new (const gchar *uri, const gchar *piggyback) { RRMessageStartRpy *rpy; rpy = g_object_new (RR_TYPE_MESSAGE_STARTRPY, NULL); if (uri) rpy->uri = g_strdup (uri); if (piggyback) rpy->piggyback = g_strdup (piggyback); return rpy; } static gboolean process_frame (RRMessage *message, RRFrame *frame, GError **error) { RRMessageStartRpy *rpy; RRConnection *conn; xmlDocPtr doc; xmlNodePtr node; gboolean ret; xmlChar *str; const gchar *data; gint len; g_return_val_if_fail (RR_IS_MESSAGE_STARTRPY (message), FALSE); g_return_val_if_fail (RR_IS_FRAME (frame), FALSE); g_return_val_if_fail (RR_IS_CHANNEL (message->channel), FALSE); g_return_val_if_fail (RR_IS_CONNECTION (message->channel->connection), FALSE); conn = message->channel->connection; rpy = RR_MESSAGE_STARTRPY (message); data = rr_frame_mime_get_body (frame); len = rr_frame_mime_get_body_size (frame); doc = xmlParseMemory (data, len); if (doc == NULL) { g_set_error (error, RR_ERROR, RR_BEEP_CODE_SYNTAX_ERROR, "Invalid start reply."); return FALSE; } node = xmlDocGetRootElement (doc); if (strcmp (node->name, "profile") != 0) goto err; if ((str = xmlGetProp (node, "uri")) == NULL) goto err; rpy->uri = g_strdup (str); xmlFree (str); /* Extract the piggyback data if it exists */ if (node->children) { xmlNode *child, *cdata_node = NULL; child = node->children; while (child) { if (child->type == XML_CDATA_SECTION_NODE && child->content) { cdata_node = child; break; } child = child->next; } if (cdata_node && child->content) rpy->piggyback = g_strdup (cdata_node->content); else if (node->children->type == XML_TEXT_NODE && node->children->content) rpy->piggyback = g_strdup (node->children->content); } ret = TRUE; goto end; err: g_set_error (error, RR_ERROR, RR_BEEP_CODE_PARAM_ERROR, RR_GERROR_DEFAULT_MESSAGE); ret = FALSE; end: xmlFreeDoc (doc); return ret; } static RRFrame * get_frame (RRMessage *message, gsize max_size) { RRMessageStartRpy *rpy = RR_MESSAGE_STARTRPY(message); RRFrame *frame; GString *str; g_assert (RR_IS_MESSAGE_STARTRPY (rpy)); g_assert (max_size > 0); str = g_string_new (NULL); if (rpy->piggyback) g_string_printf (str, RR_BEEP_MIME_HEADER " \r\n" " \r\n" " \r\n", rpy->uri, rpy->piggyback); else g_string_printf (str, RR_BEEP_MIME_HEADER "\r\n", rpy->uri); if (str->len > max_size) { g_string_free (str, TRUE); return NULL; } frame = rr_frame_new (RR_FRAME_TYPE_RPY, message->channel->id, FALSE, message->msgno, str->len, 0, str->str, TRUE); g_string_free (str, FALSE); return frame; }