Changeset 129

Show
Ignore:
Timestamp:
03/21/08 15:17:54 (4 years ago)
Author:
haze11
Message:

파일 송수신 보완

Location:
trunk/src
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/switchboard.c

    r126 r129  
    793793        } 
    794794        else if (cmd->param_count == 4 && !strcmp(cmd->params[2], "FILE") && \ 
    795                         !strncmp(cmd->params[3], "CANCEL", strlen("")) ) 
     795                        !strncmp(cmd->params[3], "CANCEL", strlen("CANCEL")) ) 
    796796        { 
    797797                /* file transfer cancelled */ 
  • trunk/src/xfer.c

    r126 r129  
    88#define NATEON_P2P_END_PORT      (6004) 
    99 
    10 static void 
    11 nateon_xfer_end(PurpleXfer *xfer); 
     10static void nateon_xfer_end(PurpleXfer *xfer); 
     11static ssize_t nateon_xfer_sock_write(NateonXferConnection *conn, const char *buf, size_t len); 
     12static void nateon_xfer_send_next(NateonXfer *nate_xfer); 
     13 
    1214static char* 
    1315generate_p2p_cookie(NateonSession *session) 
     
    5658 
    5759static void 
    58 nateon_xfer_sock_write_cb(gpointer data, gint source, PurpleInputCondition cond) 
    59 { 
    60         NateonXferConnection *conn = data; 
    61         int ret, writelen; 
    62  
    63         purple_debug_info("nateon", "write_cb\n"); 
    64         writelen = purple_circ_buffer_get_max_read(conn->tx_buf); 
    65  
    66         if (writelen == 0) { 
    67                 purple_input_remove(conn->tx_handler); 
    68                 conn->tx_handler = -1; 
    69                 return; 
    70         } 
    71  
    72         ret = write(conn->fd, conn->tx_buf->outptr, writelen); 
    73  
    74         if (ret < 0 && errno == EAGAIN) 
    75                 return; 
    76         else if (ret <= 0) { 
    77                 //nateon_servconn_got_error(servconn, NATEON_SERVCONN_ERROR_WRITE); 
    78                 purple_debug_info("nateon", "%s:%s\n", __FUNCTION__, "socket write error"); 
    79                 return; 
    80         } 
    81  
    82         purple_circ_buffer_mark_read(conn->tx_buf, ret); 
    83 } 
    84  
    85 static ssize_t 
    86 nateon_xfer_sock_write(NateonXferConnection *conn, const char *buf, size_t len) 
    87 { 
    88         ssize_t ret = 0; 
    89  
    90         g_return_val_if_fail(conn != NULL, 0); 
    91  
    92         if (conn->tx_handler == -1) { 
    93                 ret = write(conn->fd, buf, len); 
    94         } else { 
    95                 ret = -1; 
    96                 errno = EAGAIN; 
    97         } 
    98  
    99         if (ret < 0 && errno == EAGAIN) 
    100                 ret = 0; 
    101         if (ret < len) { 
    102                 if (conn->tx_handler == -1) 
    103                         conn->tx_handler = purple_input_add( 
    104                                         conn->fd, PURPLE_INPUT_WRITE, 
    105                                         nateon_xfer_sock_write_cb, conn); 
    106                 purple_circ_buffer_append(conn->tx_buf, buf + ret, len - ret); 
    107         } 
    108  
    109         if (ret == -1) 
    110         { 
    111                 purple_debug_info("nateon", "%s:%s\n", __FUNCTION__, "socket write error"); 
    112                 //nateon_servconn_got_error(servconn, NATEON_SERVCONN_ERROR_WRITE); 
    113         } 
    114  
    115         return ret; 
    116 } 
    117  
    118 static ssize_t nateon_xfer_send_data(NateonXfer *nate_xfer, const char *buf, size_t len); 
    119  
    120 static void 
    121 nateon_xfer_send_next(NateonXfer *nate_xfer) 
    122 { 
    123         NateonXferConnection *conn; 
    124         gchar *buf; 
    125         int cmd_len; 
    126  
    127         conn = &nate_xfer->conn; 
    128  
    129         if (nate_xfer->sent_len == purple_xfer_get_size(nate_xfer->prpl_xfer)) 
    130         { 
    131                 purple_input_remove(conn->tx_handler); 
    132                 conn->tx_handler = -1; 
    133                 return; 
    134         } 
    135         if (purple_xfer_get_size(nate_xfer->prpl_xfer)-nate_xfer->sent_len > NATEON_XFER_SEND_BUFFER_SIZE) 
    136         { 
    137                 nate_xfer->chunk_len = NATEON_XFER_SEND_BUFFER_SIZE; 
    138         } 
    139         else 
    140         { 
    141                 nate_xfer->chunk_len = purple_xfer_get_size(nate_xfer->prpl_xfer) - nate_xfer->sent_len; 
    142         } 
    143  
    144         buf = g_strdup_printf("FILE %d DATA %d\r\n", 
    145                         nate_xfer->send_data_trid, nate_xfer->chunk_len); 
    146         cmd_len = strlen(buf); 
    147         buf = g_realloc(buf, cmd_len + nate_xfer->chunk_len); 
    148         fread(buf + cmd_len, 1, nate_xfer->chunk_len, nate_xfer->local_fp); 
    149         nateon_xfer_send_data(nate_xfer, buf, cmd_len + nate_xfer->chunk_len); 
    150         g_free(buf); 
    151         nate_xfer->send_data_trid++; 
    152 } 
    153  
    154 static void 
    155 nateon_xfer_send_data_cb(gpointer data, gint source, PurpleInputCondition cond) 
    156 { 
    157         NateonXfer *nate_xfer = data; 
    158         NateonXferConnection *conn = &nate_xfer->conn; 
    159         int ret, writelen; 
    160  
    161         writelen = purple_circ_buffer_get_max_read(conn->tx_buf); 
    162  
    163         if (writelen == 0) 
    164         { 
    165                 purple_input_remove(conn->tx_handler); 
    166                 conn->tx_handler = -1; 
    167                 nate_xfer->sent_len += nate_xfer->chunk_len; 
    168                 nateon_xfer_send_next(nate_xfer); 
    169                 purple_xfer_set_bytes_sent(nate_xfer->prpl_xfer, nate_xfer->sent_len); 
    170                 purple_xfer_update_progress(nate_xfer->prpl_xfer); 
    171                 return; 
    172         } 
    173  
    174         ret = write(conn->fd, conn->tx_buf->outptr, writelen); 
    175  
    176         if (ret < 0 && errno == EAGAIN) 
    177                 return; 
    178         else if (ret <= 0) { 
    179                 //nateon_servconn_got_error(servconn, NATEON_SERVCONN_ERROR_WRITE); 
    180                 purple_debug_info("nateon", "%s:%s\n", __FUNCTION__, "socket write error"); 
    181                 purple_input_remove(conn->tx_handler); 
    182                 conn->tx_handler = -1; 
    183                 purple_xfer_cancel_remote(nate_xfer->prpl_xfer); 
    184                 return; 
    185         } 
    186  
    187         purple_circ_buffer_mark_read(conn->tx_buf, ret); 
    188 } 
    189  
    190 static ssize_t 
    191 nateon_xfer_send_data(NateonXfer *nate_xfer, const char *buf, size_t len) 
    192 { 
    193         ssize_t ret = 0; 
    194         NateonXferConnection *conn; 
    195  
    196         conn = &nate_xfer->conn; 
    197         if (conn->tx_handler == -1) 
    198         { 
    199                 ret = write(conn->fd, buf, len); 
    200         } 
    201         else 
    202         { 
    203                 ret = -1; 
    204                 errno = EAGAIN; 
    205         } 
    206  
    207         if (ret < 0 && errno == EAGAIN) 
    208                 ret = 0; 
    209         if (ret < len) 
    210         { 
    211                 if (conn->tx_handler == -1) 
    212                 { 
    213                         conn->tx_handler = purple_input_add( conn->fd, PURPLE_INPUT_WRITE, 
    214                                         nateon_xfer_send_data_cb, nate_xfer); 
    215                 } 
    216                 purple_circ_buffer_append(conn->tx_buf, buf + ret, len - ret); 
    217         } else if (ret == len) 
    218         { 
    219                 nate_xfer->sent_len += nate_xfer->chunk_len; 
    220                 purple_xfer_set_bytes_sent(nate_xfer->prpl_xfer, nate_xfer->sent_len); 
    221                 purple_xfer_update_progress(nate_xfer->prpl_xfer); 
    222                 nateon_xfer_send_next(nate_xfer); 
    223                 return ret; 
    224         } 
    225  
    226         if (ret == -1) 
    227         { 
    228                 purple_debug_info("nateon", "%s:%s\n", __FUNCTION__, "socket write error"); 
    229                 purple_xfer_cancel_remote(nate_xfer->prpl_xfer); 
    230                 //nateon_servconn_got_error(servconn, NATEON_SERVCONN_ERROR_WRITE); 
    231         } 
    232  
    233         return ret; 
    234  
    235 } 
    236  
    237 static void 
    23860nateon_xfer_process_p2p_cmd_receive(NateonXfer *xfer, char *cmd) 
    23961{ 
     
    361183        g_strfreev(split); 
    362184} 
     185 
    363186static gssize  
    364 nateon_xfer_read(guchar **buffer, PurpleXfer *xfer) 
     187nateon_xfer_sock_read(NateonXferConnection *conn, guchar **buffer) 
    365188{ 
    366189        NateonXfer *nate_xfer; 
    367         NateonXferConnection *conn; 
    368190        int len, cur_len; 
    369191        char buf[NATEON_BUF_LEN]; 
     
    373195        *buffer = NULL; 
    374196        buffer_len = 0; 
    375  
    376         nate_xfer = xfer->data; 
    377  
    378         if (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) { 
     197        nate_xfer = conn->nate_xfer; 
     198 
     199        if (purple_xfer_get_type(nate_xfer->prpl_xfer) == PURPLE_XFER_RECEIVE) { 
    379200                conn = &nate_xfer->conn; 
    380201         
     
    382203 
    383204                if (len <= 0) { 
    384                         if (nate_xfer->recv_len == purple_xfer_get_size(xfer)) { 
    385                                 gchar *buf; 
    386                                 purple_debug_info("nateon", "%s:%s\n", __FUNCTION__, "file transfer complete"); 
    387                                 purple_xfer_set_completed(xfer, TRUE); 
    388  
    389                                 /* Send FILE END to sender */ 
    390                                 buf = g_strdup_printf("ATHC 0 END N 0\r\n"); 
    391                                 nateon_xfer_sock_write(conn, buf, strlen(buf)); 
    392                                 g_free(buf); 
    393                                 return 0; 
    394                         } 
    395  
    396205                        if (len < 0 && errno == EAGAIN) { 
    397206                                return 0; 
     
    399208                                /* FIXME handle error */ 
    400209                                purple_debug_info("nateon", "%s:read_error\n", __FUNCTION__); 
    401                                 //purple_debug_error("nateon", "xfer_read read error, len: %d error: %s\n", len, strerror(errno)); 
    402210                                return -1; 
    403211                        } 
     
    436244                                } 
    437245 
    438                                 if (nate_xfer->recv_len == purple_xfer_get_size(xfer)) { 
     246                                if (nate_xfer->recv_len == purple_xfer_get_size(nate_xfer->prpl_xfer)) { 
    439247                                        gchar *buf; 
    440248 
    441249                                        purple_debug_info("nateon", "%s:%s\n", __FUNCTION__, "file transfer complete"); 
    442                                         purple_xfer_set_completed(xfer, TRUE); 
     250                                        purple_xfer_set_completed(nate_xfer->prpl_xfer, TRUE); 
    443251 
    444252                                        /* Send FILE END to sender */ 
     
    523331                g_free(old_rx_buf); 
    524332 
    525                 if (purple_xfer_is_completed(nate_xfer->prpl_xfer)) 
    526                 { 
    527                         purple_xfer_end(nate_xfer->prpl_xfer); 
    528                 } 
    529333                return buffer_len; 
    530334        } 
     
    532336} 
    533337 
    534 static gssize 
    535 nateon_xfer_write(const guchar *buffer, size_t buflen, PurpleXfer *prpl_xfer) 
    536 { 
    537         return 0; 
     338static void 
     339nateon_xfer_sock_read_cb(gpointer data, gint source, PurpleInputCondition condition) 
     340{ 
     341        NateonXfer *nate_xfer = data; 
     342        gssize r = 0; 
     343        guchar *buffer = NULL; 
     344 
     345        if (purple_xfer_get_type(nate_xfer->prpl_xfer) == PURPLE_XFER_RECEIVE) 
     346        { 
     347                r = nateon_xfer_sock_read(&nate_xfer->conn, &buffer); 
     348                if (r > 0) 
     349                { 
     350                        const size_t wc = fwrite(buffer, 1, r, nate_xfer->dest_fp); 
     351                        if (wc != r) 
     352                        { 
     353                                purple_debug_error("nateon", "%s:Unable to write whole buffer.\n"); 
     354                                purple_xfer_cancel_remote(nate_xfer->prpl_xfer); 
     355                                g_free(buffer); 
     356                                return; 
     357                        } 
     358                        purple_xfer_set_bytes_sent(nate_xfer->prpl_xfer, nate_xfer->recv_len); 
     359                        purple_xfer_update_progress(nate_xfer->prpl_xfer); 
     360                } 
     361                else if (r < 0) 
     362                { 
     363                        purple_xfer_cancel_remote(nate_xfer->prpl_xfer); 
     364 
     365                } 
     366        } 
     367        else if (purple_xfer_get_type(nate_xfer->prpl_xfer) == PURPLE_XFER_SEND) 
     368        { 
     369                r = nateon_xfer_sock_read(&nate_xfer->conn, &buffer); 
     370        } 
     371 
     372        if (r > 0) 
     373        { 
     374                g_free(buffer); 
     375        } 
     376 
     377        if (purple_xfer_is_completed(nate_xfer->prpl_xfer)) 
     378        { 
     379                if (nate_xfer->dest_fp) 
     380                { 
     381                        fclose(nate_xfer->dest_fp); 
     382                        nate_xfer->dest_fp = NULL; 
     383                } 
     384                purple_xfer_end(nate_xfer->prpl_xfer); 
     385        } 
     386 
     387        return; 
     388} 
     389 
     390static void 
     391nateon_xfer_sock_write_cb(gpointer data, gint source, PurpleInputCondition cond) 
     392{ 
     393        NateonXferConnection *conn = data; 
     394        int ret, writelen; 
     395 
     396        purple_debug_info("nateon", "write_cb\n"); 
     397        writelen = purple_circ_buffer_get_max_read(conn->tx_buf); 
     398 
     399        if (writelen == 0) { 
     400                purple_input_remove(conn->tx_handler); 
     401                conn->tx_handler = -1; 
     402                return; 
     403        } 
     404 
     405        ret = write(conn->fd, conn->tx_buf->outptr, writelen); 
     406 
     407        if (ret < 0 && errno == EAGAIN) 
     408                return; 
     409        else if (ret <= 0) { 
     410                purple_debug_info("nateon", "%s:%s\n", __FUNCTION__, "socket write error"); 
     411                return; 
     412        } 
     413 
     414        purple_circ_buffer_mark_read(conn->tx_buf, ret); 
     415} 
     416 
     417static ssize_t 
     418nateon_xfer_sock_write(NateonXferConnection *conn, const char *buf, size_t len) 
     419{ 
     420        ssize_t ret = 0; 
     421 
     422        g_return_val_if_fail(conn != NULL, 0); 
     423 
     424        if (conn->tx_handler == -1) { 
     425                ret = write(conn->fd, buf, len); 
     426        } else { 
     427                ret = -1; 
     428                errno = EAGAIN; 
     429        } 
     430 
     431        if (ret < 0 && errno == EAGAIN) 
     432                ret = 0; 
     433        if (ret < len) { 
     434                if (conn->tx_handler == -1) 
     435                        conn->tx_handler = purple_input_add( 
     436                                        conn->fd, PURPLE_INPUT_WRITE, 
     437                                        nateon_xfer_sock_write_cb, conn); 
     438                purple_circ_buffer_append(conn->tx_buf, buf + ret, len - ret); 
     439        } 
     440 
     441        if (ret == -1) 
     442        { 
     443                purple_debug_info("nateon", "%s:%s\n", __FUNCTION__, "socket write error"); 
     444        } 
     445 
     446        return ret; 
     447} 
     448 
     449static ssize_t nateon_xfer_send_data(NateonXfer *nate_xfer, const char *buf, size_t len); 
     450 
     451static void 
     452nateon_xfer_send_next(NateonXfer *nate_xfer) 
     453{ 
     454        NateonXferConnection *conn; 
     455        gchar *buf; 
     456        int cmd_len; 
     457 
     458        conn = &nate_xfer->conn; 
     459 
     460        if (nate_xfer->sent_len == purple_xfer_get_size(nate_xfer->prpl_xfer)) 
     461        { 
     462                purple_input_remove(conn->tx_handler); 
     463                conn->tx_handler = -1; 
     464                return; 
     465        } 
     466        if (purple_xfer_get_size(nate_xfer->prpl_xfer)-nate_xfer->sent_len > NATEON_XFER_SEND_BUFFER_SIZE) 
     467        { 
     468                nate_xfer->chunk_len = NATEON_XFER_SEND_BUFFER_SIZE; 
     469        } 
     470        else 
     471        { 
     472                nate_xfer->chunk_len = purple_xfer_get_size(nate_xfer->prpl_xfer) - nate_xfer->sent_len; 
     473        } 
     474 
     475        buf = g_strdup_printf("FILE %d DATA %d\r\n", 
     476                        nate_xfer->send_data_trid, nate_xfer->chunk_len); 
     477        cmd_len = strlen(buf); 
     478        buf = g_realloc(buf, cmd_len + nate_xfer->chunk_len); 
     479        fread(buf + cmd_len, 1, nate_xfer->chunk_len, nate_xfer->local_fp); 
     480        nateon_xfer_send_data(nate_xfer, buf, cmd_len + nate_xfer->chunk_len); 
     481        g_free(buf); 
     482        nate_xfer->send_data_trid++; 
     483} 
     484 
     485static void 
     486nateon_xfer_send_data_cb(gpointer data, gint source, PurpleInputCondition cond) 
     487{ 
     488        NateonXfer *nate_xfer = data; 
     489        NateonXferConnection *conn = &nate_xfer->conn; 
     490        int ret, writelen; 
     491 
     492        writelen = purple_circ_buffer_get_max_read(conn->tx_buf); 
     493 
     494        if (writelen == 0) 
     495        { 
     496                purple_input_remove(conn->tx_handler); 
     497                conn->tx_handler = -1; 
     498                nate_xfer->sent_len += nate_xfer->chunk_len; 
     499                nateon_xfer_send_next(nate_xfer); 
     500                purple_xfer_set_bytes_sent(nate_xfer->prpl_xfer, nate_xfer->sent_len); 
     501                purple_xfer_update_progress(nate_xfer->prpl_xfer); 
     502                return; 
     503        } 
     504 
     505        ret = write(conn->fd, conn->tx_buf->outptr, writelen); 
     506 
     507        if (ret < 0 && errno == EAGAIN) 
     508                return; 
     509        else if (ret <= 0) { 
     510                //nateon_servconn_got_error(servconn, NATEON_SERVCONN_ERROR_WRITE); 
     511                purple_debug_info("nateon", "%s:%s\n", __FUNCTION__, "socket write error"); 
     512                purple_input_remove(conn->tx_handler); 
     513                conn->tx_handler = -1; 
     514                purple_xfer_cancel_remote(nate_xfer->prpl_xfer); 
     515                return; 
     516        } 
     517 
     518        purple_circ_buffer_mark_read(conn->tx_buf, ret); 
     519} 
     520 
     521static ssize_t 
     522nateon_xfer_send_data(NateonXfer *nate_xfer, const char *buf, size_t len) 
     523{ 
     524        ssize_t ret = 0; 
     525        NateonXferConnection *conn; 
     526 
     527        conn = &nate_xfer->conn; 
     528        if (conn->tx_handler == -1) 
     529        { 
     530                ret = write(conn->fd, buf, len); 
     531        } 
     532        else 
     533        { 
     534                ret = -1; 
     535                errno = EAGAIN; 
     536        } 
     537 
     538        if (ret < 0 && errno == EAGAIN) 
     539                ret = 0; 
     540        if (ret < len) 
     541        { 
     542                if (conn->tx_handler == -1) 
     543                { 
     544                        conn->tx_handler = purple_input_add( conn->fd, PURPLE_INPUT_WRITE, 
     545                                        nateon_xfer_send_data_cb, nate_xfer); 
     546                } 
     547                purple_circ_buffer_append(conn->tx_buf, buf + ret, len - ret); 
     548        } else if (ret == len) 
     549        { 
     550                nate_xfer->sent_len += nate_xfer->chunk_len; 
     551                purple_xfer_set_bytes_sent(nate_xfer->prpl_xfer, nate_xfer->sent_len); 
     552                purple_xfer_update_progress(nate_xfer->prpl_xfer); 
     553                nateon_xfer_send_next(nate_xfer); 
     554                return ret; 
     555        } 
     556 
     557        if (ret == -1) 
     558        { 
     559                purple_debug_info("nateon", "%s:%s\n", __FUNCTION__, "socket write error"); 
     560                purple_xfer_cancel_remote(nate_xfer->prpl_xfer); 
     561        } 
     562 
     563        return ret; 
     564 
    538565} 
    539566 
     
    556583} 
    557584 
    558 static void p2p_read_cb(gpointer data, gint source, PurpleInputCondition condition); 
    559  
    560585static void 
    561586p2p_accept_cb(gpointer data, gint source, PurpleInputCondition cond) 
     
    564589        int fd; 
    565590 
     591        purple_input_remove(nate_xfer->p2p_listen_pa); 
     592        nate_xfer->p2p_listen_pa = -1; 
     593 
    566594        if (nate_xfer->conntype != NATEON_XFER_CONN_NONE) 
    567595        { 
    568596                /* already connected p2p session exists. drop this connection */ 
    569597                purple_debug_info("nateon", "%s:drop duplicate connection\n", __FUNCTION__); 
    570                 purple_input_remove(nate_xfer->p2p_listen_pa); 
    571598                close(source); 
    572                 nate_xfer->p2p_listen_pa = -1; 
    573599                return; 
    574600        } 
     
    579605                /* accept failed. wait for outgoing p2p or fr-conn to succeed */ 
    580606                purple_debug_info("nateon", "%s:accept error\n", __FUNCTION__); 
    581                 purple_input_remove(nate_xfer->p2p_listen_pa); 
    582607                close(source); 
    583                 nate_xfer->p2p_listen_pa = -1; 
    584608                return; 
    585609        } 
     
    589613        nate_xfer->conn.fd = fd; 
    590614 
    591         purple_input_remove(nate_xfer->p2p_listen_pa); 
    592615        close(source); 
    593         nate_xfer->p2p_listen_pa = -1; 
    594  
    595         if (purple_xfer_get_type(nate_xfer->prpl_xfer) == PURPLE_XFER_RECEIVE) 
    596         { 
    597                 purple_xfer_start(nate_xfer->prpl_xfer, fd, NULL, 0); 
    598         } 
    599         else 
    600         { 
    601                 purple_xfer_start(nate_xfer->prpl_xfer, -1, NULL, 0); 
    602                 nate_xfer->p2p_read_pa = purple_input_add(fd, PURPLE_INPUT_READ, \ 
    603                                 p2p_read_cb, nate_xfer); 
    604         } 
     616 
     617        purple_xfer_start(nate_xfer->prpl_xfer, -1, NULL, 0); 
     618        nate_xfer->conn.rx_pa = purple_input_add(fd, PURPLE_INPUT_READ, \ 
     619                        nateon_xfer_sock_read_cb, nate_xfer); 
    605620 
    606621        /* cancel other connecting processes */ 
     
    620635        NateonXfer *nate_xfer = data; 
    621636 
     637        nate_xfer->p2p_listen_data = NULL; 
     638 
    622639        if (listenfd == -1) { 
    623                 /* FIXME handle error */ 
    624                 /* 
    625                 purple_connection_error_reason(sip->gc, 
    626                         PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 
    627                         _("Could not create listen socket")); 
    628                 */ 
    629                 return; 
    630         } 
    631  
    632         nate_xfer->p2p_listen_data = NULL; 
     640                purple_debug_info("nateon",  
     641                                "%s:Could not create listen socket. Wait for other connections.\n", 
     642                                __FUNCTION__); 
     643                return; 
     644        } 
     645 
    633646        nate_xfer->p2p_listen_port = purple_network_get_port_from_fd(listenfd); 
    634647        nate_xfer->my_ip = g_strdup(purple_network_get_my_ip(listenfd)); 
     
    701714 
    702715static void 
     716p2p_connect_cb(gpointer data, gint source, const char *error_message) 
     717{ 
     718        NateonXfer *nate_xfer = data; 
     719 
     720        gchar *buf; 
     721 
     722        nate_xfer->p2p_connect_data = NULL; 
     723 
     724        if (source < 0) 
     725        { 
     726                /* Simply wait for FR to begin */ 
     727                purple_debug_info("nateon", "%s:Connect failed. err: [%s]\n", __FUNCTION__, error_message); 
     728                return; 
     729        } 
     730 
     731        if (nate_xfer->conntype != NATEON_XFER_CONN_NONE) 
     732        { 
     733                /* already connected session exists. drop this connection */ 
     734                purple_debug_info("nateon", "%s:drop duplicate connection\n", __FUNCTION__); 
     735                close(source); 
     736                return; 
     737        } 
     738 
     739        purple_debug_info("nateon", "%s:using outgoing connection for p2p\n", __FUNCTION__); 
     740        nate_xfer->conntype = NATEON_XFER_CONN_P2P; 
     741        nate_xfer->conn.fd = source; 
     742 
     743        /* register watcher for read callback */ 
     744        purple_xfer_start(nate_xfer->prpl_xfer, -1, NULL, 0); 
     745        nate_xfer->conn.rx_pa = purple_input_add(nate_xfer->conn.fd, PURPLE_INPUT_READ, \ 
     746                        nateon_xfer_sock_read_cb, nate_xfer); 
     747 
     748        buf = g_strdup_printf("ATHC 0 %s %s %s 6004 0\r\n", 
     749                        nate_xfer->session->user->account_name, 
     750                        nate_xfer->who, 
     751                        nate_xfer->p2p_cookie); 
     752        nateon_xfer_sock_write(&nate_xfer->conn, buf, strlen(buf)); 
     753        g_free(buf); 
     754 
     755        /* cancel other connecting processes */ 
     756        if (nate_xfer->p2p_listen_data) 
     757        { 
     758                purple_network_listen_cancel(nate_xfer->p2p_listen_data); 
     759                nate_xfer->p2p_listen_data = NULL; 
     760        } 
     761        if (nate_xfer->p2p_listen_pa) 
     762        { 
     763                purple_input_remove(nate_xfer->p2p_listen_pa); 
     764                nate_xfer->p2p_listen_pa = -1; 
     765        } 
     766        if (nate_xfer->p2p_listen_fd) 
     767        { 
     768                close(nate_xfer->p2p_listen_fd); 
     769                nate_xfer->p2p_listen_fd = 0; 
     770        } 
     771        if (nate_xfer->p2p_timer) { 
     772                purple_timeout_remove(nate_xfer->p2p_timer); 
     773                nate_xfer->p2p_timer = 0; 
     774        } 
     775        return; 
     776} 
     777 
     778static void 
     779fr_connect_cb(gpointer data, gint source, const char *error_message) 
     780{ 
     781        NateonXfer *nate_xfer = data; 
     782        gchar *buf; 
     783 
     784        nate_xfer->fr_connect_data = NULL; 
     785 
     786        purple_debug_info("nateon", "%s\n", __FUNCTION__); 
     787        if (source < 0) 
     788        { 
     789                /* FIXME: Handle error. This was our last try.. */ 
     790                purple_debug_info("nateon", "%s:Connect failed. err: [%s]\n", __FUNCTION__, error_message); 
     791                return; 
     792        } 
     793 
     794        if (nate_xfer->conntype != NATEON_XFER_CONN_NONE) 
     795        { 
     796                /* already connected p2p session exists. drop this connection */ 
     797                purple_debug_info("nateon", "%s:drop duplicate connection\n", __FUNCTION__); 
     798                close(source); 
     799                return; 
     800        } 
     801 
     802        nate_xfer->conntype = NATEON_XFER_CONN_FR; 
     803 
     804        /* cancel p2p connection tries */ 
     805        if (nate_xfer->p2p_connect_data) 
     806        { 
     807                purple_proxy_connect_cancel(nate_xfer->p2p_connect_data); 
     808                nate_xfer->p2p_connect_data = NULL; 
     809        } 
     810        if (nate_xfer->p2p_listen_data) 
     811        { 
     812                purple_network_listen_cancel(nate_xfer->p2p_listen_data); 
     813                nate_xfer->p2p_listen_data = NULL; 
     814        } 
     815        if (nate_xfer->p2p_listen_pa > 0) 
     816        { 
     817                purple_input_remove(nate_xfer->p2p_listen_pa); 
     818                nate_xfer->p2p_listen_pa = -1; 
     819        } 
     820        if (nate_xfer->p2p_listen_fd) 
     821        { 
     822                close(nate_xfer->p2p_listen_fd); 
     823                nate_xfer->p2p_listen_fd = 0; 
     824        } 
     825 
     826        purple_debug_info("nateon", "%s:using fr connection for file transfer\n", __FUNCTION__); 
     827        nate_xfer->conn.fd = source; 
     828 
     829        /* register watcher for read callback */ 
     830        nate_xfer->conn.rx_pa = purple_input_add(nate_xfer->conn.fd, PURPLE_INPUT_READ, \ 
     831                        nateon_xfer_sock_read_cb, nate_xfer); 
     832        purple_xfer_start(nate_xfer->prpl_xfer, -1, NULL, 0); 
     833 
     834        if (purple_xfer_get_type(nate_xfer->prpl_xfer) == PURPLE_XFER_RECEIVE) 
     835        { 
     836                buf = g_strdup_printf("FRIN 0 %s %s\r\n", nate_xfer->session->user->account_name,  
     837                                nate_xfer->fr_authkey); 
     838                nateon_xfer_sock_write(&nate_xfer->conn, buf, strlen(buf)); 
     839                g_free(buf); 
     840        } 
     841        else if (purple_xfer_get_type(nate_xfer->prpl_xfer) == PURPLE_XFER_SEND) 
     842        { 
     843                buf = g_strdup_printf("ATHC 0 %s %s %s %s 6004 0\r\n",  
     844                                nate_xfer->session->user->account_name,  
     845                                nate_xfer->who, 
     846                                nate_xfer->p2p_cookie, nate_xfer->fr_authkey); 
     847                nateon_xfer_sock_write(&nate_xfer->conn, buf, strlen(buf)); 
     848                g_free(buf); 
     849        } 
     850} 
     851 
     852static void 
    703853nateon_xfer_init(PurpleXfer *xfer) 
    704854{ 
     
    713863        if (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) 
    714864        { 
     865                nate_xfer->dest_fp = fopen(purple_xfer_get_local_filename(xfer), "wb"); 
     866 
     867                if (nate_xfer->dest_fp == NULL) { 
     868                        purple_debug_info("nateon", "%s: Error Writing File %s\n", __FUNCTION__, 
     869                                        purple_xfer_get_local_filename(xfer)); 
     870                        purple_xfer_cancel_local(xfer); 
     871                        return; 
     872                } 
     873 
    715874                nate_xfer->p2p_listen_data = purple_network_listen_range(NATEON_P2P_START_PORT,\ 
    716875                                NATEON_P2P_END_PORT, SOCK_STREAM, p2p_listen_cb, nate_xfer); 
     
    802961                        purple_proxy_connect_cancel(nate_xfer->fr_connect_data); 
    803962 
     963                if (nate_xfer->conn.rx_pa > 0) 
     964                        purple_input_remove(nate_xfer->conn.rx_pa); 
    804965                if (nate_xfer->conn.rx_buf) 
    805966                        g_free(nate_xfer->conn.rx_buf); 
     
    811972                if (nate_xfer->conn.fd) 
    812973                        close(nate_xfer->conn.fd); 
    813                 if (nate_xfer->p2p_read_pa) 
    814                         purple_input_remove(nate_xfer->p2p_read_pa); 
    815974                if (nate_xfer->local_fp) 
    816975                        fclose(nate_xfer->local_fp); 
     
    8421001        xfer->conn.tx_handler = -1; 
    8431002        xfer->conn.tx_buf = purple_circ_buffer_new(0); 
     1003        xfer->conn.nate_xfer = xfer; 
    8441004        xfer->p2p_listen_pa = -1; 
    8451005 
    8461006        return xfer; 
    847 } 
    848  
    849 static void 
    850 p2p_read_cb(gpointer data, gint source, PurpleInputCondition condition) 
    851 { 
    852         NateonXfer *nate_xfer = data; 
    853         gssize r = 0; 
    854         guchar *buffer = NULL; 
    855  
    856         r = purple_xfer_read(nate_xfer->prpl_xfer, &buffer); 
    857         if (r < 0) { 
    858                 purple_input_remove(nate_xfer->p2p_read_pa); 
    859         } 
    860  
    861         return; 
    862 } 
    863  
    864 static void 
    865 p2p_connect_cb(gpointer data, gint source, const char *error_message) 
    866 { 
    867         NateonXfer *nate_xfer = data; 
    868  
    869         gchar *buf; 
    870  
    871         nate_xfer->p2p_connect_data = NULL; 
    872  
    873         if (source < 0) 
    874         { 
    875                 /* Simply wait for FR to begin */ 
    876                 purple_debug_info("nateon", "%s:Connect failed. err: [%s]\n", __FUNCTION__, error_message); 
    877                 return; 
    878         } 
    879  
    880         if (nate_xfer->conntype != NATEON_XFER_CONN_NONE) 
    881         { 
    882                 /* already connected session exists. drop this connection */ 
    883                 purple_debug_info("nateon", "%s:drop duplicate connection\n", __FUNCTION__); 
    884                 close(source); 
    885                 return; 
    886         } 
    887  
    888         purple_debug_info("nateon", "%s:using outgoing connection for p2p\n", __FUNCTION__); 
    889         nate_xfer->conntype = NATEON_XFER_CONN_P2P; 
    890         nate_xfer->conn.fd = source; 
    891  
    892         buf = g_strdup_printf("ATHC 0 %s %s %s 6004 0\r\n", 
    893                         nate_xfer->session->user->account_name, 
    894                         nate_xfer->who, 
    895                         nate_xfer->p2p_cookie); 
    896         nateon_xfer_sock_write(&nate_xfer->conn, buf, strlen(buf)); 
    897         g_free(buf); 
    898  
    899         if (purple_xfer_get_type(nate_xfer->prpl_xfer) == PURPLE_XFER_RECEIVE) 
    900         { 
    901                 purple_xfer_start(nate_xfer->prpl_xfer, source, NULL, 0); 
    902         } 
    903         else 
    904         { 
    905                 //purple_xfer_set_status(nate_xfer->prpl_xfer, PURPLE_XFER_STATUS_STARTED); 
    906                 purple_xfer_start(nate_xfer->prpl_xfer, -1, NULL, 0); 
    907                 nate_xfer->p2p_read_pa = purple_input_add(source, PURPLE_INPUT_READ, \ 
    908                                 p2p_read_cb, nate_xfer); 
    909         } 
    910  
    911         /* cancel other connecting processes */ 
    912         if (nate_xfer->p2p_listen_data) 
    913         { 
    914                 purple_network_listen_cancel(nate_xfer->p2p_listen_data); 
    915                 nate_xfer->p2p_listen_data = NULL; 
    916         } 
    917         if (nate_xfer->p2p_listen_pa) 
    918         { 
    919                 purple_input_remove(nate_xfer->p2p_listen_pa); 
    920                 nate_xfer->p2p_listen_pa = -1; 
    921         } 
    922         if (nate_xfer->p2p_listen_fd) 
    923         { 
    924                 close(nate_xfer->p2p_listen_fd); 
    925                 nate_xfer->p2p_listen_fd = 0; 
    926         } 
    927         if (nate_xfer->p2p_timer) { 
    928                 purple_timeout_remove(nate_xfer->p2p_timer); 
    929                 nate_xfer->p2p_timer = 0; 
    930         } 
    931         return; 
    932 } 
    933  
    934 static void 
    935 fr_connect_cb(gpointer data, gint source, const char *error_message) 
    936 { 
    937         NateonXfer *nate_xfer = data; 
    938         gchar *buf; 
    939  
    940         nate_xfer->fr_connect_data = NULL; 
    941  
    942         purple_debug_info("nateon", "%s\n", __FUNCTION__); 
    943         if (source < 0) 
    944         { 
    945                 /* FIXME: Handle error. This was our last try.. */ 
    946                 purple_debug_info("nateon", "%s:Connect failed. err: [%s]\n", __FUNCTION__, error_message); 
    947                 return; 
    948         } 
    949  
    950         if (nate_xfer->conntype != NATEON_XFER_CONN_NONE) 
    951         { 
    952                 /* already connected p2p session exists. drop this connection */ 
    953                 purple_debug_info("nateon", "%s:drop duplicate connection\n", __FUNCTION__); 
    954                 close(source); 
    955                 return; 
    956         } 
    957  
    958         nate_xfer->conntype = NATEON_XFER_CONN_FR; 
    959  
    960         /* cancel p2p connection tries */ 
    961         if (nate_xfer->p2p_connect_data) 
    962         { 
    963                 purple_proxy_connect_cancel(nate_xfer->p2p_connect_data); 
    964                 nate_xfer->p2p_connect_data = NULL; 
    965         } 
    966         if (nate_xfer->p2p_listen_data) 
    967         { 
    968                 purple_network_listen_cancel(nate_xfer->p2p_listen_data); 
    969                 nate_xfer->p2p_listen_data = NULL; 
    970         } 
    971         if (nate_xfer->p2p_listen_pa > 0) 
    972         { 
    973                 purple_input_remove(nate_xfer->p2p_listen_pa); 
    974                 nate_xfer->p2p_listen_pa = -1; 
    975         } 
    976         if (nate_xfer->p2p_listen_fd) 
    977         { 
    978                 close(nate_xfer->p2p_listen_fd); 
    979                 nate_xfer->p2p_listen_fd = 0; 
    980         } 
    981  
    982         purple_debug_info("nateon", "%s:using fr connection for file transfer\n", __FUNCTION__); 
    983         nate_xfer->conn.fd = source; 
    984  
    985         if (purple_xfer_get_type(nate_xfer->prpl_xfer) == PURPLE_XFER_RECEIVE) 
    986         { 
    987                 buf = g_strdup_printf("FRIN 0 %s %s\r\n", nate_xfer->session->user->account_name,  
    988                                 nate_xfer->fr_authkey); 
    989                 nateon_xfer_sock_write(&nate_xfer->conn, buf, strlen(buf)); 
    990                 g_free(buf); 
    991  
    992                 purple_xfer_start(nate_xfer->prpl_xfer, source, NULL, 0); 
    993         } 
    994         else if (purple_xfer_get_type(nate_xfer->prpl_xfer) == PURPLE_XFER_SEND) 
    995         { 
    996                 buf = g_strdup_printf("ATHC 0 %s %s %s %s 6004 0\r\n",  
    997                                 nate_xfer->session->user->account_name,  
    998                                 nate_xfer->who, 
    999                                 nate_xfer->p2p_cookie, nate_xfer->fr_authkey); 
    1000                 nateon_xfer_sock_write(&nate_xfer->conn, buf, strlen(buf)); 
    1001                 g_free(buf); 
    1002                 purple_xfer_start(nate_xfer->prpl_xfer, -1, NULL, 0); 
    1003                 nate_xfer->p2p_read_pa = purple_input_add(source, PURPLE_INPUT_READ, \ 
    1004                                 p2p_read_cb, nate_xfer); 
    1005         } 
    10061007} 
    10071008 
     
    11411142        purple_xfer_set_cancel_recv_fnc(xfer->prpl_xfer, nateon_xfer_cancel_recv); 
    11421143        purple_xfer_set_request_denied_fnc(xfer->prpl_xfer, nateon_xfer_request_denied); 
    1143         purple_xfer_set_read_fnc(xfer->prpl_xfer, nateon_xfer_read); 
    11441144        purple_xfer_set_end_fnc(xfer->prpl_xfer, nateon_xfer_end); 
    11451145 
     
    11581158        purple_xfer_set_cancel_recv_fnc(xfer->prpl_xfer, nateon_xfer_cancel_recv); 
    11591159        purple_xfer_set_request_denied_fnc(xfer->prpl_xfer, nateon_xfer_request_denied); 
    1160         purple_xfer_set_read_fnc(xfer->prpl_xfer, nateon_xfer_read); 
    1161         purple_xfer_set_write_fnc(xfer->prpl_xfer, nateon_xfer_write); 
    11621160        purple_xfer_set_end_fnc(xfer->prpl_xfer, nateon_xfer_end); 
    11631161        purple_xfer_set_cancel_send_fnc(xfer->prpl_xfer, nateon_xfer_cancel_send); 
  • trunk/src/xfer.h

    r126 r129  
    3939        int fd;         /**< socket file descriptor */ 
    4040 
     41        int rx_pa;              /**< socket read watcher */ 
    4142        char *rx_buf;   /**< The receive buffer. */ 
    4243        int rx_len;             /**< The receive buffer length. */ 
     
    4748        int inpa; 
    4849 
     50        NateonXfer *nate_xfer; 
    4951}; 
    5052 
     
    7779        int             p2p_listen_port;        /**< listening port number */ 
    7880        guint   p2p_timer; 
    79         int             p2p_read_pa; 
    8081 
    8182        /* FR-server related */ 
     
    8788 
    8889        char *file_cookie;      /**< cookie of the file transferred */ 
     90        FILE *dest_fp; 
    8991 
    9092        NateonXferConnType conntype;