added SSL support for POP using OpenSSL
[claws.git] / src / socket.c
index 9a1d8eb..4a8f73f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * 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
@@ -163,7 +163,7 @@ static gboolean is_nonblocking_mode(gint fd)
 
 gboolean sock_is_nonblocking_mode(SockInfo *sock)
 {
-       g_assert(sock);
+       g_return_val_if_fail(sock != NULL, FALSE);
 
        return is_nonblocking_mode(sock->sock);
 }
@@ -258,6 +258,7 @@ static gint sock_connect_by_getaddrinfo(const gchar *hostname, gushort      port)
 }
 #endif /* !INET6 */
 
+#if 0
 SockInfo *sock_connect_nb(const gchar *hostname, gushort port)
 {
        gint sock;
@@ -297,6 +298,7 @@ SockInfo *sock_connect_nb(const gchar *hostname, gushort port)
        sockinfo->state = CONN_ESTABLISHED;
        return sockinfo;
 }
+#endif
 
 SockInfo *sock_connect(const gchar *hostname, gushort port)
 {
@@ -391,10 +393,39 @@ gint sock_printf(SockInfo *sock, const gchar *format, ...)
        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);
+}
+
+#ifdef 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);
 }
 
@@ -414,14 +445,25 @@ gint fd_write(gint fd, const gchar *buf, gint len)
        return wrlen;
 }
 
-gint sock_read(SockInfo *sock, gchar *buf, gint len)
+#ifdef 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;
@@ -443,6 +485,100 @@ gint fd_read(gint fd, gchar *buf, gint len)
        return bp - buf;
 }
 
+#if USE_SSL
+gint ssl_gets(SSL *ssl, gchar *buf, gint len)
+{
+       gchar *buf2 = buf;
+       gboolean newline = FALSE;
+       gint n, count = 0;
+
+       if (--len < 1)
+               return -1;
+       while(len > 0 && !newline) {
+               *buf2 = '\0';
+               if((n = SSL_read(ssl, buf2, 1)) < 0)
+                       return -1;
+               if(*buf2 == '\n')
+                       newline = TRUE;
+               buf2 += n;
+               count += n;
+       }
+
+       *buf2 = '\0';
+       return n;
+}
+#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;
@@ -468,15 +604,16 @@ gint sock_peek(SockInfo *sock)
 
 gint sock_close(SockInfo *sock)
 {
-       gint rc;
+       gint ret;
 
        if (!sock)
                return 0;
 
-       rc = fd_close(sock->sock); 
+       ret = fd_close(sock->sock); 
        g_free(sock->hostname);
        g_free(sock);
-       return rc;
+
+       return ret;
 }
 
 gint fd_close(gint fd)
@@ -485,9 +622,9 @@ 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);