Annotation of sbbs/sbbs3/sbbscon.c, revision 1.1.1.2

1.1       root        1: /* sbbscon.c */
                      2: 
                      3: /* Synchronet vanilla/console-mode "front-end" */
                      4: 
1.1.1.2 ! root        5: /* $Id: sbbscon.c,v 1.187 2004/11/18 09:12:09 rswindell Exp $ */
1.1       root        6: 
                      7: /****************************************************************************
                      8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                     10:  *                                                                                                                                                     *
1.1.1.2 ! root       11:  * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html         *
1.1       root       12:  *                                                                                                                                                     *
                     13:  * This program is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU General Public License                         *
                     15:  * as published by the Free Software Foundation; either version 2                      *
                     16:  * of the License, or (at your option) any later version.                                      *
                     17:  * See the GNU General Public License for more details: gpl.txt or                     *
                     18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
                     19:  *                                                                                                                                                     *
                     20:  * Anonymous FTP access to the most recent released source is available at     *
                     21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     22:  *                                                                                                                                                     *
                     23:  * Anonymous CVS access to the development source and modification history     *
                     24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     26:  *     (just hit return, no password is necessary)                                                     *
                     27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     28:  *                                                                                                                                                     *
                     29:  * For Synchronet coding style and modification guidelines, see                                *
                     30:  * http://www.synchro.net/source.html                                                                          *
                     31:  *                                                                                                                                                     *
                     32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     33:  * format) via e-mail to [email protected]                                                                      *
                     34:  *                                                                                                                                                     *
                     35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     36:  ****************************************************************************/
                     37: 
1.1.1.2 ! root       38: /* ANSI headers */
        !            39: #include <stdio.h>
        !            40: #include <string.h>
        !            41: #include <signal.h>
        !            42: #include <ctype.h>
        !            43: #ifdef __QNX__
        !            44: #include <locale.h>
        !            45: #endif
        !            46: 
1.1       root       47: /* Synchronet-specific headers */
1.1.1.2 ! root       48: #undef SBBS    /* this shouldn't be defined unless building sbbs.dll/libsbbs.so */
        !            49: #include "sbbs.h"              /* load_cfg() */
        !            50: #include "sbbs_ini.h"  /* sbbs_read_ini() */
1.1       root       51: #include "ftpsrvr.h"   /* ftp_startup_t, ftp_server */
                     52: #include "mailsrvr.h"  /* mail_startup_t, mail_server */
1.1.1.2 ! root       53: #include "services.h"  /* services_startup_t, services_thread */
        !            54: 
        !            55: /* XPDEV headers */
        !            56: #include "conwrap.h"   /* kbhit/getch */
        !            57: #include "threadwrap.h"        /* pthread_mutex_t */
        !            58: 
        !            59: #ifdef __unix__
        !            60: 
        !            61: #include <sys/types.h>
        !            62: #include <unistd.h>
        !            63: #include <pwd.h>
        !            64: #include <grp.h>
        !            65: #include <stdarg.h>
        !            66: #include <stdlib.h>  /* Is this included from somewhere else? */
        !            67: #include <syslog.h>
        !            68: 
        !            69: #endif
        !            70: 
        !            71: /* Services doesn't work without JavaScript support */
        !            72: #if !defined(JAVASCRIPT)
        !            73:        #define NO_SERVICES
        !            74: #endif
1.1       root       75: 
                     76: /* Constants */
1.1.1.2 ! root       77: #define SBBS_PID_FILE  "/var/run/sbbs.pid"
        !            78: #define SBBS_LOG_NAME  "synchronet"
1.1       root       79: 
                     80: /* Global variables */
1.1.1.2 ! root       81: BOOL                           terminated=FALSE;
1.1       root       82: 
1.1.1.2 ! root       83: BOOL                           run_bbs=FALSE;
        !            84: BOOL                           bbs_running=FALSE;
        !            85: BOOL                           bbs_stopped=FALSE;
        !            86: BOOL                           has_bbs=FALSE;
        !            87: bbs_startup_t          bbs_startup;
        !            88: BOOL                           run_ftp=FALSE;
        !            89: BOOL                           ftp_running=FALSE;
        !            90: BOOL                           ftp_stopped=FALSE;
        !            91: BOOL                           has_ftp=FALSE;
        !            92: ftp_startup_t          ftp_startup;
        !            93: BOOL                           run_mail=FALSE;
        !            94: BOOL                           mail_running=FALSE;
        !            95: BOOL                           mail_stopped=FALSE;
        !            96: BOOL                           has_mail=FALSE;
        !            97: mail_startup_t         mail_startup;
        !            98: BOOL                           run_services=FALSE;
        !            99: BOOL                           services_running=FALSE;
        !           100: BOOL                           services_stopped=FALSE;
        !           101: BOOL                           has_services=FALSE;
        !           102: services_startup_t     services_startup;
        !           103: BOOL                           run_web=FALSE;
        !           104: BOOL                           web_running=FALSE;
        !           105: BOOL                           web_stopped=FALSE;
        !           106: BOOL                           has_web=FALSE;
        !           107: web_startup_t          web_startup;
        !           108: uint                           thread_count=1;
        !           109: uint                           socket_count=0;
        !           110: uint                           client_count=0;
        !           111: int                                    prompt_len=0;
        !           112: static scfg_t          scfg;                                   /* To allow rerun */
        !           113: static ulong           served=0;
        !           114: char                           ini_file[MAX_PATH+1];
        !           115: 
        !           116: #ifdef __unix__
        !           117: char                           new_uid_name[32];
        !           118: char                           new_gid_name[32];
        !           119: uid_t                          new_uid;
        !           120: uid_t                          old_uid;
        !           121: gid_t                          new_gid;
        !           122: gid_t                          old_gid;
        !           123: BOOL                           is_daemon=FALSE;
        !           124: char                           daemon_type[2];
        !           125: BOOL                           std_facilities=FALSE;
        !           126: FILE *                         pidf;
        !           127: #endif
        !           128: 
        !           129: static const char* prompt;
        !           130: 
        !           131: static const char* usage  = "\nusage: %s [[setting] [...]] [path/ini_file]\n"
        !           132:                                                        "\n"
        !           133:                                                        "Global settings:\n"
        !           134:                                                        "\n"
        !           135:                                                        "\thn[host]   set hostname for this instance\n"
        !           136:                                                        "\t           if host not specified, uses gethostname\n"
        !           137: #ifdef __unix__
        !           138:                                                        "\tun<user>   set username for BBS to run as\n"
        !           139:                                                        "\tug<group>  set group for BBS to run as\n"
        !           140:                                                        "\td[x]       run as daemon, log using syslog\n"
        !           141:                                                        "\t           x is the optional LOCALx facility to use\n"
        !           142:                                                        "\t           if none is specified, uses USER\n"
        !           143:                                                        "\t           if 'S' is specified, uses standard facilities\n"
        !           144: #endif
        !           145:                                                        "\tgi         get user identity (using IDENT protocol)\n"
        !           146:                                                        "\tnh         disable hostname lookups\n"
        !           147:                                                        "\tnj         disable JavaScript support\n"
        !           148:                                                        "\tne         disable event thread\n"
        !           149:                                                        "\tni         do not read settings from .ini file\n"
        !           150: #ifdef __unix__
        !           151:                                                        "\tnd         do not read run as daemon - overrides .ini file\n"
        !           152: #endif
        !           153:                                                        "\tlt         use local timezone (do not force UTC/GMT)\n"
        !           154:                                                        "\tdefaults   show default settings and options\n"
        !           155:                                                        "\n"
        !           156:                                                        ;
        !           157: static const char* telnet_usage  = "Telnet server settings:\n\n"
        !           158:                                                        "\ttf<node>   set first Telnet node number\n"
        !           159:                                                        "\ttl<node>   set last Telnet node number\n"
        !           160:                                                        "\ttp<port>   set Telnet server port\n"
        !           161:                                                        "\trp<port>   set RLogin server port (and enable RLogin server)\n"
        !           162:                                                        "\tr2         use second RLogin name in BSD RLogin\n"
        !           163:                                                        "\tto<value>  set Telnet server options value (advanced)\n"
        !           164:                                                        "\tta         enable auto-logon via IP address\n"
        !           165:                                                        "\ttd         enable Telnet command debug output\n"
        !           166:                                                        "\ttc         emabble sysop availability for chat\n"
        !           167:                                                        "\ttq         disable QWK events\n"
        !           168:                                                        "\tt-         disable Telnet/RLogin server\n"
        !           169:                                                        "\n"
        !           170:                                                        ;
        !           171: static const char* ftp_usage  = "FTP server settings:\n"
        !           172:                                                        "\n"
        !           173:                                                        "\tfp<port>   set FTP server port\n"
        !           174:                                                        "\tfo<value>  set FTP server options value (advanced)\n"
        !           175:                                                        "\tf-         disable FTP server\n"
        !           176:                                                        "\n"
        !           177:                                                        ;
        !           178: static const char* mail_usage  = "Mail server settings:\n"
        !           179:                                                        "\n"
        !           180:                                                        "\tms<port>   set SMTP server port\n"
        !           181:                                                        "\tmp<port>   set POP3 server port\n"
        !           182:                                                        "\tmr<addr>   set SMTP relay server (and enable SMTP relay)\n"
        !           183:                                                        "\tmd<addr>   set DNS server address for MX-record lookups\n"
        !           184:                                                        "\tmo<value>  set Mail server options value (advanced)\n"
        !           185:                                                        "\tma         allow SMTP relays from authenticated users\n"
        !           186:                                                        "\tm-         disable Mail server (entirely)\n"
        !           187:                                                        "\tmp-        disable POP3 server\n"
        !           188:                                                        "\tms-        disable SendMail thread\n"
        !           189:                                                        "\n"
        !           190:                                                        ;
        !           191: static const char* services_usage  = "Services settings:\n"
        !           192:                                                        "\n"
        !           193:                                                        "\tso<value>  set Services option value (advanced)\n"
        !           194:                                                        "\ts-         disable Services (no services module)\n"
        !           195:                                                        "\n"
        !           196:                                                        ;
1.1       root      197: 
1.1.1.2 ! root      198: static int lputs(int level, char *str)
1.1       root      199: {
                    200:        static pthread_mutex_t mutex;
                    201:        static BOOL mutex_initialized;
                    202: 
1.1.1.2 ! root      203: #ifdef __unix__
        !           204: 
        !           205:        if (is_daemon)  {
        !           206:                if(str!=NULL) {
        !           207:                        if (std_facilities)
        !           208:                                syslog(level|LOG_AUTH,"%s",str);
        !           209:                        else
        !           210:                                syslog(level,"%s",str);
        !           211:                }
        !           212:                return(0);
        !           213:        }
        !           214: #endif
1.1       root      215:        if(!mutex_initialized) {
                    216:                pthread_mutex_init(&mutex,NULL);
                    217:                mutex_initialized=TRUE;
                    218:        }
                    219:        pthread_mutex_lock(&mutex);
1.1.1.2 ! root      220:        /* erase prompt */
        !           221:        printf("\r%*s\r",prompt_len,"");
        !           222:        if(str!=NULL)
        !           223:                printf("%s\n",str);
        !           224:        /* re-display prompt with current stats */
        !           225:        if(prompt!=NULL)
        !           226:                prompt_len = printf(prompt, thread_count, socket_count, client_count, served);
1.1       root      227:        fflush(stdout);
                    228:        pthread_mutex_unlock(&mutex);
1.1.1.2 ! root      229: 
        !           230:     return(prompt_len);
        !           231: }
        !           232: 
        !           233: static int lprintf(int level, char *fmt, ...)
        !           234: {
        !           235:        va_list argptr;
        !           236:        char sbuf[1024];
        !           237: 
        !           238:     va_start(argptr,fmt);
        !           239:     vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
        !           240:        sbuf[sizeof(sbuf)-1]=0;
        !           241:     va_end(argptr);
        !           242:     return(lputs(level,sbuf));
        !           243: }
        !           244: 
        !           245: #ifdef __unix__
        !           246: /**********************************************************
        !           247: * Change uid of the calling process to the user if specified
        !           248: * **********************************************************/
        !           249: static BOOL do_seteuid(BOOL to_new) 
        !           250: {
        !           251:        BOOL    result=FALSE;
        !           252:        static pthread_mutex_t mutex;
        !           253:        static BOOL mutex_initialized;
        !           254: 
        !           255:        if(new_uid_name[0]==0)  /* not set? */
        !           256:                return(TRUE);           /* do nothing */
        !           257: 
        !           258:        if(!mutex_initialized) {
        !           259:                pthread_mutex_init(&mutex,NULL);
        !           260:                mutex_initialized=TRUE;
        !           261:        }
        !           262: 
        !           263:        pthread_mutex_lock(&mutex);
        !           264: 
        !           265:        if(to_new)
        !           266:                if(!setregid(-1,new_gid) && !setreuid(-1,new_uid))
        !           267:                        result=TRUE;
        !           268:                else
        !           269:                        result=FALSE;
        !           270:        else
        !           271:                if(!setregid(-1,old_gid) && !setreuid(-1,old_uid))
        !           272:                        result=TRUE;
        !           273:                else
        !           274:                        result=FALSE;
        !           275: 
        !           276:                
        !           277:        pthread_mutex_unlock(&mutex);
        !           278: 
        !           279:        if(!result) {
        !           280:                lputs(LOG_ERR,"!seteuid FAILED");
        !           281:                lputs(LOG_ERR,strerror(errno));
        !           282:        }
        !           283:        return result;
        !           284: }
        !           285: 
        !           286: /**********************************************************
        !           287: * Change uid of the calling process to the user if specified
        !           288: * **********************************************************/
        !           289: BOOL do_setuid(BOOL force)
        !           290: {
        !           291:        BOOL result=TRUE;
        !           292: #if defined(DONT_BLAME_SYNCHRONET) || defined(_THREAD_SUID_BROKEN)
        !           293:        if(!force)
        !           294:                return(do_seteuid(TRUE));
        !           295: #endif
        !           296:        setregid(-1,old_gid);
        !           297:        setreuid(-1,old_uid);
        !           298:        if(setregid(new_gid,new_gid))
        !           299:        {
        !           300:                lputs(LOG_ERR,"!setgid FAILED");
        !           301:                lputs(LOG_ERR,strerror(errno));
        !           302:                result=FALSE;
        !           303:        }
        !           304: 
        !           305:        if(setreuid(new_uid,new_uid))
        !           306:        {
        !           307:                lputs(LOG_ERR,"!setuid FAILED");
        !           308:                lputs(LOG_ERR,strerror(errno));
        !           309:                result=FALSE;
        !           310:        }
        !           311:        if(force && (!result))
        !           312:                exit(1);
        !           313: 
        !           314:        return(result);
        !           315: }
        !           316: #endif   /* __unix__ */
        !           317: 
        !           318: #ifdef _WINSOCKAPI_
        !           319: 
        !           320: static WSADATA WSAData;
        !           321: 
        !           322: static BOOL winsock_startup(void)
        !           323: {
        !           324:        int             status;             /* Status Code */
        !           325: 
        !           326:     if((status = WSAStartup(MAKEWORD(1,1), &WSAData))==0)
        !           327:                return(TRUE);
        !           328: 
        !           329:     lprintf(LOG_ERR,"!WinSock startup ERROR %d", status);
        !           330:        return(FALSE);
        !           331: }
        !           332: 
        !           333: static BOOL winsock_cleanup(void)      
        !           334: {
        !           335:        if(WSACleanup()==0)
        !           336:                return(TRUE);
        !           337: 
        !           338:        lprintf(LOG_ERR,"!WinSock cleanup ERROR %d",ERROR_VALUE);
        !           339:        return(FALSE);
        !           340: }
        !           341: 
        !           342: #else /* No WINSOCK */
        !           343: 
        !           344: #define winsock_startup()      (TRUE)  
        !           345: #define winsock_cleanup()      (TRUE)
        !           346: 
        !           347: #endif
        !           348: 
        !           349: static void thread_up(void* p, BOOL up, BOOL setuid)
        !           350: {
        !           351:        static pthread_mutex_t mutex;
        !           352:        static BOOL mutex_initialized;
        !           353: 
        !           354: #ifdef _THREAD_SUID_BROKEN
        !           355:        if(up && setuid) {
        !           356:                do_seteuid(FALSE);
        !           357:                do_setuid(FALSE);
        !           358:        }
        !           359: #endif
        !           360: 
        !           361:        if(!mutex_initialized) {
        !           362:                pthread_mutex_init(&mutex,NULL);
        !           363:                mutex_initialized=TRUE;
        !           364:        }
        !           365: 
        !           366:        pthread_mutex_lock(&mutex);
        !           367:        if(up)
        !           368:            thread_count++;
        !           369:     else if(thread_count>0)
        !           370:        thread_count--;
        !           371:        pthread_mutex_unlock(&mutex);
        !           372:        lputs(LOG_INFO,NULL); /* update displayed stats */
        !           373: }
        !           374: 
        !           375: static void socket_open(void* p, BOOL open)
        !           376: {
        !           377:        static pthread_mutex_t mutex;
        !           378:        static BOOL mutex_initialized;
        !           379: 
        !           380:        if(!mutex_initialized) {
        !           381:                pthread_mutex_init(&mutex,NULL);
        !           382:                mutex_initialized=TRUE;
        !           383:        }
        !           384: 
        !           385:        pthread_mutex_lock(&mutex);
        !           386:        if(open)
        !           387:            socket_count++;
        !           388:     else if(socket_count>0)
        !           389:        socket_count--;
        !           390:        pthread_mutex_unlock(&mutex);
        !           391:        lputs(LOG_INFO,NULL); /* update displayed stats */
1.1       root      392: }
                    393: 
1.1.1.2 ! root      394: static void client_on(void* p, BOOL on, int sock, client_t* client, BOOL update)
        !           395: {
        !           396:        static pthread_mutex_t mutex;
        !           397:        static BOOL mutex_initialized;
        !           398: 
        !           399:        if(!mutex_initialized) {
        !           400:                pthread_mutex_init(&mutex,NULL);
        !           401:                mutex_initialized=TRUE;
        !           402:        }
        !           403: 
        !           404:        pthread_mutex_lock(&mutex);
        !           405:        if(on && !update) {
        !           406:                client_count++;
        !           407:            served++;
        !           408:        } else if(!on && client_count>0)
        !           409:                client_count--;
        !           410:        pthread_mutex_unlock(&mutex);
        !           411:        lputs(LOG_INFO,NULL); /* update displayed stats */
1.1       root      412: }
                    413: 
                    414: /****************************************************************************/
                    415: /* BBS local/log print routine                                                                                         */
                    416: /****************************************************************************/
1.1.1.2 ! root      417: static int bbs_lputs(void* p, int level, char *str)
1.1       root      418: {
                    419:        char            logline[512];
                    420:        char            tstr[64];
                    421:        time_t          t;
1.1.1.2 ! root      422:        struct tm       tm;
        !           423: 
        !           424:        if(!(bbs_startup.log_mask&(1<<level)))
        !           425:                return(0);
        !           426: 
        !           427: #ifdef __unix__
        !           428:        if (is_daemon)  {
        !           429:                if(str==NULL)
        !           430:                        return(0);
        !           431:                if (std_facilities)
        !           432:                        syslog(level|LOG_AUTH,"%s",str);
        !           433:                else
        !           434:                        syslog(level,"     %s",str);
        !           435:                return(strlen(str));
        !           436:        }
        !           437: #endif
1.1       root      438: 
                    439:        t=time(NULL);
1.1.1.2 ! root      440:        if(localtime_r(&t,&tm)==NULL)
1.1       root      441:                tstr[0]=0;
                    442:        else
                    443:                sprintf(tstr,"%d/%d %02d:%02d:%02d "
1.1.1.2 ! root      444:                        ,tm.tm_mon+1,tm.tm_mday
        !           445:                        ,tm.tm_hour,tm.tm_min,tm.tm_sec);
1.1       root      446: 
1.1.1.2 ! root      447:        sprintf(logline,"%s     %.*s",tstr,(int)sizeof(logline)-32,str);
1.1       root      448:        truncsp(logline);
1.1.1.2 ! root      449:        lputs(level,logline);
1.1       root      450:        
                    451:     return(strlen(logline)+1);
                    452: }
                    453: 
1.1.1.2 ! root      454: static void bbs_started(void* p)
1.1       root      455: {
                    456:        bbs_running=TRUE;
1.1.1.2 ! root      457:        bbs_stopped=FALSE;
        !           458:        #ifdef _THREAD_SUID_BROKEN
        !           459:            do_seteuid(FALSE);
        !           460:            do_setuid(FALSE);
        !           461:        #endif
1.1       root      462: }
                    463: 
1.1.1.2 ! root      464: static void bbs_terminated(void* p, int code)
1.1       root      465: {
                    466:        bbs_running=FALSE;
1.1.1.2 ! root      467:        bbs_stopped=TRUE;
1.1       root      468: }
                    469: 
                    470: /****************************************************************************/
                    471: /* FTP local/log print routine                                                                                         */
                    472: /****************************************************************************/
1.1.1.2 ! root      473: static int ftp_lputs(void* p, int level, char *str)
1.1       root      474: {
                    475:        char            logline[512];
                    476:        char            tstr[64];
                    477:        time_t          t;
1.1.1.2 ! root      478:        struct tm       tm;
        !           479: 
        !           480:        if(!(ftp_startup.log_mask&(1<<level)))
        !           481:                return(0);
        !           482: 
        !           483: #ifdef __unix__
        !           484:        if (is_daemon)  {
        !           485:                if(str==NULL)
        !           486:                        return(0);
        !           487:                if (std_facilities)
        !           488: #ifdef __solaris__
        !           489:                        syslog(level|LOG_DAEMON,"%s",str);
        !           490: #else
        !           491:                        syslog(level|LOG_FTP,"%s",str);
        !           492: #endif
        !           493:                else
        !           494:                        syslog(level,"ftp  %s",str);
        !           495:                return(strlen(str));
        !           496:        }
        !           497: #endif
1.1       root      498: 
                    499:        t=time(NULL);
1.1.1.2 ! root      500:        if(localtime_r(&t,&tm)==NULL)
1.1       root      501:                tstr[0]=0;
                    502:        else
                    503:                sprintf(tstr,"%d/%d %02d:%02d:%02d "
1.1.1.2 ! root      504:                        ,tm.tm_mon+1,tm.tm_mday
        !           505:                        ,tm.tm_hour,tm.tm_min,tm.tm_sec);
1.1       root      506: 
1.1.1.2 ! root      507:        sprintf(logline,"%sftp  %.*s",tstr,(int)sizeof(logline)-32,str);
1.1       root      508:        truncsp(logline);
1.1.1.2 ! root      509:        lputs(level,logline);
1.1       root      510:        
                    511:     return(strlen(logline)+1);
                    512: }
                    513: 
1.1.1.2 ! root      514: static void ftp_started(void* p)
1.1       root      515: {
                    516:        ftp_running=TRUE;
1.1.1.2 ! root      517:        ftp_stopped=FALSE;
        !           518:        #ifdef _THREAD_SUID_BROKEN
        !           519:            do_seteuid(FALSE);
        !           520:            do_setuid(FALSE);
        !           521:        #endif
1.1       root      522: }
                    523: 
1.1.1.2 ! root      524: static void ftp_terminated(void* p, int code)
1.1       root      525: {
                    526:        ftp_running=FALSE;
1.1.1.2 ! root      527:        ftp_stopped=TRUE;
1.1       root      528: }
                    529: 
                    530: /****************************************************************************/
                    531: /* Mail Server local/log print routine                                                                         */
                    532: /****************************************************************************/
1.1.1.2 ! root      533: static int mail_lputs(void* p, int level, char *str)
1.1       root      534: {
                    535:        char            logline[512];
                    536:        char            tstr[64];
                    537:        time_t          t;
1.1.1.2 ! root      538:        struct tm       tm;
        !           539: 
        !           540:        if(!(mail_startup.log_mask&(1<<level)))
        !           541:                return(0);
        !           542: 
        !           543: #ifdef __unix__
        !           544:        if (is_daemon)  {
        !           545:                if(str==NULL)
        !           546:                        return(0);
        !           547:                if (std_facilities)
        !           548:                        syslog(level|LOG_MAIL,"%s",str);
        !           549:                else
        !           550:                        syslog(level,"mail %s",str);
        !           551:                return(strlen(str));
        !           552:        }
        !           553: #endif
1.1       root      554: 
                    555:        t=time(NULL);
1.1.1.2 ! root      556:        if(localtime_r(&t,&tm)==NULL)
1.1       root      557:                tstr[0]=0;
                    558:        else
                    559:                sprintf(tstr,"%d/%d %02d:%02d:%02d "
1.1.1.2 ! root      560:                        ,tm.tm_mon+1,tm.tm_mday
        !           561:                        ,tm.tm_hour,tm.tm_min,tm.tm_sec);
1.1       root      562: 
1.1.1.2 ! root      563:        sprintf(logline,"%smail %.*s",tstr,(int)sizeof(logline)-32,str);
1.1       root      564:        truncsp(logline);
1.1.1.2 ! root      565:        lputs(level,logline);
1.1       root      566:        
                    567:     return(strlen(logline)+1);
                    568: }
                    569: 
1.1.1.2 ! root      570: static void mail_started(void* p)
1.1       root      571: {
                    572:        mail_running=TRUE;
1.1.1.2 ! root      573:        mail_stopped=FALSE;
        !           574:        #ifdef _THREAD_SUID_BROKEN
        !           575:            do_seteuid(FALSE);
        !           576:            do_setuid(FALSE);
        !           577:        #endif
1.1       root      578: }
                    579: 
1.1.1.2 ! root      580: static void mail_terminated(void* p, int code)
1.1       root      581: {
                    582:        mail_running=FALSE;
1.1.1.2 ! root      583:        mail_stopped=TRUE;
        !           584: }
        !           585: 
        !           586: /****************************************************************************/
        !           587: /* Services local/log print routine                                                                                    */
        !           588: /****************************************************************************/
        !           589: static int services_lputs(void* p, int level, char *str)
        !           590: {
        !           591:        char            logline[512];
        !           592:        char            tstr[64];
        !           593:        time_t          t;
        !           594:        struct tm       tm;
        !           595: 
        !           596:        if(!(services_startup.log_mask&(1<<level)))
        !           597:                return(0);
        !           598: 
        !           599: #ifdef __unix__
        !           600:        if (is_daemon)  {
        !           601:                if(str==NULL)
        !           602:                        return(0);
        !           603:                if (std_facilities)
        !           604:                        syslog(level|LOG_DAEMON,"%s",str);
        !           605:                else
        !           606:                        syslog(level,"srvc %s",str);
        !           607:                return(strlen(str));
        !           608:        }
        !           609: #endif
        !           610: 
        !           611:        t=time(NULL);
        !           612:        if(localtime_r(&t,&tm)==NULL)
        !           613:                tstr[0]=0;
        !           614:        else
        !           615:                sprintf(tstr,"%d/%d %02d:%02d:%02d "
        !           616:                        ,tm.tm_mon+1,tm.tm_mday
        !           617:                        ,tm.tm_hour,tm.tm_min,tm.tm_sec);
        !           618: 
        !           619:        sprintf(logline,"%ssrvc %.*s",tstr,(int)sizeof(logline)-32,str);
        !           620:        truncsp(logline);
        !           621:        lputs(level,logline);
        !           622:        
        !           623:     return(strlen(logline)+1);
        !           624: }
        !           625: 
        !           626: static void services_started(void* p)
        !           627: {
        !           628:        services_running=TRUE;
        !           629:        services_stopped=FALSE;
        !           630:        #ifdef _THREAD_SUID_BROKEN
        !           631:            do_seteuid(FALSE);
        !           632:            do_setuid(FALSE);
        !           633:        #endif
        !           634: }
        !           635: 
        !           636: static void services_terminated(void* p, int code)
        !           637: {
        !           638:        services_running=FALSE;
        !           639:        services_stopped=TRUE;
        !           640: }
        !           641: 
        !           642: /****************************************************************************/
        !           643: /* Event thread local/log print routine                                                                                */
        !           644: /****************************************************************************/
        !           645: static int event_lputs(int level, char *str)
        !           646: {
        !           647:        char            logline[512];
        !           648:        char            tstr[64];
        !           649:        time_t          t;
        !           650:        struct tm       tm;
        !           651: 
        !           652:        if(!(bbs_startup.log_mask&(1<<level)))
        !           653:                return(0);
        !           654: 
        !           655: #ifdef __unix__
        !           656:        if (is_daemon)  {
        !           657:                if(str==NULL)
        !           658:                        return(0);
        !           659:                if (std_facilities)
        !           660:                        syslog(level|LOG_CRON,"%s",str);
        !           661:                else
        !           662:                        syslog(level,"evnt %s",str);
        !           663:                return(strlen(str));
        !           664:        }
        !           665: #endif
        !           666: 
        !           667:        t=time(NULL);
        !           668:        if(localtime_r(&t,&tm)==NULL)
        !           669:                tstr[0]=0;
        !           670:        else
        !           671:                sprintf(tstr,"%d/%d %02d:%02d:%02d "
        !           672:                        ,tm.tm_mon+1,tm.tm_mday
        !           673:                        ,tm.tm_hour,tm.tm_min,tm.tm_sec);
        !           674: 
        !           675:        sprintf(logline,"%sevnt %.*s",tstr,(int)sizeof(logline)-32,str);
        !           676:        truncsp(logline);
        !           677:        lputs(level,logline);
        !           678:        
        !           679:     return(strlen(logline)+1);
        !           680: }
        !           681: 
        !           682: /****************************************************************************/
        !           683: /* web local/log print routine                                                                                 */
        !           684: /****************************************************************************/
        !           685: static int web_lputs(void* p, int level, char *str)
        !           686: {
        !           687:        char            logline[512];
        !           688:        char            tstr[64];
        !           689:        time_t          t;
        !           690:        struct tm       tm;
        !           691: 
        !           692:        if(!(web_startup.log_mask&(1<<level)))
        !           693:                return(0);
        !           694: 
        !           695: #ifdef __unix__
        !           696:        if (is_daemon)  {
        !           697:                if(str==NULL)
        !           698:                        return(0);
        !           699:                if (std_facilities)
        !           700:                        syslog(level|LOG_DAEMON,"%s",str);
        !           701:                else
        !           702:                        syslog(level,"web  %s",str);
        !           703:                return(strlen(str));
        !           704:        }
        !           705: #endif
        !           706: 
        !           707:        t=time(NULL);
        !           708:        if(localtime_r(&t,&tm)==NULL)
        !           709:                tstr[0]=0;
        !           710:        else
        !           711:                sprintf(tstr,"%d/%d %02d:%02d:%02d "
        !           712:                        ,tm.tm_mon+1,tm.tm_mday
        !           713:                        ,tm.tm_hour,tm.tm_min,tm.tm_sec);
        !           714: 
        !           715:        sprintf(logline,"%sweb  %.*s",tstr,(int)sizeof(logline)-32,str);
        !           716:        truncsp(logline);
        !           717:        lputs(level,logline);
        !           718:        
        !           719:     return(strlen(logline)+1);
        !           720: }
        !           721: 
        !           722: static void web_started(void* p)
        !           723: {
        !           724:        web_running=TRUE;
        !           725:        web_stopped=FALSE;
        !           726:        #ifdef _THREAD_SUID_BROKEN
        !           727:            do_seteuid(FALSE);
        !           728:            do_setuid(FALSE);
        !           729:        #endif
        !           730: }
        !           731: 
        !           732: static void web_terminated(void* p, int code)
        !           733: {
        !           734:        web_running=FALSE;
        !           735:        web_stopped=TRUE;
        !           736: }
        !           737: 
        !           738: static void terminate(void)
        !           739: {
        !           740:        ulong count=0;
        !           741: 
        !           742:        if(bbs_running)
        !           743:                bbs_terminate();
        !           744:        if(ftp_running)
        !           745:                ftp_terminate();
        !           746: #ifndef NO_WEB_SERVER
        !           747:        if(web_running)
        !           748:                web_terminate();
        !           749: #endif
        !           750:        if(mail_running)
        !           751:                mail_terminate();
        !           752: #ifndef NO_SERVICES
        !           753:        if(services_running)
        !           754:                services_terminate();
        !           755: #endif
        !           756: 
        !           757:        while(bbs_running || ftp_running || web_running || mail_running || services_running)  {
        !           758:                if(count && (count%10)==0) {
        !           759:                        if(bbs_running)
        !           760:                                lputs(LOG_INFO,"BBS System thread still running");
        !           761:                        if(ftp_running)
        !           762:                                lputs(LOG_INFO,"FTP Server thread still running");
        !           763:                        if(web_running)
        !           764:                                lputs(LOG_INFO,"Web Server thread still running");
        !           765:                        if(mail_running)
        !           766:                                lputs(LOG_INFO,"Mail Server thread still running");
        !           767:                        if(services_running)
        !           768:                                lputs(LOG_INFO,"Services thread still running");
        !           769:                }
        !           770:                count++;
        !           771:                SLEEP(1000);
        !           772:        }
        !           773: }
        !           774: 
        !           775: static void read_startup_ini(BOOL recycle
        !           776:                                                         ,bbs_startup_t* bbs, ftp_startup_t* ftp, web_startup_t* web
        !           777:                                                         ,mail_startup_t* mail, services_startup_t* services)
        !           778: {
        !           779:        FILE*   fp=NULL;
        !           780: 
        !           781:        /* Read .ini file here */
        !           782:        if(ini_file[0]!=0) { 
        !           783:                if((fp=fopen(ini_file,"r"))==NULL) {
        !           784:                        lprintf(LOG_ERR,"!ERROR %d (%s) opening %s",errno,strerror(errno),ini_file);
        !           785:                } else {
        !           786:                        lprintf(LOG_INFO,"Reading %s",ini_file);
        !           787:                }
        !           788:        }
        !           789:        if(fp==NULL)
        !           790:                lputs(LOG_WARNING,"Using default initialization values");
        !           791: 
        !           792:        /* We call this function to set defaults, even if there's no .ini file */
        !           793:        sbbs_read_ini(fp, 
        !           794:                NULL,                   /* global_startup */
        !           795:                &run_bbs,               bbs,
        !           796:                &run_ftp,               ftp, 
        !           797:                &run_web,               web,
        !           798:                &run_mail,              mail, 
        !           799:                &run_services,  services);
        !           800: 
        !           801:        /* read/default any sbbscon-specific .ini keys here */
        !           802: #if defined(__unix__)
        !           803:        {
        !           804:                char    value[INI_MAX_VALUE_LEN];
        !           805:                SAFECOPY(new_uid_name,iniReadString(fp,"UNIX","User","",value));
        !           806:                SAFECOPY(new_gid_name,iniReadString(fp,"UNIX","Group","",value));
        !           807:                if(!recycle)
        !           808:                        is_daemon=iniReadBool(fp,"UNIX","Daemonize",FALSE);
        !           809:                SAFECOPY(daemon_type,iniReadString(fp,"UNIX","LogFacility","U",value));
        !           810:                umask(iniReadInteger(fp,"UNIX","umask",077));
        !           811:        }
        !           812: #endif
        !           813:        /* close .ini file here */
        !           814:        if(fp!=NULL)
        !           815:                fclose(fp);
        !           816: }
        !           817: 
        !           818: /* Server recycle callback (read relevant startup .ini file section)           */
        !           819: void recycle(void* cbdata)
        !           820: {
        !           821:        bbs_startup_t* bbs=NULL;
        !           822:        ftp_startup_t* ftp=NULL;
        !           823:        web_startup_t* web=NULL;
        !           824:        mail_startup_t* mail=NULL;
        !           825:        services_startup_t* services=NULL;
        !           826: 
        !           827:        if(cbdata==&bbs_startup)
        !           828:                bbs=cbdata;
        !           829:        else if(cbdata==&ftp_startup)
        !           830:                ftp=cbdata;
        !           831:        else if(cbdata==&web_startup)
        !           832:                web=cbdata;
        !           833:        else if(cbdata==&mail_startup)
        !           834:                mail=cbdata;
        !           835:        else if(cbdata==&services_startup)
        !           836:                services=cbdata;
        !           837: 
        !           838:        read_startup_ini(/* recycle? */TRUE,bbs,ftp,web,mail,services);
        !           839: }
        !           840: 
        !           841: void cleanup(void)
        !           842: {
        !           843: #ifdef __unix__
        !           844:        unlink(SBBS_PID_FILE);
        !           845: #endif
        !           846: }
        !           847: 
        !           848: #if defined(_WIN32)
        !           849: BOOL WINAPI ControlHandler(DWORD CtrlType)
        !           850: {
        !           851:        terminated=TRUE;
        !           852:        return TRUE;
        !           853: }
        !           854: #endif
        !           855: 
        !           856: 
        !           857: #ifdef __unix__
        !           858: void _sighandler_quit(int sig)
        !           859: {
        !           860:        char    str[1024];
        !           861:        static pthread_mutex_t mutex;
        !           862:        static BOOL mutex_initialized;
        !           863: 
        !           864:        if(!mutex_initialized) {
        !           865:                pthread_mutex_init(&mutex,NULL);
        !           866:                mutex_initialized=TRUE;
        !           867:        }
        !           868:        pthread_mutex_lock(&mutex);
        !           869:        /* Can I get away with leaving this locked till exit? */
        !           870: 
        !           871:        lprintf(LOG_NOTICE,"     Got quit signal (%d)",sig);
        !           872:        terminate();
        !           873: 
        !           874:     exit(0);
        !           875: }
        !           876: 
        !           877: void _sighandler_rerun(int sig)
        !           878: {
        !           879: 
        !           880:        lputs(LOG_NOTICE,"     Got HUP (rerun) signal");
        !           881: 
        !           882:        bbs_startup.recycle_now=TRUE;
        !           883:        ftp_startup.recycle_now=TRUE;
        !           884:        web_startup.recycle_now=TRUE;
        !           885:        mail_startup.recycle_now=TRUE;
        !           886:        services_startup.recycle_now=TRUE;
1.1       root      887: }
                    888: 
1.1.1.2 ! root      889: static void handle_sigs(void)
        !           890: {
        !           891:        int                     i;
        !           892:        int                     sig=0;
        !           893:        sigset_t        sigs;
        !           894: 
        !           895:        thread_up(NULL,TRUE,TRUE);
        !           896: 
        !           897:        if (is_daemon) {
        !           898:                /* Write the standard .pid file if running as a daemon */
        !           899:                /* Must be here so signals are sent to the correct thread */
        !           900: 
        !           901:                if(pidf!=NULL) {
        !           902:                        fprintf(pidf,"%d",getpid());
        !           903:                        fclose(pidf);
        !           904:                }
        !           905:        }
        !           906: 
        !           907:        /* Set up blocked signals */
        !           908:        sigemptyset(&sigs);
        !           909:        sigaddset(&sigs,SIGINT);
        !           910:        sigaddset(&sigs,SIGQUIT);
        !           911:        sigaddset(&sigs,SIGABRT);
        !           912:        sigaddset(&sigs,SIGTERM);
        !           913:        sigaddset(&sigs,SIGHUP);
        !           914:        sigaddset(&sigs,SIGALRM);
        !           915:        /* sigaddset(&sigs,SIGPIPE); */
        !           916:        pthread_sigmask(SIG_BLOCK,&sigs,NULL);
        !           917:        while(1)  {
        !           918:                if((i=sigwait(&sigs,&sig))!=0) {   /* wait here until signaled */
        !           919:                        lprintf(LOG_ERR,"     !sigwait FAILURE (%d)", i);
        !           920:                        continue;
        !           921:                }
        !           922:                lprintf(LOG_NOTICE,"     Got signal (%d)", sig);
        !           923:                switch(sig)  {
        !           924:                        /* QUIT-type signals */
        !           925:                        case SIGINT:
        !           926:                        case SIGQUIT:
        !           927:                        case SIGABRT:
        !           928:                        case SIGTERM:
        !           929:                                _sighandler_quit(sig);
        !           930:                                break;
        !           931:                        case SIGHUP:    /* rerun */
        !           932:                                _sighandler_rerun(sig);
        !           933:                                break;
        !           934:                        default:
        !           935:                                lputs(LOG_NOTICE,"     Signal has no handler (unexpected)");
        !           936:                }
        !           937:        }
        !           938: }
        !           939: #endif /* __unix__ */
        !           940: 
        !           941: /****************************************************************************/
        !           942: /* Displays appropriate usage info                                                                                     */
        !           943: /****************************************************************************/
        !           944: static void show_usage(char *cmd)
        !           945: {
        !           946:        printf(usage,cmd);
        !           947:        if(has_bbs)
        !           948:                printf(telnet_usage);
        !           949:        if(has_ftp)
        !           950:                printf(ftp_usage);
        !           951:        if(has_mail)
        !           952:                printf(mail_usage);
        !           953:        if(has_services)
        !           954:                printf(services_usage);
        !           955: }
        !           956: 
        !           957: #if SBBS_MAGIC_FILENAMES
        !           958: static int command_is(char *cmdline, char *cmd)
        !           959: {
        !           960:        return(strnicmp(getfname(cmdline),cmd,strlen(cmd))==0);
        !           961: }
        !           962: #endif
        !           963: 
1.1       root      964: /****************************************************************************/
                    965: /* Main Entry Point                                                                                                                    */
                    966: /****************************************************************************/
                    967: int main(int argc, char** argv)
                    968: {
1.1.1.2 ! root      969:        int             i;
        !           970:        int             n;
        !           971:        int             file;
1.1       root      972:        char    ch;
1.1.1.2 ! root      973:        char*   p;
        !           974:        char*   arg;
1.1       root      975:        char*   ctrl_dir;
1.1.1.2 ! root      976:        char    str[MAX_PATH+1];
        !           977:     char       error[256];
        !           978:        char    host_name[128]="";
        !           979:        node_t  node;
        !           980: #ifdef __unix__
        !           981:        struct passwd*  pw_entry;
        !           982:        struct group*   gr_entry;
        !           983:        sigset_t                sigs;
        !           984: #endif
1.1       root      985: 
1.1.1.2 ! root      986: #ifdef __QNX__
        !           987:        setlocale( LC_ALL, "C-TRADITIONAL" );
        !           988: #endif
        !           989: #ifdef __unix__
        !           990:        setsid();       /* Disassociate from controlling terminal */
        !           991:        umask(077);
        !           992: #endif
        !           993:        printf("\nSynchronet Console for %s  Version %s%c  %s\n\n"
        !           994:                ,PLATFORM_DESC,VERSION,REVISION,COPYRIGHT_NOTICE);
        !           995: 
        !           996:        atexit(cleanup);
1.1       root      997: 
                    998:        ctrl_dir=getenv("SBBSCTRL");    /* read from environment variable */
1.1.1.2 ! root      999:        if(ctrl_dir==NULL || ctrl_dir[0]==0) {
        !          1000:                ctrl_dir="/sbbs/ctrl";          /* Not set? Use default */
        !          1001:                printf("!SBBSCTRL environment variable not set, using default value: %s\n\n"
        !          1002:                        ,ctrl_dir);
        !          1003:        }
        !          1004: 
        !          1005:        if(!winsock_startup())
        !          1006:                return(-1);
        !          1007: 
        !          1008:        gethostname(host_name,sizeof(host_name)-1);
        !          1009: 
        !          1010:        if(!winsock_cleanup())
        !          1011:                return(-1);
        !          1012: 
        !          1013:        sbbs_get_ini_fname(ini_file, ctrl_dir, host_name);
1.1       root     1014: 
                   1015:        /* Initialize BBS startup structure */
                   1016:     memset(&bbs_startup,0,sizeof(bbs_startup));
                   1017:     bbs_startup.size=sizeof(bbs_startup);
1.1.1.2 ! root     1018:        bbs_startup.cbdata=&bbs_startup;
        !          1019:        bbs_startup.log_mask=~0;
1.1       root     1020:        bbs_startup.lputs=bbs_lputs;
1.1.1.2 ! root     1021:        bbs_startup.event_lputs=event_lputs;
1.1       root     1022:     bbs_startup.started=bbs_started;
1.1.1.2 ! root     1023:        bbs_startup.recycle=recycle;
1.1       root     1024:     bbs_startup.terminated=bbs_terminated;
1.1.1.2 ! root     1025:     bbs_startup.thread_up=thread_up;
        !          1026:     bbs_startup.socket_open=socket_open;
        !          1027:     bbs_startup.client_on=client_on;
        !          1028: #ifdef __unix__
        !          1029:        bbs_startup.seteuid=do_seteuid;
        !          1030:        bbs_startup.setuid=do_setuid;
        !          1031: #endif
1.1       root     1032: /*     These callbacks haven't been created yet
                   1033:     bbs_startup.status=bbs_status;
                   1034:     bbs_startup.clients=bbs_clients;
                   1035: */
                   1036:     strcpy(bbs_startup.ctrl_dir,ctrl_dir);
                   1037: 
                   1038:        /* Initialize FTP startup structure */
                   1039:     memset(&ftp_startup,0,sizeof(ftp_startup));
                   1040:     ftp_startup.size=sizeof(ftp_startup);
1.1.1.2 ! root     1041:        ftp_startup.cbdata=&ftp_startup;
        !          1042:        ftp_startup.log_mask=~0;
1.1       root     1043:        ftp_startup.lputs=ftp_lputs;
                   1044:     ftp_startup.started=ftp_started;
1.1.1.2 ! root     1045:        ftp_startup.recycle=recycle;
1.1       root     1046:     ftp_startup.terminated=ftp_terminated;
1.1.1.2 ! root     1047:        ftp_startup.thread_up=thread_up;
        !          1048:     ftp_startup.socket_open=socket_open;
        !          1049:     ftp_startup.client_on=client_on;
        !          1050: #ifdef __unix__
        !          1051:        ftp_startup.seteuid=do_seteuid;
        !          1052:        ftp_startup.setuid=do_setuid;
        !          1053: #endif
1.1       root     1054:     strcpy(ftp_startup.index_file_name,"00index");
                   1055:     strcpy(ftp_startup.ctrl_dir,ctrl_dir);
                   1056: 
1.1.1.2 ! root     1057:        /* Initialize Web Server startup structure */
        !          1058:     memset(&web_startup,0,sizeof(web_startup));
        !          1059:     web_startup.size=sizeof(web_startup);
        !          1060:        web_startup.cbdata=&web_startup;
        !          1061:        web_startup.log_mask=~0;
        !          1062:        web_startup.lputs=web_lputs;
        !          1063:     web_startup.started=web_started;
        !          1064:        web_startup.recycle=recycle;
        !          1065:     web_startup.terminated=web_terminated;
        !          1066:        web_startup.thread_up=thread_up;
        !          1067:     web_startup.socket_open=socket_open;
        !          1068:        web_startup.client_on=client_on;
        !          1069: #ifdef __unix__
        !          1070:        web_startup.seteuid=do_seteuid;
        !          1071:        web_startup.setuid=do_setuid;
        !          1072: #endif
        !          1073:     strcpy(web_startup.ctrl_dir,ctrl_dir);
        !          1074: 
1.1       root     1075:        /* Initialize Mail Server startup structure */
                   1076:     memset(&mail_startup,0,sizeof(mail_startup));
                   1077:     mail_startup.size=sizeof(mail_startup);
1.1.1.2 ! root     1078:        mail_startup.cbdata=&mail_startup;
        !          1079:        mail_startup.log_mask=~0;
1.1       root     1080:        mail_startup.lputs=mail_lputs;
                   1081:     mail_startup.started=mail_started;
1.1.1.2 ! root     1082:        mail_startup.recycle=recycle;
1.1       root     1083:     mail_startup.terminated=mail_terminated;
1.1.1.2 ! root     1084:        mail_startup.thread_up=thread_up;
        !          1085:     mail_startup.socket_open=socket_open;
        !          1086:     mail_startup.client_on=client_on;
        !          1087: #ifdef __unix__
        !          1088:        mail_startup.seteuid=do_seteuid;
        !          1089:        mail_startup.setuid=do_setuid;
        !          1090: #endif
1.1       root     1091:     strcpy(mail_startup.ctrl_dir,ctrl_dir);
                   1092: 
1.1.1.2 ! root     1093: #ifdef __unix__        /* Look up DNS server address */
        !          1094:        {
        !          1095:                FILE*   fp;
        !          1096:                char*   p;
        !          1097:                char    str[128];
        !          1098: 
        !          1099:                if((fp=fopen("/etc/resolv.conf","r"))!=NULL) {
        !          1100:                        while(!feof(fp)) {
        !          1101:                                if(fgets(str,sizeof(str),fp)==NULL)
        !          1102:                                        break;
        !          1103:                                truncsp(str);
        !          1104:                                p=str;
        !          1105:                                while(*p && *p<=' ') p++;       /* skip white-space */
        !          1106:                                if(strnicmp(p,"nameserver",10)!=0) /* no match */
        !          1107:                                        continue;
        !          1108:                                p+=10;  /* skip "nameserver" */
        !          1109:                                while(*p && *p<=' ') p++;       /* skip more white-space */
        !          1110:                                SAFECOPY(mail_startup.dns_server,p);
1.1       root     1111:                                break;
1.1.1.2 ! root     1112:                        }
        !          1113:                        fclose(fp);
        !          1114:                }
        !          1115:        }
        !          1116: #endif /* __unix__ */
        !          1117: 
        !          1118:        /* Initialize Services startup structure */
        !          1119:     memset(&services_startup,0,sizeof(services_startup));
        !          1120:     services_startup.size=sizeof(services_startup);
        !          1121:        services_startup.cbdata=&services_startup;
        !          1122:        services_startup.log_mask=~0;
        !          1123:        services_startup.lputs=services_lputs;
        !          1124:     services_startup.started=services_started;
        !          1125:        services_startup.recycle=recycle;
        !          1126:     services_startup.terminated=services_terminated;
        !          1127:        services_startup.thread_up=thread_up;
        !          1128:     services_startup.socket_open=socket_open;
        !          1129:     services_startup.client_on=client_on;
        !          1130: #ifdef __unix__
        !          1131:        services_startup.seteuid=do_seteuid;
        !          1132:        services_startup.setuid=do_setuid;
        !          1133: #endif
        !          1134:     strcpy(services_startup.ctrl_dir,ctrl_dir);
        !          1135: 
        !          1136:        /* Pre-INI command-line switches */
        !          1137:        for(i=1;i<argc;i++) {
        !          1138:                arg=argv[i];
        !          1139:                while(*arg=='-')
        !          1140:                        arg++;
        !          1141:                if(strcspn(arg,"\\/")!=strlen(arg)) {
        !          1142:                        strcpy(ini_file,arg);
        !          1143:                        continue;
        !          1144:                }
        !          1145:                if(!stricmp(arg,"ni")) {
        !          1146:                        ini_file[0]=0;
        !          1147:                        break;
        !          1148:                }
        !          1149:        }
        !          1150: 
        !          1151:        read_startup_ini(/* recycle? */FALSE
        !          1152:                ,&bbs_startup, &ftp_startup, &web_startup, &mail_startup, &services_startup);
        !          1153: 
        !          1154: #if SBBS_MAGIC_FILENAMES       /* This stuff is just broken */
        !          1155: 
        !          1156:        if(!command_is(argv[0],"sbbs"))  {
        !          1157:                run_bbs=has_bbs=FALSE;
        !          1158:                run_ftp=has_ftp=FALSE;
        !          1159:                run_mail=has_mail=FALSE;
        !          1160:                run_services=has_services=FALSE;
        !          1161:                run_web=has_web=FALSE;
        !          1162:        }
        !          1163:        if(command_is(argv[0],"sbbs_ftp"))
        !          1164:                run_ftp=has_ftp=TRUE;
        !          1165:        else if(command_is(argv[0],"sbbs_mail"))
        !          1166:                run_mail=has_mail=TRUE;
        !          1167:        else if(command_is(argv[0],"sbbs_bbs"))
        !          1168:                run_bbs=has_bbs=TRUE;
        !          1169: #ifndef NO_SERVICES
        !          1170:        else if(command_is(argv[0],"sbbs_srvc"))
        !          1171:                run_services=has_services=TRUE;
        !          1172: #endif
        !          1173: #ifndef NO_WEB_SERVER
        !          1174:        else if(command_is(argv[0],"sbbs_web"))
        !          1175:                run_web=has_web=TRUE;
        !          1176: #endif
        !          1177:        else {
        !          1178:                run_bbs=has_bbs=TRUE;
        !          1179:                run_ftp=has_ftp=TRUE;
        !          1180:                run_mail=has_mail=TRUE;
        !          1181: #ifndef NO_SERVICES
        !          1182:                run_services=has_services=TRUE;
        !          1183: #endif
        !          1184: #ifndef NO_WEB_SERVER
        !          1185:                run_web=has_web=TRUE;
        !          1186: #endif
        !          1187:        }
        !          1188: 
        !          1189: #endif /* Removed broken stuff */
        !          1190: 
        !          1191:        /* Post-INI command-line switches */
        !          1192:        for(i=1;i<argc;i++) {
        !          1193:                arg=argv[i];
        !          1194:                while(*arg=='-')
        !          1195:                        arg++;
        !          1196:                if(strcspn(arg,"\\/")!=strlen(arg))     /* ini_file name */
        !          1197:                        continue;
        !          1198:                if(!stricmp(arg,"defaults")) {
        !          1199:                        printf("Default settings:\n");
        !          1200:                        printf("\n");
        !          1201:                        printf("Telnet server port:\t%u\n",bbs_startup.telnet_port);
        !          1202:                        printf("Telnet first node:\t%u\n",bbs_startup.first_node);
        !          1203:                        printf("Telnet last node:\t%u\n",bbs_startup.last_node);
        !          1204:                        printf("Telnet server options:\t0x%08lX\n",bbs_startup.options);
        !          1205:                        printf("FTP server port:\t%u\n",ftp_startup.port);
        !          1206:                        printf("FTP server options:\t0x%08lX\n",ftp_startup.options);
        !          1207:                        printf("Mail SMTP server port:\t%u\n",mail_startup.smtp_port);
        !          1208:                        printf("Mail SMTP relay port:\t%u\n",mail_startup.relay_port);
        !          1209:                        printf("Mail POP3 server port:\t%u\n",mail_startup.pop3_port);
        !          1210:                        printf("Mail server options:\t0x%08lX\n",mail_startup.options);
        !          1211:                        printf("Services options:\t0x%08lX\n",services_startup.options);
        !          1212:                        return(0);
        !          1213:                }
        !          1214:                switch(toupper(*(arg++))) {
        !          1215: #ifdef __unix__
        !          1216:                                case 'D': /* Run as daemon */
        !          1217:                                        is_daemon=TRUE;
        !          1218:                                        SAFECOPY(daemon_type,arg++);
        !          1219:                                break;
        !          1220: #endif
        !          1221:                        case 'T':       /* Telnet settings */
        !          1222:                                switch(toupper(*(arg++))) {
        !          1223:                                        case '-':       
        !          1224:                                                run_bbs=FALSE;
        !          1225:                                                break;
        !          1226:                                        case 'D': /* debug output */
        !          1227:                                                bbs_startup.options|=BBS_OPT_DEBUG_TELNET;
        !          1228:                                                break;
        !          1229:                                        case 'A': /* Auto-logon via IP */
        !          1230:                                                bbs_startup.options|=BBS_OPT_AUTO_LOGON;
        !          1231:                                                break;
        !          1232:                                        case 'Q': /* No QWK events */
        !          1233:                                                bbs_startup.options|=BBS_OPT_NO_QWK_EVENTS;
        !          1234:                                                break;
        !          1235:                                        case 'C': /* Sysop available for chat */
        !          1236:                                                bbs_startup.options|=BBS_OPT_SYSOP_AVAILABLE;
        !          1237:                                                break;
        !          1238:                                        case 'O': /* Set options */
        !          1239:                                                bbs_startup.options=strtoul(arg,NULL,0);
        !          1240:                                                break;
        !          1241:                                        case 'P':
        !          1242:                                                bbs_startup.telnet_port=atoi(arg);
        !          1243:                                                break;
        !          1244:                                        case 'F':
        !          1245:                                                bbs_startup.first_node=atoi(arg);
        !          1246:                                                break;
        !          1247:                                        case 'L':
        !          1248:                                                bbs_startup.last_node=atoi(arg);
        !          1249:                                                break;
        !          1250:                                        default:
        !          1251:                                                show_usage(argv[0]);
        !          1252:                                                return(1);
        !          1253:                                }
        !          1254:                                break;
        !          1255:                        case 'R':       /* RLogin */
        !          1256:                                bbs_startup.options|=BBS_OPT_ALLOW_RLOGIN;
        !          1257:                                switch(toupper(*(arg++))) {
        !          1258:                                        case 'P':
        !          1259:                                                bbs_startup.rlogin_port=atoi(arg);
        !          1260:                                                break;
        !          1261:                                        case '2':
        !          1262:                                                bbs_startup.options|=BBS_OPT_USE_2ND_RLOGIN;
        !          1263:                                                break;
        !          1264:                                        default:
        !          1265:                                                show_usage(argv[0]);
        !          1266:                                                return(1);
        !          1267:                                }
        !          1268:                                break;
        !          1269:                        case 'F':       /* FTP */
        !          1270:                                switch(toupper(*(arg++))) {
        !          1271:                                        case '-':       
        !          1272:                                                run_ftp=FALSE;
        !          1273:                                                break;
        !          1274:                                        case 'P':
        !          1275:                                                ftp_startup.port=atoi(arg);
        !          1276:                                                break;
        !          1277:                                        case 'O': /* Set options */
        !          1278:                                                ftp_startup.options=strtoul(arg,NULL,0);
        !          1279:                                                break;
        !          1280:                                        default:
        !          1281:                                                show_usage(argv[0]);
        !          1282:                                                return(1);
        !          1283:                                }
        !          1284:                                break;
        !          1285:                        case 'M':       /* Mail */
        !          1286:                                switch(toupper(*(arg++))) {
        !          1287:                                        case '-':
        !          1288:                                                run_mail=FALSE;
        !          1289:                                                break;
        !          1290:                                        case 'O': /* Set options */
        !          1291:                                                mail_startup.options=strtoul(arg,NULL,0);
        !          1292:                                                break;
        !          1293:                                        case 'S':       /* SMTP/SendMail */
        !          1294:                                                if(isdigit(*arg)) {
        !          1295:                                                        mail_startup.smtp_port=atoi(arg);
        !          1296:                                                        break;
        !          1297:                                                }
        !          1298:                                                switch(toupper(*(arg++))) {
        !          1299:                                                        case '-':
        !          1300:                                                                mail_startup.options|=MAIL_OPT_NO_SENDMAIL;
        !          1301:                                                                break;
        !          1302:                                                        default:
        !          1303:                                                                show_usage(argv[0]);
        !          1304:                                                                return(1);
        !          1305:                                                }
        !          1306:                                                break;
        !          1307:                                        case 'P':       /* POP3 */
        !          1308:                                                if(isdigit(*arg)) {
        !          1309:                                                        mail_startup.pop3_port=atoi(arg);
        !          1310:                                                        break;
        !          1311:                                                }
        !          1312:                                                switch(toupper(*(arg++))) {
        !          1313:                                                        case '-':
        !          1314:                                                                mail_startup.options&=~MAIL_OPT_ALLOW_POP3;
        !          1315:                                                                break;
        !          1316:                                                        default:
        !          1317:                                                                show_usage(argv[0]);
        !          1318:                                                                return(1);
        !          1319:                                                }
        !          1320:                                                break;
        !          1321:                                        case 'R':       /* Relay */
        !          1322:                                                mail_startup.options|=MAIL_OPT_RELAY_TX;
        !          1323:                                                p=strchr(arg,':');      /* port specified */
        !          1324:                                                if(p!=NULL) {
        !          1325:                                                        *p=0;
        !          1326:                                                        mail_startup.relay_port=atoi(p+1);
        !          1327:                                                }
        !          1328:                                                SAFECOPY(mail_startup.relay_server,arg);
        !          1329:                                                break;
        !          1330:                                        case 'D':       /* DNS Server */
        !          1331:                                                SAFECOPY(mail_startup.dns_server,arg);
        !          1332:                                                break;
        !          1333:                                        case 'A':
        !          1334:                                                mail_startup.options|=MAIL_OPT_ALLOW_RELAY;
        !          1335:                                                break;
        !          1336:                                        default:
        !          1337:                                                show_usage(argv[0]);
        !          1338:                                                return(1);
        !          1339:                                }
        !          1340:                                break;
        !          1341:                        case 'S':       /* Services */
        !          1342:                                switch(toupper(*(arg++))) {
        !          1343:                                        case '-':
        !          1344:                                                run_services=FALSE;
        !          1345:                                                break;
        !          1346:                                        case 'O': /* Set options */
        !          1347:                                                services_startup.options=strtoul(arg,NULL,0);
        !          1348:                                                break;
        !          1349:                                        default:
        !          1350:                                                show_usage(argv[0]);
        !          1351:                                                return(1);
        !          1352:                                }
        !          1353:                                break;
        !          1354:                        case 'G':       /* GET */
        !          1355:                                switch(toupper(*(arg++))) {
        !          1356:                                        case 'I': /* Identity */
        !          1357:                                                bbs_startup.options|=BBS_OPT_GET_IDENT;
        !          1358:                                                ftp_startup.options|=BBS_OPT_GET_IDENT;
        !          1359:                                                mail_startup.options|=BBS_OPT_GET_IDENT;
        !          1360:                                                services_startup.options|=BBS_OPT_GET_IDENT;
        !          1361:                                                break;
        !          1362:                                        default:
        !          1363:                                                show_usage(argv[0]);
        !          1364:                                                return(1);
        !          1365:                                }
        !          1366:                                break;
        !          1367:                        case 'H':       /* Host */
        !          1368:                                switch(toupper(*(arg++))) {
        !          1369:                                        case 'N':       /* Name */
        !          1370:                                                if(*arg) {
        !          1371:                                                        SAFECOPY(bbs_startup.host_name,arg);
        !          1372:                                                        SAFECOPY(ftp_startup.host_name,arg);
        !          1373:                                                        SAFECOPY(mail_startup.host_name,arg);
        !          1374:                                                        SAFECOPY(services_startup.host_name,arg);
        !          1375:                                                } else {
        !          1376:                                                        SAFECOPY(bbs_startup.host_name,host_name);
        !          1377:                                                        SAFECOPY(ftp_startup.host_name,host_name);
        !          1378:                                                        SAFECOPY(mail_startup.host_name,host_name);
        !          1379:                                                        SAFECOPY(services_startup.host_name,host_name);
        !          1380:                                                }
        !          1381:                                                printf("Setting hostname: %s\n",bbs_startup.host_name);
        !          1382:                                                break;
        !          1383:                                        default:
        !          1384:                                                show_usage(argv[0]);
        !          1385:                                                return(1);
        !          1386:                                }
        !          1387:                                break;
        !          1388:                        case 'U':       /* runtime UID */
        !          1389:                                switch(toupper(*(arg++))) {
        !          1390:                                        case 'N': /* username */
        !          1391: #ifdef __unix__
        !          1392:                                                if(strlen(arg) > 1)
        !          1393:                                                {
        !          1394:                                                        SAFECOPY(new_uid_name,arg);
        !          1395:                                                }
        !          1396: #endif                 
        !          1397:                                                break;
        !          1398:                                        case 'G': /* groupname */
        !          1399: #ifdef __unix__
        !          1400:                                                if(strlen(arg) > 1)
        !          1401:                                                {
        !          1402:                                                        SAFECOPY(new_gid_name,arg);
        !          1403:                                                }
        !          1404: #endif                 
        !          1405:                                                break;
        !          1406:                                        default:
        !          1407:                                                show_usage(argv[0]);
        !          1408:                                                return(1);
        !          1409:                                }
        !          1410:                                break;
        !          1411:                        case 'N':       /* No */
        !          1412:                                switch(toupper(*(arg++))) {
        !          1413:                                        case 'F':       /* FTP Server */
        !          1414:                                                run_ftp=FALSE;
        !          1415:                                                break;
        !          1416:                                        case 'M':       /* Mail Server */
        !          1417:                                                run_mail=FALSE;
        !          1418:                                                break;
        !          1419:                                        case 'S':       /* Services */
        !          1420:                                                run_services=FALSE;
        !          1421:                                                break;
        !          1422:                                        case 'T':       /* Telnet */
        !          1423:                                                run_bbs=FALSE;
        !          1424:                                                break;
        !          1425:                                        case 'E': /* No Events */
        !          1426:                                                bbs_startup.options             |=BBS_OPT_NO_EVENTS;
        !          1427:                                                break;
        !          1428:                                        case 'Q': /* No QWK events */
        !          1429:                                                bbs_startup.options             |=BBS_OPT_NO_QWK_EVENTS;
        !          1430:                                                break;
        !          1431:                                        case 'H':       /* Hostname lookup */
        !          1432:                                                bbs_startup.options             |=BBS_OPT_NO_HOST_LOOKUP;
        !          1433:                                                ftp_startup.options             |=BBS_OPT_NO_HOST_LOOKUP;
        !          1434:                                                mail_startup.options    |=BBS_OPT_NO_HOST_LOOKUP;
        !          1435:                                                services_startup.options|=BBS_OPT_NO_HOST_LOOKUP;
        !          1436:                                                break;
        !          1437:                                        case 'J':       /* JavaScript */
        !          1438:                                                bbs_startup.options             |=BBS_OPT_NO_JAVASCRIPT;
        !          1439:                                                ftp_startup.options             |=BBS_OPT_NO_JAVASCRIPT;
        !          1440:                                                mail_startup.options    |=BBS_OPT_NO_JAVASCRIPT;
        !          1441:                                                services_startup.options|=BBS_OPT_NO_JAVASCRIPT;
        !          1442:                                                break;
        !          1443:                                        case 'I':       /* no .ini file */
        !          1444:                                                break;
        !          1445:                                        case 'D':
        !          1446: #if defined(__unix__)
        !          1447:                                                is_daemon=FALSE;
1.1       root     1448: #endif
1.1.1.2 ! root     1449:                                                break;
        !          1450:                                        default:
        !          1451:                                                show_usage(argv[0]);
        !          1452:                                                return(1);
        !          1453:                                }
        !          1454:                                break;
        !          1455:                        case 'L':       /* Local */
        !          1456:                                switch(toupper(*(arg++))) {
        !          1457:                                        case 'T': /* timezone */
        !          1458:                                                bbs_startup.options             |=BBS_OPT_LOCAL_TIMEZONE;
        !          1459:                                                ftp_startup.options             |=BBS_OPT_LOCAL_TIMEZONE;
        !          1460:                                                mail_startup.options    |=BBS_OPT_LOCAL_TIMEZONE;
        !          1461:                                                services_startup.options|=BBS_OPT_LOCAL_TIMEZONE;
        !          1462:                                                break;
        !          1463:                                        default:
        !          1464:                                                show_usage(argv[0]);
        !          1465:                                                return(1);
        !          1466:                                }
1.1       root     1467:                                break;
1.1.1.2 ! root     1468: 
        !          1469:                        default:
        !          1470:                                show_usage(argv[0]);
        !          1471:                                return(1);
        !          1472:                }
        !          1473:        }
        !          1474: 
        !          1475:        /* Read in configuration files */
        !          1476:     memset(&scfg,0,sizeof(scfg));
        !          1477:     SAFECOPY(scfg.ctrl_dir,bbs_startup.ctrl_dir);
        !          1478: 
        !          1479:        if(chdir(scfg.ctrl_dir)!=0)
        !          1480:                lprintf(LOG_ERR,"!ERROR %d changing directory to: %s", errno, scfg.ctrl_dir);
        !          1481: 
        !          1482:     scfg.size=sizeof(scfg);
        !          1483:        SAFECOPY(error,UNKNOWN_LOAD_ERROR);
        !          1484:        lprintf(LOG_INFO,"Loading configuration files from %s", scfg.ctrl_dir);
        !          1485:        if(!load_cfg(&scfg, NULL /* text.dat */, TRUE /* prep */, error)) {
        !          1486:                lprintf(LOG_ERR,"!ERROR Loading Configuration Files: %s", error);
        !          1487:         return(-1);
        !          1488:     }
        !          1489: 
        !          1490: /* Daemonize / Set uid/gid */
        !          1491: #ifdef __unix__
        !          1492: 
        !          1493:        switch(toupper(daemon_type[0])) {
        !          1494:                case '0':
        !          1495:                        openlog(SBBS_LOG_NAME,LOG_CONS,LOG_LOCAL0);
        !          1496:                        break;
        !          1497:                case '1':
        !          1498:                        openlog(SBBS_LOG_NAME,LOG_CONS,LOG_LOCAL1);
        !          1499:                        break;
        !          1500:                case '2':
        !          1501:                        openlog(SBBS_LOG_NAME,LOG_CONS,LOG_LOCAL2);
        !          1502:                        break;
        !          1503:                case '3':
        !          1504:                        openlog(SBBS_LOG_NAME,LOG_CONS,LOG_LOCAL3);
        !          1505:                        break;
        !          1506:                case '4':
        !          1507:                        openlog(SBBS_LOG_NAME,LOG_CONS,LOG_LOCAL4);
        !          1508:                        break;
        !          1509:                case '5':
        !          1510:                        openlog(SBBS_LOG_NAME,LOG_CONS,LOG_LOCAL5);
        !          1511:                        break;
        !          1512:                case '6':
        !          1513:                        openlog(SBBS_LOG_NAME,LOG_CONS,LOG_LOCAL6);
        !          1514:                        break;
        !          1515:                case '7':
        !          1516:                        openlog(SBBS_LOG_NAME,LOG_CONS,LOG_LOCAL7);
        !          1517:                        break;
        !          1518:                case 'F':       /* this is legacy */
        !          1519:                case 'S':
        !          1520:                        /* Use standard facilities */
        !          1521:                        openlog(SBBS_LOG_NAME,LOG_CONS,LOG_USER);
        !          1522:                        std_facilities = TRUE;
        !          1523:                        break;
        !          1524:                default:
        !          1525:                        openlog(SBBS_LOG_NAME,LOG_CONS,LOG_USER);
        !          1526:        }
        !          1527:        if(is_daemon) {
        !          1528: 
        !          1529:                lprintf(LOG_INFO,"Running as daemon");
        !          1530:                if(daemon(TRUE,FALSE))  { /* Daemonize, DON'T switch to / and DO close descriptors */
        !          1531:                        lprintf(LOG_ERR,"!ERROR %d running as daemon",errno);
        !          1532:                        is_daemon=FALSE;
        !          1533:                }
        !          1534: 
        !          1535:                /* Open here to use startup permissions to create the file */
        !          1536:                pidf=fopen(SBBS_PID_FILE,"w");
        !          1537:        }
        !          1538:        old_uid = getuid();
        !          1539:        if((pw_entry=getpwnam(new_uid_name))!=0)
        !          1540:        {
        !          1541:                new_uid=pw_entry->pw_uid;
        !          1542:                new_gid=pw_entry->pw_gid;
        !          1543:        }
        !          1544:        else  {
        !          1545:                new_uid=getuid();
        !          1546:                new_gid=getgid();
        !          1547:        }
        !          1548:        old_gid = getgid();
        !          1549:        if((gr_entry=getgrnam(new_gid_name))!=0)
        !          1550:                new_gid=gr_entry->gr_gid;
        !          1551:        
        !          1552: #endif
        !          1553: 
        !          1554:        /* Install Ctrl-C/Break signal handler here */
        !          1555: #if defined(_WIN32)
        !          1556:        SetConsoleCtrlHandler(ControlHandler, TRUE /* Add */);
        !          1557: #elif defined(__unix__)
        !          1558:        /* Set up blocked signals */
        !          1559:        sigemptyset(&sigs);
        !          1560:        sigaddset(&sigs,SIGINT);
        !          1561:        sigaddset(&sigs,SIGQUIT);
        !          1562:        sigaddset(&sigs,SIGABRT);
        !          1563:        sigaddset(&sigs,SIGTERM);
        !          1564:        sigaddset(&sigs,SIGHUP);
        !          1565:        sigaddset(&sigs,SIGALRM);
        !          1566:        /* sigaddset(&sigs,SIGPIPE); */
        !          1567:        pthread_sigmask(SIG_BLOCK,&sigs,NULL);
        !          1568:     signal(SIGPIPE, SIG_IGN);       /* Ignore "Broken Pipe" signal (Also used for broken socket etc.) */
        !          1569:     signal(SIGALRM, SIG_IGN);       /* Ignore "Alarm" signal */
        !          1570:        _beginthread((void(*)(void*))handle_sigs,0,NULL);
        !          1571:        if(new_uid_name[0]!=0) {        /*  check the user arg, if we have uid 0 */
        !          1572:                /* Can't recycle servers (re-bind ports) as non-root user */
        !          1573:                /* If DONT_BLAME_SYNCHRONET is set, keeps root credentials laying around */
        !          1574: #if !defined(DONT_BLAME_SYNCHRONET) && !defined(_THREAD_SUID_BROKEN)
        !          1575:                if(bbs_startup.telnet_port < IPPORT_RESERVED
        !          1576:                        || (bbs_startup.options & BBS_OPT_ALLOW_RLOGIN
        !          1577:                                && bbs_startup.rlogin_port < IPPORT_RESERVED))
        !          1578:                        bbs_startup.options|=BBS_OPT_NO_RECYCLE;
        !          1579:                if(ftp_startup.port < IPPORT_RESERVED)
        !          1580:                        ftp_startup.options|=FTP_OPT_NO_RECYCLE;
        !          1581:                if(web_startup.port < IPPORT_RESERVED)
        !          1582:                        web_startup.options|=BBS_OPT_NO_RECYCLE;
        !          1583:                if((mail_startup.options & MAIL_OPT_ALLOW_POP3
        !          1584:                        && mail_startup.pop3_port < IPPORT_RESERVED)
        !          1585:                        || mail_startup.smtp_port < IPPORT_RESERVED)
        !          1586:                        mail_startup.options|=MAIL_OPT_NO_RECYCLE;
        !          1587:                /* Perhaps a BBS_OPT_NO_RECYCLE_LOW option? */
        !          1588:                services_startup.options|=BBS_OPT_NO_RECYCLE;
        !          1589: #endif
        !          1590:        }
        !          1591: #endif
        !          1592: 
        !          1593:        if(run_bbs)
        !          1594:                _beginthread((void(*)(void*))bbs_thread,0,&bbs_startup);
        !          1595:        if(run_ftp)
        !          1596:                _beginthread((void(*)(void*))ftp_server,0,&ftp_startup);
        !          1597:        if(run_mail)
        !          1598:                _beginthread((void(*)(void*))mail_server,0,&mail_startup);
        !          1599: #ifdef NO_SERVICES
        !          1600:        run_services=FALSE;
        !          1601: #else
        !          1602:        if(run_services)
        !          1603:                _beginthread((void(*)(void*))services_thread,0,&services_startup);
        !          1604: #endif
        !          1605: #ifdef NO_WEB_SERVER
        !          1606:        run_web=FALSE;
        !          1607: #else
        !          1608:        if(run_web)
        !          1609:                _beginthread((void(*)(void*))web_server,0,&web_startup);
        !          1610: #endif
        !          1611: 
        !          1612: #ifdef __unix__
        !          1613:        if(getuid())  { /*  are we running as a normal user?  */
        !          1614:                lprintf(LOG_WARNING
        !          1615:                        ,"!Started as non-root user.  Cannot bind() to ports below %u.", IPPORT_RESERVED);
        !          1616:        }
        !          1617:        
        !          1618:        else if(new_uid_name[0]==0)   /*  check the user arg, if we have uid 0 */
        !          1619:                lputs(LOG_WARNING,"WARNING: No user account specified, running as root.");
        !          1620:        
        !          1621:        else 
        !          1622:        {
        !          1623:                lputs(LOG_INFO,"Waiting for child threads to bind ports...");
        !          1624:                while((run_bbs && !(bbs_running || bbs_stopped)) 
        !          1625:                                || (run_ftp && !(ftp_running || ftp_stopped)) 
        !          1626:                                || (run_web && !(web_running || web_stopped)) 
        !          1627:                                || (run_mail && !(mail_running || mail_stopped)) 
        !          1628:                                || (run_services && !(services_running || services_stopped)))  {
        !          1629:                        mswait(1000);
        !          1630:                        if(run_bbs && !(bbs_running || bbs_stopped))
        !          1631:                                lputs(LOG_INFO,"Waiting for BBS thread");
        !          1632:                        if(run_web && !(web_running || web_stopped))
        !          1633:                                lputs(LOG_INFO,"Waiting for Web thread");
        !          1634:                        if(run_ftp && !(ftp_running || ftp_stopped))
        !          1635:                                lputs(LOG_INFO,"Waiting for FTP thread");
        !          1636:                        if(run_mail && !(mail_running || mail_stopped))
        !          1637:                                lputs(LOG_INFO,"Waiting for Mail thread");
        !          1638:                        if(run_services && !(services_running || services_stopped))
        !          1639:                                lputs(LOG_INFO,"Waiting for Services thread");
        !          1640:                }
        !          1641: 
        !          1642:                if(!do_setuid(FALSE))
        !          1643:                                /* actually try to change the uid of this process */
        !          1644:                        lputs(LOG_ERR,"!Setting new user_id failed!  (Does the user exist?)");
        !          1645:        
        !          1646:                else {
        !          1647:                        char str[256];
        !          1648:                        struct passwd *pwent;
        !          1649: 
        !          1650:                        pwent=getpwnam(new_uid_name);
        !          1651:                        if(pwent != NULL) {
        !          1652:                                char    uenv[128];
        !          1653:                                char    henv[MAX_PATH+6];
        !          1654:                                sprintf(uenv,"USER=%s",pwent->pw_name);
        !          1655:                                putenv(uenv);
        !          1656:                                sprintf(henv,"HOME=%s",pwent->pw_dir);
        !          1657:                                putenv(henv);
        !          1658:                        }
        !          1659:                        if(new_gid_name[0]) {
        !          1660:                                char    genv[128];
        !          1661:                                sprintf(genv,"GROUP=%s",new_gid_name);
        !          1662:                                putenv(genv);
        !          1663:                        }
        !          1664:                        lprintf(LOG_INFO,"Successfully changed user_id to %s", new_uid_name);
1.1       root     1665:                }
                   1666:        }
                   1667: 
1.1.1.2 ! root     1668:        if(!isatty(fileno(stdin)))                      /* redirected */
        !          1669:                select(0,NULL,NULL,NULL,NULL);  /* Sleep forever - Should this just exit the thread? */
        !          1670:        else                                                            /* interactive */
        !          1671: #endif
        !          1672:        {
        !          1673:                prompt = "[Threads: %d  Sockets: %d  Clients: %d  Served: %lu] (?=Help): ";
        !          1674:                lputs(LOG_INFO,NULL);   /* display prompt */
        !          1675: 
        !          1676:                while(!terminated) {
        !          1677: #ifdef __unix__
        !          1678:                        if(!isatty(STDIN_FILENO))  {            /* Controlling terminal has left us *sniff* */
        !          1679:                                int fd;
        !          1680:                                openlog(SBBS_LOG_NAME,LOG_CONS,LOG_USER);
        !          1681:                        if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
        !          1682:                                (void)dup2(fd, STDIN_FILENO);
        !          1683:                                (void)dup2(fd, STDOUT_FILENO);
        !          1684:                                (void)dup2(fd, STDERR_FILENO);
        !          1685:                                if (fd > 2)
        !          1686:                                (void)close(fd);
        !          1687:                        }
        !          1688:                                is_daemon=TRUE;
        !          1689:                                lputs(LOG_WARNING, "STDIN is not a tty anymore... switching to syslog logging");
        !          1690:                                select(0,NULL,NULL,NULL,NULL);  /* Sleep forever - Should this just exit the thread? */
        !          1691:                        }
        !          1692: #endif
1.1       root     1693: 
1.1.1.2 ! root     1694:                        if(!kbhit()) {
        !          1695:                                YIELD();
        !          1696:                                continue;
        !          1697:                        }
        !          1698:                        ch=getch();
        !          1699:                        printf("%c\n",ch);
        !          1700:                        switch(ch) {
        !          1701:                                case 'q':
        !          1702:                                        terminated=TRUE;
        !          1703:                                        break;
        !          1704:                                case 'w':       /* who's online */
        !          1705:                                        printf("\nNodes in use:\n");
        !          1706:                                case 'n':       /* nodelist */
        !          1707:                                        printf("\n");
        !          1708:                                        for(i=1;i<=scfg.sys_nodes;i++) {
        !          1709:                                                getnodedat(&scfg,i,&node,NULL /* file */);
        !          1710:                                                if(ch=='w' && node.status!=NODE_INUSE && node.status!=NODE_QUIET)
        !          1711:                                                        continue;
        !          1712:                                                printnodedat(&scfg, i,&node);
        !          1713:                                        }
        !          1714:                                        break;
        !          1715:                                case 'l':       /* lock node */
        !          1716:                                case 'd':       /* down node */
        !          1717:                                case 'i':       /* interrupt node */
        !          1718:                                        printf("\nNode number: ");
        !          1719:                                        if((n=atoi(fgets(str,sizeof(str),stdin)))<1)
        !          1720:                                                break;
        !          1721:                                        fflush(stdin);
        !          1722:                                        printf("\n");
        !          1723:                                        if((i=getnodedat(&scfg,n,&node,&file))!=0) {
        !          1724:                                                printf("!Error %d getting node %d data\n",i,n);
        !          1725:                                                break;
        !          1726:                                        }
        !          1727:                                        switch(ch) {
        !          1728:                                                case 'l':
        !          1729:                                                        node.misc^=NODE_LOCK;
        !          1730:                                                        break;
        !          1731:                                                case 'd':
        !          1732:                                                        node.misc^=NODE_DOWN;
        !          1733:                                                        break;
        !          1734:                                                case 'i':
        !          1735:                                                        node.misc^=NODE_INTR;
        !          1736:                                                        break;
        !          1737:                                        }
        !          1738:                                        putnodedat(&scfg,n,&node,file);
        !          1739:                                        printnodedat(&scfg,n,&node);
        !          1740:                                        break;
        !          1741:                                case 'r':       /* recycle */
        !          1742:                                case 's':       /* shutdown */
        !          1743:                                case 't':       /* terminate */
        !          1744:                                        printf("BBS, FTP, Web, Mail, Services, or [All] ? ");
        !          1745:                                        switch(toupper(getch())) {
        !          1746:                                                case 'B':
        !          1747:                                                        printf("BBS\n");
        !          1748:                                                        if(ch=='t')
        !          1749:                                                                bbs_terminate();
        !          1750:                                                        else if(ch=='s')
        !          1751:                                                                bbs_startup.shutdown_now=TRUE;
        !          1752:                                                        else
        !          1753:                                                                bbs_startup.recycle_now=TRUE;
        !          1754:                                                        break;
        !          1755:                                                case 'F':
        !          1756:                                                        printf("FTP\n");
        !          1757:                                                        if(ch=='t')
        !          1758:                                                                ftp_terminate();
        !          1759:                                                        else if(ch=='s')
        !          1760:                                                                ftp_startup.shutdown_now=TRUE;
        !          1761:                                                        else
        !          1762:                                                                ftp_startup.recycle_now=TRUE;
        !          1763:                                                        break;
        !          1764:                                                case 'W':
        !          1765:                                                        printf("Web\n");
        !          1766:                                                        if(ch=='t')
        !          1767:                                                                web_terminate();
        !          1768:                                                        else if(ch=='s')
        !          1769:                                                                web_startup.shutdown_now=TRUE;
        !          1770:                                                        else
        !          1771:                                                                web_startup.recycle_now=TRUE;
        !          1772:                                                        break;
        !          1773:                                                case 'M':
        !          1774:                                                        printf("Mail\n");
        !          1775:                                                        if(ch=='t')
        !          1776:                                                                mail_terminate();
        !          1777:                                                        else if(ch=='s')
        !          1778:                                                                mail_startup.shutdown_now=TRUE;
        !          1779:                                                        else
        !          1780:                                                                mail_startup.recycle_now=TRUE;
        !          1781:                                                        break;
        !          1782:                                                case 'S':
        !          1783:                                                        printf("Services\n");
        !          1784:                                                        if(ch=='t')
        !          1785:                                                                services_terminate();
        !          1786:                                                        else if(ch=='s')
        !          1787:                                                                services_startup.shutdown_now=TRUE;
        !          1788:                                                        else
        !          1789:                                                                services_startup.recycle_now=TRUE;
        !          1790:                                                        break;
        !          1791:                                                default:
        !          1792:                                                        printf("All\n");
        !          1793:                                                        if(ch=='t')
        !          1794:                                                                terminate();
        !          1795:                                                        else if(ch=='s') {
        !          1796:                                                                bbs_startup.shutdown_now=TRUE;
        !          1797:                                                                ftp_startup.shutdown_now=TRUE;
        !          1798:                                                                web_startup.shutdown_now=TRUE;
        !          1799:                                                                mail_startup.shutdown_now=TRUE;
        !          1800:                                                                services_startup.shutdown_now=TRUE;
        !          1801:                                                        }
        !          1802:                                                        else {
        !          1803:                                                                bbs_startup.recycle_now=TRUE;
        !          1804:                                                                ftp_startup.recycle_now=TRUE;
        !          1805:                                                                web_startup.recycle_now=TRUE;
        !          1806:                                                                mail_startup.recycle_now=TRUE;
        !          1807:                                                                services_startup.recycle_now=TRUE;                                                      
        !          1808:                                                        }
        !          1809:                                                        break;
        !          1810:                                        }
        !          1811:                                        break;
        !          1812:                                case '!':       /* execute */
        !          1813:                                        printf("Command line: ");
        !          1814:                                        fgets(str,sizeof(str),stdin);
        !          1815:                                        system(str);
        !          1816:                                        break;
        !          1817:                                default:
        !          1818:                                        printf("\nSynchronet Console Version %s%c Help\n\n",VERSION,REVISION);
        !          1819:                                        printf("q   = quit\n");
        !          1820:                                        printf("n   = node list\n");
        !          1821:                                        printf("w   = who's online\n");
        !          1822:                                        printf("l   = lock node (toggle)\n");
        !          1823:                                        printf("d   = down node (toggle)\n");
        !          1824:                                        printf("i   = interrupt node (toggle)\n");
        !          1825:                                        printf("r   = recycle servers (when not in use)\n");
        !          1826:                                        printf("s   = shutdown servers (when not in use)\n");
        !          1827:                                        printf("t   = terminate servers (immediately)\n");
        !          1828:                                        printf("!   = execute external command\n");
        !          1829: #if 0  /* to do */     
        !          1830:                                        printf("c#  = chat with node #\n");
        !          1831:                                        printf("s#  = spy on node #\n");
        !          1832: #endif
        !          1833:                                        break;
        !          1834:                        }
        !          1835:                        lputs(LOG_INFO,"");     /* redisplay prompt */
        !          1836:                }
        !          1837:        }
        !          1838: 
        !          1839:        terminate();
1.1       root     1840: 
                   1841:        /* erase the prompt */
1.1.1.2 ! root     1842:        printf("\r%*s\r",prompt_len,"");
1.1       root     1843: 
                   1844:        return(0);
1.1.1.2 ! root     1845: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.