/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2001 Hiroyuki Yamamoto
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#endif
#include "socket.h"
+#if USE_SSL
+# include "ssl.h"
+#endif
#if USE_GIO
#error USE_GIO is currently not supported
gboolean sock_is_nonblocking_mode(SockInfo *sock)
{
- g_assert(sock);
+ g_return_val_if_fail(sock != NULL, FALSE);
return is_nonblocking_mode(sock->sock);
}
}
#endif /* !INET6 */
-SockInfo *sock_connect_nb(const gchar *hostname, gushort port)
-{
- gint sock;
- gint ret;
- SockInfo *sockinfo;
-
-#ifdef INET6
- if ((sock = sock_connect_by_getaddrinfo(hostname, port)) < 0)
- return NULL;
- if (set_nonblocking_mode(sock, TRUE) < 0) return NULL;
- ret = sock;
-#else
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("socket");
- return NULL;
- }
-
- if (set_nonblocking_mode(sock, TRUE) < 0) return NULL;
-
- ret = sock_connect_by_hostname(sock, hostname, port);
-
- if (ret < 0 && errno != EINPROGRESS) {
- if (errno != 0) perror("connect");
- close(sock);
- return NULL;
- }
-#endif /* INET6 */
-
- sockinfo = g_new0(SockInfo, 1);
- sockinfo->sock = sock;
- sockinfo->hostname = g_strdup(hostname);
- sockinfo->port = port;
- sockinfo->state = CONN_LOOKUPSUCCESS;
-
- if (ret < 0 && errno == EINPROGRESS) return sockinfo;
-
- sockinfo->state = CONN_ESTABLISHED;
- return sockinfo;
-}
-
SockInfo *sock_connect(const gchar *hostname, gushort port)
{
gint sock;
return sock_write(sock, buf, strlen(buf));
}
+gint sock_read(SockInfo *sock, gchar *buf, gint len)
+{
+ g_return_val_if_fail(sock != NULL, -1);
+
+#if USE_SSL
+ if (sock->ssl)
+ return ssl_read(sock->ssl, buf, len);
+#endif
+ return fd_read(sock->sock, buf, len);
+}
+
+gint fd_read(gint fd, gchar *buf, gint len)
+{
+ return read(fd, buf, len);
+}
+
+#if USE_SSL
+gint ssl_read(SSL *ssl, gchar *buf, gint len)
+{
+ return SSL_read(ssl, buf, len);
+}
+#endif
+
gint sock_write(SockInfo *sock, const gchar *buf, gint len)
{
g_return_val_if_fail(sock != NULL, -1);
+#if USE_SSL
+ if (sock->ssl)
+ return ssl_write(sock->ssl, buf, len);
+#endif
return fd_write(sock->sock, buf, len);
}
return wrlen;
}
-gint sock_read(SockInfo *sock, gchar *buf, gint len)
+#if USE_SSL
+gint ssl_write(SSL *ssl, const gchar *buf, gint len)
{
- g_return_val_if_fail(sock != NULL, -1);
+ gint n, wrlen = 0;
- return fd_read(sock->sock, buf, len);
+ while (len) {
+ n = SSL_write(ssl, buf, len);
+ if (n <= 0)
+ return -1;
+ len -= n;
+ wrlen += n;
+ buf += n;
+ }
+
+ return wrlen;
}
+#endif
-gint fd_read(gint fd, gchar *buf, gint len)
+gint fd_gets(gint fd, gchar *buf, gint len)
{
gchar *newline, *bp = buf;
gint n;
return bp - buf;
}
+#if USE_SSL
+gint ssl_gets(SSL *ssl, gchar *buf, gint len)
+{
+ gchar *newline, *bp = buf;
+ gint n;
+
+ if (--len < 1)
+ return -1;
+ do {
+ if ((n = SSL_peek(ssl, bp, len)) <= 0)
+ return -1;
+ if ((newline = memchr(bp, '\n', n)) != NULL)
+ n = newline - bp + 1;
+ if ((n = SSL_read(ssl, bp, n)) < 0)
+ return -1;
+ bp += n;
+ len -= n;
+ } while (!newline && len);
+
+ *bp = '\0';
+ return bp - buf;
+}
+#endif
+
+gint sock_gets(SockInfo *sock, gchar *buf, gint len)
+{
+ g_return_val_if_fail(sock != NULL, -1);
+
+#if USE_SSL
+ if (sock->ssl)
+ return ssl_gets(sock->ssl, buf, len);
+#endif
+ return fd_gets(sock->sock, buf, len);
+}
+
+gchar *fd_getline(gint fd)
+{
+ gchar buf[BUFFSIZE];
+ gchar *str = NULL;
+ gint len;
+ gulong size = 1;
+
+ while ((len = fd_gets(fd, buf, sizeof(buf))) > 0) {
+ size += len;
+ if (!str)
+ str = g_strdup(buf);
+ else {
+ str = g_realloc(str, size);
+ strcat(str, buf);
+ }
+ if (buf[len - 1] == '\n')
+ break;
+ }
+
+ return str;
+}
+
+#if USE_SSL
+gchar *ssl_getline(SSL *ssl)
+{
+ gchar buf[BUFFSIZE];
+ gchar *str = NULL;
+ gint len;
+ gulong size = 1;
+
+ while ((len = ssl_gets(ssl, buf, sizeof(buf))) > 0) {
+ size += len;
+ if (!str)
+ str = g_strdup(buf);
+ else {
+ str = g_realloc(str, size);
+ strcat(str, buf);
+ }
+ if (buf[len - 1] == '\n')
+ break;
+ }
+
+ return str;
+}
+#endif
+
+gchar *sock_getline(SockInfo *sock)
+{
+ g_return_val_if_fail(sock != NULL, NULL);
+
+#if USE_SSL
+ if (sock->ssl)
+ return ssl_getline(sock->ssl);
+#endif
+ return fd_getline(sock->sock);
+}
+
gint sock_puts(SockInfo *sock, const gchar *buf)
{
gint ret;
gint sock_close(SockInfo *sock)
{
- gint rc;
+ gint ret;
if (!sock)
return 0;
- rc = fd_close(sock->sock);
+#if USE_SSL
+ if (sock->ssl)
+ ssl_done_socket(sock);
+#endif
+ ret = fd_close(sock->sock);
g_free(sock->hostname);
g_free(sock);
- return rc;
+
+ return ret;
}
gint fd_close(gint fd)
}
gint sock_gdk_input_add(SockInfo *sock,
- GdkInputCondition condition,
- GdkInputFunction function,
- gpointer data)
+ GdkInputCondition condition,
+ GdkInputFunction function,
+ gpointer data)
{
g_return_val_if_fail(sock != NULL, -1);