Annotation of sbbs/src/sbbs3/ctrl/mainformunit.cpp, revision 1.1.1.1

1.1       root        1: /* Synchronet Control Panel (GUI Borland C++ Builder Project for Win32) */
                      2: 
                      3: /* $Id: MainFormUnit.cpp,v 1.157 2006/09/24 19:45:17 deuce Exp $ */
                      4: 
                      5: /****************************************************************************
                      6:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      7:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                      8:  *                                                                                                                                                     *
                      9:  * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html         *
                     10:  *                                                                                                                                                     *
                     11:  * This program is free software; you can redistribute it and/or                       *
                     12:  * modify it under the terms of the GNU General Public License                         *
                     13:  * as published by the Free Software Foundation; either version 2                      *
                     14:  * of the License, or (at your option) any later version.                                      *
                     15:  * See the GNU General Public License for more details: gpl.txt or                     *
                     16:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
                     17:  *                                                                                                                                                     *
                     18:  * Anonymous FTP access to the most recent released source is available at     *
                     19:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     20:  *                                                                                                                                                     *
                     21:  * Anonymous CVS access to the development source and modification history     *
                     22:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     23:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     24:  *     (just hit return, no password is necessary)                                                     *
                     25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     26:  *                                                                                                                                                     *
                     27:  * For Synchronet coding style and modification guidelines, see                                *
                     28:  * http://www.synchro.net/source.html                                                                          *
                     29:  *                                                                                                                                                     *
                     30:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     31:  * format) via e-mail to [email protected]                                                                      *
                     32:  *                                                                                                                                                     *
                     33:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     34:  ****************************************************************************/
                     35: 
                     36: //---------------------------------------------------------------------------
                     37: #include "sbbs.h"           // unixtodstr()
                     38: #include <vcl.h>
                     39: #include <vcl/Registry.hpp>    /* TRegistry */
                     40: #pragma hdrstop
                     41: #include <winsock.h>           // IPPORT_TELNET, INADDR_ANY
                     42: #include <process.h>           // _beginthread()
                     43: #include <io.h>
                     44: #include <stdio.h>
                     45: #include <sys/stat.h>
                     46: #include <sys/locking.h>
                     47: #include <fcntl.h>
                     48: #include <share.h>
                     49: 
                     50: #include "MainFormUnit.h"
                     51: #include "TelnetFormUnit.h"
                     52: #include "EventsFormUnit.h"
                     53: #include "ServicesFormUnit.h"
                     54: #include "FtpFormUnit.h"
                     55: #include "WebFormUnit.h"
                     56: #include "MailFormUnit.h"
                     57: #include "NodeFormUnit.h"
                     58: 
                     59: #include "StatsFormUnit.h"
                     60: #include "ClientFormUnit.h"
                     61: #include "CtrlPathDialogUnit.h"
                     62: #include "TelnetCfgDlgUnit.h"
                     63: #include "MailCfgDlgUnit.h"
                     64: #include "FtpCfgDlgUnit.h"
                     65: #include "WebCfgDlgUnit.h"
                     66: #include "ServicesCfgDlgUnit.h"
                     67: #include "AboutBoxFormUnit.h"
                     68: #include "CodeInputFormUnit.h"
                     69: #include "TextFileEditUnit.h"
                     70: #include "UserListFormUnit.h"
                     71: #include "PropertiesDlgUnit.h"
                     72: #include "ConfigWizardUnit.h"
                     73: #include "PreviewFormUnit.h"
                     74: 
                     75: #include "sbbs_ini.h"          // sbbs_read_ini()
                     76: #include "userdat.h"           // lastuser()
                     77: #include "ntsvcs.h"                    // NTSVC_NAME_*
                     78: 
                     79: //---------------------------------------------------------------------------
                     80: #pragma package(smart_init)
                     81: #pragma link "trayicon"
                     82: #pragma link "Trayicon"
                     83: #pragma resource "*.dfm"
                     84: TMainForm *MainForm;
                     85: 
                     86: #define LOG_TIME_FMT "  m/d  hh:mm:ssa/p"
                     87: 
                     88: /* Service functions are NT-only, must call dynamically :-( */
                     89: typedef WINADVAPI SC_HANDLE (WINAPI *OpenSCManager_t)(LPCTSTR,LPCTSTR,DWORD);
                     90: typedef WINADVAPI SC_HANDLE (WINAPI *OpenService_t)(SC_HANDLE,LPCTSTR,DWORD);
                     91: typedef WINADVAPI BOOL (WINAPI *StartService_t)(SC_HANDLE,DWORD,LPCTSTR*);
                     92: typedef WINADVAPI BOOL (WINAPI *ControlService_t)(SC_HANDLE,DWORD,LPSERVICE_STATUS);
                     93: typedef WINADVAPI BOOL (WINAPI *QueryServiceStatus_t)(SC_HANDLE,LPSERVICE_STATUS);
                     94: typedef WINADVAPI BOOL (WINAPI *QueryServiceConfig_t)(SC_HANDLE,LPQUERY_SERVICE_CONFIG,DWORD,LPDWORD);
                     95: typedef WINADVAPI BOOL (WINAPI *CloseServiceHandle_t)(SC_HANDLE);
                     96: 
                     97: OpenSCManager_t                openSCManager;
                     98: OpenService_t                  openService;
                     99: StartService_t                 startService;
                    100: ControlService_t       controlService;
                    101: QueryServiceStatus_t    queryServiceStatus;
                    102: QueryServiceConfig_t    queryServiceConfig;
                    103: CloseServiceHandle_t   closeServiceHandle;
                    104: 
                    105: SC_HANDLE       hSCManager;
                    106: SC_HANDLE          bbs_svc;
                    107: SC_HANDLE          ftp_svc;
                    108: SC_HANDLE          web_svc;
                    109: SC_HANDLE          mail_svc;
                    110: SC_HANDLE          services_svc;
                    111: SERVICE_STATUS bbs_svc_status;
                    112: SERVICE_STATUS ftp_svc_status;
                    113: SERVICE_STATUS web_svc_status;
                    114: SERVICE_STATUS mail_svc_status;
                    115: SERVICE_STATUS services_svc_status;
                    116: QUERY_SERVICE_CONFIG*  bbs_svc_config;
                    117: DWORD                                  bbs_svc_config_size;
                    118: QUERY_SERVICE_CONFIG*  ftp_svc_config;
                    119: DWORD                                  ftp_svc_config_size;
                    120: QUERY_SERVICE_CONFIG*  web_svc_config;
                    121: DWORD                                  web_svc_config_size;
                    122: QUERY_SERVICE_CONFIG*  mail_svc_config;
                    123: DWORD                                  mail_svc_config_size;
                    124: QUERY_SERVICE_CONFIG*  services_svc_config;
                    125: DWORD                                  services_svc_config_size;
                    126: 
                    127: DWORD  MaxLogLen=20000;
                    128: int     threads=1;
                    129: time_t  initialized=0;
                    130: static str_list_t recycle_semfiles;
                    131: static  str_list_t shutdown_semfiles;
                    132: bool    terminating=false;
                    133: 
                    134: static void thread_up(void* p, BOOL up, BOOL setuid)
                    135: {
                    136:        char str[128];
                    137:        static HANDLE mutex;
                    138: 
                    139:     if(!mutex)
                    140:        mutex=CreateMutex(NULL,false,NULL);
                    141:        WaitForSingleObject(mutex,INFINITE);
                    142:     if(up)
                    143:            threads++;
                    144:     else if(threads>0)
                    145:        threads--;
                    146:     sprintf(str,"Threads: %d",threads);
                    147:     AnsiString Str=AnsiString(str);
                    148:     if(MainForm->StatusBar->Panels->Items[0]->Text!=Str)
                    149:                MainForm->StatusBar->Panels->Items[0]->Text=Str;
                    150:     ReleaseMutex(mutex);
                    151: }
                    152: 
                    153: int sockets=0;
                    154: 
                    155: void socket_open(void* p, BOOL open)
                    156: {
                    157:        char    str[128];
                    158:        static HANDLE mutex;
                    159: 
                    160:     if(!mutex)
                    161:        mutex=CreateMutex(NULL,false,NULL);
                    162:        WaitForSingleObject(mutex,INFINITE);
                    163:     if(open)
                    164:            sockets++;
                    165:     else if(sockets>0)
                    166:        sockets--;
                    167:     sprintf(str,"Sockets: %d",sockets);
                    168:     AnsiString Str=AnsiString(str);
                    169:     if(MainForm->StatusBar->Panels->Items[1]->Text!=Str)
                    170:                MainForm->StatusBar->Panels->Items[1]->Text=Str;
                    171:     ReleaseMutex(mutex);
                    172: }
                    173: 
                    174: int clients=0;
                    175: int total_clients=0;
                    176: 
                    177: static void client_add(void* p, BOOL add)
                    178: {
                    179:        char    str[128];
                    180: 
                    181:     if(add) {
                    182:            clients++;
                    183:         total_clients++;
                    184:     } else if(clients>0)
                    185:        clients--;
                    186:     sprintf(str,"Clients: %d",clients);
                    187:     AnsiString Str=AnsiString(str);
                    188:     if(MainForm->StatusBar->Panels->Items[2]->Text!=Str)
                    189:                MainForm->StatusBar->Panels->Items[2]->Text=Str;
                    190: 
                    191:     sprintf(str,"Served: %d",total_clients);
                    192:     Str=AnsiString(str);
                    193:     if(MainForm->StatusBar->Panels->Items[3]->Text!=Str)
                    194:                MainForm->StatusBar->Panels->Items[3]->Text=Str;
                    195: }
                    196: 
                    197: static void client_on(void* p, BOOL on, int sock, client_t* client, BOOL update)
                    198: {
                    199:     char    str[128];
                    200:     int     i,j;
                    201:     time_t  t;
                    202:        static  HANDLE mutex;
                    203:     TListItem*  Item;
                    204: 
                    205:     if(!mutex)
                    206:        mutex=CreateMutex(NULL,false,NULL);
                    207:        WaitForSingleObject(mutex,INFINITE);
                    208:     WaitForSingleObject(ClientForm->ListMutex,INFINITE);
                    209: 
                    210:     /* Search for exising entry for this socket */
                    211:     for(i=0;i<ClientForm->ListView->Items->Count;i++) {
                    212:         if(ClientForm->ListView->Items->Item[i]->Caption.ToIntDef(0)==sock)
                    213:             break;
                    214:     }
                    215:     if(i>=ClientForm->ListView->Items->Count) {
                    216:                if(update)      { /* Can't update a non-existing entry */
                    217:                        ReleaseMutex(mutex);
                    218:                        ReleaseMutex(ClientForm->ListMutex);
                    219:                        return;
                    220:                }
                    221:         i=-1;
                    222:        }
                    223: 
                    224:     if(on) {
                    225:            if(!update)
                    226:                client_add(NULL, TRUE);
                    227:     } else { // Off
                    228:         client_add(NULL, FALSE);
                    229:         if(i>=0)
                    230:             ClientForm->ListView->Items->Delete(i);
                    231:         ReleaseMutex(mutex);
                    232:         ReleaseMutex(ClientForm->ListMutex);
                    233:         return;
                    234:     }
                    235:     if(client!=NULL && client->size==sizeof(client_t)) {
                    236:         if(i>=0) {
                    237:             Item=ClientForm->ListView->Items->Item[i];
                    238:         } else {
                    239:             Item=ClientForm->ListView->Items->Add();
                    240:             Item->Data=(void*)client->time;
                    241:             Item->Caption=sock;
                    242:         }
                    243:         Item->SubItems->Clear();
                    244:         Item->SubItems->Add(client->protocol);
                    245:         Item->SubItems->Add(client->user);
                    246:         Item->SubItems->Add(client->addr);
                    247:         Item->SubItems->Add(client->host);
                    248:         Item->SubItems->Add(client->port);
                    249:         t=time(NULL)-(time_t)Item->Data;
                    250:         sprintf(str,"%d:%02d",t/60,t%60);
                    251:         Item->SubItems->Add(str);
                    252:     }
                    253:     ReleaseMutex(mutex);
                    254:     ReleaseMutex(ClientForm->ListMutex);
                    255: }
                    256: 
                    257: static int bbs_lputs(void* p, int level, char *str)
                    258: {
                    259:        static HANDLE mutex;
                    260: 
                    261:     if(!mutex)
                    262:        mutex=CreateMutex(NULL,false,NULL);
                    263:        WaitForSingleObject(mutex,INFINITE);
                    264: 
                    265:     while(MaxLogLen && TelnetForm->Log->Text.Length()>=MaxLogLen)
                    266:         TelnetForm->Log->Lines->Delete(0);
                    267: 
                    268:     AnsiString Line=Now().FormatString(LOG_TIME_FMT)+"  ";
                    269:     Line+=AnsiString(str).Trim();
                    270:        TelnetForm->Log->Lines->Add(Line);
                    271:     ReleaseMutex(mutex);
                    272:     return(Line.Length());
                    273: }
                    274: 
                    275: static void bbs_status(void* p, char *str)
                    276: {
                    277:        static HANDLE mutex;
                    278: 
                    279:     if(!mutex)
                    280:        mutex=CreateMutex(NULL,false,NULL);
                    281:        WaitForSingleObject(mutex,INFINITE);
                    282: 
                    283:        TelnetForm->Status->Caption=AnsiString(str);
                    284: 
                    285:     ReleaseMutex(mutex);
                    286: }
                    287: 
                    288: static void bbs_clients(void* p, int clients)
                    289: {
                    290:        static HANDLE mutex;
                    291:     static save_clients;
                    292: 
                    293:     save_clients=clients;
                    294: 
                    295:     if(!mutex)
                    296:        mutex=CreateMutex(NULL,false,NULL);
                    297:        WaitForSingleObject(mutex,INFINITE);
                    298: 
                    299:     TelnetForm->ProgressBar->Max
                    300:        =(MainForm->bbs_startup.last_node
                    301:            -MainForm->bbs_startup.first_node)+1;
                    302:        TelnetForm->ProgressBar->Position=clients;
                    303: 
                    304:     ReleaseMutex(mutex);
                    305: }
                    306: 
                    307: static void bbs_terminated(void* p, int code)
                    308: {
                    309:        Screen->Cursor=crDefault;
                    310:        MainForm->TelnetStart->Enabled=true;
                    311:        MainForm->TelnetStop->Enabled=false;
                    312:        MainForm->TelnetRecycle->Enabled=false;    
                    313:     Application->ProcessMessages();
                    314: }
                    315: static void bbs_started(void* p)
                    316: {
                    317:        Screen->Cursor=crDefault;
                    318:        MainForm->TelnetStart->Enabled=false;
                    319:     MainForm->TelnetStop->Enabled=true;
                    320:     MainForm->TelnetRecycle->Enabled=true;    
                    321:     Application->ProcessMessages();
                    322: }
                    323: static void bbs_start(void)
                    324: {
                    325:        Screen->Cursor=crAppStart;
                    326:     bbs_status(NULL,"Starting");
                    327: 
                    328:     FILE* fp=fopen(MainForm->ini_file,"r");
                    329:     sbbs_read_ini(fp
                    330:         ,&MainForm->global
                    331:         ,NULL   ,&MainForm->bbs_startup
                    332:         ,NULL   ,NULL
                    333:         ,NULL   ,NULL
                    334:         ,NULL   ,NULL
                    335:         ,NULL   ,NULL
                    336:         );
                    337:     if(fp!=NULL)
                    338:         fclose(fp);
                    339: 
                    340:        _beginthread((void(*)(void*))bbs_thread,0,&MainForm->bbs_startup);
                    341:     Application->ProcessMessages();
                    342: }
                    343: 
                    344: static int event_lputs(int level, char *str)
                    345: {
                    346:        static HANDLE mutex;
                    347: 
                    348:     if(!mutex)
                    349:        mutex=CreateMutex(NULL,false,NULL);
                    350:        WaitForSingleObject(mutex,INFINITE);
                    351: 
                    352:     while(MaxLogLen && EventsForm->Log->Text.Length()>=MaxLogLen)
                    353:         EventsForm->Log->Lines->Delete(0);
                    354: 
                    355:     AnsiString Line=Now().FormatString(LOG_TIME_FMT)+"  ";
                    356:     Line+=AnsiString(str).Trim();
                    357:        EventsForm->Log->Lines->Add(Line);
                    358:     ReleaseMutex(mutex);
                    359:     return(Line.Length());
                    360: }
                    361: 
                    362: static int service_lputs(void* p, int level, char *str)
                    363: {
                    364:        static HANDLE mutex;
                    365: 
                    366:     if(!mutex)
                    367:        mutex=CreateMutex(NULL,false,NULL);
                    368:        WaitForSingleObject(mutex,INFINITE);
                    369: 
                    370:     while(MaxLogLen && ServicesForm->Log->Text.Length()>=MaxLogLen)
                    371:         ServicesForm->Log->Lines->Delete(0);
                    372: 
                    373:     AnsiString Line=Now().FormatString(LOG_TIME_FMT)+"  ";
                    374:     Line+=AnsiString(str).Trim();
                    375:        ServicesForm->Log->Lines->Add(Line);
                    376:     ReleaseMutex(mutex);
                    377:     return(Line.Length());
                    378: }
                    379: 
                    380: static void services_status(void* p, char *str)
                    381: {
                    382:        static HANDLE mutex;
                    383: 
                    384:     if(!mutex)
                    385:        mutex=CreateMutex(NULL,false,NULL);
                    386:        WaitForSingleObject(mutex,INFINITE);
                    387: 
                    388:        ServicesForm->Status->Caption=AnsiString(str);
                    389: 
                    390:     ReleaseMutex(mutex);
                    391: }
                    392: 
                    393: static void services_terminated(void* p, int code)
                    394: {
                    395:        Screen->Cursor=crDefault;
                    396:        MainForm->ServicesStart->Enabled=true;
                    397:        MainForm->ServicesStop->Enabled=false;
                    398:     MainForm->ServicesRecycle->Enabled=false;
                    399:     Application->ProcessMessages();
                    400: }
                    401: static void services_started(void* p)
                    402: {
                    403:        Screen->Cursor=crDefault;
                    404:        MainForm->ServicesStart->Enabled=false;
                    405:     MainForm->ServicesStop->Enabled=true;
                    406:     MainForm->ServicesRecycle->Enabled=true;
                    407:     Application->ProcessMessages();
                    408: }
                    409: 
                    410: static void services_clients(void* p, int clients)
                    411: {
                    412: }
                    413: 
                    414: static int mail_lputs(void* p, int level, char *str)
                    415: {
                    416:        static HANDLE mutex;
                    417:        static FILE* LogStream;
                    418: 
                    419:     if(!mutex)
                    420:        mutex=CreateMutex(NULL,false,NULL);
                    421:        WaitForSingleObject(mutex,INFINITE);
                    422: 
                    423:     if(str==NULL) {
                    424:         if(LogStream!=NULL)
                    425:             fclose(LogStream);
                    426:         LogStream=NULL;
                    427:         ReleaseMutex(mutex);
                    428:         return(0);
                    429:     }
                    430: 
                    431:     while(MaxLogLen && MailForm->Log->Text.Length()>=MaxLogLen)
                    432:         MailForm->Log->Lines->Delete(0);
                    433: 
                    434:     AnsiString Line=Now().FormatString(LOG_TIME_FMT)+"  ";
                    435:     Line+=AnsiString(str).Trim();
                    436:        MailForm->Log->Lines->Add(Line);
                    437: 
                    438:     if(MainForm->MailLogFile && MainForm->MailStop->Enabled) {
                    439:         AnsiString LogFileName
                    440:             =AnsiString(MainForm->cfg.data_dir)
                    441:             +"LOGS\\MS"
                    442:             +Now().FormatString("mmddyy")
                    443:             +".LOG";
                    444: 
                    445:         if(!FileExists(LogFileName)) {
                    446:             if(LogStream!=NULL) {
                    447:                fclose(LogStream);
                    448:                 LogStream=NULL;
                    449:             }
                    450:         }
                    451:         if(LogStream==NULL)
                    452:             LogStream=_fsopen(LogFileName.c_str(),"a",SH_DENYNONE);
                    453: 
                    454:         if(LogStream!=NULL) {
                    455:                        Line=Now().FormatString("hh:mm:ss")+"  ";
                    456:                    Line+=AnsiString(str).Trim();
                    457:                Line+="\n";
                    458:                fwrite(AnsiString(Line).c_str(),1,Line.Length(),LogStream);
                    459:         }
                    460:        }
                    461: 
                    462:     ReleaseMutex(mutex);
                    463:     return(Line.Length());
                    464: }
                    465: 
                    466: static void mail_status(void* p, char *str)
                    467: {
                    468:        static HANDLE mutex;
                    469: 
                    470:     if(!mutex)
                    471:        mutex=CreateMutex(NULL,false,NULL);
                    472:        WaitForSingleObject(mutex,INFINITE);
                    473: 
                    474:        MailForm->Status->Caption=AnsiString(str);
                    475: 
                    476:     ReleaseMutex(mutex);
                    477: }
                    478: 
                    479: static void mail_clients(void* p, int clients)
                    480: {
                    481:        static HANDLE mutex;
                    482: 
                    483:     if(!mutex)
                    484:        mutex=CreateMutex(NULL,false,NULL);
                    485:        WaitForSingleObject(mutex,INFINITE);
                    486: 
                    487:     MailForm->ProgressBar->Max=MainForm->mail_startup.max_clients;
                    488:        MailForm->ProgressBar->Position=clients;
                    489: 
                    490:     ReleaseMutex(mutex);
                    491: }
                    492: 
                    493: static void mail_terminated(void* p, int code)
                    494: {
                    495:        Screen->Cursor=crDefault;
                    496:        MainForm->MailStart->Enabled=true;
                    497:        MainForm->MailStop->Enabled=false;
                    498:     MainForm->MailRecycle->Enabled=false;
                    499:     Application->ProcessMessages();
                    500: }
                    501: static void mail_started(void* p)
                    502: {
                    503:        Screen->Cursor=crDefault;
                    504:        MainForm->MailStart->Enabled=false;
                    505:     MainForm->MailStop->Enabled=true;
                    506:     MainForm->MailRecycle->Enabled=true;
                    507:     Application->ProcessMessages();
                    508: }
                    509: static void mail_start(void)
                    510: {
                    511:        Screen->Cursor=crAppStart;
                    512:     mail_status(NULL, "Starting");
                    513: 
                    514:     FILE* fp=fopen(MainForm->ini_file,"r");
                    515:     sbbs_read_ini(fp
                    516:         ,&MainForm->global
                    517:         ,NULL   ,NULL
                    518:         ,NULL   ,NULL
                    519:         ,NULL   ,NULL
                    520:         ,NULL   ,&MainForm->mail_startup
                    521:         ,NULL   ,NULL
                    522:         );
                    523:     if(fp!=NULL)
                    524:         fclose(fp);
                    525: 
                    526:        _beginthread((void(*)(void*))mail_server,0,&MainForm->mail_startup);
                    527:     Application->ProcessMessages();
                    528: }
                    529: 
                    530: static int ftp_lputs(void* p, int level, char *str)
                    531: {
                    532:        static HANDLE mutex;
                    533:        static FILE* LogStream;
                    534: 
                    535:     if(!mutex)
                    536:        mutex=CreateMutex(NULL,false,NULL);
                    537:        WaitForSingleObject(mutex,INFINITE);
                    538: 
                    539:     if(str==NULL) {
                    540:         if(LogStream!=NULL)
                    541:             fclose(LogStream);
                    542:         LogStream=NULL;
                    543:         ReleaseMutex(mutex);
                    544:         return(0);
                    545:     }
                    546: 
                    547:     while(MaxLogLen && FtpForm->Log->Text.Length()>=MaxLogLen)
                    548:         FtpForm->Log->Lines->Delete(0);
                    549: 
                    550:     AnsiString Line=Now().FormatString(LOG_TIME_FMT)+"  ";
                    551:     Line+=AnsiString(str).Trim();
                    552:        FtpForm->Log->Lines->Add(Line);
                    553: 
                    554:     if(MainForm->FtpLogFile && MainForm->FtpStop->Enabled) {
                    555:         AnsiString LogFileName
                    556:             =AnsiString(MainForm->cfg.data_dir)
                    557:             +"LOGS\\FS"
                    558:             +Now().FormatString("mmddyy")
                    559:             +".LOG";
                    560: 
                    561:         if(!FileExists(LogFileName)) {
                    562:             FileClose(FileCreate(LogFileName));
                    563:             if(LogStream!=NULL) {
                    564:                 fclose(LogStream);
                    565:                 LogStream=NULL;
                    566:             }
                    567:         }
                    568:         if(LogStream==NULL)
                    569:             LogStream=_fsopen(LogFileName.c_str(),"a",SH_DENYNONE);
                    570: 
                    571:         if(LogStream!=NULL) {
                    572:             Line=Now().FormatString("hh:mm:ss")+"  ";
                    573:             Line+=AnsiString(str).Trim();
                    574:             Line+="\n";
                    575:                fwrite(AnsiString(Line).c_str(),1,Line.Length(),LogStream);
                    576:         }
                    577:        }
                    578: 
                    579:     ReleaseMutex(mutex);
                    580:     return(Line.Length());
                    581: }
                    582: 
                    583: static void ftp_status(void* p, char *str)
                    584: {
                    585:        static HANDLE mutex;
                    586: 
                    587:     if(!mutex)
                    588:        mutex=CreateMutex(NULL,false,NULL);
                    589:        WaitForSingleObject(mutex,INFINITE);
                    590: 
                    591:        FtpForm->Status->Caption=AnsiString(str);
                    592: 
                    593:     ReleaseMutex(mutex);
                    594: }
                    595: 
                    596: static void ftp_clients(void* p, int clients)
                    597: {
                    598:        static HANDLE mutex;
                    599: 
                    600:     if(!mutex)
                    601:        mutex=CreateMutex(NULL,false,NULL);
                    602:        WaitForSingleObject(mutex,INFINITE);
                    603: 
                    604:     FtpForm->ProgressBar->Max=MainForm->ftp_startup.max_clients;
                    605:        FtpForm->ProgressBar->Position=clients;
                    606: 
                    607:     ReleaseMutex(mutex);
                    608: }
                    609: 
                    610: static void ftp_terminated(void* p, int code)
                    611: {
                    612:        Screen->Cursor=crDefault;
                    613:        MainForm->FtpStart->Enabled=true;
                    614:        MainForm->FtpStop->Enabled=false;
                    615:     MainForm->FtpRecycle->Enabled=false;
                    616:     Application->ProcessMessages();
                    617: }
                    618: static void ftp_started(void* p)
                    619: {
                    620:        Screen->Cursor=crDefault;
                    621:        MainForm->FtpStart->Enabled=false;
                    622:     MainForm->FtpStop->Enabled=true;
                    623:     MainForm->FtpRecycle->Enabled=true;
                    624:     Application->ProcessMessages();
                    625: }
                    626: static void ftp_start(void)
                    627: {
                    628:        Screen->Cursor=crAppStart;
                    629:     ftp_status(NULL, "Starting");
                    630: 
                    631:     FILE* fp=fopen(MainForm->ini_file,"r");
                    632:     sbbs_read_ini(fp
                    633:         ,&MainForm->global
                    634:         ,NULL   ,NULL
                    635:         ,NULL   ,&MainForm->ftp_startup
                    636:         ,NULL   ,NULL
                    637:         ,NULL   ,NULL
                    638:         ,NULL   ,NULL
                    639:         );
                    640:     if(fp!=NULL)
                    641:         fclose(fp);
                    642: 
                    643:        _beginthread((void(*)(void*))ftp_server,0,&MainForm->ftp_startup);
                    644:     Application->ProcessMessages();
                    645: }
                    646: //---------------------------------------------------------------------------
                    647: static int web_lputs(void* p, int level, char *str)
                    648: {
                    649:        static HANDLE mutex;
                    650:        static FILE* LogStream;
                    651: 
                    652:     if(!mutex)
                    653:        mutex=CreateMutex(NULL,false,NULL);
                    654:        WaitForSingleObject(mutex,INFINITE);
                    655: 
                    656:     if(str==NULL) {
                    657:         if(LogStream!=NULL)
                    658:             fclose(LogStream);
                    659:         LogStream=NULL;
                    660:         ReleaseMutex(mutex);
                    661:         return(0);
                    662:     }
                    663: 
                    664:     while(MaxLogLen && WebForm->Log->Text.Length()>=MaxLogLen)
                    665:         WebForm->Log->Lines->Delete(0);
                    666: 
                    667:     AnsiString Line=Now().FormatString(LOG_TIME_FMT)+"  ";
                    668:     Line+=AnsiString(str).Trim();
                    669:        WebForm->Log->Lines->Add(Line);
                    670: #if 0
                    671:     if(MainForm->WebLogFile && MainForm->WebStop->Enabled) {
                    672:         AnsiString LogFileName
                    673:             =AnsiString(MainForm->cfg.data_dir)
                    674:             +"LOGS\\FS"
                    675:             +Now().FormatString("mmddyy")
                    676:             +".LOG";
                    677: 
                    678:         if(!FileExists(LogFileName)) {
                    679:             FileClose(FileCreate(LogFileName));
                    680:             if(LogStream!=NULL) {
                    681:                 fclose(LogStream);
                    682:                 LogStream=NULL;
                    683:             }
                    684:         }
                    685:         if(LogStream==NULL)
                    686:             LogStream=_fsopen(LogFileName.c_str(),"a",SH_DENYNONE);
                    687: 
                    688:         if(LogStream!=NULL) {
                    689:             Line=Now().FormatString("hh:mm:ss")+"  ";
                    690:             Line+=AnsiString(str).Trim();
                    691:             Line+="\n";
                    692:                fwrite(AnsiString(Line).c_str(),1,Line.Length(),LogStream);
                    693:         }
                    694:        }
                    695: #endif
                    696:     ReleaseMutex(mutex);
                    697:     return(Line.Length());
                    698: }
                    699: 
                    700: static void web_status(void* p, char *str)
                    701: {
                    702:        static HANDLE mutex;
                    703: 
                    704:     if(!mutex)
                    705:        mutex=CreateMutex(NULL,false,NULL);
                    706:        WaitForSingleObject(mutex,INFINITE);
                    707: 
                    708:        WebForm->Status->Caption=AnsiString(str);
                    709: 
                    710:     ReleaseMutex(mutex);
                    711: }
                    712: 
                    713: static void web_clients(void* p, int clients)
                    714: {
                    715:        static HANDLE mutex;
                    716: 
                    717:     if(!mutex)
                    718:        mutex=CreateMutex(NULL,false,NULL);
                    719:        WaitForSingleObject(mutex,INFINITE);
                    720: 
                    721:     WebForm->ProgressBar->Max=MainForm->ftp_startup.max_clients;
                    722:        WebForm->ProgressBar->Position=clients;
                    723: 
                    724:     ReleaseMutex(mutex);
                    725: }
                    726: 
                    727: static void web_terminated(void* p, int code)
                    728: {
                    729:        Screen->Cursor=crDefault;
                    730:        MainForm->WebStart->Enabled=true;
                    731:        MainForm->WebStop->Enabled=false;
                    732:     MainForm->WebRecycle->Enabled=false;
                    733:     Application->ProcessMessages();
                    734: }
                    735: static void web_started(void* p)
                    736: {
                    737:        Screen->Cursor=crDefault;
                    738:        MainForm->WebStart->Enabled=false;
                    739:     MainForm->WebStop->Enabled=true;
                    740:     MainForm->WebRecycle->Enabled=true;
                    741:     Application->ProcessMessages();
                    742: }
                    743: static void web_start(void)
                    744: {
                    745:        Screen->Cursor=crAppStart;
                    746:     web_status(NULL, "Starting");
                    747: 
                    748:     FILE* fp=fopen(MainForm->ini_file,"r");
                    749:     sbbs_read_ini(fp
                    750:         ,&MainForm->global
                    751:         ,NULL   ,NULL
                    752:         ,NULL   ,NULL
                    753:         ,NULL   ,&MainForm->web_startup
                    754:         ,NULL   ,NULL
                    755:         ,NULL   ,NULL
                    756:         );
                    757:     if(fp!=NULL)
                    758:         fclose(fp);
                    759: 
                    760:        _beginthread((void(*)(void*))web_server,0,&MainForm->web_startup);
                    761:     Application->ProcessMessages();
                    762: }
                    763: //---------------------------------------------------------------------------
                    764: /* Server recycle callback (read relevant startup .ini file section)           */
                    765: static void recycle(void* cbdata)
                    766: {
                    767:     char            str[MAX_PATH*2];
                    768:     FILE*           fp=NULL;
                    769:        bbs_startup_t*  bbs=NULL;
                    770:        ftp_startup_t*  ftp=NULL;
                    771:        web_startup_t*  web=NULL;
                    772:        mail_startup_t* mail=NULL;
                    773:        services_startup_t* services=NULL;
                    774: 
                    775:     SAFEPRINTF(str,"Reading %s",MainForm->ini_file);
                    776:        if(cbdata==(void*)&MainForm->bbs_startup) {
                    777:                bbs=&MainForm->bbs_startup;
                    778:         bbs_lputs(cbdata,LOG_INFO,str);
                    779:        } else if(cbdata==(void*)&MainForm->ftp_startup) {
                    780:                ftp=&MainForm->ftp_startup;
                    781:         ftp_lputs(cbdata,LOG_INFO,str);
                    782:     } else if(cbdata==(void*)&MainForm->web_startup) {
                    783:                web=&MainForm->web_startup;
                    784:         web_lputs(cbdata,LOG_INFO,str);
                    785:     } else if(cbdata==(void*)&MainForm->mail_startup) {
                    786:                mail=&MainForm->mail_startup;
                    787:         mail_lputs(cbdata,LOG_INFO,str);
                    788:        } else if(cbdata==(void*)&MainForm->services_startup) {
                    789:                services=&MainForm->services_startup;
                    790:         service_lputs(cbdata,LOG_INFO,str);
                    791:     }
                    792: 
                    793:     fp=fopen(MainForm->ini_file,"r");
                    794:     sbbs_read_ini(fp
                    795:         ,&MainForm->global
                    796:         ,NULL   ,bbs
                    797:         ,NULL   ,ftp
                    798:         ,NULL   ,web
                    799:         ,NULL   ,mail
                    800:         ,NULL   ,services
                    801:         );
                    802:     if(fp!=NULL)
                    803:         fclose(fp);
                    804: }
                    805: //---------------------------------------------------------------------------
                    806: __fastcall TMainForm::TMainForm(TComponent* Owner)
                    807:         : TForm(Owner)
                    808: {
                    809:     /* Defaults */
                    810:     SAFECOPY(global.ctrl_dir,"c:\\sbbs\\ctrl\\");
                    811:     global.js.max_bytes=JAVASCRIPT_MAX_BYTES;
                    812:     global.js.cx_stack=JAVASCRIPT_CONTEXT_STACK;
                    813:     global.js.branch_limit=JAVASCRIPT_BRANCH_LIMIT;
                    814:     global.js.gc_interval=JAVASCRIPT_GC_INTERVAL;
                    815:     global.js.yield_interval=JAVASCRIPT_YIELD_INTERVAL;
                    816:     global.sem_chk_freq=5;             /* seconds */
                    817: 
                    818:     /* These are SBBSCTRL-specific */
                    819:     LoginCommand="telnet://localhost";
                    820:     ConfigCommand="%sscfg.exe %s -l25";
                    821:     MinimizeToSysTray=false;
                    822:     UndockableForms=false;
                    823:     UseFileAssociations=true;
                    824:     Initialized=false;
                    825: 
                    826:     char* p;
                    827:     if((p=getenv("SBBSCTRL"))!=NULL)
                    828:         SAFECOPY(global.ctrl_dir,p);
                    829:        p=lastchar(global.ctrl_dir);
                    830:        if(*p!='/' && *p!='\\')
                    831:        strcat(global.ctrl_dir,"\\");
                    832:         
                    833:     memset(&bbs_startup,0,sizeof(bbs_startup));
                    834:     bbs_startup.size=sizeof(bbs_startup);
                    835:     bbs_startup.cbdata=&bbs_startup;
                    836:     bbs_startup.first_node=1;
                    837:     bbs_startup.last_node=4;
                    838:        bbs_startup.options=BBS_OPT_XTRN_MINIMIZED|BBS_OPT_SYSOP_AVAILABLE;
                    839:        bbs_startup.telnet_port=IPPORT_TELNET;
                    840:     bbs_startup.telnet_interface=INADDR_ANY;
                    841:     bbs_startup.rlogin_port=513;
                    842:     bbs_startup.rlogin_interface=INADDR_ANY;
                    843:        bbs_startup.lputs=bbs_lputs;
                    844:     bbs_startup.status=bbs_status;
                    845:     bbs_startup.clients=bbs_clients;
                    846:     bbs_startup.started=bbs_started;
                    847:     bbs_startup.recycle=recycle;
                    848:     bbs_startup.terminated=bbs_terminated;
                    849:     bbs_startup.thread_up=thread_up;
                    850:     bbs_startup.client_on=client_on;
                    851:     bbs_startup.socket_open=socket_open;
                    852:     bbs_startup.event_lputs=event_lputs;
                    853: 
                    854:     memset(&mail_startup,0,sizeof(mail_startup));
                    855:     mail_startup.size=sizeof(mail_startup);
                    856:     mail_startup.cbdata=&mail_startup;
                    857:     mail_startup.smtp_port=IPPORT_SMTP;
                    858:     mail_startup.relay_port=IPPORT_SMTP;
                    859:     mail_startup.pop3_port=110;
                    860:     mail_startup.interface_addr=INADDR_ANY;
                    861:        mail_startup.lputs=mail_lputs;
                    862:     mail_startup.status=mail_status;
                    863:     mail_startup.clients=mail_clients;
                    864:     mail_startup.started=mail_started;
                    865:     mail_startup.recycle=recycle;
                    866:     mail_startup.terminated=mail_terminated;
                    867:     mail_startup.options=MAIL_OPT_ALLOW_POP3;
                    868:     mail_startup.thread_up=thread_up;
                    869:     mail_startup.client_on=client_on;
                    870:     mail_startup.socket_open=socket_open;
                    871:     mail_startup.max_delivery_attempts=50;
                    872:     mail_startup.rescan_frequency=3600;  /* 60 minutes */
                    873:     mail_startup.lines_per_yield=10;
                    874:     mail_startup.max_clients=10;
                    875:     mail_startup.max_msg_size=10*1024*1024;
                    876: 
                    877:     memset(&ftp_startup,0,sizeof(ftp_startup));
                    878:     ftp_startup.size=sizeof(ftp_startup);
                    879:     ftp_startup.cbdata=&ftp_startup;
                    880:     ftp_startup.port=IPPORT_FTP;
                    881:     ftp_startup.interface_addr=INADDR_ANY;
                    882:        ftp_startup.lputs=ftp_lputs;
                    883:     ftp_startup.status=ftp_status;
                    884:     ftp_startup.clients=ftp_clients;
                    885:     ftp_startup.started=ftp_started;
                    886:     ftp_startup.recycle=recycle;
                    887:     ftp_startup.terminated=ftp_terminated;
                    888:     ftp_startup.thread_up=thread_up;
                    889:     ftp_startup.client_on=client_on;
                    890:     ftp_startup.socket_open=socket_open;
                    891:        ftp_startup.options
                    892:         =FTP_OPT_INDEX_FILE|FTP_OPT_HTML_INDEX_FILE|FTP_OPT_ALLOW_QWK;
                    893:     ftp_startup.max_clients=10;
                    894:     strcpy(ftp_startup.index_file_name,"00index");
                    895:     strcpy(ftp_startup.html_index_file,"00index.html");
                    896:     strcpy(ftp_startup.html_index_script,"ftp-html.js");
                    897: 
                    898:     memset(&web_startup,0,sizeof(web_startup));
                    899:     web_startup.size=sizeof(web_startup);
                    900:     web_startup.cbdata=&web_startup;
                    901:        web_startup.lputs=web_lputs;
                    902:     web_startup.status=web_status;
                    903:     web_startup.clients=web_clients;
                    904:     web_startup.started=web_started;
                    905:     web_startup.recycle=recycle;
                    906:     web_startup.terminated=web_terminated;
                    907:     web_startup.thread_up=thread_up;
                    908:     web_startup.client_on=client_on;
                    909:     web_startup.socket_open=socket_open;
                    910: 
                    911:     memset(&services_startup,0,sizeof(services_startup));
                    912:     services_startup.size=sizeof(services_startup);
                    913:     services_startup.cbdata=&services_startup;
                    914:     services_startup.interface_addr=INADDR_ANY;
                    915:     services_startup.lputs=service_lputs;
                    916:     services_startup.status=services_status;
                    917:     services_startup.clients=services_clients;
                    918:     services_startup.started=services_started;
                    919:     services_startup.recycle=recycle;    
                    920:     services_startup.terminated=services_terminated;
                    921:     services_startup.thread_up=thread_up;
                    922:     services_startup.client_on=client_on;
                    923:     services_startup.socket_open=socket_open;
                    924: 
                    925:     bbs_log=INVALID_HANDLE_VALUE;
                    926:     event_log=INVALID_HANDLE_VALUE;
                    927:     ftp_log=INVALID_HANDLE_VALUE;
                    928:     web_log=INVALID_HANDLE_VALUE;    
                    929:     mail_log=INVALID_HANDLE_VALUE;
                    930:     services_log=INVALID_HANDLE_VALUE;
                    931: 
                    932:     /* Default local "Spy Terminal" settings */
                    933:     SpyTerminalFont=new TFont;
                    934:     SpyTerminalFont->Name="Terminal";
                    935:     SpyTerminalFont->Size=9;
                    936:     SpyTerminalFont->Pitch=fpFixed;
                    937:     SpyTerminalWidth=434;
                    938:     SpyTerminalHeight=365;
                    939:     SpyTerminalKeyboardActive=true;
                    940: 
                    941:     Application->OnMinimize=FormMinimize;
                    942: 
                    943:     /* Get pointers to NT Service functions */
                    944:        HANDLE hSCMlib = LoadLibrary("ADVAPI32.DLL");
                    945:        if(hSCMlib!=NULL) {
                    946:                openSCManager=(OpenSCManager_t)GetProcAddress(hSCMlib, "OpenSCManagerA");
                    947:                openService=(OpenService_t)GetProcAddress(hSCMlib,"OpenServiceA");
                    948:                startService=(StartService_t)GetProcAddress(hSCMlib,"StartServiceA");
                    949:                controlService=(ControlService_t)GetProcAddress(hSCMlib,"ControlService");
                    950:                queryServiceStatus=(QueryServiceStatus_t)GetProcAddress(hSCMlib,"QueryServiceStatus");
                    951:                queryServiceConfig=(QueryServiceConfig_t)GetProcAddress(hSCMlib,"QueryServiceConfigA");
                    952:                closeServiceHandle=(CloseServiceHandle_t)GetProcAddress(hSCMlib,"CloseServiceHandle");
                    953:                FreeLibrary(hSCMlib);
                    954:     }
                    955: 
                    956:     /* Open Service Manager */
                    957:     if(openSCManager!=NULL)
                    958:         hSCManager = openSCManager(
                    959:                             NULL,                   // machine (NULL == local)
                    960:                             NULL,                   // database (NULL == default)
                    961:                             SC_MANAGER_CONNECT         // access required
                    962:                             );
                    963: 
                    964:        /* Open Synchronet Services */
                    965:     if(hSCManager!=NULL) {
                    966:                bbs_svc =  openService(hSCManager, NTSVC_NAME_BBS, GENERIC_READ|GENERIC_EXECUTE);
                    967:                ftp_svc =  openService(hSCManager, NTSVC_NAME_FTP, GENERIC_READ|GENERIC_EXECUTE);
                    968:                web_svc =  openService(hSCManager, NTSVC_NAME_WEB, GENERIC_READ|GENERIC_EXECUTE);        
                    969:                mail_svc =  openService(hSCManager, NTSVC_NAME_MAIL, GENERIC_READ|GENERIC_EXECUTE);
                    970:                services_svc =  openService(hSCManager, NTSVC_NAME_SERVICES, GENERIC_READ|GENERIC_EXECUTE);
                    971:     }
                    972: }
                    973: //---------------------------------------------------------------------------
                    974: void __fastcall TMainForm::FileExitMenuItemClick(TObject *Sender)
                    975: {
                    976:         Close();
                    977: }
                    978: void __fastcall TMainForm::FormCreate(TObject *Sender)
                    979: {
                    980:        Height=400;     // Just incase we mess it up in the IDE
                    981:     Width=700;
                    982: 
                    983:     // Verify SBBS.DLL version
                    984:     long bbs_ver = bbs_ver_num();
                    985:     if(bbs_ver != VERSION_HEX) {
                    986:         char str[128];
                    987:         sprintf(str,"Incorrect SBBS.DLL Version (%lX)",bbs_ver);
                    988:        Application->MessageBox(str,"ERROR",MB_OK|MB_ICONEXCLAMATION);
                    989:         Application->Terminate();
                    990:     }
                    991: 
                    992:     // Read Registry keys
                    993:        TRegistry* Registry=new TRegistry;
                    994:     if(!Registry->OpenKey(REG_KEY,true)) {
                    995:        Application->MessageBox("Error opening registry key"
                    996:                ,REG_KEY,MB_OK|MB_ICONEXCLAMATION);
                    997:         Application->Terminate();
                    998:         return;
                    999:     }
                   1000:        if(Registry->ValueExists("MainFormTop"))
                   1001:                Top=Registry->ReadInteger("MainFormTop");
                   1002:        if(Registry->ValueExists("MainFormLeft"))
                   1003:                Left=Registry->ReadInteger("MainFormLeft");
                   1004:        if(Registry->ValueExists("MainFormHeight"))
                   1005:                Height=Registry->ReadInteger("MainFormHeight");
                   1006:        if(Registry->ValueExists("MainFormWidth"))
                   1007:                Width=Registry->ReadInteger("MainFormWidth");
                   1008:     else
                   1009:         WindowState=wsMaximized;    // Default to fullscreen
                   1010:        if(Registry->ValueExists("SpyTerminalWidth"))
                   1011:                SpyTerminalWidth=Registry->ReadInteger("SpyTerminalWidth");
                   1012:        if(Registry->ValueExists("SpyTerminalHeight"))
                   1013:                SpyTerminalHeight=Registry->ReadInteger("SpyTerminalHeight");
                   1014:        if(Registry->ValueExists("SpyTerminalFontName"))
                   1015:                SpyTerminalFont->Name=Registry->ReadString("SpyTerminalFontName");
                   1016:        if(Registry->ValueExists("SpyTerminalFontSize"))
                   1017:                SpyTerminalFont->Size=Registry->ReadInteger("SpyTerminalFontSize");
                   1018:        if(Registry->ValueExists("SpyTerminalKeyboardActive"))
                   1019:                SpyTerminalKeyboardActive
                   1020:             =Registry->ReadBool("SpyTerminalKeyboardActive");
                   1021: 
                   1022:     Registry->CloseKey();
                   1023:     delete Registry;
                   1024: }
                   1025: //---------------------------------------------------------------------------
                   1026: void __fastcall TMainForm::FormShow(TObject *Sender)
                   1027: {
                   1028:        StartupTimer->Enabled=true;
                   1029: }
                   1030: //---------------------------------------------------------------------------
                   1031: 
                   1032: void __fastcall TMainForm::ViewToolbarMenuItemClick(TObject *Sender)
                   1033: {
                   1034:        Toolbar->Visible=ViewToolbarMenuItem->Checked;
                   1035: }
                   1036: //---------------------------------------------------------------------------
                   1037: BOOL NTsvcEnabled(SC_HANDLE svc, QUERY_SERVICE_CONFIG* config, DWORD config_size)
                   1038: {
                   1039:        if(svc==NULL || startService==NULL || queryServiceStatus==NULL || config==NULL)
                   1040:        return(FALSE);
                   1041: 
                   1042:        DWORD ret;
                   1043:        if(!queryServiceConfig(svc,config,config_size,&ret))
                   1044:                return(FALSE);
                   1045:        if(config->dwStartType==SERVICE_DISABLED)
                   1046:                return(FALSE);
                   1047:        return(TRUE);
                   1048: }
                   1049: //---------------------------------------------------------------------------
                   1050: BOOL __fastcall TMainForm::bbsServiceEnabled(void)
                   1051: {
                   1052:     return NTsvcEnabled(bbs_svc,bbs_svc_config,bbs_svc_config_size);
                   1053: }
                   1054: BOOL __fastcall TMainForm::mailServiceEnabled(void)
                   1055: {
                   1056:     return NTsvcEnabled(mail_svc,mail_svc_config,mail_svc_config_size);
                   1057: }
                   1058: BOOL __fastcall TMainForm::ftpServiceEnabled(void)
                   1059: {
                   1060:     return NTsvcEnabled(ftp_svc,ftp_svc_config,ftp_svc_config_size);
                   1061: }
                   1062: BOOL __fastcall TMainForm::webServiceEnabled(void)
                   1063: {
                   1064:     return NTsvcEnabled(web_svc,web_svc_config,web_svc_config_size);
                   1065: }
                   1066: BOOL __fastcall TMainForm::servicesServiceEnabled(void)
                   1067: {
                   1068:     return NTsvcEnabled(services_svc,services_svc_config,services_svc_config_size);
                   1069: }
                   1070: //---------------------------------------------------------------------------
                   1071: void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
                   1072: {
                   1073:     UpTimer->Enabled=false; /* Stop updating the status bar */
                   1074:        StatsTimer->Enabled=false;
                   1075: 
                   1076:     if(TrayIcon->Visible)           /* minimized to tray? */
                   1077:         TrayIcon->Visible=false;    /* restore to avoid crash */
                   1078:         
                   1079:     /* This is necessary to save form sizes/positions */
                   1080:     if(Initialized) /* Don't overwrite registry settings with defaults */
                   1081:         SaveRegistrySettings(Sender);
                   1082: 
                   1083:        StatusBar->Panels->Items[4]->Text="Terminating servers...";
                   1084:     time_t start=time(NULL);
                   1085:        while( (TelnetStop->Enabled     && !bbsServiceEnabled())
                   1086:         || (MailStop->Enabled       && !mailServiceEnabled())
                   1087:         || (FtpStop->Enabled        && !ftpServiceEnabled())
                   1088:         || (WebStop->Enabled        && !webServiceEnabled())
                   1089:        || (ServicesStop->Enabled   && !servicesServiceEnabled())) {
                   1090:         if(time(NULL)-start>30)
                   1091:             break;
                   1092:         Application->ProcessMessages();
                   1093:         YIELD();
                   1094:     }
                   1095:        StatusBar->Panels->Items[4]->Text="Closing...";
                   1096:     Application->ProcessMessages();
                   1097:     
                   1098:        LogTimer->Enabled=false;
                   1099:        ServiceStatusTimer->Enabled=false;
                   1100:        NodeForm->Timer->Enabled=false;
                   1101:        ClientForm->Timer->Enabled=false;
                   1102: #if 0
                   1103:     /* Extra time for callbacks to be called by child threads */
                   1104:     start=time(NULL);
                   1105:     while(time(NULL)<start+2) {
                   1106:         Application->ProcessMessages();
                   1107:         YIELD();
                   1108:     }
                   1109: #endif
                   1110: #if 0
                   1111:     if(hSCManager!=NULL)
                   1112:        closeServiceHandle(hSCManager);
                   1113: #endif
                   1114: }
                   1115: //---------------------------------------------------------------------------
                   1116: void __fastcall TMainForm::FormCloseQuery(TObject *Sender, bool &CanClose)
                   1117: {
                   1118:        CanClose=false;
                   1119: 
                   1120:     if(TelnetStop->Enabled && !bbsServiceEnabled()) {
                   1121:        if(!terminating && TelnetForm->ProgressBar->Position
                   1122:                && Application->MessageBox("Shut down the Telnet Server?"
                   1123:                ,"Telnet Server In Use", MB_OKCANCEL)!=IDOK)
                   1124:             return;
                   1125:         TelnetStopExecute(Sender);
                   1126:        }
                   1127: 
                   1128:     if(MailStop->Enabled && !mailServiceEnabled()) {
                   1129:        if(!terminating && MailForm->ProgressBar->Position
                   1130:                && Application->MessageBox("Shut down the Mail Server?"
                   1131:                ,"Mail Server In Use", MB_OKCANCEL)!=IDOK)
                   1132:             return;
                   1133:         MailStopExecute(Sender);
                   1134:     }
                   1135: 
                   1136:     if(FtpStop->Enabled && !ftpServiceEnabled()) {
                   1137:        if(!terminating && FtpForm->ProgressBar->Position
                   1138:                && Application->MessageBox("Shut down the FTP Server?"
                   1139:                ,"FTP Server In Use", MB_OKCANCEL)!=IDOK)
                   1140:             return;
                   1141:         FtpStopExecute(Sender);
                   1142:     }
                   1143: 
                   1144:     if(WebStop->Enabled && !webServiceEnabled()) {
                   1145:        if(!terminating && WebForm->ProgressBar->Position
                   1146:                && Application->MessageBox("Shut down the Web Server?"
                   1147:                ,"Web Server In Use", MB_OKCANCEL)!=IDOK)
                   1148:             return;
                   1149:         WebStopExecute(Sender);
                   1150:     }
                   1151: 
                   1152:     if(ServicesStop->Enabled && !servicesServiceEnabled())
                   1153:            ServicesStopExecute(Sender);
                   1154: 
                   1155:     CanClose=true;
                   1156: }
                   1157: 
                   1158: //---------------------------------------------------------------------------
                   1159: BOOL StartNTsvc(SC_HANDLE svc, SERVICE_STATUS* status, QUERY_SERVICE_CONFIG* config, DWORD config_size)
                   1160: {
                   1161:        if(svc==NULL || startService==NULL || queryServiceStatus==NULL || config==NULL)
                   1162:        return(FALSE);
                   1163: 
                   1164:        DWORD ret;
                   1165:        if(!queryServiceConfig(svc,config,config_size,&ret))
                   1166:                return(FALSE);
                   1167:        if(config->dwStartType==SERVICE_DISABLED)
                   1168:                return(FALSE);
                   1169:     if(!queryServiceStatus(svc,status))
                   1170:        return(FALSE);
                   1171:     if(status->dwCurrentState!=SERVICE_STOPPED)
                   1172:        return(TRUE);
                   1173:     if(!startService(svc,0,NULL))
                   1174:                Application->MessageBox(AnsiString("ERROR " + IntToStr(GetLastError()) +
                   1175:             " starting " + config->lpDisplayName).c_str()
                   1176:             ,"ERROR"
                   1177:             ,MB_OK|MB_ICONEXCLAMATION);
                   1178:     return(TRUE);
                   1179: }
                   1180: //---------------------------------------------------------------------------
                   1181: void __fastcall TMainForm::TelnetStartExecute(TObject *Sender)
                   1182: {
                   1183:        if(!StartNTsvc(bbs_svc,&bbs_svc_status,bbs_svc_config,bbs_svc_config_size))
                   1184:                bbs_start();
                   1185: }
                   1186: //---------------------------------------------------------------------------
                   1187: void __fastcall TMainForm::ServicesStartExecute(TObject *Sender)
                   1188: {
                   1189:        if(StartNTsvc(services_svc,&services_svc_status,services_svc_config,services_svc_config_size))
                   1190:        return;
                   1191:        Screen->Cursor=crAppStart;
                   1192:     services_status(NULL, "Starting");
                   1193: 
                   1194:     FILE* fp=fopen(ini_file,"r");
                   1195:     sbbs_read_ini(fp
                   1196:         ,&MainForm->global
                   1197:         ,NULL   ,NULL
                   1198:         ,NULL   ,NULL
                   1199:         ,NULL   ,NULL
                   1200:         ,NULL   ,NULL
                   1201:         ,NULL   ,&services_startup
                   1202:         );
                   1203:     if(fp!=NULL)
                   1204:         fclose(fp);
                   1205: 
                   1206:        _beginthread((void(*)(void*))services_thread,0,&services_startup);
                   1207:     Application->ProcessMessages();
                   1208: }
                   1209: 
                   1210: //---------------------------------------------------------------------------
                   1211: BOOL StopNTsvc(SC_HANDLE svc, SERVICE_STATUS* status)
                   1212: {
                   1213:        if(svc==NULL || controlService==NULL)
                   1214:        return(FALSE);
                   1215: 
                   1216:     return controlService(svc,SERVICE_CONTROL_STOP,status);
                   1217: }
                   1218: 
                   1219: //---------------------------------------------------------------------------
                   1220: 
                   1221: void __fastcall TMainForm::ServicesStopExecute(TObject *Sender)
                   1222: {
                   1223:        if(StopNTsvc(services_svc,&services_svc_status))
                   1224:        return;
                   1225:     Screen->Cursor=crAppStart;
                   1226:     services_status(NULL, "Terminating");
                   1227:     services_terminate();
                   1228:     Application->ProcessMessages();
                   1229: }
                   1230: //---------------------------------------------------------------------------
                   1231: 
                   1232: void __fastcall TMainForm::TelnetStopExecute(TObject *Sender)
                   1233: {
                   1234:        if(StopNTsvc(bbs_svc,&bbs_svc_status))
                   1235:        return;
                   1236:     Screen->Cursor=crAppStart;
                   1237:     bbs_status(NULL, "Terminating");
                   1238:     bbs_terminate();
                   1239:     Application->ProcessMessages();
                   1240: }
                   1241: //---------------------------------------------------------------------------
                   1242: 
                   1243: void __fastcall TMainForm::TelnetConfigureExecute(TObject *Sender)
                   1244: {
                   1245:     static inside;
                   1246:     if(inside) return;
                   1247:     inside=true;
                   1248: 
                   1249:        Application->CreateForm(__classid(TTelnetCfgDlg), &TelnetCfgDlg);
                   1250:        TelnetCfgDlg->ShowModal();
                   1251:     delete TelnetCfgDlg;
                   1252:     
                   1253:     inside=false;
                   1254: }
                   1255: //---------------------------------------------------------------------------
                   1256: 
                   1257: 
                   1258: void __fastcall TMainForm::NodeListStartExecute(TObject *Sender)
                   1259: {
                   1260:        NodeForm->Timer->Enabled=true;
                   1261:     NodeListStart->Enabled=false;
                   1262:     NodeListStop->Enabled=true;
                   1263: }
                   1264: //---------------------------------------------------------------------------
                   1265: 
                   1266: void __fastcall TMainForm::NodeListStopExecute(TObject *Sender)
                   1267: {
                   1268:     NodeForm->Timer->Enabled=false;
                   1269:     NodeListStart->Enabled=true;
                   1270:     NodeListStop->Enabled=false;
                   1271: }
                   1272: //---------------------------------------------------------------------------
                   1273: 
                   1274: 
                   1275: void __fastcall TMainForm::MailConfigureExecute(TObject *Sender)
                   1276: {
                   1277:     static inside;
                   1278:     if(inside) return;
                   1279:     inside=true;
                   1280: 
                   1281:        Application->CreateForm(__classid(TMailCfgDlg), &MailCfgDlg);
                   1282:        MailCfgDlg->ShowModal();
                   1283:     delete MailCfgDlg;
                   1284: 
                   1285:     inside=false;
                   1286: }
                   1287: //---------------------------------------------------------------------------
                   1288: 
                   1289: void __fastcall TMainForm::MailStartExecute(TObject *Sender)
                   1290: {
                   1291:        if(!StartNTsvc(mail_svc,&mail_svc_status,mail_svc_config,mail_svc_config_size))
                   1292:            mail_start();
                   1293: }
                   1294: //---------------------------------------------------------------------------
                   1295: 
                   1296: void __fastcall TMainForm::MailStopExecute(TObject *Sender)
                   1297: {
                   1298:        if(StopNTsvc(mail_svc,&mail_svc_status))
                   1299:        return;
                   1300:     Screen->Cursor=crAppStart;
                   1301:     mail_status(NULL, "Terminating");
                   1302:     mail_terminate();
                   1303:     Application->ProcessMessages();
                   1304: }
                   1305: //---------------------------------------------------------------------------
                   1306: void __fastcall TMainForm::ViewTelnetExecute(TObject *Sender)
                   1307: {
                   1308:        TelnetForm->Visible=ViewTelnet->Checked;
                   1309: }
                   1310: //---------------------------------------------------------------------------
                   1311: void __fastcall TMainForm::ViewEventsExecute(TObject *Sender)
                   1312: {
                   1313:        EventsForm->Visible=ViewEvents->Checked;
                   1314: }
                   1315: //---------------------------------------------------------------------------
                   1316: 
                   1317: void __fastcall TMainForm::ViewNodesExecute(TObject *Sender)
                   1318: {
                   1319:        NodeForm->Visible=ViewNodes->Checked;
                   1320: }
                   1321: //---------------------------------------------------------------------------
                   1322: 
                   1323: void __fastcall TMainForm::ViewMailServerExecute(TObject *Sender)
                   1324: {
                   1325:        MailForm->Visible=ViewMailServer->Checked;
                   1326: }
                   1327: //---------------------------------------------------------------------------
                   1328: 
                   1329: void __fastcall TMainForm::ViewFtpServerExecute(TObject *Sender)
                   1330: {
                   1331:        FtpForm->Visible=ViewFtpServer->Checked;
                   1332: }
                   1333: //---------------------------------------------------------------------------
                   1334: void __fastcall TMainForm::ViewWebServerExecute(TObject *Sender)
                   1335: {
                   1336:     WebForm->Visible=ViewWebServer->Checked;
                   1337: }
                   1338: //---------------------------------------------------------------------------
                   1339: void __fastcall TMainForm::ViewServicesExecute(TObject *Sender)
                   1340: {
                   1341:     ServicesForm->Visible=ViewServices->Checked;
                   1342: }
                   1343: //---------------------------------------------------------------------------
                   1344: void __fastcall TMainForm::ViewStatsExecute(TObject *Sender)
                   1345: {
                   1346:        StatsForm->Visible=ViewStats->Checked;
                   1347: }
                   1348: //---------------------------------------------------------------------------
                   1349: void __fastcall TMainForm::ViewClientsExecute(TObject *Sender)
                   1350: {
                   1351:        ClientForm->Visible=ViewClients->Checked;
                   1352: }
                   1353: //---------------------------------------------------------------------------
                   1354: void __fastcall TMainForm::FtpStartExecute(TObject *Sender)
                   1355: {
                   1356:        if(!StartNTsvc(ftp_svc,&ftp_svc_status,ftp_svc_config,ftp_svc_config_size))
                   1357:                ftp_start();
                   1358: }
                   1359: //---------------------------------------------------------------------------
                   1360: 
                   1361: void __fastcall TMainForm::FtpStopExecute(TObject *Sender)
                   1362: {
                   1363:        if(StopNTsvc(ftp_svc,&ftp_svc_status))
                   1364:        return;
                   1365:     Screen->Cursor=crAppStart;
                   1366:     ftp_status(NULL, "Terminating");
                   1367:     ftp_terminate();
                   1368:     Application->ProcessMessages();
                   1369: }
                   1370: //---------------------------------------------------------------------------
                   1371: 
                   1372: void __fastcall TMainForm::FtpConfigureExecute(TObject *Sender)
                   1373: {
                   1374:     static inside;
                   1375:     if(inside) return;
                   1376:     inside=true;
                   1377: 
                   1378:        Application->CreateForm(__classid(TFtpCfgDlg), &FtpCfgDlg);
                   1379:        FtpCfgDlg->ShowModal();
                   1380:     delete FtpCfgDlg;
                   1381: 
                   1382:     inside=false;
                   1383: }
                   1384: //---------------------------------------------------------------------------
                   1385: void __fastcall TMainForm::WebStartExecute(TObject *Sender)
                   1386: {
                   1387:        if(!StartNTsvc(web_svc,&web_svc_status,web_svc_config,web_svc_config_size))
                   1388:                web_start();
                   1389: }
                   1390: //---------------------------------------------------------------------------
                   1391: void __fastcall TMainForm::WebStopExecute(TObject *Sender)
                   1392: {
                   1393:        if(StopNTsvc(web_svc,&web_svc_status))
                   1394:        return;
                   1395:     Screen->Cursor=crAppStart;
                   1396:     web_status(NULL, "Terminating");
                   1397:     web_terminate();
                   1398:     Application->ProcessMessages();
                   1399: }
                   1400: //---------------------------------------------------------------------------
                   1401: void __fastcall TMainForm::WebConfigureExecute(TObject *Sender)
                   1402: {
                   1403:     static inside;
                   1404:     if(inside) return;
                   1405:     inside=true;
                   1406: 
                   1407:        Application->CreateForm(__classid(TWebCfgDlg), &WebCfgDlg);
                   1408:        WebCfgDlg->ShowModal();
                   1409:     delete WebCfgDlg;
                   1410: 
                   1411:     inside=false;
                   1412: }
                   1413: //---------------------------------------------------------------------------
                   1414: void __fastcall TMainForm::BBSConfigureMenuItemClick(TObject *Sender)
                   1415: {
                   1416:        char str[256];
                   1417: 
                   1418:     sprintf(str,ConfigCommand.c_str()
                   1419:        ,cfg.exec_dir, cfg.ctrl_dir);
                   1420:     STARTUPINFO startup_info={0};
                   1421:     PROCESS_INFORMATION process_info;
                   1422:     startup_info.cb=sizeof(startup_info);
                   1423:     startup_info.lpTitle="Synchronet Configuration Utility";
                   1424:        CreateProcess(
                   1425:                NULL,                   // pointer to name of executable module
                   1426:                str,                    // pointer to command line string
                   1427:                NULL,                   // process security attributes
                   1428:                NULL,                   // thread security attributes
                   1429:                FALSE,                  // handle inheritance flag
                   1430:                CREATE_NEW_CONSOLE|CREATE_SEPARATE_WOW_VDM, // creation flags
                   1431:         NULL,                          // pointer to new environment block
                   1432:                cfg.ctrl_dir,   // pointer to current directory name
                   1433:                &startup_info,  // pointer to STARTUPINFO
                   1434:                &process_info   // pointer to PROCESS_INFORMATION
                   1435:                );
                   1436:        // Resource leak if you don't close these:
                   1437:        CloseHandle(process_info.hThread);
                   1438:        CloseHandle(process_info.hProcess);
                   1439: }
                   1440: //---------------------------------------------------------------------------
                   1441: 
                   1442: 
                   1443: 
                   1444: 
                   1445: void __fastcall TMainForm::NodeCloseButtonClick(TObject *Sender)
                   1446: {
                   1447:        ViewNodesExecute(Sender);
                   1448: }
                   1449: //---------------------------------------------------------------------------
                   1450: 
                   1451: void __fastcall TMainForm::TelnetCloseButtonClick(TObject *Sender)
                   1452: {
                   1453:        ViewTelnetExecute(Sender);
                   1454: }
                   1455: //---------------------------------------------------------------------------
                   1456: 
                   1457: void __fastcall TMainForm::MailCloseButtonClick(TObject *Sender)
                   1458: {
                   1459:        ViewMailServerExecute(Sender);
                   1460: }
                   1461: //---------------------------------------------------------------------------
                   1462: 
                   1463: void __fastcall TMainForm::FtpCloseButtonClick(TObject *Sender)
                   1464: {
                   1465:        ViewFtpServerExecute(Sender);
                   1466: }
                   1467: //---------------------------------------------------------------------------
                   1468: void __fastcall TMainForm::StatsTimerTick(TObject *Sender)
                   1469: {
                   1470:        char    str[128];
                   1471:        int     i;
                   1472:        static stats_t stats;
                   1473:        static users;
                   1474:        static newusers;
                   1475:        static counter;
                   1476: 
                   1477:        if(!StatsForm->Visible)
                   1478:                return;
                   1479: 
                   1480:     getstats(&cfg,0,&stats);
                   1481: 
                   1482:        StatsForm->TotalLogons->Caption=AnsiString(stats.logons);
                   1483:     StatsForm->LogonsToday->Caption=AnsiString(stats.ltoday);
                   1484:     StatsForm->TotalTimeOn->Caption=AnsiString(stats.timeon);
                   1485:     StatsForm->TimeToday->Caption=AnsiString(stats.ttoday);
                   1486:     StatsForm->TotalEMail->Caption=AnsiString(getmail(&cfg,0,0));
                   1487:        StatsForm->EMailToday->Caption=AnsiString(stats.etoday);
                   1488:        StatsForm->TotalFeedback->Caption=AnsiString(getmail(&cfg,1,0));
                   1489:        StatsForm->FeedbackToday->Caption=AnsiString(stats.ftoday);
                   1490:        /* Don't scan a large user database more often than necessary */
                   1491:        if(!counter || users<100 || (counter%(users/100))==0 || stats.nusers!=newusers)
                   1492:                users=total_users(&cfg);
                   1493:     StatsForm->TotalUsers->Caption=AnsiString(users);
                   1494:     StatsForm->NewUsersToday->Caption=AnsiString(newusers=stats.nusers);
                   1495:     StatsForm->PostsToday->Caption=AnsiString(stats.ptoday);
                   1496:     StatsForm->UploadedFiles->Caption=AnsiString(stats.uls);
                   1497:        if(stats.ulb>=1024*1024)
                   1498:        sprintf(str,"%.1fM",stats.ulb/(1024.0*1024.0));
                   1499:     else if(stats.ulb>=1024)
                   1500:        sprintf(str,"%luK",stats.ulb/1024);
                   1501:     else
                   1502:        sprintf(str,"%lu",stats.ulb);
                   1503:     StatsForm->UploadedBytes->Caption=AnsiString(str);
                   1504:     StatsForm->DownloadedFiles->Caption=AnsiString(stats.dls);
                   1505:        if(stats.dlb>=1024*1024)
                   1506:        sprintf(str,"%.1fM",stats.dlb/(1024.0*1024.0));
                   1507:     else if(stats.dlb>=1024)
                   1508:        sprintf(str,"%luK",stats.dlb/1024);
                   1509:     else
                   1510:        sprintf(str,"%lu",stats.dlb);
                   1511:     StatsForm->DownloadedBytes->Caption=AnsiString(str);
                   1512: 
                   1513:        counter++;
                   1514: }
                   1515: //---------------------------------------------------------------------------
                   1516: void __fastcall TMainForm::StatsCloseButtonClick(TObject *Sender)
                   1517: {
                   1518:        ViewStatsExecute(Sender);
                   1519: }
                   1520: //---------------------------------------------------------------------------
                   1521: enum {
                   1522:         PAGE_UPPERLEFT
                   1523:     ,PAGE_UPPERRIGHT
                   1524:     ,PAGE_LOWERRIGHT
                   1525:     ,PAGE_LOWERLEFT
                   1526:     };
                   1527: TPageControl* __fastcall TMainForm::PageControl(int num)
                   1528: {
                   1529:        switch(num)
                   1530:     {
                   1531:        case PAGE_UPPERLEFT:
                   1532:                return(UpperLeftPageControl);
                   1533:         case PAGE_UPPERRIGHT:
                   1534:                return(UpperRightPageControl);
                   1535:         case PAGE_LOWERRIGHT:
                   1536:                return(LowerRightPageControl);
                   1537:         case PAGE_LOWERLEFT:
                   1538:                return(LowerLeftPageControl);
                   1539:     }
                   1540:     return(NULL);
                   1541: }
                   1542: int __fastcall TMainForm::PageNum(TPageControl* obj)
                   1543: {
                   1544:     if(obj==UpperLeftPageControl)
                   1545:                return(PAGE_UPPERLEFT);
                   1546:     if(obj==UpperRightPageControl)
                   1547:                return(PAGE_UPPERRIGHT);
                   1548:     if(obj==LowerRightPageControl)
                   1549:                return(PAGE_LOWERRIGHT);
                   1550:     if(obj==LowerLeftPageControl)
                   1551:                return(PAGE_LOWERLEFT);
                   1552:        return(PAGE_LOWERRIGHT);
                   1553: }
                   1554: TColor __fastcall TMainForm::ReadColor(TRegistry* Registry
                   1555:     ,AnsiString name)
                   1556: {
                   1557:     if(Registry->ValueExists(name + "Color"))
                   1558:         return(StringToColor(Registry->ReadString(name + "Color")));
                   1559:         
                   1560:     return(clWindow);   // Default
                   1561: }
                   1562: void __fastcall TMainForm::WriteColor(TRegistry* Registry
                   1563:     ,AnsiString name, TColor color)
                   1564: {
                   1565:     Registry->WriteString(name + "Color", ColorToString(color));
                   1566: }
                   1567: 
                   1568: int FontStyleToInt(TFont* Font)
                   1569: {
                   1570:     int style=0;
                   1571:     for(int i=fsBold;i<=fsStrikeOut;i++)
                   1572:        if(Font->Style.Contains((TFontStyle)i))
                   1573:                style|=(1<<i);
                   1574:     return(style);
                   1575: }
                   1576: 
                   1577: void IntToFontStyle(int style, TFont* Font)
                   1578: {
                   1579:     Font->Style=Font->Style.Clear();
                   1580:     for(int i=fsBold;i<=fsStrikeOut;i++)
                   1581:         if(style&(1<<i))
                   1582:             Font->Style=Font->Style<<(TFontStyle)i;
                   1583: }
                   1584: 
                   1585: void __fastcall TMainForm::ReadFont(AnsiString subkey, TFont* Font)
                   1586: {
                   1587:     // Read Registry keys
                   1588:        TRegistry* Registry=new TRegistry;
                   1589:     AnsiString key = REG_KEY + subkey + "Font";
                   1590:     if(!Registry->OpenKey(key,true)) {
                   1591:        Application->MessageBox("Error opening registry key"
                   1592:                ,key.c_str(),MB_OK|MB_ICONEXCLAMATION);
                   1593:         Application->Terminate();
                   1594:         return;
                   1595:     }
                   1596:     if(Registry->ValueExists("Name"))
                   1597:         Font->Name=Registry->ReadString("Name");
                   1598:     if(Registry->ValueExists("Color"))
                   1599:         Font->Color=StringToColor(Registry->ReadString("Color"));
                   1600:     if(Registry->ValueExists("Height"))
                   1601:         Font->Height=Registry->ReadInteger("Height");
                   1602:     if(Registry->ValueExists("Size"))
                   1603:         Font->Size=Registry->ReadInteger("Size");
                   1604: 
                   1605:     if(Registry->ValueExists("Style"))
                   1606:         IntToFontStyle(Registry->ReadInteger("Style"),Font);
                   1607: 
                   1608:     Registry->CloseKey();
                   1609:     delete Registry;
                   1610: }
                   1611: void __fastcall TMainForm::WriteFont(AnsiString subkey, TFont* Font)
                   1612: {
                   1613:     // Read Registry keys
                   1614:        TRegistry* Registry=new TRegistry;
                   1615:     AnsiString key = REG_KEY + subkey + "Font";
                   1616:     if(!Registry->OpenKey(key,true)) {
                   1617:        Application->MessageBox("Error opening registry key"
                   1618:                ,key.c_str(),MB_OK|MB_ICONEXCLAMATION);
                   1619:         Application->Terminate();
                   1620:         return;
                   1621:     }
                   1622:     Registry->WriteString("Name",Font->Name);
                   1623:     Registry->WriteString("Color",ColorToString(Font->Color));
                   1624:     Registry->WriteInteger("Height",Font->Height);
                   1625:     Registry->WriteInteger("Size",Font->Size);
                   1626:     Registry->WriteInteger("Style",FontStyleToInt(Font));
                   1627: 
                   1628:     Registry->CloseKey();
                   1629:     delete Registry;
                   1630: }
                   1631: void __fastcall TMainForm::StartupTimerTick(TObject *Sender)
                   1632: {
                   1633:     bool       TelnetFormFloating=false;
                   1634:     bool       EventsFormFloating=false;
                   1635:     bool       ServicesFormFloating=false;
                   1636:     bool       NodeFormFloating=false;
                   1637:     bool       StatsFormFloating=false;
                   1638:     bool       ClientFormFloating=false;
                   1639:     bool       MailFormFloating=false;
                   1640:     bool       FtpFormFloating=false;
                   1641:     bool       WebFormFloating=false;
                   1642:     int                NodeFormPage=PAGE_UPPERLEFT;
                   1643:     int                StatsFormPage=PAGE_UPPERLEFT;
                   1644:     int                ClientFormPage=PAGE_UPPERLEFT;
                   1645:     int                TelnetFormPage=PAGE_LOWERLEFT;
                   1646:     int                EventsFormPage=PAGE_LOWERLEFT;
                   1647:     int                MailFormPage=PAGE_UPPERRIGHT;
                   1648:     int                FtpFormPage=PAGE_LOWERRIGHT;
                   1649:     int                WebFormPage=PAGE_LOWERRIGHT;
                   1650:     int     ServicesFormPage=PAGE_LOWERRIGHT;
                   1651: #if 0   /* not yet working */
                   1652:     bool       TelnetFormVisible=true;
                   1653:     bool       EventsFormVisible=true;
                   1654:     bool       ServicesFormVisible=true;
                   1655:     bool       NodeFormVisible=true;
                   1656:     bool       StatsFormVisible=true;
                   1657:     bool       ClientFormVisible=true;
                   1658:     bool       MailFormVisible=true;
                   1659:     bool       FtpFormVisible=true;
                   1660:     bool       WebFormVisible=true;
                   1661: #endif
                   1662: 
                   1663:     AnsiString Str;
                   1664: 
                   1665:     delete StartupTimer;
                   1666: 
                   1667:     // Read Registry keys
                   1668:        TRegistry* Registry=new TRegistry;
                   1669:     if(!Registry->OpenKey(REG_KEY,true)) {
                   1670:        Application->MessageBox("Error opening registry key"
                   1671:                ,REG_KEY,MB_OK|MB_ICONEXCLAMATION);
                   1672:         Application->Terminate();
                   1673:         return;
                   1674:     }
                   1675: 
                   1676:     TopPanel->Height=Height/3;
                   1677:     UpperLeftPageControl->Width=Width/2;
                   1678:     LowerLeftPageControl->Width=Width/2;
                   1679: 
                   1680:     if(Registry->ValueExists("TopPanelHeight"))
                   1681:        TopPanel->Height=Registry->ReadInteger("TopPanelHeight");
                   1682:     if(Registry->ValueExists("UpperLeftPageControlWidth"))
                   1683:        UpperLeftPageControl->Width
                   1684:                =Registry->ReadInteger("UpperLeftPageControlWidth");
                   1685:     if(Registry->ValueExists("LowerLeftPageControlWidth"))
                   1686:        LowerLeftPageControl->Width
                   1687:                =Registry->ReadInteger("LowerLeftPageControlWidth");
                   1688:     if(Registry->ValueExists("UndockableForms"))
                   1689:         UndockableForms=Registry->ReadBool("UndockableForms");
                   1690: 
                   1691:     if(UndockableForms) {
                   1692:         if(Registry->ValueExists("TelnetFormFloating"))
                   1693:             TelnetFormFloating=Registry->ReadBool("TelnetFormFloating");
                   1694:         if(Registry->ValueExists("EventsFormFloating"))
                   1695:             EventsFormFloating=Registry->ReadBool("EventsFormFloating");
                   1696:         if(Registry->ValueExists("ServicesFormFloating"))
                   1697:             ServicesFormFloating=Registry->ReadBool("ServicesFormFloating");
                   1698:         if(Registry->ValueExists("NodeFormFloating"))
                   1699:             NodeFormFloating=Registry->ReadBool("NodeFormFloating");
                   1700:         if(Registry->ValueExists("StatsFormFloating"))
                   1701:             StatsFormFloating=Registry->ReadBool("StatsFormFloating");
                   1702:         if(Registry->ValueExists("ClientFormFloating"))
                   1703:             ClientFormFloating=Registry->ReadBool("ClientFormFloating");
                   1704:         if(Registry->ValueExists("MailFormFloating"))
                   1705:             MailFormFloating=Registry->ReadBool("MailFormFloating");
                   1706:         if(Registry->ValueExists("FtpFormFloating"))
                   1707:             FtpFormFloating=Registry->ReadBool("FtpFormFloating");
                   1708:         if(Registry->ValueExists("WebFormFloating"))
                   1709:             WebFormFloating=Registry->ReadBool("WebFormFloating");
                   1710:     }
                   1711: #if 0
                   1712:     if(Registry->ValueExists("TelnetFormVisible"))
                   1713:         TelnetFormVisible=Registry->ReadBool("TelnetFormVisible");
                   1714:     if(Registry->ValueExists("EventsFormVisible"))
                   1715:         EventsFormVisible=Registry->ReadBool("EventsFormVisible");
                   1716:     if(Registry->ValueExists("ServicesFormVisible"))
                   1717:         ServicesFormVisible=Registry->ReadBool("ServicesFormVisible");
                   1718:     if(Registry->ValueExists("NodeFormVisible"))
                   1719:         NodeFormVisible=Registry->ReadBool("NodeFormVisible");
                   1720:     if(Registry->ValueExists("StatsFormVisible"))
                   1721:         StatsFormVisible=Registry->ReadBool("StatsFormVisible");
                   1722:     if(Registry->ValueExists("ClientFormVisible"))
                   1723:         ClientFormVisible=Registry->ReadBool("ClientFormVisible");
                   1724:     if(Registry->ValueExists("MailFormVisible"))
                   1725:         MailFormVisible=Registry->ReadBool("MailFormVisible");
                   1726:     if(Registry->ValueExists("FtpFormVisible"))
                   1727:         FtpFormVisible=Registry->ReadBool("FtpFormVisible");
                   1728:     if(Registry->ValueExists("WebFormVisible"))
                   1729:         WebFormVisible=Registry->ReadBool("WebFormVisible");
                   1730: #endif
                   1731:     if(Registry->ValueExists("TelnetFormPage"))
                   1732:        TelnetFormPage=Registry->ReadInteger("TelnetFormPage");
                   1733:     if(Registry->ValueExists("EventsFormPage"))
                   1734:        EventsFormPage=Registry->ReadInteger("EventsFormPage");
                   1735:     if(Registry->ValueExists("ServicesFormPage"))
                   1736:        ServicesFormPage=Registry->ReadInteger("ServicesFormPage");
                   1737:     if(Registry->ValueExists("NodeFormPage"))
                   1738:        NodeFormPage=Registry->ReadInteger("NodeFormPage");
                   1739:     if(Registry->ValueExists("StatsFormPage"))
                   1740:        StatsFormPage=Registry->ReadInteger("StatsFormPage");
                   1741:     if(Registry->ValueExists("ClientFormPage"))
                   1742:        ClientFormPage=Registry->ReadInteger("ClientFormPage");
                   1743:     if(Registry->ValueExists("MailFormPage"))
                   1744:        MailFormPage=Registry->ReadInteger("MailFormPage");
                   1745:     if(Registry->ValueExists("FtpFormPage"))
                   1746:        FtpFormPage=Registry->ReadInteger("FtpFormPage");
                   1747:     if(Registry->ValueExists("WebFormPage"))
                   1748:        WebFormPage=Registry->ReadInteger("WebFormPage");
                   1749: 
                   1750:     TelnetForm->Log->Color=ReadColor(Registry,"TelnetLog");
                   1751:     ReadFont("TelnetLog",TelnetForm->Log->Font);
                   1752:     EventsForm->Log->Color=ReadColor(Registry,"EventsLog");
                   1753:     ReadFont("EventsLog",EventsForm->Log->Font);
                   1754:     ServicesForm->Log->Color=ReadColor(Registry,"ServicesLog");
                   1755:     ReadFont("ServicesLog",ServicesForm->Log->Font);
                   1756:     MailForm->Log->Color=ReadColor(Registry,"MailLog");
                   1757:     ReadFont("MailLog",MailForm->Log->Font);
                   1758:     FtpForm->Log->Color=ReadColor(Registry,"FtpLog");
                   1759:     ReadFont("FtpLog",FtpForm->Log->Font);
                   1760:     WebForm->Log->Color=ReadColor(Registry,"WebLog");
                   1761:     ReadFont("WebLog",WebForm->Log->Font);
                   1762:     NodeForm->ListBox->Color=ReadColor(Registry,"NodeList");
                   1763:     ReadFont("NodeList",NodeForm->ListBox->Font);
                   1764:     ClientForm->ListView->Color=ReadColor(Registry,"ClientList");
                   1765:     ReadFont("ClientList",ClientForm->ListView->Font);
                   1766: 
                   1767:        if(Registry->ValueExists("TelnetFormTop"))
                   1768:        TelnetForm->Top=Registry->ReadInteger("TelnetFormTop");
                   1769:        if(Registry->ValueExists("TelnetFormLeft"))
                   1770:        TelnetForm->Left=Registry->ReadInteger("TelnetFormLeft");
                   1771:        if(Registry->ValueExists("TelnetFormWidth"))
                   1772:        TelnetForm->Width=Registry->ReadInteger("TelnetFormWidth");
                   1773:        if(Registry->ValueExists("TelnetFormHeight"))
                   1774:        TelnetForm->Height=Registry->ReadInteger("TelnetFormHeight");
                   1775: 
                   1776:        if(Registry->ValueExists("EventsFormTop"))
                   1777:        EventsForm->Top=Registry->ReadInteger("EventsFormTop");
                   1778:        if(Registry->ValueExists("EventsFormLeft"))
                   1779:        EventsForm->Left=Registry->ReadInteger("EventsFormLeft");
                   1780:        if(Registry->ValueExists("EventsFormWidth"))
                   1781:        EventsForm->Width=Registry->ReadInteger("EventsFormWidth");
                   1782:        if(Registry->ValueExists("EventsFormHeight"))
                   1783:        EventsForm->Height=Registry->ReadInteger("EventsFormHeight");
                   1784: 
                   1785:        if(Registry->ValueExists("ServicesFormTop"))
                   1786:        ServicesForm->Top=Registry->ReadInteger("ServicesFormTop");
                   1787:        if(Registry->ValueExists("ServicesFormLeft"))
                   1788:        ServicesForm->Left=Registry->ReadInteger("ServicesFormLeft");
                   1789:        if(Registry->ValueExists("ServicesFormWidth"))
                   1790:        ServicesForm->Width=Registry->ReadInteger("ServicesFormWidth");
                   1791:        if(Registry->ValueExists("ServicesFormHeight"))
                   1792:        ServicesForm->Height=Registry->ReadInteger("ServicesFormHeight");
                   1793: 
                   1794:        if(Registry->ValueExists("FtpFormTop"))
                   1795:        FtpForm->Top=Registry->ReadInteger("FtpFormTop");
                   1796:        if(Registry->ValueExists("FtpFormLeft"))
                   1797:        FtpForm->Left=Registry->ReadInteger("FtpFormLeft");
                   1798:        if(Registry->ValueExists("FtpFormWidth"))
                   1799:        FtpForm->Width=Registry->ReadInteger("FtpFormWidth");
                   1800:        if(Registry->ValueExists("FtpFormHeight"))
                   1801:        FtpForm->Height=Registry->ReadInteger("FtpFormHeight");
                   1802: 
                   1803:        if(Registry->ValueExists("WebFormTop"))
                   1804:        WebForm->Top=Registry->ReadInteger("WebFormTop");
                   1805:        if(Registry->ValueExists("WebFormLeft"))
                   1806:        WebForm->Left=Registry->ReadInteger("WebFormLeft");
                   1807:        if(Registry->ValueExists("WebFormWidth"))
                   1808:        WebForm->Width=Registry->ReadInteger("WebFormWidth");
                   1809:        if(Registry->ValueExists("WebFormHeight"))
                   1810:        WebForm->Height=Registry->ReadInteger("WebFormHeight");
                   1811: 
                   1812:        if(Registry->ValueExists("MailFormTop"))
                   1813:        MailForm->Top=Registry->ReadInteger("MailFormTop");
                   1814:        if(Registry->ValueExists("MailFormLeft"))
                   1815:        MailForm->Left=Registry->ReadInteger("MailFormLeft");
                   1816:        if(Registry->ValueExists("MailFormWidth"))
                   1817:        MailForm->Width=Registry->ReadInteger("MailFormWidth");
                   1818:        if(Registry->ValueExists("MailFormHeight"))
                   1819:        MailForm->Height=Registry->ReadInteger("MailFormHeight");
                   1820: 
                   1821:        if(Registry->ValueExists("NodeFormTop"))
                   1822:        NodeForm->Top=Registry->ReadInteger("NodeFormTop");
                   1823:        if(Registry->ValueExists("NodeFormLeft"))
                   1824:        NodeForm->Left=Registry->ReadInteger("NodeFormLeft");
                   1825:        if(Registry->ValueExists("NodeFormWidth"))
                   1826:        NodeForm->Width=Registry->ReadInteger("NodeFormWidth");
                   1827:        if(Registry->ValueExists("NodeFormHeight"))
                   1828:        NodeForm->Height=Registry->ReadInteger("NodeFormHeight");
                   1829: 
                   1830:        if(Registry->ValueExists("StatsFormTop"))
                   1831:        StatsForm->Top=Registry->ReadInteger("StatsFormTop");
                   1832:        if(Registry->ValueExists("StatsFormLeft"))
                   1833:        StatsForm->Left=Registry->ReadInteger("StatsFormLeft");
                   1834:        if(Registry->ValueExists("StatsFormWidth"))
                   1835:        StatsForm->Width=Registry->ReadInteger("StatsFormWidth");
                   1836:        if(Registry->ValueExists("StatsFormHeight"))
                   1837:        StatsForm->Height=Registry->ReadInteger("StatsFormHeight");
                   1838: 
                   1839:        if(Registry->ValueExists("ClientFormTop"))
                   1840:        ClientForm->Top=Registry->ReadInteger("ClientFormTop");
                   1841:        if(Registry->ValueExists("ClientFormLeft"))
                   1842:        ClientForm->Left=Registry->ReadInteger("ClientFormLeft");
                   1843:        if(Registry->ValueExists("ClientFormWidth"))
                   1844:        ClientForm->Width=Registry->ReadInteger("ClientFormWidth");
                   1845:        if(Registry->ValueExists("ClientFormHeight"))
                   1846:        ClientForm->Height=Registry->ReadInteger("ClientFormHeight");
                   1847: 
                   1848:     for(int i=0;i<ClientForm->ListView->Columns->Count;i++) {
                   1849:         char str[128];
                   1850:         sprintf(str,"ClientListColumn%dWidth",i);
                   1851:         if(Registry->ValueExists(str))
                   1852:             ClientForm->ListView->Columns->Items[i]->Width
                   1853:                 =Registry->ReadInteger(str);
                   1854:     }
                   1855: 
                   1856:     if(Registry->ValueExists("ToolbarVisible"))
                   1857:        Toolbar->Visible=Registry->ReadBool("ToolbarVisible");
                   1858: 
                   1859:     ViewToolbarMenuItem->Checked=Toolbar->Visible;
                   1860:     ViewStatusBarMenuItem->Checked=StatusBar->Visible;
                   1861: 
                   1862:     if(Registry->ValueExists("MaxLogLen"))
                   1863:        MaxLogLen=Registry->ReadInteger("MaxLogLen");
                   1864: 
                   1865:     if(Registry->ValueExists("LoginCommand"))
                   1866:        LoginCommand=Registry->ReadString("LoginCommand");
                   1867:     if(Registry->ValueExists("ConfigCommand"))
                   1868:        ConfigCommand=Registry->ReadString("ConfigCommand");
                   1869:     if(Registry->ValueExists("Password"))
                   1870:        Password=Registry->ReadString("Password");
                   1871:     if(Registry->ValueExists("MinimizeToSysTray"))
                   1872:        MinimizeToSysTray=Registry->ReadBool("MinimizeToSysTray");
                   1873:     if(Registry->ValueExists("UseFileAssociations"))
                   1874:        UseFileAssociations=Registry->ReadBool("UseFileAssociations");
                   1875:        if(Registry->ValueExists("NodeDisplayInterval"))
                   1876:        NodeForm->Timer->Interval=Registry->ReadInteger("NodeDisplayInterval")*1000;
                   1877:        if(Registry->ValueExists("ClientDisplayInterval"))
                   1878:        ClientForm->Timer->Interval=Registry->ReadInteger("ClientDisplayInterval")*1000;
                   1879: 
                   1880:     if(Registry->ValueExists("MailLogFile"))
                   1881:        MailLogFile=Registry->ReadInteger("MailLogFile");
                   1882:     else
                   1883:        MailLogFile=true;
                   1884: 
                   1885:     if(Registry->ValueExists("FtpLogFile"))
                   1886:        FtpLogFile=Registry->ReadInteger("FtpLogFile");
                   1887:     else
                   1888:        FtpLogFile=true;
                   1889: 
                   1890:     FILE* fp;
                   1891:     if((!Registry->ValueExists("SysAutoStart")
                   1892:         || (Registry->ValueExists("Imported") && Registry->ReadBool("Imported")))
                   1893:         && ini_file[0]) {
                   1894:         if((fp=fopen(ini_file,"r"))==NULL) {
                   1895:             char err[MAX_PATH*2];
                   1896:             sprintf(err,"Error %d opening initialization file: %s",errno,ini_file);
                   1897:             Application->MessageBox(err,"ERROR",MB_OK|MB_ICONEXCLAMATION);
                   1898:             Application->Terminate();
                   1899:             return;
                   1900:         }
                   1901:         sbbs_read_ini(fp
                   1902:             ,&global
                   1903:             ,&SysAutoStart             ,&bbs_startup
                   1904:             ,&FtpAutoStart                     ,&ftp_startup
                   1905:             ,&WebAutoStart                     ,&web_startup
                   1906:             ,&MailAutoStart        ,&mail_startup
                   1907:             ,&ServicesAutoStart     ,&services_startup
                   1908:             );
                   1909:                StatusBar->Panels->Items[4]->Text="Read " + AnsiString(ini_file);
                   1910:         fclose(fp);
                   1911: 
                   1912:     } else {    /* Legacy (v3.10-3.11) */
                   1913: 
                   1914:         if(Registry->ValueExists("SysAutoStart"))
                   1915:             SysAutoStart=Registry->ReadInteger("SysAutoStart");
                   1916:         else
                   1917:             SysAutoStart=true;
                   1918: 
                   1919:         if(Registry->ValueExists("MailAutoStart"))
                   1920:             MailAutoStart=Registry->ReadInteger("MailAutoStart");
                   1921:         else
                   1922:             MailAutoStart=true;
                   1923: 
                   1924:         if(Registry->ValueExists("FtpAutoStart"))
                   1925:             FtpAutoStart=Registry->ReadInteger("FtpAutoStart");
                   1926:         else
                   1927:             FtpAutoStart=true;
                   1928: 
                   1929:         if(Registry->ValueExists("WebAutoStart"))
                   1930:             WebAutoStart=Registry->ReadInteger("WebAutoStart");
                   1931:         else
                   1932:             WebAutoStart=true;
                   1933: 
                   1934:         if(Registry->ValueExists("ServicesAutoStart"))
                   1935:             ServicesAutoStart=Registry->ReadInteger("ServicesAutoStart");
                   1936:         else
                   1937:             ServicesAutoStart=true;
                   1938: 
                   1939:         if(Registry->ValueExists("Hostname"))
                   1940:             SAFECOPY(global.host_name,Registry->ReadString("Hostname").c_str());
                   1941:                if(Registry->ValueExists("CtrlDirectory"))
                   1942:             SAFECOPY(global.ctrl_dir,Registry->ReadString("CtrlDirectory").c_str());
                   1943:         if(Registry->ValueExists("TempDirectory"))
                   1944:             SAFECOPY(global.temp_dir,Registry->ReadString("TempDirectory").c_str());
                   1945: 
                   1946:         if(Registry->ValueExists("SemFileCheckFrequency"))
                   1947:             global.sem_chk_freq=Registry->ReadInteger("SemFileCheckFrequency");
                   1948: 
                   1949:         /* JavaScript Operating Parameters */
                   1950:         if(Registry->ValueExists("JS_MaxBytes"))
                   1951:             global.js.max_bytes=Registry->ReadInteger("JS_MaxBytes");
                   1952:         if(global.js.max_bytes==0)
                   1953:             global.js.max_bytes=JAVASCRIPT_MAX_BYTES;
                   1954:         if(Registry->ValueExists("JS_ContextStack"))
                   1955:             global.js.cx_stack=Registry->ReadInteger("JS_ContextStack");
                   1956:         if(global.js.cx_stack==0)
                   1957:             global.js.cx_stack=JAVASCRIPT_CONTEXT_STACK;
                   1958:         if(Registry->ValueExists("JS_BranchLimit"))
                   1959:             global.js.branch_limit=Registry->ReadInteger("JS_BranchLimit");
                   1960:         if(Registry->ValueExists("JS_GcInterval"))
                   1961:             global.js.gc_interval=Registry->ReadInteger("JS_GcInterval");
                   1962:         if(Registry->ValueExists("JS_YieldInterval"))
                   1963:             global.js.yield_interval=Registry->ReadInteger("JS_YieldInterval");
                   1964: 
                   1965:         if(Registry->ValueExists("TelnetInterface"))
                   1966:             bbs_startup.telnet_interface=Registry->ReadInteger("TelnetInterface");
                   1967:         if(Registry->ValueExists("RLoginInterface"))
                   1968:             bbs_startup.rlogin_interface=Registry->ReadInteger("RLoginInterface");
                   1969: 
                   1970:         if(Registry->ValueExists("TelnetPort"))
                   1971:             bbs_startup.telnet_port=Registry->ReadInteger("TelnetPort");
                   1972:         if(Registry->ValueExists("RLoginPort"))
                   1973:             bbs_startup.rlogin_port=Registry->ReadInteger("RLoginPort");
                   1974: 
                   1975:         if(Registry->ValueExists("FirstNode"))
                   1976:             bbs_startup.first_node=Registry->ReadInteger("FirstNode");
                   1977: 
                   1978:         if(Registry->ValueExists("LastNode"))
                   1979:             bbs_startup.last_node=Registry->ReadInteger("LastNode");
                   1980: 
                   1981:         if(Registry->ValueExists("OutbufHighwaterMark"))
                   1982:             bbs_startup.outbuf_highwater_mark=Registry->ReadInteger("OutbufHighwaterMark");
                   1983:         else
                   1984:             bbs_startup.outbuf_highwater_mark=1024;
                   1985:         if(Registry->ValueExists("OutbufDrainTimeout"))
                   1986:             bbs_startup.outbuf_drain_timeout=Registry->ReadInteger("OutbufDrainTimeout");
                   1987:         else
                   1988:             bbs_startup.outbuf_drain_timeout=10;
                   1989: 
                   1990:         if(Registry->ValueExists("AnswerSound"))
                   1991:             SAFECOPY(bbs_startup.answer_sound
                   1992:                 ,Registry->ReadString("AnswerSound").c_str());
                   1993: 
                   1994:         if(Registry->ValueExists("HangupSound"))
                   1995:             SAFECOPY(bbs_startup.hangup_sound
                   1996:                 ,Registry->ReadString("HangupSound").c_str());
                   1997: 
                   1998:         if(Registry->ValueExists("StartupOptions"))
                   1999:             bbs_startup.options=Registry->ReadInteger("StartupOptions");
                   2000: 
                   2001:         if(Registry->ValueExists("MailMaxClients"))
                   2002:             mail_startup.max_clients=Registry->ReadInteger("MailMaxClients");
                   2003: 
                   2004:         if(Registry->ValueExists("MailMaxInactivity"))
                   2005:             mail_startup.max_inactivity=Registry->ReadInteger("MailMaxInactivity");
                   2006: 
                   2007:         if(Registry->ValueExists("MailInterface"))
                   2008:             mail_startup.interface_addr=Registry->ReadInteger("MailInterface");
                   2009: 
                   2010:         if(Registry->ValueExists("MailMaxDeliveryAttempts"))
                   2011:             mail_startup.max_delivery_attempts
                   2012:                 =Registry->ReadInteger("MailMaxDeliveryAttempts");
                   2013: 
                   2014:         if(Registry->ValueExists("MailRescanFrequency"))
                   2015:             mail_startup.rescan_frequency
                   2016:                 =Registry->ReadInteger("MailRescanFrequency");
                   2017: 
                   2018:         if(Registry->ValueExists("MailLinesPerYield"))
                   2019:             mail_startup.lines_per_yield
                   2020:                 =Registry->ReadInteger("MailLinesPerYield");
                   2021: 
                   2022:         if(Registry->ValueExists("MailMaxRecipients"))
                   2023:             mail_startup.max_recipients
                   2024:                 =Registry->ReadInteger("MailMaxRecipients");
                   2025: 
                   2026:         if(Registry->ValueExists("MailMaxMsgSize"))
                   2027:             mail_startup.max_msg_size
                   2028:                 =Registry->ReadInteger("MailMaxMsgSize");
                   2029: 
                   2030:         if(Registry->ValueExists("MailSMTPPort"))
                   2031:             mail_startup.smtp_port=Registry->ReadInteger("MailSMTPPort");
                   2032: 
                   2033:         if(Registry->ValueExists("MailPOP3Port"))
                   2034:             mail_startup.pop3_port=Registry->ReadInteger("MailPOP3Port");
                   2035: 
                   2036:         if(Registry->ValueExists("MailRelayServer"))
                   2037:             SAFECOPY(mail_startup.relay_server
                   2038:                 ,Registry->ReadString("MailRelayServer").c_str());
                   2039: 
                   2040:         if(Registry->ValueExists("MailRelayPort"))
                   2041:             mail_startup.relay_port=Registry->ReadInteger("MailRelayPort");
                   2042: 
                   2043:         if(Registry->ValueExists("MailDefaultUser"))
                   2044:             SAFECOPY(mail_startup.default_user
                   2045:                 ,Registry->ReadString("MailDefaultUser").c_str());
                   2046: 
                   2047:         if(Registry->ValueExists("MailDNSBlacklistSubject"))
                   2048:             SAFECOPY(mail_startup.dnsbl_tag
                   2049:                 ,Registry->ReadString("MailDNSBlacklistSubject").c_str());
                   2050:         else
                   2051:             SAFECOPY(mail_startup.dnsbl_tag,"SPAM");
                   2052: 
                   2053:         if(Registry->ValueExists("MailDNSBlacklistHeader"))
                   2054:             SAFECOPY(mail_startup.dnsbl_hdr
                   2055:                 ,Registry->ReadString("MailDNSBlacklistHeader").c_str());
                   2056:         else
                   2057:             SAFECOPY(mail_startup.dnsbl_hdr,"X-DNSBL");
                   2058: 
                   2059:         if(Registry->ValueExists("MailDNSServer"))
                   2060:             SAFECOPY(mail_startup.dns_server
                   2061:                 ,Registry->ReadString("MailDNSServer").c_str());
                   2062: 
                   2063:         if(Registry->ValueExists("MailInboundSound"))
                   2064:             SAFECOPY(mail_startup.inbound_sound
                   2065:                 ,Registry->ReadString("MailInboundSound").c_str());
                   2066: 
                   2067:         if(Registry->ValueExists("MailOutboundSound"))
                   2068:             SAFECOPY(mail_startup.outbound_sound
                   2069:                 ,Registry->ReadString("MailOutboundSound").c_str());
                   2070: 
                   2071:         if(Registry->ValueExists("MailPOP3Sound"))
                   2072:             SAFECOPY(mail_startup.pop3_sound
                   2073:                 ,Registry->ReadString("MailPOP3Sound").c_str());
                   2074: 
                   2075:         if(Registry->ValueExists("MailOptions"))
                   2076:             mail_startup.options=Registry->ReadInteger("MailOptions");
                   2077: 
                   2078:         if(Registry->ValueExists("FtpMaxClients"))
                   2079:             ftp_startup.max_clients=Registry->ReadInteger("FtpMaxClients");
                   2080: 
                   2081:         if(Registry->ValueExists("FtpMaxInactivity"))
                   2082:             ftp_startup.max_inactivity=Registry->ReadInteger("FtpMaxInactivity");
                   2083: 
                   2084:         if(Registry->ValueExists("FtpQwkTimeout"))
                   2085:             ftp_startup.qwk_timeout=Registry->ReadInteger("FtpQwkTimeout");
                   2086: 
                   2087:         if(Registry->ValueExists("FtpInterface"))
                   2088:             ftp_startup.interface_addr=Registry->ReadInteger("FtpInterface");
                   2089: 
                   2090:         if(Registry->ValueExists("FtpPort"))
                   2091:             ftp_startup.port=Registry->ReadInteger("FtpPort");
                   2092: 
                   2093:         if(Registry->ValueExists("FtpAnswerSound"))
                   2094:             SAFECOPY(ftp_startup.answer_sound
                   2095:                 ,Registry->ReadString("FtpAnswerSound").c_str());
                   2096: 
                   2097:         if(Registry->ValueExists("FtpHangupSound"))
                   2098:             SAFECOPY(ftp_startup.hangup_sound
                   2099:                 ,Registry->ReadString("FtpHangupSound").c_str());
                   2100: 
                   2101:         if(Registry->ValueExists("FtpHackAttemptSound"))
                   2102:             SAFECOPY(ftp_startup.hack_sound
                   2103:                 ,Registry->ReadString("FtpHackAttemptSound").c_str());
                   2104: 
                   2105:         if(Registry->ValueExists("FtpIndexFileName"))
                   2106:             SAFECOPY(ftp_startup.index_file_name
                   2107:                 ,Registry->ReadString("FtpIndexFileName").c_str());
                   2108: 
                   2109:         if(Registry->ValueExists("FtpHtmlIndexFile"))
                   2110:             SAFECOPY(ftp_startup.html_index_file
                   2111:                 ,Registry->ReadString("FtpHtmlIndexFile").c_str());
                   2112: 
                   2113:         if(Registry->ValueExists("FtpHtmlIndexScript"))
                   2114:             SAFECOPY(ftp_startup.html_index_script
                   2115:                 ,Registry->ReadString("FtpHtmlIndexScript").c_str());
                   2116: 
                   2117:         if(Registry->ValueExists("FtpOptions"))
                   2118:             ftp_startup.options=Registry->ReadInteger("FtpOptions");
                   2119: 
                   2120:         if(Registry->ValueExists("ServicesInterface"))
                   2121:             services_startup.interface_addr
                   2122:                 =Registry->ReadInteger("ServicesInterface");
                   2123: 
                   2124:         if(Registry->ValueExists("ServicesAnswerSound"))
                   2125:             SAFECOPY(services_startup.answer_sound
                   2126:                 ,Registry->ReadString("ServicesAnswerSound").c_str());
                   2127: 
                   2128:         if(Registry->ValueExists("ServicesHangupSound"))
                   2129:             SAFECOPY(services_startup.hangup_sound
                   2130:                 ,Registry->ReadString("ServicesHangupSound").c_str());
                   2131: 
                   2132:         if(Registry->ValueExists("ServicesOptions"))
                   2133:             services_startup.options=Registry->ReadInteger("ServicesOptions");
                   2134: 
                   2135:                if(SaveIniSettings(Sender))
                   2136:             Registry->WriteBool("Imported",true);   /* Use the .ini file for these settings from now on */
                   2137: 
                   2138: #if 0
                   2139:         /******************************************************/
                   2140:         /* Copy global values into each server startup struct */
                   2141:         /******************************************************/
                   2142: 
                   2143:         /* used to be handled in bbs_start() */
                   2144:         SAFECOPY(bbs_startup.ctrl_dir,global.ctrl_dir);
                   2145:         SAFECOPY(bbs_startup.temp_dir,global.temp_dir);
                   2146:         SAFECOPY(bbs_startup.host_name,global.host_name);
                   2147:         bbs_startup.sem_chk_freq=global.sem_chk_freq;
                   2148: 
                   2149:         /* JavaScript operational parameters */
                   2150:         bbs_startup.js_max_bytes=global.js.max_bytes;
                   2151:         bbs_startup.js_cx_stack=global.js.cx_stack;
                   2152:         bbs_startup.js_branch_limit=global.js.branch_limit;
                   2153:         bbs_startup.js_gc_interval=global.js.gc_interval;
                   2154:         bbs_startup.js_yield_interval=global.js.yield_interval;
                   2155: 
                   2156:         /* used to be handled in mail_start() */
                   2157:         SAFECOPY(mail_startup.ctrl_dir
                   2158:             ,global.ctrl_dir);
                   2159:         SAFECOPY(mail_startup.host_name
                   2160:             ,global.host_name);
                   2161:         mail_startup.sem_chk_freq=global.sem_chk_freq;
                   2162: 
                   2163:         /* used to be handled in ftp_start() */
                   2164:         SAFECOPY(ftp_startup.ctrl_dir
                   2165:             ,global.ctrl_dir);
                   2166:         SAFECOPY(ftp_startup.temp_dir
                   2167:             ,global.temp_dir);
                   2168:         SAFECOPY(ftp_startup.host_name
                   2169:             ,global.host_name);
                   2170:         ftp_startup.sem_chk_freq=global.sem_chk_freq;
                   2171: 
                   2172:         /* JavaScript operational parameters */
                   2173:         ftp_startup.js_max_bytes=global.js.max_bytes;
                   2174:         ftp_startup.js_cx_stack=global.js.cx_stack;
                   2175: 
                   2176:         /* used to be handled in web_start() */
                   2177:         SAFECOPY(web_startup.ctrl_dir,global.ctrl_dir);
                   2178:         SAFECOPY(web_startup.host_name,global.host_name);
                   2179:         web_startup.sem_chk_freq=global.sem_chk_freq;
                   2180: 
                   2181:         /* JavaScript operational parameters */
                   2182:         web_startup.js_max_bytes=global.js.max_bytes;
                   2183:         web_startup.js_cx_stack=global.js.cx_stack;
                   2184: 
                   2185:         /* used to be handled in ServicesStartExecute() */
                   2186:         SAFECOPY(services_startup.ctrl_dir,global.ctrl_dir);
                   2187:         SAFECOPY(services_startup.host_name,global.host_name);
                   2188:         services_startup.sem_chk_freq=global.sem_chk_freq;
                   2189: 
                   2190:         /* JavaScript operational parameters */
                   2191:         services_startup.js_max_bytes=global.js.max_bytes;
                   2192:         services_startup.js_cx_stack=global.js.cx_stack;
                   2193:         services_startup.js_branch_limit=global.js.branch_limit;
                   2194:         services_startup.js_gc_interval=global.js.gc_interval;
                   2195:         services_startup.js_yield_interval=global.js.yield_interval;
                   2196: #endif
                   2197:     }
                   2198: 
                   2199:     Registry->CloseKey();
                   2200:     delete Registry;
                   2201: 
                   2202:     AnsiString CtrlDirectory = AnsiString(global.ctrl_dir);
                   2203:     if(!FileExists(CtrlDirectory+"MAIN.CNF")) {
                   2204:                Application->CreateForm(__classid(TCtrlPathDialog), &CtrlPathDialog);
                   2205:        if(CtrlPathDialog->ShowModal()!=mrOk) {
                   2206:                Application->Terminate();
                   2207:             return;
                   2208:         }
                   2209:         CtrlDirectory=CtrlPathDialog->Edit->Text;
                   2210:         delete CtrlPathDialog;
                   2211:     }
                   2212:     if(CtrlDirectory.UpperCase().AnsiPos("MAIN.CNF"))
                   2213:                CtrlDirectory.SetLength(CtrlDirectory.Length()-8);
                   2214:     SAFECOPY(global.ctrl_dir,CtrlDirectory.c_str());
                   2215:     memset(&cfg,0,sizeof(cfg));
                   2216:     SAFECOPY(cfg.ctrl_dir,global.ctrl_dir);
                   2217:     cfg.size=sizeof(cfg);
                   2218:     cfg.node_num=bbs_startup.first_node;
                   2219:     char error[256];
                   2220:        SAFECOPY(error,UNKNOWN_LOAD_ERROR);
                   2221:        if(!load_cfg(&cfg, NULL, TRUE, error)) {
                   2222:        Application->MessageBox(error,"ERROR Loading Configuration"
                   2223:                ,MB_OK|MB_ICONEXCLAMATION);
                   2224:         Application->Terminate();
                   2225:         return;
                   2226:     }
                   2227: 
                   2228:        recycle_semfiles=semfile_list_init(cfg.ctrl_dir,"recycle","ctrl");
                   2229:        semfile_list_check(&initialized,recycle_semfiles);
                   2230: 
                   2231:        shutdown_semfiles=semfile_list_init(cfg.ctrl_dir,"shutdown","ctrl");
                   2232:        semfile_list_check(&initialized,shutdown_semfiles);
                   2233: 
                   2234:     if(!(cfg.sys_misc&SM_LOCAL_TZ)) {
                   2235:        if(putenv("TZ=UTC0")) {
                   2236:                Application->MessageBox("Error setting timezone"
                   2237:                ,"ERROR",MB_OK|MB_ICONEXCLAMATION);
                   2238:             Application->Terminate();
                   2239:         }
                   2240:        tzset();
                   2241:     }
                   2242: 
                   2243:     if(cfg.new_install) {
                   2244:        Application->BringToFront();
                   2245:         for(int i=0;i<10;i++) {
                   2246:                Application->ProcessMessages();
                   2247:                Sleep(300);     // Let 'em see the logo for a bit
                   2248:         }
                   2249:         BBSConfigWizardMenuItemClick(Sender);
                   2250:     }
                   2251: 
                   2252:     if(bbs_startup.options&BBS_OPT_MUTE)
                   2253:        SoundToggle->Checked=false;
                   2254:     else
                   2255:        SoundToggle->Checked=true;
                   2256: 
                   2257:     if(bbs_startup.options&BBS_OPT_SYSOP_AVAILABLE)
                   2258:        ChatToggle->Checked=true;
                   2259:     else
                   2260:        ChatToggle->Checked=false;
                   2261: 
                   2262:        if(!NodeFormFloating)
                   2263:        NodeForm->ManualDock(PageControl(NodeFormPage),NULL,alClient);
                   2264:        if(!ClientFormFloating)
                   2265:        ClientForm->ManualDock(PageControl(ClientFormPage),NULL,alClient);
                   2266:        if(!StatsFormFloating)
                   2267:        StatsForm->ManualDock(PageControl(StatsFormPage),NULL,alClient);
                   2268:        if(!MailFormFloating)
                   2269:        MailForm->ManualDock(PageControl(MailFormPage),NULL,alClient);
                   2270:        if(!TelnetFormFloating)
                   2271:        TelnetForm->ManualDock(PageControl(TelnetFormPage),NULL,alClient);
                   2272:        if(!EventsFormFloating)
                   2273:        EventsForm->ManualDock(PageControl(EventsFormPage),NULL,alClient);
                   2274:        if(!ServicesFormFloating)
                   2275:        ServicesForm->ManualDock(PageControl(ServicesFormPage),NULL,alClient);
                   2276:        if(!FtpFormFloating)
                   2277:        FtpForm->ManualDock(PageControl(FtpFormPage),NULL,alClient);
                   2278:        if(!WebFormFloating)
                   2279:        WebForm->ManualDock(PageControl(WebFormPage),NULL,alClient);
                   2280: 
                   2281:     NodeForm->Show();
                   2282: //    ViewNodes->Checked=NodeFormVisible,     ViewNodesExecute(Sender);
                   2283:     ClientForm->Show();
                   2284: //    ViewClients->Checked=ClientFormVisible, ViewClientsExecute(Sender);
                   2285:     StatsForm->Show();
                   2286: //    ViewStats->Checked=StatsFormVisible,    ViewStatsExecute(Sender);
                   2287:     TelnetForm->Show();
                   2288: //    ViewTelnet->Checked=TelnetFormVisible,  ViewTelnetExecute(Sender);
                   2289:     EventsForm->Show();
                   2290: //    ViewEvents->Checked=EventsFormVisible,  ViewEventsExecute(Sender);
                   2291:     FtpForm->Show();
                   2292: //    ViewFtpServer->Checked=FtpFormVisible,  ViewFtpServerExecute(Sender);
                   2293:     WebForm->Show();
                   2294: //    ViewWebServer->Checked=WebFormVisible;
                   2295: //    WebForm->Visible=ViewWebServer->Checked;
                   2296:     MailForm->Show();
                   2297: //    ViewMailServer->Checked=MailFormVisible,ViewMailServerExecute(Sender);
                   2298:     ServicesForm->Show();
                   2299: //    ViewServices->Checked=ServicesFormVisible,ViewServicesExecute(Sender);
                   2300: 
                   2301:        UpperLeftPageControl->Visible=true;
                   2302:        UpperRightPageControl->Visible=true;
                   2303:        LowerLeftPageControl->Visible=true;
                   2304:        LowerRightPageControl->Visible=true;
                   2305:        HorizontalSplitter->Visible=true;
                   2306:     BottomPanel->Visible=true;
                   2307:        TopPanel->Visible=true;
                   2308: 
                   2309:     // Work-around for CB5 PageControl anomaly
                   2310:     int i;
                   2311: 
                   2312:     for(i=1;i<UpperLeftPageControl->PageCount;i++)
                   2313:         UpperLeftPageControl->ActivePageIndex=i;
                   2314:     UpperLeftPageControl->ActivePageIndex=0;
                   2315: 
                   2316:     for(i=1;i<UpperRightPageControl->PageCount;i++)
                   2317:         UpperRightPageControl->ActivePageIndex=i;
                   2318:     UpperRightPageControl->ActivePageIndex=0;
                   2319: 
                   2320:     for(i=1;i<LowerRightPageControl->PageCount;i++)
                   2321:         LowerRightPageControl->ActivePageIndex=i;
                   2322:     LowerRightPageControl->ActivePageIndex=0;
                   2323: 
                   2324:     for(i=1;i<LowerLeftPageControl->PageCount;i++)
                   2325:         LowerLeftPageControl->ActivePageIndex=i;
                   2326:     LowerLeftPageControl->ActivePageIndex=0;
                   2327: 
                   2328:     LogTimerTick(Sender);                      /* Open Log Mailslots */
                   2329:        ServiceStatusTimerTick(Sender); /* Query service config lengths */
                   2330: 
                   2331:     if(SysAutoStart)
                   2332:        TelnetStartExecute(Sender);
                   2333:     if(MailAutoStart)
                   2334:         MailStartExecute(Sender);
                   2335:     if(FtpAutoStart)
                   2336:         FtpStartExecute(Sender);
                   2337:     if(WebAutoStart)
                   2338:         WebStartExecute(Sender);
                   2339:     if(ServicesAutoStart)
                   2340:         ServicesStartExecute(Sender);
                   2341: 
                   2342:     NodeForm->Timer->Enabled=true;
                   2343:     ClientForm->Timer->Enabled=true;
                   2344: 
                   2345:     SemFileTimer->Interval=global.sem_chk_freq;
                   2346:     SemFileTimer->Enabled=true;
                   2347: 
                   2348:     StatsTimer->Interval=cfg.node_stat_check*1000;
                   2349:        StatsTimer->Enabled=true;
                   2350:     Initialized=true;
                   2351: 
                   2352:     UpTimer->Enabled=true; /* Start updating the status bar */
                   2353:     LogTimer->Enabled=true;
                   2354:     ServiceStatusTimer->Enabled=true;
                   2355: 
                   2356:     if(!Application->Active)   /* Starting up minimized? */
                   2357:        FormMinimize(Sender);   /* Put icon in systray */
                   2358: }
                   2359: //---------------------------------------------------------------------------
                   2360: void __fastcall TMainForm::SaveRegistrySettings(TObject* Sender)
                   2361: {
                   2362:        StatusBar->Panels->Items[4]->Text="Saving Registry Settings...";
                   2363: 
                   2364:     // Write Registry keys
                   2365:        TRegistry* Registry=new TRegistry;
                   2366:     if(!Registry->OpenKey(REG_KEY,true)) {
                   2367:        Application->MessageBox("Error creating registry key"
                   2368:                ,REG_KEY,MB_OK|MB_ICONEXCLAMATION);
                   2369:         Application->Terminate();
                   2370:         return;
                   2371:     }
                   2372:     Registry->WriteInteger("MainFormTop",Top);
                   2373:     Registry->WriteInteger("MainFormLeft",Left);
                   2374:     Registry->WriteInteger("MainFormHeight",Height);
                   2375:     Registry->WriteInteger("MainFormWidth",Width);
                   2376: 
                   2377:     Registry->WriteInteger("NodeFormTop",NodeForm->Top);
                   2378:     Registry->WriteInteger("NodeFormLeft",NodeForm->Left);
                   2379:     Registry->WriteInteger("NodeFormHeight",NodeForm->Height);
                   2380:     Registry->WriteInteger("NodeFormWidth",NodeForm->Width);
                   2381: 
                   2382:     Registry->WriteInteger("StatsFormTop",StatsForm->Top);
                   2383:     Registry->WriteInteger("StatsFormLeft",StatsForm->Left);
                   2384:     Registry->WriteInteger("StatsFormHeight",StatsForm->Height);
                   2385:     Registry->WriteInteger("StatsFormWidth",StatsForm->Width);
                   2386: 
                   2387:     Registry->WriteInteger("ClientFormTop",ClientForm->Top);
                   2388:     Registry->WriteInteger("ClientFormLeft",ClientForm->Left);
                   2389:     Registry->WriteInteger("ClientFormHeight",ClientForm->Height);
                   2390:     Registry->WriteInteger("ClientFormWidth",ClientForm->Width);
                   2391: 
                   2392:     for(int i=0;i<ClientForm->ListView->Columns->Count;i++) {
                   2393:         char str[128];
                   2394:         sprintf(str,"ClientListColumn%dWidth",i);
                   2395:         Registry->WriteInteger(str
                   2396:             ,ClientForm->ListView->Columns->Items[i]->Width);
                   2397:     }
                   2398:     
                   2399:     Registry->WriteInteger("TelnetFormTop",TelnetForm->Top);
                   2400:     Registry->WriteInteger("TelnetFormLeft",TelnetForm->Left);
                   2401:     Registry->WriteInteger("TelnetFormHeight",TelnetForm->Height);
                   2402:     Registry->WriteInteger("TelnetFormWidth",TelnetForm->Width);
                   2403: 
                   2404:     Registry->WriteInteger("EventsFormTop",EventsForm->Top);
                   2405:     Registry->WriteInteger("EventsFormLeft",EventsForm->Left);
                   2406:     Registry->WriteInteger("EventsFormHeight",EventsForm->Height);
                   2407:     Registry->WriteInteger("EventsFormWidth",EventsForm->Width);
                   2408: 
                   2409:     Registry->WriteInteger("ServicesFormTop",ServicesForm->Top);
                   2410:     Registry->WriteInteger("ServicesFormLeft",ServicesForm->Left);
                   2411:     Registry->WriteInteger("ServicesFormHeight",ServicesForm->Height);
                   2412:     Registry->WriteInteger("ServicesFormWidth",ServicesForm->Width);
                   2413: 
                   2414:     Registry->WriteInteger("FtpFormTop",FtpForm->Top);
                   2415:     Registry->WriteInteger("FtpFormLeft",FtpForm->Left);
                   2416:     Registry->WriteInteger("FtpFormHeight",FtpForm->Height);
                   2417:     Registry->WriteInteger("FtpFormWidth",FtpForm->Width);
                   2418: 
                   2419:     Registry->WriteInteger("WebFormTop",WebForm->Top);
                   2420:     Registry->WriteInteger("WebFormLeft",WebForm->Left);
                   2421:     Registry->WriteInteger("WebFormHeight",WebForm->Height);
                   2422:     Registry->WriteInteger("WebFormWidth",WebForm->Width);
                   2423: 
                   2424:     Registry->WriteInteger("MailFormTop",MailForm->Top);
                   2425:     Registry->WriteInteger("MailFormLeft",MailForm->Left);
                   2426:     Registry->WriteInteger("MailFormHeight",MailForm->Height);
                   2427:     Registry->WriteInteger("MailFormWidth",MailForm->Width);
                   2428: 
                   2429:     Registry->WriteInteger("TopPanelHeight",TopPanel->Height);
                   2430:        Registry->WriteInteger("UpperLeftPageControlWidth"
                   2431:        ,UpperLeftPageControl->Width);
                   2432:     Registry->WriteInteger("LowerLeftPageControlWidth"
                   2433:        ,LowerLeftPageControl->Width);
                   2434: 
                   2435:     Registry->WriteBool("UndockableForms",UndockableForms);
                   2436: 
                   2437:     Registry->WriteBool("TelnetFormFloating",TelnetForm->Floating);
                   2438:     Registry->WriteBool("EventsFormFloating",EventsForm->Floating);
                   2439:     Registry->WriteBool("ServicesFormFloating",ServicesForm->Floating);
                   2440:     Registry->WriteBool("NodeFormFloating",NodeForm->Floating);
                   2441:     Registry->WriteBool("StatsFormFloating",StatsForm->Floating);
                   2442:     Registry->WriteBool("ClientFormFloating",ClientForm->Floating);
                   2443:     Registry->WriteBool("FtpFormFloating",FtpForm->Floating);
                   2444:     Registry->WriteBool("WebFormFloating",WebForm->Floating);
                   2445:     Registry->WriteBool("MailFormFloating",MailForm->Floating);
                   2446: 
                   2447:     Registry->WriteBool("TelnetFormVisible",TelnetForm->Visible);
                   2448:     Registry->WriteBool("EventsFormVisible",EventsForm->Visible);
                   2449:     Registry->WriteBool("ServicesFormVisible",ServicesForm->Visible);
                   2450:     Registry->WriteBool("NodeFormVisible",NodeForm->Visible);
                   2451:     Registry->WriteBool("StatsFormVisible",StatsForm->Visible);
                   2452:     Registry->WriteBool("ClientFormVisible",ClientForm->Visible);
                   2453:     Registry->WriteBool("FtpFormVisible",FtpForm->Visible);
                   2454:     Registry->WriteBool("WebFormVisible",WebForm->Visible);
                   2455:     Registry->WriteBool("MailFormVisible",MailForm->Visible);
                   2456: 
                   2457:     Registry->WriteInteger("TelnetFormPage"
                   2458:            ,PageNum((TPageControl*)TelnetForm->HostDockSite));
                   2459:     Registry->WriteInteger("EventsFormPage"
                   2460:            ,PageNum((TPageControl*)EventsForm->HostDockSite));
                   2461:     Registry->WriteInteger("ServicesFormPage"
                   2462:            ,PageNum((TPageControl*)ServicesForm->HostDockSite));
                   2463:     Registry->WriteInteger("NodeFormPage"
                   2464:        ,PageNum((TPageControl*)NodeForm->HostDockSite));
                   2465:     Registry->WriteInteger("MailFormPage"
                   2466:        ,PageNum((TPageControl*)MailForm->HostDockSite));
                   2467:     Registry->WriteInteger("FtpFormPage"
                   2468:        ,PageNum((TPageControl*)FtpForm->HostDockSite));
                   2469:     Registry->WriteInteger("WebFormPage"
                   2470:        ,PageNum((TPageControl*)WebForm->HostDockSite));
                   2471:     Registry->WriteInteger("StatsFormPage"
                   2472:        ,PageNum((TPageControl*)StatsForm->HostDockSite));
                   2473:     Registry->WriteInteger("ClientFormPage"
                   2474:        ,PageNum((TPageControl*)ClientForm->HostDockSite));
                   2475: 
                   2476:     WriteColor(Registry,"TelnetLog",TelnetForm->Log->Color);
                   2477:     WriteFont("TelnetLog",TelnetForm->Log->Font);
                   2478:     WriteColor(Registry,"EventsLog",EventsForm->Log->Color);
                   2479:     WriteFont("EventsLog",EventsForm->Log->Font);
                   2480:     WriteColor(Registry,"ServicesLog",ServicesForm->Log->Color);
                   2481:     WriteFont("ServicesLog",ServicesForm->Log->Font);
                   2482:     WriteColor(Registry,"MailLog",MailForm->Log->Color);
                   2483:     WriteFont("MailLog",MailForm->Log->Font);
                   2484:     WriteColor(Registry,"FtpLog",FtpForm->Log->Color);
                   2485:     WriteFont("FtpLog",FtpForm->Log->Font);
                   2486:     WriteColor(Registry,"WebLog",WebForm->Log->Color);
                   2487:     WriteFont("WebLog",WebForm->Log->Font);
                   2488:     WriteColor(Registry,"NodeList",NodeForm->ListBox->Color);
                   2489:     WriteFont("NodeList",NodeForm->ListBox->Font);
                   2490:     WriteColor(Registry,"ClientList",ClientForm->ListView->Color);
                   2491:     WriteFont("ClientList",ClientForm->ListView->Font);
                   2492: 
                   2493:     Registry->WriteBool("ToolBarVisible",Toolbar->Visible);
                   2494:     Registry->WriteBool("StatusBarVisible",StatusBar->Visible);
                   2495: 
                   2496:     Registry->WriteInteger("MaxLogLen",MaxLogLen);
                   2497: 
                   2498:     Registry->WriteString("LoginCommand",LoginCommand);
                   2499:     Registry->WriteString("ConfigCommand",ConfigCommand);
                   2500:     Registry->WriteString("Password",Password);
                   2501:     Registry->WriteBool("MinimizeToSysTray",MinimizeToSysTray);
                   2502:     Registry->WriteBool("UseFileAssociations",UseFileAssociations);
                   2503:     Registry->WriteInteger("NodeDisplayInterval",NodeForm->Timer->Interval/1000);
                   2504:     Registry->WriteInteger("ClientDisplayInterval",ClientForm->Timer->Interval/1000);
                   2505: 
                   2506:        Registry->WriteInteger( "SpyTerminalWidth"
                   2507:                             ,SpyTerminalWidth);
                   2508:        Registry->WriteInteger( "SpyTerminalHeight"
                   2509:                             ,SpyTerminalHeight);
                   2510:        Registry->WriteString(  "SpyTerminalFontName"
                   2511:                             ,SpyTerminalFont->Name);
                   2512:        Registry->WriteInteger( "SpyTerminalFontSize"
                   2513:                             ,SpyTerminalFont->Size);
                   2514:        Registry->WriteBool(    "SpyTerminalKeyboardActive"
                   2515:                             ,SpyTerminalKeyboardActive);
                   2516: 
                   2517:     Registry->CloseKey();
                   2518:     delete Registry;
                   2519: }
                   2520: //---------------------------------------------------------------------------
                   2521: void __fastcall TMainForm::SaveSettings(TObject* Sender)
                   2522: {
                   2523:     SaveIniSettings(Sender);
                   2524:     SaveRegistrySettings(Sender);
                   2525: }
                   2526: //---------------------------------------------------------------------------
                   2527: bool __fastcall TMainForm::SaveIniSettings(TObject* Sender)
                   2528: {
                   2529:     FILE* fp=NULL;
                   2530:        if(ini_file[0]==0)
                   2531:         return(false);
                   2532: 
                   2533:     if((fp=fopen(ini_file,"r+"))==NULL) {
                   2534:         char err[MAX_PATH*2];
                   2535:         SAFEPRINTF2(err,"Error %d opening initialization file: %s",errno,ini_file);
                   2536:         Application->MessageBox(err,"ERROR",MB_OK|MB_ICONEXCLAMATION);
                   2537:         return(false);
                   2538:     }
                   2539: 
                   2540:        StatusBar->Panels->Items[4]->Text="Saving Settings to " + AnsiString(ini_file) + " ...";
                   2541: 
                   2542:     bool success = sbbs_write_ini(fp
                   2543:         ,&cfg
                   2544:         ,&global
                   2545:         ,SysAutoStart          ,&bbs_startup
                   2546:         ,FtpAutoStart          ,&ftp_startup
                   2547:         ,WebAutoStart          ,&web_startup
                   2548:         ,MailAutoStart         ,&mail_startup
                   2549:         ,ServicesAutoStart     ,&services_startup
                   2550:         );
                   2551:     fclose(fp);
                   2552: 
                   2553:        if(!success) {
                   2554:                char err[MAX_PATH*2];
                   2555:         SAFEPRINTF(err,"Failure writing initialization file: %s",ini_file);
                   2556:         Application->MessageBox(err,"ERROR",MB_OK|MB_ICONEXCLAMATION);
                   2557:        }
                   2558: 
                   2559:     return(success);
                   2560: }
                   2561: 
                   2562: //---------------------------------------------------------------------------
                   2563: void __fastcall TMainForm::ImportFormSettings(TMemIniFile* IniFile, const char* section, TForm* Form)
                   2564: {
                   2565:        Form->Top=IniFile->ReadInteger(section,"Top",Form->Top);
                   2566:        Form->Left=IniFile->ReadInteger(section,"Left",Form->Left);
                   2567:        Form->Width=IniFile->ReadInteger(section,"Width",Form->Width);
                   2568:        Form->Height=IniFile->ReadInteger(section,"Height",Form->Height);
                   2569: }
                   2570: //---------------------------------------------------------------------------
                   2571: void __fastcall TMainForm::ExportFormSettings(TMemIniFile* IniFile, const char* section, TForm* Form)
                   2572: {
                   2573:     IniFile->WriteInteger(section,"Top",Form->Top);
                   2574:     IniFile->WriteInteger(section,"Left",Form->Left);
                   2575:     IniFile->WriteInteger(section,"Width",Form->Width);
                   2576:     IniFile->WriteInteger(section,"Height",Form->Height);
                   2577:     IniFile->WriteInteger(section,"Page",PageNum((TPageControl*)Form->HostDockSite));
                   2578:     IniFile->WriteBool(section,"Floating",Form->Floating);
                   2579: }
                   2580: //---------------------------------------------------------------------------
                   2581: void __fastcall TMainForm::ImportFont(TMemIniFile* IniFile, const char* section, AnsiString prefix, TFont* Font)
                   2582: {
                   2583:     Font->Name=IniFile->ReadString(section,prefix + "Name",Font->Name);
                   2584:     Font->Color=StringToColor(IniFile->ReadString(section,prefix + "Color",ColorToString(Font->Color)));
                   2585:     Font->Height=IniFile->ReadInteger(section,prefix + "Height",Font->Height);
                   2586:     Font->Size=IniFile->ReadInteger(section,prefix + "Size", Font->Size);
                   2587:     IntToFontStyle(IniFile->ReadInteger(section,prefix + "Style",FontStyleToInt(Font)),Font);
                   2588: }
                   2589: //---------------------------------------------------------------------------
                   2590: void __fastcall TMainForm::ExportFont(TMemIniFile* IniFile, const char* section, AnsiString prefix, TFont* Font)
                   2591: {
                   2592:     IniFile->WriteString(section,prefix+"Name",Font->Name);
                   2593:     IniFile->WriteString(section,prefix+"Color",ColorToString(Font->Color));
                   2594:     IniFile->WriteInteger(section,prefix+"Height",Font->Height);
                   2595:     IniFile->WriteInteger(section,prefix+"Size",Font->Size);
                   2596:     IniFile->WriteInteger(section,prefix+"Style",FontStyleToInt(Font));
                   2597: }
                   2598: //---------------------------------------------------------------------------
                   2599: void __fastcall TMainForm::ImportSettings(TObject* Sender)
                   2600: {
                   2601:     OpenDialog->Filter="Settings files (*.ini)|*.ini|All files|*.*";
                   2602:     OpenDialog->FileName=AnsiString(global.ctrl_dir)+"sbbsctrl.ini";
                   2603:     if(!OpenDialog->Execute())
                   2604:        return;
                   2605: 
                   2606:        StatusBar->Panels->Items[4]->Text="Importing Settings...";
                   2607: 
                   2608:        TMemIniFile* IniFile=new TMemIniFile(OpenDialog->FileName);
                   2609: 
                   2610:     const char* section = "Properties";
                   2611: 
                   2612:        LoginCommand=IniFile->ReadString(section,"LoginCommand",LoginCommand);
                   2613:     ConfigCommand=IniFile->ReadString(section,"ConfigCommand",ConfigCommand);
                   2614:        Password=IniFile->ReadString(section,"Password",Password);
                   2615:        MinimizeToSysTray=IniFile->ReadBool(section,"MinimizeToSysTray",MinimizeToSysTray);
                   2616:        UseFileAssociations=IniFile->ReadBool(section,"UseFileAssociations"     ,UseFileAssociations);
                   2617:     UndockableForms=IniFile->ReadBool(section,"UndockableForms",UndockableForms);
                   2618: 
                   2619:     ImportFormSettings(IniFile,section="MainForm",MainForm);
                   2620:        TopPanel->Height=IniFile->ReadInteger(section,"TopPanelHeight",TopPanel->Height);
                   2621:        UpperLeftPageControl->Width=IniFile->ReadInteger(section,"UpperLeftPageControlWidth",UpperLeftPageControl->Width);
                   2622:        LowerLeftPageControl->Width=IniFile->ReadInteger(section,"LowerLeftPageControlWidth",LowerLeftPageControl->Width);
                   2623:     Toolbar->Visible=IniFile->ReadBool(section,"ToolBarVisible",Toolbar->Visible);
                   2624:     StatusBar->Visible=IniFile->ReadBool(section,"StatusBarVisible",StatusBar->Visible);
                   2625: 
                   2626:     ImportFormSettings(IniFile,section="TelnetForm",TelnetForm);
                   2627:     ImportFont(IniFile,section,"LogFont",TelnetForm->Log->Font);
                   2628:     TelnetForm->Log->Color=StringToColor(IniFile->ReadString(section,"LogColor",clWindow));
                   2629: 
                   2630:     ImportFormSettings(IniFile,section="EventsForm",EventsForm);
                   2631:     ImportFont(IniFile,section,"LogFont",EventsForm->Log->Font);
                   2632:     EventsForm->Log->Color=StringToColor(IniFile->ReadString(section,"LogColor",clWindow));
                   2633: 
                   2634:     ImportFormSettings(IniFile,section="ServicesForm",ServicesForm);
                   2635:     ImportFont(IniFile,section,"LogFont",ServicesForm->Log->Font);
                   2636:     ServicesForm->Log->Color=StringToColor(IniFile->ReadString(section,"LogColor",clWindow));
                   2637: 
                   2638:     ImportFormSettings(IniFile,section="FtpForm",FtpForm);
                   2639:     ImportFont(IniFile,section,"LogFont",FtpForm->Log->Font);
                   2640:        FtpLogFile=IniFile->ReadInteger(section,"LogFile",true);
                   2641:     FtpForm->Log->Color=StringToColor(IniFile->ReadString(section,"LogColor",clWindow));
                   2642: 
                   2643:     ImportFormSettings(IniFile,section="WebForm",WebForm);
                   2644:     ImportFont(IniFile,section,"LogFont",WebForm->Log->Font);
                   2645:     WebForm->Log->Color=StringToColor(IniFile->ReadString(section,"LogColor",clWindow));
                   2646: 
                   2647:     ImportFormSettings(IniFile,section="MailForm",MailForm);
                   2648:     ImportFont(IniFile,section,"LogFont",MailForm->Log->Font);
                   2649:        MailLogFile=IniFile->ReadInteger(section,"LogFile",true);
                   2650:     MailForm->Log->Color=StringToColor(IniFile->ReadString(section,"LogColor",clWindow));
                   2651: 
                   2652:     ImportFormSettings(IniFile,section="NodeForm",NodeForm);
                   2653:     ImportFont(IniFile,section,"ListFont",NodeForm->ListBox->Font);
                   2654:     NodeForm->Timer->Interval=IniFile->ReadInteger(section,"DisplayInterval"
                   2655:         ,NodeForm->Timer->Interval/1000)*1000;
                   2656:     NodeForm->ListBox->Color=StringToColor(IniFile->ReadString(section,"ListColor",clWindow));
                   2657: 
                   2658:     ImportFormSettings(IniFile,section="StatsForm",StatsForm);
                   2659: 
                   2660:     ImportFormSettings(IniFile,section="ClientForm",ClientForm);
                   2661:     ImportFont(IniFile,section,"ListFont",ClientForm->ListView->Font);
                   2662:     ClientForm->ListView->Color=StringToColor(IniFile->ReadString(section,"ListColor",clWindow));
                   2663:     ClientForm->Timer->Interval=IniFile->ReadInteger(section,"DisplayInterval"
                   2664:         ,ClientForm->Timer->Interval/1000)*1000;
                   2665:     for(int i=0;i<ClientForm->ListView->Columns->Count;i++) {
                   2666:         char str[128];
                   2667:         sprintf(str,"Column%dWidth",i);
                   2668:         if(IniFile->ValueExists(section,str))
                   2669:             ClientForm->ListView->Columns->Items[i]->Width
                   2670:                 =IniFile->ReadInteger(section,str,0);
                   2671:     }
                   2672: 
                   2673:     section = "SpyTerminal";
                   2674:        SpyTerminalWidth=IniFile->ReadInteger(section, "Width", SpyTerminalWidth);
                   2675:        SpyTerminalHeight=IniFile->ReadInteger(section, "Height", SpyTerminalHeight);
                   2676:        SpyTerminalFont->Name=IniFile->ReadString(section, "FontName", SpyTerminalFont->Name);
                   2677:        SpyTerminalFont->Size=IniFile->ReadInteger(section, "FontSize", SpyTerminalFont->Size);
                   2678:        SpyTerminalKeyboardActive=IniFile->ReadBool(section, "KeyboardActive", SpyTerminalKeyboardActive);
                   2679: 
                   2680:     delete IniFile;
                   2681: 
                   2682:     Application->MessageBox(AnsiString("Successfully imported SBBSCTRL settings from "
                   2683:        + OpenDialog->FileName).c_str(),"Successful Import",MB_OK);
                   2684: }
                   2685: //---------------------------------------------------------------------------
                   2686: void __fastcall TMainForm::ExportSettings(TObject* Sender)
                   2687: {
                   2688:        char str[128];
                   2689: 
                   2690:     SaveDialog->Filter="Settings files (*.ini)|*.ini|All files|*.*";
                   2691:     SaveDialog->FileName=AnsiString(global.ctrl_dir)+"sbbsctrl.ini";
                   2692:     if(!SaveDialog->Execute())
                   2693:        return;
                   2694: 
                   2695:        TMemIniFile* IniFile=new TMemIniFile(SaveDialog->FileName);
                   2696: 
                   2697:        StatusBar->Panels->Items[4]->Text="Exporting Settings...";
                   2698: 
                   2699:     const char* section = "Properties";
                   2700: 
                   2701:     IniFile->WriteString(section,"LoginCommand",LoginCommand);
                   2702:     IniFile->WriteString(section,"ConfigCommand",ConfigCommand);
                   2703:     IniFile->WriteString(section,"Password",Password);
                   2704:     IniFile->WriteBool(section,"MinimizeToSysTray",MinimizeToSysTray);
                   2705:     IniFile->WriteBool(section,"UseFileAssociations",UseFileAssociations);
                   2706:     IniFile->WriteBool(section,"UndockableForms",UndockableForms);
                   2707: 
                   2708:     ExportFormSettings(IniFile,section="MainForm",MainForm);
                   2709:     IniFile->WriteInteger(section,"TopPanelHeight",TopPanel->Height);
                   2710:        IniFile->WriteInteger(section,"UpperLeftPageControlWidth",UpperLeftPageControl->Width);
                   2711:     IniFile->WriteInteger(section,"LowerLeftPageControlWidth",LowerLeftPageControl->Width);
                   2712:     IniFile->WriteBool(section,"ToolBarVisible",Toolbar->Visible);
                   2713:     IniFile->WriteBool(section,"StatusBarVisible",StatusBar->Visible);
                   2714: 
                   2715:     ExportFormSettings(IniFile,section = "NodeForm",NodeForm);
                   2716:     ExportFont(IniFile,section,"ListFont",NodeForm->ListBox->Font);
                   2717:     IniFile->WriteString(section,"ListColor",ColorToString(NodeForm->ListBox->Color));
                   2718:     IniFile->WriteInteger(section,"DisplayInterval",NodeForm->Timer->Interval/1000);
                   2719: 
                   2720:     ExportFormSettings(IniFile,section = "StatsForm",StatsForm);
                   2721: 
                   2722:     ExportFormSettings(IniFile,section = "ClientForm",ClientForm);
                   2723:     ExportFont(IniFile,section,"ListFont",ClientForm->ListView->Font);
                   2724:     IniFile->WriteString(section,"ListColor",ColorToString(ClientForm->ListView->Color));
                   2725:     IniFile->WriteInteger(section,"DisplayInterval",ClientForm->Timer->Interval/1000);
                   2726:     for(int i=0;i<ClientForm->ListView->Columns->Count;i++) {
                   2727:         char str[128];
                   2728:         sprintf(str,"Column%dWidth",i);
                   2729:         IniFile->WriteInteger(section,str
                   2730:             ,ClientForm->ListView->Columns->Items[i]->Width);
                   2731:     }
                   2732: 
                   2733:     ExportFormSettings(IniFile,section = "TelnetForm",TelnetForm);
                   2734:     ExportFont(IniFile,section,"LogFont",TelnetForm->Log->Font);
                   2735: 
                   2736:     ExportFormSettings(IniFile,section = "EventsForm",EventsForm);
                   2737:     ExportFont(IniFile,section,"LogFont",EventsForm->Log->Font);
                   2738: 
                   2739:     ExportFormSettings(IniFile,section = "ServicesForm",ServicesForm);
                   2740:     ExportFont(IniFile,section,"LogFont",ServicesForm->Log->Font);
                   2741: 
                   2742:     ExportFormSettings(IniFile,section = "FtpForm",FtpForm);
                   2743:     ExportFont(IniFile,section,"LogFont",FtpForm->Log->Font);
                   2744: 
                   2745:     ExportFormSettings(IniFile,section = "MailForm",MailForm);
                   2746:     ExportFont(IniFile,section,"LogFont",MailForm->Log->Font);
                   2747: 
                   2748:     section = "SpyTerminal";
                   2749:        IniFile->WriteInteger(section, "Width"
                   2750:                             ,SpyTerminalWidth);
                   2751:        IniFile->WriteInteger(section, "Height"
                   2752:                             ,SpyTerminalHeight);
                   2753:        IniFile->WriteString(section,  "FontName"
                   2754:                             ,SpyTerminalFont->Name);
                   2755:        IniFile->WriteInteger(section, "FontSize"
                   2756:                             ,SpyTerminalFont->Size);
                   2757:        IniFile->WriteBool(section,    "KeyboardActive"
                   2758:                             ,SpyTerminalKeyboardActive);
                   2759: 
                   2760:     IniFile->UpdateFile();
                   2761: 
                   2762:     delete IniFile;
                   2763: 
                   2764:     Application->MessageBox(AnsiString("Successfully exported SBBSCTRL settings to "
                   2765:        + SaveDialog->FileName).c_str(),"Successful Export",MB_OK);
                   2766: }
                   2767: //---------------------------------------------------------------------------
                   2768: 
                   2769: void __fastcall TMainForm::ViewStatusBarMenuItemClick(TObject *Sender)
                   2770: {
                   2771:        StatusBar->Visible=!StatusBar->Visible;
                   2772:     ViewStatusBarMenuItem->Checked=StatusBar->Visible;
                   2773: }
                   2774: //---------------------------------------------------------------------------
                   2775: void __fastcall TMainForm::HelpAboutMenuItemClick(TObject *Sender)
                   2776: {
                   2777:        Application->CreateForm(__classid(TAboutBoxForm), &AboutBoxForm);
                   2778:     AboutBoxForm->ShowModal();
                   2779:     delete AboutBoxForm;
                   2780: }
                   2781: //---------------------------------------------------------------------------
                   2782: BOOL MuteService(SC_HANDLE svc, SERVICE_STATUS* status, BOOL mute)
                   2783: {
                   2784:        if(svc==NULL || controlService==NULL)
                   2785:        return(FALSE);
                   2786: 
                   2787:        return controlService(svc
                   2788:         ,mute ? SERVICE_CONTROL_MUTE:SERVICE_CONTROL_UNMUTE, status);
                   2789: }
                   2790: //---------------------------------------------------------------------------
                   2791: void __fastcall TMainForm::SoundToggleExecute(TObject *Sender)
                   2792: {
                   2793:     SoundToggle->Checked=!SoundToggle->Checked;
                   2794: 
                   2795:     if(!SoundToggle->Checked) {
                   2796:            bbs_startup.options|=BBS_OPT_MUTE;
                   2797:            ftp_startup.options|=FTP_OPT_MUTE;
                   2798:            web_startup.options|=FTP_OPT_MUTE;
                   2799:            mail_startup.options|=MAIL_OPT_MUTE;
                   2800:            services_startup.options|=MAIL_OPT_MUTE;
                   2801:        } else {
                   2802:            bbs_startup.options&=~BBS_OPT_MUTE;
                   2803:            ftp_startup.options&=~FTP_OPT_MUTE;
                   2804:            web_startup.options&=~FTP_OPT_MUTE;
                   2805:            mail_startup.options&=~MAIL_OPT_MUTE;
                   2806:            services_startup.options&=~MAIL_OPT_MUTE;
                   2807:     }
                   2808:     MuteService(bbs_svc,&bbs_svc_status,!SoundToggle->Checked);
                   2809:     MuteService(ftp_svc,&ftp_svc_status,!SoundToggle->Checked);
                   2810:     MuteService(web_svc,&web_svc_status,!SoundToggle->Checked);
                   2811:     MuteService(mail_svc,&mail_svc_status,!SoundToggle->Checked);
                   2812:     MuteService(services_svc,&services_svc_status,!SoundToggle->Checked);
                   2813: }
                   2814: //---------------------------------------------------------------------------
                   2815: void __fastcall TMainForm::BBSStatisticsLogMenuItemClick(TObject *Sender)
                   2816: {
                   2817:        StatsForm->LogButtonClick(Sender);
                   2818: }
                   2819: //---------------------------------------------------------------------------
                   2820: 
                   2821: void __fastcall TMainForm::ForceTimedEventMenuItemClick(TObject *Sender)
                   2822: {
                   2823:        int i,file;
                   2824:        char str[MAX_PATH+1];
                   2825: 
                   2826:        Application->CreateForm(__classid(TCodeInputForm), &CodeInputForm);
                   2827:        CodeInputForm->Label->Caption="Event Internal Code";
                   2828:     CodeInputForm->ComboBox->Items->Clear();
                   2829:     for(i=0;i<cfg.total_events;i++)
                   2830:        CodeInputForm->ComboBox->Items->Add(
                   2831:             AnsiString(cfg.event[i]->code).UpperCase());
                   2832:     CodeInputForm->ComboBox->ItemIndex=0;
                   2833:     if(CodeInputForm->ShowModal()==mrOk
                   2834:                && CodeInputForm->ComboBox->Text.Length()) {
                   2835:         for(i=0;i<cfg.total_events;i++) {
                   2836:                        if(!stricmp(CodeInputForm->ComboBox->Text.c_str(),cfg.event[i]->code)) {
                   2837:                                sprintf(str,"%s%s.now",cfg.data_dir,cfg.event[i]->code);
                   2838:                if((file=_sopen(str,O_CREAT|O_TRUNC|O_WRONLY
                   2839:                        ,SH_DENYRW,S_IREAD|S_IWRITE))!=-1)
                   2840:                        close(file);
                   2841:                 break;
                   2842:                        }
                   2843:         }
                   2844:         if(i>=cfg.total_events)
                   2845:                Application->MessageBox(CodeInputForm->ComboBox->Text.c_str()
                   2846:                 ,"Event Code Not Found",MB_OK|MB_ICONEXCLAMATION);
                   2847:     }
                   2848:     delete CodeInputForm;
                   2849: }
                   2850: //---------------------------------------------------------------------------
                   2851: 
                   2852: void __fastcall TMainForm::ForceNetworkCalloutMenuItemClick(
                   2853:       TObject *Sender)
                   2854: {
                   2855:        int i,file;
                   2856:        char str[MAX_PATH+1];
                   2857: 
                   2858:        Application->CreateForm(__classid(TCodeInputForm), &CodeInputForm);
                   2859:        CodeInputForm->Label->Caption="Hub QWK-ID";
                   2860:     CodeInputForm->ComboBox->Items->Clear();
                   2861:     for(i=0;i<cfg.total_qhubs;i++)
                   2862:        CodeInputForm->ComboBox->Items->Add(
                   2863:             AnsiString(cfg.qhub[i]->id).UpperCase());
                   2864:     CodeInputForm->ComboBox->ItemIndex=0;
                   2865:     if(CodeInputForm->ShowModal()==mrOk
                   2866:        && CodeInputForm->ComboBox->Text.Length()) {
                   2867:         for(i=0;i<cfg.total_qhubs;i++) {
                   2868:                        if(!stricmp(CodeInputForm->ComboBox->Text.c_str(),cfg.qhub[i]->id)) {
                   2869:                                sprintf(str,"%sqnet/%s.now",cfg.data_dir,cfg.qhub[i]->id);
                   2870:                if((file=_sopen(str,O_CREAT|O_TRUNC|O_WRONLY
                   2871:                        ,SH_DENYRW,S_IREAD|S_IWRITE))!=-1)
                   2872:                        close(file);
                   2873:                 break;
                   2874:                        }
                   2875:         }
                   2876:         if(i>=cfg.total_qhubs)
                   2877:                Application->MessageBox(CodeInputForm->ComboBox->Text.c_str()
                   2878:                 ,"QWKnet Hub ID Not Found",MB_OK|MB_ICONEXCLAMATION);
                   2879:     }
                   2880:     delete CodeInputForm;
                   2881: }
                   2882: //---------------------------------------------------------------------------
                   2883: 
                   2884: void __fastcall TMainForm::TextMenuItemEditClick(TObject *Sender)
                   2885: {
                   2886:        char filename[MAX_PATH+1];
                   2887: 
                   2888:     sprintf(filename,"%s%s"
                   2889:        ,MainForm->cfg.text_dir
                   2890:         ,((TMenuItem*)Sender)->Hint.c_str());
                   2891:     EditFile(filename,((TMenuItem*)Sender)->Caption);
                   2892: }
                   2893: 
                   2894: //---------------------------------------------------------------------------
                   2895: void __fastcall TMainForm::CtrlMenuItemEditClick(TObject *Sender)
                   2896: {
                   2897:        char filename[MAX_PATH+1];
                   2898: 
                   2899:     iniFileName(filename,sizeof(filename)
                   2900:        ,MainForm->cfg.ctrl_dir
                   2901:         ,((TMenuItem*)Sender)->Hint.c_str());
                   2902:     EditFile(filename,((TMenuItem*)Sender)->Caption);
                   2903: }
                   2904: void __fastcall TMainForm::DataMenuItemClick(TObject *Sender)
                   2905: {
                   2906:        char filename[MAX_PATH+1];
                   2907: 
                   2908:     sprintf(filename,"%s%s"
                   2909:        ,MainForm->cfg.data_dir
                   2910:         ,((TMenuItem*)Sender)->Hint.c_str());
                   2911:     EditFile(filename,((TMenuItem*)Sender)->Caption);
                   2912: }
                   2913: //---------------------------------------------------------------------------
                   2914: 
                   2915: //---------------------------------------------------------------------------
                   2916: 
                   2917: void __fastcall TMainForm::UpTimerTick(TObject *Sender)
                   2918: {
                   2919:        char    str[128];
                   2920:     char    days[64];
                   2921:     static  time_t start;
                   2922:     ulong   up;
                   2923: 
                   2924:     if(!start)
                   2925:         start=time(NULL);
                   2926:     up=time(NULL)-start;
                   2927: 
                   2928:     days[0]=0;
                   2929:     if((up/(24*60*60))>=2) {
                   2930:         sprintf(days,"%u days ",up/(24*60*60));
                   2931:         up%=(24*60*60);
                   2932:     }
                   2933:     sprintf(str,"Up: %s%u:%02u"
                   2934:         ,days
                   2935:         ,up/(60*60)
                   2936:         ,(up/60)%60
                   2937:         );
                   2938:     AnsiString Str=AnsiString(str);
                   2939:     if(MainForm->StatusBar->Panels->Items[4]->Text!=Str)
                   2940:                MainForm->StatusBar->Panels->Items[4]->Text=Str;
                   2941: #if 0
                   2942:     THeapStatus hp=GetHeapStatus();
                   2943:     sprintf(str,"Mem Used: %lu bytes",hp.TotalAllocated);
                   2944:     Str=AnsiString(str);
                   2945:     if(MainForm->StatusBar->Panels->Items[5]->Text!=Str)
                   2946:                MainForm->StatusBar->Panels->Items[5]->Text=Str;
                   2947: #endif
                   2948:     if(TrayIcon->Visible) {
                   2949:         /* Animate TrayIcon when in use */
                   2950:         AnsiString NumClients;
                   2951:         try {
                   2952:             if(clients) {
                   2953:                 TrayIcon->IconIndex=(TrayIcon->IconIndex==4) ? 59 : 4;
                   2954:                 NumClients=" ("+AnsiString(clients)+" client";
                   2955:                 if(clients>1)
                   2956:                     NumClients+="s";
                   2957:                 NumClients+=")";
                   2958:             } else if(TrayIcon->IconIndex!=4)
                   2959:                 TrayIcon->IconIndex=4;
                   2960:             TrayIcon->Hint=AnsiString(APP_TITLE)+NumClients;
                   2961:         } catch(...) { /* ignore exceptions here */ };
                   2962:     }
                   2963: }
                   2964: //---------------------------------------------------------------------------
                   2965: 
                   2966: void __fastcall TMainForm::BBSViewErrorLogMenuItemClick(TObject *Sender)
                   2967: {
                   2968:        char filename[MAX_PATH+1];
                   2969: 
                   2970:     sprintf(filename,"%sERROR.LOG"
                   2971:        ,MainForm->cfg.logs_dir);
                   2972:     ViewFile(filename,"Error Log");
                   2973: }
                   2974: //---------------------------------------------------------------------------
                   2975: 
                   2976: void __fastcall TMainForm::ChatToggleExecute(TObject *Sender)
                   2977: {
                   2978:     ChatToggle->Checked=!ChatToggle->Checked;
                   2979:     if(ChatToggle->Checked)
                   2980:            bbs_startup.options|=BBS_OPT_SYSOP_AVAILABLE;
                   2981:     else
                   2982:         bbs_startup.options&=~BBS_OPT_SYSOP_AVAILABLE;
                   2983: 
                   2984:        if(bbs_svc!=NULL && controlService!=NULL)
                   2985:         controlService(bbs_svc
                   2986:             ,ChatToggle->Checked ? SERVICE_CONTROL_SYSOP_AVAILABLE : SERVICE_CONTROL_SYSOP_UNAVAILABLE
                   2987:             ,&bbs_svc_status);
                   2988: }
                   2989: //---------------------------------------------------------------------------
                   2990: void __fastcall TMainForm::UserEditExecute(TObject *Sender)
                   2991: {
                   2992:     char str[256];
                   2993: 
                   2994:     sprintf(str,"%sUSEREDIT %s",cfg.exec_dir,cfg.data_dir);
                   2995:     WinExec(str,SW_SHOWNORMAL);
                   2996: }
                   2997: //---------------------------------------------------------------------------
                   2998: 
                   2999: void __fastcall TMainForm::BBSPreviewMenuItemClick(TObject *Sender)
                   3000: {
                   3001:     TOpenDialog* dlg=new TOpenDialog((TComponent*)Sender);
                   3002: 
                   3003:     dlg->Options << ofNoChangeDir;
                   3004:     dlg->Filter = "ANSI/Ctrl-A files (*.asc; *.msg; *.ans)|*.ASC;*.MSG;*.ANS"
                   3005:                 "|All files|*.*";
                   3006:     dlg->InitialDir=cfg.text_dir;
                   3007:     if(dlg->Execute()==true) {
                   3008:         Application->CreateForm(__classid(TPreviewForm), &PreviewForm);
                   3009:         PreviewForm->Filename=AnsiString(dlg->FileName);
                   3010:         PreviewForm->ShowModal();
                   3011:         delete PreviewForm;
                   3012:     }
                   3013:     delete dlg;
                   3014: }
                   3015: //---------------------------------------------------------------------------
                   3016: void __fastcall TMainForm::BBSLoginMenuItemClick(TObject *Sender)
                   3017: {
                   3018:     if(!strnicmp(LoginCommand.c_str(),"start ",6)) /* Doesn't work on NT */
                   3019:         ShellExecute(Handle, "open", LoginCommand.c_str()+6,
                   3020:             NULL,NULL,SW_SHOWDEFAULT);
                   3021:     else if(!strnicmp(LoginCommand.c_str(),"telnet:",7))
                   3022:         ShellExecute(Handle, "open", LoginCommand.c_str(),
                   3023:             NULL,NULL,SW_SHOWDEFAULT);
                   3024:     else
                   3025:         WinExec(LoginCommand.c_str(),SW_SHOWNORMAL);
                   3026: }
                   3027: //---------------------------------------------------------------------------
                   3028: void __fastcall TMainForm::ViewLogClick(TObject *Sender)
                   3029: {
                   3030:     char    str[128];
                   3031:        char    filename[MAX_PATH+1];
                   3032:     struct  tm* tm;
                   3033:     time_t  t;
                   3034:     TModalResult mr;
                   3035: 
                   3036:     if(((TMenuItem*)Sender)->Tag==-1) {
                   3037:        Application->CreateForm(__classid(TCodeInputForm), &CodeInputForm);
                   3038:        CodeInputForm->Label->Caption="Date";
                   3039:         CodeInputForm->ComboBox->Items->Clear();
                   3040:                CodeInputForm->ComboBox->Text=AnsiString(unixtodstr(&cfg,time(NULL),str));
                   3041:         mr=CodeInputForm->ShowModal();
                   3042:         t=dstrtounix(&cfg,CodeInputForm->ComboBox->Text.c_str());
                   3043:         delete CodeInputForm;
                   3044:         if(mr!=mrOk)
                   3045:             return;
                   3046:     } else {
                   3047:         t=time(NULL);
                   3048:         t-=((TMenuItem*)Sender)->Tag*24*60*60;
                   3049:     }
                   3050:     tm=localtime(&t);
                   3051:     if(tm==NULL)
                   3052:         return;
                   3053: 
                   3054:     /* Close Mail/FTP logs */
                   3055:     mail_lputs(NULL,0,NULL);
                   3056:     ftp_lputs(NULL,0,NULL);
                   3057: 
                   3058:     sprintf(filename,"%sLOGS\\%s%02d%02d%02d.LOG"
                   3059:        ,MainForm->cfg.logs_dir
                   3060:         ,((TMenuItem*)Sender)->Hint.c_str()
                   3061:         ,tm->tm_mon+1
                   3062:         ,tm->tm_mday
                   3063:         ,tm->tm_year%100
                   3064:         );
                   3065:     ViewFile(filename,((TMenuItem*)Sender)->Caption);
                   3066: }
                   3067: //---------------------------------------------------------------------------
                   3068: void __fastcall TMainForm::UserListExecute(TObject *Sender)
                   3069: {
                   3070:     UserListForm->Show();
                   3071: }
                   3072: //---------------------------------------------------------------------------
                   3073: 
                   3074: void __fastcall TMainForm::WebPageMenuItemClick(TObject *Sender)
                   3075: {
                   3076:     ShellExecute(Handle, "open", ((TMenuItem*)Sender)->Hint.c_str(),
                   3077:         NULL,NULL,SW_SHOWDEFAULT);
                   3078: }
                   3079: //---------------------------------------------------------------------------
                   3080: void __fastcall TMainForm::FormMinimize(TObject *Sender)
                   3081: {
                   3082:     if(MinimizeToSysTray) {
                   3083:        if(Password.Length()) {
                   3084:                TrayIcon->RestoreOn=imNone;
                   3085:             CloseTrayMenuItem->Enabled=false;
                   3086:             ConfigureTrayMenuItem->Enabled=false;
                   3087:             UserEditTrayMenuItem->Enabled=false;
                   3088:         } else {
                   3089:                TrayIcon->RestoreOn=imLeftClickUp;
                   3090:             CloseTrayMenuItem->Enabled=true;
                   3091:             ConfigureTrayMenuItem->Enabled=true;
                   3092:             UserEditTrayMenuItem->Enabled=true;
                   3093:         }
                   3094:         if(!TrayIcon->Visible)
                   3095:                TrayIcon->Visible=true;
                   3096:            TrayIcon->Minimize();
                   3097:     }
                   3098: }
                   3099: 
                   3100: void __fastcall TMainForm::TrayIconRestore(TObject *Sender)
                   3101: {
                   3102:     TrayIcon->Visible=false;
                   3103: }
                   3104: 
                   3105: //---------------------------------------------------------------------------
                   3106: 
                   3107: void __fastcall TMainForm::PropertiesExecute(TObject *Sender)
                   3108: {
                   3109:     static inside;
                   3110:     if(inside) return;
                   3111:     inside=true;
                   3112: 
                   3113:     Application->CreateForm(__classid(TPropertiesDlg), &PropertiesDlg);
                   3114:     PropertiesDlg->LoginCmdEdit->Text=LoginCommand;
                   3115:     PropertiesDlg->ConfigCmdEdit->Text=ConfigCommand;
                   3116:     PropertiesDlg->HostnameEdit->Text=global.host_name;
                   3117:     PropertiesDlg->CtrlDirEdit->Text=global.ctrl_dir;
                   3118:     PropertiesDlg->TempDirEdit->Text=global.temp_dir;
                   3119:     PropertiesDlg->NodeIntUpDown->Position=NodeForm->Timer->Interval/1000;
                   3120:     PropertiesDlg->ClientIntUpDown->Position=ClientForm->Timer->Interval/1000;
                   3121:     PropertiesDlg->SemFreqUpDown->Position=global.sem_chk_freq;
                   3122:     PropertiesDlg->TrayIconCheckBox->Checked=MinimizeToSysTray;
                   3123:     PropertiesDlg->UndockableCheckBox->Checked=UndockableForms;
                   3124:     PropertiesDlg->FileAssociationsCheckBox->Checked=UseFileAssociations;
                   3125:     PropertiesDlg->PasswordEdit->Text=Password;
                   3126:     PropertiesDlg->JS_MaxBytesEdit->Text=IntToStr(global.js.max_bytes);
                   3127:     PropertiesDlg->JS_ContextStackEdit->Text=IntToStr(global.js.cx_stack);
                   3128:     PropertiesDlg->JS_ThreadStackEdit->Text=IntToStr(global.js.thread_stack);    
                   3129:     PropertiesDlg->JS_BranchLimitEdit->Text=IntToStr(global.js.branch_limit);
                   3130:     PropertiesDlg->JS_GcIntervalEdit->Text=IntToStr(global.js.gc_interval);
                   3131:     PropertiesDlg->JS_YieldIntervalEdit->Text=IntToStr(global.js.yield_interval);
                   3132: 
                   3133:     if(MaxLogLen==0)
                   3134:                PropertiesDlg->MaxLogLenEdit->Text="<unlimited>";
                   3135:     else
                   3136:            PropertiesDlg->MaxLogLenEdit->Text=IntToStr(MaxLogLen);
                   3137:        if(PropertiesDlg->ShowModal()==mrOk) {
                   3138:         LoginCommand=PropertiesDlg->LoginCmdEdit->Text;
                   3139:         ConfigCommand=PropertiesDlg->ConfigCmdEdit->Text;
                   3140:         SAFECOPY(global.host_name,PropertiesDlg->HostnameEdit->Text.c_str());
                   3141:         SAFECOPY(global.ctrl_dir,PropertiesDlg->CtrlDirEdit->Text.c_str());
                   3142:         SAFECOPY(global.temp_dir,PropertiesDlg->TempDirEdit->Text.c_str());
                   3143:         global.sem_chk_freq=PropertiesDlg->SemFreqUpDown->Position;
                   3144:         SemFileTimer->Interval=global.sem_chk_freq;
                   3145: 
                   3146:         /* Copy global values to server startup structs */
                   3147:         /* We don't support per-server unique values here (yet) */
                   3148:         SAFECOPY(bbs_startup.host_name,global.host_name);
                   3149:         SAFECOPY(bbs_startup.ctrl_dir,global.ctrl_dir);
                   3150:         SAFECOPY(bbs_startup.temp_dir,global.temp_dir);
                   3151:         bbs_startup.sem_chk_freq=global.sem_chk_freq;
                   3152: 
                   3153:         SAFECOPY(ftp_startup.host_name,global.host_name);
                   3154:         SAFECOPY(ftp_startup.ctrl_dir,global.ctrl_dir);
                   3155:         SAFECOPY(ftp_startup.temp_dir,global.temp_dir);
                   3156:         ftp_startup.sem_chk_freq=global.sem_chk_freq;
                   3157: 
                   3158:         SAFECOPY(web_startup.host_name,global.host_name);
                   3159:         SAFECOPY(web_startup.ctrl_dir,global.ctrl_dir);
                   3160:         SAFECOPY(web_startup.temp_dir,global.temp_dir);
                   3161:         web_startup.sem_chk_freq=global.sem_chk_freq;
                   3162: 
                   3163:         SAFECOPY(mail_startup.host_name,global.host_name);
                   3164:         SAFECOPY(mail_startup.ctrl_dir,global.ctrl_dir);
                   3165:         SAFECOPY(mail_startup.temp_dir,global.temp_dir);
                   3166:         mail_startup.sem_chk_freq=global.sem_chk_freq;
                   3167: 
                   3168:         SAFECOPY(services_startup.host_name,global.host_name);
                   3169:         SAFECOPY(services_startup.ctrl_dir,global.ctrl_dir);
                   3170:         SAFECOPY(services_startup.temp_dir,global.temp_dir);
                   3171:         services_startup.sem_chk_freq=global.sem_chk_freq;
                   3172: 
                   3173:         Password=PropertiesDlg->PasswordEdit->Text;
                   3174:         NodeForm->Timer->Interval=PropertiesDlg->NodeIntUpDown->Position*1000;
                   3175:         ClientForm->Timer->Interval=PropertiesDlg->ClientIntUpDown->Position*1000;
                   3176:         MinimizeToSysTray=PropertiesDlg->TrayIconCheckBox->Checked;
                   3177:         UndockableForms=PropertiesDlg->UndockableCheckBox->Checked;
                   3178:         UseFileAssociations=PropertiesDlg->FileAssociationsCheckBox->Checked;
                   3179: 
                   3180:         /* JavaScript operating parameters */
                   3181:         js_startup_t js=global.js; // save for later comparison
                   3182:         global.js.max_bytes
                   3183:                =PropertiesDlg->JS_MaxBytesEdit->Text.ToIntDef(JAVASCRIPT_MAX_BYTES);
                   3184:         global.js.cx_stack
                   3185:                =PropertiesDlg->JS_ContextStackEdit->Text.ToIntDef(JAVASCRIPT_CONTEXT_STACK);
                   3186:         global.js.thread_stack
                   3187:                =PropertiesDlg->JS_ThreadStackEdit->Text.ToIntDef(JAVASCRIPT_THREAD_STACK);
                   3188:         global.js.branch_limit
                   3189:                =PropertiesDlg->JS_BranchLimitEdit->Text.ToIntDef(JAVASCRIPT_BRANCH_LIMIT);
                   3190:         global.js.gc_interval
                   3191:                =PropertiesDlg->JS_GcIntervalEdit->Text.ToIntDef(JAVASCRIPT_GC_INTERVAL);
                   3192:         global.js.yield_interval
                   3193:                =PropertiesDlg->JS_YieldIntervalEdit->Text.ToIntDef(JAVASCRIPT_YIELD_INTERVAL);
                   3194: 
                   3195:         /* Copy global settings, if appropriate (not unique) */
                   3196:         if(memcmp(&bbs_startup.js,&js,sizeof(js))==0)       bbs_startup.js=global.js;
                   3197:         if(memcmp(&ftp_startup.js,&js,sizeof(js))==0)       ftp_startup.js=global.js;
                   3198:         if(memcmp(&web_startup.js,&js,sizeof(js))==0)       web_startup.js=global.js;
                   3199:         if(memcmp(&mail_startup.js,&js,sizeof(js))==0)      mail_startup.js=global.js;
                   3200:         if(memcmp(&services_startup.js,&js,sizeof(js))==0)  services_startup.js=global.js;
                   3201: 
                   3202:         MaxLogLen
                   3203:                =PropertiesDlg->MaxLogLenEdit->Text.ToIntDef(0);
                   3204:         SaveSettings(Sender);
                   3205:     }
                   3206:     delete PropertiesDlg;
                   3207: 
                   3208:     inside=false;
                   3209: }
                   3210: //---------------------------------------------------------------------------
                   3211: 
                   3212: void __fastcall TMainForm::CloseTrayMenuItemClick(TObject *Sender)
                   3213: {
                   3214:     Close();
                   3215: }
                   3216: //---------------------------------------------------------------------------
                   3217: 
                   3218: void __fastcall TMainForm::RestoreTrayMenuItemClick(TObject *Sender)
                   3219: {
                   3220: #if 0
                   3221:     TrayIcon->Visible=false;
                   3222:     Application->Restore();
                   3223: #else
                   3224:        static inside;
                   3225:     if(inside)
                   3226:        return;
                   3227:     inside=true;
                   3228:     
                   3229:        if(Password.Length()) {
                   3230:        Application->CreateForm(__classid(TCodeInputForm), &CodeInputForm);
                   3231:        CodeInputForm->Label->Caption="Password";
                   3232:         CodeInputForm->Edit->Visible=true;
                   3233:         CodeInputForm->Edit->PasswordChar='*';
                   3234:            if(CodeInputForm->ShowModal()==mrOk
                   3235:                && CodeInputForm->Edit->Text.AnsiCompareIC(Password)==0)
                   3236:             TrayIcon->Restore();
                   3237:         delete CodeInputForm;
                   3238:     } else
                   3239:         TrayIcon->Restore();
                   3240: 
                   3241:     inside=false;
                   3242: #endif
                   3243: }
                   3244: //---------------------------------------------------------------------------
                   3245: void __fastcall TMainForm::BBSConfigWizardMenuItemClick(TObject *Sender)
                   3246: {
                   3247:     TConfigWizard* ConfigWizard;
                   3248:     static inside;
                   3249:     if(inside) return;
                   3250:     inside=true;
                   3251: 
                   3252:     Application->CreateForm(__classid(TConfigWizard), &ConfigWizard);
                   3253:        if(ConfigWizard->ShowModal()==mrOk) {
                   3254:         SaveSettings(Sender);
                   3255: //        ReloadConfigExecute(Sender);  /* unnecessary since refresh_cfg() is already called */
                   3256:     }
                   3257:     delete ConfigWizard;
                   3258: 
                   3259:     inside=false;
                   3260: }
                   3261: //---------------------------------------------------------------------------
                   3262: 
                   3263: void __fastcall TMainForm::PageControlUnDock(TObject *Sender,
                   3264:       TControl *Client, TWinControl *NewTarget, bool &Allow)
                   3265: {
                   3266:     if(NewTarget==NULL) /* Desktop */
                   3267:         Allow=UndockableForms;
                   3268: }
                   3269: //---------------------------------------------------------------------------
                   3270: void __fastcall TMainForm::reload_config(void)
                   3271: {
                   3272:        char error[256];
                   3273:        SAFECOPY(error,UNKNOWN_LOAD_ERROR);
                   3274:        if(!load_cfg(&cfg, NULL, TRUE, error)) {
                   3275:        Application->MessageBox(error,"ERROR Re-loading Configuration"
                   3276:                ,MB_OK|MB_ICONEXCLAMATION);
                   3277:         Application->Terminate();
                   3278:     }
                   3279:        semfile_list_check(&initialized,recycle_semfiles);
                   3280: }
                   3281: //---------------------------------------------------------------------------
                   3282: 
                   3283: void __fastcall TMainForm::ReloadConfigExecute(TObject *Sender)
                   3284: {
                   3285:        FtpRecycleExecute(Sender);
                   3286:        WebRecycleExecute(Sender);
                   3287:        MailRecycleExecute(Sender);
                   3288:     TelnetRecycleExecute(Sender);
                   3289:        ServicesRecycleExecute(Sender);
                   3290: 
                   3291:     reload_config();
                   3292: #if 0   /* This appears to be redundant */
                   3293:     node_t node;
                   3294:     for(int i=0;i<cfg.sys_nodes;i++) {
                   3295:        int file;
                   3296:                if(NodeForm->getnodedat(i+1,&node,&file))
                   3297:             break;
                   3298:         node.misc|=NODE_RRUN;
                   3299:         if(NodeForm->putnodedat(i+1,&node,file))
                   3300:             break;
                   3301:     }
                   3302: #endif
                   3303: }
                   3304: 
                   3305: //---------------------------------------------------------------------------
                   3306: 
                   3307: 
                   3308: void __fastcall TMainForm::ServicesConfigureExecute(TObject *Sender)
                   3309: {
                   3310:     static inside;
                   3311:     if(inside) return;
                   3312:     inside=true;
                   3313: 
                   3314:        Application->CreateForm(__classid(TServicesCfgDlg), &ServicesCfgDlg);
                   3315:        ServicesCfgDlg->ShowModal();
                   3316:     delete ServicesCfgDlg;
                   3317: 
                   3318:     inside=false;
                   3319: }
                   3320: //---------------------------------------------------------------------------
                   3321: 
                   3322: void __fastcall TMainForm::UserTruncateMenuItemClick(TObject *Sender)
                   3323: {
                   3324:     int usernumber;
                   3325:     int deleted=0;
                   3326:     user_t user;
                   3327: 
                   3328:     Screen->Cursor=crHourGlass;
                   3329:     while((user.number=lastuser(&cfg))!=0) {
                   3330:         if(getuserdat(&cfg,&user)!=0)
                   3331:             break;
                   3332:         if(!(user.misc&DELETED))
                   3333:             break;
                   3334:         if(!del_lastuser(&cfg))
                   3335:             break;
                   3336:         deleted++;
                   3337:     }
                   3338:     Screen->Cursor=crDefault;
                   3339:     char str[128];
                   3340:     sprintf(str,"%u Deleted User Records Removed",deleted);
                   3341:        Application->MessageBox(str,"Users Truncated",MB_OK);
                   3342: }
                   3343: 
                   3344: BOOL RecycleService(SC_HANDLE svc, SERVICE_STATUS* status)
                   3345: {
                   3346:        if(svc==NULL || controlService==NULL)
                   3347:        return(FALSE);
                   3348: 
                   3349:        return controlService(svc, SERVICE_CONTROL_RECYCLE, status);
                   3350: }
                   3351: 
                   3352: //---------------------------------------------------------------------------
                   3353: void __fastcall TMainForm::MailRecycleExecute(TObject *Sender)
                   3354: {
                   3355:        if(!RecycleService(mail_svc,&mail_svc_status)) {
                   3356:                mail_startup.recycle_now=true;
                   3357:            MailRecycle->Enabled=false;
                   3358:     }
                   3359: }
                   3360: //---------------------------------------------------------------------------
                   3361: void __fastcall TMainForm::FtpRecycleExecute(TObject *Sender)
                   3362: {
                   3363:        if(!RecycleService(ftp_svc,&ftp_svc_status)) {
                   3364:                ftp_startup.recycle_now=true;
                   3365:            FtpRecycle->Enabled=false;
                   3366:     }
                   3367: }
                   3368: //---------------------------------------------------------------------------
                   3369: void __fastcall TMainForm::WebRecycleExecute(TObject *Sender)
                   3370: {
                   3371:        if(!RecycleService(web_svc,&web_svc_status)) {
                   3372:                web_startup.recycle_now=true;
                   3373:            WebRecycle->Enabled=false;
                   3374:     }
                   3375: }
                   3376: //---------------------------------------------------------------------------
                   3377: void __fastcall TMainForm::ServicesRecycleExecute(TObject *Sender)
                   3378: {
                   3379:        if(!RecycleService(services_svc,&services_svc_status)) {
                   3380:                services_startup.recycle_now=true;
                   3381:            ServicesRecycle->Enabled=false;
                   3382:     }
                   3383: }
                   3384: //---------------------------------------------------------------------------
                   3385: 
                   3386: void __fastcall TMainForm::TelnetRecycleExecute(TObject *Sender)
                   3387: {
                   3388:     if(!RecycleService(bbs_svc,&bbs_svc_status)) {
                   3389:                bbs_startup.recycle_now=true;
                   3390:            TelnetRecycle->Enabled=false;
                   3391:     }
                   3392: }
                   3393: //---------------------------------------------------------------------------
                   3394: 
                   3395: void __fastcall TMainForm::FileEditTextFilesClick(TObject *Sender)
                   3396: {
                   3397:        TOpenDialog* dlg=new TOpenDialog((TComponent*)Sender);
                   3398: 
                   3399:     dlg->Options << ofNoChangeDir;
                   3400:     dlg->Filter =      "Text files (*.txt)|*.TXT"
                   3401:                                "|All files|*.*";
                   3402:     dlg->InitialDir=cfg.text_dir;
                   3403:     if(dlg->Execute()==true)
                   3404:         EditFile(dlg->FileName.c_str());
                   3405:     delete dlg;
                   3406: }
                   3407: //---------------------------------------------------------------------------
                   3408: 
                   3409: void __fastcall TMainForm::BBSEditBajaMenuItemClick(TObject *Sender)
                   3410: {
                   3411:        TOpenDialog* dlg=new TOpenDialog((TComponent*)Sender);
                   3412: 
                   3413:     dlg->Options << ofNoChangeDir;
                   3414:     dlg->Filter = "Baja Source Code (*.src)|*.SRC";
                   3415:     dlg->InitialDir=cfg.exec_dir;
                   3416:     if(dlg->Execute()==true) {
                   3417:         Application->CreateForm(__classid(TTextFileEditForm), &TextFileEditForm);
                   3418:         TextFileEditForm->Filename=AnsiString(dlg->FileName);
                   3419:         TextFileEditForm->Caption="Edit";
                   3420:         if(TextFileEditForm->ShowModal()==mrOk) {
                   3421:                /* Compile Baja Source File (requires Baja v2.33+) */
                   3422:                char cmdline[512];
                   3423:             sprintf(cmdline,"%sbaja -p %s",cfg.exec_dir,dlg->FileName);
                   3424:             WinExec(cmdline,SW_SHOW);
                   3425:                }
                   3426:         delete TextFileEditForm;
                   3427:     }
                   3428:     delete dlg;
                   3429: }
                   3430: //---------------------------------------------------------------------------
                   3431: 
                   3432: void __fastcall TMainForm::FileEditJavaScriptClick(TObject *Sender)
                   3433: {
                   3434:        TOpenDialog* dlg=new TOpenDialog((TComponent*)Sender);
                   3435: 
                   3436:     dlg->Options << ofNoChangeDir;
                   3437:     dlg->Filter = "JavaScript Files (*.js)|*.JS";
                   3438:     dlg->InitialDir=cfg.exec_dir;
                   3439:     if(dlg->Execute()==true)
                   3440:         EditFile(dlg->FileName.c_str());
                   3441:     delete dlg;
                   3442: }
                   3443: //---------------------------------------------------------------------------
                   3444: 
                   3445: void __fastcall TMainForm::FileEditConfigFilesClick(TObject *Sender)
                   3446: {
                   3447:        TOpenDialog* dlg=new TOpenDialog((TComponent*)Sender);
                   3448: 
                   3449:     dlg->Options << ofNoChangeDir;
                   3450:     dlg->Filter = "Configuration Files (*.cfg; *.ini; *.conf)|*.cfg;*.ini;*.conf";
                   3451:     dlg->InitialDir=cfg.ctrl_dir;
                   3452:     if(dlg->Execute()==true)
                   3453:         EditFile(dlg->FileName.c_str());
                   3454:     delete dlg;
                   3455: }
                   3456: 
                   3457: void __fastcall TMainForm::BBSEditFileClick(TObject *Sender)
                   3458: {
                   3459:    TOpenDialog* dlg=new TOpenDialog((TComponent*)Sender);
                   3460: 
                   3461:    dlg->Options << ofNoChangeDir;
                   3462:     dlg->Filter = "ANSI/Ctrl-A files (*.asc; *.msg; *.ans)|*.ASC;*.MSG;*.ANS"
                   3463:                 "|All files|*.*";
                   3464:     dlg->InitialDir=cfg.text_dir;
                   3465:     if(dlg->Execute()==true) {
                   3466:         Application->CreateForm(__classid(TTextFileEditForm), &TextFileEditForm);
                   3467:         TextFileEditForm->Filename=AnsiString(dlg->FileName);
                   3468:         TextFileEditForm->Caption="Edit";
                   3469:         if(TextFileEditForm->ShowModal()==mrOk) {
                   3470:                Application->CreateForm(__classid(TPreviewForm), &PreviewForm);
                   3471:            PreviewForm->Filename=AnsiString(dlg->FileName);
                   3472:             PreviewForm->ShowModal();
                   3473:                delete PreviewForm;
                   3474:         }
                   3475:         delete TextFileEditForm;
                   3476:     }
                   3477:     delete dlg;
                   3478: }
                   3479: //---------------------------------------------------------------------------
                   3480: bool GetServerLogLine(HANDLE& log, const char* name, char* line, size_t len)
                   3481: {
                   3482:        char fname[256];
                   3483: 
                   3484:        if(log==INVALID_HANDLE_VALUE) {
                   3485:                sprintf(fname,"\\\\.\\mailslot\\%s.log",name);
                   3486:         log = CreateMailslot(
                   3487:             fname,                                     // pointer to string for mailslot name
                   3488:             0,                                         // maximum message size
                   3489:             0,                                         // milliseconds before read time-out
                   3490:             NULL);                  // pointer to security structure
                   3491:         if(log==INVALID_HANDLE_VALUE)
                   3492:                return(false);
                   3493:     }
                   3494:     DWORD msgs=0;
                   3495:     if(!GetMailslotInfo(
                   3496:         log,   // mailslot handle
                   3497:         NULL,  // address of maximum message size
                   3498:         NULL,  // address of size of next message
                   3499:         &msgs, // address of number of messages
                   3500:         NULL   // address of read time-out
                   3501:         ) || !msgs)
                   3502:         return(false);
                   3503: 
                   3504:     DWORD rd=0;
                   3505:     if(!ReadFile(
                   3506:         log,                           // handle of file to read
                   3507:         line,                  // pointer to buffer that receives data
                   3508:         len-1,                         // number of bytes to read
                   3509:         &rd,                           // pointer to number of bytes read
                   3510:         NULL                           // pointer to structure for data
                   3511:         ) || !rd)
                   3512:                return(false);
                   3513: 
                   3514:     line[rd]=0;        /* 0-terminate */
                   3515: 
                   3516:        return(true);
                   3517: }
                   3518: //---------------------------------------------------------------------------
                   3519: 
                   3520: void __fastcall TMainForm::LogTimerTick(TObject *Sender)
                   3521: {
                   3522:        char line[1024];
                   3523: 
                   3524:        while(GetServerLogLine(bbs_log,NTSVC_NAME_BBS,line,sizeof(line)))
                   3525:        bbs_lputs(NULL,LOG_INFO,line);
                   3526: 
                   3527:        while(GetServerLogLine(event_log,NTSVC_NAME_EVENT,line,sizeof(line)))
                   3528:        event_lputs(LOG_INFO,line);
                   3529: 
                   3530:        while(GetServerLogLine(ftp_log,NTSVC_NAME_FTP,line,sizeof(line)))
                   3531:        ftp_lputs(NULL,LOG_INFO,line);
                   3532: 
                   3533:        while(GetServerLogLine(web_log,NTSVC_NAME_WEB,line,sizeof(line)))
                   3534:        web_lputs(NULL,LOG_INFO,line);
                   3535: 
                   3536:        while(GetServerLogLine(mail_log,NTSVC_NAME_MAIL,line,sizeof(line)))
                   3537:        mail_lputs(NULL,LOG_INFO,line);
                   3538: 
                   3539:        while(GetServerLogLine(services_log,NTSVC_NAME_SERVICES,line,sizeof(line)))
                   3540:        service_lputs(NULL,LOG_INFO,line);
                   3541: 
                   3542: }
                   3543: 
                   3544: //---------------------------------------------------------------------------
                   3545: void CheckServiceStatus(
                   3546:         SC_HANDLE svc
                   3547:        ,SERVICE_STATUS* status
                   3548:        ,QUERY_SERVICE_CONFIG* &config
                   3549:        ,DWORD &config_size
                   3550:        ,TStaticText* text
                   3551:     ,TAction* start
                   3552:     ,TAction* stop
                   3553:     ,TAction* recycle
                   3554:     ,TProgressBar* bar
                   3555:     )
                   3556: {
                   3557:        if(svc==NULL)
                   3558:        return;
                   3559: 
                   3560:        DWORD ret;
                   3561: 
                   3562:        if(!queryServiceConfig(svc,config,config_size,&ret)) {
                   3563:                if(GetLastError()==ERROR_INSUFFICIENT_BUFFER) {
                   3564:                        config_size=ret;
                   3565:                        if(config!=NULL)
                   3566:                                free(config);
                   3567:                        config = (QUERY_SERVICE_CONFIG*)malloc(config_size);
                   3568:                }
                   3569:                return;
                   3570:        }
                   3571: 
                   3572:        if(config->dwStartType==SERVICE_DISABLED)
                   3573:                return;
                   3574: 
                   3575:        if(!queryServiceStatus(svc,status)) {
                   3576:        text->Caption="QueryServiceStatus Error "; // + GetLastError());
                   3577:         return;
                   3578:        }
                   3579: 
                   3580:     bool running=false;
                   3581: 
                   3582:        switch(status->dwCurrentState) {
                   3583:        case SERVICE_STOPPED:
                   3584:                text->Caption="Stopped NT Service";
                   3585:             break;
                   3586:         case SERVICE_STOP_PENDING:
                   3587:                text->Caption="Stopping NT Service";
                   3588:             break;
                   3589:         case SERVICE_RUNNING:
                   3590:                text->Caption="Running NT Service";
                   3591:             running=true;
                   3592:             break;
                   3593:         case SERVICE_START_PENDING:
                   3594:                text->Caption="Starting NT Service";
                   3595:             running=true;
                   3596:             break;
                   3597:         default:
                   3598:                text->Caption="!UNKNOWN: " +  status->dwCurrentState;
                   3599:             break;
                   3600:     }
                   3601: 
                   3602:     start->Enabled=!running;
                   3603:     stop->Enabled=running;
                   3604:     recycle->Enabled=running;
                   3605: }
                   3606: //---------------------------------------------------------------------------
                   3607: 
                   3608: void __fastcall TMainForm::ServiceStatusTimerTick(TObject *Sender)
                   3609: {
                   3610:        if(queryServiceStatus==NULL || queryServiceConfig==NULL
                   3611:        || (bbs_svc==NULL
                   3612:         && ftp_svc==NULL
                   3613:                && web_svc==NULL
                   3614:         && mail_svc==NULL
                   3615:         && services_svc==NULL)) {
                   3616:        ServiceStatusTimer->Enabled=false;
                   3617:         return;
                   3618:     }
                   3619: 
                   3620:     CheckServiceStatus(
                   3621:         bbs_svc
                   3622:        ,&bbs_svc_status
                   3623:                ,bbs_svc_config
                   3624:                ,bbs_svc_config_size
                   3625:         ,TelnetForm->Status
                   3626:         ,TelnetStart
                   3627:         ,TelnetStop
                   3628:         ,TelnetRecycle
                   3629:         ,TelnetForm->ProgressBar
                   3630:         );
                   3631:     CheckServiceStatus(
                   3632:         ftp_svc
                   3633:        ,&ftp_svc_status
                   3634:                ,ftp_svc_config
                   3635:                ,ftp_svc_config_size
                   3636:         ,FtpForm->Status
                   3637:         ,FtpStart
                   3638:         ,FtpStop
                   3639:         ,FtpRecycle
                   3640:         ,FtpForm->ProgressBar
                   3641:         );
                   3642:     CheckServiceStatus(
                   3643:         web_svc
                   3644:        ,&web_svc_status
                   3645:                ,web_svc_config
                   3646:                ,web_svc_config_size
                   3647:         ,WebForm->Status
                   3648:         ,WebStart
                   3649:         ,WebStop
                   3650:         ,WebRecycle
                   3651:         ,WebForm->ProgressBar
                   3652:         );
                   3653:     CheckServiceStatus(
                   3654:         mail_svc
                   3655:        ,&mail_svc_status
                   3656:                ,mail_svc_config
                   3657:                ,mail_svc_config_size
                   3658:         ,MailForm->Status
                   3659:         ,MailStart
                   3660:         ,MailStop
                   3661:         ,MailRecycle
                   3662:         ,MailForm->ProgressBar
                   3663:         );
                   3664:     CheckServiceStatus(
                   3665:         services_svc
                   3666:        ,&services_svc_status
                   3667:                ,services_svc_config
                   3668:                ,services_svc_config_size
                   3669:         ,ServicesForm->Status
                   3670:         ,ServicesStart
                   3671:         ,ServicesStop
                   3672:         ,ServicesRecycle
                   3673:         ,NULL
                   3674:         );
                   3675: 
                   3676: }
                   3677: //---------------------------------------------------------------------------
                   3678: void __fastcall TMainForm::EditFile(AnsiString filename, AnsiString Caption)
                   3679: {
                   3680:    if(!UseFileAssociations
                   3681:         || (int)ShellExecute(Handle, "edit", filename.c_str(), NULL,NULL,SW_SHOWDEFAULT)<=32) {
                   3682:         Application->CreateForm(__classid(TTextFileEditForm), &TextFileEditForm);
                   3683:         TextFileEditForm->Filename=filename;
                   3684:         TextFileEditForm->Caption=Caption;
                   3685:         TextFileEditForm->ShowModal();
                   3686:         delete TextFileEditForm;
                   3687:     }
                   3688: }
                   3689: //---------------------------------------------------------------------------
                   3690: void __fastcall TMainForm::ViewFile(AnsiString filename, AnsiString Caption)
                   3691: {
                   3692:    if(!UseFileAssociations
                   3693:         || (int)ShellExecute(Handle, "open", filename.c_str(), NULL,NULL,SW_SHOWDEFAULT)<=32) {
                   3694:         Application->CreateForm(__classid(TTextFileEditForm), &TextFileEditForm);
                   3695:         TextFileEditForm->Filename=filename;
                   3696:         TextFileEditForm->Caption=Caption;
                   3697:         TextFileEditForm->Memo->ReadOnly=true;
                   3698:         TextFileEditForm->ShowModal();
                   3699:         delete TextFileEditForm;
                   3700:     }
                   3701: }
                   3702: //---------------------------------------------------------------------------
                   3703: void __fastcall TMainForm::SemFileTimerTick(TObject *Sender)
                   3704: {
                   3705:     char* p;
                   3706: 
                   3707:     if((p=semfile_list_check(&initialized,shutdown_semfiles))!=NULL) {
                   3708:            StatusBar->Panels->Items[4]->Text=AnsiString(p) + " signaled";
                   3709:         terminating=true;
                   3710:         Close();
                   3711:     }
                   3712:     else if((p=semfile_list_check(&initialized,recycle_semfiles))!=NULL) {
                   3713:            StatusBar->Panels->Items[4]->Text=AnsiString(p) + " signaled";
                   3714:         reload_config();
                   3715:     }
                   3716: }
                   3717: //---------------------------------------------------------------------------
                   3718: 

unix.superglobalmegacorp.com

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