* waiting on the specified port for incoming HTTP connections. When a
* connection is established, it calls context_loop() from context_loop.c.
*
- * Copyright (c) 1996-2008 by the citadel.org developers.
+ * Copyright (c) 1996-2009 by the citadel.org developers.
* This program is released under the terms of the GNU General Public License v3.
*
*/
* 0 Request timed out.
* -1 Connection is broken, or other error.
*/
-int client_read_to(int *sock, StrBuf *Target, StrBuf *Buf, int bytes, int timeout)
+int client_read_to(int *sock, StrBuf *Target, StrBuf *Buf, const char **Pos, int bytes, int timeout)
{
const char *Error;
int retval = 0;
#ifdef HAVE_OPENSSL
if (is_https) {
+ long bufremain = StrLength(Buf) - (*Pos - ChrPtr(Buf));
+ StrBufAppendBufPlain(Target, *Pos, bufremain, 0);
+ *Pos = NULL;
+ FlushStrBuf(Buf);
+
while ((StrLength(Buf) + StrLength(Target) < bytes) &&
(retval >= 0))
retval = client_read_sslbuffer(Buf, timeout);
if (retval >= 0) {
- StrBufAppendBuf(Target, Buf, 0); /// todo: Buf > bytes?
+ StrBufAppendBuf(Target, Buf, 0); /* todo: Buf > bytes? */
#ifdef HTTP_TRACING
write(2, "\033[32m", 5);
write(2, buf, bytes);
}
#endif
- if (StrLength(Buf) > 0) {//// todo: what if Buf > bytes?
- StrBufAppendBuf(Target, Buf, 0);
- }
- retval = StrBufReadBLOB(Target,
- sock,
- (StrLength(Target) > 0),
- bytes - StrLength(Target),
- &Error);
+ retval = StrBufReadBLOBBuffered(Target,
+ Buf, Pos,
+ sock,
+ 1,
+ bytes,
+ O_TERM,
+ &Error);
if (retval < 0) {
lprintf(2, "client_read() failed: %s\n",
Error);
*/
void begin_burst(void)
{
- if (WC->WBuf == NULL)
+ if (WC->WBuf == NULL) {
WC->WBuf = NewStrBufPlain(NULL, 32768);
+ }
}
*/
long end_burst(void)
{
- struct wcsession *WCC = WC;
+ wcsession *WCC = WC;
const char *ptr, *eptr;
long count;
ssize_t res;
fd_set wset;
int fdflags;
-#ifdef HAVE_ZLIB
- /* Perform gzip compression, if enabled and supported by client */
if (!DisableGzip && (WCC->gzip_ok) && CompressBuffer(WCC->WBuf))
{
hprintf("Content-encoding: gzip\r\n");
}
-#endif /* HAVE_ZLIB */
hprintf("Content-length: %d\r\n\r\n", StrLength(WCC->WBuf));
}
-
-/*
- * Read data from the client socket with default timeout.
- * (This is implemented in terms of client_read_to() and could be
- * justifiably moved out of sysdep.c)
- *
- * sock the socket fd to read from
- * buf the buffer to write to
- * bytes Number of bytes to read
- */
-int client_read(int *sock, StrBuf *Target, StrBuf *buf, int bytes)
-{
- return (client_read_to(sock, Target, buf, bytes, SLEEPING));
-}
-
-
-/*
- * Get a LF-terminated line of text from the client.
- * (This is implemented in terms of client_read() and could be
- * justifiably moved out of sysdep.c)
- *
- * sock socket fd to get client line from
- * buf buffer to write read data to
- * bufsiz how many bytes to read
- *
- * returns the number of bytes read
- */
-/////int client_getln(int *sock, char *buf, int bufsiz)
-/////{
-///// int i, retval;
-/////
-///// /* Read one character at a time.*/
-///// for (i = 0; *sock > 0; i++) {
-///// retval = client_read(sock, &buf[i], 1);
-///// if (retval < 0)
-///// return retval;
-///// if (retval != 1 || buf[i] == '\n' || i == (bufsiz-1))
-///// break;
-///// if ( (!isspace(buf[i])) && (!isprint(buf[i])) ) {
-///// /* Non printable character recieved from client */
-///// return(-1);
-///// }
-///// }
-/////
-///// /* If we got a long line, discard characters until the newline. */
-///// if (i == (bufsiz-1))
-///// while (buf[i] != '\n' && retval == 1)
-///// retval = client_read(sock, &buf[i], 1);
-/////
-///// /*
-///// * Strip any trailing non-printable characters.
-///// */
-///// buf[i] = 0;
-///// while ((i > 0) && (!isprint(buf[i - 1]))) {
-///// buf[--i] = 0;
-///// }
-///// return (retval);
-/////}
-
/*
* Shut us down the regular way.
* signum is the signal we want to forward
}
-int ClientGetLine(int *sock, StrBuf *Target, StrBuf *CLineBuf)
+int ClientGetLine(int *sock, StrBuf *Target, StrBuf *CLineBuf, const char **Pos)
{
const char *Error, *pch, *pchs;
int rlen, len, retval = 0;
+#ifdef HAVE_OPENSSL
if (is_https) {
int ntries = 0;
if (StrLength(CLineBuf) > 0) {
return -1;
}
else
- return StrBufTCP_read_buffered_line(Target,
- CLineBuf,
- sock,
- 5,
- 1,
- &Error);
+#endif
+ return StrBufTCP_read_buffered_line_fast(Target,
+ CLineBuf,
+ Pos,
+ sock,
+ 5,
+ 1,
+ &Error);
}
*/
pid_t current_child;
void graceful_shutdown(int signum) {
-// kill(current_child, signum);
char wd[SIZ];
FILE *FD;
int fd;
exit(errno);
}
- else if (current_child == 0) { // child process
-// signal(SIGTERM, graceful_shutdown);
+ else if (current_child == 0) { /* child process */
signal(SIGHUP, graceful_shutdown);
return; /* continue starting webcit. */
}
-
- else { // watcher process
-// signal(SIGTERM, SIG_IGN);
-// signal(SIGHUP, SIG_IGN);
+ else { /* watcher process */
if (pid_file) {
fp = fopen(pid_file, "w");
if (fp != NULL) {
pthread_attr_destroy(&attr);
}
-//#define DBG_PRINNT_HOOKS_AT_START
+/* #define DBG_PRINNT_HOOKS_AT_START */
#ifdef DBG_PRINNT_HOOKS_AT_START
const char foobuf[32];
const char *nix(void *vptr) {snprintf(foobuf, 32, "%0x", (long) vptr); return foobuf;}
#endif
+extern int dbg_analyze_msg;
+extern int dbg_bactrace_template_errors;
+extern int DumpTemplateI18NStrings;
+extern StrBuf *I18nDump;
void InitTemplateCache(void);
extern int LoadTemplates;
extern void LoadZoneFiles(void);
char *mo = NULL;
#endif /* ENABLE_NLS */
char uds_listen_path[PATH_MAX]; /* listen on a unix domain socket? */
+ const char *I18nDumpFile = NULL;
+
+ WildFireInitBacktrace(argv[0], 2);
HandlerHash = NewHash(1, NULL);
PreferenceHooks = NewHash(1, NULL);
Conditionals = NewHash(1, NULL);
MsgHeaderHandler = NewHash(1, NULL);
MimeRenderHandler = NewHash(1, NULL);
+ SortHash = NewHash(1, NULL);
LoadZoneFiles();
/* Parse command line */
#ifdef HAVE_OPENSSL
- while ((a = getopt(argc, argv, "h:i:p:t:T:x:dD:cfsZ")) != EOF)
+ while ((a = getopt(argc, argv, "h:i:p:t:T:x:dD:G:cfsZ")) != EOF)
#else
- while ((a = getopt(argc, argv, "h:i:p:t:T:x:dD:cfZ")) != EOF)
+ while ((a = getopt(argc, argv, "h:i:p:t:T:x:dD:G:cfZ")) != EOF)
#endif
switch (a) {
case 'h':
break;
case 'T':
LoadTemplates = atoi(optarg);
+ dbg_analyze_msg = (LoadTemplates && (1<<1)) != 0;
+ dbg_bactrace_template_errors = (LoadTemplates && (1<<2)) != 0;
break;
case 'Z':
DisableGzip = 1;
case 's':
is_https = 1;
break;
+ case 'G':
+ DumpTemplateI18NStrings = 1;
+ I18nDump = NewStrBufPlain(HKEY("int templatestrings(void)\n{\n"));
+ I18nDumpFile = optarg;
+ break;
default:
fprintf(stderr, "usage: webcit "
"[-i ip_addr] [-p http_port] "
"[-t tracefile] [-c] [-f] "
"[-T Templatedebuglevel] "
- "[-d] [-Z] "
+ "[-d] [-Z] [-G i18ndumpfile] "
#ifdef HAVE_OPENSSL
"[-s] "
#endif
}
/* daemonize, if we were asked to */
- if (running_as_daemon) {
+ if (!DumpTemplateI18NStrings && running_as_daemon) {
start_daemon(pidfile);
}
else {
-/// signal(SIGTERM, graceful_shutdown);
signal(SIGHUP, graceful_shutdown);
}
/* Tell 'em who's in da house */
lprintf(1, PACKAGE_STRING "\n");
- lprintf(1, "Copyright (C) 1996-2008 by the Citadel development team.\n"
+ lprintf(1, "Copyright (C) 1996-2009 by the Citadel development team.\n"
"This software is distributed under the terms of the "
"GNU General Public License.\n\n"
);
#ifdef ENABLE_NLS
initialize_locales();
+
locale = setlocale(LC_ALL, "");
mo = malloc(strlen(webcitdir) + 20);
free(mo);
lprintf(9, "Text domain: %s\n", textdomain("webcit"));
lprintf(9, "Text domain Charset: %s\n", bind_textdomain_codeset("webcit","UTF8"));
- preset_locale();
#endif
initialize_axdefs();
InitTemplateCache();
+ if (DumpTemplateI18NStrings) {
+ FILE *fd;
+ StrBufAppendBufPlain(I18nDump, HKEY("}\n"), 0);
+ if (StrLength(I18nDump) < 50) {
+ lprintf(1, "********************************************************************************\n");
+ lprintf(1, "* No strings found in templates! are you shure they're there? *\n");
+ lprintf(1, "********************************************************************************\n");
+ return -1;
+ }
+ fd = fopen(I18nDumpFile, "w");
+ if (fd == NULL) {
+ lprintf(1, "********************************************************************************\n");
+ lprintf(1, "* unable to open I18N dumpfile [%s] *\n", I18nDumpFile);
+ lprintf(1, "********************************************************************************\n");
+ return -1;
+ }
+ fwrite(ChrPtr(I18nDump), 1, StrLength(I18nDump), fd);
+ fclose(fd);
+ return 0;
+ }
if (!access("static.local/webcit.css", R_OK)) {
csslocal = NewStrBufPlain(HKEY("<link href=\"static.local/webcit.css\" rel=\"stylesheet\" type=\"text/css\">"));
/* Tell libical to return an error instead of aborting if it sees badly formed iCalendar data. */
icalerror_errors_are_fatal = 0;
+ /* Use our own prefix on tzid's generated from system tzdata */
+ icaltimezone_set_tzid_prefix("/citadel.org/");
+
/*
* Set up a place to put thread-specific data.
* We only need a single pointer per thread - it points to the
DeleteHash(&MimeRenderHandler);
DeleteHash(&Conditionals);
DeleteHash(&MsgHeaderHandler);
+ DeleteHash(&SortHash);
#ifdef ENABLE_NLS
ShutdownLocale();
#endif
if (msock > 0) ret = select(msock+1, &tempset, NULL, NULL, &tv);
end_critical_section(S_SELECT);
if ((ret < 0) && (errno != EINTR) && (errno != EAGAIN))
- {// EINTR and EAGAIN are thrown but not of interest.
+ {/* EINTR and EAGAIN are thrown but not of interest. */
lprintf(2, "accept() failed:%d %s\n",
errno, strerror(errno));
}
else if ((ret > 0) && (msock > 0) && FD_ISSET(msock, &tempset))
- {// Successfully selected, and still not shutting down? Accept!
+ {/* Successfully selected, and still not shutting down? Accept! */
ssock = accept(msock, NULL, 0);
}
} while ((msock > 0) && (ssock < 0) && (time_to_die == 0));
if ((msock == -1)||(time_to_die))
- {// ok, we're going down.
+ {/* ok, we're going down. */
int shutdown = 0;
/* the first to come here will have to do the cleanup.
}
end_critical_section(S_SHUTDOWN);
if (shutdown == 1)
- {// we're the one to cleanup the mess.
+ {/* we're the one to cleanup the mess. */
lprintf(2, "I'm master shutdown: tagging sessions to be killed.\n");
shutdown_sessions();
lprintf(2, "master shutdown: waiting for others\n");
- sleeeeeeeeeep(1); // wait so some others might finish...
+ sleeeeeeeeeep(1); /* wait so some others might finish... */
lprintf(2, "master shutdown: cleaning up sessions\n");
do_housekeeping();
lprintf(2, "master shutdown: cleaning up libical\n");
if (ssock > 0) close (ssock);
lprintf(2, "inbetween.");
pthread_exit(NULL);
- } else { // Got it? do some real work!
+ } else { /* Got it? do some real work! */
/* Set the SO_REUSEADDR socket option */
i = 1;
setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR,