/*
* Header file for libcitadel
*
- * Copyright (c) 1987-2013 by the citadel.org team
+ * Copyright (c) 1987-2021 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.
* GNU General Public License for more details.
*/
-
/* protect against double includes */
#ifndef LIBCITADEL_H
#define LIBCITADEL_H
-
/*
* since we reference time_t...
*/
#include <sys/types.h>
#include <netinet/in.h>
-#define LIBCITADEL_VERSION_NUMBER 829
+#define LIBCITADEL_VERSION_NUMBER 945
/*
* Here's a bunch of stupid magic to make the MIME parser portable.
#define SIZ 4096
#endif
-
typedef enum AXLevel {
AxDeleted = 0,
AxNewU = 1,
}eUsrAxlvl;
typedef enum __RoomNetCfg {
- subpending,
- unsubpending,
- lastsent, /* Server internal use only */
- ignet_push_share,
- listrecp,
- digestrecp,
- pop3client,
- rssclient,
- participate,
- roommailalias,
+ 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;
#define BLOG_EUIDBUF_SIZE 40
#ifndef IsEmptyStr
-#define IsEmptyStr(a) ((a)[0] == '\0')
+#define IsEmptyStr(a) ( ( (a) == NULL ) || ((a)[0] == '\0') )
#endif
char *libcitadel_version_string(void);
int libcitadel_version_number(void);
-void StartLibCitadel(size_t basesize);
void ShutDownLibCitadel(void);
/*
void *userdata,
int dont_decode);
-
-
char *fixed_partnum(char *);
+
void mime_decode(char *partnum,
char *part_start, size_t length,
char *content_type, char *charset, char *encoding,
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,
MimeParserCallBackType CallBack,
StrBuf* NewStrBuf(void);
StrBuf* NewStrBufDup(const StrBuf *CopyMe);
StrBuf* NewStrBufPlain(const char* ptr, int nChars);
+void SwapBuffers(StrBuf *A, StrBuf *B);
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);
#define NewConstStrBuf(a) _NewConstStrBuf(a, sizeof(a))
void HFreeStrBuf (void *VFreeMe);
int FlushStrBuf(StrBuf *buf);
int FLUSHStrBuf(StrBuf *buf); /* expensive but doesn't leave content behind for others to find in case of errors */
-
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);
-
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);
#define NNN_TERM 1
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);
/* 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;
+
+typedef struct vStreamT vStreamT;
+vStreamT *StrBufNewStreamContext(eStreamType type, const char **Err);
+int StrBufDestroyStreamContext(eStreamType type, vStreamT **Stream, const char **Err);
+int StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, const char* pIn, long pInLen, vStreamT *Stream, int LastChunk, const char **Err);
+
int StrBufDecodeBase64(StrBuf *Buf);
+void StrBufDecodeQP(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);
size_t striplt(char *);
int haschar(const char *st, int ch);
void remove_token(char *source, int parmnum, char separator);
-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);
long stripallbut(char *str, char leftboundary, char rightboundary);
int is_msg_in_mset(const char *mset, long msgnum);
int pattern2(char *search, char *patn);
void stripltlen(char *, int *);
-char *html_to_ascii(const char *inputmsg, int msglen, int screenwidth, int do_citaformat);
+char *html_to_ascii(const char *inputmsg, int msglen, int screenwidth);
void LoadEntityList(char *FileName);
+typedef struct {
+ void *the_elements;
+ size_t element_size;
+ int num_elements;
+ int num_alloc;
+} Array;
+
+Array *array_new(size_t element_size);
+void array_free(Array *arr);
+void array_append(Array *arr, void *new_element);
+void *array_get_element_at(Array *arr, int index);
+int array_len(Array *arr);
+void array_sort(Array *arr, int (*compar)(const void *, const void *));
+void array_delete_element_at(Array *arr, int index);
+
/* vCard stuff */
struct vCard *vcard_new(void);
-void vcard_add_prop(struct vCard *v, char *propname, char *propvalue);
+void vcard_add_prop(struct vCard *v, const char *propname, const char *propvalue);
struct vCard *vcard_load(char *vtext);
struct vCard *VCardLoad(StrBuf *vbtext);
typedef int (*CompareFunc)(const void* Item1, const void*Item2);
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);
+typedef const char* (*PrintHashDataFunc) (const char *Key, void *Item, int Odd);
+long FourHash(const char *key, long length);
long Flathash(const char *str, long len);
long lFlathash(const char *str, long len);
#define IKEY(a) (const char*) &a, sizeof(a)
void Put(HashList *Hash, const char *HKey, long HKLen, void *Data, DeleteHashDataFunc DeleteIt);
int GetKey(HashList *Hash, char *HKey, long HKLen, void **Data);
int GetHashKeys(HashList *Hash, char ***List);
+const char *dbg_PrintStrBufPayload(const char *Key, void *Item, int Odd);
int dbg_PrintHash(HashList *Hash, PrintHashContent first, PrintHashContent Second);
int PrintHash(HashList *Hash, TransitionFunc Trans, PrintHashDataFunc PrintEntry);
HashPos *GetNewHashPos(const HashList *Hash, int StepWidth);
JsonValue *NewJsonBigNumber(const char *Key, long keylen, double Number);
-JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe);
+enum {
+ NEWJSONSTRING_COPYBUF, // make a copy of the StrBuf, source is left alone
+ NEWJSONSTRING_SMASHBUF // smash the source StrBuf, the json object now owns that memory
+};
+JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe, int copy_or_smash);
JsonValue *NewJsonPlainString(const char *Key, long keylen, const char *CopyMe, long len);
void SerializeJson(StrBuf *Target, JsonValue *Val, int FreeVal);
-
-/*
- * Citadels Wildfire implementation, see
- * http://www.firephp.org/Wiki/Reference/Protocol
- * and http://wildfirehq.org/ for details
- */
+/* the following declarations are leftover from the defunct wildfire implementation. can we remove them? */
typedef void (*AddHeaderFunc)(const char *HdrName, const char *HdrValue);
typedef enum _WF_MessageType {
/* 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)))
+#define ThreadIdHashOffset(Buf, Offset) abs(HashLittle(ChrPtr(Buf) + Offset, StrLength(Buf)-Offset))
#ifdef __cplusplus
extern "C" {
#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
+ * object types used in Citadel for configuration stuff (some of these are obsolete)
*/
#define SPOOLMIME "application/x-citadel-delivery-list"
#define INTERNETCFG "application/x-citadel-internet-config"
#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 GLOBAL_ALIASES "global_alias_table"
#define FILE_MAILALIAS "__MAIL_ALIAS__"
#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 QR2_NOUPLMSG 64 /* If a file is uploaded, no message will be posted. */
#define US_NEEDVALID 1 /* User needs to be validated */
#define US_EXTEDIT 2 /* Always use external editor */