certificate: implement certificate store
[siplcs.git] / src / miranda / miranda-transport.c
blob60d495498a83ba3627955bb69ea52a40869c21a6
1 /**
2 * @file miranda-transport.c
4 * pidgin-sipe
6 * Copyright (C) 2010-11 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <windows.h>
24 #include <stdio.h>
25 #include <glib.h>
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
31 #include "sipe-common.h"
32 #include "sipe-core.h"
33 #include "sipe-core-private.h"
34 #include "sipe-backend.h"
35 #include "sip-transport.h"
36 #include "sipe-nls.h"
38 #include "newpluginapi.h"
39 #include "m_protosvc.h"
40 #include "m_protoint.h"
41 #include "m_netlib.h"
42 #include "miranda-private.h"
44 #define MIRANDA_TRANSPORT ((struct sipe_transport_miranda *) conn)
45 #define SIPE_TRANSPORT_CONNECTION ((struct sipe_transport_connection *) transport)
47 #define BUFFER_SIZE_INCREMENT 4096
49 struct sipe_transport_miranda {
50 /* public part shared with core */
51 struct sipe_transport_connection public;
53 /* miranda private part */
54 transport_connected_cb *connected;
55 transport_input_cb *input;
56 transport_error_cb *error;
57 HANDLE fd;
58 struct sipe_miranda_sel_entry *inputhandler;
60 SIPPROTO *pr;
63 static void
64 miranda_sipe_input_cb(gpointer data,
65 SIPE_UNUSED_PARAMETER gint source,
66 SIPE_UNUSED_PARAMETER sipe_miranda_input_condition cond)
68 struct sipe_transport_miranda *transport = (struct sipe_transport_miranda *)data;
69 struct sipe_transport_connection *conn = SIPE_TRANSPORT_CONNECTION;
70 SIPPROTO *pr = transport->pr;
71 int len;
72 int readlen;
73 gboolean firstread = TRUE;
75 LOCK;
77 if (!transport->fd)
79 UNLOCK;
80 return;
83 do {
84 /* Increase input buffer size as needed */
85 if (conn->buffer_length < conn->buffer_used + BUFFER_SIZE_INCREMENT) {
86 conn->buffer_length += BUFFER_SIZE_INCREMENT;
87 conn->buffer = g_realloc(conn->buffer, conn->buffer_length);
88 SIPE_DEBUG_INFO("miranda_sipe_input_cb: new buffer length %" G_GSIZE_FORMAT,
89 conn->buffer_length);
92 /* Try to read as much as there is space left in the buffer */
93 /* minus 1 for the string terminator */
94 readlen = conn->buffer_length - conn->buffer_used - 1;
96 len = Netlib_Recv(transport->fd, conn->buffer + conn->buffer_used, readlen, MSG_NODUMP);
98 if (len == SOCKET_ERROR) {
99 SIPE_DEBUG_INFO("miranda_sipe_input_cb: read error");
100 if (transport)
102 transport->error(SIPE_TRANSPORT_CONNECTION, "Read error");
104 // /* FIXME: not sure if this is the right spot */
105 sipe_miranda_input_remove(transport->inputhandler);
106 transport->inputhandler = NULL;
109 UNLOCK;
110 return;
111 } else if (firstread && (len == 0)) {
112 SIPE_DEBUG_ERROR_NOFORMAT("miranda_sipe_input_cb: server has disconnected");
113 transport->error(SIPE_TRANSPORT_CONNECTION, "Server has disconnected");
114 UNLOCK;
115 return;
118 conn->buffer_used += len;
119 firstread = FALSE;
121 /* Equivalence indicates that there is possibly more data to read */
122 } while (len == readlen);
124 conn->buffer[conn->buffer_used] = '\0';
125 transport->input(conn);
126 UNLOCK;
129 static void
130 connected_callback(HANDLE fd, void* data, const gchar *reason)
132 struct sipe_transport_miranda *transport = (struct sipe_transport_miranda*)data;
133 SIPPROTO *pr = transport->pr;
135 LOCK;
136 if (!fd)
138 transport->error(SIPE_TRANSPORT_CONNECTION, reason);
139 } else {
140 transport->fd = fd;
141 transport->public.client_port = sipe_miranda_network_get_port_from_fd( transport->fd );
142 transport->inputhandler = sipe_miranda_input_add(transport->fd, SIPE_MIRANDA_INPUT_READ, miranda_sipe_input_cb, transport );
143 transport->connected(SIPE_TRANSPORT_CONNECTION);
145 UNLOCK;
148 struct sipe_transport_connection *
149 sipe_backend_transport_connect(struct sipe_core_public *sipe_public,
150 const sipe_connect_setup *setup)
152 struct sipe_transport_miranda *transport = g_new0(struct sipe_transport_miranda, 1);
153 SIPPROTO *pr = sipe_public->backend_private;
155 NETLIBOPENCONNECTION ncon = {0};
157 transport->public.type = setup->type;
158 transport->public.user_data = setup->user_data;
159 transport->connected = setup->connected;
160 transport->input = setup->input;
161 transport->error = setup->error;
162 transport->pr = pr;
164 sipe_miranda_connect(pr, setup->server_name, setup->server_port, (setup->type == SIPE_TRANSPORT_TLS), 5, connected_callback, transport);
166 return(SIPE_TRANSPORT_CONNECTION);
169 void sipe_backend_transport_disconnect(struct sipe_transport_connection *conn)
171 struct sipe_transport_miranda *transport = MIRANDA_TRANSPORT;
173 SIPE_DEBUG_INFO("Disconnecting transport <%08x>", transport);
175 if (!transport) return;
177 Netlib_CloseHandle(transport->fd);
178 transport->fd = NULL;
180 if (transport->inputhandler)
181 sipe_miranda_input_remove(transport->inputhandler);
183 g_free(transport->public.buffer);
184 g_free(transport);
187 void sipe_backend_transport_message(struct sipe_transport_connection *conn,
188 const gchar *buffer)
190 struct sipe_transport_miranda *transport = MIRANDA_TRANSPORT;
191 guint written = 0;
193 do {
194 int len = Netlib_Send(transport->fd, buffer + written, strlen(buffer + written), MSG_NODUMP);
196 if (len == SOCKET_ERROR) {
197 SIPE_DEBUG_INFO_NOFORMAT("sipe_backend_transport_message: error, exiting");
198 transport->error(SIPE_TRANSPORT_CONNECTION,
199 "Write error");
200 return;
203 written += len;
204 } while (written < strlen(buffer));
207 void sipe_backend_transport_flush(struct sipe_transport_connection *conn)
209 /* N/A */
213 Local Variables:
214 mode: c
215 c-file-style: "bsd"
216 indent-tabs-mode: t
217 tab-width: 8
218 End: