#include <stdarg.h>
#include <syslog.h>
#include <grp.h>
-#ifdef __GNUC__
-#include <malloc.h>
-#endif
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#include "citadel.h"
#include "server.h"
-#include "dynloader.h"
+#include "serv_extensions.h"
#include "sysdep_decls.h"
#include "citserver.h"
#include "support.h"
#include "database.h"
#include "housekeeping.h"
#include "tools.h"
+#include "serv_crypto.h"
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
*/
void lprintf(int loglevel, const char *format, ...) {
va_list arg_ptr;
- char buf[4096];
+ char buf[SIZ];
va_start(arg_ptr, format);
- vsprintf(buf, format, arg_ptr);
+ vsnprintf(buf, sizeof(buf), format, arg_ptr);
va_end(arg_ptr);
if (loglevel <= verbosity) {
struct timeval tv;
struct tm *tim;
+ time_t unixtime;
gettimeofday(&tv, NULL);
- tim = localtime(&(tv.tv_sec));
+ /* Promote to time_t; types differ on some OSes (like darwin) */
+ unixtime = tv.tv_sec;
+ tim = localtime(&unixtime);
/*
* Log provides millisecond accuracy. If you need
* microsecond accuracy and your OS supports it, change
* %03ld to %06ld and remove " / 1000" after tv.tv_usec.
*/
- fprintf(stderr, "%04d/%02d/%02d %2d:%02d:%02d.%03ld %s",
- tim->tm_year + 1900, tim->tm_mon + 1, tim->tm_mday,
- tim->tm_hour, tim->tm_min, tim->tm_sec,
- tv.tv_usec / 1000, buf);
+ if (CC && CC->cs_pid) {
+ fprintf(stderr,
+ "%04d/%02d/%02d %2d:%02d:%02d.%03ld [%3d] %s",
+ tim->tm_year + 1900, tim->tm_mon + 1,
+ tim->tm_mday, tim->tm_hour, tim->tm_min,
+ tim->tm_sec, (long)tv.tv_usec / 1000,
+ CC->cs_pid, buf);
+ } else {
+ fprintf(stderr,
+ "%04d/%02d/%02d %2d:%02d:%02d.%03ld %s",
+ tim->tm_year + 1900, tim->tm_mon + 1,
+ tim->tm_mday, tim->tm_hour, tim->tm_min,
+ tim->tm_sec, (long)tv.tv_usec / 1000, buf);
+ }
fflush(stderr);
}
void init_sysdep(void) {
int a;
+#ifdef HAVE_OPENSSL
+ init_ssl();
+#endif
+
/* Set up a bunch of semaphores to be used for critical sections */
for (a=0; a<MAX_SEMAPHORES; ++a) {
pthread_mutex_init(&Critters[a], NULL);
}
-
/*
* client_write() ... Send binary data to the client.
*/
int retval;
int sock;
-
if (CC->redirect_fp != NULL) {
fwrite(buf, nbytes, 1, CC->redirect_fp);
return;
sock = CC->client_socket;
}
+#ifdef HAVE_OPENSSL
+ if (CC->redirect_ssl) {
+ client_write_ssl(buf, nbytes);
+ return;
+ }
+#endif
+
while (bytes_written < nbytes) {
retval = write(sock, &buf[bytes_written],
nbytes - bytes_written);
struct timeval tv;
int retval;
+#ifdef HAVE_OPENSSL
+ if (CC->redirect_ssl) {
+ return (client_read_ssl(buf, bytes, timeout));
+ }
+#endif
len = 0;
while(len<bytes) {
FD_ZERO(&rfds);
* (This is implemented in terms of client_read_to() and could be
* justifiably moved out of sysdep.c)
*/
-int client_read(char *buf, int bytes)
+inline int client_read(char *buf, int bytes)
{
return(client_read_to(buf, bytes, config.c_sleeping));
}
-/*
- * Tie in to the 'netsetup' program.
- *
- * (We're going to hope that netsetup never feeds more than 4096 bytes back.)
- */
-void cmd_nset(char *cmdbuf)
-{
- int retcode;
- char fbuf[4096];
- FILE *netsetup;
- int ch;
- int a, b;
- char netsetup_args[3][SIZ];
-
- if (CC->usersupp.axlevel < 6) {
- cprintf("%d Higher access required.\n",
- ERROR + HIGHER_ACCESS_REQUIRED);
- return;
- }
-
- for (a=1; a<=3; ++a) {
- if (num_parms(cmdbuf) >= a) {
- extract(netsetup_args[a-1], cmdbuf, a-1);
- for (b=0; b<strlen(netsetup_args[a-1]); ++b) {
- if (netsetup_args[a-1][b] == 34) {
- netsetup_args[a-1][b] = '_';
- }
- }
- }
- else {
- netsetup_args[a-1][0] = 0;
- }
- }
-
- sprintf(fbuf, "./netsetup \"%s\" \"%s\" \"%s\" </dev/null 2>&1",
- netsetup_args[0], netsetup_args[1], netsetup_args[2]);
- netsetup = popen(fbuf, "r");
- if (netsetup == NULL) {
- cprintf("%d %s\n", ERROR, strerror(errno));
- return;
- }
-
- fbuf[0] = 0;
- while (ch = getc(netsetup), (ch > 0)) {
- fbuf[strlen(fbuf)+1] = 0;
- fbuf[strlen(fbuf)] = ch;
- }
-
- retcode = pclose(netsetup);
-
- if (retcode != 0) {
- for (a=0; a<strlen(fbuf); ++a) {
- if (fbuf[a] < 32) fbuf[a] = 32;
- }
- fbuf[245] = 0;
- cprintf("%d %s\n", ERROR, fbuf);
- return;
- }
-
- cprintf("%d Command succeeded. Output follows:\n", LISTING_FOLLOWS);
- cprintf("%s", fbuf);
- if (fbuf[strlen(fbuf)-1] != 10) cprintf("\n");
- cprintf("000\n");
-}
-
-
-
/*
* Generic routine to convert a login name to a full name (gecos)
* Returns nonzero if a conversion took place
*/
void create_worker(void) {
int ret;
- struct worker_node *n = mallok(sizeof *n);
+ struct worker_node *n;
+ pthread_attr_t attr;
+ n = mallok(sizeof(struct worker_node));
if (n == NULL) {
lprintf(1, "can't allocate worker_node, exiting\n");
time_to_die = -1;
return;
}
- if ((ret = pthread_create(&n->tid, NULL, worker_thread, NULL) != 0))
+ if ((ret = pthread_attr_init(&attr))) {
+ lprintf(1, "pthread_attr_init: %s\n", strerror(ret));
+ time_to_die = -1;
+ return;
+ }
+
+ /* we seem to need something bigger than FreeBSD's default 64k stack */
+
+ if ((ret = pthread_attr_setstacksize(&attr, 128 * 1024))) {
+ lprintf(1, "pthread_attr_setstacksize: %s\n", strerror(ret));
+ time_to_die = -1;
+ return;
+ }
+
+ if ((ret = pthread_create(&n->tid, &attr, worker_thread, NULL) != 0))
{
lprintf(1, "Can't create worker thread: %s\n",
--num_threads;
return NULL;
}
-
-
-