We need to have a definite number for the linenumber enums.
[citadel.git] / libcitadel / lib / libcitadel.h
index b16e3296c34f56f5b4a897b6690ffada67d2db88..0ee3df9d98d5e578777bdf1dde1e696505b91205 100644 (file)
@@ -1,5 +1,15 @@
 /*
  * Header file for libcitadel
+ *
+ * Copyright (c) 1987-2013 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 <stdlib.h>
 #include <stdarg.h>
 #include <arpa/inet.h>
-#include <libcitadel.h>
+#include <sys/types.h>
+#include <netinet/in.h>
 
-#define LIBCITADEL_VERSION_NUMBER      789
+#define LIBCITADEL_VERSION_NUMBER      829
 
 /*
  * 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,
@@ -57,18 +48,19 @@ typedef enum AXLevel {
        AxAideU = 6
 }eUsrAxlvl;
 
-enum RoomNetCfg {
-       subpending,
-       unsubpending,
-       lastsent, /* Server internal use only */
-       ignet_push_share,
-       listrecp,
-       digestrecp,
-       pop3client,
-       rssclient,
-       participate,
+typedef enum __RoomNetCfg {
+       subpending        = 0,
+       unsubpending      = 1,
+       lastsent          = 2, /* Server internal use only */
+       ignet_push_share  = 3,
+       listrecp          = 4,
+       digestrecp        = 5,
+       pop3client        = 6,
+       rssclient         = 7,
+       participate       = 8,
+       roommailalias     = 9,
        maxRoomNetCfg
-};
+} RoomNetCfg;
 
 enum GNET_POP3_PARTS { /* pop3client splits into these columns: */
        GNET_POP3_HOST = 1,
@@ -107,9 +99,13 @@ typedef enum _room_views {
        VIEW_JOURNAL            = 8,    /* Journal view */
        VIEW_DRAFTS             = 9,    /* Drafts view */
        VIEW_BLOG               = 10,   /* Blog view */
-       VIEW_MAX
+       VIEW_QUEUE              = 11,   /* SMTP/... QUEUE rooms */
+       VIEW_WIKIMD             = 12,   /* Markdown Wiki view */
+       VIEW_MAX,
+       VIEW_JSON_LIST,
 } ROOM_VIEWS;
 
+#define BLOG_EUIDBUF_SIZE      40
 
 #ifndef IsEmptyStr
 #define IsEmptyStr(a) ((a)[0] == '\0')
@@ -212,6 +208,7 @@ int FLUSHStrBuf(StrBuf *buf); /* expensive but doesn't leave content behind for
 const char *ChrPtr(const StrBuf *Str);
 int StrLength(const StrBuf *Str);
 #define SKEY(a) ChrPtr(a), StrLength(a)
+void StrBufAsciify(StrBuf *Buf, const char repl);
 long StrBufPeek(StrBuf *Buf, const char* ptr, long nThChar, char PeekValue);
 long StrBufPook(StrBuf *Buf, const char* ptr, long nThChar, long nChars, char PookValue);
 
@@ -241,9 +238,6 @@ 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,
@@ -259,14 +253,38 @@ typedef struct _file_buffer {
        int nBlobBytesWanted;
 } IOBuffer;
 
+
+typedef struct __fd_iobuffer {
+       IOBuffer *IOB;
+       int OtherFD;
+       int SplicePipe[2];
+       int PipeSize;
+       long TotalSendSize;
+       loff_t TotalSentAlready;
+       loff_t TotalReadAlready;
+       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);
+int FileMoveChunked(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_tokenFromStr(StrBuf *dest, const char *Source, long SourceLen, int parmnum, char separator);
 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);
 
@@ -320,8 +338,22 @@ void StrBuf_RFC822_2_Utf8(StrBuf *Target,
 /* deprecated old version: */
 void StrBuf_RFC822_to_Utf8(StrBuf *Target, const StrBuf *DecodeMe, const StrBuf* DefaultCharset, StrBuf *FoundCharset);
 
+typedef enum __eStreamType {
+       eBase64Encode,
+       eBase64Decode,
+       eZLibEncode,
+       eZLibDecode,
+       eEmtyCodec
+} eStreamType;
+
+void *StrBufNewStreamContext(eStreamType type);
+void StrBufDestroyStreamContext(eStreamType type, void **Stream);
+void StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, const char* pIn, long pInLen, void *Stream, int LastChunk);
+
 int StrBufDecodeBase64(StrBuf *Buf);
+int StrBufDecodeBase64To(const StrBuf *BufIn, StrBuf *BufOut);
 int StrBufDecodeHex(StrBuf *Buf);
+StrBuf *StrBufRFC2047encodeMessage(const StrBuf *EncodeMe);
 int StrBufRFC2047encode(StrBuf **target, const StrBuf *source);
 StrBuf *StrBufSanitizeEmailRecipientVector(const StrBuf *Recp, 
                                           StrBuf *UserName, 
@@ -332,7 +364,11 @@ int StrBufSanitizeAscii(StrBuf *Buf, const char Mute);
 #define RB                     (2)
 #define QU                     (3)
 void StrBufUrlescAppend(StrBuf *OutBuf, const StrBuf *In, const char *PlainIn);
+void StrBufUrlescUPAppend(StrBuf *OutBuf, const StrBuf *In, const char *PlainIn);
+void StrBufXMLEscAppend(StrBuf *OutBuf, const StrBuf *In, const char *PlainIn, long PlainInLen, int OverrideLowChars);
 void StrBufHexescAppend(StrBuf *OutBuf, const StrBuf *In, const char *PlainIn);
+void StrBufHexEscAppend(StrBuf *OutBuf, const StrBuf *In, const unsigned char *PlainIn, long PlainInLen);
+void StrBufBase64Append(StrBuf *OutBuf, const StrBuf *In, const char *PlainIn, long PlainInLen, int linebreaks);
 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);
@@ -358,22 +394,30 @@ 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 in6_addr Addr;
+       struct sockaddr_in6 Addr;
        ParsedURL *Next;
+       int IsRelay;
+       StrBuf *UsrName;
+       StrBuf *Password;
 };
 
 void FreeURL(ParsedURL** Url);
 int ParseURL(ParsedURL **Url, StrBuf *UrlStr, unsigned short DefaultPort);
+void CurlPrepareURL(ParsedURL *Url);
 
 /* tools */
 
@@ -414,7 +458,7 @@ char *bmstrcasestr_len(char *text, size_t textlen, const char *pattern, size_t p
 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);
+char *rfc2047encode(const char *line, long length);
 int is_msg_in_mset(const char *mset, long msgnum);
 int pattern2(char *search, char *patn);
 void stripltlen(char *, int *);
@@ -475,6 +519,8 @@ 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);
@@ -485,14 +531,15 @@ int GetKey(HashList *Hash, char *HKey, long HKLen, void **Data);
 int GetHashKeys(HashList *Hash, char ***List);
 int dbg_PrintHash(HashList *Hash, PrintHashContent first, PrintHashContent Second);
 int PrintHash(HashList *Hash, TransitionFunc Trans, PrintHashDataFunc PrintEntry);
-HashPos *GetNewHashPos(HashList *Hash, int StepWidth);
+HashPos *GetNewHashPos(const HashList *Hash, int StepWidth);
+void RewindHashPos(const HashList *Hash, HashPos *it, int StepWidth);
 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 GetNextHashPos(const 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);
 void SortByHashKeyStr(HashList *Hash);
@@ -622,4 +669,122 @@ void WildFireSerializePayload(StrBuf *JsonBuffer, StrBuf *OutBuf, int *MsgCount,
 
 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)))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CFG_SMTP_FROM_FILTERALL 0
+#define CFG_SMTP_FROM_NOFILTER 1
+#define CFG_SMTP_FROM_CORRECT 2
+#define CFG_SMTP_FROM_REJECT 3
+/*
+ * MIME types used in Citadel for configuration stuff
+ */
+#define SPOOLMIME      "application/x-citadel-delivery-list"
+#define        INTERNETCFG     "application/x-citadel-internet-config"
+#define IGNETCFG       "application/x-citadel-ignet-config"
+#define IGNETMAP       "application/x-citadel-ignet-map"
+#define FILTERLIST     "application/x-citadel-filter-list"
+#define SIEVECONFIG    "application/x-citadel-sieve-config"
+#define XMPPMORTUARY   "application/x-citadel-xmpp-mortuary"
+#define INTERNETCFG     "application/x-citadel-internet-config"
+
+#define FILE_MAILALIAS       "__MAIL_ALIAS__"
+
+#define LISTING_FOLLOWS                100
+#define CIT_OK                 200
+#define MORE_DATA              300
+#define SEND_LISTING           400
+#define ERROR                  500
+#define BINARY_FOLLOWS         600
+#define SEND_BINARY            700
+#define START_CHAT_MODE                800
+
+#define INTERNAL_ERROR         10
+#define TOO_BIG                        11
+#define ILLEGAL_VALUE          12
+#define NOT_LOGGED_IN          20
+#define CMD_NOT_SUPPORTED      30
+#define SERVER_SHUTTING_DOWN   31
+#define PASSWORD_REQUIRED      40
+#define ALREADY_LOGGED_IN      41
+#define USERNAME_REQUIRED      42
+#define HIGHER_ACCESS_REQUIRED 50
+#define MAX_SESSIONS_EXCEEDED  51
+#define RESOURCE_BUSY          52
+#define RESOURCE_NOT_OPEN      53
+#define NOT_HERE               60
+#define INVALID_FLOOR_OPERATION        61
+#define NO_SUCH_USER           70
+#define FILE_NOT_FOUND         71
+#define ROOM_NOT_FOUND         72
+#define NO_SUCH_SYSTEM         73
+#define ALREADY_EXISTS         74
+#define MESSAGE_NOT_FOUND      75
+
+#define ASYNC_MSG              900
+#define ASYNC_GEXP             02
+
+#define QR_PERMANENT   1               /* Room does not purge              */
+#define QR_INUSE       2               /* Set if in use, clear if avail    */
+#define QR_PRIVATE     4               /* Set for any type of private room */
+#define QR_PASSWORDED  8               /* Set if there's a password too    */
+#define QR_GUESSNAME   16              /* Set if it's a guessname room     */
+#define QR_DIRECTORY   32              /* Directory room                   */
+#define QR_UPLOAD      64              /* Allowed to upload                */
+#define QR_DOWNLOAD    128             /* Allowed to download              */
+#define QR_VISDIR      256             /* Visible directory                */
+#define QR_ANONONLY    512             /* Anonymous-Only room              */
+#define QR_ANONOPT     1024            /* Anonymous-Option room            */
+#define QR_NETWORK     2048            /* Shared network room              */
+#define QR_PREFONLY    4096            /* Preferred status needed to enter */
+#define QR_READONLY    8192            /* Admin status required to post     */
+#define QR_MAILBOX     16384           /* Set if this is a private mailbox */
+
+#define QR2_SYSTEM     1               /* System room; hide by default     */
+#define QR2_SELFLIST   2               /* Self-service mailing list mgmt   */
+#define QR2_COLLABDEL  4               /* Anyone who can post can delete   */
+#define QR2_SUBJECTREQ 8               /* Subject strongly recommended */
+#define QR2_SMTP_PUBLIC        16              /* Listservice Subscribers may post */
+#define QR2_MODERATED  32              /* Listservice aide has to permit posts  */
+
+#define US_NEEDVALID   1               /* User needs to be validated       */
+#define US_EXTEDIT     2               /* Always use external editor       */
+#define US_PERM                4               /* Permanent user                   */
+#define US_LASTOLD     16              /* Print last old message with new  */
+#define US_EXPERT      32              /* Experienced user                 */
+#define US_UNLISTED    64              /* Unlisted userlog entry           */
+#define US_NOPROMPT    128             /* Don't prompt after each message  */
+#define US_PROMPTCTL   256             /* <N>ext & <S>top work at prompt   */
+#define US_DISAPPEAR   512             /* Use "disappearing msg prompts"   */
+#define US_REGIS       1024            /* Registered user                  */
+#define US_PAGINATOR   2048            /* Pause after each screen of text  */
+#define US_INTERNET    4096            /* Internet mail privileges         */
+#define US_FLOORS      8192            /* User wants to see floors         */
+#define US_COLOR       16384           /* User wants ANSI color support    */
+#define US_USER_SET    (US_LASTOLD | US_EXPERT | US_UNLISTED | \
+                       US_NOPROMPT | US_DISAPPEAR | US_PAGINATOR | \
+                       US_FLOORS | US_COLOR | US_PROMPTCTL | US_EXTEDIT)
+
+#define UA_KNOWN                2      /* Room appears in a 'known rooms' list */
+#define UA_GOTOALLOWED          4      /* User may goto this room if specified by exact name */
+#define UA_HASNEWMSGS           8      /* Unread messages exist in this room */
+#define UA_ZAPPED               16     /* User has forgotten (zapped) this room */
+#define UA_POSTALLOWED         32      /* User may post top-level messages here */
+#define UA_ADMINALLOWED                64      /* Admin or Room Admin rights exist here */
+#define UA_DELETEALLOWED       128     /* User is allowed to delete messages from this room */
+#define UA_REPLYALLOWED                256     /* User is allowed to reply to existing messages here */
+/* runtime flag extracted from goto reply; not db persistant, should be moved if new flags added */
+#define UA_ISTRASH              512    /* Only available in room view... */
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif // LIBCITADEL_H