|
|
1.1 root 1: { Synchronet User Editor (Delphi 5 for Win32 project) }
2:
3: { $Id: MainFormUnit.pas,v 1.9 2003/02/20 00:11:25 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 begin
631: Status.Text := 'Deleted User';
632: Status.Color := clRed;
633: end
634: else if user_misc AND INACTIVE <> 0 then begin
635: Status.Text := 'Inactive User';
636: Status.Color := clYellow;
637: end
638: else begin
639: Status.Text := 'Active User';
640: Status.Color := clMenu;
641: end;
642:
643: { Security }
644: GetUserText(LevelEdit,buf+U_LEVEL,2);
645: ExpireEdit.Text:=GetDateField(buf+U_EXPIRE);
646: ExpireEdit.Tag:=0;
647: Flags1Edit.Text:=GetFlagsField(buf+U_FLAGS1);
648: Flags1Edit.Tag:=0;
649: Flags2Edit.Text:=GetFlagsField(buf+U_FLAGS2);
650: Flags2Edit.Tag:=0;
651: Flags3Edit.Text:=GetFlagsField(buf+U_FLAGS3);
652: Flags3Edit.Tag:=0;
653: Flags4Edit.Text:=GetFlagsField(buf+U_FLAGS4);
654: Flags4Edit.Tag:=0;
655: ExemptionsEdit.Text:=GetFlagsField(buf+U_EXEMPT);
656: ExemptionsEdit.Tag:=0;
657: RestrictionsEdit.Text:=GetFlagsField(buf+U_REST);
658: RestrictionsEdit.Tag:=0;
659: GetUserLongInt(CreditsEdit,buf+U_CDT);
660: GetUserLongInt(FreeCreditsEdit,buf+U_FREECDT);
661: GetUserLongInt(MinutesEdit,buf+U_MIN);
662:
663: { Stats }
664: FirstOnEdit.Text:=GetDateField(buf+U_FIRSTON);
665: FirstOnEdit.Tag:=0;
666: LastOnEdit.Text:=GetDateField(buf+U_LASTON);
667: LastOnEdit.Tag:=0;
668: GetUserShortInt(LogonsEdit,buf+U_LOGONS);
669: GetUserShortInt(LogonsTodayEdit,buf+U_LTODAY);
670: GetUserShortInt(TimeOnEdit,buf+U_TIMEON);
671: GetUserShortInt(LastCallTimeEdit,buf+U_TLAST);
672: GetUserShortInt(TimeOnTodayEdit,buf+U_TTODAY);
673: GetUserShortInt(ExtraTimeEdit,buf+U_TEXTRA);
674: GetUserShortInt(PostsTotalEdit,buf+U_POSTS);
675: GetUserShortInt(PostsTodayEdit,buf+U_PTODAY);
676: GetUserShortInt(EmailTotalEdit,buf+U_EMAILS);
677: GetUserShortInt(EmailTodayEdit,buf+U_ETODAY);
678: GetUserShortInt(FeedbackEdit,buf+U_FBACKS);
679: GetUserShortInt(UploadedFilesEdit,buf+U_ULS);
680: GetUserLongInt(UploadedBytesEdit,buf+U_ULB);
681: GetUserShortInt(DownloadedFilesEdit,buf+U_DLS);
682: GetUserLongInt(DownloadedBytesEdit,buf+U_DLB);
683: LeechEdit.Text:=IntToStr(GetHexField(buf+U_LEECH,2));
684:
685: { etc... }
686:
687: { Extended Comment }
688: Memo.Lines.Clear();
689: Str:=data_dir+Format('USER/%.4d.MSG',[usernumber]);
690: if FileExists(Str) then Memo.Lines.LoadFromFile(Str);
691: Memo.Tag:=0;
692:
693: { Update User Number }
694: NumberEdit.Text:=IntToStr(ScrollBar.Position);
695: SaveUser.Enabled:=false; { no changes have been made yet }
696: end;
697:
698: { ************* }
699: { PUT USER DATA }
700: { ************* }
701:
702: { Encodes a single text data field (of any length) }
703: procedure PutTextField(buf : PChar; str : AnsiString; maxlen : Integer);
704: var len:Integer;
705: i:Integer;
706: begin
707: for i:=0 to maxlen-1 do buf[i]:=ETX;
708: len:=Length(str);
709: if len > maxlen then len:=maxlen;
710: for i:=0 to len-1 do buf[i]:=str[i+1];
711: end;
712:
713: { Encodes a flag field (A-Z) into a 32-bit Hex string }
714: procedure PutFlagsField(buf : PChar; str : AnsiString);
715: var flags: Integer;
716: i:Integer;
717: begin
718: flags:=0;
719: for i:=0 to 25 do
720: if Pos(Chr(65+i),str) <> 0 then
721: flags:=flags OR (1 shl i);
722: PutTextField(buf,IntToHex(flags,8),8);
723: end;
724:
725: { Converts a date string in xx/xx/YY format into a unix time_t format in hex }
726: procedure PutDateField(buf : PChar; str : AnsiString);
727: var val: Integer;
728: begin
729: { convert to days since 1970 }
730: try
731: val:=Round(StrToDate(str)-EncodeDate(1970,1,1));
732: except
733: val:=0;
734: end;
735: if val < 0 then val:=0;
736: { convert from days to seconds }
737: val:=val*(24*60*60);
738: PutTextField(buf,IntToHex(val,8),8);
739: end;
740:
741: { Writes to a 16-bit decimal integer field }
742: procedure PutShortIntField(buf : PChar; str : AnsiString);
743: begin
744: PutTextField(buf, str, 5);
745: end;
746:
747: { Writes to a 32-bit decimal integer field }
748: procedure PutLongIntField(buf : PChar; str : AnsiString);
749: begin
750: PutTextField(buf, str, 10);
751: end;
752:
753: { Writes to a hexadecimal integer field (of any length) }
754: procedure PutHexField(buf : PChar; val : Integer; maxlen : Integer);
755: begin
756: PutTextField(buf,IntToHex(val,maxlen),maxlen);
757: end;
758:
759: { Writes a user Edit box's contents to the buffer, if changed, resets Tag }
760: procedure PutUserText(Edit:Tedit; buf:PChar; maxlen:Integer);
761: begin
762: if Edit.Tag = 1 then { field modified, change record }
763: PutTextField(buf,Edit.Text,maxlen);
764: Edit.Tag:=0; { clear modified flag }
765: end;
766:
767: { Writes a flag Edit box's contents to the buffer, if changed }
768: { This function can be used for exemptions and restrictions too }
769: procedure PutUserFlags(Edit:Tedit; buf:PChar);
770: begin
771: if Edit.Tag = 1 then { field modified, change record }
772: PutFlagsField(buf,Edit.Text);
773: Edit.Tag:=0; { clear modified flag }
774: end;
775:
776: { Writes a 16-bit integer Edit box's contents to the buffer, if changed }
777: procedure PutUserShortInt(Edit:Tedit; buf:PChar);
778: begin
779: if Edit.Tag = 1 then { field modified, change record }
780: PutTextField(buf,Edit.Text,5);
781: Edit.Tag:=0; { clear modified flag }
782: end;
783:
784: { Writes a 32-bit integer Edit box's contents to the buffer, if changed }
785: procedure PutUserLongInt(Edit:Tedit; buf:PChar);
786: begin
787: if Edit.Tag = 1 then { field modified, change record }
788: PutTextField(buf,Edit.Text,10);
789: Edit.Tag:=0; { clear modified flag }
790: end;
791:
792: { Writes a date Edit box's contents to the buffer, if changed }
793: procedure PutUserDate(Edit:Tedit; buf:PChar);
794: begin
795: if Edit.Tag = 1 then { field modified, change record }
796: PutDateField(buf,Edit.Text);
797: Edit.Tag:=0; { clear modified flag }
798: end;
799:
800: function SetBit(set_it: bool; field: Cardinal; bit: Cardinal): Cardinal;
801: begin
802: if set_it then
803: Result:=field OR bit { set bit }
804: else
805: Result:=field AND NOT bit; { clear bit }
806: end;
807:
808: { Writes a complete user record. }
809: procedure TForm1.PutUserData(usernumber:Integer);
810: var Str: AnsiString;
811: f: TFileStream;
812: i: Integer;
813: buf: array[0..U_LEN] of Char;
814: begin
815: if AliasEdit.Tag = 1 then begin
816: { Set-up buffer for NAME.DAT record }
817: if user_misc AND DELETED <> 0 then
818: PutTextField(buf,'',LEN_ALIAS)
819: else
820: PutTextField(buf,AliasEdit.Text,LEN_ALIAS);
821: buf[LEN_ALIAS]:=CR;
822: buf[LEN_ALIAS+1]:=LF;
823:
824: { Open NAME.DAT write user name }
825: Str:=data_dir+'USER/NAME.DAT';
826: if FileExists(Str) then
827: f:=TFileStream.Create(Str,fmOpenWrite or fmShareExclusive)
828: else
829: f:=TFileStream.Create(Str,fmCreate or fmShareExclusive);
830: f.Seek((usernumber-1)*(LEN_ALIAS+2),soFromBeginning);
831: f.Write(buf,LEN_ALIAS+2);
832: f.Free;
833: end;
834:
835: { Initialize USER record buffer }
836: for i:=0 to U_LEN-1 do buf[i]:=ETX;
837:
838: { Open file and read current user record }
839: Str:=data_dir+'user/user.dat';
840: if FileExists(Str) then
841: f:=TFileStream.Create(Str,fmOpenReadWrite or fmShareExclusive)
842: else
843: f:=TFileStream.Create(Str,fmCreate or fmShareExclusive);
844:
845: f.Seek((usernumber-1)*U_LEN,soFromBeginning);
846: f.Read(buf,U_LEN);
847:
848: { Update changed fields }
849: PutUserText(AliasEdit,buf+U_ALIAS,LEN_ALIAS);
850: PutUserText(NameEdit,buf+U_NAME,LEN_NAME);
851: PutUserText(HandleEdit,buf+U_HANDLE,LEN_HANDLE);
852: PutUserText(ComputerEdit,buf+U_COMP,LEN_COMP);
853: PutUserText(NetMailEdit,buf+U_NETMAIL,LEN_NETMAIL);
854: PutUserText(AddressEdit,buf+U_ADDRESS,LEN_ADDRESS);
855: PutUserText(LocationEdit,buf+U_LOCATION,LEN_LOCATION);
856: PutUserText(NoteEdit,buf+U_NOTE,LEN_NOTE);
857: PutUserText(ZipCodeEdit,buf+U_ZIPCODE,LEN_ZIPCODE);
858: PutUserText(PasswordEdit,buf+U_PASS,LEN_PASS);
859: PutUserText(PhoneEdit,buf+U_PHONE,LEN_PHONE);
860: PutUserText(BirthDateEdit,buf+U_BIRTH,LEN_BIRTH);
861: PutUserText(ModemEdit,buf+U_MODEM,LEN_MODEM);
862: PutUserText(SexEdit,buf+U_SEX,1);
863: PutUserText(CommentEdit,buf+U_COMMENT,LEN_COMMENT);
864: { etc. }
865:
866: { Settings }
867: PutUserText(RowsEdit,buf+U_ROWS,2);
868: PutUserText(ShellEdit,buf+U_SHELL,8);
869: PutUserText(EditorEdit,buf+U_XEDIT,8);
870: PutUserText(ProtocolEdit,buf+U_PROT,1);
871: PutUserText(TempFileExtEdit,buf+U_TMPEXT,3);
872:
873: { Write MISC bit-field}
874: if (ExpertCheckBox.Tag = 1)
875: or (LogonCheckListBox.Tag = 1)
876: or (TerminalCheckListBox.Tag = 1)
877: or (MessageCheckListBox.Tag = 1)
878: or (FileCheckListBox.Tag = 1)
879: then begin
880: user_misc:=SetBit(ExpertCheckBox.Checked, user_misc, EXPERT);
881:
882: { TerminalCeckListBox }
883: user_misc:=SetBit(TerminalCheckListBox.Checked[0],user_misc,AUTOTERM);
884: user_misc:=SetBit(NOT TerminalCheckListBox.Checked[1],user_misc,NO_EXASCII);
885: user_misc:=SetBit(TerminalCheckListBox.Checked[2],user_misc,ANSI);
886: user_misc:=SetBit(TerminalCheckListBox.Checked[3],user_misc,UCOLOR);
887: user_misc:=SetBit(TerminalCheckListBox.Checked[4],user_misc,RIP);
888: user_misc:=SetBit(TerminalCheckListBox.Checked[5],user_misc,WIP);
889: user_misc:=SetBit(TerminalCheckListBox.Checked[6],user_misc,UPAUSE);
890: user_misc:=SetBit(NOT TerminalCheckListBox.Checked[7],user_misc,COLDKEYS);
891: user_misc:=SetBit(TerminalCheckListBox.Checked[8],user_misc,SPIN);
892:
893: { MessageCheckListBox }
894: user_misc:=SetBit(MessageCheckListBox.Checked[0],user_misc,NETMAIL);
895: user_misc:=SetBit(MessageCheckListBox.Checked[1],user_misc,CLRSCRN);
896:
897: { FileCheckListBox }
898: user_misc:=SetBit(FileCheckListBox.Checked[0],user_misc,ANFSCAN);
899: user_misc:=SetBit(FileCheckListBox.Checked[1],user_misc,EXTDESC);
900: user_misc:=SetBit(FileCheckListBox.Checked[2],user_misc,BATCHFLAG);
901: user_misc:=SetBit(FileCheckListBox.Checked[3],user_misc,AUTOHANG);
902:
903: { LogonCheckListBox }
904: user_misc:=SetBit(LogonCheckListBox.Checked[0],user_misc,ASK_NSCAN);
905: user_misc:=SetBit(LogonCheckListBox.Checked[1],user_misc,ASK_SSCAN);
906: user_misc:=SetBit(LogonCheckListBox.Checked[2],user_misc,CURSUB);
907: user_misc:=SetBit(LogonCheckListBox.Checked[3],user_misc,QUIET);
908: user_misc:=SetBit(LogonCheckListBox.Checked[4],user_misc,AUTOLOGON);
909:
910: PutHexField(buf+U_MISC, user_misc, 8);
911: end;
912:
913: if (ChatCheckListBox.Tag = 1) then begin
914: user_chat:=SetBit(ChatCheckListBox.Checked[0],user_chat,CHAT_ECHO);
915: user_chat:=SetBit(ChatCheckListBox.Checked[1],user_chat,CHAT_ACTION);
916: user_chat:=SetBit(NOT ChatCheckListBox.Checked[2],user_chat,CHAT_NOPAGE);
917: user_chat:=SetBit(NOT ChatCheckListBox.Checked[3],user_chat,CHAT_NOACT);
918: user_chat:=SetBit(ChatCheckListBox.Checked[4],user_chat,CHAT_SPLITP);
919:
920: PutHexField(buf+U_CHAT, user_chat, 8);
921: end;
922:
923: if (QWKCheckListBox.Tag =1) then begin
924: user_qwk:=SetBit(QWKCheckListBox.Checked[0],user_qwk,QWK_FILES);
925: user_qwk:=SetBit(QWKCheckListBox.Checked[1],user_qwk,QWK_EMAIL);
926: user_qwk:=SetBit(QWKCheckListBox.Checked[2],user_qwk,QWK_ALLMAIL);
927: user_qwk:=SetBit(QWKCheckListBox.Checked[3],user_qwk,QWK_DELMAIL);
928: user_qwk:=SetBit(QWKCheckListBox.Checked[4],user_qwk,QWK_BYSELF);
929: user_qwk:=SetBit(QWKCheckListBox.Checked[5],user_qwk,QWK_EXPCTLA);
930: user_qwk:=SetBit(NOT QWKCheckListBox.Checked[6],user_qwk,QWK_RETCTLA);
931: user_qwk:=SetBit(QWKCheckListBox.Checked[7],user_qwk,QWK_ATTACH);
932: user_qwk:=SetBit(QWKCheckListBox.Checked[8],user_qwk,QWK_NOINDEX);
933: user_qwk:=SetBit(QWKCheckListBox.Checked[9],user_qwk,QWK_TZ);
934: user_qwk:=SetBit(QWKCheckListBox.Checked[10],user_qwk,QWK_VIA);
935: user_qwk:=SetBit(NOT QWKCheckListBox.Checked[11],user_qwk,QWK_NOCTRL);
936:
937: PutHexField(buf+U_QWK, user_qwk, 8);
938: end;
939:
940: { Security }
941: PutUserText(LevelEdit,buf+U_LEVEL,2);
942: PutUserDate(ExpireEdit,buf+U_EXPIRE);
943: PutUserFlags(Flags1Edit,buf+U_FLAGS1);
944: PutUserFlags(Flags2Edit,buf+U_FLAGS2);
945: PutUserFlags(Flags3Edit,buf+U_FLAGS3);
946: PutUserFlags(Flags4Edit,buf+U_FLAGS4);
947: PutUserFlags(ExemptionsEdit,buf+U_EXEMPT);
948: PutUserFlags(RestrictionsEdit,buf+U_REST);
949: PutUserLongInt(CreditsEdit,buf+U_CDT);
950: PutUserLongInt(FreeCreditsEdit,buf+U_FREECDT);
951: PutUserLongInt(MinutesEdit,buf+U_MIN);
952: { etc. }
953:
954: { Stats }
955: PutUserDate(FirstOnEdit,buf+U_FIRSTON);
956: PutUserDate(LastOnEdit,buf+U_LASTON);
957: PutUserShortInt(LogonsEdit,buf+U_LOGONS);
958: PutUserShortInt(LogonsTodayEdit,buf+U_LTODAY);
959: PutUserShortInt(TimeOnEdit,buf+U_TIMEON);
960: PutUserShortInt(TimeOnTodayEdit,buf+U_TTODAY);
961: PutUserShortInt(LastCallTimeEdit,buf+U_TLAST);
962: PutUserShortInt(ExtraTimeEdit,buf+U_TEXTRA);
963: PutUserShortInt(PostsTotalEdit,buf+U_POSTS);
964: PutUserShortInt(PostsTodayEdit,buf+U_PTODAY);
965: PutUserShortInt(EmailTotalEdit,buf+U_EMAILS);
966: PutUserShortInt(EmailTodayEdit,buf+U_ETODAY);
967: PutUserShortInt(FeedbackEdit,buf+U_FBACKS);
968: PutUserShortInt(UploadedFilesEdit,buf+U_ULS);
969: PutUserLongInt(UploadedBytesEdit,buf+U_ULB);
970: PutUserShortInt(DownloadedFilesEdit,buf+U_DLS);
971: PutUserLongInt(DownloadedBytesEdit,buf+U_DLB);
972: PutHexField(buf+U_LEECH, StrToIntDef(LeechEdit.Text,0), 2);
973: { etc. }
974:
975: { Write user record and close file }
976: f.Seek((usernumber-1)*U_LEN,soFromBeginning);
977: f.Write(buf,U_LEN);
978: f.Free;
979:
980: { Extended Comemnt }
981: if Memo.Tag = 1 then begin
982: Str:=data_dir+Format('USER/%.4d.MSG',[usernumber]);
983: if Memo.Lines.Count<>0 then
984: Memo.Lines.SaveToFile(Str)
985: else
986: DeleteFile(Str);
987: end;
988:
989: SaveUser.Enabled:=false;
990: end;
991:
992: { ********* }
993: { MAIN FORM }
994: { ********* }
995:
996: { There's probably a better place to do this init stuff... constructor? }
997: procedure TForm1.FormShow(Sender: TObject);
998: begin
999:
1000: { Over-ride Locale settings here }
1001: DateSeparator:='/';
1002:
1003: if (ShortDateFormat = 'M/d/yy')
1004: or (ShortDateFormat = 'M/d/yyyy')
1005: or (ShortDateFormat = 'MM/dd/yy')
1006: or (ShortDateFormat = 'MM/dd/yyyy')
1007: then
1008: ShortDateFormat:='mm/dd/yy' { American }
1009: else
1010: ShortDateFormat:='dd/mm/yy'; { European }
1011:
1012: data_dir:=ParamStr(1);
1013: { if Length(data_dir)=0 then data_dir:='.\'; }
1014:
1015: users:=LastUser();
1016:
1017: if users = 0 then { Create user if none exist }
1018: users:=1;
1019:
1020: ScrollBar.Min:=1;
1021: ScrollBar.Max:=users;
1022: TotalStaticText.Caption:='of '+IntToStr(users);
1023: { *********************************** }
1024: { Set max lengths for edit boxes here }
1025: { *********************************** }
1026: { Personal }
1027: AliasEdit.MaxLength:=LEN_ALIAS;
1028: NameEdit.MaxLength:=LEN_NAME;
1029: PhoneEdit.MaxLength:=LEN_PHONE;
1030: HandleEdit.MaxLength:=LEN_HANDLE;
1031: ComputerEdit.MaxLength:=LEN_COMP;
1032: AddressEdit.MaxLength:=LEN_ADDRESS;
1033: LocationEdit.MaxLength:=LEN_LOCATION;
1034: ZipCodeEdit.MaxLength:=LEN_ZIPCODE;
1035: ModemEdit.MaxLength:=LEN_MODEM;
1036: CommentEdit.MaxLength:=LEN_COMMENT;
1037: { Security }
1038: PasswordEdit.MaxLength:=LEN_PASS;
1039: PhoneEdit.MaxLength:=LEN_PHONE;
1040: ModemEdit.MaxLength:=LEN_MODEM;
1041: SexEdit.MaxLength:=1;
1042: { Stats }
1043: { etc. }
1044:
1045: ScrollBar.Position:=StrToIntDef(ParamStr(2),1);
1046: GetUserData(ScrollBar.Position);
1047:
1048: PageControl.ActivePage:=PersonalTabSheet;
1049: end;
1050:
1051: { Change user }
1052: procedure TForm1.ScrollBarChange(Sender: TObject);
1053: begin
1054: if SaveUser.Enabled then SaveChanges();
1055: users:=LastUser(); { this could change dynamically }
1056: ScrollBar.Max:=users;
1057: TotalStaticText.Caption:='of '+IntToStr(users);
1058: GetUserData(ScrollBar.Position);
1059: end;
1060:
1061: { Better than on OnChange event, waits til users hits enter key }
1062: procedure TForm1.NumberEditKeyPress(Sender: TObject; var Key: Char);
1063: var val : Integer;
1064: begin
1065: if Key <> #13 then Exit;
1066: users:=lastuser;
1067: val:=StrToIntDef(NumberEdit.Text,0);
1068: if (val = 0) or (val > users) then
1069: NumberEdit.Text:=IntToStr(ScrollBar.Position)
1070: else begin
1071: ScrollBar.Position:=val;
1072: GetUserData(val);
1073: Key:=#0;
1074: end
1075: end;
1076:
1077: procedure TForm1.FileExitMenuItemClick(Sender: TObject);
1078: begin
1079: Close;
1080: end;
1081:
1082: { OnChange event for ALL User Data Edit boxes }
1083: procedure TForm1.EditChange(Sender: TObject);
1084: begin
1085: SaveUser.Enabled:=true;
1086: (Sender as TComponent).Tag:=1; { Mark as modified }
1087: end;
1088:
1089: { Create a New User record }
1090: procedure TForm1.SaveUserExecute(Sender: TObject);
1091: begin
1092: PutUserData(StrToIntDef(NumberEdit.Text,ScrollBar.Position));
1093: end;
1094:
1095: procedure TForm1.NewUserExecute(Sender: TObject);
1096: begin
1097: if SaveUser.Enabled then SaveChanges();
1098:
1099: { New users's number }
1100: users:=lastuser()+1;
1101:
1102: { Initialize fields to default values }
1103: AliasEdit.Text:='New User';
1104: AliasEdit.Tag := 1;
1105: LevelEdit.Text:='10';
1106: LevelEdit.Tag :=1;
1107: FirstOnEdit.Text:=DatetoStr(Date);
1108: FirstOnEdit.Tag :=1;
1109: LastOnEdit.Text:=DateToStr(Date);
1110: LastOnEdit.Tag :=1;
1111: TerminalCheckListBox.Checked[0] := true; // AUTOTERM
1112: TerminalCheckListBox.Checked[1] := true; // EXASCII
1113: TerminalCheckListBox.Checked[2] := true; // ANSI
1114: TerminalCheckListBox.Checked[3] := true; // COLOR
1115: TerminalCheckListBox.Checked[6] := true; // UPAUSE
1116: TerminalCheckListBox.Checked[7] := true; // HOTKEYS
1117: FileCheckListBox.Checked[2] := true; // BATCHFLAG
1118: LogonCheckListBox.Tag:=1;
1119:
1120: { Create the new record }
1121: PutUserData(users);
1122:
1123: { Set scroll bar and usernumber text }
1124: ScrollBar.Max:=users;
1125: ScrollBar.Position:=users;
1126: NumberEdit.Text:=IntToStr(users);
1127:
1128: end;
1129:
1130: procedure TForm1.DeleteUserExecute(Sender: TObject);
1131: begin
1132: user_misc:=user_misc xor DELETED;
1133: LogonCheckListBox.Tag:=1; { flag as modified }
1134: AliasEdit.Tag := 1;
1135: PutUserData(ScrollBar.Position);
1136: GetUserData(ScrollBar.Position);
1137: end;
1138:
1139: procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
1140: begin
1141: if SaveUser.Enabled then SaveChanges();
1142: end;
1143:
1144: procedure TForm1.DeactivateUserExecute(Sender: TObject);
1145: begin
1146: user_misc:=user_misc xor INACTIVE;
1147: LogonCheckListBox.Tag:=1; { flag as modified }
1148: PutUserData(ScrollBar.Position);
1149: GetUserData(ScrollBar.Position);
1150: end;
1151:
1152: procedure TForm1.FindButtonClick(Sender: TObject);
1153: var Str: AnsiString;
1154: SearchStr: AnsiString;
1155: f: TFileStream;
1156: usernumber: Integer;
1157: buf: array[0..U_LEN] of Char;
1158: begin
1159: SearchStr:=AnsiUpperCase(FindEdit.Text);
1160: usernumber:=0;
1161: { Open USER.DAT to search for string }
1162: Str:=data_dir+'user/user.dat';
1163: if not FileExists(Str) then Exit;
1164: f:=TFileStream.Create(Str,fmOpenRead or fmShareDenyNone);
1165: if Sender = FindNextButton then
1166: f.Seek((ScrollBar.Position)*(U_LEN),soFromBeginning);
1167: while (f.Position < f.Size) and (usernumber=0) do begin
1168: f.Read(buf,U_LEN);
1169: SetString(Str,buf,U_LEN);
1170: Str:=AnsiUpperCase(Str);
1171: if Pos(SearchStr,Str) <> 0 then
1172: usernumber:=f.Position div (U_LEN);
1173: end;
1174: f.Free;
1175: if usernumber <> 0 then begin
1176: ScrollBar.Position:=usernumber;
1177: end;
1178: end;
1179:
1180: procedure TForm1.FindEditKeyPress(Sender: TObject; var Key: Char);
1181: begin
1182: if Key = #13 then begin
1183: FindButtonClick(Sender);
1184: Key:=#0;
1185: end;
1186: end;
1187:
1188: end.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.