me->cs_pid = ++next_pid;
me->prev = NULL;
me->next = ContextList;
+ me->lastcmd = time(NULL); /* set lastcmd to now to prevent idle timer infanticide */
ContextList = me;
if (me->next != NULL) {
me->next->prev = me;
strcat (sysname, name);
len = cutuserkey(sysname);
memcpy(context->curr_user, sysname, len + 1);
+ context->client_socket = (-1);
/* internal_create_user has the side effect of loading the user regardless of wether they
* already existed or needed to be created
* Citadel Threads API
*/
struct CtdlThreadNode *CtdlThreadCreate(char *name, long flags, void *(*thread_func) (void *arg), void *args);
-struct CtdlThreadNode *CtdlThreadSchedule(char *name, long flags, void *(*thread_func) (void *arg), void *args, time_t when);
void CtdlThreadSleep(int secs);
void CtdlThreadStop(struct CtdlThreadNode *thread);
int CtdlThreadCheckStop(void);
}
-/*! \brief Create the notify message queue. We use the exact same room
- * as the Funambol module.
+/* Create the notify message queue. We use the exact same room
+ * as the Funambol module.
*
- * Run at server startup, creates FNBL_QUEUE_ROOM if it doesn't exist
- * and sets as system room.
+ * Run at server startup, creates FNBL_QUEUE_ROOM if it doesn't exist
+ * and sets as system room.
*/
void create_extnotify_queue(void) {
struct ctdlroom qrbuf;
NotifyContext Ctx;
static int doing_queue = 0;
int i = 0;
- CitContext extnotifyCC;
/*
* This is a simple concurrency check to make sure only one queue run
if (doing_queue) return;
doing_queue = 1;
- /* Give this thread its own private CitContext */
- CtdlFillSystemContext(&extnotifyCC, "extnotify");
- citthread_setspecific(MyConKey, (void *)&extnotifyCC );
-
/*
* Go ahead and run the queue
*/
CtdlLogPrintf(CTDL_DEBUG, "serv_extnotify: queue run completed\n");
doing_queue = 0;
- CtdlClearSystemContext();
}
-/*!
- * \brief Process messages in the external notification queue
+
+/*
+ * Process messages in the external notification queue
*/
void process_notify(long NotifyMsgnum, void *usrdata)
{
*
* Run through the rooms doing various types of network stuff.
*/
-void *network_do_queue(void *args) {
+void network_do_queue(void) {
static time_t last_run = 0L;
struct RoomProcList *ptr;
int full_processing = 1;
- struct CitContext networkerCC;
-
- /* Give the networker its own private CitContext */
- CtdlFillSystemContext(&networkerCC, "network");
- citthread_setspecific(MyConKey, (void *)&networkerCC );
/*
* Run the full set of processing tasks no more frequently
* with a static variable instead.
*/
if (doing_queue) {
- CtdlClearSystemContext();
- return NULL;
+ return;
}
doing_queue = 1;
}
doing_queue = 0;
-
- /* Reschedule this task to happen again periodically, unless the thread system indicates
- * that the server is shutting down.
- */
- if (!CtdlThreadCheckStop()) {
- CtdlThreadSchedule("IGnet Network", CTDLTHREAD_BIGSTACK,
- network_do_queue, NULL, time(NULL) + 60
- );
- }
- else {
- CtdlLogPrintf(CTDL_DEBUG, "network: Task STOPPED.\n");
- }
- CtdlClearSystemContext();
- return NULL;
}
return 0;
}
+void *ignet_thread(void *arg) {
+ struct CitContext ignet_thread_CC;
+
+ CtdlLogPrintf(CTDL_DEBUG, "ignet_thread() initializing\n");
+ CtdlFillSystemContext(&ignet_thread_CC, "IGnet Queue");
+ citthread_setspecific(MyConKey, (void *)&ignet_thread_CC);
+
+ while (!CtdlThreadCheckStop()) {
+ network_do_queue();
+ CtdlThreadSleep(60);
+ }
+
+ CtdlClearSystemContext();
+ return(NULL);
+}
+
+
+
/*
* Module entry point
CtdlRegisterProtoHook(cmd_snet, "SNET", "Set network config");
CtdlRegisterProtoHook(cmd_netp, "NETP", "Identify as network poller");
CtdlRegisterProtoHook(cmd_nsyn, "NSYN", "Synchronize room to node");
- CtdlRegisterRoomHook(network_room_handler);
+ CtdlRegisterRoomHook(network_room_handler);
CtdlRegisterCleanupHook(destroy_network_queue_room);
+ CtdlThreadCreate("SMTP Send", CTDLTHREAD_BIGSTACK, ignet_thread, NULL);
}
- else
- CtdlThreadSchedule("IGnet Network", CTDLTHREAD_BIGSTACK, network_do_queue, NULL, 0);
- /* return our Subversion id for the Log */
return "network";
}
static int doing_pop3client = 0;
struct pop3aggr *pptr;
time_t fastest_scan;
- CitContext popclientCC;
-
- /* Give this thread its own private CitContext */
- CtdlFillSystemContext(&popclientCC, "popclient");
- citthread_setspecific(MyConKey, (void *)&popclientCC );
if (config.c_pop3_fastest < config.c_pop3_fetch)
fastest_scan = config.c_pop3_fastest;
CtdlLogPrintf(CTDL_DEBUG, "pop3client ended\n");
last_run = time(NULL);
doing_pop3client = 0;
- CtdlClearSystemContext();
}
/*
* Scan for rooms that have RSS client requests configured
*/
-void *rssclient_scan(void *args) {
+void rssclient_scan(void *args) {
static time_t last_run = 0L;
static int doing_rssclient = 0;
rssnetcfg *rptr = NULL;
- CitContext rssclientCC;
-
- /* Give this thread its own private CitContext */
- CtdlFillSystemContext(&rssclientCC, "rssclient");
- citthread_setspecific(MyConKey, (void *)&rssclientCC );
/*
* This is a simple concurrency check to make sure only one rssclient run
CtdlLogPrintf(CTDL_DEBUG, "rssclient ended\n");
last_run = time(NULL);
doing_rssclient = 0;
- if (!CtdlThreadCheckStop())
- CtdlThreadSchedule ("RSS Client", CTDLTHREAD_BIGSTACK, rssclient_scan, NULL, last_run + config.c_net_freq);
- else
- CtdlLogPrintf(CTDL_DEBUG, "rssclient: Task STOPPED.\n");
- CtdlClearSystemContext();
return NULL;
}
if (threading)
{
CtdlLogPrintf(CTDL_INFO, "%s\n", curl_version());
- CtdlThreadSchedule ("RSS Client", CTDLTHREAD_BIGSTACK, rssclient_scan, NULL, 0);
+ CtdlRegisterSessionHook(rssclient_scan, EVT_TIMER);
}
StartHandlers = NewHash(1, NULL);
int run_queue_now = 0; /* Set to 1 to ignore SMTP send retry times */
-citthread_mutex_t smtp_send_lock;
-
/*****************************************************************************/
/* SMTP SERVER (INBOUND) STUFF */
/*
- * smtp_do_queue()
+ * smtp_queue_thread()
*
* Run through the queue sending out messages.
*/
-void *smtp_do_queue(void *arg) {
+void *smtp_queue_thread(void *arg) {
int num_processed = 0;
struct CitContext smtp_queue_CC;
CtdlFillSystemContext(&smtp_queue_CC, "SMTP Send");
- citthread_setspecific(MyConKey, (void *)&smtp_queue_CC );
- CtdlLogPrintf(CTDL_INFO, "SMTP client: processing outbound queue\n");
+ citthread_setspecific(MyConKey, (void *)&smtp_queue_CC);
+ CtdlLogPrintf(CTDL_DEBUG, "smtp_queue_thread() initializing\n");
- if (CtdlGetRoom(&CC->room, SMTP_SPOOLOUT_ROOM) != 0) {
- CtdlLogPrintf(CTDL_ERR, "Cannot find room <%s>\n", SMTP_SPOOLOUT_ROOM);
- }
- else {
- num_processed = CtdlForEachMessage(MSGS_ALL, 0L, NULL, SPOOLMIME, NULL, smtp_do_procmsg, NULL);
- }
+ while (!CtdlThreadCheckStop()) {
+
+ CtdlLogPrintf(CTDL_INFO, "SMTP client: processing outbound queue\n");
- citthread_mutex_unlock (&smtp_send_lock);
- CtdlLogPrintf(CTDL_INFO, "SMTP client: queue run completed; %d messages processed\n", num_processed);
+ if (CtdlGetRoom(&CC->room, SMTP_SPOOLOUT_ROOM) != 0) {
+ CtdlLogPrintf(CTDL_ERR, "Cannot find room <%s>\n", SMTP_SPOOLOUT_ROOM);
+ }
+ else {
+ num_processed = CtdlForEachMessage(MSGS_ALL, 0L, NULL, SPOOLMIME, NULL, smtp_do_procmsg, NULL);
+ }
+ CtdlLogPrintf(CTDL_INFO, "SMTP client: queue run completed; %d messages processed\n", num_processed);
+ CtdlThreadSleep(60);
+ }
CtdlClearSystemContext();
return(NULL);
-/*
- * smtp_queue_thread
- *
- * Create a thread to run the SMTP queue
- *
- * This was created as a response to a situation seen on Uncensored where a bad remote was holding
- * up SMTP sending for long times.
- * Converting to a thread does not fix the problem caused by the bad remote but it does prevent
- * the SMTP sending from stopping housekeeping and the EVT_TIMER event system which in turn prevented
- * other things from happening.
- */
-void smtp_queue_thread (void)
-{
- if (citthread_mutex_trylock (&smtp_send_lock)) {
- CtdlLogPrintf(CTDL_DEBUG, "SMTP queue run already in progress\n");
- }
- else {
- CtdlThreadCreate("SMTP Send", CTDLTHREAD_BIGSTACK, smtp_do_queue, NULL);
- }
-}
-
-
-
-void smtp_server_going_down (void)
-{
- CtdlLogPrintf(CTDL_DEBUG, "SMTP module clean up for shutdown.\n");
-
- citthread_mutex_destroy (&smtp_send_lock);
-}
-
-
-
/*****************************************************************************/
/* SMTP UTILITY COMMANDS */
/*****************************************************************************/
CitadelServiceSMTP_LMTP_UNF);
smtp_init_spoolout();
- CtdlRegisterSessionHook(smtp_queue_thread, EVT_TIMER);
CtdlRegisterSessionHook(smtp_cleanup_function, EVT_STOP);
CtdlRegisterProtoHook(cmd_smtp, "SMTP", "SMTP utility commands");
- CtdlRegisterCleanupHook (smtp_server_going_down);
- citthread_mutex_init (&smtp_send_lock, NULL);
+ CtdlThreadCreate("SMTP Send", CTDLTHREAD_BIGSTACK, smtp_queue_thread, NULL);
}
/* return our Subversion id for the Log */
-/*
- * Internal function to schedule a thread.
- * Must be called from within a S_THREAD_LIST critical section
- */
-CtdlThreadNode *CtdlThreadSchedule(char *name, long flags, void *(*thread_func) (void *arg), void *args, time_t when)
-{
- CtdlThreadNode *this_thread;
-
- if (num_threads >= 32767)
- {
- CtdlLogPrintf(CTDL_EMERG, "Thread system. Thread list full.\n");
- return NULL;
- }
-
- this_thread = malloc(sizeof(CtdlThreadNode));
- if (this_thread == NULL) {
- CtdlLogPrintf(CTDL_EMERG, "Thread system, can't allocate CtdlThreadNode, exiting\n");
- return NULL;
- }
- /* Initialise the thread structure */
- if (ctdl_internal_init_thread_struct(this_thread, flags) == NULL)
- {
- free(this_thread);
- CtdlLogPrintf(CTDL_EMERG, "Thread system, can't initialise CtdlThreadNode, exiting\n");
- return NULL;
- }
-
- /*
- * If we got here we are going to create the thread so we must initilise the structure
- * first because most implimentations of threading can't create it in a stopped state
- * and it might want to do things with its structure that aren't initialised otherwise.
- */
- if(name)
- {
- this_thread->name = name;
- }
- else
- {
- this_thread->name = "Un-named Thread";
- }
-
- this_thread->flags = flags;
- this_thread->thread_func = thread_func;
- this_thread->user_args = args;
-
- /*
- * When to start this thread
- */
- this_thread->when = when;
-
- begin_critical_section(S_SCHEDULE_LIST);
- this_thread->next = CtdlThreadSchedList;
- CtdlThreadSchedList = this_thread;
- if (this_thread->next)
- this_thread->next->prev = this_thread;
- end_critical_section(S_SCHEDULE_LIST);
-
- return this_thread;
-}
-
-
-
CtdlThreadNode *ctdl_thread_internal_start_scheduled (CtdlThreadNode *this_thread)
{
int ret = 0;
}
+/*
+ * People expect blogs to be sorted newest-to-oldest
+ */
int blogview_sortfunc(const void *s1, const void *s2) {
long l1;
long l2;
l1 = *(long *)(s1);
l2 = *(long *)(s2);
- if (l1 > l2) return(+1);
- if (l1 < l2) return(-1);
+ if (l1 > l2) return(-1);
+ if (l1 < l2) return(+1);
return(0);
}
-int blogview_RenderView_or_Tail(SharedMessageStatus *Stat,
+int blogview_render(SharedMessageStatus *Stat,
void **ViewSpecific,
long oper)
{
struct blogview *BLOG = (struct blogview *) *ViewSpecific;
int i;
- const StrBuf *Mime;
wc_printf("<div class=\"fix_scrollbar_bug\">");
for (i=0; (i<BLOG->num_msgs); ++i) {
if (BLOG->msgs[i] > 0L) {
- read_message(WC->WBuf, HKEY("view_message"), BLOG->msgs[i], NULL, &Mime);
+ wc_printf("<p>Message %d %ld</p>\n", i, BLOG->msgs[i]);
+
+ /* maybe put some of this into its own function later */
+ StrBuf *Buf;
+ Buf = NewStrBuf();
+ serv_printf("MSG0 %ld|1", BLOG->msgs[i]); /* top level citadel headers only */
+ StrBuf_ServGetln(Buf);
+ if (GetServerStatus(Buf, NULL) == 1) {
+ while (StrBuf_ServGetln(Buf), strcmp(ChrPtr(Buf), "000")) {
+ wc_printf("%s<br>\n", ChrPtr(Buf));
+ }
+ }
+ FreeStrBuf(&Buf);
}
}
NULL,
NULL,
blogview_LoadMsgFromServer,
- blogview_RenderView_or_Tail,
+ blogview_render,
blogview_Cleanup
);
}
/*
- * RSS/Atom feed generator
+ * RSS feed generator (could be adapted in the future to feed both RSS and Atom)
*
* Copyright (c) 2010 by the citadel.org team
*
int state=0;
Buf = NewStrBuf();
- lprintf(9, "MSG4 %ld|%s\n", Msg->msgnum, ChrPtr(Msg->PartNum));
if (Msg->PartNum != NULL) {
serv_printf("MSG4 %ld|%s", Msg->msgnum, ChrPtr(Msg->PartNum));
}
/* Server isn't ready for us? */
if (short_status != 2) {
if (Status == 571) {
+ hprintf("HTTP/1.1 503 Service Unavailable\r\n");
+ hprintf("Content-type: text/plain; charset=utf-8\r\n");
wc_printf(_("This server is already serving its maximum number of users and cannot accept any additional logins at this time. Please try again later or contact your system administrator."));
}
else {
Status,
_("Received unexpected answer from Citadel server; bailing out.")
);
+ hprintf("HTTP/1.1 502 Bad Gateway\r\n");
+ hprintf("Content-type: text/plain; charset=utf-8\r\n");
}
end_burst();
end_webcit_session();
if (WCC->serv_info == NULL){
begin_burst();
wc_printf(_("Received unexpected answer from Citadel server; bailing out."));
- hprintf("HTTP/1.1 200 OK\r\n");
+ hprintf("HTTP/1.1 502 Bad Gateway\r\n");
hprintf("Content-type: text/plain; charset=utf-8\r\n");
end_burst();
end_webcit_session();
output_static_safe(StaticFilemappings[3]);
}
+
+/*
+ * robots.txt
+ */
+void robots_txt(void) {
+ output_headers(0, 0, 0, 0, 0, 0);
+
+ hprintf("Content-type: text/plain\r\n"
+ "Server: %s\r\n"
+ "Connection: close\r\n",
+ PACKAGE_STRING);
+ begin_burst();
+
+ wc_printf("User-agent: *\r\n"
+ "Disallow:\r\n"
+ "Sitemap: %s/sitemap.xml\r\n"
+ "\r\n"
+ ,
+ ChrPtr(site_prefix)
+ );
+
+ wDumpContent(0);
+}
+
+
void
ServerStartModule_STATIC
(void)
LoadStaticDir(static_dirs[2], StaticFilemappings[2], "");
LoadStaticDir(static_dirs[3], StaticFilemappings[3], "");
- WebcitAddUrlHandler(HKEY("robots.txt"), "", 0, output_flat_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
+ WebcitAddUrlHandler(HKEY("robots.txt"), "", 0, robots_txt, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
WebcitAddUrlHandler(HKEY("favicon.ico"), "", 0, output_flat_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
WebcitAddUrlHandler(HKEY("static"), "", 0, output_static_0, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
WebcitAddUrlHandler(HKEY("static.local"), "", 0, output_static_1, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
+++ /dev/null
-User-agent: *
-Disallow: