|
|
1.1 ! root 1: /* MainFormUnit.cpp */ ! 2: ! 3: /* Local sysop chat module (GUI Borland C++ Builder Project for Win32) */ ! 4: ! 5: /* $Id: MainFormUnit.cpp,v 1.6 2005/09/20 03:40:06 deuce Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: //--------------------------------------------------------------------------- ! 39: ! 40: #include <vcl.h> ! 41: #include <io.h> ! 42: #include <sys\stat.h> ! 43: #include <fcntl.h> ! 44: #include <share.h> ! 45: #include <sys/locking.h> ! 46: #include <vcl\Registry.hpp> /* TRegistry */ ! 47: #pragma hdrstop ! 48: ! 49: #include <utime.h> ! 50: #include "gen_defs.h" /* BS and DEL */ ! 51: ! 52: #define PCHAT_LEN 1000 /* Size of Private chat file */ ! 53: #define REG_KEY "\\Software\\Swindell\\Synchronet Chat\\" ! 54: ! 55: #include "MainFormUnit.h" ! 56: //--------------------------------------------------------------------------- ! 57: #pragma package(smart_init) ! 58: #pragma resource "*.dfm" ! 59: TMainForm *MainForm; ! 60: extern int node_num; ! 61: extern char ctrl_dir[]; ! 62: extern char node_dir[]; ! 63: extern char user_name[]; ! 64: ! 65: char node_path[MAX_PATH+1]; ! 66: char out_path[MAX_PATH+1]; ! 67: ! 68: //--------------------------------------------------------------------------- ! 69: __fastcall TMainForm::TMainForm(TComponent* Owner) ! 70: : TForm(Owner) ! 71: { ! 72: in=-1; ! 73: out=-1; ! 74: nodedab=-1; ! 75: } ! 76: bool __fastcall TMainForm::ToggleChat(bool on) ! 77: { ! 78: int n=node_num-1; ! 79: static int org_act; ! 80: ! 81: if(nodedab==-1) ! 82: return(false); ! 83: ! 84: lseek(nodedab, n*sizeof(node_t), SEEK_SET); ! 85: int i=locking(nodedab, LK_LOCK, sizeof(node_t)); ! 86: if(i) { ! 87: Remote->Lines->Add("!Error "+AnsiString(i)+" reading record for" ! 88: "node "+AnsiString(node_num)); ! 89: return(false); ! 90: } ! 91: read(nodedab, &node, sizeof(node_t)); ! 92: if(on) { ! 93: org_act=node.action; ! 94: if(org_act==NODE_PCHT) ! 95: org_act=NODE_MAIN; ! 96: node.misc|=NODE_LCHAT; ! 97: } else { ! 98: node.action=org_act; ! 99: node.misc&=~NODE_LCHAT; ! 100: } ! 101: ! 102: lseek(nodedab, n*sizeof(node_t), SEEK_SET); ! 103: write(nodedab, &node, sizeof(node_t)); ! 104: lseek(nodedab, n*sizeof(node_t), SEEK_SET); ! 105: locking(nodedab, LK_UNLCK, sizeof(node_t)); ! 106: ! 107: utime(node_path,NULL); ! 108: ! 109: return(true); ! 110: } ! 111: //--------------------------------------------------------------------------- ! 112: void __fastcall TMainForm::FormShow(TObject *Sender) ! 113: { ! 114: char* p; ! 115: char path[MAX_PATH+1]; ! 116: ! 117: Caption="Waiting for " ! 118: +AnsiString(user_name)+" on Node "+AnsiString(node_num); ! 119: ! 120: wsprintf(node_path,"%sNODE.DAB",ctrl_dir); ! 121: nodedab=_sopen(node_path,O_RDWR|O_BINARY|O_CREAT, SH_DENYNONE,S_IREAD|S_IWRITE); ! 122: ! 123: if(nodedab==-1) { ! 124: Remote->Lines->Add("!Error opening " + AnsiString(node_path)); ! 125: return; ! 126: } ! 127: ! 128: ToggleChat(true); ! 129: ! 130: wsprintf(out_path,"%sLCHAT.DAB",node_dir); ! 131: if((out=_sopen(out_path,O_RDWR|O_CREAT|O_BINARY,O_DENYNONE ! 132: ,S_IREAD|S_IWRITE))==-1) { ! 133: Remote->Lines->Add("!Error opening " + AnsiString(out_path)); ! 134: return; ! 135: } ! 136: ! 137: wsprintf(path,"%sCHAT.DAB",node_dir); ! 138: #if 0 ! 139: if(!fexist(path)) /* Wait while it's created for the first time */ ! 140: mswait(2000); ! 141: #endif ! 142: ! 143: if((in=_sopen(path,O_RDWR|O_CREAT|O_BINARY,O_DENYNONE ! 144: ,S_IREAD|S_IWRITE))==-1) { ! 145: close(out); ! 146: Remote->Lines->Add("!Error opening CHAT.DAB"); ! 147: return; ! 148: } ! 149: ! 150: if((p=(char *)malloc(PCHAT_LEN))==NULL) { ! 151: close(in); ! 152: close(out); ! 153: Remote->Lines->Add("!Error allocating memory"); ! 154: return; ! 155: } ! 156: memset(p,0,PCHAT_LEN); ! 157: write(in,p,PCHAT_LEN); ! 158: write(out,p,PCHAT_LEN); ! 159: free(p); ! 160: lseek(in,0L,SEEK_SET); ! 161: lseek(out,0L,SEEK_SET); ! 162: ! 163: Timer->Enabled=true; ! 164: } ! 165: //--------------------------------------------------------------------------- ! 166: void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) ! 167: { ! 168: ToggleChat(false); ! 169: ! 170: if(in!=-1) ! 171: close(in); ! 172: if(out!=-1) ! 173: close(out); ! 174: if(nodedab!=-1) ! 175: close(nodedab); ! 176: ! 177: // Write Registry keys ! 178: TRegistry* Registry=new TRegistry; ! 179: if(!Registry->OpenKey(REG_KEY,true)) { ! 180: Application->MessageBox("Error opening registry key" ! 181: ,REG_KEY,MB_OK|MB_ICONEXCLAMATION); ! 182: Application->Terminate(); ! 183: } ! 184: Registry->WriteInteger("FormHeight",Height); ! 185: Registry->WriteInteger("FormWidth",Width); ! 186: Registry->WriteInteger("RemoteHeight",Remote->Height); ! 187: ! 188: Registry->CloseKey(); ! 189: delete Registry; ! 190: ! 191: } ! 192: //--------------------------------------------------------------------------- ! 193: void __fastcall TMainForm::LocalKeyPress(TObject *Sender, char &Key) ! 194: { ! 195: char c; ! 196: ! 197: if(Key==22) { /* Ctrl-V */ ! 198: Key=0; ! 199: return; /* Don't allow "paste from clipboard" */ ! 200: } ! 201: if(Key<' ' && Key!='\r' && Key!='\t' && Key!='\b') ! 202: return; ! 203: ! 204: if(out==-1 || Local->ReadOnly==true) { ! 205: Beep(); ! 206: return; ! 207: } ! 208: read(out,&c,1); ! 209: lseek(out,-1L,SEEK_CUR); ! 210: if(!c) /* hasn't wrapped */ ! 211: write(out,&Key,1); ! 212: else { ! 213: if(!tell(out)) ! 214: lseek(out,0L,SEEK_END); ! 215: lseek(out,-1L,SEEK_CUR); ! 216: c=0; ! 217: write(out,&c,1); ! 218: lseek(out,-1L,SEEK_CUR); ! 219: } ! 220: utime(out_path,NULL); ! 221: if(tell(out)>=PCHAT_LEN) ! 222: lseek(out,0L,SEEK_SET); ! 223: } ! 224: //--------------------------------------------------------------------------- ! 225: void __fastcall TMainForm::InputTimerTick(TObject *Sender) ! 226: { ! 227: char ch=0; ! 228: ! 229: Timer->Interval=100; ! 230: ! 231: while(in!=-1) { ! 232: if(tell(in)>=PCHAT_LEN) ! 233: lseek(in,0L,SEEK_SET); ! 234: read(in,&ch,1); ! 235: lseek(in,-1L,SEEK_CUR); ! 236: if(!ch) ! 237: break; /* char from other node */ ! 238: ! 239: Timer->Interval=1; ! 240: ! 241: /* Got char, display it */ ! 242: if(ch=='\r') ! 243: Remote->Lines->Add(""); ! 244: else if(ch==BS || ch==DEL) { // backspace ! 245: Remote->Text ! 246: =Remote->Text.SetLength(Remote->Text.Length()-1); ! 247: /* Need to scroll window down here */ ! 248: } else { ! 249: Remote->SelLength=0; ! 250: Remote->SelStart=Remote->Text.Length(); ! 251: Remote->SelText=AnsiString(ch); ! 252: } ! 253: ! 254: /* mark char as rx'd */ ! 255: ch=0; ! 256: write(in,&ch,1); ! 257: } ! 258: } ! 259: //--------------------------------------------------------------------------- ! 260: void __fastcall TMainForm::TimerTick(TObject *Sender) ! 261: { ! 262: if(nodedab==-1) ! 263: return; ! 264: ! 265: int n=node_num-1; ! 266: lseek(nodedab, n*sizeof(node_t), SEEK_SET); ! 267: read(nodedab, &node, sizeof(node_t)); ! 268: if(node.misc&NODE_LCHAT) ! 269: ; ! 270: else if(Local->ReadOnly==true) { ! 271: MainForm->Caption=AnsiString(user_name)+" on Node " ! 272: +AnsiString(node_num); ! 273: Local->ReadOnly=false; ! 274: } ! 275: else if(!node.status || node.status>NODE_QUIET || node.action!=NODE_PCHT) { ! 276: Beep(); ! 277: OutputDebugString("CHAT: User Disconnected\r\n"); ! 278: MainForm->Caption=MainForm->Caption+" - Disconnected!"; ! 279: Timer->Enabled=false; ! 280: Local->ReadOnly=true; ! 281: } ! 282: } ! 283: //--------------------------------------------------------------------------- ! 284: ! 285: void __fastcall TMainForm::FormCreate(TObject *Sender) ! 286: { ! 287: // Read Registry keys ! 288: TRegistry* Registry=new TRegistry; ! 289: if(!Registry->OpenKey(REG_KEY,true)) { ! 290: Application->MessageBox("Error opening registry key" ! 291: ,REG_KEY,MB_OK|MB_ICONEXCLAMATION); ! 292: Application->Terminate(); ! 293: } ! 294: if(Registry->ValueExists("FormHeight")) ! 295: Height=Registry->ReadInteger("FormHeight"); ! 296: if(Registry->ValueExists("FormWidth")) ! 297: Width=Registry->ReadInteger("FormWidth"); ! 298: if(Registry->ValueExists("RemoteHeight")) ! 299: Remote->Height=Registry->ReadInteger("RemoteHeight"); ! 300: ! 301: Registry->CloseKey(); ! 302: delete Registry; ! 303: ! 304: } ! 305: //--------------------------------------------------------------------------- ! 306: ! 307: ! 308: ! 309:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.