* 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-2009 by the citadel.org developers.
+ * Copyright (c) 1996-2010 by the citadel.org developers.
* This program is released under the terms of the GNU General Public License v3.
*
*/
int home_specified = 0; /* did the user specify a homedir? */
int time_to_die = 0; /* Nonzero if server is shutting down */
int DisableGzip = 0;
-extern void *context_loop(int*);
+extern void *context_loop(ParsedHttpHdrs *Hdr);
extern void *housekeeping_loop(void);
extern pthread_mutex_t SessionListMutex;
extern pthread_key_t MyConKey;
extern int ig_tcp_server(char *ip_addr, int port_number, int queue_len);
extern int ig_uds_server(char *sockpath, int queue_len);
+extern void drop_root(uid_t UID);
char ctdl_key_dir[PATH_MAX]=SSL_DIR;
char file_crpt_file_key[PATH_MAX]="";
*/
pid_t current_child;
void graceful_shutdown(int signum) {
- char wd[SIZ];
FILE *FD;
int fd;
- getcwd(wd, SIZ);
- lprintf (1, "bye going down gracefull.[%d][%s]\n", signum, wd);
+
+ lprintf (1, "WebCit is being shut down on signal %d.\n", signum);
fd = msock;
msock = -1;
time_to_die = 1;
pid_t child = 0;
FILE *fp;
int do_restart = 0;
+ int rv;
+ FILE *rvfp = NULL;
current_child = 0;
* We don't just call close() because we don't want these fd's
* to be reused for other files.
*/
- chdir("/");
+ rv = chdir("/");
signal(SIGHUP, SIG_IGN);
signal(SIGINT, SIG_IGN);
setsid();
umask(0);
- freopen("/dev/null", "r", stdin);
- freopen("/dev/null", "w", stdout);
- freopen("/dev/null", "w", stderr);
+ rvfp = freopen("/dev/null", "r", stdin);
+ rvfp = freopen("/dev/null", "w", stdout);
+ rvfp = freopen("/dev/null", "w", stderr);
signal(SIGTERM, graceful_shutdown_watcher);
signal(SIGHUP, graceful_shutdown_watcher);
pthread_attr_t attr; /* Thread attributes */
int ret;
- lprintf(3, "Creating a new thread\n");
+ lprintf(3, "Creating a new thread. Pool size is now %d\n", ++num_threads);
/* set attributes for the new thread */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
/*
- * Our per-thread stacks need to be bigger than the default size, otherwise
- * the MIME parser crashes on FreeBSD, and the IMAP service crashes on
- * 64-bit Linux.
+ * Our per-thread stacks need to be bigger than the default size,
+ * otherwise the MIME parser crashes on FreeBSD.
*/
if ((ret = pthread_attr_setstacksize(&attr, 1024 * 1024))) {
lprintf(1, "pthread_attr_setstacksize: %s\n",
extern HashList *HandlerHash;
+
void
webcit_calc_dirs_n_files(int relh, const char *basedir, int home, char *webcitdir, char *relhome)
{
COMPUTE_DIRECTORY(static_icon_dir);
basedir=WWWDIR "/static.local";
COMPUTE_DIRECTORY(static_local_dir);
+ StripSlashes(static_dir, 1);
+ StripSlashes(static_icon_dir, 1);
+ StripSlashes(static_local_dir, 1);
snprintf(file_crpt_file_key,
sizeof file_crpt_file_key,
*/
int main(int argc, char **argv)
{
+ uid_t UID = -1;
+ size_t basesize = 2; /* how big should strbufs be on creation? */
pthread_t SessThread; /* Thread descriptor */
pthread_attr_t attr; /* Thread attributes */
int a, i; /* General-purpose variables */
char webcitdir[PATH_MAX] = DATADIR;
char *pidfile = NULL;
char *hdir;
- const char *basedir;
-#ifdef ENABLE_NLS
- char *locale = NULL;
- char *mo = NULL;
-#endif /* ENABLE_NLS */
+ const char *basedir = NULL;
char uds_listen_path[PATH_MAX]; /* listen on a unix domain socket? */
const char *I18nDumpFile = NULL;
+ FILE *rvfp = NULL;
+ int rv = 0;
WildFireInitBacktrace(argv[0], 2);
/* Parse command line */
#ifdef HAVE_OPENSSL
- while ((a = getopt(argc, argv, "h:i:p:t:T:x:dD:G:cfsZ")) != EOF)
+ while ((a = getopt(argc, argv, "u:h:i:p:t:T:B:x:dD:G:cfsS:Z")) != EOF)
#else
- while ((a = getopt(argc, argv, "h:i:p:t:T:x:dD:G:cfZ")) != EOF)
+ while ((a = getopt(argc, argv, "u:h:i:p:t:T:B:x:dD:G:cfZ")) != EOF)
#endif
switch (a) {
+ case 'u':
+ UID = atol(optarg);
+ break;
case 'h':
hdir = strdup(optarg);
relh=hdir[0]!='/';
- if (!relh) safestrncpy(webcitdir, hdir,
- sizeof webcitdir);
- else
- safestrncpy(relhome, relhome,
- sizeof relhome);
+ if (!relh) {
+ safestrncpy(webcitdir, hdir, sizeof webcitdir);
+ }
+ else {
+ safestrncpy(relhome, relhome, sizeof relhome);
+ }
/* free(hdir); TODO: SHOULD WE DO THIS? */
home_specified = 1;
home=1;
pidfile = strdup(optarg);
running_as_daemon = 1;
break;
+ case 'B': /* Basesize */
+ basesize = atoi(optarg);
+ if (basesize > 2)
+ StartLibCitadel(basesize);
+ break;
case 'i':
safestrncpy(ip_addr, optarg, sizeof ip_addr);
break;
break;
case 't':
safestrncpy(tracefile, optarg, sizeof tracefile);
- freopen(tracefile, "w", stdout);
- freopen(tracefile, "w", stderr);
- freopen(tracefile, "r", stdin);
+ rvfp = freopen(tracefile, "w", stdout);
+ rvfp = freopen(tracefile, "w", stderr);
+ rvfp = freopen(tracefile, "r", stdin);
break;
case 'T':
LoadTemplates = atoi(optarg);
}
}
break;
+#ifdef HAVE_OPENSSL
case 's':
is_https = 1;
break;
+ case 'S':
+ is_https = 1;
+ ssl_cipher_list = strdup(optarg);
+ break;
+#endif
case 'G':
DumpTemplateI18NStrings = 1;
I18nDump = NewStrBufPlain(HKEY("int templatestrings(void)\n{\n"));
"[-T Templatedebuglevel] "
"[-d] [-Z] [-G i18ndumpfile] "
#ifdef HAVE_OPENSSL
- "[-s] "
+ "[-s] [-S cipher_suites]"
#endif
"[remotehost [remoteport]]\n");
return 1;
/* Tell 'em who's in da house */
lprintf(1, PACKAGE_STRING "\n");
- lprintf(1, "Copyright (C) 1996-2009 by the Citadel development team.\n"
+ lprintf(1, "Copyright (C) 1996-2010 by the Citadel development team.\n"
"This software is distributed under the terms of the "
"GNU General Public License.\n\n"
);
/* initialize the International Bright Young Thing */
-#ifdef ENABLE_NLS
- initialize_locales();
-
-
- locale = setlocale(LC_ALL, "");
-
- mo = malloc(strlen(webcitdir) + 20);
- lprintf(9, "Message catalog directory: %s\n", bindtextdomain("webcit", LOCALEDIR"/locale"));
- free(mo);
- lprintf(9, "Text domain: %s\n", textdomain("webcit"));
- lprintf(9, "Text domain Charset: %s\n", bind_textdomain_codeset("webcit","UTF8"));
-#endif
-
-
-
-
-
-
-
-
-
initialise_modules();
initialize_viewdefs();
lprintf(1, "********************************************************************************\n");
return -1;
}
- fwrite(ChrPtr(I18nDump), 1, StrLength(I18nDump), fd);
+ rv = fwrite(ChrPtr(I18nDump), 1, StrLength(I18nDump), fd);
fclose(fd);
return 0;
}
lprintf(2, "Attempting to bind to port %d...\n", http_port);
msock = ig_tcp_server(ip_addr, http_port, LISTEN_QUEUE_LENGTH);
}
+ if (msock < 0)
+ {
+ ShutDownWebcit();
+ return -msock;
+ }
lprintf(2, "Listening on socket %d\n", msock);
signal(SIGPIPE, SIG_IGN);
init_ssl();
}
#endif
+ drop_root(UID);
/* Start a few initial worker threads */
for (i = 0; i < (MIN_WORKER_THREADS); ++i) {
icalmemory_free_ring ();
ShutDownLibCitadel ();
shutdown_modules ();
-#ifdef ENABLE_NLS
- ShutdownLocale();
-#endif
#ifdef HAVE_OPENSSL
if (is_https) {
shutdown_ssl();
int ret;
struct timeval tv;
fd_set readset, tempset;
+ ParsedHttpHdrs Hdr;
+ memset(&Hdr, 0, sizeof(ParsedHttpHdrs));
+ Hdr.HR.eReqType = eGET;
+ http_new_modules(&Hdr);
tv.tv_sec = 0;
tv.tv_usec = 10000;
FD_ZERO(&readset);
end_critical_section(S_SHUTDOWN);
if (shutdown == 1)
{/* we're the one to cleanup the mess. */
+ http_destroy_modules(&Hdr);
lprintf(2, "I'm master shutdown: tagging sessions to be killed.\n");
shutdown_sessions();
lprintf(2, "master shutdown: waiting for others\n");
}
}
else
+#endif
{
int fdflags;
fdflags = fcntl(ssock, F_GETFL);
lprintf(1, "unable to get server socket flags! %s \n",
strerror(errno));
fdflags = fdflags | O_NONBLOCK;
- if (fcntl(ssock, F_SETFD, fdflags) < 0)
+ if (fcntl(ssock, F_SETFL, fdflags) < 0)
lprintf(1, "unable to set server socket nonblocking flags! %s \n",
strerror(errno));
}
-#endif
if (fail_this_transaction == 0) {
+ Hdr.http_sock = ssock;
/* Perform an HTTP transaction... */
- context_loop(&ssock);
+ context_loop(&Hdr);
/* Shut down SSL/TLS if required... */
#ifdef HAVE_OPENSSL
#endif
/* ...and close the socket. */
- if (ssock > 0)
+ if (Hdr.http_sock > 0)
lingering_close(ssock);
+ http_detach_modules(&Hdr);
+
}
}
} while (!time_to_die);
+ http_destroy_modules(&Hdr);
lprintf (1, "bye\n");
pthread_exit(NULL);
}