Readloop remove special cases
[citadel.git] / libcitadel / lib / libcitadel.h
index 8c6f726a7e04f8ed59a2869478c25114c2bf6a77..d520eae4c96d8733104465bc58402629ada5b796 100644 (file)
@@ -1,6 +1,15 @@
 /*
- * $Id$
+ * Header file for libcitadel
  *
+ * Copyright (c) 1987-2012 by the citadel.org team
+ *
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ *
+ * 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.
  */
 
 
 #include <time.h>
 #include <stdlib.h>
 #include <stdarg.h>
-#define LIBCITADEL_VERSION_NUMBER      770
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#define LIBCITADEL_VERSION_NUMBER      810
 
 /*
  * Here's a bunch of stupid magic to make the MIME parser portable.
 #endif
 
 
-/* Logging levels - correspond to syslog(3) */
-enum LogLevel {
-       /* When about to exit the server for an unrecoverable error */
-        CTDL_EMERG,    /* system is unusable */
-       /* Manual intervention is required to avoid an abnormal exit */
-        CTDL_ALERT,    /* action must be taken immediately */
-       /* The server can continue to run with degraded functionality */
-        CTDL_CRIT,     /* critical conditions */
-       /* An error occurs but the server continues to run normally */
-        CTDL_ERR,      /* error conditions */
-       /* An abnormal condition was detected; server will continue normally */
-        CTDL_WARNING,  /* warning conditions */
-       /* Normal messages (login/out, activity, etc.) */
-        CTDL_NOTICE,   /* normal but significant condition */
-       /* Unimportant progress messages, etc. */
-        CTDL_INFO,     /* informational */
-       /* Debugging messages */
-        CTDL_DEBUG     /* debug-level messages */
+typedef enum AXLevel {
+       AxDeleted = 0,
+       AxNewU = 1,
+       AxProbU = 2,
+       AxLocU = 3,
+       AxNetU = 4,
+       AxPrefU = 5,
+       AxAideU = 6
+}eUsrAxlvl;
+
+enum RoomNetCfg {
+       subpending,
+       unsubpending,
+       lastsent, /* Server internal use only */
+       ignet_push_share,
+       listrecp,
+       digestrecp,
+       pop3client,
+       rssclient,
+       participate,
+       maxRoomNetCfg
+};
+
+enum GNET_POP3_PARTS { /* pop3client splits into these columns: */
+       GNET_POP3_HOST = 1,
+       GNET_POP3_USER = 2,
+       GNET_POP3_PASS = 4,
+       GNET_POP3_DONT_DELETE_REMOTE = 4,
+       GNET_POP3_INTERVAL = 5
+};
+
+enum GNET_PUSH_SHARE { /* ignet_push_share splits into these columns: */
+       GNET_IGNET_NODE = 1,
+       GNET_IGNET_ROOM = 2
 };
 
+typedef enum __GPEXWhichPolicy {
+       roompolicy,
+       floorpolicy,
+       sitepolicy,
+       mailboxespolicy,
+       maxpolicy
+}GPEXWhichPolicy;
 
 /*
  * View definitions.
  * Note that not all views are implemented in all clients.
  */
-#define        VIEW_BBS                0       /* Bulletin board view */
-#define VIEW_MAILBOX           1       /* Mailbox summary */
-#define VIEW_ADDRESSBOOK       2       /* Address book view */
-#define VIEW_CALENDAR          3       /* Calendar view */
-#define VIEW_TASKS             4       /* Tasks view */
-#define VIEW_NOTES             5       /* Notes view */
-#define        VIEW_WIKI               6       /* Wiki view */
-#define VIEW_CALBRIEF          7       /* Brief Calendar view */
-#define VIEW_JOURNAL           8       /* Journal view */
-
+typedef enum _room_views {
+       VIEW_BBS                = 0,    /* Bulletin board view */
+       VIEW_MAILBOX            = 1,    /* Mailbox summary */
+       VIEW_ADDRESSBOOK        = 2,    /* Address book view */
+       VIEW_CALENDAR           = 3,    /* Calendar view */
+       VIEW_TASKS              = 4,    /* Tasks view */
+       VIEW_NOTES              = 5,    /* Notes view */
+       VIEW_WIKI               = 6,    /* Wiki view */
+       VIEW_CALBRIEF           = 7,    /* Brief Calendar view */
+       VIEW_JOURNAL            = 8,    /* Journal view */
+       VIEW_DRAFTS             = 9,    /* Drafts view */
+       VIEW_BLOG               = 10,   /* Blog view */
+       VIEW_QUEUE              = 11,   /* SMTP/... QUEUE rooms */
+       VIEW_MAX,
+       VIEW_JSON_LIST,
+} ROOM_VIEWS;
+
+#define BLOG_EUIDBUF_SIZE      40
 
 #ifndef IsEmptyStr
 #define IsEmptyStr(a) ((a)[0] == '\0')
 #endif
 
+
 /*
  * another word to indicate n/a for a pointer if NULL already has a "meaning"
  */
@@ -83,48 +128,27 @@ void ShutDownLibCitadel(void);
  * MIME parser declarations
  */
 
-void extract_key(char *target, char *source, long sourcelen, char *key, long keylen);
+long extract_key(char *target, char *source, long sourcelen, char *key, long keylen, char KeyEnd);
+
+
+typedef void (*MimeParserCallBackType)(char *cbname,
+                                      char *cbfilename,
+                                      char *cbpartnum,
+                                      char *cbdisp,
+                                      void *cbcontent,
+                                      char *cbtype,
+                                      char *cbcharset,
+                                      size_t cblength,
+                                      char *cbencoding,
+                                      char *cbid,
+                                      void *cbuserdata);
 
 void mime_parser(char *content_start, char *content_end,
-               void (*CallBack)
-                       (char *cbname,
-                       char *cbfilename,
-                       char *cbpartnum,
-                       char *cbdisp,
-                       void *cbcontent,
-                       char *cbtype,
-                       char *cbcharset,
-                       size_t cblength,
-                       char *cbencoding,
-                       char *cbid,
-                       void *cbuserdata),
-               void (*PreMultiPartCallBack)
-                       (char *cbname,
-                       char *cbfilename,
-                       char *cbpartnum,
-                       char *cbdisp,
-                       void *cbcontent,
-                       char *cbtype,
-                       char *cbcharset,
-                       size_t cblength,
-                       char *cbencoding,
-                       char *cbid,
-                       void *cbuserdata),
-               void (*PostMultiPartCallBack)
-                       (char *cbname,
-                       char *cbfilename,
-                       char *cbpartnum,
-                       char *cbdisp,
-                       void *cbcontent,
-                       char *cbtype,
-                       char *cbcharset,
-                       size_t cblength,
-                       char *cbencoding,
-                       char *cbid,
-                       void *cbuserdata),
-               void *userdata,
-               int dont_decode
-);
+                MimeParserCallBackType CallBack,
+                MimeParserCallBackType PreMultiPartCallBack,
+                MimeParserCallBackType PostMultiPartCallBack,
+                void *userdata,
+                int dont_decode);
 
 
 
@@ -135,89 +159,28 @@ void mime_decode(char *partnum,
                 char *disposition,
                 char *id,
                 char *name, char *filename,
-                void (*CallBack)
-                 (char *cbname,
-                  char *cbfilename,
-                  char *cbpartnum,
-                  char *cbdisp,
-                  void *cbcontent,
-                  char *cbtype,
-                  char *cbcharset,
-                  size_t cblength,
-                  char *cbencoding,
-                  char *cbid,
-                  void *cbuserdata),
-                void (*PreMultiPartCallBack)
-                 (char *cbname,
-                  char *cbfilename,
-                  char *cbpartnum,
-                  char *cbdisp,
-                  void *cbcontent,
-                  char *cbtype,
-                  char *cbcharset,
-                  size_t cblength,
-                  char *cbencoding,
-                  char *cbid,
-                  void *cbuserdata),
-                void (*PostMultiPartCallBack)
-                 (char *cbname,
-                  char *cbfilename,
-                  char *cbpartnum,
-                  char *cbdisp,
-                  void *cbcontent,
-                  char *cbtype,
-                  char *cbcharset,
-                  size_t cblength,
-                  char *cbencoding,
-                  char *cbid,
-                  void *cbuserdata),
-                 void *userdata,
-                 int dont_decode
-);
+                MimeParserCallBackType CallBack,
+                MimeParserCallBackType PreMultiPartCallBack,
+                MimeParserCallBackType PostMultiPartCallBack,
+                void *userdata,
+                int dont_decode);
+int mime_decode_now (char *part_start, 
+                    size_t length,
+                    char *encoding,
+                    char **decoded,
+                    size_t *bytes_decoded);
 void the_mime_parser(char *partnum,
                     char *content_start, char *content_end,
-                    void (*CallBack)
-                     (char *cbname,
-                      char *cbfilename,
-                      char *cbpartnum,
-                      char *cbdisp,
-                      void *cbcontent,
-                      char *cbtype,
-                      char *cbcharset,
-                      size_t cblength,
-                      char *cbencoding,
-                      char *cbid,
-                      void *cbuserdata),
-                    void (*PreMultiPartCallBack)
-                     (char *cbname,
-                      char *cbfilename,
-                      char *cbpartnum,
-                      char *cbdisp,
-                      void *cbcontent,
-                      char *cbtype,
-                      char *cbcharset,
-                      size_t cblength,
-                      char *cbencoding,
-                      char *cbid,
-                      void *cbuserdata),
-                    void (*PostMultiPartCallBack)
-                     (char *cbname,
-                      char *cbfilename,
-                      char *cbpartnum,
-                      char *cbdisp,
-                      void *cbcontent,
-                      char *cbtype,
-                      char *cbcharset,
-                      size_t cblength,
-                      char *cbencoding,
-                      char *cbid,
-                      void *cbuserdata),
-                     void *userdata,
-                     int dont_decode
-);
+                    MimeParserCallBackType CallBack,
+                    MimeParserCallBackType PreMultiPartCallBack,
+                    MimeParserCallBackType PostMultiPartCallBack,
+                    void *userdata,
+                    int dont_decode);
 
 typedef struct StrBuf StrBuf;
 
+#define strof(a) #a
+#define CStrOf(a) #a, sizeof(#a) - 1
 typedef struct _ConstStr {
        const char *Key;
        long len;
@@ -229,6 +192,7 @@ StrBuf* NewStrBufDup(const StrBuf *CopyMe);
 StrBuf* NewStrBufPlain(const char* ptr, int nChars);
 long StrBufShrinkToFit(StrBuf *Buf, int Force);
 void ReAdjustEmptyBuf(StrBuf *Buf, long ThreshHold, long NewSize);
+void NewStrBufDupAppendFlush(StrBuf **CreateRelpaceMe, StrBuf *CopyFlushMe, const char *NoMe, int KeepOriginal);
 
 int StrBufPlain(StrBuf *Buf, const char* ptr, int nChars);
 StrBuf* _NewConstStrBuf(const char* StringConstant, size_t SizeOfStrConstant);
@@ -243,6 +207,7 @@ const char *ChrPtr(const StrBuf *Str);
 int StrLength(const StrBuf *Str);
 #define SKEY(a) ChrPtr(a), StrLength(a)
 long StrBufPeek(StrBuf *Buf, const char* ptr, long nThChar, char PeekValue);
+long StrBufPook(StrBuf *Buf, const char* ptr, long nThChar, long nChars, char PookValue);
 
 int StrBufTCP_read_line(StrBuf *buf, int *fd, int append, const char **Error);
 int StrBufReadBLOB(StrBuf *Buf, int *fd, int append, long nBytes, const char **Error);
@@ -270,7 +235,49 @@ int StrBufTCP_read_buffered_line_fast(StrBuf *Line,
                                      int selectresolution, 
                                      const char **Error);
 
-int StrBufSipLine(StrBuf *LineBuf, StrBuf *Buf, const char **Ptr);
+typedef enum _eReadState {
+       eReadFail,
+       eReadSuccess,
+       eMustReadMore, 
+       eBufferNotEmpty
+} eReadState;
+
+typedef struct _file_buffer {
+       StrBuf *Buf;
+       const char *ReadWritePointer;
+       int fd;
+       int LineCompleted;
+       int nBlobBytesWanted;
+} IOBuffer;
+
+
+typedef struct __fd_iobuffer {
+       IOBuffer *IOB;
+       int OtherFD;
+       int SplicePipe[2];
+       long TotalSendSize;
+       long TotalSentAlready;
+       long ChunkSize;
+       long ChunkSendRemain;
+       StrBuf *ChunkBuffer; /* just used if we don't have sendfile */
+} FDIOBuffer;
+
+
+void FDIOBufferInit(FDIOBuffer *FDB, IOBuffer *IO, int FD, long TotalSendSize);
+void FDIOBufferDelete(FDIOBuffer *FDB);
+int FileSendChunked(FDIOBuffer *FDB, const char **Err);
+int FileRecvChunked(FDIOBuffer *FDB, const char **Err);
+eReadState WriteIOBAlreadyRead(FDIOBuffer *FDB, const char **Error);
+
+long StrBuf_read_one_chunk_callback (int fd, short event, IOBuffer *FB);
+int StrBuf_write_one_chunk_callback(int fd, short event, IOBuffer *FB);
+
+eReadState StrBufChunkSipLine(StrBuf *LineBuf, IOBuffer *FB);
+eReadState StrBufCheckBuffer(IOBuffer *FB);
+long IOBufferStrLength(IOBuffer *FB);
+
+int StrBufSipLine(StrBuf *LineBuf, const StrBuf *Buf, const char **Ptr);
+int StrBufReplaceToken(StrBuf *Buf, long where, long HowLong, const char *Repl, long ReplLen);
 int StrBufExtract_token(StrBuf *dest, const StrBuf *Source, int parmnum, char separator);
 int StrBufSub(StrBuf *dest, const StrBuf *Source, unsigned long Offset, size_t nChars);
 
@@ -301,26 +308,43 @@ void StrBufCutLeft(StrBuf *Buf, int nChars);
 void StrBufCutRight(StrBuf *Buf, int nChars);
 void StrBufCutAt(StrBuf *Buf, int AfternChars, const char *At);
 void StrBufTrim(StrBuf *Buf);
+void StrBufSpaceToBlank(StrBuf *Buf);
+void StrBufStripAllBut(StrBuf *Buf, char leftboundary, char rightboundary);
 void StrBufUpCase(StrBuf *Buf);
 void StrBufLowerCase(StrBuf *Buf);
 void StrBufStripSlashes(StrBuf *Dir, int RemoveTrailingSlash);
 void StrBufEUid_unescapize(StrBuf *target, const StrBuf *source);
 void StrBufEUid_escapize(StrBuf *target, const StrBuf *source);
 
+void StrBufToUnixLF(StrBuf *buf);
 void StrBufReplaceChars(StrBuf *buf, char search, char replace);
 
 int CompressBuffer(StrBuf *Buf);
 void StrBufConvert(StrBuf *ConvertBuf, StrBuf *TmpBuf, void *pic);
 void ctdl_iconv_open(const char *tocode, const char *fromcode, void *pic);
+void StrBuf_RFC822_2_Utf8(StrBuf *Target, 
+                         const StrBuf *DecodeMe, 
+                         const StrBuf* DefaultCharset, 
+                         StrBuf *FoundCharset, 
+                         StrBuf *ConvertBuf, 
+                         StrBuf *ConvertBuf2);
+/* deprecated old version: */
 void StrBuf_RFC822_to_Utf8(StrBuf *Target, const StrBuf *DecodeMe, const StrBuf* DefaultCharset, StrBuf *FoundCharset);
+
 int StrBufDecodeBase64(StrBuf *Buf);
 int StrBufDecodeHex(StrBuf *Buf);
 int StrBufRFC2047encode(StrBuf **target, const StrBuf *source);
+StrBuf *StrBufSanitizeEmailRecipientVector(const StrBuf *Recp, 
+                                          StrBuf *UserName, 
+                                          StrBuf *EmailAddress,
+                                          StrBuf *EncBuf);
 int StrBufSanitizeAscii(StrBuf *Buf, const char Mute);
 #define LB                     (1)             /* Internal escape chars */
 #define RB                     (2)
 #define QU                     (3)
 void StrBufUrlescAppend(StrBuf *OutBuf, const StrBuf *In, const char *PlainIn);
+void StrBufHexescAppend(StrBuf *OutBuf, const StrBuf *In, const char *PlainIn);
+void StrBufHexEscAppend(StrBuf *OutBuf, const StrBuf *In, const unsigned char *PlainIn, long PlainInLen);
 long StrEscAppend(StrBuf *Target, const StrBuf *Source, const char *PlainIn, int nbsp, int nolinebreaks);
 long StrECMAEscAppend(StrBuf *Target, const StrBuf *Source, const char *PlainIn);
 long StrHtmlEcmaEscAppend(StrBuf *Target, const StrBuf *Source, const char *PlainIn, int nbsp, int nolinebreaks);
@@ -343,6 +367,31 @@ int LoadIconDir(const char *DirName);
 const char *GetIconFilename(char *MimeType, size_t len);
 
 
+/* URL parsing & connection data */
+typedef struct ParsedURL ParsedURL;
+struct ParsedURL {
+       int Priority;
+       StrBuf *URL;
+       StrBuf *UrlWithoutCred;
+       StrBuf *CurlCreds;
+       unsigned Port;
+       const char *Host;
+       const char *User;
+       const char *Pass;
+       const char *LocalPart;
+       const char *PlainUrl;
+       int IsIP;
+       int IPv6;
+       int af;
+       struct hostent *HEnt;
+       struct sockaddr_in6 Addr;
+       ParsedURL *Next;
+};
+
+void FreeURL(ParsedURL** Url);
+int ParseURL(ParsedURL **Url, StrBuf *UrlStr, unsigned short DefaultPort);
+void CurlPrepareURL(ParsedURL *Url);
+
 /* tools */
 
 
@@ -366,23 +415,27 @@ void fmt_date(char *buf, size_t n, time_t thetime, int seconds);
 int is_msg_in_sequence_set(const char *mset, long msgnum);
 char *memreadline(char *start, char *buf, int maxlen);
 char *memreadlinelen(char *start, char *buf, int maxlen, int *retlen);
+const char *cmemreadline(const char *start, char *buf, int maxlen);
+const char *cmemreadlinelen(const char *start, char *buf, int maxlen, int *retlen);
 #define IsEmptyStr(a) ((a)[0] == '\0')
 #define num_parms(source)              num_tokens(source,(char)'|')
 int stripout(char *str, char leftboundary, char rightboundary);
-void stripallbut(char *str, char leftboundary, char rightboundary);
+long stripallbut(char *str, char leftboundary, char rightboundary);
 char *myfgets(char *s, int size, FILE *stream);
 void urlesc(char *outbuf, size_t oblen, char *strbuf);
 char *CtdlTempFileName(char *prefix1, int prefix2);
 FILE *CtdlTempFile(void);
 void generate_uuid(char *buf);
-char *bmstrcasestr(char *text, char *pattern);
-char *bmstrcasestr_len(char *text, size_t textlen, char *pattern, size_t patlen);
+char *bmstrcasestr(char *text, const char *pattern);
+char *bmstrcasestr_len(char *text, size_t textlen, const char *pattern, size_t patlen);
+const char *cbmstrcasestr(const char *text, const char *pattern);
+const char *cbmstrcasestr_len(const char *text, size_t textlen, const char *pattern, size_t patlen);
 void CtdlMakeTempFileName(char *name, int len);
 char *rfc2047encode(char *line, long length);
 int is_msg_in_mset(const char *mset, long msgnum);
 int pattern2(char *search, char *patn);
 void stripltlen(char *, int *);
-char *html_to_ascii(char *inputmsg, int msglen, int screenwidth, int do_citaformat);
+char *html_to_ascii(const char *inputmsg, int msglen, int screenwidth, int do_citaformat);
 void LoadEntityList(char *FileName);
 
 
@@ -430,15 +483,20 @@ typedef struct HashPos HashPos;
 typedef void (*DeleteHashDataFunc)(void * Data);
 typedef const char *(*PrintHashContent)(void * Data);
 typedef int (*CompareFunc)(const void* Item1, const void*Item2);
-typedef int (*HashFunc)(const char *Str, long Len);
+typedef long (*HashFunc)(const char *Str, long Len);
 typedef void (*TransitionFunc) (void *Item1, void *Item2, int Odd);
 typedef void (*PrintHashDataFunc) (const char *Key, void *Item, int Odd);
 
-int Flathash(const char *str, long len);
+long Flathash(const char *str, long len);
+long lFlathash(const char *str, long len);
 #define IKEY(a) (const char*) &a, sizeof(a)
+#define LKEY(a) (const char*) &a, sizeof(a)
+
+int TestValidateHash(HashList *TestHash);
 
 HashList *NewHash(int Uniq, HashFunc F);
 void DeleteHash(HashList **Hash);
+void DeleteHashContent(HashList **Hash);
 void HDeleteHash(void *vHash);
 int GetHash(HashList *Hash, const char *HKey, long HKLen, void **Data);
 void Put(HashList *Hash, const char *HKey, long HKLen, void *Data, DeleteHashDataFunc DeleteIt);
@@ -451,6 +509,8 @@ int GetHashPosFromKey(HashList *Hash, const char *HKey, long HKLen, HashPos *At)
 int DeleteEntryFromHash(HashList *Hash, HashPos *At);
 int GetHashPosCounter(HashList *Hash, HashPos *At);
 void DeleteHashPos(HashPos **DelMe);
+int NextHashPos(HashList *Hash, HashPos *At);
+int GetHashPos(HashList *Hash, HashPos *At, long *HKLen, const char **HashKey, void **Data);
 int GetNextHashPos(HashList *Hash, HashPos *At, long *HKLen, const char **HashKey, void **Data);
 int GetHashAt(HashList *Hash,long At, long *HKLen, const char **HashKey, void **Data);
 void SortByHashKey(HashList *Hash, int Order);
@@ -458,12 +518,16 @@ void SortByHashKeyStr(HashList *Hash);
 int GetCount(HashList *Hash);
 const void *GetSearchPayload(const void *HashVoid);
 void SortByPayload(HashList *Hash, CompareFunc SortBy);
-void generic_free_handler(void *ptr);
 void reference_free_handler(void *ptr);
 int HashLittle(const void *key, size_t length);
 
+typedef struct MSet MSet;
+int ParseMSet(MSet **MsetList, StrBuf *MSetStr);
+int IsInMSetList(MSet *MSetList, long MsgNo);
+void DeleteMSet(MSet **FreeMe);
 
 void convert_spaces_to_underscores(char *str);
+int CheckEncode(const char *pch, long len, const char *pche);
 
 /*
  * Convert 4 bytes char into an Integer.
@@ -575,5 +639,13 @@ void WildFireSerializePayload(StrBuf *JsonBuffer, StrBuf *OutBuf, int *MsgCount,
 #define WF_STRUCTINDEX "1"
 #define WF_SUB "1"
 
+extern ConstStr RoomNetCfgStrs[maxRoomNetCfg];
+
+/* Convenience function to "perform a function and cut a log record if result != 0" */
+#define CtdlLogResult(x) if (x) syslog(LOG_CRIT, "%s:%d %s", __FILE__, __LINE__, strerror(errno))
+
+/* a nice consistent place to define how we turn a message id into a thread id hash */
+#define ThreadIdHash(Buf) abs(HashLittle(ChrPtr(Buf), StrLength(Buf)))
+
 
 #endif // LIBCITADEL_H