view src/protocols/icq/eventhandle.c @ 6160:7416a43dc786

[gaim-migrate @ 6635] Hold it.. Nobody said anything about _three_ books. Oh that stinkin' wise man. He was so busy filling me full of his secret little workds and his phrases and his BALONEY that he never said anything about this... committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Wed, 16 Jul 2003 22:43:27 +0000
parents f0a2a9afdb77
children
line wrap: on
line source

/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */

/*
 * $Id: eventhandle.c 2509 2001-10-13 00:06:18Z warmenhoven $
 *
 * Copyright (C) 1998-2001, Denis V. Dmitrienko <denis@null.net> and
 *                          Bill Soudan <soudan@kde.org>
 *
 * 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
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <time.h>

#ifndef _WIN32
#include <unistd.h>
#endif

#include "icqevent.h"
#include "icqpacket.h"
#include "tcplink.h"
#include "chatsession.h"
#include "filesession.h"

#include "eventhandle.h"

void icq_TCPProcessPacket2(icq_Packet *p, icq_TCPLink *tcplink)
{
  icq_MessageEvent *pevent=(icq_MessageEvent *)icq_ParsePacket(p);
  icq_Event *pbase=(icq_Event *)pevent;

  icq_Link *icqlink=tcplink->icqlink;

  if (pbase->uin != tcplink->remote_uin)
  {
    /* TODO: spoofed packet! */
  }

  pbase->handleEvent(pbase, icqlink);

  /* notify library client than the ack was received from remote client */
  if (pbase->subtype==ICQ_EVENT_ACK)
  {
    icq_FmtLog(tcplink->icqlink, ICQ_LOG_MESSAGE, "received ack %d\n", p->id);
    if(icqlink->icq_RequestNotify)
    {
      (*icqlink->icq_RequestNotify)(icqlink, pbase->id,
        ICQ_NOTIFY_ACK, pevent->status, (void *)pevent->message);
      (*icqlink->icq_RequestNotify)(icqlink, pbase->id,
        ICQ_NOTIFY_SUCCESS, 0, 0);
    }
  }    
}

void icq_HandleMessageEvent(icq_Event *pbase, icq_Link *icqlink)
{
  icq_MessageEvent *pevent=(icq_MessageEvent *)pbase;
  struct tm *ptime=localtime(&(pbase->time));

  if (pbase->subtype==ICQ_EVENT_MESSAGE && icqlink->icq_RecvMessage)
  {
    (*icqlink->icq_RecvMessage)(icqlink, pbase->uin, ptime->tm_hour,
      ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1,
      ptime->tm_year+1900, pevent->message);
    /* TODO: send ack */
  }

}

void icq_HandleURLEvent(icq_Event *pbase, icq_Link *icqlink) 
{
  icq_URLEvent *pevent=(icq_URLEvent *)pbase;
  struct tm *ptime=localtime(&(pbase->time));

  if (pbase->subtype==ICQ_EVENT_MESSAGE && icqlink->icq_RecvURL)
  {
    (*icqlink->icq_RecvURL)(icqlink, pbase->uin, ptime->tm_hour,
      ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1,
      ptime->tm_year+1900, pevent->url, pevent->message);
    /* TODO: send ack */
  }
}

void icq_HandleChatRequestEvent(icq_Event *pbase, icq_Link *icqlink)
{
  icq_MessageEvent *pmsgevent=(icq_MessageEvent *)pmsgevent;

  struct tm *ptime=localtime(&(pbase->time));

  switch(pbase->subtype)
  {
    case ICQ_EVENT_MESSAGE:
      if (icqlink->icq_RecvChatReq)
        (*icqlink->icq_RecvChatReq)(icqlink, pbase->uin,
          ptime->tm_hour, ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1,
          ptime->tm_year+1900, pmsgevent->message, pbase->id);
      /* don't send an ack to the remote client!  library client is
       * responsible for sending the ack once the user accepts
       * or denies the request */
      break;
    case ICQ_EVENT_ACK:
      icq_HandleChatRequestAck(pbase, icqlink);
      break;
    case ICQ_EVENT_CANCEL:
      /* TODO */
      break;
    default:
      /* TODO */
      break;
  }
}

void icq_HandleChatRequestAck(icq_Event *pbase, icq_Link *icqlink)
{
  icq_ChatRequestEvent *pevent=(icq_ChatRequestEvent *)pbase;
  icq_TCPLink *pchatlink;
  icq_ChatSession *pchat;
  icq_Packet *p2;

  /* once a chat request acknowledgement has been received, the remote
   * client opens up a listening port for us.  we need to connect to
   * this port and all chat session communication takes place over
   * this new tcp link */
  pchatlink=icq_TCPLinkNew(icqlink);
  pchatlink->type=TCP_LINK_CHAT;
  pchatlink->id=pbase->id;

  /* create a new chat session to manage the communication, and link
   * it to the tcp link */
  pchat=icq_ChatSessionNew(icqlink);
  pchat->id=pbase->id;
  pchat->remote_uin=pbase->uin;
  pchatlink->session=pchat;

  icq_ChatSessionSetStatus(pchat, CHAT_STATUS_CONNECTING);

  /* initiate the connection to the remote client's chat session 
   * port, which was specified in the ack event they sent */
  icq_TCPLinkConnect(pchatlink, pbase->uin, pevent->port);

  /* send off chat init event */
  p2=icq_TCPCreateChatInfoPacket(pchatlink, icqlink->icq_Nick, 0x00ffffff,
    0x00000000);
  icq_TCPLinkSend(pchatlink, p2);  
}


void icq_HandleFileRequestEvent(icq_Event *pbase, icq_Link *icqlink)
{
  icq_FileRequestEvent *pevent=(icq_FileRequestEvent *)pbase;
  icq_MessageEvent *pmsgevent=(icq_MessageEvent *)pmsgevent;
  struct tm *ptime=localtime(&(pbase->time));

  switch(pbase->subtype)
  {
    case ICQ_EVENT_MESSAGE:
      if (icqlink->icq_RecvFileReq)
        (*icqlink->icq_RecvFileReq)(icqlink, pbase->uin,
          ptime->tm_hour, ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1,
          ptime->tm_year+1900, pmsgevent->message, pevent->filename,
          pevent->filesize, pbase->id);
      /* don't send an ack to the remote client!  library client is
       * responsible for sending the ack once the user accepts
       * or denies the request */
      break;
    case ICQ_EVENT_ACK:
      icq_HandleFileRequestAck(pbase, icqlink);
      break;
    case ICQ_EVENT_CANCEL:
      break;
    default:
      /* TODO */
      break;
  }
}

void icq_HandleFileRequestAck(icq_Event *pbase, icq_Link *icqlink)
{
  icq_FileRequestEvent *pevent=(icq_FileRequestEvent *)pbase;
  icq_TCPLink *pfilelink;
  icq_FileSession *pfile;
  icq_Packet *p2;

  /* once a file request acknowledgement has been received, the remote
   * client opens up a listening port for us.  we need to connect to
   * this port and all file transfer communication takes place over
   * this new tcp link */
  pfilelink=icq_TCPLinkNew(icqlink);
  pfilelink->type=TCP_LINK_FILE;

  /* a file session was created when the request was initially sent,
   * but it wasn't attached to a tcp link because one did not exist. 
   * find the file sesion now and link it to the new tcp link */
  pfile=icq_FindFileSession(icqlink, pbase->uin, 
    pbase->id); /* TODO: make sure find session succeeded */
  pfile->tcplink=pfilelink;
  pfilelink->id=pfile->id;
  pfilelink->session=pfile;

  /* notify the library client of the created file session */
  if (icqlink->icq_RequestNotify)
    (*icqlink->icq_RequestNotify)(icqlink, pfile->id,
      ICQ_NOTIFY_FILESESSION, sizeof(icq_FileSession), pfile);
  icq_FileSessionSetStatus(pfile, FILE_STATUS_CONNECTING);

  /* initiate the connection to the remote client's file session 
   * port, which was specified in the ack event they sent */
  icq_TCPLinkConnect(pfilelink, pbase->uin, pevent->port);

  /* send off the file transfer init event */
  /* TODO: convert file packets to events */
  p2=icq_TCPCreateFile00Packet( pfile->total_files,
    pfile->total_bytes, pfile->current_speed, icqlink->icq_Nick);
  icq_TCPLinkSend(pfilelink, p2); 
}


/*
icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, "unknown message type %d!\n", type);
icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, "unknown packet command %d!\n",
 command); 

 TODO: conversion
    strncpy(data,message,512) ;
    icq_RusConv("wk",data) ;


 TODO: ack code

    if(plink)
    {
      pack=icq_TCPCreateMessageAck(plink,0);
      icq_PacketAppend32(pack, id);
      icq_PacketSend(pack, plink->socket);
      icq_PacketDelete(pack);
    }
*/