|
|
1.1 root 1: { Synchronet User Editor (Delphi 5 for Win32 project) }
2:
3: { $Id: MainFormUnit.pas,v 1.5 2000/12/13 02:24:08 rswindell 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 2000 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: { User Data function Notes:
37:
38: The Tag member of the Edit boxes is used to indicate modified data.
39: GetUserXxxx() calls GetXxxxField() sets the Tag to 0.
40: PutUserXxxx() only gets PutXxxxField() if Tag = 1.
41: GetXxxxField() and PutXxxxField() do not care about TEdits or Tags.
42: }
43:
44: unit MainFormUnit;
45:
46: interface
47:
48: uses
49: Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
50: StdCtrls, Menus, ComCtrls, ExtCtrls, Buttons, ActnList, ImgList, CheckLst,
51: ToolWin, Registry;
52:
53: type
54: TForm1 = class(TForm)
55: MainMenu: TMainMenu;
56: FileMenuItem: TMenuItem;
57: Panel: TPanel;
58: FileExitMenuItem: TMenuItem;
59: FileDeleteMenuItem: TMenuItem;
60: PageControl: TPageControl;
61: PersonalTabSheet: TTabSheet;
62: Label2: TLabel;
63: NameEdit: TEdit;
64: Label1: TLabel;
65: ComputerEdit: TEdit;
66: NetmailAddress: TLabel;
67: NetmailEdit: TEdit;
68: Label7: TLabel;
69: NoteEdit: TEdit;
70: HandleLabel: TLabel;
71: HandleEdit: TEdit;
72: Label5: TLabel;
73: PasswordEdit: TEdit;
74: Label6: TLabel;
75: BirthdateEdit: TEdit;
76: Label8: TLabel;
77: ModemEdit: TEdit;
78: Label16: TLabel;
79: SexEdit: TEdit;
80: Label18: TLabel;
81: PhoneEdit: TEdit;
82: SecurityTabSheet: TTabSheet;
83: Label10: TLabel;
84: LevelEdit: TEdit;
85: Label11: TLabel;
86: ExpireEdit: TEdit;
87: StatsTabSheet: TTabSheet;
88: TopPanel: TPanel;
89: NumberLabel: TLabel;
90: NumberEdit: TEdit;
91: TotalStaticText: TStaticText;
92: AliasLabel: TLabel;
93: AliasEdit: TEdit;
94: Label24: TLabel;
95: CommentEdit: TEdit;
96: FileNewUserMenuItem: TMenuItem;
97: Label25: TLabel;
98: ExemptionsEdit: TEdit;
99: Label26: TLabel;
100: RestrictionsEdit: TEdit;
101: Label27: TLabel;
102: CreditsEdit: TEdit;
103: Label28: TLabel;
104: MinutesEdit: TEdit;
105: Label29: TLabel;
106: FreeCreditsEdit: TEdit;
107: FileSaveUserMenuItem: TMenuItem;
108: ActionList: TActionList;
109: SaveUser: TAction;
110: NewUser: TAction;
111: RefreshUser: TAction;
112: ImageList: TImageList;
113: DeleteUser: TAction;
114: FileRefreshUserMenuItem: TMenuItem;
115: GroupBox1: TGroupBox;
116: TimeOnEdit: TEdit;
117: Label22: TLabel;
118: Label23: TLabel;
119: TimeOnTodayEdit: TEdit;
120: Label30: TLabel;
121: ExtraTimeEdit: TEdit;
122: Label31: TLabel;
123: LastCallTimeEdit: TEdit;
124: GroupBox2: TGroupBox;
125: Label20: TLabel;
126: LogonsEdit: TEdit;
127: Label21: TLabel;
128: LogonsTodayEdit: TEdit;
129: GroupBox3: TGroupBox;
130: Label17: TLabel;
131: FirstOnEdit: TEdit;
132: Label19: TLabel;
133: LastOnEdit: TEdit;
134: GroupBox4: TGroupBox;
135: Label32: TLabel;
136: PostsTotalEdit: TEdit;
137: Label33: TLabel;
138: PostsTodayEdit: TEdit;
139: GroupBox5: TGroupBox;
140: Label34: TLabel;
141: Label35: TLabel;
142: EmailTotalEdit: TEdit;
143: EmailTodayEdit: TEdit;
144: Label36: TLabel;
145: FeedbackEdit: TEdit;
146: GroupBox6: TGroupBox;
147: Label37: TLabel;
148: UploadedFilesEdit: TEdit;
149: Label38: TLabel;
150: UploadedBytesEdit: TEdit;
151: GroupBox7: TGroupBox;
152: Label39: TLabel;
153: Label40: TLabel;
154: DownloadedFilesEdit: TEdit;
155: DownloadedBytesEdit: TEdit;
156: GroupBox8: TGroupBox;
157: Label12: TLabel;
158: Flags1Edit: TEdit;
159: Label13: TLabel;
160: Flags2Edit: TEdit;
161: Label14: TLabel;
162: Flags3Edit: TEdit;
163: Label15: TLabel;
164: Flags4Edit: TEdit;
165: GroupBox9: TGroupBox;
166: AddressEdit: TEdit;
167: LocationEdit: TEdit;
168: ZipCodeEdit: TEdit;
169: DeactivateUser: TAction;
170: N1: TMenuItem;
171: FileDeactivateUserMenuItem: TMenuItem;
172: SettingsTabSheet: TTabSheet;
173: GroupBox10: TGroupBox;
174: Label3: TLabel;
175: RowsEdit: TEdit;
176: GroupBox11: TGroupBox;
177: GroupBox13: TGroupBox;
178: GroupBox15: TGroupBox;
179: ShellEdit: TEdit;
180: ExpertCheckBox: TCheckBox;
181: ChatCheckListBox: TCheckListBox;
182: TerminalCheckListBox: TCheckListBox;
183: LogonCheckListBox: TCheckListBox;
184: ToolBar: TToolBar;
185: ToolButton1: TToolButton;
186: ToolButton2: TToolButton;
187: ToolButton3: TToolButton;
188: ToolButton4: TToolButton;
189: ToolButton5: TToolButton;
190: FindEdit: TEdit;
191: ToolButton6: TToolButton;
192: FindNextButton: TButton;
193: FindButton: TButton;
194: ScrollBar: TScrollBar;
195: Label42: TLabel;
196: LeechEdit: TEdit;
197: Status: TEdit;
198: ToolButton7: TToolButton;
199: MsgFileSettingsTabSheet: TTabSheet;
200: GroupBox16: TGroupBox;
201: Label41: TLabel;
202: MessageCheckListBox: TCheckListBox;
203: EditorEdit: TEdit;
204: GroupBox12: TGroupBox;
205: Label4: TLabel;
206: Label9: TLabel;
207: TempFileExtEdit: TEdit;
208: ProtocolEdit: TEdit;
209: FileCheckListBox: TCheckListBox;
210: GroupBox14: TGroupBox;
211: QWKCheckListBox: TCheckListBox;
212: ExtendedCommentTabSheet: TTabSheet;
213: Memo: TMemo;
214: procedure FormShow(Sender: TObject);
215: procedure ScrollBarChange(Sender: TObject);
216: procedure NumberEditKeyPress(Sender: TObject; var Key: Char);
217: procedure FileExitMenuItemClick(Sender: TObject);
218: procedure EditChange(Sender: TObject);
219: procedure SaveUserExecute(Sender: TObject);
220: procedure NewUserExecute(Sender: TObject);
221: procedure DeleteUserExecute(Sender: TObject);
222: procedure FormClose(Sender: TObject; var Action: TCloseAction);
223: procedure DeactivateUserExecute(Sender: TObject);
224: procedure FindButtonClick(Sender: TObject);
225: procedure FindEditKeyPress(Sender: TObject; var Key: Char);
226: private
227: { Private declarations }
228: public
229: { Public declarations }
230: data_dir: AnsiString;
231: users: Integer;
232: user_misc: Integer;
233: user_chat: Integer;
234: user_qwk: Integer;
235: function LastUser: Integer;
236: procedure GetUserData(usernumber: Integer);
237: procedure PutUserData(usernumber: Integer);
238: end;
239:
240: var
241: Form1: TForm1;
242:
243: implementation
244:
245: const ETX=#3; { End Of Text character, all fields use for padding/terminator }
246: const CR=#13; { Carriage-return }
247: const LF=#10; { Line-feed }
248:
249: const { String lengths }
250: LEN_ALIAS =25; { User alias }
251: LEN_NAME =25; { User name }
252: LEN_HANDLE =8; { User chat handle }
253: LEN_NOTE =30; { User note }
254: LEN_COMP =30; { User computer description }
255: LEN_COMMENT =60; { User comment }
256: LEN_NETMAIL =60; { NetMail forwarding address }
257: LEN_PASS =8; { User password }
258: LEN_PHONE =12; { User phone number }
259: LEN_BIRTH =8; { Birthday in xx/xx/YY format }
260: LEN_ADDRESS =30; { User address }
261: LEN_LOCATION =30; { Location (City, State) }
262: LEN_ZIPCODE =10; { Zip/Postal code }
263: LEN_MODEM =8; { User modem type description }
264: LEN_FDESC =58; { File description }
265: LEN_FCDT =9; { 9 digits for file credit values }
266: LEN_TITLE =70; { Message title }
267: LEN_MAIN_CMD =40; { Storage in user.dat for custom commands }
268: LEN_XFER_CMD =40;
269: LEN_SCAN_CMD =40;
270: LEN_MAIL_CMD =40;
271: LEN_CID =25; { Caller ID (phone number) }
272: LEN_ARSTR =40; { Max length of Access Requirement string }
273: LEN_CHATACTCMD =9; { Chat action command }
274: LEN_CHATACTOUT =65; { Chat action output string }
275:
276:
277: { This is a list of offsets into the USER.DAT file for different variables
278: that are stored (for each user) }
279: const
280: U_ALIAS =0; { Offset to alias }
281: U_NAME =U_ALIAS+LEN_ALIAS; { Offset to name }
282: U_HANDLE =U_NAME+LEN_NAME;
283: U_NOTE =U_HANDLE+LEN_HANDLE+2;
284: U_COMP =U_NOTE+LEN_NOTE;
285: U_COMMENT =U_COMP+LEN_COMP+2;
286:
287: U_NETMAIL =U_COMMENT+LEN_COMMENT+2;
288:
289: U_ADDRESS =U_NETMAIL+LEN_NETMAIL+2;
290: U_LOCATION =U_ADDRESS+LEN_ADDRESS;
291: U_ZIPCODE =U_LOCATION+LEN_LOCATION;
292:
293: U_PASS =U_ZIPCODE+LEN_ZIPCODE+2;
294: U_PHONE =U_PASS+8; { Offset to phone-number }
295: U_BIRTH =U_PHONE+12; { Offset to users birthday }
296: U_MODEM =U_BIRTH+8;
297: U_LASTON =U_MODEM+8;
298: U_FIRSTON =U_LASTON+8;
299: U_EXPIRE =U_FIRSTON+8;
300: U_PWMOD =U_EXPIRE+8;
301:
302: U_LOGONS =U_PWMOD+8+2;
303: U_LTODAY =U_LOGONS+5;
304: U_TIMEON =U_LTODAY+5;
305: U_TEXTRA =U_TIMEON+5;
306: U_TTODAY =U_TEXTRA+5;
307: U_TLAST =U_TTODAY+5;
308: U_POSTS =U_TLAST+5;
309: U_EMAILS =U_POSTS+5;
310: U_FBACKS =U_EMAILS+5;
311: U_ETODAY =U_FBACKS+5;
312: U_PTODAY =U_ETODAY+5;
313:
314: U_ULB =U_PTODAY+5+2;
315: U_ULS =U_ULB+10;
316: U_DLB =U_ULS+5;
317: U_DLS =U_DLB+10;
318: U_CDT =U_DLS+5;
319: U_MIN =U_CDT+10;
320:
321: U_LEVEL =U_MIN+10+2; { Offset to Security Level }
322: U_FLAGS1 =U_LEVEL+2; { Offset to Flags }
323: U_TL =U_FLAGS1+8; { Offset to unused field }
324: U_FLAGS2 =U_TL+2;
325: U_EXEMPT =U_FLAGS2+8;
326: U_REST =U_EXEMPT+8;
327: U_ROWS =U_REST+8+2; { Number of Rows on user's monitor }
328: U_SEX =U_ROWS+2; { Sex, Del, ANSI, color etc. }
329: U_MISC =U_SEX+1; { Miscellaneous flags in 8-byte hex }
330: U_OLDXEDIT =U_MISC+8; { External editor (Version 1 method) }
331: U_LEECH =U_OLDXEDIT+2; { two hex digits - leech attempt count }
332: U_CURSUB =U_LEECH+2; { Current sub (internal code }
333: U_CURDIR =U_CURSUB+8; { Current dir (internal code }
334: U_CMDSET =U_CURDIR+8; { unused }
335: U_MAIN_CMD =U_CMDSET+2+2; { unused }
336: U_XFER_CMD =U_MAIN_CMD+LEN_MAIN_CMD; { unused }
337: U_SCAN_CMD =U_XFER_CMD+LEN_XFER_CMD+2; { unused }
338: U_MAIL_CMD =U_SCAN_CMD+LEN_SCAN_CMD; { unused }
339: U_FREECDT =U_MAIL_CMD+LEN_MAIL_CMD+2;
340: U_FLAGS3 =U_FREECDT+10; { Flag set #3 }
341: U_FLAGS4 =U_FLAGS3+8; { Flag set #4 }
342: U_XEDIT =U_FLAGS4+8; { External editor (code) }
343: U_SHELL =U_XEDIT+8; { Command shell (code) }
344: U_QWK =U_SHELL+8; { QWK settings }
345: U_TMPEXT =U_QWK+8; { QWK extension }
346: U_CHAT =U_TMPEXT+3; { Chat settings }
347: U_NS_TIME =U_CHAT+8; { New-file scan date/time }
348: U_PROT =U_NS_TIME+8; { Default transfer protocol }
349: U_UNUSED =U_PROT+1;
350: U_LEN =(U_UNUSED+28+2);
351:
352: { Bit values for user_misc }
353: const
354: DELETED =(1 shl 0); { Deleted user }
355: ANSI =(1 shl 1); { Supports ANSI terminal emulation }
356: UCOLOR =(1 shl 2); { Send color codes }
357: RIP =(1 shl 3); { Supports RIP terminal emulation }
358: UPAUSE =(1 shl 4); { Pause on every screen full }
359: SPIN =(1 shl 5); { Spinning cursor - Same as K_SPIN }
360: INACTIVE =(1 shl 6); { Inactive user slot }
361: EXPERT =(1 shl 7); { Expert menu mode }
362: ANFSCAN =(1 shl 8); { Auto New file scan }
363: CLRSCRN =(1 shl 9); { Clear screen before each message }
364: QUIET =(1 shl 10); { Quiet mode upon logon }
365: BATCHFLAG =(1 shl 11); { File list allow batch dl flags }
366: NETMAIL =(1 shl 12); { Forward e-mail to fidonet addr }
367: CURSUB =(1 shl 13); { Remember current sub-board/dir }
368: ASK_NSCAN =(1 shl 14); { Ask for newscanning upon logon }
369: NO_EXASCII =(1 shl 15); { Don't send extended ASCII }
370: ASK_SSCAN =(1 shl 16); { Ask for messages to you at logon }
371: AUTOTERM =(1 shl 17); { Autodetect terminal type }
372: COLDKEYS =(1 shl 18); { No hot-keys }
373: EXTDESC =(1 shl 19); { Extended file descriptions }
374: AUTOHANG =(1 shl 20); { Auto-hang-up after transfer }
375: WIP =(1 shl 21); { Supports WIP terminal emulation }
376: AUTOLOGON =(1 shl 22); { AutoLogon via IP }
377:
378: { Bit values for user_chat }
379: const
380: CHAT_ECHO =(1 shl 0); { Multinode chat echo }
381: CHAT_ACTION =(1 shl 1); { Chat actions }
382: CHAT_NOPAGE =(1 shl 2); { Can't be paged }
383: CHAT_NOACT =(1 shl 3); { No activity alerts }
384: CHAT_SPLITP =(1 shl 4); { Split screen private chat }
385:
386: { Bits for user_qwk }
387: const
388: QWK_FILES =(1 shl 0); { Include new files list }
389: QWK_EMAIL =(1 shl 1); { Include unread e-mail }
390: QWK_ALLMAIL =(1 shl 2); { Include ALL e-mail }
391: QWK_DELMAIL =(1 shl 3); { Delete e-mail after download }
392: QWK_BYSELF =(1 shl 4); { Include messages from self }
393: QWK_UNUSED =(1 shl 5); { Currently unused }
394: QWK_EXPCTLA =(1 shl 6); { Expand ctrl-a codes to ascii }
395: QWK_RETCTLA =(1 shl 7); { Retain ctrl-a codes }
396: QWK_ATTACH =(1 shl 8); { Include file attachments }
397: QWK_NOINDEX =(1 shl 9); { Do not create index files in QWK }
398: QWK_TZ =(1 shl 10); { Include "@TZ" time zone in msgs }
399: QWK_VIA =(1 shl 11); { Include "@VIA" seen-bys in msgs }
400: QWK_NOCTRL =(1 shl 12); { No extraneous control files }
401:
402: {$R *.DFM}
403:
404: { Returns total number of users in database }
405: function TForm1.LastUser: Integer;
406: var Str: AnsiString;
407: f: TFileStream;
408: begin
409: Str:=data_dir+'USER/USER.DAT';
410: try
411: f:=TFileStream.Create(Str,fmOpenRead or fmShareDenyNone);
412: Result := f.Size div U_LEN;
413: f.Free;
414: except
415: Result := 0;
416: end;
417: end;
418:
419: procedure SaveChanges;
420: begin
421: if Application.MessageBox('Save Changes','User Modified',MB_YESNO)=IDYES
422: then
423: Form1.SaveUserExecute(Form1)
424: else
425: Form1.GetUserData(Form1.ScrollBar.Position);
426: end;
427:
428: { ************* }
429: { GET USER DATA }
430: { ************* }
431:
432: { Parses a single text data field }
433: function GetTextField(buf : PChar; maxlen : Integer): AnsiString;
434: var str: AnsiString;
435: len: Integer;
436: term: PChar;
437: begin
438: term:=StrScan(buf,ETX); { Look for end-of-text marker }
439: if term = nil then
440: len:=maxlen { not found? }
441: else
442: len:=Term-buf;
443: if len > maxlen then len:=maxlen;
444: SetString(str,buf,len);
445: Result:=str;
446: end;
447:
448: { Get a 16-bit decimal integer field }
449: function GetShortIntField(buf : PChar): AnsiString;
450: begin
451: Result:=GetTextField(buf,5);
452: end;
453:
454: { Get a 32-bit decimal integer field }
455: function GetLongIntField(buf : PChar): AnsiString;
456: begin
457: Result:=GetTextField(buf,10);
458: end;
459:
460: { Parses a flag field returning string with flag letters and spaces }
461: { This function can be used for exemptions and restrictions too }
462: function GetFlagsField(buf : PChar): AnsiString;
463: var str: AnsiString;
464: flagstr: AnsiString;
465: flags: Integer;
466: i: Integer;
467: begin
468: str:='0x'+GetTextField(buf,8);
469: flags:=StrToIntDef(str,0);
470: for i:=0 to 25 do
471: if flags AND (1 shl i) <> 0 then
472: flagstr:=flagstr+Char(65+i)
473: else
474: flagstr:=flagstr+' ';
475: Result:=TrimRight(flagstr);
476: end;
477:
478: { Get a hexadecimal integer field (of any size) }
479: function GetHexField(buf : PChar; maxlen : Integer): Integer;
480: var str: AnsiString;
481: begin
482: str:='0x'+GetTextField(buf,maxlen);
483: Result:=StrToIntDef(str,0);
484: end;
485:
486: { Convert a hexadecimal time field (in unix format) to xx/xx/YY }
487: function GetDateField(buf : PChar): AnsiString;
488: var str: AnsiString;
489: date: TDateTime;
490: time: Integer;
491: begin
492: str:='0x'+GetTextField(buf,8);
493: time:=StrToIntDef(str,0);
494: if time=0 then begin
495: Result:='00/00/00';
496: Exit;
497: end;
498: time:=time div (24*60*60); { convert from seconds to days }
499: date:=EncodeDate(1970,1,1)+time; { convert to days since 1970 }
500: Result:=DateToStr(date);
501: end;
502:
503: { Reads a user data record to an Edit box and clears modified flag }
504: function GetUserText(Edit: Tedit; buf: PChar; maxlen: Integer) : AnsiString;
505: begin
506: Edit.Text:=GetTextField(buf,maxlen);
507: Edit.Tag:=0; { clear modified flag }
508: Edit.MaxLength:=maxlen;
509: Result:=Edit.Text;
510: end;
511:
512: { Reads a user data record to an Edit box and clears modified flag }
513: function GetUserShortInt(Edit: Tedit; buf: PChar) : AnsiString;
514: begin
515: GetUserText(Edit,buf,5);
516: Result:=Edit.Text;
517: end;
518:
519: { Reads a user data record to an Edit box and clears modified flag }
520: function GetUserLongInt(Edit: Tedit; buf: PChar) : AnsiString;
521: begin
522: GetUserText(Edit,buf,10);
523: Result:=Edit.Text;
524: end;
525:
526: { Reads and parses a single user record, filling in edit boxes, etc. }
527: procedure TForm1.GetUserData(usernumber: Integer);
528: var Str: AnsiString;
529: f: TFileStream;
530: buf: array[0..U_LEN] of Char;
531: begin
532: { Open file and read user record }
533: Str:=data_dir+'USER/USER.DAT';
534: try
535: f:=TFileStream.Create(Str,fmOpenRead or fmShareDenyNone);
536: except
537: Exit;
538: end;
539: f.Seek((usernumber-1)*U_LEN,soFromBeginning);
540: f.Read(buf,U_LEN);
541: f.Free;
542:
543: { ********************** }
544: { Parse user data buffer }
545: { ********************** }
546:
547: { Personal }
548: GetUserText(AliasEdit,buf+U_ALIAS,LEN_ALIAS);
549: GetUserText(NameEdit,buf+U_NAME,LEN_NAME);
550: GetUserText(HandleEdit,buf+U_HANDLE,LEN_HANDLE);
551: GetUserText(ComputerEdit,buf+U_COMP,LEN_COMP);
552: GetUserText(NetMailEdit,buf+U_NETMAIL,LEN_NETMAIL);
553: GetUserText(AddressEdit,buf+U_ADDRESS,LEN_ADDRESS);
554: GetUserText(LocationEdit,buf+U_LOCATION,LEN_LOCATION);
555: GetUserText(NoteEdit,buf+U_NOTE,LEN_NOTE);
556: GetUserText(BirthDateEdit,buf+U_BIRTH,LEN_BIRTH);
557: GetUserText(PasswordEdit,buf+U_PASS,LEN_PASS);
558: GetUserText(ModemEdit,buf+U_MODEM,LEN_MODEM);
559: GetUserText(ZipCodeEdit,buf+U_ZIPCODE,LEN_ZIPCODE);
560: GetUserText(SexEdit,buf+U_SEX,1);
561: GetUserText(PhoneEdit,buf+U_PHONE,LEN_PHONE);
562: GetUserText(CommentEdit,buf+U_COMMENT,LEN_COMMENT);
563:
564: { Settings }
565: GetUserText(RowsEdit,buf+U_ROWS,2);
566: GetUserText(ShellEdit,buf+U_SHELL,8);
567: GetUserText(EditorEdit,buf+U_XEDIT,8);
568: GetUserText(ProtocolEdit,buf+U_PROT,1);
569: GetUserText(TempFileExtEdit,buf+U_TMPEXT,3);
570:
571: { Read 'misc' bit-field }
572: user_misc:=GetHexField(buf+U_MISC,8);
573: ExpertCheckBox.Checked:=user_misc AND EXPERT <> 0;
574: ExpertCheckBox.Tag:=0;
575:
576: TerminalCheckListBox.Checked[0]:=user_misc AND AUTOTERM <> 0;
577: TerminalCheckListBox.Checked[1]:=user_misc AND NO_EXASCII = 0;
578: TerminalCheckListBox.Checked[2]:=user_misc AND ANSI <> 0;
579: TerminalCheckListBox.Checked[3]:=user_misc AND UCOLOR <> 0;
580: TerminalCheckListBox.Checked[4]:=user_misc AND RIP <> 0;
581: TerminalCheckListBox.Checked[5]:=user_misc AND WIP <> 0;
582: TerminalCheckListBox.Checked[6]:=user_misc AND UPAUSE <> 0;
583: TerminalCheckListBox.Checked[7]:=user_misc AND COLDKEYS = 0;
584: TerminalCheckListBox.Checked[8]:=user_misc AND SPIN <> 0;
585: TerminalCheckListBox.Tag:=0;
586:
587: MessageCheckListBox.Checked[0]:=user_misc AND NETMAIL <> 0;
588: MessageCheckListBox.Checked[1]:=user_misc AND CLRSCRN <> 0;
589: MessageCheckListBox.Tag:=0;
590:
591: FileCheckListBox.Checked[0]:=user_misc AND ANFSCAN <> 0;
592: FileCheckListBox.Checked[1]:=user_misc AND EXTDESC <> 0;
593: FileCheckListBox.Checked[2]:=user_misc AND BATCHFLAG <> 0;
594: FileCheckListBox.Checked[3]:=user_misc AND AUTOHANG <> 0;
595: FileCheckListBox.Tag:=0;
596:
597: LogonCheckListBox.Checked[0]:=user_misc AND ASK_NSCAN <> 0;
598: LogonCheckListBox.Checked[1]:=user_misc AND ASK_SSCAN <> 0;
599: LogonCheckListBox.Checked[2]:=user_misc AND CURSUB <> 0;
600: LogonCheckListBox.Checked[3]:=user_misc AND QUIET <> 0;
601: LogonCheckListBox.Checked[4]:=user_misc AND AUTOLOGON <> 0;
602: LogonCheckListBox.Tag:=0;
603:
604: { Read 'QWK' bit-field }
605: user_qwk:=GetHexField(buf+U_QWK,8);
606: QWKCheckListBox.Checked[0]:=user_qwk AND QWK_FILES <> 0;
607: QWKCheckListBox.Checked[1]:=user_qwk AND QWK_EMAIL <> 0;
608: QWKCheckListBox.Checked[2]:=user_qwk AND QWK_ALLMAIL <> 0;
609: QWKCheckListBox.Checked[3]:=user_qwk AND QWK_DELMAIL <> 0;
610: QWKCheckListBox.Checked[4]:=user_qwk AND QWK_BYSELF <> 0;
611: QWKCheckListBox.Checked[5]:=user_qwk AND QWK_EXPCTLA <> 0;
612: QWKCheckListBox.Checked[6]:=user_qwk AND QWK_RETCTLA = 0;
613: QWKCheckListBox.Checked[7]:=user_qwk AND QWK_ATTACH <> 0;
614: QWKCheckListBox.Checked[8]:=user_qwk AND QWK_NOINDEX <> 0;
615: QWKCheckListBox.Checked[9]:=user_qwk AND QWK_TZ <> 0;
616: QWKCheckListBox.Checked[10]:=user_qwk AND QWK_VIA <> 0;
617: QWKCheckListBox.Checked[11]:=user_qwk AND QWK_NOCTRL = 0;
618: QWKCheckListBox.Tag:=0;
619:
620: { Read 'chat' bit-field }
621: user_chat:=GetHexField(buf+U_CHAT,8);
622: ChatCheckListBox.Checked[0]:=user_chat AND CHAT_ECHO <> 0;
623: ChatCheckListBox.Checked[1]:=user_chat AND CHAT_ACTION <> 0;
624: ChatCheckListBox.Checked[2]:=user_chat AND CHAT_NOPAGE = 0;
625: ChatCheckListBox.Checked[3]:=user_chat AND CHAT_NOACT = 0;
626: ChatCheckListBox.Checked[4]:=user_chat AND CHAT_SPLITP <> 0;
627: ChatCheckListBox.Tag:=0;
628:
629: { Initialize controls based on bits set/unset }
630: if user_misc AND DELETED <> 0 then
631: Status.Text := 'Deleted User'
632: else if user_misc AND INACTIVE <> 0 then
633: Status.Text := 'Inactive User'
634: else
635: Status.Text := 'Active User';
636:
637: { Security }
638: GetUserText(LevelEdit,buf+U_LEVEL,2);
639: ExpireEdit.Text:=GetDateField(buf+U_EXPIRE);
640: ExpireEdit.Tag:=0;
641: Flags1Edit.Text:=GetFlagsField(buf+U_FLAGS1);
642: Flags1Edit.Tag:=0;
643: Flags2Edit.Text:=GetFlagsField(buf+U_FLAGS2);
644: Flags2Edit.Tag:=0;
645: Flags3Edit.Text:=GetFlagsField(buf+U_FLAGS3);
646: Flags3Edit.Tag:=0;
647: Flags4Edit.Text:=GetFlagsField(buf+U_FLAGS4);
648: Flags4Edit.Tag:=0;
649: ExemptionsEdit.Text:=GetFlagsField(buf+U_EXEMPT);
650: ExemptionsEdit.Tag:=0;
651: RestrictionsEdit.Text:=GetFlagsField(buf+U_REST);
652: RestrictionsEdit.Tag:=0;
653: GetUserLongInt(CreditsEdit,buf+U_CDT);
654: GetUserLongInt(FreeCreditsEdit,buf+U_FREECDT);
655: GetUserLongInt(MinutesEdit,buf+U_MIN);
656:
657: { Stats }
658: FirstOnEdit.Text:=GetDateField(buf+U_FIRSTON);
659: FirstOnEdit.Tag:=0;
660: LastOnEdit.Text:=GetDateField(buf+U_LASTON);
661: LastOnEdit.Tag:=0;
662: GetUserShortInt(LogonsEdit,buf+U_LOGONS);
663: GetUserShortInt(LogonsTodayEdit,buf+U_LTODAY);
664: GetUserShortInt(TimeOnEdit,buf+U_TIMEON);
665: GetUserShortInt(LastCallTimeEdit,buf+U_TLAST);
666: GetUserShortInt(TimeOnTodayEdit,buf+U_TTODAY);
667: GetUserShortInt(ExtraTimeEdit,buf+U_TEXTRA);
668: GetUserShortInt(PostsTotalEdit,buf+U_POSTS);
669: GetUserShortInt(PostsTodayEdit,buf+U_PTODAY);
670: GetUserShortInt(EmailTotalEdit,buf+U_EMAILS);
671: GetUserShortInt(EmailTodayEdit,buf+U_ETODAY);
672: GetUserShortInt(FeedbackEdit,buf+U_FBACKS);
673: GetUserShortInt(UploadedFilesEdit,buf+U_ULS);
674: GetUserLongInt(UploadedBytesEdit,buf+U_ULB);
675: GetUserShortInt(DownloadedFilesEdit,buf+U_DLS);
676: GetUserLongInt(DownloadedBytesEdit,buf+U_DLB);
677: LeechEdit.Text:=IntToStr(GetHexField(buf+U_LEECH,2));
678:
679: { etc... }
680:
681: { Extended Comment }
682: Memo.Lines.Clear();
683: Str:=data_dir+Format('USER/%.4d.MSG',[usernumber]);
684: if FileExists(Str) then Memo.Lines.LoadFromFile(Str);
685: Memo.Tag:=0;
686:
687: { Update User Number }
688: NumberEdit.Text:=IntToStr(ScrollBar.Position);
689: SaveUser.Enabled:=false; { no changes have been made yet }
690: end;
691:
692: { ************* }
693: { PUT USER DATA }
694: { ************* }
695:
696: { Encodes a single text data field (of any length) }
697: procedure PutTextField(buf : PChar; str : AnsiString; maxlen : Integer);
698: var len:Integer;
699: i:Integer;
700: begin
701: for i:=0 to maxlen-1 do buf[i]:=ETX;
702: len:=Length(str);
703: if len > maxlen then len:=maxlen;
704: for i:=0 to len-1 do buf[i]:=str[i+1];
705: end;
706:
707: { Encodes a flag field (A-Z) into a 32-bit Hex string }
708: procedure PutFlagsField(buf : PChar; str : AnsiString);
709: var flags: Integer;
710: i:Integer;
711: begin
712: flags:=0;
713: for i:=0 to 25 do
714: if Pos(Chr(65+i),str) <> 0 then
715: flags:=flags OR (1 shl i);
716: PutTextField(buf,IntToHex(flags,8),8);
717: end;
718:
719: { Converts a date string in xx/xx/YY format into a unix time_t format in hex }
720: procedure PutDateField(buf : PChar; str : AnsiString);
721: var val: Integer;
722: begin
723: { convert to days since 1970 }
724: val:=Round(StrToDate(str)-EncodeDate(1970,1,1));
725: if val < 0 then val:=0;
726: { convert from days to seconds }
727: val:=val*(24*60*60);
728: PutTextField(buf,IntToHex(val,8),8);
729: end;
730:
731: { Writes to a 16-bit decimal integer field }
732: procedure PutShortIntField(buf : PChar; str : AnsiString);
733: begin
734: PutTextField(buf, str, 5);
735: end;
736:
737: { Writes to a 32-bit decimal integer field }
738: procedure PutLongIntField(buf : PChar; str : AnsiString);
739: begin
740: PutTextField(buf, str, 10);
741: end;
742:
743: { Writes to a hexadecimal integer field (of any length) }
744: procedure PutHexField(buf : PChar; val : Integer; maxlen : Integer);
745: begin
746: PutTextField(buf,IntToHex(val,maxlen),maxlen);
747: end;
748:
749: { Writes a user Edit box's contents to the buffer, if changed, resets Tag }
750: procedure PutUserText(Edit:Tedit; buf:PChar; maxlen:Integer);
751: begin
752: if Edit.Tag = 1 then { field modified, change record }
753: PutTextField(buf,Edit.Text,maxlen);
754: Edit.Tag:=0; { clear modified flag }
755: end;
756:
757: { Writes a flag Edit box's contents to the buffer, if changed }
758: { This function can be used for exemptions and restrictions too }
759: procedure PutUserFlags(Edit:Tedit; buf:PChar);
760: begin
761: if Edit.Tag = 1 then { field modified, change record }
762: PutFlagsField(buf,Edit.Text);
763: Edit.Tag:=0; { clear modified flag }
764: end;
765:
766: { Writes a 16-bit integer Edit box's contents to the buffer, if changed }
767: procedure PutUserShortInt(Edit:Tedit; buf:PChar);
768: begin
769: if Edit.Tag = 1 then { field modified, change record }
770: PutTextField(buf,Edit.Text,5);
771: Edit.Tag:=0; { clear modified flag }
772: end;
773:
774: { Writes a 32-bit integer Edit box's contents to the buffer, if changed }
775: procedure PutUserLongInt(Edit:Tedit; buf:PChar);
776: begin
777: if Edit.Tag = 1 then { field modified, change record }
778: PutTextField(buf,Edit.Text,10);
779: Edit.Tag:=0; { clear modified flag }
780: end;
781:
782: { Writes a date Edit box's contents to the buffer, if changed }
783: procedure PutUserDate(Edit:Tedit; buf:PChar);
784: begin
785: if Edit.Tag = 1 then { field modified, change record }
786: PutDateField(buf,Edit.Text);
787: Edit.Tag:=0; { clear modified flag }
788: end;
789:
790: function SetBit(set_it: bool; field: Cardinal; bit: Cardinal): Cardinal;
791: begin
792: if set_it then
793: Result:=field OR bit { set bit }
794: else
795: Result:=field AND NOT bit; { clear bit }
796: end;
797:
798: { Writes a complete user record. }
799: procedure TForm1.PutUserData(usernumber:Integer);
800: var Str: AnsiString;
801: f: TFileStream;
802: i: Integer;
803: buf: array[0..U_LEN] of Char;
804: begin
805: if AliasEdit.Tag = 1 then begin
806: { Set-up buffer for NAME.DAT record }
807: if user_misc AND DELETED <> 0 then
808: PutTextField(buf,'',LEN_ALIAS)
809: else
810: PutTextField(buf,AliasEdit.Text,LEN_ALIAS);
811: buf[LEN_ALIAS]:=CR;
812: buf[LEN_ALIAS+1]:=LF;
813:
814: { Open NAME.DAT write user name }
815: Str:=data_dir+'USER/NAME.DAT';
816: if FileExists(Str) then
817: f:=TFileStream.Create(Str,fmOpenWrite or fmShareExclusive)
818: else
819: f:=TFileStream.Create(Str,fmCreate or fmShareExclusive);
820: f.Seek((usernumber-1)*(LEN_ALIAS+2),soFromBeginning);
821: f.Write(buf,LEN_ALIAS+2);
822: f.Free;
823: end;
824:
825: { Initialize USER record buffer }
826: for i:=0 to U_LEN-1 do buf[i]:=ETX;
827:
828: { Open file and read current user record }
829: Str:=data_dir+'USER/USER.DAT';
830: if FileExists(Str) then
831: f:=TFileStream.Create(Str,fmOpenReadWrite or fmShareExclusive)
832: else
833: f:=TFileStream.Create(Str,fmCreate or fmShareExclusive);
834:
835: f.Seek((usernumber-1)*U_LEN,soFromBeginning);
836: f.Read(buf,U_LEN);
837:
838: { Update changed fields }
839: PutUserText(AliasEdit,buf+U_ALIAS,LEN_ALIAS);
840: PutUserText(NameEdit,buf+U_NAME,LEN_NAME);
841: PutUserText(HandleEdit,buf+U_HANDLE,LEN_HANDLE);
842: PutUserText(ComputerEdit,buf+U_COMP,LEN_COMP);
843: PutUserText(NetMailEdit,buf+U_NETMAIL,LEN_NETMAIL);
844: PutUserText(AddressEdit,buf+U_ADDRESS,LEN_ADDRESS);
845: PutUserText(LocationEdit,buf+U_LOCATION,LEN_LOCATION);
846: PutUserText(ZipCodeEdit,buf+U_ZIPCODE,LEN_ZIPCODE);
847: PutUserText(PasswordEdit,buf+U_PASS,LEN_PASS);
848: PutUserText(PhoneEdit,buf+U_PHONE,LEN_PHONE);
849: PutUserText(BirthDateEdit,buf+U_BIRTH,LEN_BIRTH);
850: PutUserText(ModemEdit,buf+U_MODEM,LEN_MODEM);
851: PutUserText(SexEdit,buf+U_SEX,1);
852: PutUserText(CommentEdit,buf+U_COMMENT,LEN_COMMENT);
853: { etc. }
854:
855: { Settings }
856: PutUserText(RowsEdit,buf+U_ROWS,2);
857: PutUserText(ShellEdit,buf+U_SHELL,8);
858: PutUserText(EditorEdit,buf+U_XEDIT,8);
859: PutUserText(ProtocolEdit,buf+U_PROT,1);
860: PutUserText(TempFileExtEdit,buf+U_TMPEXT,3);
861:
862: { Write MISC bit-field}
863: if (ExpertCheckBox.Tag = 1)
864: or (LogonCheckListBox.Tag = 1)
865: or (TerminalCheckListBox.Tag = 1)
866: or (MessageCheckListBox.Tag = 1)
867: or (FileCheckListBox.Tag = 1)
868: then begin
869: user_misc:=SetBit(ExpertCheckBox.Checked, user_misc, EXPERT);
870:
871: { TerminalCeckListBox }
872: user_misc:=SetBit(TerminalCheckListBox.Checked[0],user_misc,AUTOTERM);
873: user_misc:=SetBit(NOT TerminalCheckListBox.Checked[1],user_misc,NO_EXASCII);
874: user_misc:=SetBit(TerminalCheckListBox.Checked[2],user_misc,ANSI);
875: user_misc:=SetBit(TerminalCheckListBox.Checked[3],user_misc,UCOLOR);
876: user_misc:=SetBit(TerminalCheckListBox.Checked[4],user_misc,RIP);
877: user_misc:=SetBit(TerminalCheckListBox.Checked[5],user_misc,WIP);
878: user_misc:=SetBit(TerminalCheckListBox.Checked[6],user_misc,UPAUSE);
879: user_misc:=SetBit(NOT TerminalCheckListBox.Checked[7],user_misc,COLDKEYS);
880: user_misc:=SetBit(TerminalCheckListBox.Checked[8],user_misc,SPIN);
881:
882: { MessageCheckListBox }
883: user_misc:=SetBit(MessageCheckListBox.Checked[0],user_misc,NETMAIL);
884: user_misc:=SetBit(MessageCheckListBox.Checked[1],user_misc,CLRSCRN);
885:
886: { FileCheckListBox }
887: user_misc:=SetBit(FileCheckListBox.Checked[0],user_misc,ANFSCAN);
888: user_misc:=SetBit(FileCheckListBox.Checked[1],user_misc,EXTDESC);
889: user_misc:=SetBit(FileCheckListBox.Checked[2],user_misc,BATCHFLAG);
890: user_misc:=SetBit(FileCheckListBox.Checked[3],user_misc,AUTOHANG);
891:
892: { LogonCheckListBox }
893: user_misc:=SetBit(LogonCheckListBox.Checked[0],user_misc,ASK_NSCAN);
894: user_misc:=SetBit(LogonCheckListBox.Checked[1],user_misc,ASK_SSCAN);
895: user_misc:=SetBit(LogonCheckListBox.Checked[2],user_misc,CURSUB);
896: user_misc:=SetBit(LogonCheckListBox.Checked[3],user_misc,QUIET);
897: user_misc:=SetBit(LogonCheckListBox.Checked[4],user_misc,AUTOLOGON);
898:
899: PutHexField(buf+U_MISC, user_misc, 8);
900: end;
901:
902: if (ChatCheckListBox.Tag = 1) then begin
903: user_chat:=SetBit(ChatCheckListBox.Checked[0],user_chat,CHAT_ECHO);
904: user_chat:=SetBit(ChatCheckListBox.Checked[1],user_chat,CHAT_ACTION);
905: user_chat:=SetBit(NOT ChatCheckListBox.Checked[2],user_chat,CHAT_NOPAGE);
906: user_chat:=SetBit(NOT ChatCheckListBox.Checked[3],user_chat,CHAT_NOACT);
907: user_chat:=SetBit(ChatCheckListBox.Checked[4],user_chat,CHAT_SPLITP);
908:
909: PutHexField(buf+U_CHAT, user_chat, 8);
910: end;
911:
912: if (QWKCheckListBox.Tag =1) then begin
913: user_qwk:=SetBit(QWKCheckListBox.Checked[0],user_qwk,QWK_FILES);
914: user_qwk:=SetBit(QWKCheckListBox.Checked[1],user_qwk,QWK_EMAIL);
915: user_qwk:=SetBit(QWKCheckListBox.Checked[2],user_qwk,QWK_ALLMAIL);
916: user_qwk:=SetBit(QWKCheckListBox.Checked[3],user_qwk,QWK_DELMAIL);
917: user_qwk:=SetBit(QWKCheckListBox.Checked[4],user_qwk,QWK_BYSELF);
918: user_qwk:=SetBit(QWKCheckListBox.Checked[5],user_qwk,QWK_EXPCTLA);
919: user_qwk:=SetBit(NOT QWKCheckListBox.Checked[6],user_qwk,QWK_RETCTLA);
920: user_qwk:=SetBit(QWKCheckListBox.Checked[7],user_qwk,QWK_ATTACH);
921: user_qwk:=SetBit(QWKCheckListBox.Checked[8],user_qwk,QWK_NOINDEX);
922: user_qwk:=SetBit(QWKCheckListBox.Checked[9],user_qwk,QWK_TZ);
923: user_qwk:=SetBit(QWKCheckListBox.Checked[10],user_qwk,QWK_VIA);
924: user_qwk:=SetBit(NOT QWKCheckListBox.Checked[11],user_qwk,QWK_NOCTRL);
925:
926: PutHexField(buf+U_QWK, user_qwk, 8);
927: end;
928:
929: { Security }
930: PutUserText(LevelEdit,buf+U_LEVEL,2);
931: PutUserDate(ExpireEdit,buf+U_EXPIRE);
932: PutUserFlags(Flags1Edit,buf+U_FLAGS1);
933: PutUserFlags(Flags2Edit,buf+U_FLAGS2);
934: PutUserFlags(Flags3Edit,buf+U_FLAGS3);
935: PutUserFlags(Flags4Edit,buf+U_FLAGS4);
936: PutUserFlags(ExemptionsEdit,buf+U_EXEMPT);
937: PutUserFlags(RestrictionsEdit,buf+U_REST);
938: PutUserLongInt(CreditsEdit,buf+U_CDT);
939: PutUserLongInt(FreeCreditsEdit,buf+U_FREECDT);
940: PutUserLongInt(MinutesEdit,buf+U_MIN);
941: { etc. }
942:
943: { Stats }
944: PutUserDate(FirstOnEdit,buf+U_FIRSTON);
945: PutUserDate(LastOnEdit,buf+U_LASTON);
946: PutUserShortInt(LogonsEdit,buf+U_LOGONS);
947: PutUserShortInt(LogonsTodayEdit,buf+U_LTODAY);
948: PutUserShortInt(TimeOnEdit,buf+U_TIMEON);
949: PutUserShortInt(TimeOnTodayEdit,buf+U_TTODAY);
950: PutUserShortInt(LastCallTimeEdit,buf+U_TLAST);
951: PutUserShortInt(ExtraTimeEdit,buf+U_TEXTRA);
952: PutUserShortInt(PostsTotalEdit,buf+U_POSTS);
953: PutUserShortInt(PostsTodayEdit,buf+U_PTODAY);
954: PutUserShortInt(EmailTotalEdit,buf+U_EMAILS);
955: PutUserShortInt(EmailTodayEdit,buf+U_ETODAY);
956: PutUserShortInt(FeedbackEdit,buf+U_FBACKS);
957: PutUserShortInt(UploadedFilesEdit,buf+U_ULS);
958: PutUserLongInt(UploadedBytesEdit,buf+U_ULB);
959: PutUserShortInt(DownloadedFilesEdit,buf+U_DLS);
960: PutUserLongInt(DownloadedBytesEdit,buf+U_DLB);
961: PutHexField(buf+U_LEECH, StrToIntDef(LeechEdit.Text,0), 2);
962: { etc. }
963:
964: { Write user record and close file }
965: f.Seek((usernumber-1)*U_LEN,soFromBeginning);
966: f.Write(buf,U_LEN);
967: f.Free;
968:
969: { Extended Comemnt }
970: if Memo.Tag = 1 then begin
971: Str:=data_dir+Format('USER/%.4d.MSG',[usernumber]);
972: if Memo.Lines.Count<>0 then
973: Memo.Lines.SaveToFile(Str)
974: else
975: DeleteFile(Str);
976: end;
977:
978: SaveUser.Enabled:=false;
979: end;
980:
981: { ********* }
982: { MAIN FORM }
983: { ********* }
984:
985: { There's probably a better place to do this init stuff... constructor? }
986: procedure TForm1.FormShow(Sender: TObject);
987: begin
988:
989: { Over-ride Locale settings here }
990: DateSeparator:='/';
991:
992: if(ShortDateFormat = 'M/d/yyyy') then
993: ShortDateFormat:='mm/dd/yy' { American }
994: else
995: ShortDateFormat:='dd/mm/yy'; { European }
996:
997: data_dir:=ParamStr(1);
998: if Length(data_dir)=0 then data_dir:='c:\sbbs\data\';
999:
1000: users:=LastUser();
1001:
1002: if users = 0 then { Create user if none exist }
1003: users:=1;
1004:
1005: ScrollBar.Min:=1;
1006: ScrollBar.Max:=users;
1007: TotalStaticText.Caption:='of '+IntToStr(users);
1008: { *********************************** }
1009: { Set max lengths for edit boxes here }
1010: { *********************************** }
1011: { Personal }
1012: AliasEdit.MaxLength:=LEN_ALIAS;
1013: NameEdit.MaxLength:=LEN_NAME;
1014: PhoneEdit.MaxLength:=LEN_PHONE;
1015: HandleEdit.MaxLength:=LEN_HANDLE;
1016: ComputerEdit.MaxLength:=LEN_COMP;
1017: AddressEdit.MaxLength:=LEN_ADDRESS;
1018: LocationEdit.MaxLength:=LEN_LOCATION;
1019: ZipCodeEdit.MaxLength:=LEN_ZIPCODE;
1020: ModemEdit.MaxLength:=LEN_MODEM;
1021: CommentEdit.MaxLength:=LEN_COMMENT;
1022: { Security }
1023: PasswordEdit.MaxLength:=LEN_PASS;
1024: PhoneEdit.MaxLength:=LEN_PHONE;
1025: ModemEdit.MaxLength:=LEN_MODEM;
1026: SexEdit.MaxLength:=1;
1027: { Stats }
1028: { etc. }
1029:
1030: ScrollBar.Position:=StrToIntDef(ParamStr(2),1);
1031: GetUserData(ScrollBar.Position);
1032:
1033: PageControl.ActivePage:=PersonalTabSheet;
1034: end;
1035:
1036: { Change user }
1037: procedure TForm1.ScrollBarChange(Sender: TObject);
1038: begin
1039: if SaveUser.Enabled then SaveChanges();
1040: users:=LastUser(); { this could change dynamically }
1041: ScrollBar.Max:=users;
1042: TotalStaticText.Caption:='of '+IntToStr(users);
1043: GetUserData(ScrollBar.Position);
1044: end;
1045:
1046: { Better than on OnChange event, waits til users hits enter key }
1047: procedure TForm1.NumberEditKeyPress(Sender: TObject; var Key: Char);
1048: var val : Integer;
1049: begin
1050: if Key <> #13 then Exit;
1051: users:=lastuser;
1052: val:=StrToIntDef(NumberEdit.Text,0);
1053: if (val = 0) or (val > users) then
1054: NumberEdit.Text:=IntToStr(ScrollBar.Position)
1055: else begin
1056: ScrollBar.Position:=val;
1057: GetUserData(val);
1058: Key:=#0;
1059: end
1060: end;
1061:
1062: procedure TForm1.FileExitMenuItemClick(Sender: TObject);
1063: begin
1064: Close;
1065: end;
1066:
1067: { OnChange event for ALL User Data Edit boxes }
1068: procedure TForm1.EditChange(Sender: TObject);
1069: begin
1070: SaveUser.Enabled:=true;
1071: (Sender as TComponent).Tag:=1; { Mark as modified }
1072: end;
1073:
1074: { Create a New User record }
1075: procedure TForm1.SaveUserExecute(Sender: TObject);
1076: begin
1077: PutUserData(StrToIntDef(NumberEdit.Text,ScrollBar.Position));
1078: end;
1079:
1080: procedure TForm1.NewUserExecute(Sender: TObject);
1081: begin
1082: if SaveUser.Enabled then SaveChanges();
1083:
1084: { New users's number }
1085: users:=lastuser()+1;
1086:
1087: { Initialize fields to default values }
1088: AliasEdit.Text:='New User';
1089: AliasEdit.Tag := 1;
1090: LevelEdit.Text:='10';
1091: LevelEdit.Tag :=1;
1092: FirstOnEdit.Text:=DatetoStr(Date);
1093: FirstOnEdit.Tag :=1;
1094: LastOnEdit.Text:=DateToStr(Date);
1095: LastOnEdit.Tag :=1;
1096: TerminalCheckListBox.Checked[0] := true; // AUTOTERM
1097: TerminalCheckListBox.Checked[1] := true; // EXASCII
1098: TerminalCheckListBox.Checked[2] := true; // ANSI
1099: TerminalCheckListBox.Checked[3] := true; // COLOR
1100: TerminalCheckListBox.Checked[6] := true; // UPAUSE
1101: TerminalCheckListBox.Checked[7] := true; // HOTKEYS
1102: FileCheckListBox.Checked[2] := true; // BATCHFLAG
1103: LogonCheckListBox.Tag:=1;
1104:
1105: { Create the new record }
1106: PutUserData(users);
1107:
1108: { Set scroll bar and usernumber text }
1109: ScrollBar.Max:=users;
1110: ScrollBar.Position:=users;
1111: NumberEdit.Text:=IntToStr(users);
1112:
1113: end;
1114:
1115: procedure TForm1.DeleteUserExecute(Sender: TObject);
1116: begin
1117: user_misc:=user_misc xor DELETED;
1118: LogonCheckListBox.Tag:=1; { flag as modified }
1119: AliasEdit.Tag := 1;
1120: PutUserData(ScrollBar.Position);
1121: GetUserData(ScrollBar.Position);
1122: end;
1123:
1124: procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
1125: begin
1126: if SaveUser.Enabled then SaveChanges();
1127: end;
1128:
1129: procedure TForm1.DeactivateUserExecute(Sender: TObject);
1130: begin
1131: user_misc:=user_misc xor INACTIVE;
1132: LogonCheckListBox.Tag:=1; { flag as modified }
1133: PutUserData(ScrollBar.Position);
1134: GetUserData(ScrollBar.Position);
1135: end;
1136:
1137: procedure TForm1.FindButtonClick(Sender: TObject);
1138: var Str: AnsiString;
1139: SearchStr: AnsiString;
1140: f: TFileStream;
1141: usernumber: Integer;
1142: buf: array[0..U_LEN] of Char;
1143: begin
1144: SearchStr:=AnsiUpperCase(FindEdit.Text);
1145: usernumber:=0;
1146: { Open USER.DAT to search for string }
1147: Str:=data_dir+'USER/USER.DAT';
1148: if not FileExists(Str) then Exit;
1149: f:=TFileStream.Create(Str,fmOpenRead or fmShareDenyNone);
1150: if Sender = FindNextButton then
1151: f.Seek((ScrollBar.Position)*(U_LEN),soFromBeginning);
1152: while (f.Position < f.Size) and (usernumber=0) do begin
1153: f.Read(buf,U_LEN);
1154: SetString(Str,buf,U_LEN);
1155: Str:=AnsiUpperCase(Str);
1156: if Pos(SearchStr,Str) <> 0 then
1157: usernumber:=f.Position div (U_LEN);
1158: end;
1159: f.Free;
1160: if usernumber <> 0 then begin
1161: ScrollBar.Position:=usernumber;
1162: end;
1163: end;
1164:
1165: procedure TForm1.FindEditKeyPress(Sender: TObject; var Key: Char);
1166: begin
1167: if Key = #13 then begin
1168: FindButtonClick(Sender);
1169: Key:=#0;
1170: end;
1171: end;
1172:
1173: end.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.