of tools.c into libcitadel. It compiles cleanly, and seems to work, but I'm sure
I broke *something* so let's give this lots of testing.
housekeeping.c html.c ical_dezonify.c \
internet_addressing.c ecrash.c \
ipc_c_tcp.c locate_host.c md5.c messages.c \
- mime_parser.c msgbase.c msgform.c parsedate.c policy.c \
+ msgbase.c msgform.c parsedate.c policy.c \
room_ops.c rooms.c routines.c routines2.c tuiconfig.c euidindex.c \
screen.c sendcommand.c getmail.c \
server_main.c \
setup.c snprintf.c \
- stress.c support.c sysdep.c tools.c user_ops.c userlist.c \
+ stress.c support.c sysdep.c user_ops.c userlist.c \
whobbs.c vcard.c \
crc16.c journaling.c citadel_dirs.c
citadel$(EXEEXT): citadel.o citadel_ipc.o client_chat.o client_passwords.o \
commands.o html.o ipc_c_tcp.o md5.o messages.o rooms.o routines.o \
- routines2.o tuiconfig.o screen.o tools.o citadel_dirs.o ecrash.o $(LIBOBJS)
+ routines2.o tuiconfig.o screen.o citadel_dirs.o ecrash.o $(LIBOBJS)
$(CC) citadel.o citadel_ipc.o client_chat.o client_passwords.o \
commands.o html.o ipc_c_tcp.o md5.o messages.o rooms.o routines.o \
- routines2.o tuiconfig.o screen.o tools.o citadel_dirs.o ecrash.o $(LIBOBJS) \
+ routines2.o tuiconfig.o screen.o citadel_dirs.o ecrash.o $(LIBOBJS) \
$(LDFLAGS) -o citadel $(LIBS)
.y.c:
SERV_OBJS = server_main.o \
user_ops.o citserver.o sysdep.o serv_extensions.o \
- tools.o $(DATABASE:.c=.o) domain.o \
+ $(DATABASE:.c=.o) domain.o \
control.o policy.o config.o support.o room_ops.o \
file_ops.o msgbase.o euidindex.o \
- locate_host.o housekeeping.o mime_parser.o html.o \
+ locate_host.o housekeeping.o html.o \
internet_addressing.o journaling.o \
parsedate.o genstamp.o ecrash.o \
clientsocket.o modules_init.o $(AUTH) $(SERV_MODULES)
aidepost: aidepost.o config.o
$(CC) aidepost.o config.o citadel_dirs.o $(LDFLAGS) -o aidepost $(LIBS)
-citmail: citmail.o citadel_dirs.o tools.o
- $(CC) citmail.o citadel_dirs.o tools.o $(LDFLAGS) -o citmail $(LIBS)
+citmail: citmail.o citadel_dirs.o
+ $(CC) citmail.o citadel_dirs.o $(LDFLAGS) -o citmail $(LIBS)
# setup does need LIBS defined, because it uses network functions which are in -lsocket -lnsl on Solaris.
-setup: setup.o tools.o citadel_dirs.o
- $(CC) setup.o tools.o citadel_dirs.o $(LDFLAGS) -o setup $(LIBS) $(SETUP_LIBS)
+setup: setup.o citadel_dirs.o
+ $(CC) setup.o citadel_dirs.o $(LDFLAGS) -o setup $(LIBS) $(SETUP_LIBS)
chkpwd: chkpwd.o auth.o
$(CC) chkpwd.o auth.o $(LDFLAGS) -o chkpwd $(chkpwd_LIBS)
chkpw: chkpw.o auth.o citadel_dirs.o
$(CC) chkpw.o auth.o citadel_dirs.o $(LDFLAGS) -o chkpw $(chkpwd_LIBS)
-whobbs$(EXEEXT): whobbs.o ipc_c_tcp.o tools.o citadel_ipc.o citadel_dirs.o $(LIBOBJS)
- $(CC) whobbs.o ipc_c_tcp.o tools.o citadel_ipc.o citadel_dirs.o $(LIBOBJS) $(LDFLAGS) -o whobbs $(LIBS)
+whobbs$(EXEEXT): whobbs.o ipc_c_tcp.o citadel_ipc.o citadel_dirs.o $(LIBOBJS)
+ $(CC) whobbs.o ipc_c_tcp.o citadel_ipc.o citadel_dirs.o $(LIBOBJS) $(LDFLAGS) -o whobbs $(LIBS)
-stress$(EXEEXT): stress.o ipc_c_tcp.o tools.o citadel_ipc.o citadel_dirs.o $(LIBOBJS)
- $(CC) stress.o ipc_c_tcp.o tools.o citadel_ipc.o citadel_dirs.o $(LIBOBJS) $(LDFLAGS) -o stress $(LIBS)
+stress$(EXEEXT): stress.o ipc_c_tcp.o citadel_ipc.o citadel_dirs.o $(LIBOBJS)
+ $(CC) stress.o ipc_c_tcp.o citadel_ipc.o citadel_dirs.o $(LIBOBJS) $(LDFLAGS) -o stress $(LIBS)
-sendcommand: sendcommand.o ipc_c_tcp.o citadel_ipc.o tools.o config.o $(LIBOBJS)
- $(CC) sendcommand.o ipc_c_tcp.o citadel_ipc.o tools.o config.o \
+sendcommand: sendcommand.o ipc_c_tcp.o citadel_ipc.o config.o $(LIBOBJS)
+ $(CC) sendcommand.o ipc_c_tcp.o citadel_ipc.o config.o \
citadel_dirs.o $(LIBOBJS) $(LDFLAGS) -o sendcommand $(LIBS)
-getmail: getmail.o ipc_c_tcp.o citadel_ipc.o tools.o config.o $(LIBOBJS)
- $(CC) getmail.o ipc_c_tcp.o citadel_ipc.o tools.o config.o \
+getmail: getmail.o ipc_c_tcp.o citadel_ipc.o config.o $(LIBOBJS)
+ $(CC) getmail.o ipc_c_tcp.o citadel_ipc.o config.o \
citadel_dirs.o $(LIBOBJS) $(LDFLAGS) -o getmail $(LIBS)
base64: base64.o
$(CC) base64.o $(LDFLAGS) -o base64
-userlist: userlist.o ipc_c_tcp.o citadel_ipc.o tools.o citadel_dirs.o $(LIBOBJS)
- $(CC) userlist.o ipc_c_tcp.o citadel_ipc.o tools.o citadel_dirs.o \
+userlist: userlist.o ipc_c_tcp.o citadel_ipc.o citadel_dirs.o $(LIBOBJS)
+ $(CC) userlist.o ipc_c_tcp.o citadel_ipc.o citadel_dirs.o \
$(LIBOBJS) $(LDFLAGS) -o userlist $(LIBS)
msgform: msgform.o
#include <pwd.h>
#include <stdarg.h>
#include <errno.h>
-
+#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
#include "axdefs.h"
#include "client_chat.h"
#include "client_passwords.h"
#include "citadel_decls.h"
-#include "tools.h"
#include "sysdep.h"
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
#ifdef THREADED_CLIENT
#include <pthread.h>
#endif
+#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
#include "citadel_decls.h"
-#include "tools.h"
#include "citadel_dirs.h"
#ifdef THREADED_CLIENT
pthread_mutex_t rwlock;
#include <errno.h>
#include <stdarg.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
-#include "tools.h"
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
#endif
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "sysdep_decls.h"
#include "file_ops.h"
#include "policy.h"
#include "control.h"
-#include "tools.h"
#include "euidindex.h"
#ifndef HAVE_SNPRINTF
#include <sys/select.h>
#endif
#include <stdarg.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
#include "client_chat.h"
#include "commands.h"
#include "routines.h"
#include "citadel_decls.h"
-#include "tools.h"
#include "rooms.h"
#include "messages.h"
#ifndef HAVE_SNPRINTF
#include <sys/stat.h>
#include <limits.h>
#include <stdio.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
-#include "tools.h"
#include "commands.h"
#include "client_passwords.h"
|| (strcasecmp(portbuf, port)) ) {
snprintf(buf, sizeof buf, "%s|%s|%s|%s|",
hostbuf, portbuf, ubuf, pbuf);
- CtdlEncodeBase64(buf64, buf, strlen(buf));
+ CtdlEncodeBase64(buf64, buf, strlen(buf), 0);
fprintf(fp, "%s\n", buf64);
}
}
if (!IsEmptyStr(username)) {
snprintf(buf, sizeof buf, "%s|%s|%s|%s|",
host, port, username, password);
- CtdlEncodeBase64(buf64, buf, strlen(buf));
+ CtdlEncodeBase64(buf64, buf, strlen(buf), 0);
fprintf(fp, "%s\n", buf64);
}
fclose(oldfp);
#include <pwd.h>
#include <errno.h>
#include <stdarg.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#ifndef HAVE_SNPRINTF
#include "sysdep_decls.h"
#include "config.h"
#include "clientsocket.h"
-#include "tools.h"
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#include <signal.h>
#include <errno.h>
#include <stdarg.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
#include "commands.h"
#include "citadel_decls.h"
#include "routines.h"
#include "routines2.h"
-#include "tools.h"
#include "rooms.h"
#include "client_chat.h"
#include "citadel_dirs.h"
test -d /usr/kerberos/include && CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include"
+
+dnl Check for libcitadel
+AC_CHECK_HEADER(libcitadel.h,
+ [AC_CHECK_LIB(citadel, libcitadel_version_string,
+ [
+ AC_MSG_RESULT(OK)
+ LIBS="-lcitadel $LIBS"
+ ],
+ [
+ AC_MSG_ERROR(libcitadel was not found or is not usable. Please install libcitadel.)
+ ]
+ ,
+ )],
+ [
+ AC_MSG_ERROR(libcitadel.h was not found or is not usable. Please install libcitadel.)
+ ]
+)
+
+
+
# The big search for OpenSSL
if test "$with_ssl" != "no"; then
saved_LIBS="$LIBS"
#include <limits.h>
#include <sys/types.h>
#include <sys/file.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "control.h"
#include "config.h"
#include "msgbase.h"
#include "citserver.h"
-#include "tools.h"
#include "room_ops.h"
#include "user_ops.h"
#include "database.h"
#endif
#include <resolv.h>
#endif
-
+#include <libcitadel.h>
#include "sysdep_decls.h"
#include "citadel.h"
#include "domain.h"
#include "server.h"
-#include "tools.h"
#include "internet_addressing.h"
#include <errno.h>
#include <stdarg.h>
#include <sys/stat.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "database.h"
#include "file_ops.h"
#include "config.h"
#include "control.h"
-#include "tools.h"
#include "euidindex.h"
/*
#endif
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "config.h"
#include "support.h"
#include "room_ops.h"
#include "msgbase.h"
-#include "tools.h"
#include "citserver.h"
#ifndef HAVE_SNPRINTF
#include <signal.h>
#include <errno.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
-#include "tools.h"
#include "citadel_ipc.h"
#include "server.h"
#include "config.h"
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
-#include "tools.h"
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "serv_extensions.h"
#include <string.h>
#include <errno.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "control.h"
#include "support.h"
#include "config.h"
#include "msgbase.h"
-#include "tools.h"
#include "room_ops.h"
#include "html.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "sysdep_decls.h"
#include "citserver.h"
#include "support.h"
#include "config.h"
-#include "tools.h"
#include "msgbase.h"
#include "internet_addressing.h"
#include "user_ops.h"
#include <pwd.h>
#include <errno.h>
#include <stdarg.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
#include "citadel_decls.h"
-#include "tools.h"
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
#endif
#include <errno.h>
#include <stdarg.h>
#include <sys/stat.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "database.h"
#include "file_ops.h"
#include "config.h"
#include "control.h"
-#include "tools.h"
-#include "mime_parser.h"
#include "html.h"
#include "genstamp.h"
#include "internet_addressing.h"
#include <limits.h>
#include <netdb.h>
#include <string.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "locate_host.h"
#include "sysdep_decls.h"
#include "config.h"
-#include "tools.h"
#include "domain.h"
#ifdef HAVE_RESOLV_H
#endif
#include <stdarg.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
#include "citadel_decls.h"
#include "messages.h"
#include "commands.h"
#include "rooms.h"
-#include "tools.h"
#include "html.h"
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
+++ /dev/null
-/*
- * $Id$
- *
- * This is the MIME parser for Citadel.
- *
- * Copyright (c) 1998-2006 by Art Cancro
- * This code is distributed under the GNU General Public License v2.
- *
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <ctype.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#include "citadel.h"
-#include "server.h"
-#include "sysdep_decls.h"
-#include "tools.h"
-
-#include "mime_parser.h"
-
-
-void extract_key(char *target, char *source, char *key)
-{
- char *ptr;
- char looking_for[256];
- int double_quotes = 0;
-
- snprintf(looking_for, sizeof looking_for, "%s=", key);
-
- ptr = bmstrcasestr(source, looking_for);
- if (ptr == NULL) {
- strcpy(target, "");
- return;
- }
- strcpy(target, (ptr + strlen(looking_for)));
-
- for (ptr=target; (*ptr != 0); ++ptr) {
-
- /* A semicolon means we've hit the end of the key, unless we're inside double quotes */
- if ( (double_quotes != 1) && (*ptr == ';')) {
- *ptr = 0;
- }
-
- /* if we find double quotes, we've got a great set of string boundaries */
- if (*ptr == '\"') {
- ++double_quotes;
- if (double_quotes == 1) {
- strcpy(ptr, ptr+1);
- }
- else {
- *ptr = 0;
- }
- }
- }
-}
-
-
-/*
- * For non-multipart messages, we need to generate a quickie partnum of "1"
- * to return to callback functions. Some callbacks demand it.
- */
-char *fixed_partnum(char *supplied_partnum) {
- if (supplied_partnum == NULL) return "1";
- if (strlen(supplied_partnum)==0) return "1";
- return supplied_partnum;
-}
-
-
-
-/*
- * Given a message or message-part body and a length, handle any necessary
- * decoding and pass the request up the stack.
- */
-void mime_decode(char *partnum,
- char *part_start, size_t length,
- char *content_type, char *charset, char *encoding,
- char *disposition,
- 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,
- void *cbuserdata),
- void (*PreMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void (*PostMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void *userdata,
- int dont_decode
-)
-{
-
- char *decoded;
- size_t bytes_decoded = 0;
-
- /* Some encodings aren't really encodings */
- if (!strcasecmp(encoding, "7bit"))
- strcpy(encoding, "");
- if (!strcasecmp(encoding, "8bit"))
- strcpy(encoding, "");
- if (!strcasecmp(encoding, "binary"))
- strcpy(encoding, "");
-
- /* If this part is not encoded, send as-is */
- if ( (strlen(encoding) == 0) || (dont_decode)) {
- if (CallBack != NULL) {
- CallBack(name, filename, fixed_partnum(partnum),
- disposition, part_start,
- content_type, charset, length, encoding, userdata);
- }
- return;
- }
-
- /* Fail silently if we hit an unknown encoding. */
- if ((strcasecmp(encoding, "base64"))
- && (strcasecmp(encoding, "quoted-printable"))) {
- return;
- }
-
- /*
- * Allocate a buffer for the decoded data. The output buffer is slightly
- * larger than the input buffer; this assumes that the decoded data
- * will never be significantly larger than the encoded data. This is a
- * safe assumption with base64, uuencode, and quoted-printable.
- */
- decoded = malloc(length + 32768);
- if (decoded == NULL) {
- return;
- }
-
- if (!strcasecmp(encoding, "base64")) {
- bytes_decoded = CtdlDecodeBase64(decoded, part_start, length);
- }
- else if (!strcasecmp(encoding, "quoted-printable")) {
- bytes_decoded = CtdlDecodeQuotedPrintable(decoded, part_start, length);
- }
-
- if (bytes_decoded > 0) if (CallBack != NULL) {
- CallBack(name, filename, fixed_partnum(partnum),
- disposition, decoded,
- content_type, charset, bytes_decoded, "binary", userdata);
- }
-
- free(decoded);
-}
-
-/*
- * Break out the components of a multipart message
- * (This function expects to be fed HEADERS + CONTENT)
- * Note: NULL can be supplied as content_end; in this case, the message is
- * considered to have ended when the parser encounters a 0x00 byte.
- */
-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,
- void *cbuserdata),
- void (*PreMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void (*PostMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void *userdata,
- int dont_decode
-)
-{
-
- char *ptr;
- char *srch = NULL;
- char *part_start, *part_end = NULL;
- char buf[SIZ];
- char *header;
- char *boundary;
- char *startary;
- size_t startary_len = 0;
- char *endary;
- char *next_boundary;
- char *content_type;
- char *charset;
- size_t content_length;
- char *encoding;
- char *disposition;
- char *name = NULL;
- char *content_type_name;
- char *content_disposition_name;
- char *filename;
- int is_multipart;
- int part_seq = 0;
- int i;
- size_t length;
- char nested_partnum[256];
- int crlf_in_use = 0;
- char *evaluate_crlf_ptr = NULL;
- int buflen = 0;
- int headerlen = 0;
-
- ptr = content_start;
- content_length = 0;
-
- boundary = malloc(SIZ);
- memset(boundary, 0, SIZ);
-
- startary = malloc(SIZ);
- memset(startary, 0, SIZ);
-
- endary = malloc(SIZ);
- memset(endary, 0, SIZ);
-
- header = malloc(SIZ);
- memset(header, 0, SIZ);
-
- content_type = malloc(SIZ);
- memset(content_type, 0, SIZ);
-
- charset = malloc(SIZ);
- memset(charset, 0, SIZ);
-
- encoding = malloc(SIZ);
- memset(encoding, 0, SIZ);
-
- content_type_name = malloc(SIZ);
- memset(content_type_name, 0, SIZ);
-
- content_disposition_name = malloc(SIZ);
- memset(content_disposition_name, 0, SIZ);
-
- filename = malloc(SIZ);
- memset(filename, 0, SIZ);
-
- disposition = malloc(SIZ);
- memset(disposition, 0, SIZ);
-
- /* If the caller didn't supply an endpointer, generate one by measure */
- if (content_end == NULL) {
- content_end = &content_start[strlen(content_start)];
- }
-
- /* Learn interesting things from the headers */
- strcpy(header, "");
- headerlen = 0;
- do {
- ptr = memreadlinelen(ptr, buf, SIZ, &buflen);
- if (ptr >= content_end) {
- goto end_parser;
- }
-
- for (i = 0; i < buflen; ++i) {
- if (isspace(buf[i])) {
- buf[i] = ' ';
- }
- }
-
- if (!isspace(buf[0])) {
- if (!strncasecmp(header, "Content-type:", 13)) {
- strcpy(content_type, &header[13]);
- striplt(content_type);
- extract_key(content_type_name, content_type, "name");
- extract_key(charset, content_type, "charset");
- extract_key(boundary, header, "boundary");
- /* Deal with weird headers */
- if (strchr(content_type, ' '))
- *(strchr(content_type, ' ')) = '\0';
- if (strchr(content_type, ';'))
- *(strchr(content_type, ';')) = '\0';
- }
- if (!strncasecmp(header, "Content-Disposition:", 20)) {
- strcpy(disposition, &header[20]);
- striplt(disposition);
- extract_key(content_disposition_name, disposition, "name");
- extract_key(filename, disposition, "filename");
- }
- if (!strncasecmp(header, "Content-length: ", 15)) {
- char clbuf[10];
- safestrncpy(clbuf, &header[15], sizeof clbuf);
- striplt(clbuf);
- content_length = (size_t) atol(clbuf);
- }
- if (!strncasecmp(header, "Content-transfer-encoding: ", 26)) {
- strcpy(encoding, &header[26]);
- striplt(encoding);
- }
- strcpy(header, "");
- headerlen = 0;
- }
- if ((headerlen + buflen + 2) < SIZ) {
- memcpy(&header[headerlen], buf, buflen);
- headerlen += buflen;
- header[headerlen] = '\0';
- }
- } while ((!IsEmptyStr(buf)) && (*ptr != 0));
-
- if (strchr(disposition, ';'))
- *(strchr(disposition, ';')) = '\0';
- striplt(disposition);
- if (strchr(content_type, ';'))
- *(strchr(content_type, ';')) = '\0';
- striplt(content_type);
-
- if (!IsEmptyStr(boundary)) {
- is_multipart = 1;
- } else {
- is_multipart = 0;
- }
-
- /* If this is a multipart message, then recursively process it */
- part_start = NULL;
- if (is_multipart) {
-
- /* Tell the client about this message's multipartedness */
- if (PreMultiPartCallBack != NULL) {
- PreMultiPartCallBack("", "", partnum, "",
- NULL, content_type, charset,
- 0, encoding, userdata);
- }
-
- /* Figure out where the boundaries are */
- snprintf(startary, SIZ, "--%s", boundary);
- snprintf(endary, SIZ, "--%s--", boundary);
- startary_len = strlen(startary);
-
- part_start = NULL;
- do {
- next_boundary = NULL;
- for (srch=ptr; srch<content_end; ++srch) {
- if (!memcmp(srch, startary, startary_len)) {
- next_boundary = srch;
- srch = content_end;
- }
- }
-
- if ( (part_start != NULL) && (next_boundary != NULL) ) {
- part_end = next_boundary;
- --part_end; /* omit the trailing LF */
- if (crlf_in_use) {
- --part_end; /* omit the trailing CR */
- }
-
- if (!IsEmptyStr(partnum)) {
- snprintf(nested_partnum,
- sizeof nested_partnum,
- "%s.%d", partnum,
- ++part_seq);
- }
- else {
- snprintf(nested_partnum,
- sizeof nested_partnum,
- "%d", ++part_seq);
- }
- the_mime_parser(nested_partnum,
- part_start, part_end,
- CallBack,
- PreMultiPartCallBack,
- PostMultiPartCallBack,
- userdata,
- dont_decode);
- }
-
- if (next_boundary != NULL) {
- /* If we pass out of scope, don't attempt to
- * read past the end boundary. */
- if (!strcmp(next_boundary, endary)) {
- ptr = content_end;
- }
- else {
- /* Set up for the next part. */
- part_start = strstr(next_boundary, "\n");
-
- /* Determine whether newlines are LF or CRLF */
- evaluate_crlf_ptr = part_start;
- --evaluate_crlf_ptr;
- if (!memcmp(evaluate_crlf_ptr, "\r\n", 2)) {
- crlf_in_use = 1;
- }
- else {
- crlf_in_use = 0;
- }
-
- /* Advance past the LF ... now we're in the next part */
- ++part_start;
- ptr = part_start;
- }
- }
- else {
- /* Invalid end of multipart. Bail out! */
- ptr = content_end;
- }
- } while ( (ptr < content_end) && (next_boundary != NULL) );
-
- if (PostMultiPartCallBack != NULL) {
- PostMultiPartCallBack("", "", partnum, "", NULL,
- content_type, charset, 0, encoding, userdata);
- }
- goto end_parser;
- }
-
- /* If it's not a multipart message, then do something with it */
- if (!is_multipart) {
- part_start = ptr;
- length = 0;
- while (ptr < content_end) {
- ++ptr;
- ++length;
- }
- part_end = content_end;
-
- /******
- * I thought there was an off-by-one error here, but there isn't.
- * This probably means that there's an off-by-one error somewhere
- * else ... or maybe only in certain messages?
- --part_end;
- --length;
- ******/
-
- /* Truncate if the header told us to */
- if ( (content_length > 0) && (length > content_length) ) {
- length = content_length;
- }
-
- /* Sometimes the "name" field is tacked on to Content-type,
- * and sometimes it's tacked on to Content-disposition. Use
- * whichever one we have.
- */
- if (strlen(content_disposition_name) > strlen(content_type_name)) {
- name = content_disposition_name;
- }
- else {
- name = content_type_name;
- }
-
- /* lprintf(CTDL_DEBUG, "mime_decode part=%s, len=%d, type=%s, charset=%s, encoding=%s\n",
- partnum, length, content_type, charset, encoding); */
-
- /* Ok, we've got a non-multipart part here, so do something with it.
- */
- mime_decode(partnum,
- part_start, length,
- content_type, charset, encoding, disposition,
- name, filename,
- CallBack, NULL, NULL,
- userdata, dont_decode
- );
-
- /*
- * Now if it's an encapsulated message/rfc822 then we have to recurse into it
- */
- if (!strcasecmp(content_type, "message/rfc822")) {
-
- if (PreMultiPartCallBack != NULL) {
- PreMultiPartCallBack("", "", partnum, "",
- NULL, content_type, charset,
- 0, encoding, userdata);
- }
- if (CallBack != NULL) {
- if (strlen(partnum) > 0) {
- snprintf(nested_partnum,
- sizeof nested_partnum,
- "%s.%d", partnum,
- ++part_seq);
- }
- else {
- snprintf(nested_partnum,
- sizeof nested_partnum,
- "%d", ++part_seq);
- }
- the_mime_parser(nested_partnum,
- part_start, part_end,
- CallBack,
- PreMultiPartCallBack,
- PostMultiPartCallBack,
- userdata,
- dont_decode
- );
- }
- if (PostMultiPartCallBack != NULL) {
- PostMultiPartCallBack("", "", partnum, "", NULL,
- content_type, charset, 0, encoding, userdata);
- }
-
-
- }
-
- }
-
-end_parser: /* free the buffers! end the oppression!! */
- free(boundary);
- free(startary);
- free(endary);
- free(header);
- free(content_type);
- free(charset);
- free(encoding);
- free(content_type_name);
- free(content_disposition_name);
- free(filename);
- free(disposition);
-}
-
-
-
-/*
- * Entry point for the MIME parser.
- * (This function expects to be fed HEADERS + CONTENT)
- * Note: NULL can be supplied as content_end; in this case, the message is
- * considered to have ended when the parser encounters a 0x00 byte.
- */
-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,
- void *cbuserdata),
-
- void (*PreMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
-
- void (*PostMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
-
- void *userdata,
- int dont_decode
-)
-{
-
- the_mime_parser("", content_start, content_end,
- CallBack,
- PreMultiPartCallBack,
- PostMultiPartCallBack,
- userdata, dont_decode);
-}
+++ /dev/null
-/*
- * $Id$
- *
- */
-
-/*
- * Here's a bunch of stupid magic to make the MIME parser portable between
- * Citadel and WebCit.
- */
-#ifndef SIZ
-#define SIZ 4096
-#endif
-
-
-/*
- * Declarations for functions in the parser
- */
-
-void extract_key(char *target, char *source, char *key);
-
-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,
- void *cbuserdata),
- void (*PreMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void (*PostMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void *userdata,
- int dont_decode
- );
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "support.h"
#include "config.h"
-#include "tools.h"
#include "msgbase.h"
#include "user_ops.h"
#include "room_ops.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "citadel_dirs.h"
#include "ctdl_module.h"
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "config.h"
#include "user_ops.h"
#include "room_ops.h"
-#include "tools.h"
#include "msgbase.h"
-#include "mime_parser.h"
#include "internet_addressing.h"
#include "serv_calendar.h"
#include "euidindex.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "serv_chat.h"
#include "citserver.h"
#include "support.h"
#include "config.h"
-#include "tools.h"
#include "msgbase.h"
#include "user_ops.h"
#include "room_ops.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "user_ops.h"
#include "control.h"
#include "serv_network.h" /* Needed for defenition of UseTable */
-#include "tools.h"
#include "ctdl_module.h"
#include <ctype.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "sysdep_decls.h"
#include "database.h"
#include "msgbase.h"
#include "control.h"
-#include "tools.h"
#include "ft_wordbreaker.h"
#include "crc16.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "msgbase.h"
#include "control.h"
#include "room_ops.h"
-#include "tools.h"
#include "serv_fulltext.h"
#include "ft_wordbreaker.h"
#include <string.h>
#include <limits.h>
#include <sys/socket.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "user_ops.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "domain.h"
#include "clientsocket.h"
#include <ctype.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "sysdep_decls.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "serv_imap.h"
#include "imap_tools.h"
#include <ctype.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "sysdep_decls.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
-#include "mime_parser.h"
#include "serv_imap.h"
#include "imap_tools.h"
#include "imap_fetch.h"
#include <ctype.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "sysdep_decls.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "serv_imap.h"
#include "imap_tools.h"
#include <ctype.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "sysdep_decls.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "serv_imap.h"
#include "imap_tools.h"
#include <ctype.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "sysdep_decls.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "serv_imap.h"
#include "imap_tools.h"
#include <ctype.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "sysdep_decls.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "serv_imap.h"
#include "imap_tools.h"
#include <ctype.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "sysdep_decls.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "serv_imap.h"
#include "imap_tools.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "sysdep_decls.h"
-#include "tools.h"
#include "room_ops.h"
#include "internet_addressing.h"
#include "imap_tools.h"
#include <ctype.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "serv_imap.h"
#include "imap_tools.h"
}
if (!strcasecmp(parms[2], "LOGIN")) {
- CtdlEncodeBase64(buf, "Username:", 9);
+ CtdlEncodeBase64(buf, "Username:", 9, 0);
cprintf("+ %s\r\n", buf);
IMAP->authstate = imap_as_expecting_username;
strcpy(IMAP->authseq, parms[0]);
}
if (!strcasecmp(parms[2], "PLAIN")) {
- // CtdlEncodeBase64(buf, "Username:", 9);
+ // CtdlEncodeBase64(buf, "Username:", 9, 0);
// cprintf("+ %s\r\n", buf);
cprintf("+ \r\n");
IMAP->authstate = imap_as_expecting_plainauth;
CtdlDecodeBase64(buf, cmd, SIZ);
CtdlLoginExistingUser(NULL, buf);
- CtdlEncodeBase64(buf, "Password:", 9);
+ CtdlEncodeBase64(buf, "Password:", 9, 0);
cprintf("+ %s\r\n", buf);
IMAP->authstate = imap_as_expecting_password;
return;
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "genstamp.h"
#include "domain.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "serv_ldap.h"
-#include "tools.h"
#include "ctdl_module.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "clientsocket.h"
#include "file_ops.h"
);
/* Convert it to base64 so it looks cool */
- CtdlEncodeBase64(buf, sourcebuf, strlen(sourcebuf));
+ CtdlEncodeBase64(buf, sourcebuf, strlen(sourcebuf), 0);
}
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "imap_tools.h" /* Needed for imap_parameterize */
#include "genstamp.h"
if (strlen(argbuf) >= 7) {
}
else {
- CtdlEncodeBase64(username_prompt, "Username:", 9);
+ CtdlEncodeBase64(username_prompt, "Username:", 9, 0);
cprintf("334 %s\r\n", username_prompt);
}
return;
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "ctdl_module.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "database.h"
#include "msgbase.h"
#include "serv_network.h" /* Needed for defenition of FilterList */
-#include "tools.h"
#include "ctdl_module.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "serv_network.h"
#include "clientsocket.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "ctdl_module.h"
#include <string.h>
#include <limits.h>
#include <sys/socket.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "domain.h"
#include "clientsocket.h"
#include <ctype.h>
#include <string.h>
#include <errno.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "support.h"
#include "user_ops.h"
#include "md5.h"
-#include "tools.h"
#include "ctdl_module.h"
#include <string.h>
#include <limits.h>
#include <ctype.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "serv_pop3.h"
#include "md5.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "support.h"
#include "config.h"
-#include "tools.h"
#include "room_ops.h"
#include "ctdl_module.h"
#include "clientsocket.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "support.h"
#include "config.h"
-#include "tools.h"
#include "room_ops.h"
#include "ctdl_module.h"
#include "clientsocket.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "ctdl_module.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "database.h"
#include "msgbase.h"
#include "internet_addressing.h"
-#include "tools.h"
#include "ctdl_module.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "genstamp.h"
#include "domain.h"
CtdlDecodeBase64(username, argbuf, SIZ);
/* lprintf(CTDL_DEBUG, "Trying <%s>\n", username); */
if (CtdlLoginExistingUser(NULL, username) == login_ok) {
- CtdlEncodeBase64(buf, "Password:", 9);
+ CtdlEncodeBase64(buf, "Password:", 9, 0);
cprintf("334 %s\r\n", buf);
SMTP->command_state = smtp_password;
}
smtp_get_user(&argbuf[6]);
}
else {
- CtdlEncodeBase64(username_prompt, "Username:", 9);
+ CtdlEncodeBase64(username_prompt, "Username:", 9, 0);
cprintf("334 %s\r\n", username_prompt);
SMTP->command_state = smtp_user;
}
if (!IsEmptyStr(mx_user)) {
char encoded[1024];
sprintf(buf, "%s%c%s%c%s", mx_user, '\0', mx_user, '\0', mx_pass);
- CtdlEncodeBase64(encoded, buf, strlen(mx_user) + strlen(mx_user) + strlen(mx_pass) + 2);
+ CtdlEncodeBase64(encoded, buf, strlen(mx_user) + strlen(mx_user) + strlen(mx_pass) + 2, 0);
snprintf(buf, sizeof buf, "AUTH PLAIN %s\r\n", encoded);
lprintf(CTDL_DEBUG, ">%s", buf);
sock_write(sock, buf, strlen(buf));
#include <string.h>
#include <limits.h>
#include <sys/socket.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "domain.h"
#include "clientsocket.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "room_ops.h"
#include "user_ops.h"
#include "msgbase.h"
-#include "tools.h"
#include "serv_upgrade.h"
#include "euidindex.h"
#include <string.h>
#include <ctype.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "config.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "user_ops.h"
#include "room_ops.h"
#include "control.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "database.h"
#include "msgbase.h"
#include "internet_addressing.h"
-#include "tools.h"
-#include "mime_parser.h"
#include "vcard.h"
#include "serv_vcard.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <regex.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "serv_extensions.h"
#include "file_ops.h"
#include "config.h"
#include "control.h"
-#include "tools.h"
-#include "mime_parser.h"
#include "html.h"
#include "genstamp.h"
#include "internet_addressing.h"
CtdlEncodeBase64(
&encoded_message[strlen(encoded_message)],
raw_message,
- (int)raw_length
+ (int)raw_length,
+ 0
);
}
else {
#endif
#include <errno.h>
-#include "tools.h"
-
+#include <libcitadel.h>
int qwk = 0;
#endif
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "database.h"
#include "user_ops.h"
#include "msgbase.h"
#include "citserver.h"
-#include "tools.h"
/*
#include <limits.h>
#include <errno.h>
#include "citadel.h"
+#include <libcitadel.h>
#include "server.h"
#include "database.h"
#include "config.h"
#include "msgbase.h"
#include "citserver.h"
#include "control.h"
-#include "tools.h"
#include "citadel_dirs.h"
struct floor *floorcache[MAXFLOORS];
#include <sys/wait.h>
#include <errno.h>
#include <stdarg.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
#include "citadel_decls.h"
#include "rooms.h"
#include "commands.h"
-#include "tools.h"
#include "messages.h"
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
# include <time.h>
# endif
#endif
+
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_UTMPX_H
#include <utmpx.h>
#endif
+
+#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
#include "screen.h"
#include "citadel.h"
#include "routines.h"
#include "commands.h"
-#include "tools.h"
#include "citadel_decls.h"
#include "routines2.h"
void locate_host(CtdlIPC* ipc, char *hbuf);
void misc_server_cmd(CtdlIPC *ipc, char *cmd);
int nukedir(char *dirname);
-int num_parms(char *source);
void strproc(char *string);
void back(int spaces);
void progress(CtdlIPC* ipc, unsigned long curr, unsigned long cmax);
#include <pwd.h>
#include <errno.h>
#include <stdarg.h>
+#include <libcitadel.h>
#include "sysdep.h"
#include "citadel.h"
#include "citadel_ipc.h"
#include "routines2.h"
#include "routines.h"
#include "commands.h"
-#include "tools.h"
#include "messages.h"
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
#include <signal.h>
#include <errno.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
-#include "tools.h"
#include "citadel_ipc.h"
#include "server.h"
#include "config.h"
#include <string.h>
#include <limits.h>
#include <ctype.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "serv_extensions.h"
#include "sysdep_decls.h"
#include "msgbase.h"
-#include "tools.h"
#include "config.h"
#include "modules/crypto/serv_crypto.h" /* Needed until a universal crypto startup hook is implimented for CtdlStartTLS */
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#endif
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "serv_extensions.h"
#include "database.h"
#include "user_ops.h"
#include "housekeeping.h"
-#include "tools.h"
#include "citadel_dirs.c"
#include "modules_init.h"
"General Public License.\n");
lprintf(CTDL_NOTICE, "\n");
lprintf(CTDL_DEBUG, "Called as: %s\n", argv[0]);
+ lprintf(CTDL_INFO, "%s\n", libcitadel_version_string());
/* Load site-specific parameters, and set the ipgm secret */
lprintf(CTDL_INFO, "Loading citadel.config\n");
#include <limits.h>
#include <pwd.h>
#include <time.h>
-
+#include <libcitadel.h>
#include "citadel.h"
#include "axdefs.h"
#include "sysdep.h"
#include "config.h"
-#include "tools.h"
#include "citadel_dirs.h"
#define MAXSETUP 5 /* How many setup questions to ask */
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
+#include <libcitadel.h>
#include "sysdep.h"
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
# endif
#endif
-#include "tools.h"
#include "citadel_ipc.h"
#ifndef HAVE_PTHREAD_H
#include <ctype.h>
#include <stdio.h>
#include <string.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "support.h"
-#include "tools.h"
/*
* strproc() - make a string 'nice'
}
-/*
- * pattern2() - searches for patn within search string, returns pos
- */
-int pattern2(char *search, char *patn)
-{
- int a, len;
-
- len = strlen(patn);
- for (a=0; !IsEmptyStr(&search[a]); ++a) {
- if (!strncasecmp(&search[a],patn, len)) return(a);
- }
- return(-1);
- }
/*
/* $Id$ */
void strproc (char *string);
int getstring (FILE *fp, char *string);
-int pattern2 (char *search, char *patn);
void mesg_locate (char *targ, size_t n, const char *searchfor,
int numdirs, const char * const *dirs);
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "sysdep_decls.h"
#include "config.h"
#include "database.h"
#include "housekeeping.h"
-#include "tools.h"
#include "modules/crypto/serv_crypto.h" /* Needed for init_ssl, client_write_ssl, client_read_ssl, destruct_ssl */
#include "ecrash.h"
+++ /dev/null
-/*
- * $Id$
- *
- * Utility functions that are used by both the client and server.
- *
- */
-
-#include "sysdep.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdarg.h>
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#include "tools.h"
-#include "citadel.h"
-#include "sysdep_decls.h"
-
-#define TRUE 1
-#define FALSE 0
-
-typedef unsigned char byte; /* Byte type */
-static byte dtable[256] = "\0"; /* base64 decode table */
-static byte etable[256] = "\0"; /* base64 encode table */
-
-/* Month strings for date conversions */
-char *ascmonths[12] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-char *safestrncpy(char *dest, const char *src, size_t n)
-{
- int i = 0;
-
- if (dest == NULL || src == NULL) {
- fprintf(stderr, "safestrncpy: NULL argument\n");
- abort();
- }
-
- do {
- dest[i] = src[i];
- if (dest[i] == 0) return(dest);
- ++i;
- } while (i<n);
- dest[n - 1] = 0;
- return dest;
-}
-
-
-
-#ifndef HAVE_STRNCASECMP
-int strncasecmp(char *lstr, char *rstr, int len)
-{
- int pos = 0;
- char lc,rc;
- while (pos<len) {
- lc=tolower(lstr[pos]);
- rc=tolower(rstr[pos]);
- if ((lc==0)&&(rc==0)) return(0);
- if (lc<rc) return(-1);
- if (lc>rc) return(1);
- pos=pos+1;
- }
- return(0);
-}
-#endif
-
-
-
-/*
- * num_tokens() - discover number of parameters/tokens in a string
- */
-int num_tokens(const char *source, char tok)
-{
- int count = 1;
- const char *ptr = source;
-
- if (source == NULL) {
- return (0);
- }
-
- while (*ptr != '\0') {
- if (*ptr++ == tok) {
- ++count;
- }
- }
-
- return (count);
-}
-
-//extern void cit_backtrace(void);
-
-
-/*
- * extract_token() - a string tokenizer
- * returns -1 if not found, or length of token.
- */
-long extract_token(char *dest, const char *source, int parmnum, char separator, int maxlen)
-{
- const char *s; //* source * /
- int len = 0; //* running total length of extracted string * /
- int current_token = 0; //* token currently being processed * /
-
- s = source;
-
- if (dest == NULL) {
- return(-1);
- }
-
-// cit_backtrace();
-// lprintf (CTDL_DEBUG, "test >: n: %d sep: %c source: %s \n willi \n", parmnum, separator, source);
- dest[0] = 0;
-
- if (s == NULL) {
- return(-1);
- }
-
- maxlen--;
-
- while (*s) {
- if (*s == separator) {
- ++current_token;
- }
- if ( (current_token == parmnum) &&
- (*s != separator) &&
- (len < maxlen) ) {
- dest[len] = *s;
- ++len;
- }
- else if ((current_token > parmnum) || (len >= maxlen)) {
- break;
- }
- ++s;
- }
-
- dest[len] = '\0';
- if (current_token < parmnum) {
-// lprintf (CTDL_DEBUG,"test <!: %s\n", dest);
- return(-1);
- }
-// lprintf (CTDL_DEBUG,"test <: %d; %s\n", len, dest);
- return(len);
-}
-//*/
-
-
-/*
- * extract_token() - a string tokenizer
- * /
-long extract_token(char *dest, const char *source, int parmnum, char separator, int maxlen)
-{
- char *d; // dest
- const char *s; // source
- int count = 0;
- int len = 0;
-
-
-// cit_backtrace();
- lprintf (CTDL_DEBUG, "test >: n: %d sep: %c source: %s \n willi \n", parmnum, separator, source);
- strcpy(dest, "");
-
- // Locate desired parameter
- s = source;
- while (count < parmnum) {
- // End of string, bail!
- if (!*s) {
- s = NULL;
- break;
- }
- if (*s == separator) {
- count++;
- }
- s++;
- }
- if (!s) {
- lprintf (CTDL_DEBUG,"test <!: %s\n", dest);
- return -1; // Parameter not found
- }
-
- for (d = dest; *s && *s != separator && ++len<maxlen; s++, d++) {
- *d = *s;
- }
- *d = 0;
- lprintf (CTDL_DEBUG,"test <: %d; %s\n", len, dest);
- return 0;
-}
-*/
-
-
-/*
- * remove_token() - a tokenizer that kills, maims, and destroys
- */
-void remove_token(char *source, int parmnum, char separator)
-{
- char *d, *s; /* dest, source */
- int count = 0;
-
- /* Find desired parameter */
- d = source;
- while (count < parmnum) {
- /* End of string, bail! */
- if (!*d) {
- d = NULL;
- break;
- }
- if (*d == separator) {
- count++;
- }
- d++;
- }
- if (!d) return; /* Parameter not found */
-
- /* Find next parameter */
- s = d;
- while (*s && *s != separator) {
- s++;
- }
-
- /* Hack and slash */
- if (*s)
- strcpy(d, ++s);
- else if (d == source)
- *d = 0;
- else
- *--d = 0;
- /*
- while (*s) {
- *d++ = *s++;
- }
- *d = 0;
- */
-}
-
-
-/*
- * extract_int() - extract an int parm w/o supplying a buffer
- */
-int extract_int(const char *source, int parmnum)
-{
- char buf[32];
-
- extract_token(buf, source, parmnum, '|', sizeof buf);
- return(atoi(buf));
-}
-
-/*
- * extract_long() - extract an long parm w/o supplying a buffer
- */
-long extract_long(const char *source, int parmnum)
-{
- char buf[32];
-
- extract_token(buf, source, parmnum, '|', sizeof buf);
- return(atol(buf));
-}
-
-
-/*
- * extract_unsigned_long() - extract an unsigned long parm
- */
-unsigned long extract_unsigned_long(const char *source, int parmnum)
-{
- char buf[32];
-
- extract_token(buf, source, parmnum, '|', sizeof buf);
- return strtoul(buf, NULL, 10);
-}
-
-
-
-void CtdlInitBase64Table(void)
-{
- int i;
- /* Fill dtable with character encodings. */
-
- /* Encoder Table */
- for (i = 0; i < 26; i++) {
- etable[i] = 'A' + i;
- etable[26 + i] = 'a' + i;
- }
- for (i = 0; i < 10; i++) {
- etable[52 + i] = '0' + i;
- }
- etable[62] = '+';
- etable[63] = '/';
-
- /* Decoder Table */
- for (i = 0; i < 255; i++) {
- dtable[i] = 0x80;
- }
- for (i = 'A'; i <= 'Z'; i++) {
- dtable[i] = 0 + (i - 'A');
- }
- for (i = 'a'; i <= 'z'; i++) {
- dtable[i] = 26 + (i - 'a');
- }
- for (i = '0'; i <= '9'; i++) {
- dtable[i] = 52 + (i - '0');
- }
- dtable['+'] = 62;
- dtable['/'] = 63;
- dtable['='] = 0;
-}
-
-/*
- * CtdlDecodeBase64() and CtdlEncodeBase64() are adaptations of code by
- * John Walker, found in full in the file "base64.c" included with this
- * distribution. We are moving in the direction of eventually discarding
- * the separate executables, and using the ones in our code exclusively.
- */
-
-void CtdlEncodeBase64(char *dest, const char *source, size_t sourcelen)
-{
- int i, hiteof = FALSE;
- int spos = 0;
- int dpos = 0;
-
- while (!hiteof) {
- byte igroup[3], ogroup[4];
- int c, n;
-
- igroup[0] = igroup[1] = igroup[2] = 0;
- for (n = 0; n < 3; n++) {
- if (spos >= sourcelen) {
- hiteof = TRUE;
- break;
- }
- c = source[spos++];
- igroup[n] = (byte) c;
- }
- if (n > 0) {
- ogroup[0] = etable[igroup[0] >> 2];
- ogroup[1] = etable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
- ogroup[2] = etable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
- ogroup[3] = etable[igroup[2] & 0x3F];
-
- /* Replace characters in output stream with "=" pad
- characters if fewer than three characters were
- read from the end of the input stream. */
-
- if (n < 3) {
- ogroup[3] = '=';
- if (n < 2) {
- ogroup[2] = '=';
- }
- }
- for (i = 0; i < 4; i++) {
- dest[dpos++] = ogroup[i];
- dest[dpos] = 0;
- }
- }
- }
-}
-
-
-/*
- * Convert base64-encoded to binary. Returns the length of the decoded data.
- * It will stop after reading 'length' bytes.
- */
-int CtdlDecodeBase64(char *dest, const char *source, size_t length)
-{
- int i, c;
- int dpos = 0;
- int spos = 0;
-
-
- /*CONSTANTCONDITION*/
- while (TRUE) {
- byte a[4], b[4], o[3];
-
- for (i = 0; i < 4; i++) {
- if (spos >= length) {
- return(dpos);
- }
- c = source[spos++];
-
- if (c == 0) {
- if (i > 0) {
- return(dpos);
- }
- return(dpos);
- }
- if (dtable[c] & 0x80) {
- /* Ignoring errors: discard invalid character. */
- i--;
- continue;
- }
- a[i] = (byte) c;
- b[i] = (byte) dtable[c];
- }
- o[0] = (b[0] << 2) | (b[1] >> 4);
- o[1] = (b[1] << 4) | (b[2] >> 2);
- o[2] = (b[2] << 6) | b[3];
- i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
- if (i>=1) dest[dpos++] = o[0];
- if (i>=2) dest[dpos++] = o[1];
- if (i>=3) dest[dpos++] = o[2];
- dest[dpos] = 0;
- if (i < 3) {
- return(dpos);
- }
- }
-}
-
-/*
- * Convert "quoted-printable" to binary. Returns number of bytes decoded.
- * according to RFC2045 section 6.7
- */
-int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen) {
- unsigned int ch;
- int decoded_length = 0;
- int pos = 0;
-
- while (pos < sourcelen)
- {
- if (!strncmp(&encoded[pos], "=\r\n", 3))
- {
- pos += 3;
- }
- else if (!strncmp(&encoded[pos], "=\n", 2))
- {
- pos += 2;
- }
- else if (encoded[pos] == '=')
- {
- ch = 0;
- sscanf(&encoded[pos+1], "%02x", &ch);
- pos += 3;
- decoded[decoded_length++] = ch;
- }
- else
- {
- decoded[decoded_length++] = encoded[pos];
- pos += 1;
- }
- }
- decoded[decoded_length] = 0;
- return(decoded_length);
-}
-
-
-/*
- * if we send out non ascii subjects, we encode it this way.
- */
-char *rfc2047encode(char *line, long length)
-{
- char *AlreadyEncoded;
- char *result;
- long end;
-#define UTF8_HEADER "=?UTF-8?B?"
-
- /* check if we're already done */
- AlreadyEncoded = strstr(line, "=?");
- if ((AlreadyEncoded != NULL) &&
- ((strstr(AlreadyEncoded, "?B?") != NULL)||
- (strstr(AlreadyEncoded, "?Q?") != NULL)))
- {
- return strdup(line);
- }
-
- result = (char*) malloc(strlen(UTF8_HEADER) + 4 + length * 2);
- strncpy (result, UTF8_HEADER, strlen (UTF8_HEADER));
- CtdlEncodeBase64(result + strlen(UTF8_HEADER), line, length);
- end = strlen (result);
- result[end]='?';
- result[end+1]='=';
- result[end+2]='\0';
- return result;
-}
-
-
-/*
- * Strip leading and trailing spaces from a string
- */
-void striplt(char *buf)
-{
- size_t len;
- int a;
-
- if (buf==NULL) return;
- if (IsEmptyStr(buf)) return;
- len = strlen(buf);
- while ((!IsEmptyStr(buf)) && (isspace(buf[len - 1])))
- buf[--len] = 0;
- if (IsEmptyStr(buf)) return;
- a = 0;
- while ((!IsEmptyStr(buf)) && (isspace(buf[a])))
- a++;
- if (a > 0)
- memmove(buf, &buf[a], len - a + 1);
-}
-
-
-
-
-
-/**
- * \brief check for the presence of a character within a string (returns count)
- * \param st the string to examine
- * \param ch the char to search
- * \return the position inside of st
- */
-int haschar(const char *st,int ch)
-{
- const char *ptr;
- int b;
- b = 0;
- ptr = st;
- while (!IsEmptyStr(ptr))
- {
- if (*ptr == ch)
- ++b;
- ptr ++;
- }
- return (b);
-}
-
-
-
-
-
-/*
- * Format a date/time stamp for output
- * seconds is whether to print the seconds
- */
-void fmt_date(char *buf, size_t n, time_t thetime, int seconds) {
- struct tm tm;
- int hour;
-
- strcpy(buf, "");
- localtime_r(&thetime, &tm);
-
- hour = tm.tm_hour;
- if (hour == 0) hour = 12;
- else if (hour > 12) hour = hour - 12;
-
- if (seconds) {
- snprintf(buf, n, "%s %d %4d %d:%02d:%02d%s",
- ascmonths[tm.tm_mon],
- tm.tm_mday,
- tm.tm_year + 1900,
- hour,
- tm.tm_min,
- tm.tm_sec,
- ( (tm.tm_hour >= 12) ? "pm" : "am" )
- );
- } else {
- snprintf(buf, n, "%s %d %4d %d:%02d%s",
- ascmonths[tm.tm_mon],
- tm.tm_mday,
- tm.tm_year + 1900,
- hour,
- tm.tm_min,
- ( (tm.tm_hour >= 12) ? "pm" : "am" )
- );
- }
-}
-
-
-
-/*
- * Determine whether the specified message number is contained within the
- * specified sequence set.
- */
-int is_msg_in_sequence_set(char *mset, long msgnum) {
- int num_sets;
- int s;
- char setstr[128], lostr[128], histr[128];
- long lo, hi;
-
- num_sets = num_tokens(mset, ',');
- for (s=0; s<num_sets; ++s) {
- extract_token(setstr, mset, s, ',', sizeof setstr);
-
- extract_token(lostr, setstr, 0, ':', sizeof lostr);
- if (num_tokens(setstr, ':') >= 2) {
- extract_token(histr, setstr, 1, ':', sizeof histr);
- if (!strcmp(histr, "*")) {
- snprintf(histr, sizeof histr, "%ld", LONG_MAX);
- }
- }
- else {
- strcpy(histr, lostr);
- }
- lo = atol(lostr);
- hi = atol(histr);
-
- if ((msgnum >= lo) && (msgnum <= hi)) return(1);
- }
-
- return(0);
-}
-
-/**
- * \brief Utility function to "readline" from memory
- * \param start Location in memory from which we are reading.
- * \param buf the buffer to place the string in.
- * \param maxlen Size of string buffer
- * \return Pointer to the source memory right after we stopped reading.
- */
-char *memreadline(char *start, char *buf, int maxlen)
-{
- char ch;
- char *ptr;
- int len = 0; /**< tally our own length to avoid strlen() delays */
-
- ptr = start;
-
- while (1) {
- ch = *ptr++;
- if ((len + 1 < (maxlen)) && (ch != 13) && (ch != 10)) {
- buf[len++] = ch;
- }
- if ((ch == 10) || (ch == 0)) {
- buf[len] = 0;
- return ptr;
- }
- }
-}
-
-
-/**
- * \brief Utility function to "readline" from memory
- * \param start Location in memory from which we are reading.
- * \param buf the buffer to place the string in.
- * \param maxlen Size of string buffer
- * \param retlen the length of the returned string
- * \return Pointer to the source memory right after we stopped reading.
- */
-char *memreadlinelen(char *start, char *buf, int maxlen, int *retlen)
-{
- char ch;
- char *ptr;
- int len = 0; /**< tally our own length to avoid strlen() delays */
-
- ptr = start;
-
- while (1) {
- ch = *ptr++;
- if ((len + 1 < (maxlen)) && (ch != 13) && (ch != 10)) {
- buf[len++] = ch;
- }
- if ((ch == 10) || (ch == 0)) {
- buf[len] = 0;
- *retlen = len;
- return ptr;
- }
- }
-}
-
-
-
-
-/*
- * Strip a boundarized substring out of a string (for example, remove
- * parentheses and anything inside them).
- */
-void stripout(char *str, char leftboundary, char rightboundary) {
- int a;
- int lb = (-1);
- int rb = (-1);
-
- for (a = 0; a < strlen(str); ++a) {
- if (str[a] == leftboundary) lb = a;
- if (str[a] == rightboundary) rb = a;
- }
-
- if ( (lb > 0) && (rb > lb) ) {
- strcpy(&str[lb - 1], &str[rb + 1]);
- }
-
- else if ( (lb == 0) && (rb > lb) ) {
- strcpy(str, &str[rb + 1]);
- }
-
-}
-
-
-/*
- * Reduce a string down to a boundarized substring (for example, remove
- * parentheses and anything outside them).
- */
-void stripallbut(char *str, char leftboundary, char rightboundary) {
- int a;
-
- for (a = 0; a < strlen(str); ++ a) {
- if (str[a] == leftboundary) strcpy(str, &str[a+1]);
- }
-
- for (a = 0; a < strlen(str); ++ a) {
- if (str[a] == rightboundary) str[a] = 0;
- }
-
-}
-
-char *myfgets(char *s, int size, FILE *stream) {
- char *ret = fgets(s, size, stream);
- char *nl;
-
- if (ret != NULL) {
- nl = strchr(s, '\n');
-
- if (nl != NULL)
- *nl = 0;
- }
-
- return ret;
-}
-
-/*
- * Escape a string for feeding out as a URL.
- * Output buffer must be big enough to handle escape expansion!
- */
-void urlesc(char *outbuf, char *strbuf)
-{
- int a, b, c;
- char *ec = " #&;`'|*?-~<>^()[]{}$\\";
-
- strcpy(outbuf, "");
-
- for (a = 0; a < (int)strlen(strbuf); ++a) {
- c = 0;
- for (b = 0; b < strlen(ec); ++b) {
- if (strbuf[a] == ec[b])
- c = 1;
- }
- b = strlen(outbuf);
- if (c == 1)
- sprintf(&outbuf[b], "%%%02x", strbuf[a]);
- else
- sprintf(&outbuf[b], "%c", strbuf[a]);
- }
-}
-
-
-
-/*
- * In our world, we want strcpy() to be able to work with overlapping strings.
- */
-#ifdef strcpy
-#undef strcpy
-#endif
-char *strcpy(char *dest, const char *src) {
- memmove(dest, src, (strlen(src) + 1) );
- return(dest);
-}
-
-
-/*
- * Generate a new, globally unique UID parameter for a calendar etc. object
- */
-void generate_uuid(char *buf) {
- static int seq = 0;
-
- sprintf(buf, "%lx-"F_XPID_T"-%x",
- time(NULL),
- getpid(),
- (seq++)
- );
-}
-
-/*
- * bmstrcasestr() -- case-insensitive substring search
- *
- * This uses the Boyer-Moore search algorithm and is therefore quite fast.
- * The code is roughly based on the strstr() replacement from 'tin' written
- * by Urs Jannsen.
- */
-char *bmstrcasestr(char *text, char *pattern) {
-
- register unsigned char *p, *t;
- register int i, j, *delta;
- register size_t p1;
- int deltaspace[256];
- size_t textlen;
- size_t patlen;
-
- textlen = strlen (text);
- patlen = strlen (pattern);
-
- /* algorithm fails if pattern is empty */
- if ((p1 = patlen) == 0)
- return (text);
-
- /* code below fails (whenever i is unsigned) if pattern too long */
- if (p1 > textlen)
- return (NULL);
-
- /* set up deltas */
- delta = deltaspace;
- for (i = 0; i <= 255; i++)
- delta[i] = p1;
- for (p = (unsigned char *) pattern, i = p1; --i > 0;)
- delta[tolower(*p++)] = i;
-
- /*
- * From now on, we want patlen - 1.
- * In the loop below, p points to the end of the pattern,
- * t points to the end of the text to be tested against the
- * pattern, and i counts the amount of text remaining, not
- * including the part to be tested.
- */
- p1--;
- p = (unsigned char *) pattern + p1;
- t = (unsigned char *) text + p1;
- i = textlen - patlen;
- while(1) {
- if (tolower(p[0]) == tolower(t[0])) {
- if (strncasecmp ((const char *)(p - p1), (const char *)(t - p1), p1) == 0) {
- return ((char *)t - p1);
- }
- }
- j = delta[tolower(t[0])];
- if (i < j)
- break;
- i -= j;
- t += j;
- }
- return (NULL);
-}
-
-
-
-/*
- * Local replacement for controversial C library function that generates
- * names for temporary files. Included to shut up compiler warnings.
- */
-void CtdlMakeTempFileName(char *name, int len) {
- int i = 0;
-
- while (i++, i < 100) {
- snprintf(name, len, "/tmp/ctdl."F_XPID_T".%04x",
- getpid(),
- rand()
- );
- if (!access(name, F_OK)) {
- return;
- }
- }
-}
+++ /dev/null
-/* $Id$ */
-char *safestrncpy(char *dest, const char *src, size_t n);
-int num_tokens (const char *source, char tok);
-long extract_token(char *dest, const char *source, int parmnum, char separator, int maxlen);
-long grab_token(char **dest, const char *source, int parmnum, char separator);
-int extract_int (const char *source, int parmnum);
-long extract_long (const char *source, int parmnum);
-unsigned long extract_unsigned_long(const char *source, int parmnum);
-void CtdlInitBase64Table(void);
-void CtdlEncodeBase64(char *dest, const char *source, size_t sourcelen);
-int CtdlDecodeBase64(char *dest, const char *source, size_t length);
-int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen);
-void 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(char *mset, long msgnum);
-char *memreadline(char *start, char *buf, int maxlen);
-char *memreadlinelen(char *start, char *buf, int maxlen, int *retlen);
-
-#ifndef HAVE_STRNCASECMP
-int strncasecmp(char *, char *, int);
-#endif
-#ifndef HAVE_STRCASECMP
-#define strcasecmp(x,y) strncasecmp(x,y,INT_MAX);
-#endif
-
-#define IsEmptyStr(a) ((a)[0] == '\0')
-
-#define num_parms(source) num_tokens(source,(char)'|')
-void stripout(char *str, char leftboundary, char rightboundary);
-void stripallbut(char *str, char leftboundary, char rightboundary);
-
-char *myfgets(char *s, int size, FILE *stream);
-void urlesc(char *outbuf, char *strbuf);
-char *CtdlTempFileName(char *prefix1, int prefix2);
-FILE *CtdlTempFile(void);
-char *ascmonths[12];
-void generate_uuid(char *buf);
-char *bmstrcasestr(char *text, char *pattern);
-void CtdlMakeTempFileName(char *name, int len);
-char *rfc2047encode(char *line, long length);
#include <pwd.h>
#include <errno.h>
#include <stdarg.h>
+#include <libcitadel.h>
#include "sysdep.h"
#include "citadel.h"
#include "citadel_ipc.h"
#include "messages.h"
#include "routines.h"
#include "commands.h"
-#include "tools.h"
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
#endif
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "auth.h"
#include "citadel.h"
#include "server.h"
#include "control.h"
#include "msgbase.h"
#include "config.h"
-#include "tools.h"
#include "citserver.h"
#include "citadel_dirs.h"
#include "genstamp.h"
# endif
#endif
+#include <libcitadel.h>
#include "citadel.h"
#include <unistd.h>
#include "citadel_ipc.h"
-#include "tools.h"
#include "citadel_dirs.h"
void logoff(int code)
#include <errno.h>
#include <limits.h>
#include <string.h>
-
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "support.h"
#include "vcard.h"
-#include "tools.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
#include "citadel_dirs.h"
-#include "tools.h"
void logoff(int code)
{
LINK_EXE = $(LIBTOOL) $(LTFLAGS) --mode=link $(COMPILE) $(LDFLAGS) -o $@
LINK_CXX_EXE = $(LIBTOOL) $(LTFLAGS) --mode=link $(CXXCOMPILE) $(LDFLAGS) -o $@
-LIB_OBJS = lib/libcitadel.lo
+LIB_OBJS = lib/libcitadel.lo lib/mime_parser.lo lib/tools.lo
$(LIBRARY): $(LIB_OBJS)
$(LINK_LIB) $(LIB_OBJS)
lib/libcitadel.lo: lib/libcitadel.c lib/libcitadel.h
+lib/mime_parser.lo: lib/mime_parser.c lib/libcitadel.h
+lib/tools.lo: lib/tools.c lib/libcitadel.h
.SUFFIXES: .c .cpp .lo .o
#define SIZ 4096
#endif
+#ifndef IsEmptyStr
+#define IsEmptyStr(a) ((a)[0] == '\0')
+#endif
+
/*
* Misc declarations
*/
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,
+ char *disposition,
+ 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,
+ void *cbuserdata),
+ void (*PreMultiPartCallBack)
+ (char *cbname,
+ char *cbfilename,
+ char *cbpartnum,
+ char *cbdisp,
+ void *cbcontent,
+ char *cbtype,
+ char *cbcharset,
+ size_t cblength,
+ char *cbencoding,
+ void *cbuserdata),
+ void (*PostMultiPartCallBack)
+ (char *cbname,
+ char *cbfilename,
+ char *cbpartnum,
+ char *cbdisp,
+ void *cbcontent,
+ char *cbtype,
+ char *cbcharset,
+ size_t cblength,
+ char *cbencoding,
+ void *cbuserdata),
+ void *userdata,
+ int dont_decode
+);
+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,
+ void *cbuserdata),
+ void (*PreMultiPartCallBack)
+ (char *cbname,
+ char *cbfilename,
+ char *cbpartnum,
+ char *cbdisp,
+ void *cbcontent,
+ char *cbtype,
+ char *cbcharset,
+ size_t cblength,
+ char *cbencoding,
+ void *cbuserdata),
+ void (*PostMultiPartCallBack)
+ (char *cbname,
+ char *cbfilename,
+ char *cbpartnum,
+ char *cbdisp,
+ void *cbcontent,
+ char *cbtype,
+ char *cbcharset,
+ size_t cblength,
+ char *cbencoding,
+ void *cbuserdata),
+ void *userdata,
+ int dont_decode
+);
+
+
+
+/* tools */
+
+
+
+char *safestrncpy(char *dest, const char *src, size_t n);
+int num_tokens (const char *source, char tok);
+long extract_token(char *dest, const char *source, int parmnum, char separator, int maxlen);
+long grab_token(char **dest, const char *source, int parmnum, char separator);
+int extract_int (const char *source, int parmnum);
+long extract_long (const char *source, int parmnum);
+unsigned long extract_unsigned_long(const char *source, int parmnum);
+void CtdlInitBase64Table(void);
+size_t CtdlEncodeBase64(char *dest, const char *source, size_t sourcelen, int linebreaks);
+int CtdlDecodeBase64(char *dest, const char *source, size_t length);
+int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen);
+void 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(char *mset, long msgnum);
+char *memreadline(char *start, char *buf, int maxlen);
+char *memreadlinelen(char *start, char *buf, int maxlen, int *retlen);
+#define IsEmptyStr(a) ((a)[0] == '\0')
+#define num_parms(source) num_tokens(source,(char)'|')
+void stripout(char *str, char leftboundary, char rightboundary);
+void stripallbut(char *str, char leftboundary, char rightboundary);
+char *myfgets(char *s, int size, FILE *stream);
+void urlesc(char *outbuf, char *strbuf);
+char *CtdlTempFileName(char *prefix1, int prefix2);
+FILE *CtdlTempFile(void);
+char *ascmonths[12];
+void generate_uuid(char *buf);
+char *bmstrcasestr(char *text, char *pattern);
+void CtdlMakeTempFileName(char *name, int len);
+char *rfc2047encode(char *line, long length);
+int is_msg_in_mset(char *mset, long msgnum);
+int pattern2(char *search, char *patn);
+void stripltlen(char *, int *);
+
--- /dev/null
+/*
+ *
+ */
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <limits.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#include "libcitadel.h"
+
+
+#define TRUE 1
+#define FALSE 0
+
+typedef unsigned char byte; /* Byte type */
+static byte dtable[256] = "\0"; /* base64 decode table */
+static byte etable[256] = "\0"; /* base64 encode table */
+
+/* Month strings for date conversions */
+char *ascmonths[12] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+char *safestrncpy(char *dest, const char *src, size_t n)
+{
+ int i = 0;
+
+ if (dest == NULL || src == NULL) {
+ fprintf(stderr, "safestrncpy: NULL argument\n");
+ abort();
+ }
+
+ do {
+ dest[i] = src[i];
+ if (dest[i] == 0) return(dest);
+ ++i;
+ } while (i<n);
+ dest[n - 1] = 0;
+ return dest;
+}
+
+
+
+/*
+ * num_tokens() - discover number of parameters/tokens in a string
+ */
+int num_tokens(const char *source, char tok)
+{
+ int count = 1;
+ const char *ptr = source;
+
+ if (source == NULL) {
+ return (0);
+ }
+
+ while (*ptr != '\0') {
+ if (*ptr++ == tok) {
+ ++count;
+ }
+ }
+
+ return (count);
+}
+
+//extern void cit_backtrace(void);
+
+
+/*
+ * extract_token() - a string tokenizer
+ * returns -1 if not found, or length of token.
+ */
+long extract_token(char *dest, const char *source, int parmnum, char separator, int maxlen)
+{
+ const char *s; //* source * /
+ int len = 0; //* running total length of extracted string * /
+ int current_token = 0; //* token currently being processed * /
+
+ s = source;
+
+ if (dest == NULL) {
+ return(-1);
+ }
+
+// cit_backtrace();
+// lprintf (CTDL_DEBUG, "test >: n: %d sep: %c source: %s \n willi \n", parmnum, separator, source);
+ dest[0] = 0;
+
+ if (s == NULL) {
+ return(-1);
+ }
+
+ maxlen--;
+
+ while (*s) {
+ if (*s == separator) {
+ ++current_token;
+ }
+ if ( (current_token == parmnum) &&
+ (*s != separator) &&
+ (len < maxlen) ) {
+ dest[len] = *s;
+ ++len;
+ }
+ else if ((current_token > parmnum) || (len >= maxlen)) {
+ break;
+ }
+ ++s;
+ }
+
+ dest[len] = '\0';
+ if (current_token < parmnum) {
+// lprintf (CTDL_DEBUG,"test <!: %s\n", dest);
+ return(-1);
+ }
+// lprintf (CTDL_DEBUG,"test <: %d; %s\n", len, dest);
+ return(len);
+}
+//*/
+
+
+/*
+ * extract_token() - a string tokenizer
+ * /
+long extract_token(char *dest, const char *source, int parmnum, char separator, int maxlen)
+{
+ char *d; // dest
+ const char *s; // source
+ int count = 0;
+ int len = 0;
+
+
+// cit_backtrace();
+ lprintf (CTDL_DEBUG, "test >: n: %d sep: %c source: %s \n willi \n", parmnum, separator, source);
+ strcpy(dest, "");
+
+ // Locate desired parameter
+ s = source;
+ while (count < parmnum) {
+ // End of string, bail!
+ if (!*s) {
+ s = NULL;
+ break;
+ }
+ if (*s == separator) {
+ count++;
+ }
+ s++;
+ }
+ if (!s) {
+ lprintf (CTDL_DEBUG,"test <!: %s\n", dest);
+ return -1; // Parameter not found
+ }
+
+ for (d = dest; *s && *s != separator && ++len<maxlen; s++, d++) {
+ *d = *s;
+ }
+ *d = 0;
+ lprintf (CTDL_DEBUG,"test <: %d; %s\n", len, dest);
+ return 0;
+}
+*/
+
+
+/*
+ * remove_token() - a tokenizer that kills, maims, and destroys
+ */
+void remove_token(char *source, int parmnum, char separator)
+{
+ char *d, *s; /* dest, source */
+ int count = 0;
+
+ /* Find desired parameter */
+ d = source;
+ while (count < parmnum) {
+ /* End of string, bail! */
+ if (!*d) {
+ d = NULL;
+ break;
+ }
+ if (*d == separator) {
+ count++;
+ }
+ d++;
+ }
+ if (!d) return; /* Parameter not found */
+
+ /* Find next parameter */
+ s = d;
+ while (*s && *s != separator) {
+ s++;
+ }
+
+ /* Hack and slash */
+ if (*s)
+ strcpy(d, ++s);
+ else if (d == source)
+ *d = 0;
+ else
+ *--d = 0;
+ /*
+ while (*s) {
+ *d++ = *s++;
+ }
+ *d = 0;
+ */
+}
+
+
+/*
+ * extract_int() - extract an int parm w/o supplying a buffer
+ */
+int extract_int(const char *source, int parmnum)
+{
+ char buf[32];
+
+ extract_token(buf, source, parmnum, '|', sizeof buf);
+ return(atoi(buf));
+}
+
+/*
+ * extract_long() - extract an long parm w/o supplying a buffer
+ */
+long extract_long(const char *source, int parmnum)
+{
+ char buf[32];
+
+ extract_token(buf, source, parmnum, '|', sizeof buf);
+ return(atol(buf));
+}
+
+
+/*
+ * extract_unsigned_long() - extract an unsigned long parm
+ */
+unsigned long extract_unsigned_long(const char *source, int parmnum)
+{
+ char buf[32];
+
+ extract_token(buf, source, parmnum, '|', sizeof buf);
+ return strtoul(buf, NULL, 10);
+}
+
+
+
+void CtdlInitBase64Table(void)
+{
+ int i;
+ /* Fill dtable with character encodings. */
+
+ /* Encoder Table */
+ for (i = 0; i < 26; i++) {
+ etable[i] = 'A' + i;
+ etable[26 + i] = 'a' + i;
+ }
+ for (i = 0; i < 10; i++) {
+ etable[52 + i] = '0' + i;
+ }
+ etable[62] = '+';
+ etable[63] = '/';
+
+ /* Decoder Table */
+ for (i = 0; i < 255; i++) {
+ dtable[i] = 0x80;
+ }
+ for (i = 'A'; i <= 'Z'; i++) {
+ dtable[i] = 0 + (i - 'A');
+ }
+ for (i = 'a'; i <= 'z'; i++) {
+ dtable[i] = 26 + (i - 'a');
+ }
+ for (i = '0'; i <= '9'; i++) {
+ dtable[i] = 52 + (i - '0');
+ }
+ dtable['+'] = 62;
+ dtable['/'] = 63;
+ dtable['='] = 0;
+}
+
+
+/*
+ * CtdlDecodeBase64() and CtdlEncodeBase64() are adaptations of code by John Walker.
+ */
+
+size_t CtdlEncodeBase64(char *dest, const char *source, size_t sourcelen, int linebreaks)
+{
+ int i, hiteof = FALSE;
+ int spos = 0;
+ int dpos = 0;
+ int thisline = 0;
+
+ /** Fill dtable with character encodings. */
+
+ for (i = 0; i < 26; i++) {
+ dtable[i] = 'A' + i;
+ dtable[26 + i] = 'a' + i;
+ }
+ for (i = 0; i < 10; i++) {
+ dtable[52 + i] = '0' + i;
+ }
+ dtable[62] = '+';
+ dtable[63] = '/';
+
+ while (!hiteof) {
+ byte igroup[3], ogroup[4];
+ int c, n;
+
+ igroup[0] = igroup[1] = igroup[2] = 0;
+ for (n = 0; n < 3; n++) {
+ if (spos >= sourcelen) {
+ hiteof = TRUE;
+ break;
+ }
+ c = source[spos++];
+ igroup[n] = (byte) c;
+ }
+ if (n > 0) {
+ ogroup[0] = dtable[igroup[0] >> 2];
+ ogroup[1] =
+ dtable[((igroup[0] & 3) << 4) |
+ (igroup[1] >> 4)];
+ ogroup[2] =
+ dtable[((igroup[1] & 0xF) << 2) |
+ (igroup[2] >> 6)];
+ ogroup[3] = dtable[igroup[2] & 0x3F];
+
+ /**
+ * Replace characters in output stream with "=" pad
+ * characters if fewer than three characters were
+ * read from the end of the input stream.
+ */
+
+ if (n < 3) {
+ ogroup[3] = '=';
+ if (n < 2) {
+ ogroup[2] = '=';
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ dest[dpos++] = ogroup[i];
+ dest[dpos] = 0;
+ }
+ thisline += 4;
+ if ( (linebreaks) && (thisline > 70) ) {
+ dest[dpos++] = '\r';
+ dest[dpos++] = '\n';
+ dest[dpos] = 0;
+ thisline = 0;
+ }
+ }
+ }
+ if ( (linebreaks) && (thisline > 70) ) {
+ dest[dpos++] = '\r';
+ dest[dpos++] = '\n';
+ dest[dpos] = 0;
+ thisline = 0;
+ }
+
+ return(dpos);
+}
+
+
+
+/*
+ * Convert base64-encoded to binary. Returns the length of the decoded data.
+ * It will stop after reading 'length' bytes.
+ */
+int CtdlDecodeBase64(char *dest, const char *source, size_t length)
+{
+ int i, c;
+ int dpos = 0;
+ int spos = 0;
+
+
+ /*CONSTANTCONDITION*/
+ while (TRUE) {
+ byte a[4], b[4], o[3];
+
+ for (i = 0; i < 4; i++) {
+ if (spos >= length) {
+ return(dpos);
+ }
+ c = source[spos++];
+
+ if (c == 0) {
+ if (i > 0) {
+ return(dpos);
+ }
+ return(dpos);
+ }
+ if (dtable[c] & 0x80) {
+ /* Ignoring errors: discard invalid character. */
+ i--;
+ continue;
+ }
+ a[i] = (byte) c;
+ b[i] = (byte) dtable[c];
+ }
+ o[0] = (b[0] << 2) | (b[1] >> 4);
+ o[1] = (b[1] << 4) | (b[2] >> 2);
+ o[2] = (b[2] << 6) | b[3];
+ i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
+ if (i>=1) dest[dpos++] = o[0];
+ if (i>=2) dest[dpos++] = o[1];
+ if (i>=3) dest[dpos++] = o[2];
+ dest[dpos] = 0;
+ if (i < 3) {
+ return(dpos);
+ }
+ }
+}
+
+
+/*
+ * if we send out non ascii subjects, we encode it this way.
+ */
+char *rfc2047encode(char *line, long length)
+{
+ char *AlreadyEncoded;
+ char *result;
+ long end;
+#define UTF8_HEADER "=?UTF-8?B?"
+
+ /* check if we're already done */
+ AlreadyEncoded = strstr(line, "=?");
+ if ((AlreadyEncoded != NULL) &&
+ ((strstr(AlreadyEncoded, "?B?") != NULL)||
+ (strstr(AlreadyEncoded, "?Q?") != NULL)))
+ {
+ return strdup(line);
+ }
+
+ result = (char*) malloc(strlen(UTF8_HEADER) + 4 + length * 2);
+ strncpy (result, UTF8_HEADER, strlen (UTF8_HEADER));
+ CtdlEncodeBase64(result + strlen(UTF8_HEADER), line, length, 0);
+ end = strlen (result);
+ result[end]='?';
+ result[end+1]='=';
+ result[end+2]='\0';
+ return result;
+}
+
+
+/*
+ * Strip leading and trailing spaces from a string
+ */
+void striplt(char *buf)
+{
+ size_t len;
+ int a;
+
+ if (buf==NULL) return;
+ if (IsEmptyStr(buf)) return;
+ len = strlen(buf);
+ while ((!IsEmptyStr(buf)) && (isspace(buf[len - 1])))
+ buf[--len] = 0;
+ if (IsEmptyStr(buf)) return;
+ a = 0;
+ while ((!IsEmptyStr(buf)) && (isspace(buf[a])))
+ a++;
+ if (a > 0)
+ memmove(buf, &buf[a], len - a + 1);
+}
+
+
+
+
+
+/**
+ * \brief check for the presence of a character within a string (returns count)
+ * \param st the string to examine
+ * \param ch the char to search
+ * \return the position inside of st
+ */
+int haschar(const char *st,int ch)
+{
+ const char *ptr;
+ int b;
+ b = 0;
+ ptr = st;
+ while (!IsEmptyStr(ptr))
+ {
+ if (*ptr == ch)
+ ++b;
+ ptr ++;
+ }
+ return (b);
+}
+
+
+
+
+
+/*
+ * Format a date/time stamp for output
+ * seconds is whether to print the seconds
+ */
+void fmt_date(char *buf, size_t n, time_t thetime, int seconds) {
+ struct tm tm;
+ int hour;
+
+ strcpy(buf, "");
+ localtime_r(&thetime, &tm);
+
+ hour = tm.tm_hour;
+ if (hour == 0) hour = 12;
+ else if (hour > 12) hour = hour - 12;
+
+ if (seconds) {
+ snprintf(buf, n, "%s %d %4d %d:%02d:%02d%s",
+ ascmonths[tm.tm_mon],
+ tm.tm_mday,
+ tm.tm_year + 1900,
+ hour,
+ tm.tm_min,
+ tm.tm_sec,
+ ( (tm.tm_hour >= 12) ? "pm" : "am" )
+ );
+ } else {
+ snprintf(buf, n, "%s %d %4d %d:%02d%s",
+ ascmonths[tm.tm_mon],
+ tm.tm_mday,
+ tm.tm_year + 1900,
+ hour,
+ tm.tm_min,
+ ( (tm.tm_hour >= 12) ? "pm" : "am" )
+ );
+ }
+}
+
+
+
+/*
+ * Determine whether the specified message number is contained within the
+ * specified sequence set.
+ */
+int is_msg_in_sequence_set(char *mset, long msgnum) {
+ int num_sets;
+ int s;
+ char setstr[128], lostr[128], histr[128];
+ long lo, hi;
+
+ num_sets = num_tokens(mset, ',');
+ for (s=0; s<num_sets; ++s) {
+ extract_token(setstr, mset, s, ',', sizeof setstr);
+
+ extract_token(lostr, setstr, 0, ':', sizeof lostr);
+ if (num_tokens(setstr, ':') >= 2) {
+ extract_token(histr, setstr, 1, ':', sizeof histr);
+ if (!strcmp(histr, "*")) {
+ snprintf(histr, sizeof histr, "%ld", LONG_MAX);
+ }
+ }
+ else {
+ strcpy(histr, lostr);
+ }
+ lo = atol(lostr);
+ hi = atol(histr);
+
+ if ((msgnum >= lo) && (msgnum <= hi)) return(1);
+ }
+
+ return(0);
+}
+
+/**
+ * \brief Utility function to "readline" from memory
+ * \param start Location in memory from which we are reading.
+ * \param buf the buffer to place the string in.
+ * \param maxlen Size of string buffer
+ * \return Pointer to the source memory right after we stopped reading.
+ */
+char *memreadline(char *start, char *buf, int maxlen)
+{
+ char ch;
+ char *ptr;
+ int len = 0; /**< tally our own length to avoid strlen() delays */
+
+ ptr = start;
+
+ while (1) {
+ ch = *ptr++;
+ if ((len + 1 < (maxlen)) && (ch != 13) && (ch != 10)) {
+ buf[len++] = ch;
+ }
+ if ((ch == 10) || (ch == 0)) {
+ buf[len] = 0;
+ return ptr;
+ }
+ }
+}
+
+
+/**
+ * \brief Utility function to "readline" from memory
+ * \param start Location in memory from which we are reading.
+ * \param buf the buffer to place the string in.
+ * \param maxlen Size of string buffer
+ * \param retlen the length of the returned string
+ * \return Pointer to the source memory right after we stopped reading.
+ */
+char *memreadlinelen(char *start, char *buf, int maxlen, int *retlen)
+{
+ char ch;
+ char *ptr;
+ int len = 0; /**< tally our own length to avoid strlen() delays */
+
+ ptr = start;
+
+ while (1) {
+ ch = *ptr++;
+ if ((len + 1 < (maxlen)) && (ch != 13) && (ch != 10)) {
+ buf[len++] = ch;
+ }
+ if ((ch == 10) || (ch == 0)) {
+ buf[len] = 0;
+ *retlen = len;
+ return ptr;
+ }
+ }
+}
+
+
+
+
+/*
+ * Strip a boundarized substring out of a string (for example, remove
+ * parentheses and anything inside them).
+ */
+void stripout(char *str, char leftboundary, char rightboundary) {
+ int a;
+ int lb = (-1);
+ int rb = (-1);
+
+ for (a = 0; a < strlen(str); ++a) {
+ if (str[a] == leftboundary) lb = a;
+ if (str[a] == rightboundary) rb = a;
+ }
+
+ if ( (lb > 0) && (rb > lb) ) {
+ strcpy(&str[lb - 1], &str[rb + 1]);
+ }
+
+ else if ( (lb == 0) && (rb > lb) ) {
+ strcpy(str, &str[rb + 1]);
+ }
+
+}
+
+
+/*
+ * Reduce a string down to a boundarized substring (for example, remove
+ * parentheses and anything outside them).
+ */
+void stripallbut(char *str, char leftboundary, char rightboundary) {
+ int a;
+
+ for (a = 0; a < strlen(str); ++ a) {
+ if (str[a] == leftboundary) strcpy(str, &str[a+1]);
+ }
+
+ for (a = 0; a < strlen(str); ++ a) {
+ if (str[a] == rightboundary) str[a] = 0;
+ }
+
+}
+
+char *myfgets(char *s, int size, FILE *stream) {
+ char *ret = fgets(s, size, stream);
+ char *nl;
+
+ if (ret != NULL) {
+ nl = strchr(s, '\n');
+
+ if (nl != NULL)
+ *nl = 0;
+ }
+
+ return ret;
+}
+
+/*
+ * Escape a string for feeding out as a URL.
+ * Output buffer must be big enough to handle escape expansion!
+ */
+void urlesc(char *outbuf, char *strbuf)
+{
+ int a, b, c;
+ char *ec = " #&;`'|*?-~<>^()[]{}$\\";
+
+ strcpy(outbuf, "");
+
+ for (a = 0; a < (int)strlen(strbuf); ++a) {
+ c = 0;
+ for (b = 0; b < strlen(ec); ++b) {
+ if (strbuf[a] == ec[b])
+ c = 1;
+ }
+ b = strlen(outbuf);
+ if (c == 1)
+ sprintf(&outbuf[b], "%%%02x", strbuf[a]);
+ else
+ sprintf(&outbuf[b], "%c", strbuf[a]);
+ }
+}
+
+
+
+/*
+ * In our world, we want strcpy() to be able to work with overlapping strings.
+ */
+#ifdef strcpy
+#undef strcpy
+#endif
+char *strcpy(char *dest, const char *src) {
+ memmove(dest, src, (strlen(src) + 1) );
+ return(dest);
+}
+
+
+/*
+ * Generate a new, globally unique UID parameter for a calendar etc. object
+ */
+void generate_uuid(char *buf) {
+ static int seq = 0;
+
+ sprintf(buf, "%lx-%lx-%x",
+ time(NULL),
+ (long)getpid(),
+ (seq++)
+ );
+}
+
+/*
+ * bmstrcasestr() -- case-insensitive substring search
+ *
+ * This uses the Boyer-Moore search algorithm and is therefore quite fast.
+ * The code is roughly based on the strstr() replacement from 'tin' written
+ * by Urs Jannsen.
+ */
+char *bmstrcasestr(char *text, char *pattern) {
+
+ register unsigned char *p, *t;
+ register int i, j, *delta;
+ register size_t p1;
+ int deltaspace[256];
+ size_t textlen;
+ size_t patlen;
+
+ textlen = strlen (text);
+ patlen = strlen (pattern);
+
+ /* algorithm fails if pattern is empty */
+ if ((p1 = patlen) == 0)
+ return (text);
+
+ /* code below fails (whenever i is unsigned) if pattern too long */
+ if (p1 > textlen)
+ return (NULL);
+
+ /* set up deltas */
+ delta = deltaspace;
+ for (i = 0; i <= 255; i++)
+ delta[i] = p1;
+ for (p = (unsigned char *) pattern, i = p1; --i > 0;)
+ delta[tolower(*p++)] = i;
+
+ /*
+ * From now on, we want patlen - 1.
+ * In the loop below, p points to the end of the pattern,
+ * t points to the end of the text to be tested against the
+ * pattern, and i counts the amount of text remaining, not
+ * including the part to be tested.
+ */
+ p1--;
+ p = (unsigned char *) pattern + p1;
+ t = (unsigned char *) text + p1;
+ i = textlen - patlen;
+ while(1) {
+ if (tolower(p[0]) == tolower(t[0])) {
+ if (strncasecmp ((const char *)(p - p1), (const char *)(t - p1), p1) == 0) {
+ return ((char *)t - p1);
+ }
+ }
+ j = delta[tolower(t[0])];
+ if (i < j)
+ break;
+ i -= j;
+ t += j;
+ }
+ return (NULL);
+}
+
+
+
+/*
+ * Local replacement for controversial C library function that generates
+ * names for temporary files. Included to shut up compiler warnings.
+ */
+void CtdlMakeTempFileName(char *name, int len) {
+ int i = 0;
+
+ while (i++, i < 100) {
+ snprintf(name, len, "/tmp/ctdl.%4lx.%04x",
+ (long)getpid(),
+ rand()
+ );
+ if (!access(name, F_OK)) {
+ return;
+ }
+ }
+}
+
+
+
+/*
+ * Determine whether the specified message number is contained within the specified set.
+ * Returns nonzero if the specified message number is in the specified message set string.
+ */
+int is_msg_in_mset(char *mset, long msgnum) {
+ int num_sets;
+ int s;
+ char setstr[SIZ], lostr[SIZ], histr[SIZ]; /* was 1024 */
+ long lo, hi;
+
+ /*
+ * Now set it for all specified messages.
+ */
+ num_sets = num_tokens(mset, ',');
+ for (s=0; s<num_sets; ++s) {
+ extract_token(setstr, mset, s, ',', sizeof setstr);
+
+ extract_token(lostr, setstr, 0, ':', sizeof lostr);
+ if (num_tokens(setstr, ':') >= 2) {
+ extract_token(histr, setstr, 1, ':', sizeof histr);
+ if (!strcmp(histr, "*")) {
+ snprintf(histr, sizeof histr, "%ld", LONG_MAX);
+ }
+ }
+ else {
+ strcpy(histr, lostr);
+ }
+ lo = atol(lostr);
+ hi = atol(histr);
+
+ if ((msgnum >= lo) && (msgnum <= hi)) return(1);
+ }
+
+ return(0);
+}
+
+
+/**
+ * \brief searches for a paternn within asearch string
+ * \param search the string to search
+ * \param patn the pattern to find in string
+ * \returns position in string
+ */
+int pattern2(char *search, char *patn)
+{
+ int a;
+ int len, plen;
+ len = strlen (search);
+ plen = strlen (patn);
+ for (a = 0; a < len; ++a) {
+ if (!strncasecmp(&search[a], patn, plen))
+ return (a);
+ }
+ return (-1);
+}
+
+
+/**
+ * \brief Strip leading and trailing spaces from a string; with premeasured and adjusted length.
+ * \param buf the string to modify
+ * \param len length of the string.
+ */
+void stripltlen(char *buf, int *len)
+{
+ int delta = 0;
+ if (*len == 0) return;
+ while ((*len > delta) && (isspace(buf[delta]))){
+ delta ++;
+ }
+ memmove (buf, &buf[delta], *len - delta + 1);
+ (*len) -=delta;
+
+ if (*len == 0) return;
+ while (isspace(buf[(*len) - 1])){
+ buf[--(*len)] = '\0';
+ }
+}
+
po/Makefile \
$(srcdir)/TAGS
-setup: setup.o tools.o
- $(CC) setup.o tools.o \
+setup: setup.o
+ $(CC) setup.o \
$(LIBOBJS) $(LIBS) $(LDFLAGS) $(SETUP_LIBS) -o setup
-webserver: webserver.o context_loop.o tools.o ical_dezonify.o \
+webserver: webserver.o context_loop.o ical_dezonify.o \
cookie_conversion.o locate_host.o floors.o summary.o \
webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o \
roomops.o messages.o userlist.o paging.o sysmsgs.o useredit.o \
vcard.o vcard_edit.o preferences.o html2html.o listsub.o \
- mime_parser.o graphics.o netconf.o siteconfig.o subst.o rss.o \
+ graphics.o netconf.o siteconfig.o subst.o rss.o \
calendar.o calendar_tools.o calendar_view.o event.o smtpqueue.o \
availability.o iconbar.o crypto.o inetconf.o notes.o wiki.o \
groupdav_main.o groupdav_get.o groupdav_propfind.o fmt_date.o \
groupdav_delete.o groupdav_put.o http_datestring.o setup_wizard.o \
downloads.o addressbook_popup.o pushemail.o sysdep.o \
$(LIBOBJS)
- $(CC) webserver.o context_loop.o tools.o cookie_conversion.o \
+ $(CC) webserver.o context_loop.o cookie_conversion.o \
webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o listsub.o \
roomops.o messages.o userlist.o paging.o sysmsgs.o useredit.o \
locate_host.o siteconfig.o subst.o vcard.o vcard_edit.o floors.o \
- mime_parser.o graphics.o netconf.o preferences.o html2html.o rss.o \
+ graphics.o netconf.o preferences.o html2html.o rss.o \
summary.o calendar.o calendar_tools.o calendar_view.o event.o wiki.o \
availability.o ical_dezonify.o iconbar.o crypto.o inetconf.o notes.o \
groupdav_main.o groupdav_get.o groupdav_propfind.o groupdav_delete.o \
}
else {
tt = icaltime_as_timet(t);
- fmt_date(buf, tt, 0);
+ webcit_fmt_date(buf, tt, 0);
wprintf("<dt>");
wprintf(_("Starting date/time:"));
wprintf("</dt><dd>%s</dd>", buf);
if (p != NULL) {
t = icalproperty_get_dtend(p);
tt = icaltime_as_timet(t);
- fmt_date(buf, tt, 0);
+ webcit_fmt_date(buf, tt, 0);
wprintf("<dt>");
wprintf(_("Ending date/time:"));
wprintf("</dt><dd>%s</dd>", buf);
}
else {
tt = icaltime_as_timet(t);
- fmt_date(buf, tt, 1);
+ webcit_fmt_date(buf, tt, 1);
wprintf("<i>%s</i> %s<br>",
_("Starting date/time:"), buf);
if (q != NULL) {
t = icalproperty_get_dtend(q);
tt = icaltime_as_timet(t);
- fmt_date(buf, tt, 1);
+ webcit_fmt_date(buf, tt, 1);
wprintf("<i>%s</i> %s<br>", _("Ending date/time:"), buf);
}
escputs((char *)icalproperty_get_comment(q));
wprintf("<br />");
}
- fmt_date(buf, event_tt, 1);
+ webcit_fmt_date(buf, event_tt, 1);
wprintf("<i>%s</i> %s<br>", _("Starting date/time:"), buf);
- fmt_date(buf, event_tte, 1);
+ webcit_fmt_date(buf, event_tte, 1);
wprintf("<i>%s</i> %s<br>", _("Ending date/time:"), buf);
q = icalcomponent_get_first_property(Cal->cal,ICAL_DESCRIPTION_PROPERTY);
if (q) {
escputs((char *)icalproperty_get_comment(q));
wprintf("<br />");
}
- fmt_date(buf, event_tt, 1);
+ webcit_fmt_date(buf, event_tt, 1);
wprintf("<i>%s</i> %s<br>", _("Starting date/time:"), buf);
- fmt_date(buf, event_tte, 1);
+ webcit_fmt_date(buf, event_tte, 1);
wprintf("<i>%s</i> %s<br>", _("Ending date/time:"), buf);
q = icalcomponent_get_first_property(Cal->cal,ICAL_DESCRIPTION_PROPERTY);
if (q) {
wprintf("</td>\n");
due = get_task_due_date(WC->disp_cal[i].cal);
- fmt_date(buf, due, 0);
+ webcit_fmt_date(buf, due, 0);
wprintf("<td><font");
if (due < time(NULL)) {
wprintf(" color=\"#FF0000\"");
dnl AC_FUNC_VPRINTF
AC_REPLACE_FUNCS(snprintf)
+
+dnl Check for libcitadel
+AC_CHECK_HEADER(libcitadel.h,
+ [AC_CHECK_LIB(citadel, libcitadel_version_string,
+ [
+ AC_MSG_RESULT(OK)
+ LIBS="-lcitadel $LIBS"
+ ],
+ [
+ AC_MSG_ERROR(libcitadel was not found or is not usable. Please install libcitadel.)
+ ]
+ ,
+ )],
+ [
+ AC_MSG_ERROR(libcitadel.h was not found or is not usable. Please install libcitadel.)
+ ]
+)
+
+
webcit_with_calendar_service=no
dnl Checks for the libical calendaring library.
if test "x$with_libical" != xno ; then
* \param thetime time to convert to string
* \param brief do we want compact view?????
*/
-void fmt_date(char *buf, time_t thetime, int brief)
+void webcit_fmt_date(char *buf, time_t thetime, int brief)
{
struct tm tm;
struct tm today_tm;
#include "webcit.h"
#include "webserver.h"
#include "groupdav.h"
-#include "mime_parser.h"
/*
* \param maxlen Maximum size of target buffer.
* \param source Source string to be encoded.
*/
-void rfc2047encode(char *target, int maxlen, char *source)
+void webcit_rfc2047encode(char *target, int maxlen, char *source)
{
int need_to_encode = 0;
int i, len;
wprintf(" ");
}
if (!strncasecmp(buf, "time=", 5)) {
- fmt_date(now, atol(&buf[5]), 0);
+ webcit_fmt_date(now, atol(&buf[5]), 0);
wprintf("<span>");
wprintf("%s ", now);
wprintf("</span>");
wprintf("%s ", &buf[5]);
}
if (!strncasecmp(buf, "time=", 5)) {
- fmt_date(now, atol(&buf[5]), 0);
+ webcit_fmt_date(now, atol(&buf[5]), 0);
wprintf("%s ", now);
}
}
wprintf("</td>");
wprintf("<td width=%d%%>", DATE_PLUS_BUTTONS_WIDTH_PCT);
- fmt_date(datebuf, WC->summ[num].date, 1); /* brief */
+ webcit_fmt_date(datebuf, WC->summ[num].date, 1); /* brief */
escputs(datebuf);
wprintf("</td>");
encoded_length = ((att->length * 150) / 100);
encoded = malloc(encoded_length);
if (encoded == NULL) break;
- encoded_strlen = CtdlEncodeBase64(&encoded, att->data, att->length, &encoded_length, 1);
+ encoded_strlen = CtdlEncodeBase64(encoded, att->data, att->length, 1);
serv_printf("--%s", boundary);
serv_printf("Content-type: %s", att->content_type);
_("Automatically cancelled because you have already "
"saved this message."));
} else {
- rfc2047encode(encoded_subject, sizeof encoded_subject, bstr("subject"));
+ webcit_rfc2047encode(encoded_subject, sizeof encoded_subject, bstr("subject"));
sprintf(buf, "ENT0 1|%s|%d|4|%s|%s||%s|%s|%s|%s",
bstr("recp"),
is_anonymous,
wprintf("<img src=\"static/newmess3_24x.gif\" class=\"imgedit\">");
wprintf(" "); /** header bar */
- fmt_date(buf, now, 0);
+ webcit_fmt_date(buf, now, 0);
wprintf("%s", buf);
wprintf("\n"); /** header bar */
+++ /dev/null
-/*
- * $Id$
- */
-/**
- * \defgroup MIME This is the MIME parser for Citadel.
- *
- * Copyright (c) 1998-2005 by Art Cancro
- * This code is distributed under the terms of the GNU General Public License.
- * \ingroup WebcitHttpServer
- */
-/*@{*/
-#include "webcit.h"
-#include "webserver.h"
-#include "mime_parser.h"
-
-void extract_key(char *target, char *source, char *key)
-{
- char *ptr;
- char looking_for[256];
- int double_quotes = 0;
-
- snprintf(looking_for, sizeof looking_for, "%s=", key);
-
- ptr = bmstrcasestr(source, looking_for);
- if (ptr == NULL) {
- strcpy(target, "");
- return;
- }
- strcpy(target, (ptr + strlen(looking_for)));
-
- for (ptr=target; (*ptr != 0); ++ptr) {
-
- /* A semicolon means we've hit the end of the key, unless we're inside double quotes */
- if ( (double_quotes != 1) && (*ptr == ';')) {
- *ptr = 0;
- }
-
- /* if we find double quotes, we've got a great set of string boundaries */
- if (*ptr == '\"') {
- ++double_quotes;
- if (double_quotes == 1) {
- strcpy(ptr, ptr+1);
- }
- else {
- *ptr = 0;
- }
- }
- }
-}
-
-
-/*
- * For non-multipart messages, we need to generate a quickie partnum of "1"
- * to return to callback functions. Some callbacks demand it.
- */
-char *fixed_partnum(char *supplied_partnum) {
- if (supplied_partnum == NULL) return "1";
- if (strlen(supplied_partnum)==0) return "1";
- return supplied_partnum;
-}
-
-
-
-/*
- * Given a message or message-part body and a length, handle any necessary
- * decoding and pass the request up the stack.
- */
-void mime_decode(char *partnum,
- char *part_start, size_t length,
- char *content_type, char *charset, char *encoding,
- char *disposition,
- 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,
- void *cbuserdata),
- void (*PreMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void (*PostMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void *userdata,
- int dont_decode
-)
-{
-
- char *decoded;
- size_t bytes_decoded = 0;
-
- /* Some encodings aren't really encodings */
- if (!strcasecmp(encoding, "7bit"))
- strcpy(encoding, "");
- if (!strcasecmp(encoding, "8bit"))
- strcpy(encoding, "");
- if (!strcasecmp(encoding, "binary"))
- strcpy(encoding, "");
-
- /* If this part is not encoded, send as-is */
- if ( (strlen(encoding) == 0) || (dont_decode)) {
- if (CallBack != NULL) {
- CallBack(name, filename, fixed_partnum(partnum),
- disposition, part_start,
- content_type, charset, length, encoding, userdata);
- }
- return;
- }
-
- /* Fail silently if we hit an unknown encoding. */
- if ((strcasecmp(encoding, "base64"))
- && (strcasecmp(encoding, "quoted-printable"))) {
- return;
- }
-
- /*
- * Allocate a buffer for the decoded data. The output buffer is slightly
- * larger than the input buffer; this assumes that the decoded data
- * will never be significantly larger than the encoded data. This is a
- * safe assumption with base64, uuencode, and quoted-printable.
- */
- decoded = malloc(length + 32768);
- if (decoded == NULL) {
- return;
- }
-
- if (!strcasecmp(encoding, "base64")) {
- bytes_decoded = CtdlDecodeBase64(decoded, part_start, length);
- }
- else if (!strcasecmp(encoding, "quoted-printable")) {
- bytes_decoded = CtdlDecodeQuotedPrintable(decoded, part_start, length);
- }
-
- if (bytes_decoded > 0) if (CallBack != NULL) {
- CallBack(name, filename, fixed_partnum(partnum),
- disposition, decoded,
- content_type, charset, bytes_decoded, "binary", userdata);
- }
-
- free(decoded);
-}
-
-/*
- * Break out the components of a multipart message
- * (This function expects to be fed HEADERS + CONTENT)
- * Note: NULL can be supplied as content_end; in this case, the message is
- * considered to have ended when the parser encounters a 0x00 byte.
- */
-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,
- void *cbuserdata),
- void (*PreMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void (*PostMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void *userdata,
- int dont_decode
-)
-{
-
- char *ptr;
- char *srch = NULL;
- char *part_start, *part_end = NULL;
- char buf[SIZ];
- char *header;
- char *boundary;
- char *startary;
- size_t startary_len = 0;
- char *endary;
- char *next_boundary;
- char *content_type;
- char *charset;
- size_t content_length;
- char *encoding;
- char *disposition;
- char *name = NULL;
- char *content_type_name;
- char *content_disposition_name;
- char *filename;
- int is_multipart;
- int part_seq = 0;
- int i;
- size_t length;
- char nested_partnum[256];
- int crlf_in_use = 0;
- char *evaluate_crlf_ptr = NULL;
- int buflen = 0;
- int headerlen = 0;
-
- ptr = content_start;
- content_length = 0;
-
- boundary = malloc(SIZ);
- memset(boundary, 0, SIZ);
-
- startary = malloc(SIZ);
- memset(startary, 0, SIZ);
-
- endary = malloc(SIZ);
- memset(endary, 0, SIZ);
-
- header = malloc(SIZ);
- memset(header, 0, SIZ);
-
- content_type = malloc(SIZ);
- memset(content_type, 0, SIZ);
-
- charset = malloc(SIZ);
- memset(charset, 0, SIZ);
-
- encoding = malloc(SIZ);
- memset(encoding, 0, SIZ);
-
- content_type_name = malloc(SIZ);
- memset(content_type_name, 0, SIZ);
-
- content_disposition_name = malloc(SIZ);
- memset(content_disposition_name, 0, SIZ);
-
- filename = malloc(SIZ);
- memset(filename, 0, SIZ);
-
- disposition = malloc(SIZ);
- memset(disposition, 0, SIZ);
-
- /* If the caller didn't supply an endpointer, generate one by measure */
- if (content_end == NULL) {
- content_end = &content_start[strlen(content_start)];
- }
-
- /* Learn interesting things from the headers */
- strcpy(header, "");
- headerlen = 0;
- do {
- ptr = memreadlinelen(ptr, buf, SIZ, &buflen);
- if (ptr >= content_end) {
- goto end_parser;
- }
-
- for (i = 0; i < buflen; ++i) {
- if (isspace(buf[i])) {
- buf[i] = ' ';
- }
- }
-
- if (!isspace(buf[0])) {
- if (!strncasecmp(header, "Content-type:", 13)) {
- strcpy(content_type, &header[13]);
- striplt(content_type);
- extract_key(content_type_name, content_type, "name");
- extract_key(charset, content_type, "charset");
- extract_key(boundary, header, "boundary");
- /* Deal with weird headers */
- if (strchr(content_type, ' '))
- *(strchr(content_type, ' ')) = '\0';
- if (strchr(content_type, ';'))
- *(strchr(content_type, ';')) = '\0';
- }
- if (!strncasecmp(header, "Content-Disposition:", 20)) {
- strcpy(disposition, &header[20]);
- striplt(disposition);
- extract_key(content_disposition_name, disposition, "name");
- extract_key(filename, disposition, "filename");
- }
- if (!strncasecmp(header, "Content-length: ", 15)) {
- char clbuf[10];
- safestrncpy(clbuf, &header[15], sizeof clbuf);
- striplt(clbuf);
- content_length = (size_t) atol(clbuf);
- }
- if (!strncasecmp(header, "Content-transfer-encoding: ", 26)) {
- strcpy(encoding, &header[26]);
- striplt(encoding);
- }
- strcpy(header, "");
- headerlen = 0;
- }
- if ((headerlen + buflen + 2) < SIZ) {
- memcpy(&header[headerlen], buf, buflen);
- headerlen += buflen;
- header[headerlen] = '\0';
- }
- } while ((!IsEmptyStr(buf)) && (*ptr != 0));
-
- if (strchr(disposition, ';'))
- *(strchr(disposition, ';')) = '\0';
- striplt(disposition);
- if (strchr(content_type, ';'))
- *(strchr(content_type, ';')) = '\0';
- striplt(content_type);
-
- if (!IsEmptyStr(boundary)) {
- is_multipart = 1;
- } else {
- is_multipart = 0;
- }
-
- /* If this is a multipart message, then recursively process it */
- part_start = NULL;
- if (is_multipart) {
-
- /* Tell the client about this message's multipartedness */
- if (PreMultiPartCallBack != NULL) {
- PreMultiPartCallBack("", "", partnum, "",
- NULL, content_type, charset,
- 0, encoding, userdata);
- }
-
- /* Figure out where the boundaries are */
- snprintf(startary, SIZ, "--%s", boundary);
- snprintf(endary, SIZ, "--%s--", boundary);
- startary_len = strlen(startary);
-
- part_start = NULL;
- do {
- next_boundary = NULL;
- for (srch=ptr; srch<content_end; ++srch) {
- if (!memcmp(srch, startary, startary_len)) {
- next_boundary = srch;
- srch = content_end;
- }
- }
-
- if ( (part_start != NULL) && (next_boundary != NULL) ) {
- part_end = next_boundary;
- --part_end; /* omit the trailing LF */
- if (crlf_in_use) {
- --part_end; /* omit the trailing CR */
- }
-
- if (!IsEmptyStr(partnum)) {
- snprintf(nested_partnum,
- sizeof nested_partnum,
- "%s.%d", partnum,
- ++part_seq);
- }
- else {
- snprintf(nested_partnum,
- sizeof nested_partnum,
- "%d", ++part_seq);
- }
- the_mime_parser(nested_partnum,
- part_start, part_end,
- CallBack,
- PreMultiPartCallBack,
- PostMultiPartCallBack,
- userdata,
- dont_decode);
- }
-
- if (next_boundary != NULL) {
- /* If we pass out of scope, don't attempt to
- * read past the end boundary. */
- if (!strcmp(next_boundary, endary)) {
- ptr = content_end;
- }
- else {
- /* Set up for the next part. */
- part_start = strstr(next_boundary, "\n");
-
- /* Determine whether newlines are LF or CRLF */
- evaluate_crlf_ptr = part_start;
- --evaluate_crlf_ptr;
- if (!memcmp(evaluate_crlf_ptr, "\r\n", 2)) {
- crlf_in_use = 1;
- }
- else {
- crlf_in_use = 0;
- }
-
- /* Advance past the LF ... now we're in the next part */
- ++part_start;
- ptr = part_start;
- }
- }
- else {
- /* Invalid end of multipart. Bail out! */
- ptr = content_end;
- }
- } while ( (ptr < content_end) && (next_boundary != NULL) );
-
- if (PostMultiPartCallBack != NULL) {
- PostMultiPartCallBack("", "", partnum, "", NULL,
- content_type, charset, 0, encoding, userdata);
- }
- goto end_parser;
- }
-
- /* If it's not a multipart message, then do something with it */
- if (!is_multipart) {
- part_start = ptr;
- length = 0;
- while (ptr < content_end) {
- ++ptr;
- ++length;
- }
- part_end = content_end;
-
- /******
- * I thought there was an off-by-one error here, but there isn't.
- * This probably means that there's an off-by-one error somewhere
- * else ... or maybe only in certain messages?
- --part_end;
- --length;
- ******/
-
- /* Truncate if the header told us to */
- if ( (content_length > 0) && (length > content_length) ) {
- length = content_length;
- }
-
- /* Sometimes the "name" field is tacked on to Content-type,
- * and sometimes it's tacked on to Content-disposition. Use
- * whichever one we have.
- */
- if (strlen(content_disposition_name) > strlen(content_type_name)) {
- name = content_disposition_name;
- }
- else {
- name = content_type_name;
- }
-
- /* lprintf(CTDL_DEBUG, "mime_decode part=%s, len=%d, type=%s, charset=%s, encoding=%s\n",
- partnum, length, content_type, charset, encoding); */
-
- /* Ok, we've got a non-multipart part here, so do something with it.
- */
- mime_decode(partnum,
- part_start, length,
- content_type, charset, encoding, disposition,
- name, filename,
- CallBack, NULL, NULL,
- userdata, dont_decode
- );
-
- /*
- * Now if it's an encapsulated message/rfc822 then we have to recurse into it
- */
- if (!strcasecmp(content_type, "message/rfc822")) {
-
- if (PreMultiPartCallBack != NULL) {
- PreMultiPartCallBack("", "", partnum, "",
- NULL, content_type, charset,
- 0, encoding, userdata);
- }
- if (CallBack != NULL) {
- if (strlen(partnum) > 0) {
- snprintf(nested_partnum,
- sizeof nested_partnum,
- "%s.%d", partnum,
- ++part_seq);
- }
- else {
- snprintf(nested_partnum,
- sizeof nested_partnum,
- "%d", ++part_seq);
- }
- the_mime_parser(nested_partnum,
- part_start, part_end,
- CallBack,
- PreMultiPartCallBack,
- PostMultiPartCallBack,
- userdata,
- dont_decode
- );
- }
- if (PostMultiPartCallBack != NULL) {
- PostMultiPartCallBack("", "", partnum, "", NULL,
- content_type, charset, 0, encoding, userdata);
- }
-
-
- }
-
- }
-
-end_parser: /* free the buffers! end the oppression!! */
- free(boundary);
- free(startary);
- free(endary);
- free(header);
- free(content_type);
- free(charset);
- free(encoding);
- free(content_type_name);
- free(content_disposition_name);
- free(filename);
- free(disposition);
-}
-
-
-
-/*
- * Entry point for the MIME parser.
- * (This function expects to be fed HEADERS + CONTENT)
- * Note: NULL can be supplied as content_end; in this case, the message is
- * considered to have ended when the parser encounters a 0x00 byte.
- */
-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,
- void *cbuserdata),
-
- void (*PreMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
-
- void (*PostMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
-
- void *userdata,
- int dont_decode
-)
-{
-
- the_mime_parser("", content_start, content_end,
- CallBack,
- PreMultiPartCallBack,
- PostMultiPartCallBack,
- userdata, dont_decode);
-}
+++ /dev/null
-/*
- * $Id$
- *
- */
-
-/*
- * Here's a bunch of stupid magic to make the MIME parser portable between
- * Citadel and WebCit.
- */
-#ifndef SIZ
-#define SIZ 4096
-#endif
-
-
-/*
- * Declarations for functions in the parser
- */
-
-void extract_key(char *target, char *source, char *key);
-
-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,
- void *cbuserdata),
- void (*PreMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void (*PostMultiPartCallBack)
- (char *cbname,
- char *cbfilename,
- char *cbpartnum,
- char *cbdisp,
- void *cbcontent,
- char *cbtype,
- char *cbcharset,
- size_t cblength,
- char *cbencoding,
- void *cbuserdata),
- void *userdata,
- int dont_decode
- );
char buf[256];
char fname[256];
char rule[2048];
- char *encoded_rule;
+ char encoded_rule[4096];
char my_addresses[4096];
- size_t encoded_len;
- encoded_len = 4096;
- encoded_rule = (char*) malloc (encoded_len);
/* Enumerate my email addresses in case they are needed for a vacation rule */
my_addresses[0] = 0;
serv_puts("GVEA");
redirect, automsg, final
);
- CtdlEncodeBase64(&encoded_rule, rule, strlen(rule)+1, &encoded_len, 0);
+ CtdlEncodeBase64(encoded_rule, rule, strlen(rule)+1, 0);
serv_printf("# WEBCIT_RULE|%d|%s|", i, encoded_rule);
output_sieve_rule(hfield, compare, htext, sizecomp, sizeval,
action, fileinto, redirect, automsg, final, my_addresses);
serv_puts("stop;");
serv_puts("000");
- free(encoded_rule);
}
wprintf("</td><td>");
if (submitted > 0) {
- fmt_date(buf, submitted, 1);
+ webcit_fmt_date(buf, submitted, 1);
wprintf("%s", buf);
}
else {
wprintf("</td><td>");
if (last_attempt > 0) {
- fmt_date(buf, last_attempt, 1);
+ webcit_fmt_date(buf, last_attempt, 1);
wprintf("%s", buf);
}
else {
+++ /dev/null
-/*
- * $Id$
- */
-/**
- * \defgroup MiscRout Miscellaneous routines
- * \ingroup tools
- */
-
-/*@{*/
-#include "webcit.h"
-#include "webserver.h"
-
-
-typedef unsigned char byte; /**< byte data type */
-
-#define FALSE 0 /**< no. */
-#define TRUE 1 /**< yes. */
-
-static byte dtable[256]; /**< base64 encode / decode table */
-
-/**
- * \brief sanitize strncopy.
- * \param dest destination string
- * \param src source string
- * \param n length of source to copy
- * \return result string
- */
-char *safestrncpy(char *dest, const char *src, size_t n)
-{
- if (dest == NULL || src == NULL) {
- abort();
- }
- strncpy(dest, src, n);
- dest[n - 1] = 0;
- return dest;
-}
-
-
-
-/**
- * \brief discover number of parameters/tokens in a string
- * \param source string to inspect
- * \param tok seperation token
- * \return number of tokenized parts found
- */
-int num_tokens(char *source, char tok)
-{
- int count = 1;
- char *ptr = source;
-
- if (source == NULL) {
- return (0);
- }
-
- while (*ptr != '\0') {
- if (*ptr++ == tok) {
- ++count;
- }
- }
-
- return (count);
-}
-
-/*
- * extract_token() - a string tokenizer
- * returns -1 if not found, or length of token.
- */
-long extract_token(char *dest, const char *source, int parmnum, char separator, int maxlen)
-{
- const char *s; //* source * /
- int len = 0; //* running total length of extracted string * /
- int current_token = 0; //* token currently being processed * /
-
- s = source;
-
- if (dest == NULL) {
- return(-1);
- }
-
-// cit_backtrace();
-// lprintf (CTDL_DEBUG, "test >: n: %d sep: %c source: %s \n willi \n", parmnum, separator, source);
- dest[0] = 0;
-
- if (s == NULL) {
- return(-1);
- }
-
- maxlen--;
-
- while (*s) {
- if (*s == separator) {
- ++current_token;
- }
- if ( (current_token == parmnum) &&
- (*s != separator) &&
- (len < maxlen) ) {
- dest[len] = *s;
- ++len;
- }
- else if ((current_token > parmnum) || (len >= maxlen)) {
- break;
- }
- ++s;
- }
-
- dest[len] = '\0';
- if (current_token < parmnum) {
-// lprintf (CTDL_DEBUG,"test <!: %s\n", dest);
- return(-1);
- }
-// lprintf (CTDL_DEBUG,"test <: %d; %s\n", len, dest);
- return(len);
-}
-//*/
-
-
-/**
- * \brief a tokenizer that kills, maims, and destroys
- * \param source the string to process
- * \param parmnum which token to kill
- * \param separator the tokenizer string
- */
-void remove_token(char *source, int parmnum, char separator)
-{
- int i;
- int len, slen;
- int curr_parm;
- int start, end;
-
- len = 0;
- curr_parm = 0;
- start = (-1);
- end = (-1);
-
- slen = strlen(source);
- if (slen == 0) {
- return;
- }
-
- for (i = 0;
- ( (i < slen) && (end == -1) );
- ++i) {
- if ((start < 0) && (curr_parm == parmnum)) {
- start = i;
- }
-
- if ((end < 0) && (curr_parm == (parmnum + 1))) {
- end = i;
- }
-
- if (source[i] == separator) {
- ++curr_parm;
- }
- }
-
- if (end < 0)
- end = slen;
-
- memmove(&source[start], &source[end], slen - end + 1);
-}
-
-
-
-
-/**
- * \brief extract an int parm w/o supplying a buffer
- * \param source the string to locate the int in
- * \param parmnum the n'th token to grab the int from
- * \return the integer
- */
-int extract_int(const char *source, int parmnum)
-{
- char buf[32];
-
- extract_token(buf, source, parmnum, '|', sizeof buf);
- return(atoi(buf));
-}
-
-/**
- * \brief extract an long parm w/o supplying a buffer
- * \param source string to examine
- * \param parmnum n'th token to search long in
- * \return the found long value
- */
-long extract_long(const char *source, int parmnum)
-{
- char buf[32];
-
- extract_token(buf, source, parmnum, '|', sizeof buf);
- return(atol(buf));
-}
-
-
-
-
-
-
-/**
- * \brief check for the presence of a character within a string (returns count)
- * \param st the string to examine
- * \param ch the char to search
- * \return the position inside of st
- */
-int haschar(const char *st,char ch)
-{
- const char *ptr;
- int b;
- b = 0;
- ptr = st;
- while (!IsEmptyStr(ptr))
- if (*ptr == ch)
- ++b;
- return (b);
-}
-
-
-/**
- * \brief Utility function to "readline" from memory
- * \param start Location in memory from which we are reading.
- * \param buf the buffer to place the string in.
- * \param maxlen Size of string buffer
- * \return Pointer to the source memory right after we stopped reading.
- */
-char *memreadline(char *start, char *buf, int maxlen)
-{
- char ch;
- char *ptr;
- int len = 0; /**< tally our own length to avoid strlen() delays */
-
- ptr = start;
- while (1) {
- ch = *ptr++;
- if ((len + 1 < (maxlen)) && (ch != 13) && (ch != 10)) {
- buf[len++] = ch;
- }
- if ((ch == 10) || (ch == 0)) {
- buf[len] = 0;
- return ptr;
- }
- }
-}
-
-
-/**
- * \brief Utility function to "readline" from memory
- * \param start Location in memory from which we are reading.
- * \param buf the buffer to place the string in.
- * \param maxlen Size of string buffer
- * \param retlen the length of the returned string
- * \return Pointer to the source memory right after we stopped reading.
- */
-char *memreadlinelen(char *start, char *buf, int maxlen, int *retlen)
-{
- char ch;
- char *ptr;
- int len = 0; /**< tally our own length to avoid strlen() delays */
-
- ptr = start;
-
- while (1) {
- ch = *ptr++;
- if ((len + 1 < (maxlen)) && (ch != 13) && (ch != 10)) {
- buf[len++] = ch;
- }
- if ((ch == 10) || (ch == 0)) {
- buf[len] = 0;
- *retlen = len;
- return ptr;
- }
- }
-}
-
-
-
-/**
- * \brief searches for a paternn within asearch string
- * \param search the string to search
- * \param patn the pattern to find in string
- * \returns position in string
- */
-int pattern2(char *search, char *patn)
-{
- int a;
- int len, plen;
- len = strlen (search);
- plen = strlen (patn);
- for (a = 0; a < len; ++a) {
- if (!strncasecmp(&search[a], patn, plen))
- return (a);
- }
- return (-1);
-}
-
-
-/**
- * \brief Strip leading and trailing spaces from a string; with premeasured and adjusted length.
- * \param buf the string to modify
- * \param len length of the string.
- */
-void stripltlen(char *buf, int *len)
-{
- int delta = 0;
- if (*len == 0) return;
- while ((*len > delta) && (isspace(buf[delta]))){
- delta ++;
- }
- memmove (buf, &buf[delta], *len - delta + 1);
- (*len) -=delta;
-
- if (*len == 0) return;
- while (isspace(buf[(*len) - 1])){
- buf[--(*len)] = '\0';
- }
-}
-
-/**
- * \brief Strip leading and trailing spaces from a string
- * \param buf the string to modify
- */
-void striplt(char *buf)
-{
- int len;
- len = strlen(buf);
- stripltlen(buf, &len);
-}
-
-
-/**
- * \brief Determine whether the specified message number is contained within the
- * specified set.
- *
- * \param mset Message set string
- * \param msgnum Message number we are looking for
- *
- * \return Nonzero if the specified message number is in the specified message set string.
- */
-int is_msg_in_mset(char *mset, long msgnum) {
- int num_sets;
- int s;
- char setstr[SIZ], lostr[SIZ], histr[SIZ]; /* was 1024 */
- long lo, hi;
-
- /*
- * Now set it for all specified messages.
- */
- num_sets = num_tokens(mset, ',');
- for (s=0; s<num_sets; ++s) {
- extract_token(setstr, mset, s, ',', sizeof setstr);
-
- extract_token(lostr, setstr, 0, ':', sizeof lostr);
- if (num_tokens(setstr, ':') >= 2) {
- extract_token(histr, setstr, 1, ':', sizeof histr);
- if (!strcmp(histr, "*")) {
- snprintf(histr, sizeof histr, "%ld", LONG_MAX);
- }
- }
- else {
- strcpy(histr, lostr);
- }
- lo = atol(lostr);
- hi = atol(histr);
-
- if ((msgnum >= lo) && (msgnum <= hi)) return(1);
- }
-
- return(0);
-}
-
-
-
-/**
- * \brief Strip a boundarized substring out of a string
- * (for example, remove
- * parentheses and anything inside them).
- *
- * This improved version can strip out *multiple* boundarized substrings.
- * \param str the string to process
- * \param leftboundary the boundary character on the left side of the target string
- * \param rightboundary the boundary character on the right side of the target string
- */
-void stripout(char *str, char leftboundary, char rightboundary)
-{
- int a;
- int lb = (-1);
- int rb = (-1);
- int len = strlen(str);
-
- do {
- lb = (-1);
- rb = (-1);
-
- for (a = 0; a < len; ++a) {
- if (str[a] == leftboundary)
- lb = a;
- if (str[a] == rightboundary)
- rb = a;
- }
-
- if ((lb > 0) && (rb > lb)) {
- memmove(&str[lb - 1], &str[rb + 1], len - rb);
- len -= (rb - lb + 2);
- }
-
- } while ((lb > 0) && (rb > lb));
-
-}
-
-
-
-/**
- * \brief Replacement for sleep() that uses select() in order to avoid SIGALRM
- * \param seconds how many seconds should we sleep?
- */
-void sleeeeeeeeeep(int seconds)
-{
- struct timeval tv;
-
- tv.tv_sec = seconds;
- tv.tv_usec = 0;
- select(0, NULL, NULL, NULL, &tv);
-}
-
-
-
-/**
- * \brief encode a string into base64 to for example tunnel it through mail transport
- * CtdlDecodeBase64() and CtdlEncodeBase64() are adaptations of code by
- * John Walker, copied over from the Citadel server.
- * \param dest encrypted string
- * \param source the string to encrypt
- * \param sourcelen the length of the source data (may contain string terminators)
- * \return the length of the encoded string.
- */
-
-size_t CtdlEncodeBase64(char **pdest, const char *source, size_t sourcelen, size_t *destlen, int linebreaks)
-{
- int i, hiteof = FALSE;
- int spos = 0;
- int dpos = 0;
- int thisline = 0;
- char *dest;
-
- dest = *pdest;
-
- /** Fill dtable with character encodings. */
-
- for (i = 0; i < 26; i++) {
- dtable[i] = 'A' + i;
- dtable[26 + i] = 'a' + i;
- }
- for (i = 0; i < 10; i++) {
- dtable[52 + i] = '0' + i;
- }
- dtable[62] = '+';
- dtable[63] = '/';
-
- while (!hiteof) {
- byte igroup[3], ogroup[4];
- int c, n;
-
- igroup[0] = igroup[1] = igroup[2] = 0;
- for (n = 0; n < 3; n++) {
- if (spos >= sourcelen) {
- hiteof = TRUE;
- break;
- }
- c = source[spos++];
- igroup[n] = (byte) c;
- }
- if (n > 0) {
- ogroup[0] = dtable[igroup[0] >> 2];
- ogroup[1] =
- dtable[((igroup[0] & 3) << 4) |
- (igroup[1] >> 4)];
- ogroup[2] =
- dtable[((igroup[1] & 0xF) << 2) |
- (igroup[2] >> 6)];
- ogroup[3] = dtable[igroup[2] & 0x3F];
-
- /**
- * Replace characters in output stream with "=" pad
- * characters if fewer than three characters were
- * read from the end of the input stream.
- */
-
- if (n < 3) {
- ogroup[3] = '=';
- if (n < 2) {
- ogroup[2] = '=';
- }
- }
- for (i = 0; i < 4; i++) {
- if (dpos > *destlen)
- {
- int newlen;
- char *newbuf;
- newlen = *destlen + *destlen / 2;
- newbuf = (char*) malloc(newlen);
- memcpy(newbuf, dest, *destlen);
- *pdest = dest = newbuf;
- *destlen = newlen;
- }
- dest[dpos++] = ogroup[i];
- dest[dpos] = 0;
- }
- thisline += 4;
- if ( (linebreaks) && (thisline > 70) ) {
- if (dpos + 3 > *destlen)
- {
- int newlen;
- char *newbuf;
- newlen = *destlen + *destlen / 2;
- newbuf = (char*) malloc(newlen);
- memcpy(newbuf, dest, *destlen);
- *pdest = dest = newbuf;
- *destlen = newlen;
- }
- dest[dpos++] = '\r';
- dest[dpos++] = '\n';
- dest[dpos] = 0;
- thisline = 0;
- }
- }
- }
- if ( (linebreaks) && (thisline > 70) ) {
- if (dpos + 3 > *destlen)
- {
- int newlen;
- char *newbuf;
- newlen = *destlen + 5;
- newbuf = (char*) malloc(newlen);
- memcpy(newbuf, dest, *destlen);
- *pdest = dest = newbuf;
- *destlen = newlen;
- }
- dest[dpos++] = '\r';
- dest[dpos++] = '\n';
- dest[dpos] = 0;
- thisline = 0;
- }
- return dpos;
-}
-
-
-/**
- * \brief Convert base64-encoded to binary.
- * It will stop after reading 'length' bytes.
- *
- * \param dest The destination buffer
- * \param source The base64 data to be decoded.
- * \param length The number of bytes to decode.
- * \return The actual length of the decoded data.
- */
-int CtdlDecodeBase64(char *dest, const char *source, size_t length)
-{
- int i, c;
- int dpos = 0;
- int spos = 0;
-
- for (i = 0; i < 255; i++) {
- dtable[i] = 0x80;
- }
- for (i = 'A'; i <= 'Z'; i++) {
- dtable[i] = 0 + (i - 'A');
- }
- for (i = 'a'; i <= 'z'; i++) {
- dtable[i] = 26 + (i - 'a');
- }
- for (i = '0'; i <= '9'; i++) {
- dtable[i] = 52 + (i - '0');
- }
- dtable['+'] = 62;
- dtable['/'] = 63;
- dtable['='] = 0;
-
- /**CONSTANTCONDITION*/ while (TRUE) {
- byte a[4], b[4], o[3];
-
- for (i = 0; i < 4; i++) {
- if (spos >= length) {
- return (dpos);
- }
- c = source[spos++];
-
- if (c == 0) {
- if (i > 0) {
- return (dpos);
- }
- return (dpos);
- }
- if (dtable[c] & 0x80) {
- /** Ignoring errors: discard invalid character */
- i--;
- continue;
- }
- a[i] = (byte) c;
- b[i] = (byte) dtable[c];
- }
- o[0] = (b[0] << 2) | (b[1] >> 4);
- o[1] = (b[1] << 4) | (b[2] >> 2);
- o[2] = (b[2] << 6) | b[3];
- i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
- if (i >= 1)
- dest[dpos++] = o[0];
- if (i >= 2)
- dest[dpos++] = o[1];
- if (i >= 3)
- dest[dpos++] = o[2];
- dest[dpos] = 0;
- if (i < 3) {
- return (dpos);
- }
- }
-}
-
-
-
-/**
- * \brief Generate a new, globally unique UID parameter for a calendar etc. object
- *
- * \param buf String buffer into which our newly created UUID should be placed
- */
-void generate_uuid(char *buf) {
- static int seq = 0;
-
- sprintf(buf, "%s-%lx-%lx-%x",
- serv_info.serv_nodename,
- (long)time(NULL),
- (long)getpid(),
- (seq++)
- );
-}
-
-
-/*
- * Convert "quoted-printable" to binary. Returns number of bytes decoded.
- * according to RFC2045 section 6.7
- */
-int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen) {
- unsigned int ch;
- int decoded_length = 0;
- int pos = 0;
-
- while (pos < sourcelen)
- {
- if (!strncmp(&encoded[pos], "=\r\n", 3))
- {
- pos += 3;
- }
- else if (!strncmp(&encoded[pos], "=\n", 2))
- {
- pos += 2;
- }
- else if (encoded[pos] == '=')
- {
- ch = 0;
- sscanf(&encoded[pos+1], "%02x", &ch);
- pos += 3;
- decoded[decoded_length++] = ch;
- }
- else
- {
- decoded[decoded_length++] = encoded[pos];
- pos += 1;
- }
- }
- decoded[decoded_length] = 0;
- return(decoded_length);
-}
-
-
-/**
- * \brief Local replacement for controversial C library function that generates
- * names for temporary files. Included to shut up compiler warnings.
- * \todo return a fd to the file instead of the name for security reasons
- * \param name the created filename
- * \param len the length of the filename
- */
-void CtdlMakeTempFileName(char *name, int len) {
- int i = 0;
-
- while (i++, i < 100) {
- snprintf(name, len, "/tmp/ctdl.%04x.%04x",
- getpid(),
- rand()
- );
- if (!access(name, F_OK)) {
- return;
- }
- }
-}
-
-
-
-/*
- * \brief case-insensitive substring search
- *
- * This uses the Boyer-Moore search algorithm and is therefore quite fast.
- * The code is roughly based on the strstr() replacement from 'tin' written
- * by Urs Jannsen.
- *
- * \param text String to be searched
- * \param pattern String to search for
- */
-char *bmstrcasestr(char *text, char *pattern) {
-
- register unsigned char *p, *t;
- register int i, j, *delta;
- register size_t p1;
- int deltaspace[256];
- size_t textlen;
- size_t patlen;
-
- textlen = strlen (text);
- patlen = strlen (pattern);
-
- /* algorithm fails if pattern is empty */
- if ((p1 = patlen) == 0)
- return (text);
-
- /* code below fails (whenever i is unsigned) if pattern too long */
- if (p1 > textlen)
- return (NULL);
-
- /* set up deltas */
- delta = deltaspace;
- for (i = 0; i <= 255; i++)
- delta[i] = p1;
- for (p = (unsigned char *) pattern, i = p1; --i > 0;)
- delta[tolower(*p++)] = i;
-
- /*
- * From now on, we want patlen - 1.
- * In the loop below, p points to the end of the pattern,
- * t points to the end of the text to be tested against the
- * pattern, and i counts the amount of text remaining, not
- * including the part to be tested.
- */
- p1--;
- p = (unsigned char *) pattern + p1;
- t = (unsigned char *) text + p1;
- i = textlen - patlen;
- while(1) {
- if (tolower(p[0]) == tolower(t[0])) {
- if (strncasecmp ((const char *)(p - p1), (const char *)(t - p1), p1) == 0) {
- return ((char *)t - p1);
- }
- }
- j = delta[tolower(t[0])];
- if (i < j)
- break;
- i -= j;
- t += j;
- }
- return (NULL);
-}
-
-
-
-
-
-/*@}*/
#include "webcit.h"
#include "groupdav.h"
#include "webserver.h"
-#include "mime_parser.h"
#include <stdio.h>
#include <stdarg.h>
}
}
+/**
+ * \brief Replacement for sleep() that uses select() in order to avoid SIGALRM
+ * \param seconds how many seconds should we sleep?
+ */
+void sleeeeeeeeeep(int seconds)
+{
+ struct timeval tv;
+
+ tv.tv_sec = seconds;
+ tv.tv_usec = 0;
+ select(0, NULL, NULL, NULL, &tv);
+}
+
/*@}*/
#include <signal.h>
#include <sys/utsname.h>
+#include <libcitadel.h>
+
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif
MAX_SEMAPHORES
};
+#ifndef num_parms
#define num_parms(source) num_tokens(source, '|')
+#endif
/* Per-session data */
#define WC ((struct wcsession *)pthread_getspecific(MyConKey))
void msgesc(char *target, char *strbuf);
void msgescputs(char *strbuf);
void msgescputs1(char *strbuf);
-int extract_int(const char *source, int parmnum);
-long extract_long(const char *source, int parmnum);
void stripout(char *str, char leftboundary, char rightboundary);
void dump_vars(void);
void embed_main_menu(void);
void serv_read(char *buf, int bytes);
-int haschar(const char *, char);
void readloop(char *oper);
void read_message(long msgnum, int printable_view, char *section);
void embed_message(char *msgnum_as_string);
void worker_entry(void);
void session_loop(struct httprequest *);
size_t wc_strftime(char *s, size_t max, const char *format, const struct tm *tm);
-void fmt_date(char *buf, time_t thetime, int brief);
void fmt_time(char *buf, time_t thetime);
void httpdate(char *buf, time_t thetime);
time_t httpdate_to_timestamp(char *buf);
int lingering_close(int fd);
char *memreadline(char *start, char *buf, int maxlen);
char *memreadlinelen(char *start, char *buf, int maxlen, int *retlen);
-int num_tokens (char *source, char tok);
long extract_token(char *dest, const char *source, int parmnum, char separator, int maxlen);
void remove_token(char *source, int parmnum, char separator);
char *load_mimepart(long msgnum, char *partnum);
void free_calendar_buffer(void);
void calendar_summary_view(void);
int load_msg_ptrs(char *servcmd, int with_headers);
-size_t CtdlEncodeBase64(char **dest, const char *source, size_t sourcelen, size_t *destlen, int linebreaks);
-int CtdlDecodeBase64(char *dest, const char *source, size_t length);
-int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen);
void free_attachments(struct wcsession *sess);
void free_march_list(struct wcsession *wcf);
void set_room_policy(void);
void end_tab(int tabnum, int num_tabs);
void str_wiki_index(char *s);
void display_wiki_page(void);
-char *bmstrcasestr(char *text, char *pattern);
int get_time_format_cached (void);
int xtoi(char *in, size_t len);
+void webcit_fmt_date(char *buf, time_t thetime, int brief);
#ifdef HAVE_ICONV
iconv_t ctdl_iconv_open(const char *tocode, const char *fromcode);