changeset 935:5e6ca3dd4d02

[gaim-migrate @ 945] yay. thanks bmiller committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Fri, 22 Sep 2000 10:16:40 +0000
parents e5da96def4bd
children 311b3f72e7b9
files libfaim/CHANGES libfaim/CHANGES.gaim libfaim/aim_conn.c libfaim/faim/aim.h src/buddy.c src/dialogs.c src/gaim.h
diffstat 7 files changed, 332 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/libfaim/CHANGES	Thu Sep 21 19:21:35 2000 +0000
+++ b/libfaim/CHANGES	Fri Sep 22 10:16:40 2000 +0000
@@ -1,6 +1,11 @@
 
 No release numbers
 ------------------
+ - Thu Sep 21 00:24:36 UTC 2000
+   - Add socks5 proxy support (not tested real well, worked the 
+       few times a tried).
+   - Added proxy support to faimtest.
+
  - Tue Sep 19 03:10:07 UTC 2000
    - Add aim_setuserinterests() and aim_setdirectoryinfo()
    - Add ICQ away status
--- a/libfaim/CHANGES.gaim	Thu Sep 21 19:21:35 2000 +0000
+++ b/libfaim/CHANGES.gaim	Fri Sep 22 10:16:40 2000 +0000
@@ -1,3 +1,8 @@
+
+Fri Sep 22 10:12:37 UTC 2000 EWarmenhoven
+	- yeah, libfaim does socks 5 proxying now. it may be fragile though,
+	  and the necessary call in gaim to get it to work isn't there yet.
+	  be patient. i just don't want to write the UI for it yet.
 
 Wed Sep 20 23:30:32 UTC 2000 EWarmenhoven
 	- libfaim does dir info now
--- a/libfaim/aim_conn.c	Thu Sep 21 19:21:35 2000 +0000
+++ b/libfaim/aim_conn.c	Fri Sep 22 10:16:40 2000 +0000
@@ -162,6 +162,154 @@
 }
 
 /*
+ * An extrememly quick and dirty SOCKS5 interface. 
+ */
+static int aim_proxyconnect(struct aim_session_t *sess, 
+			    char *host, unsigned short port,
+			    int *statusret)
+{
+  int fd = -1;
+
+  if (strlen(sess->socksproxy.server)) { /* connecting via proxy */
+    int i;
+    unsigned char buf[512];
+    struct sockaddr_in sa;
+    struct hostent *hp;
+    char *proxy;
+    unsigned short proxyport = 1080;
+
+    for(i=0;i<(int)strlen(sess->socksproxy.server);i++) {
+      if (sess->socksproxy.server[i] == ':') {
+	proxyport = atoi(&(sess->socksproxy.server[i+1]));
+	break;
+      }
+    }
+    proxy = (char *)malloc(i+1);
+    strncpy(proxy, sess->socksproxy.server, i);
+    proxy[i] = '\0';
+
+    if (!(hp = gethostbyname(proxy))) {
+      printf("proxyconnect: unable to resolve proxy name\n");
+      *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR);
+      return -1;
+    }
+    free(proxy);
+
+    memset(&sa.sin_zero, 0, 8);
+    sa.sin_port = htons(proxyport);
+    memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
+    sa.sin_family = hp->h_addrtype;
+  
+    fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
+    if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
+      printf("proxyconnect: unable to connect to proxy\n");
+      close(fd);
+      return -1;
+    }
+
+    i = 0;
+    buf[0] = 0x05; /* SOCKS version 5 */
+    if (strlen(sess->socksproxy.username)) {
+      buf[1] = 0x02; /* two methods */
+      buf[2] = 0x00; /* no authentication */
+      buf[3] = 0x02; /* username/password authentication */
+      i = 4;
+    } else {
+      buf[1] = 0x01;
+      buf[2] = 0x00;
+      i = 3;
+    }
+
+    if (write(fd, buf, i) < i) {
+      *statusret = errno;
+      close(fd);
+      return -1;
+    }
+
+    if (read(fd, buf, 2) < 2) {
+      *statusret = errno;
+      close(fd);
+      return -1;
+    }
+
+    if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
+      *statusret = EINVAL;
+      close(fd);
+      return -1;
+    }
+
+    /* check if we're doing username authentication */
+    if (buf[1] == 0x02) {
+      i  = aimutil_put8(buf, 0x01); /* version 1 */
+      i += aimutil_put8(buf+i, strlen(sess->socksproxy.username));
+      i += aimutil_putstr(buf+i, sess->socksproxy.username, strlen(sess->socksproxy.username));
+      i += aimutil_put8(buf+i, strlen(sess->socksproxy.password));
+      i += aimutil_putstr(buf+i, sess->socksproxy.password, strlen(sess->socksproxy.password));
+      if (write(fd, buf, i) < i) {
+	*statusret = errno;
+	close(fd);
+	return -1;
+      }
+      if (read(fd, buf, 2) < 2) {
+	*statusret = errno;
+	close(fd);
+	return -1;
+      }
+      if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
+	*statusret = EINVAL;
+	close(fd);
+	return -1;
+      }
+    }
+
+    i  = aimutil_put8(buf, 0x05);
+    i += aimutil_put8(buf+i, 0x01); /* CONNECT */
+    i += aimutil_put8(buf+i, 0x00); /* reserved */
+    i += aimutil_put8(buf+i, 0x03); /* address type: host name */
+    i += aimutil_put8(buf+i, strlen(host));
+    i += aimutil_putstr(buf+i, host, strlen(host));
+    i += aimutil_put16(buf+i, port);
+
+    if (write(fd, buf, i) < i) {
+      *statusret = errno;
+      close(fd);
+      return -1;
+    }
+    if (read(fd, buf, 10) < 10) {
+      *statusret = errno;
+      close(fd);
+      return -1;
+    }
+    if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
+      *statusret = EINVAL;
+      close(fd);
+      return -1;
+    }
+
+  } else { /* connecting directly */
+    struct sockaddr_in sa;
+    struct hostent *hp;
+
+    if (!(hp = gethostbyname(host))) {
+      *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR);
+      return -1;
+    }
+
+    memset(&sa.sin_zero, 0, 8);
+    sa.sin_port = htons(port);
+    memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
+    sa.sin_family = hp->h_addrtype;
+  
+    fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
+    if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
+      close(fd);
+      fd = -1;
+    }
+  }
+  return fd;
+}
+
+/*
  * aim_newconn(type, dest)
  *
  * Opens a new connection to the specified dest host of type type.
@@ -214,31 +362,19 @@
   strncpy(host, dest, i);
   host[i] = '\0';
 
-  hp = gethostbyname(host);
-  free(host);
-
-  if (hp == NULL) {
-    connstruct->status = (h_errno | AIM_CONN_STATUS_RESOLVERR);
+  if ((ret = aim_proxyconnect(sess, host, port, &connstruct->status)) < 0) {
+    connstruct->fd = -1;
+    connstruct->status = (errno | AIM_CONN_STATUS_CONNERR);
+    free(host);
     faim_mutex_unlock(&connstruct->active);
     return connstruct;
-  }
-
-  memset(&sa.sin_zero, 0, 8);
-  sa.sin_port = htons(port);
-  memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
-  sa.sin_family = hp->h_addrtype;
-  
-  connstruct->fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
-  ret = connect(connstruct->fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in));
-  if(ret < 0) {
-    connstruct->fd = -1;
-    connstruct->status = (errno | AIM_CONN_STATUS_CONNERR);
-    faim_mutex_unlock(&connstruct->active);
-    return connstruct;
-  }
+  } else
+    connstruct->fd = ret;
   
   faim_mutex_unlock(&connstruct->active);
 
+  free(host);
+
   return connstruct;
 }
 
@@ -372,6 +508,32 @@
   return 0;
 }
 
+/*
+ * Call this with your SOCKS5 proxy server parameters before
+ * the first call to aim_newconn().  If called with all NULL
+ * args, it will clear out a previously set proxy.  
+ *
+ * Set username and password to NULL if not applicable.
+ *
+ */
+faim_export void aim_setupproxy(struct aim_session_t *sess, char *server, char *username, char *password)
+{
+  /* clear out the proxy info */
+  if (!server || !strlen(server)) {
+    memset(sess->socksproxy.server, 0, sizeof(sess->socksproxy.server));
+    memset(sess->socksproxy.username, 0, sizeof(sess->socksproxy.username));
+    memset(sess->socksproxy.password, 0, sizeof(sess->socksproxy.password));
+    return;
+  }
+
+  strncpy(sess->socksproxy.server, server, sizeof(sess->socksproxy.server));
+  if (username && strlen(username)) 
+    strncpy(sess->socksproxy.username, username, sizeof(sess->socksproxy.username));
+  if (password && strlen(password))
+    strncpy(sess->socksproxy.password, password, sizeof(sess->socksproxy.password));
+  return;
+}
+
 faim_export void aim_session_init(struct aim_session_t *sess)
 {
   if (!sess)
--- a/libfaim/faim/aim.h	Thu Sep 21 19:21:35 2000 +0000
+++ b/libfaim/faim/aim.h	Fri Sep 22 10:16:40 2000 +0000
@@ -331,6 +331,12 @@
   faim_mutex_t snac_hash_locks[FAIM_SNAC_HASH_SIZE];
   u_long snac_nextid;
 
+  struct {
+    char server[128];
+    char username[128];
+    char password[128];
+  } socksproxy;
+
   struct aim_msgcookie_t *msgcookies;
 };
 
@@ -492,6 +498,7 @@
 faim_export int aim_conn_isready(struct aim_conn_t *);
 faim_export int aim_conn_setstatus(struct aim_conn_t *, int);
 faim_export void aim_session_init(struct aim_session_t *);
+faim_export void aim_setupproxy(struct aim_session_t *sess, char *server, char *username, char *password);
 
 /* aim_misc.c */
 
--- a/src/buddy.c	Thu Sep 21 19:21:35 2000 +0000
+++ b/src/buddy.c	Fri Sep 22 10:16:40 2000 +0000
@@ -1045,6 +1045,30 @@
 	show_add_group();
 }
 
+static void im_callback(GtkWidget *widget, GtkTree *tree)
+{
+	GList *i;
+	struct buddy *b = NULL;
+	struct conversation *c;
+	i = GTK_TREE_SELECTION(tree);
+	if (i) {
+		b = gtk_object_get_user_data(GTK_OBJECT(i->data));
+        } else {
+		show_im_dialog();
+		return;
+        }
+	if (!b->name)
+		return;
+
+        c = find_conversation(b->name);
+	if (c == NULL) {
+		c = new_conversation(b->name);
+	} else {
+		gdk_window_raise(c->window->window);
+	}
+}
+	
+
 static void info_callback(GtkWidget *widget, GtkTree *tree)
 {
 	GList *i;
@@ -1053,6 +1077,7 @@
 	if (i) {
 		b = gtk_object_get_user_data(GTK_OBJECT(i->data));
         } else {
+		show_info_dialog();
 		return;
         }
 	if (!b->name)
@@ -1771,7 +1796,7 @@
 		gtk_box_pack_start(GTK_BOX(imchatbox), chatbutton, TRUE, TRUE, 0);
 		gtk_container_border_width(GTK_CONTAINER(imchatbox), 10);
 
-		gtk_signal_connect(GTK_OBJECT(imbutton), "clicked", GTK_SIGNAL_FUNC(show_im_dialog), buddies);
+		gtk_signal_connect(GTK_OBJECT(imbutton), "clicked", GTK_SIGNAL_FUNC(im_callback), buddies);
 		gtk_signal_connect(GTK_OBJECT(infobutton), "clicked", GTK_SIGNAL_FUNC(info_callback), buddies);
 		gtk_signal_connect(GTK_OBJECT(chatbutton), "clicked", GTK_SIGNAL_FUNC(chat_callback), buddies);
 
--- a/src/dialogs.c	Thu Sep 21 19:21:35 2000 +0000
+++ b/src/dialogs.c	Fri Sep 22 10:16:40 2000 +0000
@@ -71,6 +71,7 @@
 GdkColor fgcolor;
 
 static GtkWidget *imdialog = NULL; /*I only want ONE of these :) */
+static GtkWidget *infodialog = NULL;
 static GList *dialogwindows = NULL;
 static GtkWidget *exportdialog, *importdialog;
 static GtkWidget *aliasdlg = NULL;
@@ -332,6 +333,9 @@
         if (dest == imdialog)
 		imdialog = NULL;
 
+	if (dest == infodialog)
+		infodialog = NULL;
+
 	if (dest == exportdialog)
 		exportdialog = NULL;
 
@@ -369,6 +373,11 @@
                 destroy_dialog(NULL, imdialog);
                 imdialog = NULL;
         }
+
+	if (infodialog) {
+                destroy_dialog(NULL, infodialog);
+                infodialog = NULL;
+        }
         
         if (exportdialog) {
                 destroy_dialog(NULL, exportdialog);
@@ -639,6 +648,24 @@
         g_free(who);
 }
 
+static void do_info(GtkWidget *widget, GtkWidget *infoentry)
+{
+	char *who;
+	
+        who = g_strdup(normalize(gtk_entry_get_text(GTK_ENTRY(infoentry))));
+	destroy_dialog(NULL, infodialog);
+        infodialog = NULL;
+        
+        if (!strcasecmp(who, "")) {
+                g_free(who);
+		return;
+	}
+	
+	serv_get_info(who);
+
+	g_free(who);
+}
+
 void show_ee_dialog(int ee)
 {
 	GtkWidget *ok;
@@ -682,7 +709,7 @@
 	gtk_widget_show(eedialog);
 }
 
-void show_im_dialog(GtkWidget *w, GtkWidget *w2)
+void show_im_dialog()
 {
 	GtkWidget *button;
 	GtkWidget *imentry;
@@ -722,7 +749,7 @@
 		gtk_signal_connect(GTK_OBJECT(button), "clicked",
 				   GTK_SIGNAL_FUNC(destroy_dialog), imdialog);
 
-                label = gtk_label_new(_("IM who: "));
+                label = gtk_label_new(_("IM who:"));
                 gtk_box_pack_start(GTK_BOX(ebox), label, TRUE, TRUE, 10);
                 gtk_widget_show(label);
 
@@ -757,6 +784,81 @@
         gtk_widget_show(imdialog);
 }
 
+void show_info_dialog()
+{
+	GtkWidget *button;
+	GtkWidget *infoentry;
+        GtkWidget *vbox;
+        GtkWidget *ebox;
+        GtkWidget *bbox;
+        GtkWidget *label;
+	GtkWidget *frame;
+	GtkWidget *fbox;
+
+        if (!infodialog) {
+
+                infodialog = gtk_window_new(GTK_WINDOW_DIALOG);
+		gtk_window_set_wmclass(GTK_WINDOW(infodialog), "infodialog",
+                                       "Gaim");
+		gtk_widget_set_usize(infodialog, 255, 105);
+		gtk_container_border_width(GTK_CONTAINER(infodialog), 5);
+		gtk_window_set_policy(GTK_WINDOW(infodialog), FALSE, FALSE, TRUE);
+		gtk_widget_show(infodialog);
+
+		bbox = gtk_hbox_new(TRUE, 10);
+                vbox = gtk_vbox_new(FALSE, 5);
+                ebox = gtk_hbox_new(FALSE, 2);
+		fbox = gtk_vbox_new(TRUE, 10);
+
+		frame = gtk_frame_new(_("Get User Info"));
+	
+		infoentry = gtk_entry_new();
+
+		button = picture_button(infodialog, _("OK"), ok_xpm);
+		gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 5);	
+		gtk_signal_connect(GTK_OBJECT(button), "clicked",
+				   GTK_SIGNAL_FUNC(do_info), infoentry);
+
+		button = picture_button(infodialog, _("Cancel"), cancel_xpm);
+		gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 5);	
+		gtk_signal_connect(GTK_OBJECT(button), "clicked",
+				   GTK_SIGNAL_FUNC(destroy_dialog), infodialog);
+
+                label = gtk_label_new(_("User:"));
+                gtk_box_pack_start(GTK_BOX(ebox), label, TRUE, TRUE, 10);
+                gtk_widget_show(label);
+
+                gtk_box_pack_start(GTK_BOX(ebox), infoentry, TRUE, TRUE, 10);
+
+                gtk_box_pack_start(GTK_BOX(vbox), ebox, FALSE, FALSE, 5);
+                gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 5);
+
+                /* Handle closes right */
+		gtk_signal_connect(GTK_OBJECT(infoentry), "activate",
+				   GTK_SIGNAL_FUNC(do_info), infoentry);
+                gtk_signal_connect(GTK_OBJECT(infodialog), "destroy",
+                                   GTK_SIGNAL_FUNC(destroy_dialog), infodialog);
+
+		/* Finish up */
+                gtk_widget_show(ebox);
+                gtk_widget_show(infoentry);
+                gtk_widget_show(bbox);
+                gtk_widget_show(vbox);
+		gtk_widget_show(fbox);
+		gtk_widget_show(frame);
+		gtk_container_add(GTK_CONTAINER(frame), vbox);
+		gtk_box_pack_start(GTK_BOX(fbox), frame, FALSE, FALSE, 5);
+		gtk_window_set_title(GTK_WINDOW(infodialog), _("Gaim - Get User Info"));
+                gtk_container_add(GTK_CONTAINER(infodialog), fbox);
+                gtk_widget_grab_focus(infoentry);
+                gtk_widget_realize(infodialog);
+		
+		aol_icon(infodialog->window);
+
+        }
+        gtk_widget_show(infodialog);
+}
+
 
 /*------------------------------------------------------------------------*/
 /*  The dialog for adding buddies                                         */
--- a/src/gaim.h	Thu Sep 21 19:21:35 2000 +0000
+++ b/src/gaim.h	Fri Sep 22 10:16:40 2000 +0000
@@ -414,7 +414,7 @@
 #define TYPE_SIGNOFF   4
 #define TYPE_KEEPALIVE 5
 
-#define REVISION "gaim:$Revision: 940 $"
+#define REVISION "gaim:$Revision: 945 $"
 #define FLAPON "FLAPON\r\n\r\n"
 
 #define ROAST "Tic/Toc"
@@ -808,7 +808,8 @@
 extern void show_warn_dialog(char *);
 extern void do_error_dialog(char *, char *);
 extern void show_error_dialog(char *);
-extern void show_im_dialog(GtkWidget *, GtkWidget *);
+extern void show_im_dialog();
+extern void show_info_dialog();
 extern void show_add_buddy(char *, char *);
 extern void show_add_group();
 extern void show_add_perm();