#pragma interface #ifndef TLMPNET_H #define TLMPNET_H #include #include class PRIVATE_MESSAGE; class HANDLE_SELECTS{ public: virtual void process_select (int select_ret, fd_set&set, long timeout) = 0; virtual int setup_select (fd_set&set, int max_handle)=0; }; // TLMPEPOLL is a wrapper to allow usage of epoll on system without it // using select(2) as needed enum TLMPEPOLL_CTL{ TLMPEPOLL_CTL_ADD, TLMPEPOLL_CTL_DEL, TLMPEPOLL_CTL_MOD }; #define TLMPEPOLL_IN 1 #define TLMPEPOLL_OUT 2 struct TLMPEPOLL_EVENT{ int events; // TLMPEPOLL_IN or OUT int fd; int id; void *data; }; class TLMPEPOLL{ class TLMPEPOLL_private *priv; public: /*~PROTOBEG~ TLMPEPOLL */ public: TLMPEPOLL (void); void ctl (TLMPEPOLL_CTL op, int fd, int events); private: void ctl_select (TLMPEPOLL_CTL op, int fd, int events); public: void setdata (int fd, void *data); void setid (int fd, int id); int wait (TLMPEPOLL_EVENT events[], int nbevents, int timeout); private: int wait_select (TLMPEPOLL_EVENT events[], int nbevents, int timeout); public: ~TLMPEPOLL (void); /*~PROTOEND~ TLMPEPOLL */ }; struct TCPCONNECT_INFO{ const char *host; const char *port; int handle; // socket handle int linelen; // Length of line for the receive // functag const char *bindaddr; }; #define _TLMP_TCPCONNECT struct _F_TCPCONNECT{ class TCPCONNECT_PRIVATE *priv; void settcpnodelay(bool on); int send (const char *s); int send (const void *b, int len); int sendf (const char *ctl, ...); void set_timeout(int seconds); void set_timeout(int seconds, int usec); bool setrawmode (bool mode); #define _F_TCPCONNECT_init(x) void x init(bool &end, TCPCONNECT_INFO &info) virtual _F_TCPCONNECT_init( ); #define _F_TCPCONNECT_fail(x) void x fail(TCPCONNECT_INFO &info) virtual _F_TCPCONNECT_fail( ); #define _F_TCPCONNECT_oneline(x) void x oneline(const char *line, bool &end, TCPCONNECT_INFO &info) virtual _F_TCPCONNECT_oneline( )=0; #define _F_TCPCONNECT_time_out(x) void x time_out(bool &end, TCPCONNECT_INFO &info) virtual _F_TCPCONNECT_time_out( ); #define _F_TCPCONNECT_end(x) void x end(TCPCONNECT_INFO &info) virtual _F_TCPCONNECT_end( ); }; class TCPCONNECT: public HANDLE_SELECTS{ class TCPCONNECT_PRIVATE *priv; /*~PROTOBEG~ TCPCONNECT */ public: TCPCONNECT (_F_TCPCONNECT&c, const char *bindaddr, const char *host, const char *port); TCPCONNECT (_F_TCPCONNECT&c, const char *host, const char *port); TCPCONNECT (_F_TCPCONNECT&c, int handle); int close (void); int connect (void); private: void first_connect (void); public: bool is_ok (void); int loop (int time_out); int poll (void); private: void process_lines (void); public: void process_select (int select_ret, fd_set&set, long timeout); int reconnect (const char *newhost, const char *newport); int reconnect (void); int send (const char *line); int send (const void *buf, int len); int sendf (const char *ctl, ...); void set_timeout (int seconds); bool setrawmode (bool mode); void settcpnodelay (bool on); int setup_select (fd_set&set, int max_handle); virtual ~TCPCONNECT (void); /*~PROTOEND~ TCPCONNECT */ }; #define _TLMP_tcpconnect struct _F_tcpconnect{ class tcpconnect_private *priv; void settcpnodelay(bool on); int send (const char *s); int send (const void *b, int len); int sendf (const char *ctl, ...); void set_timeout(int seconds); void set_timeout(int seconds, int usec); bool setrawmode (bool mode); #define _F_tcpconnect_init(x) void x init(bool &end, TCPCONNECT_INFO &info) virtual _F_tcpconnect_init( ); #define _F_tcpconnect_fail(x) void x fail(TCPCONNECT_INFO &info) virtual _F_tcpconnect_fail( ); #define _F_tcpconnect_oneline(x) void x oneline(const char *line, bool &end, TCPCONNECT_INFO &info) virtual _F_tcpconnect_oneline( )=0; #define _F_tcpconnect_time_out(x) void x time_out(bool &end, TCPCONNECT_INFO &info) virtual _F_tcpconnect_time_out( ); #define _F_tcpconnect_end(x) void x end(TCPCONNECT_INFO &info) virtual _F_tcpconnect_end( ); }; #define _TLMP_TCPSERVER _V1 struct TCPSERVER_INFO{ const char *port; class ARRAY_OBJ *data; // Per connection data, manage by the caller // deleted by TCPCONNECT. const char *rest; // Stuff to process still in the buffer int linelen; // Length of line for the receive // functag }; struct _F_TCPSERVER{ class TCPSERVER_PRIVATE *priv; void settcpnodelay(bool on); int send (const char *s); int send (const void *b, int len); int sendf (const char *ctl, ...); int sendall (const char *s); int sendall (const void *b, int len); int sendallf (const char *ctl, ...); int sendto (int client, const char *s); int sendto (int client, const void *b, int len); int sendtof (int client, const char *ctl, ...); void set_timeout (int nbseconds); void forgetclient(); void closeclient (int cli); int getnbclients(); bool setrawmode (bool mode); void inject (int newclient, ARRAY_OBJ *data); void inject_output(int handle); void endsession (int client); int getnbpending(); int iter_init(void *&data); int iter_init(); int iter_next(void *&data); int iter_next(); bool is_blocked(); bool is_blocked(int handle, unsigned long &size, long long &lastwrite); bool setlisten (int handle, bool on); bool islistening (int handle); #define _F_TCPSERVER_newclient(x) void x newclient(int no, unsigned long from, bool &endclient, bool &endserver, TCPSERVER_INFO &info) virtual _F_TCPSERVER_newclient( )=0; #define _F_TCPSERVER_endclient(x) void x endclient(int no, bool &endserver, TCPSERVER_INFO &info) virtual _F_TCPSERVER_endclient( ); #define _F_TCPSERVER_receive(x) void x receive(int no, const char *line, bool &endclient, bool &endserver, int &state, TCPSERVER_INFO &info) virtual _F_TCPSERVER_receive( )=0; #define _F_TCPSERVER_idle(x) void x idle(int since, bool &endserver, TCPSERVER_INFO &info) virtual _F_TCPSERVER_idle( ); #define _F_TCPSERVER_time_out(x) void x time_out(int no, bool &endserver, TCPSERVER_INFO &info) virtual _F_TCPSERVER_time_out( ); }; class TCPSERVER: public HANDLE_SELECTS{ class TCPSERVER_PRIVATE *priv; /*~PROTOBEG~ TCPSERVER */ public: TCPSERVER (_F_TCPSERVER&c); TCPSERVER (_F_TCPSERVER&c, const char *bindaddr, const char *port, int time_out); TCPSERVER (_F_TCPSERVER&c, const char *port, int time_out); TCPSERVER (_F_TCPSERVER&c, int port, int time_out); private: void accept_con (int i, bool&endserver, TLMPEPOLL *ep); public: void closeclient (int cli); private: bool dispatch (int select_ret, fd_set&set); void endsession (int cli); public: void forget_epoll (void); int getlistenport (void); int getnbclients (void)const; private: void init (_F_TCPSERVER&c, const char *bindaddr, const char *port, int time_out); public: void inject (int client); void inject (int client, ARRAY_OBJ *data); void inject_output (int handle); bool is_blocked (int fd, unsigned long &size, long long &last_write); bool is_ok (void); bool islistening (int handle); int iter_init (void *&data); int iter_init (void); int iter_next (void *&data); int iter_next (void); int listen (const char *bindaddr, const char *port); int listen (const char *port); int listen (int port); void loop (void); private: void process_data (int fd, bool&endserver); void process_end (int fd, bool&endserver, bool is_timeout); public: bool process_epoll (TLMPEPOLL&ep, TLMPEPOLL_EVENT events[], int nbevent); void process_select (int select_ret, fd_set&set, long timeout); int sendall (const char *s); int sendall (const void *s, int len); int sendallf (const char *ctl, ...); int sendto (int client, const char *line); int sendto (int client, const void *buf, int len); int sendtof (int client, const char *ctl, ...); bool setlisten (int handle, bool on); void setmaxclients (int n); bool setnonblock (bool mode, int bufsize); bool setrawmode (bool mode); void setup_epoll (TLMPEPOLL&ep); int setup_select (fd_set&set, int max_handle); virtual ~TCPSERVER (void); /*~PROTOEND~ TCPSERVER */ }; struct TCPSERVER_V1_INFO{ const char *port; class ARRAY_OBJ *data; // Per connection data, manage by the caller // deleted by TCPCONNECT. const char *rest; // Stuff to process still in the buffer int linelen; // Length of line for the receive // functag bool force_end; // Connection was killed by the server // (endclient=true) int listenhandle; // For newclient, tells the handle used to connect TCPSERVER_V1_INFO(); }; enum TCPSERVER_EVENT{ TCPSERVER_OUTFULL, // Please stop outputing, congestion somewhere TCPSERVER_OUTOK, // Now half full, can resume outputing TCPSERVER_OUTFLUSHED, // All remaining buffers are written and accepted by the OS }; struct _F_TCPSERVER_V1{ class TCPSERVER_V1_PRIVATE *priv; void settcpnodelay(bool on); void settcpnodelay(int no, bool on); int send (const char *s); int send (const void *b, int len); int sendf (const char *ctl, ...); int sendall (const char *s); int sendall (const void *b, int len); int sendallf (const char *ctl, ...); int sendto (int client, const char *s); int sendto (int client, const void *b, int len); int sendtof (int client, const char *ctl, ...); void set_timeout (int nbseconds); void forgetclient(); void closeclient (int cli); int getnbclients(); bool setrawmode (bool mode); bool setrawmode (int no, bool mode); void inject (int newclient, ARRAY_OBJ *data); void inject_output(int handle); void endsession (int client); int getnbpending(); ARRAY_OBJ *getclientdata(int no); int iter_init(void *&data); int iter_init(); int iter_next(void *&data); int iter_next(); bool is_blocked(); bool is_blocked(int handle, unsigned long &size, long long &lastwrite); bool setlisten (int handle, bool on); bool islistening (int handle); int listenfd(int fd, const char *port); #define _F_TCPSERVER_V1_newclient(x) void x newclient(int no, unsigned long from, bool &endclient, bool &endserver, TCPSERVER_V1_INFO &info) virtual _F_TCPSERVER_V1_newclient( )=0; #define _F_TCPSERVER_V1_endclient(x) void x endclient(int no, bool &endserver, TCPSERVER_V1_INFO &info) virtual _F_TCPSERVER_V1_endclient( ); #define _F_TCPSERVER_V1_receive(x) void x receive(int no, const char *line, bool &endclient, bool &endserver, int &state, TCPSERVER_V1_INFO &info) virtual _F_TCPSERVER_V1_receive( )=0; #define _F_TCPSERVER_V1_idle(x) void x idle(int since, bool &endserver, TCPSERVER_V1_INFO &info) virtual _F_TCPSERVER_V1_idle( ); #define _F_TCPSERVER_V1_time_out(x) void x time_out(int no, bool &endserver, TCPSERVER_V1_INFO &info) virtual _F_TCPSERVER_V1_time_out( ); #define _F_TCPSERVER_V1_event(x) void x event(int no, TCPSERVER_EVENT ev, bool &endserver, bool &endclient, ARRAY_OBJ *&data) virtual _F_TCPSERVER_V1_event( ); }; class TCPSERVER_V1: public HANDLE_SELECTS{ class TCPSERVER_V1_PRIVATE *priv; /*~PROTOBEG~ TCPSERVER_V1 */ public: TCPSERVER_V1 (_F_TCPSERVER_V1&c); TCPSERVER_V1 (_F_TCPSERVER_V1&c, const char *bindaddr, const char *port, int time_out); TCPSERVER_V1 (_F_TCPSERVER_V1&c, const char *port, int time_out); TCPSERVER_V1 (_F_TCPSERVER_V1&c, int port, int time_out); private: void accept_con (int i, bool&endserver, TLMPEPOLL *ep); public: void closeclient (int cli); private: bool dispatch (int select_ret, fd_set&set); void endsession (int cli); public: void forget_epoll (void); int getlistenport (void); int getnbclients (void)const; private: void init (_F_TCPSERVER_V1&c, const char *bindaddr, const char *port, int time_out); public: void inject (int client); void inject (int client, ARRAY_OBJ *data); void inject_output (int handle); bool is_blocked (int fd, unsigned long &size, long long &last_write); bool is_ok (void); bool islistening (int handle); int iter_init (void *&data); int iter_init (void); int iter_next (void *&data); int iter_next (void); int listen (const char *bindaddr, const char *port); int listen (const char *port); int listen (int port); int listenfd(int fd, const char *port); void loop (void); private: void process_data (int fd, bool&endserver); void process_end (int fd, bool&endserver, bool is_timeout, bool force_end); void process_ending (bool&endserver); public: bool process_epoll (TLMPEPOLL&ep, TLMPEPOLL_EVENT events[], int nbevent); void process_select (int select_ret, fd_set&set, long timeout); int sendall (const char *s); int sendall (const void *s, int len); int sendallf (const char *ctl, ...); int sendto (int client, const char *line); int sendto (int client, const void *buf, int len); int sendtof (int client, const char *ctl, ...); bool setlisten (int handle, bool on); void setmaxclients (int n); bool setnonblock (bool mode, int bufsize); bool setrawmode (bool mode); bool setrawmode (int no, bool mode); void setup_epoll (TLMPEPOLL&ep); int setup_select (fd_set&set, int max_handle); virtual ~TCPSERVER_V1 (void); /*~PROTOEND~ TCPSERVER_V1 */ }; class POPENFD; #define _TLMP_POPENHANDLER struct _F_POPENHANDLER{ class POPENHANDLER_PRIVATE *priv; #define _F_POPENHANDLER_oneline(x) void x oneline (POPENFD *pop, const char *line, int noline) virtual _F_POPENHANDLER_oneline( )=0; #define _F_POPENHANDLER_oneerr(x) void x oneerr (POPENFD *pop, const char *line) virtual _F_POPENHANDLER_oneerr( ); #define _F_POPENHANDLER_end(x) void x end (POPENFD *pop) virtual _F_POPENHANDLER_end( ); }; class POPENHANDLER: public HANDLE_SELECTS{ class POPENHANDLER_PRIVATE *priv; /*~PROTOBEG~ POPENHANDLER */ public: POPENHANDLER (_F_POPENHANDLER&c); void add (POPENFD *pop); int getrunning (void); void process_select (int select_ret, fd_set&set, long timeout); int setup_select (fd_set&set, int max_handle); virtual ~POPENHANDLER (void); /*~PROTOEND~ POPENHANDLER */ }; #define _TLMP_NETEVENT_MANAGER struct _F_NETEVENT_MANAGER{ class NETEVENT_MANAGER_PRIVATE *priv; #define _F_NETEVENT_MANAGER_idle(x) void x idle(int since, bool &end, bool nojob) virtual _F_NETEVENT_MANAGER_idle( ); }; class NETEVENT_MANAGER{ class NETEVENT_MANAGER_PRIVATE *priv; /*~PROTOBEG~ NETEVENT_MANAGER */ public: NETEVENT_MANAGER (_F_NETEVENT_MANAGER&c); void add (HANDLE_SELECTS&sels); void add (TCPSERVER&tcp); void add (TCPSERVER_V1&tcp); void loop (int timeout); private: void loopgen (int timeout, bool gui, PRIVATE_MESSAGE&endmsg); public: void loopgui (int timeout, PRIVATE_MESSAGE&endmsg); ~NETEVENT_MANAGER (void); /*~PROTOEND~ NETEVENT_MANAGER */ }; #define _TLMP_http_get #ifndef MISC_H #include #endif struct HTTP_HEADER_INFO { SSTRING url; SSTRING proto; // Protocol part of the URL (default http) SSTRING host; // Host part of the URL SSTRING port; // Port, generally "80" SSTRING path; // File path of the URL SSTRINGS header; // Header lines received (usable only in oneline) SSTRING contenttype; bool is_data; }; struct _F_http_get { class _F_http_get_private *priv; void reget(const char *path); // Get one more thing using the same // connection #define _F_http_get_fail(x) void x fail(const HTTP_HEADER_INFO &info, const char *msg) virtual _F_http_get_fail( ); #define _F_http_get_header(x) void x header(const char *line, int len, const HTTP_HEADER_INFO &info, bool &end) virtual _F_http_get_header( ); #define _F_http_get_oneline(x) void x oneline(const char *line, int len, const HTTP_HEADER_INFO &info, bool &end) virtual _F_http_get_oneline( )=0; #define _F_http_get_end(x) void x end(const HTTP_HEADER_INFO &info) virtual _F_http_get_end( ); }; extern const char *INETD_PORT; #include "tlmpnet.p" #endif