ramkomd.c 10.5 KB
Newer Older
Linus Tolke Y's avatar
Linus Tolke Y committed
1
/*
Per Cederqvist's avatar
Per Cederqvist committed
2
 * $Id: ramkomd.c,v 0.34 1993/10/08 17:43:48 ceder Exp $
Linus Tolke Y's avatar
Linus Tolke Y committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * Copyright (C) 1991  Lysator Academic Computer Association.
 *
 * This file is part of the LysKOM server.
 * 
 * LysKOM is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 1, or (at your option) 
 * any later version.
 * 
 * LysKOM is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with LysKOM; see the file COPYING.  If not, write to
 * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
 * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
 * MA 02139, USA.
 *
 * Please mail bug reports to bug-lyskom@lysator.liu.se. 
 */
Per Cederqvist's avatar
Per Cederqvist committed
25 26 27 28 29 30 31 32 33
/*
 * Detta {r serverns huvudprogram. Det kommer f|rhoppningsvis bli st|rre
 * {n det {r just nu...
 *
 * Created by Willf|r 31/3-90
 *
 * It has grown! /ceder
 */

Per Cederqvist's avatar
Per Cederqvist committed
34
static char *rcsid = "$Id: ramkomd.c,v 0.34 1993/10/08 17:43:48 ceder Exp $";
35 36
#include "rcs.h"
USE(rcsid);
Per Cederqvist's avatar
Per Cederqvist committed
37

Per Cederqvist's avatar
Per Cederqvist committed
38

39
#include "getopt.h"
Per Cederqvist's avatar
Per Cederqvist committed
40 41
#include <stdlib.h>
#include <signal.h>
Per Cederqvist's avatar
Per Cederqvist committed
42
#include <stdio.h>
Per Cederqvist's avatar
Per Cederqvist committed
43 44 45
#include <ctype.h>
#include <netdb.h>
#include <string.h>
46 47 48 49
#include <locale.h>		/* Not all machines have locale.h - for those
				   that don't have it we supply an empty
				   <locale.h>. gcc -M tries to include files,
				   even if they are #ifdef'd out. */
Per Cederqvist's avatar
Per Cederqvist committed
50 51
#include <sys/types.h>
#include <sys/wait.h>
52
#include <sys/param.h>
Per Cederqvist's avatar
Per Cederqvist committed
53
#include <time.h>
Per Cederqvist's avatar
Per Cederqvist committed
54
#include <sys/time.h>
Per Cederqvist's avatar
Per Cederqvist committed
55
#include <sys/resource.h>
Per Cederqvist's avatar
Per Cederqvist committed
56 57
#include <netinet/in.h>
#include <unistd.h>
Per Cederqvist's avatar
Per Cederqvist committed
58 59
#include <errno.h>

Per Cederqvist's avatar
Per Cederqvist committed
60
#include "s-string.h"
Per Cederqvist's avatar
Per Cederqvist committed
61
#include <kom-types.h>
Per Cederqvist's avatar
Per Cederqvist committed
62
#include "string-malloc.h"
Per Cederqvist's avatar
Per Cederqvist committed
63
#include "isc-malloc.h"
Per Cederqvist's avatar
Per Cederqvist committed
64 65 66
#include <kom-errno.h>
#include "internal-services.h"
#include "lyskomd.h"
67
#include "isc-interface.h"
68
#include <server/smalloc.h>
Per Cederqvist's avatar
Per Cederqvist committed
69 70 71 72 73
#include "cache.h"
#include "log.h"
#include "com.h"
#include "connections.h"
#include "config.h"
Per Cederqvist's avatar
Per Cederqvist committed
74 75
#include "exp.h"
#include "memory.h"
76
#include "internal-connections.h"
Per Cederqvist's avatar
Per Cederqvist committed
77 78 79 80 81 82 83 84 85 86 87

Kom_err		  kom_errno;
u_long		  err_stat;
Bool		  send_async_messages		= TRUE;


#ifdef DEBUG
int	buglevel = 0;
Bool	never_save = FALSE;
#endif

88 89 90
#ifdef LOGACCESSES
char *logaccess_file = NULL;
#endif
Per Cederqvist's avatar
Per Cederqvist committed
91

92 93 94 95 96 97
EXPORT char datafilename[BUFSIZ];      /* Full pathname to the database file */
EXPORT char backupfilename[BUFSIZ];    /* Full pathname to the backup file */
EXPORT char textfilename[BUFSIZ];      /* Full pathname to the text file. */
EXPORT char statisticfile[BUFSIZ];     /* Dito to statistics file. */
EXPORT char pidfile[BUFSIZ];	       /* Dito pid-file. */
INTERNAL char memusefile[BUFSIZ];      /* Memory usage file. */
Per Cederqvist's avatar
Per Cederqvist committed
98

99 100
static char ip_client_port[80];        /* Port to listen to for clients */
static char ip_mux_port[80];           /* Port to listen to for mux:es */
Per Cederqvist's avatar
Per Cederqvist committed
101

102 103 104 105 106
int num_ip_client_port=0;	/* Numeric representation of the above. */
int num_ip_mux_port=0;		/*               -"-                    */

static IscSession *listen_client = NULL;      /* ISC listen identifier */
static IscSession *listen_mux    = NULL;      /*          -"-          */
Per Cederqvist's avatar
Per Cederqvist committed
107 108


109 110 111
static void 
dump_exit_statistics(void);

Per Cederqvist's avatar
Per Cederqvist committed
112 113 114
static void
server_init( char * client_port, char * mux_port)
{
Per Cederqvist's avatar
Per Cederqvist committed
115
    IscConfig config;
116
    IscAddress *isc_adr = NULL;
Per Cederqvist's avatar
Per Cederqvist committed
117
    
Per Cederqvist's avatar
Per Cederqvist committed
118 119 120
    /*
    ** Setup some parameters here
    */
Per Cederqvist's avatar
Per Cederqvist committed
121 122 123 124 125
    config.version = 1005;
    config.master.version = 1001;
    config.master.memfn.alloc = &isc_malloc_wrapper;
    config.master.memfn.realloc = &isc_realloc_wrapper;
    config.master.memfn.free = &isc_free_wrapper;
126
    config.master.abortfn = NULL; /* Use default abort function. */
Per Cederqvist's avatar
Per Cederqvist committed
127
    config.session.version = 1001;
128
    config.session.max.msgsize = -1; /* Use default sizes. */
Per Cederqvist's avatar
Per Cederqvist committed
129 130 131 132
    config.session.max.queuedsize = -1;
    config.session.max.dequeuelen = -1;
    config.session.max.openretries = -1;
    config.session.max.backlog = -1;
Per Cederqvist's avatar
Per Cederqvist committed
133

134
    kom_server_mcb  = isc_initialize(&config);
Per Cederqvist's avatar
Per Cederqvist committed
135
    if ( kom_server_mcb == NULL )
Per Cederqvist's avatar
Per Cederqvist committed
136 137 138 139 140
	restart_kom("server_init: can't isc_initialize()\n");

    listen_client = isc_listentcp(kom_server_mcb, NULL, client_port);
    if (listen_client == NULL)
        restart_kom("server_init: can't isc_listentcp(CLIENT)\n");
Per Cederqvist's avatar
Per Cederqvist committed
141

142 143 144 145 146 147 148 149
    isc_adr = isc_getladdress (listen_client);
    if (isc_adr == NULL)
	restart_kom("server_init(): can't isc_getladdress (listen_client)\n");

    num_ip_client_port = isc_getportnum (isc_adr);
    isc_freeaddress (isc_adr);
    
    listen_mux = isc_listentcp (kom_server_mcb, NULL, mux_port);
Per Cederqvist's avatar
Per Cederqvist committed
150 151
    if (listen_mux == NULL)
        restart_kom("server_init: can't isc_listentcp(MUX)\n");
152 153 154 155

    isc_adr = isc_getladdress (listen_mux);
    if (isc_adr == NULL)
	restart_kom("server_init(): can't isc_getladdress (listen_mux)\n");
Per Cederqvist's avatar
Per Cederqvist committed
156
    
157 158 159 160 161
    num_ip_mux_port = isc_getportnum (isc_adr);
    isc_freeaddress (isc_adr);

    log("Listening for clients on %d and muxes on %d.\n",
	num_ip_client_port, num_ip_mux_port);
Per Cederqvist's avatar
Per Cederqvist committed
162 163 164 165 166 167 168 169 170 171

    /*
     * Ignore SIGPIPE, which the server gets if it tries to write to a
     * socket and the client has died. The server will anyhow handle
     * this situation correct.
     */
    signal(SIGPIPE, SIG_IGN);
}

static void
172
init_data_base(const char *dir_base)
Per Cederqvist's avatar
Per Cederqvist committed
173 174 175 176
{
    String a = EMPTY_STRING, b = EMPTY_STRING, c = EMPTY_STRING,
	    d = EMPTY_STRING;

177 178
    if (dir_base == NULL)
      dir_base = DEFAULT_DBASE_DIR;
Per Cederqvist's avatar
Per Cederqvist committed
179
    
180 181 182 183 184 185
    sprintf(datafilename,   "%s/%s", dir_base, DATAFILE_NAME);
    sprintf(backupfilename, "%s/%s", dir_base, BACKUPFILE_NAME);
    sprintf(textfilename, "%s/%s", dir_base, TEXTFILE_NAME);
    sprintf(statisticfile, "%s/%s", dir_base, STATISTIC_NAME);
    sprintf(pidfile, "%s/%s", dir_base, PID_NAME);
    sprintf(memusefile, "%s/%s", dir_base, MEMUSE_NAME);
Per Cederqvist's avatar
Per Cederqvist committed
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208

    log("Database = %s\n",  datafilename);
    log("Backup = %s\n", backupfilename);
    
    if ( init_cache() == FAILURE )
    {
	log ( "Setting up first four conferences.\n");

	if ( s_crea_str(&a, "Presentation (av nya) m|ten") != OK
	    || s_crea_str(&b, "Presentation (av nya) medlemmar") != OK
	    || s_crea_str(&c, "Lappar (p}) d|rren") != OK
	    || s_crea_str(&d, "Nyheter om LysKOM") != OK)
	{
	    restart_kom("init_data_base: can't create strings\n");
	}
	
	if ( ! (   do_create_conf(a, 0, 0, 0, NULL_CONF_TYPE)
		&& do_create_conf(b, 0, 0, 0, NULL_CONF_TYPE)
		&& do_create_conf(c, 0, 0, 0, NULL_CONF_TYPE)
		&& do_create_conf(d, 0, 0, 0, NULL_CONF_TYPE)))
	{
	    restart_kom("init_data_base: Kan ej skapa m|ten\n");
	}
209 210 211 212 213

	s_clear(&a);
	s_clear(&b);
	s_clear(&c);
	s_clear(&d);
Per Cederqvist's avatar
Per Cederqvist committed
214 215 216
    }
}

Per Cederqvist's avatar
Per Cederqvist committed
217
static void
Per Cederqvist's avatar
Per Cederqvist committed
218
sighandler_hup (int sig)
Per Cederqvist's avatar
Per Cederqvist committed
219 220 221 222 223
{
    log ("Signal HUP received. Shutting down server.\n");
    go_and_die = TRUE;
}

Per Cederqvist's avatar
Per Cederqvist committed
224
static void
Per Cederqvist's avatar
Per Cederqvist committed
225
sighandler_quit (int sig)
Per Cederqvist's avatar
Per Cederqvist committed
226 227 228 229 230 231 232
{
    log ("Signal QUIT received - syncing...\n");
    cache_sync_all();
    log ("Dumping core now.\n");
    abort();
}

Per Cederqvist's avatar
Per Cederqvist committed
233
static void
Per Cederqvist's avatar
Per Cederqvist committed
234
sighandler_usr1 (int sig)
Per Cederqvist's avatar
Per Cederqvist committed
235 236 237 238
{
    do_sync_db = TRUE;
}

Per Cederqvist's avatar
Per Cederqvist committed
239
static void
Per Cederqvist's avatar
Per Cederqvist committed
240
sighandler_usr2 (int sig)
Per Cederqvist's avatar
Per Cederqvist committed
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
{
    int		  child;
    extern int	  fork(void);

    log ("Signal USR2 received - will dump core now.  (Check that child dies.)\n");
    if ((child = fork()) == 0)
    {
	abort();
	log ("Abort() failed!!!");
	exit(1);
    }
    else if (child < 0)
    {
	log ("Couldn't fork.\n");
    }
    else
    {
	wait (NULL);
    }
}

Per Cederqvist's avatar
Per Cederqvist committed
262
static void
Per Cederqvist's avatar
Per Cederqvist committed
263 264 265 266 267 268 269 270 271 272 273
save_pid(void)
{
    FILE *fp;

    if ( (fp = fopen(pidfile, "w")) == NULL )
	return;

    fprintf(fp, "%d", getpid());
    fclose(fp);
}

Per Cederqvist's avatar
Per Cederqvist committed
274 275 276
/* Stop complaint from gcc 2.0 about "no previous prototype for `main'". */
int main(int argc, char **argv);

Per Cederqvist's avatar
Per Cederqvist committed
277 278 279 280 281
int
main (int    argc,
      char **argv)
{
    int i;
282 283
    char *dbase_dir = NULL;

Per Cederqvist's avatar
Per Cederqvist committed
284

285 286 287 288
    log("*** Version %d (process %d) started.\n",
#include "version.incl"
	, getpid());

289
#ifdef HAVE_LOCALE
290 291 292 293 294
    if (setlocale(LC_CTYPE, "iso_8859_1") == NULL)
    {
        perror("setlocale");
	exit(1);
    }
295 296
#endif

297 298 299 300 301 302
#ifdef HAVE_GETDTABLESIZE
    MAX_NO_OF_CONNECTIONS = getdtablesize() - PROTECTED_FDS;
#endif
    /* If we don't have getdtablesize MAX_NO_OF_CONNECTIONS is
       set at compile time. */

Per Cederqvist's avatar
Per Cederqvist committed
303 304 305 306
#ifdef ENCRYPT_PASSWORDS
    srand(time(NULL) + getpid());
#endif
    
Per Cederqvist's avatar
Per Cederqvist committed
307
    s_set_storage_management(string_malloc, string_realloc, string_free);
Per Cederqvist's avatar
Per Cederqvist committed
308

309

Per Cederqvist's avatar
Per Cederqvist committed
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
    strcpy(ip_client_port, DEFAULT_CLIENT_SERVICE);
    strcpy(ip_mux_port,    DEFAULT_MUX_SERVICE);

    for (i = 1; i < argc && argv[i][0] == '-'; i++)
	switch (argv[i][1])
	{
	case 'd':
	    buglevel++;
	    break;

	case 'q':
	    never_save = TRUE;
	    break;
	    
	case 'D':		/* Database directory */
	    dbase_dir = argv[i]+2;
	    break;

	case 'p':		/* TCP/IP port number for clients */
	    strcpy(ip_client_port, argv[i]+2);
	    break;

	case 'P':		/* TCP/IP port number for MUXes */
	    strcpy(ip_mux_port, argv[i]+2);
	    break;

	case 'a':
	    send_async_messages = FALSE;
	    break;

340 341 342 343 344 345
#ifdef LOGACCESSES
	case 'L':
	    logaccess_file = argv[i] + 2;
	    break;
#endif

Per Cederqvist's avatar
Per Cederqvist committed
346
	default:
Per Cederqvist's avatar
Per Cederqvist committed
347
	    restart_kom("usage: %s [-d] [-q] [-Ddir] [-pport] [-Pmuxport]"
348 349 350 351 352
			" [-a]"
#ifdef LOGACCESSES
			" [-Ldb_trace_file]"
#endif
			"\n", argv[0]);
Per Cederqvist's avatar
Per Cederqvist committed
353 354 355 356
	}
    
    if (i < argc)
    {
Per Cederqvist's avatar
Per Cederqvist committed
357 358
	restart_kom("usage: %s [-d] [-q] [-Ddir] [-pport] [-Pmuxport]"
		    " [-a]\n", argv[0]);
Per Cederqvist's avatar
Per Cederqvist committed
359 360 361 362 363 364 365 366 367 368
    }

    signal(SIGHUP, sighandler_hup);
    signal(SIGQUIT, sighandler_quit);
    signal(SIGUSR1, sighandler_usr1);
    signal(SIGUSR2, sighandler_usr2);
  
    server_init(ip_client_port, ip_mux_port);
    init_data_base(dbase_dir);
    save_pid();
Per Cederqvist's avatar
Per Cederqvist committed
369

Per Cederqvist's avatar
Per Cederqvist committed
370
    toploop();
Per Cederqvist's avatar
Per Cederqvist committed
371 372

    logout_all_clients();
373
    isc_shutdown(kom_server_mcb);
Per Cederqvist's avatar
Per Cederqvist committed
374
    cache_sync_all();
Per Cederqvist's avatar
Per Cederqvist committed
375

376 377
    dump_exit_statistics();

Per Cederqvist's avatar
Per Cederqvist committed
378
    log("%s terminated normally.\n", argv[0]);
379 380 381 382 383 384 385 386 387 388 389 390
    
    return 0;
}

static void 
dump_exit_statistics(void)
{
    FILE *stat_file;
    time_t now;

    time(&now);
    stat_file = fopen(memusefile, "a");
Per Cederqvist's avatar
Per Cederqvist committed
391 392 393 394

    if ( stat_file == NULL )
	restart_kom("Can't open file to save memory usage to.\n");

395 396
    fprintf(stat_file, "\nLysKOM Server going down at %s\n", ctime(&now));

397 398 399 400 401
    dump_cache_stats (stat_file);

    free_all_tmp();
    free_all_cache();

Per Cederqvist's avatar
Per Cederqvist committed
402 403
    dump_smalloc_counts(stat_file);
    dump_alloc_counts(stat_file);
404
    dump_cache_mem_usage(stat_file);
Per Cederqvist's avatar
Per Cederqvist committed
405
    dump_string_alloc_counts(stat_file);
406
    dump_allocated_connections(stat_file);
407
    dump_isc_alloc_counts(stat_file);
Per Cederqvist's avatar
Per Cederqvist committed
408
    fclose (stat_file);
Per Cederqvist's avatar
Per Cederqvist committed
409
}
410
    
Per Cederqvist's avatar
Per Cederqvist committed
411 412 413 414
void
restart_kom(const char * format, ...)
{
    va_list AP;
415
    char pathname[MAXPATHLEN];
416
    char *getwd(char *); /* +++ should be in sys/param.h */
Per Cederqvist's avatar
Per Cederqvist committed
417 418 419 420 421 422

    va_start(AP, format);
    logv(format, AP);
    va_end(AP);

    log("Previous message is fatal. Will dump core now.\n");
423 424 425 426 427
    if ( getwd(pathname) == NULL )
	log("getwd failed: %s\n", pathname);
    else
	log("Search for the core in %s\n", pathname);
    
Per Cederqvist's avatar
Per Cederqvist committed
428 429
    abort();
}