ramkomd.c 9.49 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.28 1992/04/15 22:59:23 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.28 1992/04/15 22:59:23 ceder Exp $";
Per Cederqvist's avatar
Per Cederqvist committed
35

Per Cederqvist's avatar
Per Cederqvist committed
36

37
#include <m-config.h>
38
#include "getopt.h"
Per Cederqvist's avatar
Per Cederqvist committed
39 40
#include <stdlib.h>
#include <signal.h>
Per Cederqvist's avatar
Per Cederqvist committed
41
#include <stdio.h>
Per Cederqvist's avatar
Per Cederqvist committed
42 43 44
#include <ctype.h>
#include <netdb.h>
#include <string.h>
45 46 47 48
#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
49 50
#include <sys/types.h>
#include <sys/wait.h>
51
#include <sys/param.h>
Per Cederqvist's avatar
Per Cederqvist committed
52 53
#include <time.h>
#include <sys/resource.h>
Per Cederqvist's avatar
Per Cederqvist committed
54 55
#include <netinet/in.h>
#include <unistd.h>
Per Cederqvist's avatar
Per Cederqvist committed
56 57
#include <errno.h>

Per Cederqvist's avatar
Per Cederqvist committed
58
#include "s-string.h"
Per Cederqvist's avatar
Per Cederqvist committed
59
#include <kom-types.h>
Per Cederqvist's avatar
Per Cederqvist committed
60
#include "string-malloc.h"
Per Cederqvist's avatar
Per Cederqvist committed
61
#include "isc-malloc.h"
Per Cederqvist's avatar
Per Cederqvist committed
62 63 64
#include <kom-errno.h>
#include "internal-services.h"
#include "lyskomd.h"
65
#include "isc-interface.h"
66
#include <server/smalloc.h>
Per Cederqvist's avatar
Per Cederqvist committed
67 68 69 70 71
#include "cache.h"
#include "log.h"
#include "com.h"
#include "connections.h"
#include "config.h"
Per Cederqvist's avatar
Per Cederqvist committed
72 73
#include "exp.h"
#include "memory.h"
74
#include "internal-connections.h"
Per Cederqvist's avatar
Per Cederqvist committed
75 76 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 91 92 93
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
94

95 96
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
97

Per Cederqvist's avatar
Per Cederqvist committed
98 99
IscSession *listen_client = NULL;      /* ISC listen identifier */
IscSession *listen_mux    = NULL;      /*          -"-          */
Per Cederqvist's avatar
Per Cederqvist committed
100 101 102 103


static char *dbase_dir = NULL;  /* Directory where database resides */

104 105 106
static void 
dump_exit_statistics(void);

Per Cederqvist's avatar
Per Cederqvist committed
107 108 109
static void
server_init( char * client_port, char * mux_port)
{
Per Cederqvist's avatar
Per Cederqvist committed
110 111
    IscConfig config;
    
Per Cederqvist's avatar
Per Cederqvist committed
112 113 114
    /*
    ** Setup some parameters here
    */
Per Cederqvist's avatar
Per Cederqvist committed
115 116 117 118 119 120 121 122 123 124 125 126
    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;
    config.master.abortfn = NULL; /* FIXME+++ */
    config.session.version = 1001;
    config.session.max.msgsize = -1;
    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
127 128 129

    kom_server_mcb  = isc_initialize(NULL);
    if ( kom_server_mcb == NULL )
Per Cederqvist's avatar
Per Cederqvist committed
130 131 132 133 134
	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
135

Per Cederqvist's avatar
Per Cederqvist committed
136 137 138
    listen_mux = isc_listentcp(kom_server_mcb, NULL, mux_port);
    if (listen_mux == NULL)
        restart_kom("server_init: can't isc_listentcp(MUX)\n");
Per Cederqvist's avatar
Per Cederqvist committed
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
    

    /*
     * 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
init_data_base(const char *dbase_dir)
{
    String a = EMPTY_STRING, b = EMPTY_STRING, c = EMPTY_STRING,
	    d = EMPTY_STRING;

    if (dbase_dir == NULL)
      dbase_dir = DEFAULT_DBASE_DIR;
    
    sprintf(datafilename,   "%s/%s", dbase_dir, DATAFILE_NAME);
    sprintf(backupfilename, "%s/%s", dbase_dir, BACKUPFILE_NAME);
    sprintf(textfilename, "%s/%s", dbase_dir, TEXTFILE_NAME);
    sprintf(statisticfile, "%s/%s", dbase_dir, STATISTIC_NAME);
    sprintf(pidfile, "%s/%s", dbase_dir, PID_NAME);
Per Cederqvist's avatar
Per Cederqvist committed
163
    sprintf(memusefile, "%s/%s", dbase_dir, MEMUSE_NAME);
Per Cederqvist's avatar
Per Cederqvist committed
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

    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");
	}
187 188 189 190 191

	s_clear(&a);
	s_clear(&b);
	s_clear(&c);
	s_clear(&d);
Per Cederqvist's avatar
Per Cederqvist committed
192 193 194
    }
}

Per Cederqvist's avatar
Per Cederqvist committed
195
static void
Per Cederqvist's avatar
Per Cederqvist committed
196
sighandler_hup (int sig)
Per Cederqvist's avatar
Per Cederqvist committed
197 198 199 200 201
{
    log ("Signal HUP received. Shutting down server.\n");
    go_and_die = TRUE;
}

Per Cederqvist's avatar
Per Cederqvist committed
202
static void
Per Cederqvist's avatar
Per Cederqvist committed
203
sighandler_quit (int sig)
Per Cederqvist's avatar
Per Cederqvist committed
204 205 206 207 208 209 210
{
    log ("Signal QUIT received - syncing...\n");
    cache_sync_all();
    log ("Dumping core now.\n");
    abort();
}

Per Cederqvist's avatar
Per Cederqvist committed
211
static void
Per Cederqvist's avatar
Per Cederqvist committed
212
sighandler_usr1 (int sig)
Per Cederqvist's avatar
Per Cederqvist committed
213 214 215 216
{
    do_sync_db = TRUE;
}

Per Cederqvist's avatar
Per Cederqvist committed
217
static void
Per Cederqvist's avatar
Per Cederqvist committed
218
sighandler_usr2 (int sig)
Per Cederqvist's avatar
Per Cederqvist committed
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
{
    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
240
static void
Per Cederqvist's avatar
Per Cederqvist committed
241 242 243 244 245 246 247 248 249 250 251
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
252 253 254
/* 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
255 256 257 258 259 260
int
main (int    argc,
      char **argv)
{
    int i;

261
#ifdef HAVE_LOCALE
262 263 264 265 266
    if (setlocale(LC_CTYPE, "iso_8859_1") == NULL)
    {
        perror("setlocale");
	exit(1);
    }
267 268
#endif

269 270 271 272 273 274
#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
275 276 277 278
#ifdef ENCRYPT_PASSWORDS
    srand(time(NULL) + getpid());
#endif
    
Per Cederqvist's avatar
Per Cederqvist committed
279
    s_set_storage_management(string_malloc, string_realloc, string_free);
Per Cederqvist's avatar
Per Cederqvist committed
280

281

Per Cederqvist's avatar
Per Cederqvist committed
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
    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;

	default:
Per Cederqvist's avatar
Per Cederqvist committed
313 314
	    restart_kom("usage: %s [-d] [-q] [-Ddir] [-pport] [-Pmuxport]"
			" [-a]\n", argv[0]);
Per Cederqvist's avatar
Per Cederqvist committed
315 316 317 318
	}
    
    if (i < argc)
    {
Per Cederqvist's avatar
Per Cederqvist committed
319 320
	restart_kom("usage: %s [-d] [-q] [-Ddir] [-pport] [-Pmuxport]"
		    " [-a]\n", argv[0]);
Per Cederqvist's avatar
Per Cederqvist committed
321 322 323 324 325 326 327 328 329 330
    }

    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
331

Per Cederqvist's avatar
Per Cederqvist committed
332
    toploop();
Per Cederqvist's avatar
Per Cederqvist committed
333 334

    logout_all_clients();
335
    isc_shutdown(kom_server_mcb);
Per Cederqvist's avatar
Per Cederqvist committed
336
    cache_sync_all();
Per Cederqvist's avatar
Per Cederqvist committed
337

338 339
    dump_exit_statistics();

Per Cederqvist's avatar
Per Cederqvist committed
340
    log("%s terminated normally.\n", argv[0]);
341 342 343 344 345 346 347 348 349 350 351 352
    
    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
353 354 355 356

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

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

359 360 361 362 363
    dump_cache_stats (stat_file);

    free_all_tmp();
    free_all_cache();

Per Cederqvist's avatar
Per Cederqvist committed
364 365
    dump_smalloc_counts(stat_file);
    dump_alloc_counts(stat_file);
366
    dump_cache_mem_usage(stat_file);
Per Cederqvist's avatar
Per Cederqvist committed
367
    dump_string_alloc_counts(stat_file);
368
    dump_allocated_connections(stat_file);
369
    dump_isc_alloc_counts(stat_file);
Per Cederqvist's avatar
Per Cederqvist committed
370
    fclose (stat_file);
Per Cederqvist's avatar
Per Cederqvist committed
371
}
372
    
Per Cederqvist's avatar
Per Cederqvist committed
373 374 375 376
void
restart_kom(const char * format, ...)
{
    va_list AP;
377 378
    char pathname[MAXPATHLEN];
    char *getwd(char *pathname); /* +++ should be in sys/param.h */
Per Cederqvist's avatar
Per Cederqvist committed
379 380 381 382 383 384

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

    log("Previous message is fatal. Will dump core now.\n");
385 386 387 388 389
    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
390 391
    abort();
}