Removed the logging facility from citserver, use syslog instead
[citadel.git] / citadel / event_client.h
1 #ifndef __EVENT_CLIENT_H__
2 #define __EVENT_CLIENT_H__
3 #define EV_COMPAT3 0
4 #include <ev.h>
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <netdb.h>
8 #include <arpa/nameser.h>
9 #include <ares.h>
10 #include <curl/curl.h>
11
12 typedef struct AsyncIO AsyncIO;
13
14 typedef enum _eNextState {
15         eSendDNSQuery,
16         eReadDNSReply,
17         eDBQuery,
18         eConnect,
19         eSendReply, 
20         eSendMore,
21         eReadMessage, 
22         eReadMore,
23         eReadPayload,
24         eTerminateConnection,
25         eAbort
26 }eNextState;
27
28 typedef eNextState (*IO_CallBack)(AsyncIO *IO);
29 typedef eReadState (*IO_LineReaderCallback)(AsyncIO *IO);
30 typedef void (*ParseDNSAnswerCb)(AsyncIO*, unsigned char*, int);
31 typedef void (*FreeDNSReply)(void *DNSData);
32
33
34 typedef struct __ReadAsyncMsg {
35         StrBuf *MsgBuf;
36         size_t maxlen;          /* maximum message length */
37
38         const char *terminator; /* token signalling EOT */
39         long tlen;
40         int dodot;
41
42         int flushing;           /* if we read maxlen, read until nothing more arives and ignore this. */
43
44         int crlf;               /* CRLF newlines instead of LF */
45 } ReadAsyncMsg;
46
47
48 typedef struct _DNSQueryParts {
49         ParseDNSAnswerCb DNS_CB;
50         IO_CallBack PostDNS;
51
52         int DNSStatus;
53         void *VParsedDNSReply;
54         FreeDNSReply DNSReplyFree;
55         void *Data;
56 } DNSQueryParts;
57
58 typedef struct _evcurl_request_data 
59 {
60         CURL              *chnd;
61         struct curl_slist *headers;
62         char               errdesc[CURL_ERROR_SIZE];
63
64         int                attached;
65
66         char              *PlainPostData;
67         long               PlainPostDataLen;
68         StrBuf            *PostData;
69
70         StrBuf            *ReplyData;
71         long               httpcode;
72 } evcurl_request_data;
73
74 struct AsyncIO {
75         eNextState NextState;
76
77         /* connection related */
78         ParsedURL *ConnectMe;
79         
80         /* read/send related... */
81         StrBuf *IOBuf;
82         IOBuffer SendBuf, 
83                 RecvBuf;
84
85         /* our events... */
86         ev_cleanup abort_by_shutdown, /* server wants to go down... */
87                 db_abort_by_shutdown; /* server wants to go down... */
88         ev_timer conn_fail,           /* connection establishing timed out */
89                 rw_timeout;           /* timeout while sending data */
90         ev_idle unwind_stack,         /* get c-ares out of the stack */
91                 db_unwind_stack,      /* wait for next db operation... */
92                 conn_fail_immediate;  /* unwind stack, but fail immediately. */
93         ev_io recv_event,             /* receive data from the client */
94                 send_event,           /* send more data to the client */
95                 conn_event;           /* Connection successfully established */
96
97         StrBuf *ErrMsg; /* if we fail to connect, or lookup, error goes here. */
98
99         /* Citadel application callbacks... */
100         IO_CallBack ReadDone, /* Theres new data to read... */
101                 SendDone,     /* we may send more data */
102                 Terminate,    /* shutting down... */
103                 Timeout,      /* Timeout handler; may also be connection timeout */
104                 ConnFail,     /* What to do when one connection failed? */
105                 ShutdownAbort,/* we're going down. make your piece. */ 
106                 NextDBOperation; /* Perform Database IO */
107
108         IO_LineReaderCallback LineReader; /* if we have linereaders, maybe we want to read more lines before the real application logic is called? */
109
110         /* DNS Related */
111         ev_io dns_recv_event, 
112                 dns_send_event;
113         struct ares_options DNSOptions;
114         ares_channel DNSChannel;
115         DNSQueryParts *DNSQuery;
116         
117         evcurl_request_data HttpReq;
118
119         /* Saving / loading a message async from / to disk */
120         ReadAsyncMsg *ReadMsg;
121         struct CtdlMessage *AsyncMsg;
122         struct recptypes *AsyncRcp;
123         /* Custom data; its expected to contain  AsyncIO so we can save malloc()s... */
124         void *Data;        /* application specific data */
125         void *CitContext;  /* Citadel Session context... */
126 };
127
128 typedef struct _IOAddHandler {
129         AsyncIO *IO;
130         IO_CallBack EvAttch;
131 }IOAddHandler; 
132
133 void FreeAsyncIOContents(AsyncIO *IO);
134
135 eNextState NextDBOperation(AsyncIO *IO, IO_CallBack CB);
136 eNextState QueueDBOperation(AsyncIO *IO, IO_CallBack CB);
137 eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB);
138 int ShutDownEventQueue(void);
139
140 eNextState InitEventIO(AsyncIO *IO, 
141                        void *pData, 
142                        double conn_timeout, 
143                        double first_rw_timeout,
144                        int ReadFirst);
145 void IO_postdns_callback(struct ev_loop *loop, ev_idle *watcher, int revents);
146
147 int QueueQuery(ns_type Type, const char *name, AsyncIO *IO, DNSQueryParts *QueryParts, IO_CallBack PostDNS);
148 void QueueGetHostByName(AsyncIO *IO, const char *Hostname, DNSQueryParts *QueryParts, IO_CallBack PostDNS);
149
150 void QueryCbDone(AsyncIO *IO);
151
152 void StopClient(AsyncIO *IO);
153
154 void StopClientWatchers(AsyncIO *IO);
155
156 void SetNextTimeout(AsyncIO *IO, double timeout);
157
158 void InitC_ares_dns(AsyncIO *IO);
159
160 #include <curl/curl.h>
161
162 #define OPT(s, v) \
163         do { \
164                 sta = curl_easy_setopt(chnd, (CURLOPT_##s), (v)); \
165                 if (sta)  {                                             \
166                         syslog(LOG_ERR, "error setting option " #s " on curl handle: %s", curl_easy_strerror(sta)); \
167         } } while (0)
168
169
170 int evcurl_init(AsyncIO *IO, 
171                 void *CustomData, 
172                 const char* Desc,
173                 IO_CallBack CallBack, 
174                 IO_CallBack Terminate);
175
176 eNextState ReAttachIO(AsyncIO *IO, 
177                       void *pData, 
178                       int ReadFirst);
179
180 void evcurl_handle_start(AsyncIO *IO);
181
182 #endif /* __EVENT_CLIENT_H__ */