/*****************************************************************************\
* Copyright (c) 2002 Pelle Johansson.                                         *
* All rights reserved.                                                        *
*                                                                             *
* This file is part of the moftpd package. Use and distribution of            *
* this software is governed by the terms in the file LICENCE, which           *
* should have come with this package.                                         *
\*****************************************************************************/

/* $moftpd: connection.h 1245 2004-12-09 12:01:59Z morth $ */

#ifndef _CONNECTION_H
#define _CONNECTION_H

typedef struct connection connection_t;

#include "server.h"
#include "user.h"
#include "tls.h"

enum
{
  ttText = 0,
  ttImage = 1
};

enum
{
  NUL, SE = 240, SB = 250, WILL, WONT, DO, DONT, IAC
};

enum
{
  tfCR     = 0x1,
  tfSubOpt = 0x2
};

enum
{
  acWelcome = 1, acLogin, acSending, acGetting, acList,
  acMsg, acAbort, acDisconnect
};

typedef ssize_t (*writeFun_t) (const void *channel, const void *buf, size_t len);
typedef ssize_t (*writeVecsFun_t) (const void *channel, struct iovec *vecs, int num);

struct connection
{
  int id, sock, accSock;
  char readBuffer[4096];
  unsigned int readBufferLen;
  int overFlow:1, authed:1, passive:1, epsvOnly:1, working:1, spontQuit:1,
	passiveAccepted:1, sending:1, inLookUp:1;
  user_t *user;
  char *email, *account;
  const char *expect;
  char *cwd;
  struct sockaddr_storage lDataAddr, rDataAddr;
  int activePort;
  int dataSock, fileFd;
  char *spontReply;
  int type, subtype;
  long long restart, endOffset;
  void *data;
  unsigned long long dataOffset, dataLen;
  char *filePath;
  time_t transferStart;
  char *rnfr;
  time_t lastCommand;
  int telnetMode, telnetFlags;
  unsigned char sb;
#if 0 // Will probably never parse subopts. RFC 1123 says not to.
  char subopt[100];
  int suboptLen;
#endif
  char *currLang;
  int langFd;
#ifdef USE_TLS
  tls_t tlsControl, tlsData;
  tlscert_t tlsClientCert;
  int tlsState, tlsDataState;
#endif
  int pbsz, failedLogins;
  time_t sleepUntil;
  int protLevel;
  int mlstTags;
#ifdef HAVE_LIBPAM
  pam_handle_t *pamh;
#endif
  int extRFd, extWFd;
  int accWait;
  writeFun_t controlWrite, dataWrite;
  writeVecsFun_t controlWriteVecs;
  void *controlChannel, *dataChannel;
  
  server_t *server, *oldserver;
};

ssize_t conn_plain_writer (const void *channel, const void *buf, size_t len);

int count_connections (void);
connection_t *new_connection(int sock, server_t *serv, int accSock);
void disconnected(connection_t *conn);
void quit_all_connections(const char *str);
void disconnect_all_connections(void);
void check_idle(void);

void reply(connection_t *conn, const char *format, ...)
     __attribute__((format (printf, 2, 3)));
int reply_file (connection_t *conn, const char *format, const char *file, const char *lastfmt);
void reply_msg (connection_t *conn, const char *format, const char *msg);
void reply_spont(connection_t *conn, const char *str, int closeConn);
void send_telnet(connection_t *conn, const char *str, int newline);

int control_handler(int sock, void *user, int urgent);
void run_commands (connection_t *conn);
int parse_telnet(connection_t *conn, char *buff, int len);

int authenticated(connection_t *conn);
void unauthenticated(connection_t *conn);

int passive_acceptor(int sock, void *user, int urgent);
int open_data_connection(connection_t *conn);
int close_data_connection(connection_t *conn);
int data_receiver(int sock, void *user, int urgent);
int data_sender(int sock, void *user, int urgent);

#endif /*_CONNECTION_H*/


syntax highlighted by Code2HTML, v. 0.9.1