|
|
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.