/*
 * dcc.h
 * (C) 1999-2002 Murat Deligonul
 *
 */
 
#ifndef __DCC_H
#define __DCC_H

#include <netinet/in.h>
#include <time.h>
#include "timer.h"
#include "linkedlist.h"
#include "socket.h"

class conn;
class dccsend;
class dccpipe;

extern int check_timers(void);

class dcc 
{
protected:
    class dccsock : public pollsocket
    {
    public:
        dccsock(dcc * owner, int fd, bool * success, int options)
         : pollsocket(fd, success, options)
        {
            this->owner = owner;
        }

        int event_handler(const struct pollfd * );

        dcc * owner;
        friend class dcc;
        friend class dccpipe;
        friend class dccsend;
    };

    friend class dccsock;

    dccsock * sender, * receiver;
    dccsock * lsock;
    conn * owner;

    int stat;
    time_t start_time;
    timer * idle_timer;

    void close_all(void);

public:

    dcc(conn * , struct sockaddr_in *, unsigned short *);
    virtual ~dcc();
    virtual int poll(struct sockaddr_in *) = 0;

    conn * get_owner() { return owner; }
    conn * set_owner(conn * c) { return owner = c; }

    struct dcc_priv {
        char * str1;
        char * str2;
        int i;
    };

    static int idle_timer_proc(time_t, int, void *);

protected:
    dcc_priv * priv;
public:
    dcc_priv * get_priv(void) { return priv; }
    dcc_priv * set_priv(const dcc_priv *);

};

class dccpipe : public dcc
{
private:
    unsigned long s_address;
    unsigned short s_port;
    bool do_connect();           /* connect to the receiver of the dcc */
    bool on_connect(int);        /* when connection to receiver is established */
    bool on_disconnect(int);     /* when one of the parties dies */

public:
    dccpipe(conn *, unsigned long, unsigned short, struct sockaddr_in * psin, unsigned short * listen_port);
    virtual int poll(struct sockaddr_in *);
};

/* 
 * Simple dcc send thing. Waits for connection and then sends.
 * Does not bother with IRC commands needed to initiate the send.
 */
class dccsend : public dcc
{
public:
    dccsend(conn * owner, const char * filename, struct sockaddr_in * psin,
            unsigned short *listen_port, unsigned long *);
    ~dccsend();
    virtual int poll(struct sockaddr_in *);
    static int idle_timer_proc(time_t, int, void *);

private:
    int file;
    char * filename;
    unsigned long sent,          /* How many bytes we have recorded sending out */
                  bytes2send,    /* How much total to send */
                  packets;       /* How many packets were transferred */

    time_t end_time;

protected:

    int  send_next_packet(void);
    void close_all(void);

};
  
enum {
    DCC_CONNECTION_ACCEPTED = 5,
    DCC_PIPE_ESTABLISHED  = 6,
    DCC_SEND_ESTABLISHED  = 7,
    DCC_SEND_COMPLETE = -1,
    DCC_ERROR         = -2,
    DCC_CLOSED        = -3,
    DCC_SEND_TIMEDOUT = -4,
    DCC_PIPE_TIMEDOUT = -5,

};


#endif


syntax highlighted by Code2HTML, v. 0.9.1