Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/proxy.c

    r19ac9c5 r701acdd4  
    2121 */
    2222
     23/* this is a little piece of code to handle proxy connection */
     24/* it is intended to : 1st handle http proxy, using the CONNECT command
     25 , 2nd provide an easy way to add socks support */
     26
    2327#define BITLBEE_CORE
    2428#include <stdio.h>
     
    4246#include "proxy.h"
    4347
     48#define GAIM_READ_COND  (G_IO_IN | G_IO_HUP | G_IO_ERR)
     49#define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)
     50#define GAIM_ERR_COND   (G_IO_HUP | G_IO_ERR | G_IO_NVAL)
     51
    4452char proxyhost[128] = "";
    4553int proxyport = 0;
     
    4957
    5058struct PHB {
    51         b_event_handler func, proxy_func;
     59        GaimInputFunction func, proxy_func;
    5260        gpointer data, proxy_data;
    5361        char *host;
     
    5664        gint inpa;
    5765};
     66
     67typedef struct _GaimIOClosure {
     68        GaimInputFunction function;
     69        guint result;
     70        gpointer data;
     71} GaimIOClosure;
    5872
    5973
     
    7892}
    7993
    80 static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition cond)
     94static void gaim_io_destroy(gpointer data)
     95{
     96        g_free(data);
     97}
     98
     99static gboolean gaim_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data)
     100{
     101        GaimIOClosure *closure = data;
     102        GaimInputCondition gaim_cond = 0;
     103
     104        if (condition & GAIM_READ_COND)
     105                gaim_cond |= GAIM_INPUT_READ;
     106        if (condition & GAIM_WRITE_COND)
     107                gaim_cond |= GAIM_INPUT_WRITE;
     108//      if (condition & GAIM_ERR_COND)
     109//              fprintf( stderr, "ERROR! fd=%d\n", g_io_channel_unix_get_fd( source ) );
     110
     111        closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond);
     112
     113        return TRUE;
     114}
     115
     116static void gaim_io_connected(gpointer data, gint source, GaimInputCondition cond)
    81117{
    82118        struct PHB *phb = data;
     
    88124        if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
    89125                closesocket(source);
    90                 b_event_remove(phb->inpa);
     126                gaim_input_remove(phb->inpa);
    91127                if( phb->proxy_func )
    92128                        phb->proxy_func(phb->proxy_data, -1, GAIM_INPUT_READ);
     
    95131                        g_free(phb);
    96132                }
    97                 return FALSE;
     133                return;
    98134        }
    99135#endif
    100136        sock_make_blocking(source);
    101         b_event_remove(phb->inpa);
     137        gaim_input_remove(phb->inpa);
    102138        if( phb->proxy_func )
    103139                phb->proxy_func(phb->proxy_data, source, GAIM_INPUT_READ);
     
    106142                g_free(phb);
    107143        }
    108        
    109         return FALSE;
    110144}
    111145
     
    126160
    127161        sock_make_nonblocking(fd);
    128        
    129         event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port, fd);
    130        
     162
    131163        if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) {
    132164                if (sockerr_again()) {
    133                         phb->inpa = b_input_add(fd, GAIM_INPUT_WRITE, gaim_io_connected, phb);
     165                        phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, gaim_io_connected, phb);
    134166                        phb->fd = fd;
    135167                } else {
     
    149181#define HTTP_GOODSTRING2 "HTTP/1.1 200 Connection established"
    150182
    151 static gboolean http_canread(gpointer data, gint source, b_input_condition cond)
     183static void http_canread(gpointer data, gint source, GaimInputCondition cond)
    152184{
    153185        int nlc = 0;
     
    156188        char inputline[8192];
    157189
    158         b_event_remove(phb->inpa);
     190        gaim_input_remove(phb->inpa);
    159191
    160192        while ((pos < sizeof(inputline)-1) && (nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) {
     
    171203                g_free(phb->host);
    172204                g_free(phb);
    173                 return FALSE;
     205                return;
    174206        }
    175207
     
    178210        g_free(phb->host);
    179211        g_free(phb);
    180        
    181         return FALSE;
    182 }
    183 
    184 static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond)
     212        return;
     213}
     214
     215static void http_canwrite(gpointer data, gint source, GaimInputCondition cond)
    185216{
    186217        char cmd[384];
     
    189220        int error = ETIMEDOUT;
    190221        if (phb->inpa > 0)
    191                 b_event_remove(phb->inpa);
     222                gaim_input_remove(phb->inpa);
    192223        len = sizeof(error);
    193224        if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
     
    196227                g_free(phb->host);
    197228                g_free(phb);
    198                 return FALSE;
     229                return;
    199230        }
    200231        sock_make_blocking(source);
     
    207238                g_free(phb->host);
    208239                g_free(phb);
    209                 return FALSE;
     240                return;
    210241        }
    211242
     
    222253                        g_free(phb->host);
    223254                        g_free(phb);
    224                         return FALSE;
     255                        return;
    225256                }
    226257        }
     
    232263                g_free(phb->host);
    233264                g_free(phb);
    234                 return FALSE;
    235         }
    236 
    237         phb->inpa = b_input_add(source, GAIM_INPUT_READ, http_canread, phb);
    238        
    239         return FALSE;
     265                return;
     266        }
     267
     268        phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, http_canread, phb);
    240269}
    241270
     
    253282/* Connecting to SOCKS4 proxies */
    254283
    255 static gboolean s4_canread(gpointer data, gint source, b_input_condition cond)
     284static void s4_canread(gpointer data, gint source, GaimInputCondition cond)
    256285{
    257286        unsigned char packet[12];
    258287        struct PHB *phb = data;
    259288
    260         b_event_remove(phb->inpa);
     289        gaim_input_remove(phb->inpa);
    261290
    262291        memset(packet, 0, sizeof(packet));
     
    265294                g_free(phb->host);
    266295                g_free(phb);
    267                 return FALSE;
     296                return;
    268297        }
    269298
     
    272301        g_free(phb->host);
    273302        g_free(phb);
    274        
    275         return FALSE;
    276 }
    277 
    278 static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
     303}
     304
     305static void s4_canwrite(gpointer data, gint source, GaimInputCondition cond)
    279306{
    280307        unsigned char packet[12];
     
    284311        int error = ETIMEDOUT;
    285312        if (phb->inpa > 0)
    286                 b_event_remove(phb->inpa);
     313                gaim_input_remove(phb->inpa);
    287314        len = sizeof(error);
    288315        if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
     
    291318                g_free(phb->host);
    292319                g_free(phb);
    293                 return FALSE;
     320                return;
    294321        }
    295322        sock_make_blocking(source);
     
    301328                g_free(phb->host);
    302329                g_free(phb);
    303                 return FALSE;
     330                return;
    304331        }
    305332
     
    318345                g_free(phb->host);
    319346                g_free(phb);
    320                 return FALSE;
    321         }
    322 
    323         phb->inpa = b_input_add(source, GAIM_INPUT_READ, s4_canread, phb);
    324        
    325         return FALSE;
     347                return;
     348        }
     349
     350        phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s4_canread, phb);
    326351}
    327352
     
    339364/* Connecting to SOCKS5 proxies */
    340365
    341 static gboolean s5_canread_again(gpointer data, gint source, b_input_condition cond)
     366static void s5_canread_again(gpointer data, gint source, GaimInputCondition cond)
    342367{
    343368        unsigned char buf[512];
    344369        struct PHB *phb = data;
    345370
    346         b_event_remove(phb->inpa);
     371        gaim_input_remove(phb->inpa);
    347372
    348373        if (read(source, buf, 10) < 10) {
     
    351376                g_free(phb->host);
    352377                g_free(phb);
    353                 return FALSE;
     378                return;
    354379        }
    355380        if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
     
    358383                g_free(phb->host);
    359384                g_free(phb);
    360                 return FALSE;
     385                return;
    361386        }
    362387
     
    364389        g_free(phb->host);
    365390        g_free(phb);
    366        
    367         return FALSE;
     391        return;
    368392}
    369393
     
    373397        struct PHB *phb = data;
    374398        int hlen = strlen(phb->host);
    375        
     399
    376400        buf[0] = 0x05;
    377401        buf[1] = 0x01;          /* CONNECT */
     
    391415        }
    392416
    393         phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb);
    394 }
    395 
    396 static gboolean s5_readauth(gpointer data, gint source, b_input_condition cond)
     417        phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb);
     418}
     419
     420static void s5_readauth(gpointer data, gint source, GaimInputCondition cond)
    397421{
    398422        unsigned char buf[512];
    399423        struct PHB *phb = data;
    400424
    401         b_event_remove(phb->inpa);
     425        gaim_input_remove(phb->inpa);
    402426
    403427        if (read(source, buf, 2) < 2) {
     
    406430                g_free(phb->host);
    407431                g_free(phb);
    408                 return FALSE;
     432                return;
    409433        }
    410434
     
    414438                g_free(phb->host);
    415439                g_free(phb);
    416                 return FALSE;
     440                return;
    417441        }
    418442
    419443        s5_sendconnect(phb, source);
    420        
    421         return FALSE;
    422 }
    423 
    424 static gboolean s5_canread(gpointer data, gint source, b_input_condition cond)
     444}
     445
     446static void s5_canread(gpointer data, gint source, GaimInputCondition cond)
    425447{
    426448        unsigned char buf[512];
    427449        struct PHB *phb = data;
    428450
    429         b_event_remove(phb->inpa);
     451        gaim_input_remove(phb->inpa);
    430452
    431453        if (read(source, buf, 2) < 2) {
     
    434456                g_free(phb->host);
    435457                g_free(phb);
    436                 return FALSE;
     458                return;
    437459        }
    438460
     
    442464                g_free(phb->host);
    443465                g_free(phb);
    444                 return FALSE;
     466                return;
    445467        }
    446468
     
    457479                        g_free(phb->host);
    458480                        g_free(phb);
    459                         return FALSE;
     481                        return;
    460482                }
    461483
    462                 phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_readauth, phb);
     484                phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_readauth, phb);
    463485        } else {
    464486                s5_sendconnect(phb, source);
    465487        }
    466        
    467         return FALSE;
    468 }
    469 
    470 static gboolean s5_canwrite(gpointer data, gint source, b_input_condition cond)
     488}
     489
     490static void s5_canwrite(gpointer data, gint source, GaimInputCondition cond)
    471491{
    472492        unsigned char buf[512];
     
    476496        int error = ETIMEDOUT;
    477497        if (phb->inpa > 0)
    478                 b_event_remove(phb->inpa);
     498                gaim_input_remove(phb->inpa);
    479499        len = sizeof(error);
    480500        if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
     
    483503                g_free(phb->host);
    484504                g_free(phb);
    485                 return FALSE;
     505                return;
    486506        }
    487507        sock_make_blocking(source);
     
    505525                g_free(phb->host);
    506526                g_free(phb);
    507                 return FALSE;
    508         }
    509 
    510         phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread, phb);
    511        
    512         return FALSE;
     527                return;
     528        }
     529
     530        phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_canread, phb);
    513531}
    514532
     
    526544/* Export functions */
    527545
    528 int proxy_connect(const char *host, int port, b_event_handler func, gpointer data)
     546gint gaim_input_add(gint source, GaimInputCondition condition, GaimInputFunction function, gpointer data)
     547{
     548        GaimIOClosure *closure = g_new0(GaimIOClosure, 1);
     549        GIOChannel *channel;
     550        GIOCondition cond = 0;
     551       
     552        closure->function = function;
     553        closure->data = data;
     554       
     555        if (condition & GAIM_INPUT_READ)
     556                cond |= GAIM_READ_COND;
     557        if (condition & GAIM_INPUT_WRITE)
     558                cond |= GAIM_WRITE_COND;
     559       
     560        channel = g_io_channel_unix_new(source);
     561        closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
     562                                              gaim_io_invoke, closure, gaim_io_destroy);
     563       
     564        g_io_channel_unref(channel);
     565        return closure->result;
     566}
     567
     568void gaim_input_remove(gint tag)
     569{
     570        if (tag > 0)
     571                g_source_remove(tag);
     572}
     573
     574int proxy_connect(const char *host, int port, GaimInputFunction func, gpointer data)
    529575{
    530576        struct PHB *phb;
Note: See TracChangeset for help on using the changeset viewer.