PageRenderTime 82ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/xp4o.pas

#
Pascal | 4422 lines | 3509 code | 231 blank | 682 comment | 475 complexity | 82439597a33e9b6db539ea369e8388a5 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. { $Id: xp4o.pas 6885 2004-11-29 14:19:31Z mkaemmerer $
  2. Copyright (C) 1991-2001 Peter Mandrella
  3. Copyright (C) 2000-2002 OpenXP team (www.openxp.de)
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. }
  16. { CrossPoint - Overlayroutinen, die von XP4 aufgerufen werden }
  17. {$I xpdefine.inc }
  18. {.$DEFINE sDebug}
  19. unit xp4o;
  20. interface
  21. uses
  22. keys, //taste
  23. classes,
  24. lister; //TLister
  25. var such_brett : string; { fuer Suche im gewaehlten Brett }
  26. FMsgReqnode : string; { F3 - Request - Nodenr. }
  27. const max_arc = 3; { maximale verschachtelte Archivdateien }
  28. suchlen = 160; { Maximallaenge der Suchbegriffe }
  29. histmax = 14; { Anzahl Eintraege in Suchbegriff-History}
  30. opthmax = 4; { Anzahl Eintraege in Optionen-History }
  31. suchmax = 20; { Anzahl AND/OR Teilstrings im Suchbegriff }
  32. var seeklen : array[0..suchmax-1] of byte;
  33. seekstart : array[0..suchmax-1] of byte;
  34. seeknot : array[0..suchmax-1] of boolean;
  35. suchand : boolean;
  36. suchanz : Integer;
  37. sst : string; // evtl. UpString von suchstring
  38. igcase : boolean;
  39. umlaut : boolean;
  40. Const
  41. historyFile = 'SEEK.TXT';
  42. libraryFile = 'SEEKLIB.TXT';
  43. optionsFile = 'OPTIONS.TXT';
  44. var Suchergebnis : boolean = false;
  45. procedure msg_info; { interpretierten Header anzeigen }
  46. procedure ShowHeader; { Original-Header anzeigen }
  47. function Suche(anztxt,suchfeld,autosuche:string):boolean;
  48. procedure betreffsuche;
  49. procedure SucheWiedervorlage;
  50. procedure BU_reorg(user,adrbuch,auto:boolean);
  51. procedure MsgReorgScan(_del,repair:boolean; var brk:boolean);
  52. procedure MsgReorg;
  53. procedure ImportBrettliste;
  54. procedure ImportUserliste;
  55. procedure ExportUB(user:boolean);
  56. procedure ModiEmpfDatum;
  57. procedure ModiBetreff;
  58. procedure ModiText;
  59. procedure ModiRot13;
  60. procedure ModiTyp;
  61. procedure ModiGelesen;
  62. procedure ModiHighlite;
  63. procedure zeige_unversandt;
  64. function ViewArchive(var fn:string; typ:shortint):shortint;
  65. procedure FileArcViewer(fn:string);
  66. procedure ShowArch(const fn:string);
  67. function a_getfilename(nr,nn:byte):string;
  68. procedure ArcSpecial(LSelf: TLister; var t:taste);
  69. procedure DupeKill(autodupekill:boolean);
  70. procedure CompleteMaintenance;
  71. procedure print_msg(initpr:boolean);
  72. function UserMarkSuche(allmode:boolean):boolean;
  73. procedure BrettInfo;
  74. procedure ntinfo;
  75. procedure do_bseek(fwd:boolean);
  76. procedure FidoMsgRequest(var nnode:string);
  77. function _killit(ask:boolean):boolean;
  78. function testbrettscope(var s:string):boolean;
  79. procedure seek_cutspace(var s:string);
  80. procedure seekmenu(var s:string);
  81. procedure OldSEEK_ed(LSelf: TLister; var t:taste); {Lister-Tastenabfrage fuer Seek-Menue}
  82. function Bool_BrettGruppe(var s:string):boolean;
  83. function Bool_Brettindex(var s:string):boolean;
  84. Procedure Brettmarksuche;
  85. implementation {-----------------------------------------------------}
  86. uses
  87. sysutils,
  88. {$IFDEF NCRT }
  89. xpcurses,
  90. {$ENDIF }
  91. {$IFDEF Kylix}
  92. xplinux,
  93. {$ENDIF}
  94. typeform,fileio,inout,
  95. maske,datadef,database,
  96. archive,maus2,winxp,printerx,resource,osdepend,
  97. xp0,xp1,xp1o,xp1o2,xp1help,xp1input,xp3,xp3o,xp3o2,xp3ex,xp4,xp4o2,xp9bp,
  98. xpkeys,xpnt,xpfido,xpmaus,xpheader, xpmakeheader,xpconst,
  99. xp_pgp,debug,viewer, MarkedList, regexpr, xpconfigedit,
  100. xprope,
  101. xpspam,
  102. xpglobal;
  103. type arcbuf = record
  104. arcer_typ : shortint;
  105. arcname : string;
  106. end;
  107. var arcbufp : byte = 0;
  108. suchopt : string = '*'; { Flag fuer erste Suche seit Programmstart }
  109. history : array[0..histmax] of String[Suchlen]=
  110. ('','','','','','','','','','','','','','','');
  111. history_changed : boolean = false;
  112. var reobuf : array[0..ablagen-1] of boolean;
  113. bufsiz : array[0..ablagen-1] of longint; { Groesse nach Reorg }
  114. abuf : array[1..max_arc+1] of arcbuf;
  115. exdir : string;
  116. arctyp_save : shortint;
  117. mid_bretter : byte;
  118. Mid_teilstring : boolean;
  119. function testbrettscope(var s:string):boolean;
  120. var i : integer;
  121. begin
  122. if (length(s)=1) and (lastkey<>keybs) then begin
  123. for i:=4 downto 0 do
  124. if upcase(FirstChar(s))=UpperCase(FirstChar(getres2(442,i))) then
  125. s:=getres2(442,i);
  126. freeres;
  127. if length(s)>1 then _keyboard(keyend);
  128. end;
  129. testbrettscope:=true;
  130. end;
  131. procedure seek_cutspace(var s:string);
  132. begin
  133. if s=' ' then s:='';
  134. end;
  135. function mid_suchoption(var s:string):boolean;
  136. begin
  137. if aktdispmode <> 11 then setfieldenable(mid_bretter,s='J');
  138. mid_suchoption:=true;
  139. end;
  140. procedure OldSEEK_ed(LSelf: TLister; var t:taste); {Lister-Tastenabfrage fuer Seek-Menue}
  141. begin
  142. if (UpperCase(t)='E') then begin
  143. EditFile(libraryFile,false,false,false,0,false);
  144. t:=keyesc;
  145. pushkey(keysf2);
  146. end;
  147. end;
  148. procedure seekmenu(var s:string);
  149. const height = 10;
  150. width = 70;
  151. var t : text;
  152. brk : boolean;
  153. x,y : Integer;
  154. List: TLister;
  155. begin
  156. assign(t,libraryFile);
  157. reset(t);
  158. s:='';
  159. if ioresult<>0 then exit;
  160. selbox(width+2,height+2,getres2(441,21),x,y,true);
  161. List := TLister.CreateWithOptions(x+1,x+width,y+1,y+height,0,'/NS/SB/DM/S/M/');
  162. ListboxCol(List);
  163. List.SetArrows(x+width+1,y+1,y+height,col.colselrahmen,col.colselrahmen,'ł');
  164. while not eof(t) do
  165. begin
  166. readln(t,s);
  167. List.AddLine(LeftStr(s,suchlen));
  168. end;
  169. List.OnKeyPressed := oldseek_ed;
  170. brk := List.Show;
  171. if List.SelCount =0 then
  172. begin
  173. s := List.GetSelection;
  174. if FirstChar(s)=' ' then brk:=true;
  175. end
  176. else if not brk then begin
  177. s:= List.FirstMarked;
  178. x:=0;
  179. repeat
  180. if (s<>#0) and (s<>'') and (s[1]<>' ')
  181. then inc(x);
  182. s:= List.NextMarked;
  183. until (s=#0) or (x=histmax);
  184. for y:=histmax downto x do history[y]:=history[y-x];
  185. s:= List.FirstMarked;
  186. y:=0;
  187. repeat
  188. if (s<>#0) and (s<>'') and (s[1]<>' ')
  189. then begin
  190. history[y]:=s;
  191. inc(y);
  192. end;
  193. s:= List.NextMarked;
  194. until (y>x) or (s=#0);
  195. s:=history[0];
  196. history_changed:=true;
  197. pushkey(keyctcr);
  198. end;
  199. List.Free;
  200. closebox;
  201. close(t);
  202. if brk then s:='';
  203. end;
  204. { Suchfeld: '' (Volltext), '*' (Umiversal), 'Betreff', 'Absender', 'MsgID' }
  205. type suchrec = record
  206. betr,user,txt : string;
  207. fidoempf,mid : string;
  208. nbetr,nuser : Boolean;
  209. nfidoempf : Boolean;
  210. or_betr : Boolean;
  211. or_user : Boolean;
  212. or_fidoempf : Boolean;
  213. vondat,bisdat : string;
  214. vonkb,biskb : longint;
  215. status : string;
  216. typ : string;
  217. end;
  218. var srec : ^suchrec = nil;
  219. opthist : array[0..opthmax] of String[8]=('','','','','');
  220. history0 : string='';
  221. history1 : string='';
  222. history2 : string='';
  223. function Suche(anztxt,suchfeld,autosuche:string):boolean;
  224. var x,y : Integer;
  225. brk : boolean;
  226. n,nf : longint;
  227. p : pointer;
  228. psize : Integer;
  229. spez : boolean;
  230. i : integer;
  231. brett : string;
  232. me,uu : boolean;
  233. hdp : Theader;
  234. hds : longint;
  235. bretter : string;
  236. t : text;
  237. suchstring : string;
  238. typc : char;
  239. statb : byte;
  240. _vondat,_bisdat : longint;
  241. minsize,maxsize : longint;
  242. regex : boolean; // regexpressions zulassen?
  243. bereich : shortint;
  244. _brett : string;
  245. mi,add : byte;
  246. bera : array[0..4] of string;
  247. stata : array[0..5] of string;
  248. typa : array[0..4] of string;
  249. RegExpr: TRegExpr;
  250. seek : string;
  251. found : boolean;
  252. markedback : TMarkedList;
  253. markanzback : integer;
  254. check4date : boolean;
  255. headersuche : byte;
  256. andmask,ormask : byte;
  257. holdmarked : boolean;
  258. label ende, restart;
  259. { Check_Seekmode:
  260. Wenn bei Normalsuche die Suchoptionen "ua&" fuer UND oder "o|" fuer ODER angegeben wurden,
  261. werden in den Arrays die Anfangs und End Offsets von bis zu 10 Teilsuchstrings gespeichert,
  262. und Suchanz auf die Anzahl der (durch Leerzeichen getrennten, bzw in Anfuehrungszeichen
  263. eingefassten) Teilsuchstrings gesetzt. Suchand ist "true" bei UND Verknuepfung und "false"
  264. bei ODER Verknuepfung. Wurden keine Verknuepfungsoptionen angegeben, wird eine OR
  265. Verknuepfung durchgefuehrt, mit einem einzigen "Teilsuchstring", der die Ganze Laenge
  266. des Suchstring abdeckt
  267. }
  268. procedure check_seekmode;
  269. var
  270. m,n,i : Integer;
  271. quotes : boolean;
  272. {$IFDEF sDebug} { Zum Debuggen der Suchstringerkennung}
  273. Procedure Show_Seekstrings;
  274. var n,x,y: byte;
  275. const width=75; height=20;
  276. begin
  277. selbox(width+2,height+2,'Suchstring-Check',x,y,true);
  278. openlist(x+1,x+width,y+1,y+height,0,'/NS/CR/');
  279. ListboxCol;
  280. listarrows(width+3,y+1,y+height,col.colselrahmen,col.colselrahmen,'ł');
  281. app_L('');
  282. app_L(' Benutzte Teilstrings: '+StrS(suchanz)+iifs(suchand,' AND',' OR')+
  283. ' Igcase='+iifs(igcase,'1','0')+' Umlaut='+iifs(umlaut,'1','0')+
  284. iifs(spez,' SPEZIAL',''));
  285. app_L('');
  286. app_l(' Suchstring: '+chr($af)+iifs(spez,srec^.txt,suchstring)+chr($ae));
  287. app_l(' sst: '+chr($af)+sst+chr($ae));
  288. app_l('');
  289. for n:=0 to iif(suchanz<10,10,suchanz-1) do
  290. begin
  291. app_l(' String'+rforms(strs(n),2)+': '+rforms(strs(seekstart[n]),3)+','+
  292. rforms(strs(seeklen[n]),3)+
  293. iifs(seeknot[n],' NOT ',' ')+chr($af)+
  294. left(mid(sst,seekstart[n]),seeklen[n])+chr($ae));
  295. end;
  296. app_l('');
  297. app_l(' Length(sst)='+strs(length(sst))+' i='+(strs(i)));
  298. if spez then with srec^do
  299. begin
  300. app_l('');
  301. app_l(dup(30,'-'));
  302. app_l(' AND-Maske: '+bin(andmask,3)+' OR-Maske: '+bin(ormask,3));
  303. app_l('');
  304. app_l(' User: '+iifs(or_user,' OR',' ')
  305. +iifs(nuser,' NOT ',' ')+chr($af)+user+chr($ae));
  306. app_l(' Betr: '+iifs(or_betr,' OR',' ')
  307. +iifs(nbetr,' NOT ',' ')+chr($af)+betr+chr($ae));
  308. app_l(' Fidoempf: '+iifs(or_fidoempf,' OR',' ')
  309. +iifs(nfidoempf,' NOT ',' ')+chr($af)+fidoempf+chr($ae));
  310. end;
  311. list(brk);
  312. closelist;
  313. closebox;
  314. end;
  315. {$ENDIF}
  316. begin
  317. {$IFDEF sDebug}
  318. for n:=0 to suchmax-1 do
  319. begin
  320. seekstart[n]:=0;
  321. seeklen[n]:=0;
  322. seeknot[n]:=false;
  323. end;
  324. {$ENDIF}
  325. suchand:=cpos('o', LowerCase(suchopt))=0; { OR }
  326. if not suchand or (cpos('a', LowerCase(suchopt))>0) { oder AND ?}
  327. and not (trim(sst)='') then { und nicht Leertext (Suche-Spezial) }
  328. begin
  329. n:=0;
  330. seek:=trim(sst); { Leerzeichen vorne und hinten, }
  331. i:=length(seek);
  332. while (i <> 0) and (seek[i]='"') do dec(i); { Und Ausrufezeichen hinten abschneiden }
  333. truncstr(seek,i);
  334. if seek<>'' then begin
  335. i:=1;
  336. sst:=seek+'"'; quotes:=false;
  337. while (i<length(sst)) and (n<suchmax) do
  338. begin
  339. while sst[i]=' ' do inc(i); { Leerzeichen ueberspringen }
  340. if not quotes then
  341. begin
  342. seeknot[n]:=sst[i]='~'; { NOT Flag setzen }
  343. while ((sst[i]='~') or (sst[i]=' '))
  344. do inc(i); { und evtl weitere ^ ueberspringen }
  345. end;
  346. quotes:=sst[i]='"'; { Evtl. "- Modus aktivieren....}
  347. while sst[i]='"' do inc(i); { weitere " ueberspringen }
  348. seekstart[n]:=i;
  349. while (i<length(sst)) and not { Weiterzaehlen bis Stringende }
  350. ((not quotes and (sst[i]=' ')) or { oder Space das nicht in " ist }
  351. (sst[i]='"')) do inc(i); { oder das naechste " gefunden wird }
  352. seeklen[n]:=i-seekstart[n];
  353. quotes:=not quotes and (sst[i]='"'); { -"- Modus umschalten }
  354. if (not quotes) then inc(i);
  355. inc(n);
  356. end;
  357. if seeklen[n-1]=0 then dec(n); { Falls String mit > "< Endete... }
  358. suchanz:=n;
  359. end;
  360. if suchanz=1 then suchand:=true;
  361. m:=0;
  362. for n:=0 to suchanz-1 do { Teilstrings Umsortieren: NOT zuerst }
  363. begin
  364. if (seeknot[n]=true) and (seeklen[n]<>0) then
  365. begin
  366. i:=seekstart[m]; seekstart[m]:=seekstart[n]; seekstart[n]:=i;
  367. i:=seeklen[m]; seeklen[m]:=seeklen[n]; seeklen[n]:=i;
  368. quotes:=seeknot[m]; seeknot[m]:=seeknot[n]; seeknot[n]:=quotes;
  369. inc(m);
  370. end;
  371. end;
  372. end
  373. else begin
  374. suchand:=true;
  375. suchanz:=1;
  376. seekstart[0]:=1;
  377. seeklen[0]:=length(sst);
  378. seeknot[0]:=false;
  379. end;
  380. {$IFDEF sDebug}
  381. if cpos('c',lstr(suchopt))>0 then show_seekstrings; { "Writeln ist der beste Debugger..." }
  382. {$ENDIF}
  383. end;
  384. function InText(const key:string):boolean;
  385. var size : longint;
  386. ofs : longint;
  387. wsize: Integer;
  388. s: String;
  389. begin
  390. dbReadN(mbase,mb_msgsize,size);
  391. if size=0 then begin { leerer Datensatz - vermutlich durch RuntimeError }
  392. dbDelete(mbase);
  393. InText:=false;
  394. end
  395. else begin
  396. wsize:=min(size,psize);
  397. ofs:=dbReadIntN(mbase, mb_msgsize)-dbReadIntN(mbase,mb_groesse);
  398. if headersuche=1 then begin { nur Header durchsuchen }
  399. wsize:=ofs;
  400. ofs:=0;
  401. end
  402. else if headersuche=2 then ofs:=0; { Header und Text durchsuchen }
  403. if (ofs>=0) and (ofs<wsize+1+length(key)) then
  404. begin
  405. dec(wsize,ofs);
  406. XmemRead(ofs,wsize,p^);
  407. if RegEx then
  408. begin
  409. RegExpr.Expression := key;
  410. SetString(s, PChar(p), WSize);
  411. InText := RegExpr.Exec(s);
  412. end else
  413. begin
  414. TxtSeekKey := Key;
  415. Intext:=TxtSeek(p,wsize,igcase,umlaut);
  416. end;
  417. end else
  418. Intext:=false;
  419. end;
  420. end;
  421. function DateFit:boolean;
  422. var d : longint;
  423. begin
  424. dbReadN(mbase,mb_origdatum,d);
  425. DateFit:=not smdl(d,_vondat) and not smdl(_bisdat,d);
  426. end;
  427. function Sizefit:boolean;
  428. var s : longint;
  429. begin
  430. dbReadN(mbase,mb_groesse,s);
  431. sizefit:=(s>=minsize) and (s<=maxsize);
  432. end;
  433. function TypeFit:boolean;
  434. var t : char;
  435. nt : longint;
  436. flags : longint;
  437. begin
  438. if typc=' ' then typefit:=true
  439. else begin
  440. dbReadN(mbase,mb_typ,t);
  441. dbReadN(mbase,mb_netztyp,nt);
  442. dbReadN(mbase,mb_flags,flags);
  443. TypeFit:=((typc='F') and (nt and $200<>0)) or
  444. ((typc='M') and (flags and 4<>0)) or
  445. (t=typc);
  446. end;
  447. end;
  448. function StatOk:boolean;
  449. var flags : byte;
  450. begin
  451. dbReadN(mbase,mb_halteflags,flags);
  452. case statb of
  453. 1,2 : StatOK:=(statb=flags);
  454. 3 : StatOK:=(flags=1) or (flags=2);
  455. 4 : StatOK:=(dbReadInt(mbase,'gelesen')=0);
  456. 5 : StatOK:=(dbReadInt(mbase,'gelesen')<>0);
  457. else
  458. {0 : }StatOk:=true;
  459. end;
  460. end;
  461. { Leerzeichen Links und rechts loschen, Tilden links ebenfalls }
  462. { boolean setzen, wenn Tilde gefunden wurde }
  463. procedure Scantilde(var s:String; var suchnot:boolean);
  464. begin
  465. trim(s);
  466. if s='' then
  467. suchnot:=false
  468. else
  469. begin
  470. suchnot:=s[1]='~';
  471. i:=1;
  472. while ((s[i]='~') or (s[i]=' ')) do inc(i);
  473. s:=mid(s,i);
  474. end;
  475. end;
  476. {--Einzelne Nachricht mit Sucheingaben vergleichen--}
  477. procedure TestMsg;
  478. var betr2 : string;
  479. user2 : string;
  480. realn : string;
  481. such : string;
  482. j : byte;
  483. d : Longint;
  484. b : byte;
  485. found_not : boolean;
  486. foundmask : byte;
  487. label msg_ok;
  488. { Volltextcheck:
  489. Seekstart und Seeklen sind Zeiger auf Anfang und Ende der Teilsuchstrings
  490. innerhalb des Gesamtsuchstrings SST. Suchand ist "true" bei UND-Suche,
  491. und "false" bei ODER-Suche Der Textinhalt wird mit den Teilsuchstrings verglichen,
  492. solange Suchand=1 (UND) und Found=0, bzw bis Suchand=0 (OR) und Found=1,
  493. wurde ein Teilsuchstring gefunden, obwol SeekNOT fuer ihn definiert ist,
  494. wird die Suche beendet und Found nachtraeglich auf 0 gesetzt (Suche gescheitert).
  495. NOT-Suchstrings werden dabei aus der UND-Verknuepfung ausgeklammert.
  496. }
  497. procedure Volltextcheck;
  498. begin
  499. j:=0;
  500. repeat
  501. seek:=LeftStr(mid(sst,seekstart[j]),seeklen[j]);
  502. found:=Intext(seek);
  503. found_not:=found and seeknot[j];
  504. if suchand and not found and seeknot[j] then found:=true;
  505. inc(j);
  506. until (j=suchanz) or (suchand xor found) or found_not;
  507. if found_not then found:=false;
  508. end;
  509. begin
  510. inc(n);
  511. if (n mod 30)=0 then
  512. begin
  513. moff;
  514. FWrt(x+9, WhereY, Format('%7d', [n]));
  515. FWrt(x+26, WhereY, Format('%5d', [nf]));
  516. mon;
  517. end;
  518. {--Spezialsuche--}
  519. if spez then with srec^ do
  520. begin
  521. if DateFit and SizeFit and TypeFit and StatOk then begin
  522. Betr2 := dbReadNStr(mbase,mb_betreff);
  523. if (betr<>'') and (length(betr2)=40) then begin
  524. ReadHeader(hdp,hds,false);
  525. if length(hdp.betreff)>40 then
  526. betr2:=hdp.betreff;
  527. end;
  528. user2 := dbReadNStr(mbase,mb_absender);
  529. if not ntEditBrettEmpf(mbnetztyp) then begin { <> Fido, QWK }
  530. realn:= dbReadNStr(mbase,mb_name);
  531. end
  532. else
  533. realn:=#0;
  534. if fidoempf<>'' then
  535. if not ntBrettEmpf(mbnetztyp) then
  536. hdp.fido_to:=''
  537. else begin
  538. ReadHeader(hdp,hds,false);
  539. end;
  540. if umlaut then begin { Umlaute anpassen}
  541. UkonvStr(betr2,Length(betr2));
  542. UkonvStr(user2,Length(user2));
  543. UkonvStr(realn,Length(realn));
  544. UkonvStr(hdp.fido_to,Length(hdp.fido_to));
  545. end;
  546. if igcase then begin { Ignore Case}
  547. UpString(betr2);
  548. UpString(user2);
  549. UpString(realn);
  550. UpString(hdp.fido_to);
  551. end;
  552. if andmask<>0 then begin
  553. foundmask:=0;
  554. if ((betr='') or (pos(betr,betr2)>0) xor nbetr)
  555. then inc(foundmask,2);
  556. if ((user='') or ((pos(user,user2)>0) or (pos(user,realn)>0)) xor nuser)
  557. then inc(foundmask,4);
  558. if ((fidoempf='') or (pos(fidoempf,hdp.fido_to)>0) xor nfidoempf)
  559. then inc(foundmask);
  560. if foundmask and ormask <> 0 then goto msg_ok;
  561. if (foundmask and andmask) <> (andmask and not ormask) then exit;
  562. end;
  563. if txt<>'' then begin
  564. volltextcheck;
  565. if not found then exit;
  566. end;
  567. msg_ok: MsgAddmark;
  568. inc(nf);
  569. end
  570. end
  571. else begin
  572. if check4date and (readmode >0) then
  573. begin { Suchen im akt. Lesemodus }
  574. if readmode=1 then begin
  575. dbReadN(mbase,mb_gelesen,b);
  576. if b>0 then exit;
  577. end
  578. else if aktdispmode <> 10 then begin
  579. dbReadN(mbase,mb_empfdatum,d);
  580. if smdl(d,readdate) then exit;
  581. end;
  582. end;
  583. { Headereintrag-Suche }
  584. if suchfeld<>'' then
  585. begin
  586. such := dbReadStr(mbase,suchfeld);
  587. if (suchfeld='Absender') and not ntEditBrettEmpf(mbnetztyp)
  588. then begin
  589. seek := dbReadNStr(mbase,mb_name); { Bei Usersuche auch Realname ansehen... }
  590. such:=such+seek;
  591. end;
  592. if stricmp(suchfeld,'betreff') and (length(such)=40)
  593. then begin
  594. ReadHeader(hdp,hds,false);
  595. if length(hdp.betreff)>40 then
  596. such:=hdp.betreff;
  597. end;
  598. if suchfeld='MsgID' then begin
  599. ReadHeader(hdp,hds,false);
  600. such:=hdp.msgid;
  601. end;
  602. if umlaut then UkonvStr(such,Length(such));
  603. j:=0;
  604. repeat
  605. seek:=LeftStr(mid(sst,seekstart[j]),seeklen[j]); { Erklaerung siehe Volltextcheck }
  606. found:=((igcase and (pos(seek,UpperCase(such))>0)) or
  607. (not igcase and (pos(seek,such)>0)));
  608. found_not:=found and seeknot[j];
  609. if suchand and not found and seeknot[j] then found:=true;
  610. inc(j);
  611. until (j=suchanz) or (suchand xor found) or found_not;
  612. if found_not then found:=false;
  613. if Found then Begin
  614. MsgAddmark;
  615. inc(nf);
  616. end;
  617. end
  618. else begin { Volltextsuche }
  619. volltextcheck;
  620. if found then Begin
  621. MsgAddmark;
  622. inc(nf);
  623. end;
  624. end;
  625. end;
  626. end;
  627. procedure TestBrett(const _brett:string);
  628. begin
  629. if check4date {and (aktdispmode<=10) } and (readmode>0)
  630. then if Readmode>1 then dbSeek(mbase,miBrett,_brett+dbLongStr(readdate))
  631. else dbSeek(mbase,miGelesen,_brett+#0)
  632. else dbSeek(mbase,miBrett,_brett);
  633. while not dbEof(mbase) and (dbReadStrN(mbase,mb_brett)=_brett) and not brk do
  634. begin
  635. TestMsg;
  636. dbNext(mbase);
  637. testbrk(brk);
  638. end;
  639. end;
  640. function userform(const s:string):string;
  641. var p : Integer;
  642. begin
  643. p:=cpos('@',s);
  644. if p=0 then userform:=s
  645. else userform:=trim(LeftStr(s,p-1))+'@'+trim(mid(s,p+1));
  646. end;
  647. procedure InitHistory; { Such-History beim Programmstart aus Datei laden }
  648. var i : byte;
  649. var t : text;
  650. begin
  651. assign(t,historyFile);
  652. reset(t);
  653. if ioresult<>0 then exit;
  654. for i:=0 to histmax do readln(t,history[i]);
  655. close(t);
  656. assign(t,optionsFile);
  657. reset(t);
  658. if ioresult<>0 then exit;
  659. for i:=0 to opthmax do readln(t,opthist[i]);
  660. close(t);
  661. end;
  662. procedure CheckHistory; { Such-History Aktualisieren und in Datei speichern }
  663. var i,h: byte;
  664. var t : text;
  665. begin
  666. if (suchstring='') or history_changed then exit;
  667. h:=histmax;
  668. for i:=0 to histmax do if history[i]=suchstring then h:=i;
  669. for i:=h downto 1 do history[i]:=history[i-1];
  670. history[0]:=suchstring;
  671. h:=opthmax;
  672. for i:=0 to opthmax do if opthist[i]=suchopt then h:=i;
  673. for i:=h downto 1 do opthist[i]:=opthist[i-1];
  674. opthist[0]:=suchopt;
  675. assign(t,historyFile);
  676. rewrite(t);
  677. for i:=0 to histmax do writeln(t,history[i]);
  678. close(t);
  679. assign(t,optionsFile);
  680. rewrite(t);
  681. for i:=0 to opthmax do writeln(t,opthist[i]);
  682. close(t);
  683. end;
  684. // adds new message id to boxname.mid
  685. procedure AddMsgId;
  686. var
  687. Boxname, Filename: String;
  688. IDList: TStringList;
  689. begin
  690. if ReadJN('Soll die Message-ID online gesucht werden?', true) then
  691. begin
  692. BoxName := UniSel(usBoxes, false, DefaultBox);
  693. if BoxName <> '' then
  694. begin
  695. ReadboxPar(0, Boxname);
  696. Filename := OwnPath + BoxPar.ClientPath + GetServerFilename(Boxname, extMid);
  697. IDLIst := TStringList.Create;
  698. try
  699. with IDList do
  700. begin
  701. if FileExists(Filename) then
  702. begin
  703. LoadFromFile(Filename);
  704. Sort;
  705. end;
  706. Sorted := true;
  707. Duplicates := dupIgnore;
  708. Add(Suchstring);
  709. SaveToFile(Filename);
  710. end;
  711. finally
  712. IDList.Free;
  713. end;
  714. end;
  715. end;
  716. end;
  717. {--# Suche #--}
  718. begin
  719. RegExpr := TRegExpr.Create;
  720. for i:=0 to 4 do bera[i]:=getres2(442,i);
  721. for i:=0 to 5 do stata[i]:=getres2(442,10+i);
  722. for i:=0 to 4 do typa[i]:=getres2(442,20+i);
  723. if FirstChar(suchopt)='*' then
  724. begin { Erste Suche seit Programmstart? }
  725. suchopt:='au';
  726. InitHistory;
  727. end;
  728. if srec=nil then begin
  729. new(srec);
  730. fillchar(srec^,sizeof(srec^),0);
  731. with srec^ do begin
  732. vondat:='01.01.80'; bisdat:='31.12.69';
  733. vonkb:=0; biskb:=maxlongint div 2048;
  734. typ:=typa[0]; status:=stata[0];
  735. end;
  736. end;
  737. spez:=(suchfeld='*');
  738. case aktdispmode of
  739. -1,0 : bretter:=bera[iif(bmarkanz>0,3,1)];
  740. 1..4 : bretter:=bera[iif(bmarkanz>0,3,2)];
  741. 10 : bretter:=bera[4];
  742. else bretter:=bera[0];
  743. end;
  744. i:=0;
  745. while (i<=4) and (bretter<>bera[i]) do inc(i);
  746. if i>4 then bretter:=bera[0];
  747. {-- Eingabemaske Normalsuche --}
  748. MaskShiftF2(seekmenu,534);
  749. restart:
  750. MaskSeekMenu:=iif(spez,4,1);
  751. if not spez then begin
  752. add:=0;
  753. (* if autosuche='' then begin *)
  754. dialog(51,7,getreps2(441,1,anztxt),x,y); { '%s-Suche' }
  755. if autosuche<>'' then suchstring:=autosuche
  756. else if suchfeld='Betreff' then suchstring:=srec^.betr
  757. else if suchfeld='Absender' then suchstring:=srec^.user
  758. else if suchfeld='MsgID' then suchstring:=srec^.mid { MID Suche aus Menue }
  759. else suchstring:=srec^.txt;
  760. maddstring(3,2,getres2(441,2),suchstring,32,SuchLen,range(' ',#255));
  761. mnotrim;
  762. if history[0] <> '' then { Bei Leerer Suchhistory kein Auswahlpfeil... }
  763. for i:=0 to histmax do mappsel(false,history[i]);
  764. mset3proc(seek_cutspace);
  765. mhnr(530); { 'Suchbegriff ' }
  766. maddstring(3,4,getres2(441,3),suchopt,8,8,''); { 'Optionen ' }
  767. if opthist[0] <>'' then
  768. for i:=0 to opthmax do mappsel(false,opthist[i]);
  769. maddstring(31,4,getres2(441,4),bretter,8,8,''); { 'Bretter ' }
  770. mid_bretter:=fieldpos;
  771. if (aktdispmode=11) or (suchfeld='#') then
  772. MDisable
  773. else begin
  774. for i:=0 to 4 do
  775. mappsel(true,bera[i]); { Alle / Netz / User / markiert / gew„hlt }
  776. mset1func(testbrettscope);
  777. end;
  778. if autosuche<>'' then _keyboard(keypgdn);
  779. if suchfeld='MsgID' then
  780. Begin
  781. Mid_teilstring:=false;
  782. Maddbool(3,6,getres2(442,25),Mid_teilstring);
  783. MSet1func(Mid_suchoption);
  784. if mid_suchoption(suchfeld) then;
  785. end;
  786. readmask(brk);
  787. MaskSeekMenu:=0;
  788. closemask;
  789. CheckHistory;
  790. if suchfeld='Betreff' then begin
  791. i:=ReCount(suchstring); // Re's wegschneiden
  792. srec^.betr:=suchstring
  793. end
  794. else if suchfeld='Absender' then begin
  795. suchstring:=userform(suchstring);
  796. srec^.user:=suchstring;
  797. end
  798. else if suchfeld='MsgID' then srec^.mid:=suchstring {JG: 22.01.00}
  799. else srec^.txt:=suchstring;
  800. if suchstring='' then goto ende;
  801. dec(x); inc(y);
  802. end
  803. {--Eingabemaske Spezialsuche--}
  804. else with srec^ do begin
  805. { Spezial: NOT-Flags wieder an Suchstrings setzen }
  806. if nbetr and (betr[1]<>'~') then betr:='~'+betr;
  807. if nuser and (user[1]<>'~') then user:='~'+user;
  808. if nfidoempf and (fidoempf[1]<>'~') then fidoempf:='~'+fidoempf;
  809. add:=iif(ntBrettEmpfUsed,1,0);
  810. dialog(53,12+add,getreps2(441,1,anztxt),x,y);
  811. i:=4;
  812. while (i>0) and (UpperCase(typ)<>UpperCase(typa[i])) do dec(i);
  813. typ:=typa[i];
  814. i:=5;
  815. while (i>0) and (UpperCase(status)<>UpperCase(stata[i])) do dec(i);
  816. status:=stata[i];
  817. maddstring(3,2,getres2(441,6),user,30,SuchLen,''); mhnr(630); { 'Absender ' }
  818. maddstring(3,3,getres2(441,7),betr,30,SuchLen,''); { 'Betreff ' }
  819. mnotrim;
  820. mset3proc(seek_cutspace);
  821. if ntBrettEmpfUsed then
  822. maddstring(3,4,getres2(441,9),fidoempf,30,SuchLen,''); { 'Fido-Empf.' }
  823. maddstring(3,4+add,getres2(441,8),txt,35,SuchLen,''); { 'Text ' }
  824. if history[0] <> '' then { Bei leerer Suchhistory kein Auswahlpfeil... }
  825. for i:=0 to histmax do mappsel(false,history[i]);
  826. mnotrim;
  827. mset3proc(seek_cutspace);
  828. maddtext(48,1,'OR',0);
  829. maddbool(46,2,'',or_user);mhnr(640);
  830. maddbool(46,3,'',or_betr);
  831. if ntBrettEmpfUsed then maddbool(46,4,'',or_fidoempf);
  832. madddate(3,6+add,getres2(441,10),vondat,false,false); mhnr(634); { 'von Datum ' }
  833. madddate(3,7+add,getres2(441,11),bisdat,false,false); mhnr(634); { 'bis Datum ' }
  834. maddint(30,6+add,getres2(441,19),vonkb,6,5,0,99999); mhnr(635); { 'von ' }
  835. maddtext(45,6+add,getres(14),0); { 'KBytes' }
  836. biskb:=min(biskb,99999);
  837. maddint(30,7+add,getres2(441,20),biskb,6,5,0,99999); mhnr(635); { 'bis ' }
  838. maddtext(45,7+add,getres(14),0); { 'KBytes' }
  839. maddstring(3,9+add,getres2(441,12),typ,8,9,''); { 'Typ ' }
  840. for i:=0 to 4 do
  841. mappsel(true,typa[i]);
  842. maddstring(3,10+add,getres2(441,13),status,8,8,''); { 'Status ' }
  843. for i:=0 to 5 do
  844. mappsel(true,stata[i]);
  845. maddstring(30,9+add,getres2(441,14),bretter,8,8,''); { 'Bretter ' }
  846. if aktdispmode=11 then
  847. MDisable
  848. else begin
  849. for i:=0 to 4 do
  850. mappsel(true,bera[i]);
  851. mset1func(testbrettscope);
  852. end;
  853. maddstring(30,10+add,getres2(441,15),suchopt,8,8,''); { 'Optionen ' }
  854. if opthist[0] <>'' then
  855. for i:=0 to opthmax do mappsel(false,opthist[i]);
  856. readmask(brk);
  857. MaskSeekMenu:=0;
  858. closemask;
  859. dec(x);
  860. suchstring:=txt;
  861. CheckHistory;
  862. end;
  863. {--Eingaben auswerten--}
  864. if not brk then with srec^ do begin
  865. if spez then begin
  866. andmask:=0; ormask:=0;
  867. if user='' then or_user:=false else andmask:=4;
  868. if betr='' then or_betr:=false else inc(andmask,2);
  869. if fidoempf='' then or_fidoempf:=false else inc(andmask);
  870. if or_user then ormask:=4;
  871. if or_betr then inc(ormask,2);
  872. if or_fidoempf then inc(ormask);
  873. if txt='' then
  874. asm
  875. mov al,ormask { verhindern, dass alle Suchbegriffe auf OR stehen }
  876. or al,al
  877. je @2
  878. cmp al,andmask
  879. jne @2
  880. mov cl,0
  881. @1: inc cx
  882. shr al,1
  883. jnc @1
  884. shl al,cl
  885. mov ormask,al
  886. @2:
  887. end;
  888. end;
  889. sst:=suchstring;
  890. igcase:=multipos('iu', LowerCase(suchopt));
  891. umlaut:=multipos('„”u', LowerCase(suchopt)); { Umlautschalter}
  892. regex := pos('r', LowerCase(suchopt)) > 0 ;
  893. if umlaut and not igcase then
  894. begin
  895. suchopt:=suchopt+'i';
  896. igcase:=true;
  897. end;
  898. check4date:=cpos('l', LowerCase(suchopt))>0; { Suchen ab aktuellem Lesedatum }
  899. HoldMarked:=cpos('m', LowerCase(suchopt))>0; { Alte Markierungen beibehalten }
  900. i:=cpos('s', LowerCase(suchopt)); { Such-History loeschen }
  901. if i>0 then
  902. begin
  903. delete(suchopt,i,1);
  904. for i:=1 to histmax do history[i]:='';
  905. CheckHistory;
  906. closebox;
  907. goto restart;
  908. end;
  909. i:=cpos('k', LowerCase(suchopt)); { Such-History loeschen }
  910. if i>0 then
  911. begin
  912. delete(suchopt,i,1);
  913. assign(t,libraryFile);
  914. append(t);
  915. if ioresult<>0 then rewrite(t);
  916. if trim(suchstring)<>'' then writeln(t,suchstring);
  917. close(t);
  918. closebox;
  919. goto restart;
  920. end;
  921. headersuche:=0; { Volltextsuche }
  922. if cpos('h', LowerCase(Suchopt))>0 then headersuche:=1; { Headersuche }
  923. if cpos('g', LowerCase(suchopt))>0 then headersuche:=2; { Volltext+Headersuche }
  924. bereich:=0;
  925. for i:=1 to 4 do
  926. if UpperCase(bretter)=UpperCase(bera[i]) then bereich:=i;
  927. statb:=0;
  928. for i:=1 to 5 do
  929. if UpperCase(status)=UpperCase(stata[i]) then statb:=i;
  930. me:=true;
  931. attrtxt(col.coldialog);
  932. if spez then with srec^ do begin
  933. sst:=txt;
  934. user:=userform(user);
  935. if umlaut then begin { Umlaute konvertieren }
  936. UkonvStr(betr, Length(betr)); UkonvStr(user, Length(user));
  937. { UkonvStr(txt,high(txt));} UkonvStr(fidoempf,Length(fidoempf));
  938. end;
  939. if igcase then begin
  940. UpString(betr); UpString(user); {UpString(txt);} UpString(fidoempf);
  941. end;
  942. scantilde(betr,nbetr); scantilde(user,nuser);
  943. scantilde(fidoempf,nfidoempf);
  944. if UpperCase(typ)=UpperCase(typa[1]) then typc:='T'
  945. else if UpperCase(typ)=UpperCase(typa[2]) then typc:='B'
  946. else if UpperCase(typ)=UpperCase(typa[3]) then typc:='F'
  947. else if UpperCase(typ)=UpperCase(typa[4]) then typc:='M'
  948. else typc:=' ';
  949. _vondat:=ixdat(copy(vondat,7,2)+copy(vondat,4,2)+copy(vondat,1,2)+'0000');
  950. _bisdat:=ixdat(copy(bisdat,7,2)+copy(bisdat,4,2)+copy(bisdat,1,2)+'2359');
  951. if biskb=99999 then biskb:=maxlongint div 2048;
  952. minsize:=vonkb*1024;
  953. maxsize:=biskb*1024+1023;
  954. end;
  955. { else begin}
  956. if umlaut then UkonvStr(sst, Length(sst)); { 15.02.00}
  957. if igcase then UpString(sst);
  958. { end;}
  959. {--Start der Suche--}
  960. markanzback:= Marked.Count;
  961. if suchfeld='#' then begin {Lister-Dummysuche}
  962. check_seekmode;
  963. CloseBox;
  964. suche:=false;
  965. exit;
  966. end;
  967. if (suchfeld='MsgID') and NOT MID_teilstring then begin {-- Suche: Message-ID --}
  968. if not brk then begin
  969. if not holdmarked then Marked.Clear;
  970. check_seekmode;
  971. for i:=0 to suchanz-1 do
  972. begin
  973. seek:=copy(suchstring,seekstart[i],seeklen[i]);
  974. n:=GetBezug(seek);
  975. if n<>0 then begin
  976. dbGo(mbase,n);
  977. MsgAddmark;
  978. end;
  979. end;
  980. end;
  981. end
  982. { Anzeige fuer alle anderen Suchvarianten }
  983. else begin
  984. {if spez then sst:=txt; } { Bei Spezialsuche nur im Volltext... }
  985. if brk then goto ende;
  986. if history_changed then begin
  987. history_changed:=false;
  988. closebox;
  989. goto restart;
  990. end;
  991. check_seekmode; { Vorbereiten fuer verknuepfte Suche}
  992. if brk then begin
  993. closebox;
  994. goto restart;
  995. end;
  996. mwrt(x+3,y+iif(spez,11+add,4),getres2(441,16)); { 'Suche: passend:' }
  997. if (aktdispmode<>11) and not holdmarked then Marked.Clear;
  998. n:=0; nf:=0;
  999. hdp := THeader.Create;
  1000. attrtxt(col.coldiahigh);
  1001. psize:=65536;
  1002. getmem(p,psize);
  1003. brk:=false;
  1004. if aktdispmode=11 then
  1005. begin {-- Suche markiert (Weiter suchen) --}
  1006. MarkedBack := TMarkedList.Create;
  1007. MarkedBack.Assign(Marked);
  1008. markanzback:= Marked.Count;
  1009. i:=0;
  1010. while i< Marked.Count do begin
  1011. dbGo(mbase,marked[i].recno);
  1012. msgunmark;
  1013. TestMsg;
  1014. if MsgMarked then inc(i);
  1015. end;
  1016. aufbau:=true;
  1017. if (Marked.Count = 0) and (markanzback<>0) then
  1018. begin
  1019. hinweis(getres2(441,18)); { 'keine passenden Nachrichten gefunden' }
  1020. Marked.Assign(MarkedBack);
  1021. end;
  1022. MarkedBack.Free;
  1023. end
  1024. else if bereich<3 then begin {-- Suche: Alle/Netz/User --}
  1025. mi:=dbGetIndex(mbase);
  1026. dbSetIndex(mbase,0);
  1027. dbGoTop(mbase);
  1028. brk:=false; i := 0;
  1029. while not dbEOF(mbase) and not brk do begin
  1030. _brett := dbReadNStr(mbase,mb_brett);
  1031. if (bereich=0) or ((bereich=1) and (FirstChar(_brett)='A')) or
  1032. ((bereich=2) and (FirstChar(_brett)='U')) then
  1033. TestMsg;
  1034. if not dbEOF(mbase) then { kann passieren, wenn fehlerhafter }
  1035. dbNext(mbase); { Satz geloescht wurde }
  1036. Inc(i);
  1037. if i mod 50 = 0 then testbrk(brk);
  1038. end;
  1039. dbSetIndex(mbase,mi);
  1040. end
  1041. else begin {-- Suche: aktuelles Brett --}
  1042. mi:=dbGetIndex(mbase);
  1043. dbSetIndex(mbase,miBrett);
  1044. if bereich=3 then begin { bzw. markierte Bretter }
  1045. if aktdispmode<11 then begin
  1046. i:=0;
  1047. uu:=((aktdispmode>0) and (aktdispmode<10));
  1048. while (i<bmarkanz) and not brk do begin
  1049. if uu then begin
  1050. dbGo(ubase,bmarked^[i]);
  1051. TestBrett(mbrettd('U',ubase));
  1052. end
  1053. else begin
  1054. dbGo(bbase,bmarked^[i]);
  1055. brett := dbReadNStr(bbase,bb_brettname);
  1056. TestBrett(mbrettd(FirstChar(brett),bbase));
  1057. end;
  1058. inc(i);
  1059. end;
  1060. end;
  1061. end
  1062. else
  1063. case aktdispmode of
  1064. -1..0 : begin
  1065. brett := dbReadNStr(bbase,bb_brettname);
  1066. TestBrett(mbrettd(FirstChar(brett),bbase));
  1067. end;
  1068. 1..4 : TestBrett(mbrettd('U',ubase));
  1069. 10 : TestBrett(such_brett);
  1070. else begin
  1071. hinweis(getres2(441,17)); { 'kein Brett gew„hlt' }
  1072. me:=false;
  1073. end;
  1074. end;
  1075. dbSetIndex(mbase,mi);
  1076. end;
  1077. freemem(p,psize);
  1078. CloseBox;
  1079. hdp.Free;
  1080. end;
  1081. {--Suche beendet--}
  1082. if (Marked.Count =0) or (holdmarked and (Marked.Count=markanzback)) { Nichts gefunden }
  1083. then
  1084. begin
  1085. if me then
  1086. begin
  1087. if Suchfeld = 'MsgID' then
  1088. AddMsgId
  1089. else
  1090. hinweis(getres2(441,18)); { 'keine passenden Nachrichten gefunden' }
  1091. aufbau:=true; { wg. gelöschter Markierung! }
  1092. end;
  1093. goto ende; { Fenster wiedeherstellen...}
  1094. end
  1095. else begin
  1096. Suchergebnis:=true;
  1097. suche:=true; { Suche erfolgreich }
  1098. signal;
  1099. CloseBox;
  1100. end;
  1101. end { of NOT Brk }
  1102. else begin { brk }
  1103. ende: { Suche gescheitert/abgebrochen }
  1104. suche:=false;
  1105. CloseBox;
  1106. end;
  1107. freeres;
  1108. end;
  1109. { R+}
  1110. { Betreff-Direktsuche }
  1111. procedure betreffsuche;
  1112. var betr,betr2 : string;
  1113. brett,_Brett : string;
  1114. begin
  1115. moment;
  1116. betr := dbReadNStr(mbase,mb_betreff);
  1117. ReCount(betr); { schneidet Re's weg }
  1118. betr:=trim(betr);
  1119. UkonvStr(betr, Length(betr));
  1120. brett := dbReadNStr(mbase,mb_brett);
  1121. dbSetIndex(mbase,miBrett);
  1122. dbSeek(mbase,miBrett,brett);
  1123. Marked.Clear;
  1124. repeat
  1125. betr2 := dbReadNStr(mbase,mb_betreff);
  1126. ReCount(betr2);
  1127. betr2:=trim(betr2);
  1128. UkonvStr(betr2, Length(betr2));
  1129. (* ll:=min(length(betr),length(betr2));
  1130. if (ll>0) and (UpperCase(left(betr,ll))=UpperCase(left(betr2,ll))) then *)
  1131. if UpperCase(betr)=UpperCase(betr2) then
  1132. MsgAddmark;
  1133. dbSkip(mbase,1);
  1134. if not dbEOF(mbase) then
  1135. _brett := dbReadNStr(mbase,mb_brett);
  1136. until dbEOF(mbase) or (_brett<>brett);
  1137. closebox;
  1138. signal;
  1139. if Marked.Count >0 then select(11);
  1140. aufbau:=true;
  1141. end;
  1142. //Nachricht/Suchen/Wiedervorlage
  1143. procedure SucheWiedervorlage;
  1144. var x,y,xx : Integer;
  1145. brk : boolean;
  1146. _brett : string;
  1147. mbrett : string;
  1148. dat : string;
  1149. n,nn : longint;
  1150. bi : shortint;
  1151. procedure testbase(xbase:pointer);
  1152. begin
  1153. bi:=dbGetIndex(xbase);
  1154. if xbase=bbase then begin
  1155. dbSetIndex(xbase,bibrett);
  1156. dbGoTop(xbase);
  1157. end
  1158. else begin
  1159. dbsetindex(xbase,uiadrbuch);
  1160. dbseek(xbase,uiadrbuch,#1);
  1161. end;
  1162. dat:=dbLongStr(ixDat('2712310000'));
  1163. brk:=false;
  1164. dbSetIndex(mbase,miBrett);
  1165. while not dbEOF(xbase) and not brk do
  1166. begin
  1167. inc(n);
  1168. attrtxt(col.colmboxhigh);
  1169. FWrt(xx, y+2, Format('%3d', [n*100 div nn]));
  1170. if (xbase=ubase) or (not smdl(dbReadInt(xbase,'ldatum'),ixDat('2712310000')))
  1171. then begin
  1172. if xbase=ubase then _brett:='U' else
  1173. _brett:=copy(dbReadStr(xbase,'brettname'),1,1);
  1174. _brett:=_brett+dbLongStr(dbReadInt(xbase,'int_nr'));
  1175. dbSeek(mbase,miBrett,_brett+dat);
  1176. mbrett:=_brett;
  1177. while not dbEOF(mbase) and (mbrett=_brett) do begin
  1178. mbrett := dbReadNStr(mbase,mb_brett);
  1179. if mbrett=_brett then MsgAddmark;
  1180. dbSkip(mbase,1);
  1181. end;
  1182. end;
  1183. dbSkip(xbase,1);
  1184. testbrk(brk);
  1185. end;
  1186. dbSetIndex(xbase,bi);
  1187. end;
  1188. begin
  1189. Marked.Clear;
  1190. msgbox(33,5,'',x,y);
  1191. wrt(x+3,y+2,getres(443)); { 'Einen Moment bitte... %' }
  1192. xx:=wherex-5;
  1193. n:=0;
  1194. nn:=dbRecCount(bbase)+dbreccount(ubase);
  1195. testbase(ubase);
  1196. if not brk then
  1197. testbase(bbase);
  1198. CloseBox;
  1199. if not brk then
  1200. if Marked.Count=0 then
  1201. hinweis(getres(444)) { 'keine Wiedervorlage-Nachrichten gefunden' }
  1202. else begin
  1203. signal;
  1204. select(11);
  1205. end;
  1206. end;
  1207. {.$I xp4o.inc} { Reorg }
  1208. { XP4O - Reorganisation }
  1209. procedure BU_reorg(user,adrbuch,auto:boolean);
  1210. var x,y,xx : Integer;
  1211. brk,ask : boolean;
  1212. typ : string;
  1213. d : DB;
  1214. brett : string[BrettLen];
  1215. brettc : char;
  1216. _brett : string;
  1217. _mbrett : string;
  1218. nfeld : integer;
  1219. loesch : string;
  1220. n,gel : longint;
  1221. leer : boolean;
  1222. next : longint;
  1223. null : byte;
  1224. procedure wrstat;
  1225. begin
  1226. attrtxt(col.coldiahigh);
  1227. moff;
  1228. Wrt(xx,y+1, Format('%5d', [n]));
  1229. Wrt(xx,y+2, Format('%5d', [gel]));
  1230. mon;
  1231. end;
  1232. const
  1233. _user12: array[boolean] of integer = (2,1);
  1234. _user34: array[boolean] of integer = (4,3);
  1235. begin
  1236. typ:=getres2(445,iif(user,1,2)); { 'User' / 'Bretter' }
  1237. if auto then
  1238. brk := false
  1239. else
  1240. begin
  1241. if not adrbuch then
  1242. { 'Beim Loeschen von '+typ+'n nachfragen' }
  1243. n := _user34[user] //ask:=ReadJNesc(getres2(445,iif(user,3,4)),true,brk)
  1244. else
  1245. n := 5; { 'Beim Austragen von Usern nachfragen' }
  1246. ask:=ReadJNesc(getres2(445,n),not adrbuch,brk);
  1247. end;
  1248. if not brk then begin
  1249. if user then begin
  1250. d:=ubase; nfeld:=ub_username; end
  1251. else begin
  1252. d:=bbase; nfeld:=bb_brettname; end;
  1253. n:=0; gel:=0;
  1254. msgbox(25,4,'',x,y);
  1255. if not adrbuch then begin
  1256. mwrt(x+3,y+1,forms(typ,8)+':');
  1257. mwrt(x+3,y+2,getres2(445,6)); { 'geloescht:' }
  1258. xx:=x+13;
  1259. end
  1260. else begin
  1261. mwrt(x+3,y+1,getres2(445,7)); { 'User ..... :' }
  1262. mwrt(x+3,y+2,getres2(445,8)); { 'ausgetragen:' }
  1263. xx:=x+16;
  1264. end;
  1265. if adrbuch then begin
  1266. dbSetindex(d,uiAdrbuch);
  1267. dbSeek(d,uiAdrbuch,#1);
  1268. end
  1269. else begin
  1270. dbSetindex(d,1);
  1271. dbGoTop(d);
  1272. end;
  1273. brettc:='U';
  1274. null:=0;
  1275. while not (dbEOF(d) or brk) do
  1276. begin
  1277. inc(n);
  1278. if not user then
  1279. begin
  1280. brett := dbReadNStr(bbase,bb_brettname);
  1281. brettc:= FirstChar(brett);
  1282. end else
  1283. brett := dbReadNStr(ubase,ub_username);
  1284. _brett:=mbrettd(brettc,d);
  1285. dbSeek(mbase,miBrett,_brett);
  1286. leer:=dbEOF(mbase);
  1287. if not leer then begin
  1288. _Mbrett := dbReadNStr(mbase,mb_brett);
  1289. leer:=_mbrett<>_brett;
  1290. end;
  1291. if leer and ((user and (LeftStr(brett,4)<>#0+'$/T')) or
  1292. (not user and (LeftStr(brett,3)<>'$/T'))) then
  1293. begin
  1294. loesch := dbReadNStr(d,nfeld);
  1295. if not user then loesch:=copy(loesch,2,80);
  1296. if adrbuch then
  1297. if (dbReadInt(ubase,'userflags') and 4=0) and
  1298. (dbXsize(ubase,'adresse')=0) then
  1299. if not ask or (ReadJNesc(getreps2(445,9,LeftStr(loesch,55)),true,brk)and not brk)
  1300. then begin { '%s austragen' }
  1301. dbSkip(d,1);
  1302. next:=dbRecno(d);
  1303. if dbEOF(d) then dbGoEnd(d)
  1304. else dbSkip(d,-1);
  1305. dbWriteN(d,ub_adrbuch,null);
  1306. dbGo(d,next);
  1307. inc(gel);
  1308. end
  1309. else
  1310. dbNext(d)
  1311. else
  1312. dbNext(d);
  1313. if not adrbuch then
  1314. if (not user or
  1315. ((dbReadInt(d,'adrbuch')=0) and (dbReadInt(d,'userflags') and 5=1)))
  1316. and (not ask or (ReadJNesc(getreps2(445,10,LeftStr(loesch,60)),true,brk)and not brk))
  1317. then begin { '%s loeschen' }
  1318. if (user and (aktdispmode in [1..4])) or
  1319. (not user and (aktdispmode<=0)) then
  1320. UBunmark(dbRecno(d));
  1321. dbDelete(d);
  1322. inc(gel);
  1323. end
  1324. else
  1325. dbNext(d);
  1326. end { not leer }
  1327. else dbNext(d);
  1328. wrstat;
  1329. if (n mod 16=0) and not brk then
  1330. begin
  1331. testbrk(brk);
  1332. if brk and not ReadJN(getres(446),true) then { 'Reorganisation abbrechen' }
  1333. brk:=false;
  1334. end;
  1335. end;
  1336. closebox;
  1337. end;
  1338. freeres;
  1339. end;
  1340. procedure MsgReorgScan(_del,repair:boolean; var brk:boolean);
  1341. var x,y,wdt: Integer;
  1342. n,ndel,
  1343. nbesch : longint;
  1344. bt,dbt,
  1345. bbt : longint;
  1346. disp : string;
  1347. hzeit : integer16;
  1348. hzahl : boolean;
  1349. dat : TDateTime;
  1350. bi : shortint;
  1351. procedure display;
  1352. begin
  1353. attrtxt(col.colmboxhigh);
  1354. moff;
  1355. Wrt(x+wdt+3,y+4, Format('%7d', [n]));
  1356. Wrt(x+wdt+3,y+5, Format('%7d', [ndel]));
  1357. Wrt(x+wdt+3,y+6, Format('%7d', [nbesch]));
  1358. Wrt(x+wdt+12,y+4, Format('%7d', [bt div 1024]));
  1359. Wrt(x+wdt+12,y+5, Format('%7d', [dbt div 1024]));
  1360. Wrt(x+wdt+12,y+6, Format('%7d', [bbt div 1024]));
  1361. mon;
  1362. end;
  1363. procedure testdel(const _brett:string);
  1364. var _mbrett : string;
  1365. haltedat: longint;
  1366. edat : longint;
  1367. msize : longint;
  1368. groesse : longint;
  1369. hflags : byte;
  1370. uvs,b : byte;
  1371. ablage : byte;
  1372. defekt : boolean;
  1373. hdp : THeader;
  1374. hds : longint;
  1375. nzahl : longint;
  1376. typ : char;
  1377. function htimeout:boolean;
  1378. begin
  1379. htimeout:=(hzahl and (hzeit>0) and (nzahl>hzeit)) or
  1380. (not hzahl and smdl(edat,haltedat));
  1381. end;
  1382. begin
  1383. if hzahl then begin
  1384. dbSeek(mbase,miBrett,_brett+#$ff#$ff); { Brettende suchen }
  1385. if dbEOF(mbase) then dbGoEnd(mbase)
  1386. else dbSkip(mbase,-1);
  1387. if dbBOF(mbase) then exit;
  1388. while not dbBOF(mbase) and (dbReadStrN(mbase,mb_brett)=_brett) and
  1389. (dbReadIntN(mbase,mb_unversandt) and 8<>0) do
  1390. dbSkip(mbase,-1);
  1391. if dbBOF(mbase) then exit;
  1392. end
  1393. else begin
  1394. dbSeek(mbase,miBrett,_brett); { Brettanfang suchen }
  1395. if dbEOF(mbase) then exit;
  1396. end;
  1397. if hzahl or (hzeit=0) then
  1398. haltedat:=0
  1399. else
  1400. haltedat:=ixdat(FormatDateTime('yymmdd', Dat-hzeit+1) + '0000');
  1401. nzahl:=1;
  1402. brk := false;
  1403. hdp := THeader.Create;
  1404. repeat
  1405. if n mod 100 = 0 then testbrk(brk);
  1406. if brk then
  1407. brk:=ReadJN(getres(iif(_del,446,447)),true); { (Reorganisation) 'abbrechen' }
  1408. _mbrett := dbReadNStr(mbase,mb_brett);
  1409. if _mbrett=_brett then begin
  1410. inc(n);
  1411. dbReadN(mbase,mb_msgsize,msize);
  1412. inc(bt,msize);
  1413. dbReadN(mbase,mb_groesse,groesse);
  1414. dbReadN(mbase,mb_ablage,ablage);
  1415. dbReadN(mbase,mb_typ,typ);
  1416. dbReadN(mbase,mb_halteflags,hflags);
  1417. defekt:=(groesse<0) or (msize<0) or (groesse+14>msize) or (ablage>=ablagen) or
  1418. (msize-groesse>iif(ntZCablage(ablage),1000000,8000)) or
  1419. (dbReadIntN(mbase, mb_adresse)+msize>ablsize[ablage]) or
  1420. ((typ<>'T') and (typ<>'B') and (typ<>'M')) or (hflags>2) or
  1421. (dbReadIntN(mbase, mb_adresse)<0) or
  1422. (dbReadIntN(mbase, mb_netztyp)<0); { empfanz > 127 ? }
  1423. if repair and not defekt then begin
  1424. dbReadN(mbase,mb_gelesen,b);
  1425. if b>1 then begin
  1426. b:=0;
  1427. dbWriteN(mbase,mb_gelesen,b);
  1428. end;
  1429. ReadHeader(hdp,hds,false);
  1430. defekt:=(hds=1) or (hds<>msize-groesse) or (groesse<>hdp.groesse);
  1431. end;
  1432. if defekt then begin
  1433. hflags:=2; { Nachricht defekt }
  1434. dbWriteN(mbase,mb_halteflags,hflags);
  1435. if repair then msgaddmark;
  1436. inc(nbesch); inc(bbt,msize);
  1437. end;
  1438. if typ='M' then begin
  1439. typ := 'T';
  1440. dbWriteN(mbase,mb_typ,typ);
  1441. end;
  1442. dbReadN(mbase,mb_empfdatum,edat);
  1443. dbReadN(mbase,mb_unversandt,uvs);
  1444. if (msize=0) or { nur zur Sicherheit - sollte nicht vorkommen }
  1445. ((uvs and 1=0) and ((hflags=2) or ((hflags<>1) and htimeout)))
  1446. then begin
  1447. inc(ndel);
  1448. inc(dbt,msize);
  1449. if _del and (hflags<>2) then begin
  1450. hflags:=2;
  1451. dbWriteN(mbase,mb_halteflags,hflags);
  1452. end;
  1453. if ablage<ablagen then reobuf[ablage]:=true;
  1454. end
  1455. else
  1456. if ablage<ablagen then inc(bufsiz[ablage],msize);
  1457. dbSkip(mbase,iif(hzahl,-1,1));
  1458. inc(nzahl);
  1459. if n mod 20=0 then display;
  1460. end;
  1461. until brk or (_mbrett<>_brett) or dbEOF(mbase) or dbBOF(mbase);
  1462. Hdp.Free;
  1463. end;
  1464. begin
  1465. if dbRecCount(mbase)=0 then begin
  1466. rfehler(420); { 'keine Nachrichten vorhanden!' }
  1467. brk:=true;
  1468. exit;
  1469. end;
  1470. if not repair then MausInfoReorg;
  1471. wdt:=length(getres2(448,4));
  1472. msgbox(max(45,wdt+33),iif(_del,9,10),getres2(448,iif(_del,1,iif(repair,2,3))),x,y);
  1473. mwrt(x+3,y+4,getres2(448,4)+' / KB'); { 'Nachrichten:' }
  1474. mwrt(x+3,y+5,getres2(448,5)+' / KB'); { 'auf Loeschen:' }
  1475. mwrt(x+3,y+6,getres2(448,6)+' / KB'); { 'fehlerhaft: ' }
  1476. n:=0; ndel:=0; nbesch:=0;
  1477. bt:=0; dbt:=0; bbt:=0;
  1478. getablsizes;
  1479. Dat := Now;
  1480. bi:=dbGetIndex(bbase);
  1481. dbSetIndex(bbase,biBrett);
  1482. dbGoTop(bbase);
  1483. dbSetIndex(mbase,miBrett);
  1484. brk:=false;
  1485. fillchar(reobuf,sizeof(reobuf),false);
  1486. fillchar(bufsiz,sizeof(bufsiz),0);
  1487. if repair then
  1488. Marked.Clear;
  1489. while not brk and not dbEOF(bbase) do begin
  1490. dbReadN(bbase,bb_haltezeit,hzeit);
  1491. hzahl:=odd(dbReadInt(bbase,'flags'));
  1492. disp := dbReadNStr(bbase,bb_brettname);
  1493. if (disp <> '') and (LeftStr(disp,3)<>'$/T') then
  1494. begin
  1495. attrtxt(col.colmboxhigh);
  1496. mwrt(x+3,y+2,forms(mid(disp,2),40));
  1497. testdel(mbrettd(disp[1],bbase));
  1498. end;
  1499. dbSkip(bbase,1);
  1500. end;
  1501. dbSetIndex(ubase,uiAdrBuch);
  1502. dbSeek(ubase,uiAdrbuch,#1);
  1503. while not brk and not dbEOF(ubase) do begin
  1504. if dbReadInt(ubase,'userflags') and 4=0 then begin { keine Verteiler }
  1505. dbReadN(ubase,ub_haltezeit,hzeit);
  1506. hzahl:=false;
  1507. disp := dbReadNStr(ubase,ub_username);
  1508. attrtxt(col.colmboxhigh);
  1509. mwrt(x+3,y+2,forms(disp,40));
  1510. testdel(mbrettd('U',ubase));
  1511. end;
  1512. dbSkip(ubase,1);
  1513. end;
  1514. dbSetIndex(bbase,bi);
  1515. if repair then begin
  1516. closebox;
  1517. if Marked.Count =0 then
  1518. hinweis(getres2(448,7)) { 'keine fehlerhaften Nachrichten gefunden' }
  1519. else
  1520. select(11);
  1521. aufbau:=true;
  1522. end
  1523. else begin
  1524. if not brk then
  1525. if _del then
  1526. wkey(1,false)
  1527. else begin
  1528. signal;
  1529. attrtxt(col.colmbox);
  1530. mwrt(x+2,y+8,' '+getres(12){+' '#8});
  1531. wait(curon);
  1532. end;
  1533. closebox;
  1534. end;
  1535. freeres;
  1536. aufbau:=true;
  1537. end;
  1538. { Alle Nachrichten mit halteflags=2 loeschen; Puffer ueberarbeiten }
  1539. { Nachrichten mit defekter Groesse werden auf 'loeschen' gesetzt }
  1540. procedure MsgReorg;
  1541. const tmp = 'REORG.$$$';
  1542. maxbufs = 20;
  1543. var x,y,yy : Integer;
  1544. lastproz: byte;
  1545. abl : byte;
  1546. ablage : byte;
  1547. n,count : longint;
  1548. f1,f2 : file;
  1549. f1s : longint;
  1550. hdfree : int64;
  1551. hflags : byte;
  1552. uflags : byte;
  1553. p : pointer;
  1554. bsize : Integer;
  1555. newadr : longint;
  1556. reo : boolean;
  1557. bufa : array[1..maxbufs] of record
  1558. bp : pointer;
  1559. size : xpWord;
  1560. end;
  1561. bufs : byte;
  1562. break : boolean;
  1563. mi : xpWord;
  1564. voll : boolean; { kein Platz fuer eine ode mehrere Abl. }
  1565. errflag : boolean;
  1566. procedure test_killed;
  1567. var f : file of boolean;
  1568. b : boolean;
  1569. i : byte;
  1570. begin
  1571. assign(f,killedDat);
  1572. if existf(f) then begin
  1573. reset(f);
  1574. i:=0;
  1575. while not eof(f) and (i<ablagen) do
  1576. begin
  1577. read(f,b);
  1578. if b then reobuf[i]:=true;
  1579. inc(i);
  1580. end;
  1581. close(f);
  1582. end;
  1583. end;
  1584. procedure flushbufs;
  1585. var i : byte;
  1586. begin
  1587. for i:=1 to bufs do
  1588. with bufa[i] do begin
  1589. blockwrite(f2,bp^,size);
  1590. freemem(bp,size);
  1591. end;
  1592. bufs:=0;
  1593. end;
  1594. procedure movemsg;
  1595. var adr,size : longint;
  1596. rr : Integer;
  1597. mid : string;
  1598. domove : boolean;
  1599. rec : longint;
  1600. b : byte;
  1601. mpos : longint;
  1602. function MsgOK:boolean; { Test, ob Xgepostete Msg schon verschoben wurde }
  1603. var fs : longint;
  1604. hdp : THeader;
  1605. hds : longint;
  1606. ok : boolean;
  1607. enr : shortint;
  1608. begin
  1609. flushbufs;
  1610. fs:=filesize(f2);
  1611. if adr+size>fs then
  1612. MsgOK:=false
  1613. else begin
  1614. seek(f2,adr);
  1615. enr:=dbReadInt(mbase,'netztyp') shr 24;
  1616. hdp := THeader.Create;
  1617. MakeHeader(true,f2,enr,hds,hdp,ok,true, true);
  1618. MsgOK:=ok and (size=hds+hdp.groesse) and (hdp.Empfaenger.Count>=min(2,enr))
  1619. and (dbReadInt(mbase,'groesse')=hdp.groesse);
  1620. Hdp.Free;
  1621. seek(f2,fs);
  1622. end;
  1623. end;
  1624. begin
  1625. dbReadN(mbase,mb_adresse,adr);
  1626. dbReadN(mbase,mb_msgsize,size);
  1627. if (size<0) or (adr<0) or (MaxInt-adr<size) or (adr+size>f1s) then begin { Nachricht defekt }
  1628. dbDelete(mbase);
  1629. exit;
  1630. end;
  1631. dbReadN(mbase,mb_gelesen,b);
  1632. if b>1 then begin { fehlerhaftes gelesen-Flag korrigieren }
  1633. b:=1;
  1634. dbWriteN(mbase,mb_gelesen,b);
  1635. end;
  1636. domove:=true;
  1637. if dbReadInt(mbase,'netztyp') shr 24>0 then begin { CrossPosting }
  1638. rec:=dbRecno(mbase);
  1639. mid:=LeftStr(dbReadStrN(mbase,mb_msgid),4);
  1640. domove:=not MsgOk;
  1641. if domove then begin
  1642. dbSeek(bezbase,beiMsgid,mid);
  1643. if dbFound then begin
  1644. while not dbEOF(bezbase) and (dbLongStr(dbReadIntN(bezbase,bezb_msgid))=mid)
  1645. do begin
  1646. mpos:=dbReadIntN(bezbase,bezb_msgpos);
  1647. if (mpos<>rec) and not dbDeleted(mbase,mpos) then begin
  1648. dbGo(mbase,mpos);
  1649. if (dbReadInt(mbase,'adresse')=adr) and
  1650. (dbReadInt(mbase,'ablage')=abl) and
  1651. (dbReadInt(mbase,'msgsize')=size) then
  1652. dbWriteN(mbase,mb_adresse,newadr)
  1653. end;
  1654. dbNext(bezbase);
  1655. end;
  1656. dbGo(mbase,rec);
  1657. end;
  1658. end; { of domove }
  1659. end; { of CrossPosting }
  1660. if domove then begin
  1661. dbWriteN(mbase,mb_adresse,newadr);
  1662. seek(f1,adr);
  1663. if size>bsize then
  1664. begin
  1665. flushbufs;
  1666. while size>0 do begin
  1667. blockread(f1,p^,min(bsize,size),rr);
  1668. blockwrite(f2,p^,rr);
  1669. dec(size,rr);
  1670. end
  1671. end
  1672. else begin
  1673. inc(bufs); { Nachricht in n„chsten Puffer lesen }
  1674. bufa[bufs].size:=size;
  1675. getmem(bufa[bufs].bp,size);
  1676. blockread(f1,bufa[bufs].bp^,size,rr);
  1677. end;
  1678. if bufs=maxbufs then
  1679. flushbufs;
  1680. inc(newadr,dbReadInt(mbase,'msgsize'));
  1681. end;
  1682. dbSkip(mbase,1);
  1683. end;
  1684. procedure show;
  1685. var
  1686. proz : byte;
  1687. begin
  1688. attrtxt(col.colmbox);
  1689. proz:=n*100 div count;
  1690. if proz<>lastproz then
  1691. begin
  1692. moff;
  1693. FWrt(WhereX, WhereY, Format('%3d', [min(proz,100)]));
  1694. mon;
  1695. lastproz:=proz;
  1696. end;
  1697. if not break then begin
  1698. testbrk(break);
  1699. if break then begin
  1700. savecursor;
  1701. break:=ReadJN(getres(449),true); { 'Abbruch nach Ablagenende' }
  1702. if break then begin
  1703. attrtxt(col.colmbox);
  1704. mwrt(x+2,y+14,getres(450)); { ' Abbruch bei Ablagenende.' }
  1705. end;
  1706. restcursor;
  1707. end;
  1708. end;
  1709. end;
  1710. procedure clkilled(ablage:byte);
  1711. var f : file of boolean;
  1712. b: boolean;
  1713. begin
  1714. if FileExists(KilledDat) then begin
  1715. assign(f,KilledDat);
  1716. reset(f);
  1717. while filesize(f)<ablage do begin
  1718. b:=false;
  1719. seek(f,filesize(f));
  1720. write(f,b);
  1721. end;
  1722. seek(f,ablage);
  1723. b:=false;
  1724. write(f,b);
  1725. close(f);
  1726. end;
  1727. end;
  1728. procedure clw;
  1729. begin
  1730. clwin(x+1,x+48,y+1,y+13);
  1731. yy:=y+1;
  1732. end;
  1733. function reobufs:boolean;
  1734. var i : integer;
  1735. b : boolean;
  1736. begin
  1737. b:=reobuf[0];
  1738. for i:=1 to ablagen-1 do
  1739. b:=b or reobuf[i];
  1740. reobufs:=b;
  1741. end;
  1742. { Zugriff fuer /T/S/XPOINT und /Z/ALT/S/XPOINT setzen }
  1743. procedure Rerout(znetz:boolean; brett:string; sperre:boolean);
  1744. var b : byte;
  1745. newbrett : string;
  1746. begin
  1747. if znetz then
  1748. dbSeek(bbase,biBrett,'A/Z-NETZ/ALT/SUPPORT/XPOINT/'+UpperCase(brett))
  1749. else
  1750. dbSeek(bbase,biBrett,'A/T-NETZ/SUPPORT/XPOINT/'+UpperCase(brett));
  1751. if dbFound then begin
  1752. if sperre then begin
  1753. b:=dbReadInt(bbase,'flags') and (not 8)+8;
  1754. dbWriteN(bbase,bb_flags,b);
  1755. end;
  1756. if znetz then
  1757. newbrett:='/Z-NETZ/ALT/SUPPORT/XPOINT/ALLGEMEINES'
  1758. else
  1759. newbrett:='/T-NETZ/SUPPORT/XPOINT/ALLGEMEINES';
  1760. dbWriteNStr(bbase,bb_adresse,newbrett);
  1761. end;
  1762. end;
  1763. begin
  1764. CloseAblage;
  1765. msgbox(50,15,getres2(451,1),x,y); { 'Reorganisation' }
  1766. bsize:=65536;
  1767. getmem(p,bsize);
  1768. test_killed;
  1769. break:=false;
  1770. DisableDos:=true;
  1771. mi:=dbGetIndex(mbase);
  1772. dbSetIndex(mbase,0); { ohne Indexreihenfolge! }
  1773. repeat
  1774. hdfree:=DiskFree(0);
  1775. clw;
  1776. abl:=0;
  1777. bufs:=0;
  1778. voll:=false;
  1779. reo:=false;
  1780. while (abl<ablagen) and not break do begin
  1781. if reobuf[abl] then begin
  1782. inc(yy);
  1783. attrtxt(col.colmbox);
  1784. mwrt(x+3,yy,getreps2(451,2,strs(abl))); { 'Ablage Nr. %s }
  1785. if hdfree<bufsiz[abl]+50000 then begin
  1786. moff;
  1787. write(getres2(451,3)); { ' - kein Platz!!!' }
  1788. mon;
  1789. errsound;
  1790. logerror(getreps2(451,4,strs(abl))); { 'zu wenig Platz, um Ablage '+strs(abl)+' zu reorganisieren' }
  1791. voll:=true;
  1792. end
  1793. else begin
  1794. assign(f1,aFile(abl));
  1795. if not FileExists(aFile(abl)) then begin
  1796. savecursor;
  1797. trfehler1(421,UpperCase(aFile(abl)),30); { 'Warnung: Ablagendatei %s fehlt!' }
  1798. restcursor;
  1799. rewrite(f1,1);
  1800. close(f1);
  1801. end;
  1802. moff;
  1803. Wrt2(getres2(451,5));
  1804. GotoXY(WhereX-5, WhereY); { ' packen ... %' }
  1805. mon;
  1806. lastproz:=101;
  1807. reset(f1,1);
  1808. f1s:=filesize(f1);
  1809. assign(f2,FileUpperCase(tmp)); { muss wg. rename jedesmal neu assigned werden! }
  1810. rewrite(f2,1);
  1811. newadr:=0;
  1812. dbGoTop(mbase);
  1813. count:=dbRecCount(mbase);
  1814. n:=1;
  1815. errflag:=false;
  1816. while not dbEOF(mbase) do
  1817. begin
  1818. if n>count then
  1819. errflag:=true;
  1820. if n mod 10=0 then show;
  1821. dbReadN(mbase,mb_ablage,ablage);
  1822. if ablage=abl then
  1823. begin
  1824. dbReadN(mbase,mb_halteflags,hflags);
  1825. dbReadN(mbase,mb_unversandt,uflags);
  1826. if (hflags<>2) or odd(uflags) then
  1827. movemsg { impliziert Skip oder Delete }
  1828. else begin
  1829. DelBezug;
  1830. dbDelete(mbase);
  1831. end;
  1832. end
  1833. else
  1834. if ablage>=ablagen then
  1835. dbDelete(mbase)
  1836. else
  1837. dbSkip(mbase,1);
  1838. inc(n);
  1839. end;
  1840. if n<=count then errflag:=true;
  1841. flushbufs;
  1842. if count>0 then show;
  1843. close(f2);
  1844. close(f1); erase(f1);
  1845. rename(f2,aFile(abl));
  1846. FlushClose;
  1847. if errflag then begin
  1848. trfehler(445,30); { 'Nachrichtendatenbank fehlerhaft - verwenden Sie /Wartung/Packen!' }
  1849. break:=true;
  1850. end;
  1851. clkilled(abl);
  1852. reobuf[abl]:=false;
  1853. reo:=true;
  1854. end;
  1855. end;
  1856. inc(abl);
  1857. if abl=10 then clw;
  1858. end;
  1859. until break or not (voll and reo and reobufs);
  1860. dbSetIndex(mbase,mi);
  1861. if reo then
  1862. begin
  1863. Wrt(x+3,yy+2,getres2(451,6));
  1864. GotoXY(WhereX-5, WhereY); { 'Einen Moment noch... %' }
  1865. brettdatumsetzen(true);
  1866. end else
  1867. mwrt(x+3,yy+2,getres2(451,7)); { 'nix zu loeschen' }
  1868. DisableDOS:=false;
  1869. signal;
  1870. Rerout(false,'MELDUNGEN',true);
  1871. Rerout(false,'UPDATES',true);
  1872. Rerout(true,'MELDUNGEN',true);
  1873. Rerout(true,'UPDATES',true);
  1874. SysDelay(500);
  1875. closebox;
  1876. freeres;
  1877. wrtiming('REORG');
  1878. freemem(p,bsize);
  1879. Marked.Clear;
  1880. aufbau:=true; xaufbau:=true;
  1881. end;
  1882. procedure ModiEmpfDatum;
  1883. var d : datetimest;
  1884. brk : boolean;
  1885. getdate: boolean;
  1886. l : longint;
  1887. begin
  1888. getdate:=true;
  1889. d:=longdat(dbReadInt(mbase,'empfdatum'));
  1890. EditDate(15,11+(screenlines-25)div 2,getres2(452,1),d,getdate,brk); { 'neues Empfangsdatum:' }
  1891. if not brk then begin
  1892. if getdate then d:=longdat(dbreadint(mbase,'origdatum'));
  1893. l:=ixdat(d);
  1894. dbWriteN(mbase,mb_empfdatum,l);
  1895. aufbau:=true;
  1896. end;
  1897. end;
  1898. function testuvs(const txt:atext):boolean;
  1899. var uvs : byte;
  1900. begin
  1901. dbReadN(mbase,mb_unversandt,uvs);
  1902. if uvs and 1<>0 then rfehler1(422,txt); { 'Bitte verwenden Sie Nachricht/Unversandt/%s' }
  1903. testuvs:=(uvs and 1<>0);
  1904. end;
  1905. procedure ModiBetreff;
  1906. var brk : boolean;
  1907. hdp : THeader;
  1908. hds : longint;
  1909. x,y : Integer;
  1910. fn : string;
  1911. f : file;
  1912. begin
  1913. if testuvs(getres(453)) then exit; { 'Aendern' }
  1914. hdp := THeader.Create;
  1915. ReadHeader(hdp,hds,true);
  1916. if hds>1 then begin
  1917. diabox(63,5,'',x,y);
  1918. readstring(x+3,y+2,getres(454),hdp.betreff,40,BetreffLen,'',brk); { 'neuer Betreff:' }
  1919. closebox;
  1920. if not brk then begin
  1921. PGP_BeginSavekey;
  1922. fn:=TempS(dbReadInt(mbase,'msgsize')+100);
  1923. assign(f,fn);
  1924. rewrite(f,1);
  1925. { ClearPGPflags(hdp); }
  1926. hdp.orgdate:=true;
  1927. WriteHeader(hdp,f);
  1928. XreadF(hds,f); { den Nachrichtentext anhaengen ... }
  1929. close(f);
  1930. Xwrite(fn);
  1931. erase(f);
  1932. wrkilled;
  1933. TruncStr(hdp.betreff,40);
  1934. dbWriteNStr(mbase,mb_betreff,hdp.betreff);
  1935. PGP_EndSavekey;
  1936. aufbau:=true;
  1937. xaufbau:=true;
  1938. end;
  1939. end;
  1940. Hdp.Free;
  1941. end;
  1942. procedure ModiHighlite;
  1943. var l : longint;
  1944. begin
  1945. dbReadN(mbase,mb_netztyp,l);
  1946. l:=l xor $1000;
  1947. dbWriteN(mbase,mb_netztyp,l);
  1948. aufbau:=true;
  1949. end;
  1950. procedure ModiText;
  1951. var fn : string;
  1952. fn2 : string;
  1953. f,f2 : file;
  1954. hdp : Theader;
  1955. hds : longint;
  1956. typ : char;
  1957. l : longint;
  1958. begin
  1959. dbReadN(mbase,mb_typ,typ);
  1960. if (typ='B') or (typ='M') then begin
  1961. rfehler(423); { 'Bei Binaerdateien nicht moeglich' }
  1962. exit;
  1963. end;
  1964. if testuvs(getres(455)) then exit; { 'Edit' }
  1965. hdp := THeader.Create;
  1966. ReadHeader(hdp,hds,true); { Heder einlesen }
  1967. if hds>1 then begin
  1968. PGP_BeginSavekey;
  1969. fn:=TempS(dbReadInt(mbase,'msgsize'));
  1970. assign(f,fn);
  1971. rewrite(f,1);
  1972. XReadIsoDecode:=true;
  1973. XreadF(hds,f); { Nachrichtentext in Tempfile.. }
  1974. close(f);
  1975. editfile(fn,true,false,false,0,false); { ..editieren.. }
  1976. fn2:=TempS(_filesize(fn)+2000);
  1977. assign(f2,fn2);
  1978. rewrite(f2,1);
  1979. hdp.groesse:=_filesize(fn);
  1980. dbWriteN(mbase,mb_groesse,hdp.groesse);
  1981. hdp.charset:='';
  1982. { ClearPGPflags(hdp); }
  1983. hdp.orgdate:=true;
  1984. WriteHeader(hdp,f2); { ..Header in neues Tempfile.. }
  1985. reset(f,1);
  1986. fmove(f,f2); { ..den Text dranhaengen.. }
  1987. close(f); erase(f);
  1988. close(f2);
  1989. dbReadN(mbase,mb_netztyp,l);
  1990. l:=l and (not $2000); { ISO-Codierung abschalten }
  1991. dbWriteN(mbase,mb_netztyp,l);
  1992. Xwrite(fn2); { ..und ab in die Datenbank. }
  1993. erase(f2);
  1994. wrkilled;
  1995. PGP_EndSavekey;
  1996. aufbau:=true; { wg. geaenderter Groesse }
  1997. end;
  1998. Hdp.Free;
  1999. end;
  2000. procedure ModiRot13;
  2001. var ablg : byte;
  2002. adr : longint;
  2003. f : file;
  2004. l,size : longint;
  2005. p : pointer;
  2006. ps : Integer;
  2007. rr: Integer;
  2008. typ : char;
  2009. begin
  2010. dbReadN(mbase,mb_typ,typ);
  2011. if typ='B' then begin
  2012. rfehler(423); { 'Bei Binaerdateien nicht moeglich' }
  2013. exit;
  2014. end;
  2015. if testuvs(getres(453)) then exit; { 'Aendern' }
  2016. dbReadN(mbase,mb_ablage,ablg);
  2017. dbReadN(mbase,mb_adresse,adr);
  2018. dbReadN(mbase,mb_groesse,size);
  2019. assign(f,aFile(ablg));
  2020. reset(f,1);
  2021. if (size=0) or (adr+size>filesize(f)) then begin
  2022. rfehler1(424,strs(ablg)); { 'Nachricht ist beschaedigt (Ablage %s)' }
  2023. close(f);
  2024. end
  2025. else
  2026. begin
  2027. ps:=32768;
  2028. getmem(p,ps);
  2029. seek(f,adr+dbReadInt(mbase,'msgsize')-size);
  2030. repeat
  2031. l:=filepos(f);
  2032. blockread(f,p^,min(ps,size),rr);
  2033. Rot13(p^,rr);
  2034. seek(f,l);
  2035. blockwrite(f,p^,rr);
  2036. dec(size,rr);
  2037. until size=0;
  2038. close(f);
  2039. freemem(p,ps);
  2040. end;
  2041. end;
  2042. procedure ModiTyp;
  2043. var c : char;
  2044. uvs : byte;
  2045. flags:longint;
  2046. begin
  2047. dbReadN(mbase,mb_unversandt,uvs);
  2048. if uvs and 1<>0 then
  2049. rfehler(425) { 'Bei unversandten Nachrichten leider nicht moeglich.' }
  2050. else begin
  2051. dbReadN(mbase,mb_typ,c);
  2052. dbReadN(mbase,mb_flags,flags);
  2053. if (c='T') and ((flags and 4)<>0) then c:='M';
  2054. case c of
  2055. 'T': c:='B';
  2056. 'B': c:='M';
  2057. else c:='T';
  2058. end;
  2059. if c='M' then flags := flags or 4 else
  2060. flags := flags and not 4;
  2061. if c='M' then c:='T';
  2062. dbWriteN(mbase,mb_flags,flags);
  2063. dbWriteN(mbase,mb_typ,c);
  2064. aufbau:=true;
  2065. end;
  2066. end;
  2067. procedure ModiGelesen; {Nachricht-Gelesen status aendern}
  2068. var b : byte;
  2069. brett : string;
  2070. begin
  2071. if not dbBOF(mbase) then
  2072. begin {Nur Wenn ueberhaupt ne Nachricht gewaehlt ist...}
  2073. dbReadN(mbase,mb_gelesen,b);
  2074. if b=1 then b:=0 else b:=1;
  2075. dbWriteN(mbase,mb_gelesen,b);
  2076. Brett := dbReadNStr(mbase,mb_brett);
  2077. if b=1 then begin
  2078. dbSeek(mbase,miGelesen,brett+#0);
  2079. if dbEOF(mbase) or (dbReadStrN(mbase,mb_brett)<>brett) or (dbReadInt(mbase,'gelesen')<>0)
  2080. then b:=0 { keine ungelesenen Nachrichten mehr im Brett vorhanden }
  2081. else b:=2;
  2082. end
  2083. else
  2084. b:=2; { noch ungelesene Nachrichten im Brett vorhanden }
  2085. dbSeek(bbase,biIntnr,mid(brett,2));
  2086. if dbFound then begin
  2087. b:=dbReadInt(bbase,'flags') and (not 2) + b;
  2088. dbWriteN(bbase,bb_flags,b);
  2089. end;
  2090. aufbau:=true;
  2091. end;
  2092. end;
  2093. { Brettliste importieren }
  2094. procedure ImportBrettliste;
  2095. var fn : string;
  2096. s : string;
  2097. t : text;
  2098. x,y : Integer;
  2099. n : longint;
  2100. useclip: boolean;
  2101. begin
  2102. fn:= WildCard;
  2103. useclip:=true;
  2104. if ReadFilename(getres2(456,1),fn,true,useclip) then { 'Brettliste einlesen' }
  2105. if not FileExists(fn) then
  2106. fehler(getres2(456,2)) { 'Datei nicht vorhanden!' }
  2107. else begin
  2108. msgbox(30,5,'',x,y);
  2109. wrt(x+3,y+2,getres2(456,3)); { 'Bretter anlegen ...' }
  2110. n:=0;
  2111. assign(t,fn);
  2112. reset(t);
  2113. while not eof(t) do
  2114. begin
  2115. readln(t,s);
  2116. makebrett(s,n,DefaultBox,ntBoxNetztyp(DefaultBox),true);
  2117. Wrt(x+22,y+2, Format('%5d', [n]));
  2118. end;
  2119. close(t);
  2120. closebox;
  2121. aufbau:=true;
  2122. dbFlushClose(bbase);
  2123. if useclip then _era(fn);
  2124. end;
  2125. freeres;
  2126. end;
  2127. { Userliste importieren }
  2128. procedure ImportUserliste;
  2129. var fn : string;
  2130. adrb: boolean;
  2131. brk : boolean;
  2132. s : string;
  2133. t : text;
  2134. x,y : Integer;
  2135. n : longint;
  2136. useclip: boolean;
  2137. b : byte;
  2138. begin
  2139. fn:= WildCard;
  2140. useclip:=true;
  2141. if ReadFilename(getres2(456,11),fn,true,useclip) then { 'Userliste einlesen' }
  2142. if not FileExists(fn) then
  2143. fehler(getres2(456,2)) { 'Datei nicht vorhanden!' }
  2144. else begin
  2145. dialog(38,3,'',x,y);
  2146. adrb:=true;
  2147. maddbool(3,2,getres2(456,12),adrb); { 'User in Adressbuch eintragen' }
  2148. readmask(brk);
  2149. enddialog;
  2150. if brk then exit;
  2151. msgbox(34,5,'',x,y);
  2152. wrt(x+3,y+2,getres2(456,13)); { 'Userbretter anlegen ...' }
  2153. n:=0;
  2154. assign(t,fn);
  2155. reset(t);
  2156. b:=0;
  2157. while not eof(t) do begin
  2158. readln(t,s);
  2159. s:=trim(s);
  2160. if cpos('@',s)>0 then begin
  2161. dbSeek(ubase,uiName,UpperCase(s));
  2162. if not dbFound then begin
  2163. inc(n);
  2164. AddNewUser(s,DefaultBox);
  2165. if not adrb then dbWriteN(ubase,ub_adrbuch,b);
  2166. Wrt(x+26, y+2, Format('%5d', [n]));
  2167. end;
  2168. end;
  2169. end;
  2170. close(t);
  2171. wkey(1,false);
  2172. closebox;
  2173. aufbau:=true;
  2174. dbFlushClose(ubase);
  2175. if useclip then _era(fn);
  2176. end;
  2177. freeres;
  2178. end;
  2179. { User-/Brettliste exportieren }
  2180. { These "functions" are used as testfunc.
  2181. What should be the default result?
  2182. }
  2183. function Bool_BrettGruppe(var s:string):boolean;
  2184. begin
  2185. Result := s<>_jn_[2];
  2186. if Result then
  2187. setfield(2,_jn_[2]);
  2188. end;
  2189. function Bool_Brettindex(var s:string):boolean;
  2190. begin
  2191. Result := s<>_jn_[2];
  2192. if Result then
  2193. setfield(1,_jn_[2]);
  2194. end;
  2195. procedure ExportUB(user:boolean);
  2196. var fname : String;
  2197. t : text;
  2198. d : DB;
  2199. x,y,xx : Integer;
  2200. cnt,n : longint;
  2201. exkom : boolean;
  2202. brk : boolean;
  2203. useclip : boolean;
  2204. onlyadress : boolean;
  2205. sortadress : boolean;
  2206. sortbox : boolean;
  2207. sort : byte;
  2208. ab,ab1 : longint;
  2209. dbindex : xpWord;
  2210. s : string[80];
  2211. sa,sa1 : string [20];
  2212. label ende;
  2213. function komform(d:DB; s:string):string;
  2214. var kom : string;
  2215. begin
  2216. kom:= dbReadStr(d,'kommentar');
  2217. if exkom and (kom<>'') then
  2218. komform:=forms(s,80)+kom
  2219. else
  2220. komform:=s;
  2221. end;
  2222. procedure getbrettinfos;
  2223. var x1,y1 : Integer;
  2224. begin
  2225. sortadress:=false; sortbox:=Usersortbox; exkom:=falsE;
  2226. dialog(50,5,getres2(457,2),x1,y1); { 'Brettliste erzeugen' }
  2227. maddbool(2,2,getres2(457,7),SortAdress); { 'nach Gruppen sortieren'}
  2228. MSet1Func(bool_brettgruppe);
  2229. maddbool(2,3,getres2(457,10),SortBox); { 'Sortierung aus Brettuebersicht beibehalten'}
  2230. MSet1Func(bool_brettindex);
  2231. maddbool(2,5,getres2(457,4),exkom); { 'auch Kommentare exportieren' }
  2232. readmask(brk);
  2233. enddialog;
  2234. end;
  2235. procedure getuserinfos;
  2236. var x1,y1 : Integer;
  2237. begin
  2238. sortadress:=true; sortbox:=Usersortbox; Onlyadress:=true; exkom:=falsE;
  2239. dialog(43,6,getres2(457,1),x1,y1); { 'Userliste erzeugen' }
  2240. maddbool(2,2,getres2(457,7),SortAdress); { 'nach Adressbuchgruppen sortieren'}
  2241. maddbool(2,3,getres2(457,8),SortBox); { 'nach Serverbox sortieren'}
  2242. maddbool(2,4,getres2(457,9),OnlyAdress); { 'Nur User im Adressbuch exportieren' }
  2243. maddbool(2,6,getres2(457,4),exkom); { 'auch Kommentare exportieren' }
  2244. readmask(brk);
  2245. enddialog;
  2246. end;
  2247. begin
  2248. fname:='';
  2249. useclip:=true;
  2250. if ReadFilename(getres2(457,iif(user,1,2)),fname,true,useclip)
  2251. then
  2252. if not ValidFileName(fname) then
  2253. fehler(getres2(457,3)) { 'ungueltiger Dateiname' }
  2254. else begin
  2255. if user then getuserinfos
  2256. else getbrettinfos;
  2257. if brk then begin
  2258. if useclip then _era(fname);
  2259. goto ende;
  2260. end;
  2261. sort:=0;
  2262. if sortadress then sort:=sort or 2;
  2263. if sortbox then sort:=sort or 1;
  2264. if user then begin
  2265. dbindex:=dbgetindex(ubase);
  2266. case Sort of
  2267. 1 : dbSetIndex(ubase,uiBoxName);
  2268. 2 : dbSetIndex(ubase,uiAdrbuch);
  2269. 3 : dbSetIndex(ubase,uiBoxAdrbuch);
  2270. else dbSetIndex(ubase,uiName);
  2271. end;
  2272. d:=ubase;
  2273. dbGoTop(ubase);
  2274. end
  2275. else begin
  2276. dbindex:=dbgetindex(mbase);
  2277. case sort of
  2278. 2 : begin
  2279. dbsetindex(bbase,biGruppe);
  2280. dbgotop(bbase);
  2281. end;
  2282. 1 : begin
  2283. dbsetindex(bbase,biIndex);
  2284. dbgotop(bbase);
  2285. end;
  2286. else begin
  2287. dbsetindex(bbase,biBrett);
  2288. dbSeek(bbase,biBrett,'A');
  2289. end;
  2290. end;
  2291. d:=bbase;
  2292. end;
  2293. msgbox(34,5,'',x,y);
  2294. wrt(x+3,y+2,getres2(457,iif(user,5,6))); { 'erzeuge User/Brettliste... %' }
  2295. xx:=wherex-5;
  2296. if not multipos(':\',fname) then fname:=ExtractPath+fname;
  2297. assign(t,fname);
  2298. rewrite(t);
  2299. cnt:=dbRecCount(d); n:=0; ab1:=-1; sa1:='';
  2300. while not dbEOF(d) do
  2301. begin
  2302. attrtxt(col.colmboxhigh);
  2303. Wrt(xx, y+2, Format('%3d', [n*100 div cnt]));
  2304. if user then
  2305. begin
  2306. s:=dbReadStrN(ubase,ub_username);
  2307. ab:=dbreadint(ubase,'adrbuch');
  2308. sa:=dbReadStrN(ubase,ub_pollbox);
  2309. if (dbReadInt(ubase,'userflags') and 4=0) AND { keine Verteiler }
  2310. (LeftStr(s,4)<>#0+'$/T') AND { keine Trennzeile }
  2311. not (onlyadress and (ab=0)) { Evtl. nur Adressbuch-User }
  2312. then begin
  2313. if sortadress and (ab<>ab1) then begin
  2314. ab1:=ab;
  2315. writeln(t,sp(60),'('+Getres2(2715,11),ab,')'); {Gruppe}
  2316. end;
  2317. if (sort=1) and (sa<>sa1) then begin
  2318. sa1:=sa;
  2319. writeln(t,sp(60),sa);
  2320. end;
  2321. writeln(t,komform(ubase,s))
  2322. end
  2323. end
  2324. else begin
  2325. if sort=2 then ab:=dbreadint(bbase,'gruppe')
  2326. else ab:=-1;
  2327. s:=dbReadStrN(bbase,bb_brettname);
  2328. if LeftStr(s,3)='$/T' { keine Trennzeile }
  2329. then begin
  2330. if sort=1 then writeln(t,dup(40,s[4]));
  2331. end
  2332. else begin
  2333. if ab1<>ab then begin
  2334. ab1:=ab;
  2335. writeln(t,sp(60),'('+Getres2(2715,11),ab,')'); {Gruppe}
  2336. end;
  2337. writeln(t,komform(bbase,copy(s,2,80)));
  2338. end;
  2339. end;
  2340. dbNext(d);
  2341. inc(n);
  2342. end;
  2343. close(t);
  2344. dbsetindex(d,dbindex);
  2345. if useclip then WriteClipfile(fname);
  2346. closebox;
  2347. end;
  2348. ende:
  2349. freeres;
  2350. end;
  2351. // N/U/Z
  2352. procedure zeige_unversandt;
  2353. var _brett : string;
  2354. _mbrett : string;
  2355. sr : tsearchrec;
  2356. rc : integer;
  2357. f : file;
  2358. hdp : Theader;
  2359. hds : longint;
  2360. ok : boolean;
  2361. adr,fsize: longint;
  2362. box : string;
  2363. uvf : boolean;
  2364. uvs : byte;
  2365. mtyp : char;
  2366. ntyp : longint;
  2367. zconnect : boolean;
  2368. crashs : boolean;
  2369. i : integer;
  2370. begin
  2371. if uvs_active then exit;
  2372. crashs:=false;
  2373. // temporary debug log
  2374. Debug.DebugLog('xp4o','Searching for '+GetCurrentDir+'/*'+extBoxFile,dlDebug);
  2375. rc:= findfirst('*'+extBoxFile,faArchive,sr);
  2376. if rc<>0 then
  2377. begin
  2378. FindClose(sr);
  2379. rc:= findfirst('*.cp',faArchive,sr);
  2380. crashs:=true;
  2381. end;
  2382. Marked.Clear;
  2383. moment;
  2384. hdp := THeader.Create;
  2385. while rc=0 do begin
  2386. if crashs then begin
  2387. box:=strs(hexval(LeftStr(sr.name,4)))+'/'+strs(hexval(copy(sr.name,5,4)));
  2388. { ^^^ nur fuer Anzeige bei fehlerhaftem CP }
  2389. zconnect:=true;
  2390. end
  2391. else begin
  2392. box:=file_box(LeftStr(sr.name,cPos('.',sr.name)-1));
  2393. zconnect:=ntZConnect(ntBoxNetztyp(box));
  2394. end;
  2395. dbSetIndex(mbase,miBrett);
  2396. assign(f,ownpath+sr.name);
  2397. reset(f,1);
  2398. adr:=0;
  2399. fsize:=filesize(f);
  2400. ok:=true;
  2401. while ok and (adr<fsize) do begin
  2402. seek(f,adr);
  2403. makeheader(zconnect,f,1,hds,hdp,ok,false, true);
  2404. if not ok then
  2405. rfehler1(427,box) { 'fehlerhaftes Pollpaket: %s' }
  2406. else with hdp do
  2407. begin
  2408. _brett:='';
  2409. for i := 0 to hdp.Empfaenger.Count-1 do
  2410. begin
  2411. _mbrett := Addr2DB(hdp.Empfaenger[i]);
  2412. if (cpos('@',_mbrett)=0) and
  2413. ((netztyp<>nt_Netcall) or (FirstChar(_mbrett)='/'))
  2414. then begin
  2415. dbSeek(bbase,biBrett,'A'+UpperCase(_mbrett));
  2416. if not dbFound then continue
  2417. else _brett:='A'+dbLongStr(dbReadInt(bbase,'int_nr'));
  2418. break;
  2419. end
  2420. else begin
  2421. dbSeek(ubase,uiName,UpperCase(_mbrett+
  2422. iifs(cPos('@',_mbrett)>0,'','@'+box+'.ZER')));
  2423. if not dbFound then continue
  2424. else _brett:='U'+dbLongStr(dbReadInt(ubase,'int_nr'));
  2425. break;
  2426. end;
  2427. end;
  2428. if _brett='' then
  2429. begin
  2430. dbSeek(bbase,biBrett,'$/'#$AF'NIX');
  2431. if dbFound then _brett:='$'+dbLongStr(dbReadInt(bbase,'int_nr'));
  2432. end;
  2433. uvf:=false;
  2434. if _brett<>'' then
  2435. begin
  2436. dbSeek(mbase,miBrett,_brett+#255);
  2437. if dbEOF(mbase) then dbGoEnd(mbase)
  2438. else dbSkip(mbase,-1);
  2439. if not dbEOF(mbase) and not dbBOF(mbase) then
  2440. repeat
  2441. _MBrett := dbReadNStr(mbase,mb_brett);
  2442. if _mbrett=_brett then begin
  2443. dbReadN(mbase,mb_unversandt,uvs);
  2444. dbReadN(mbase,mb_typ,mtyp);
  2445. dbReadN(mbase,mb_netztyp,ntyp);
  2446. if (uvs and 1=1) and EQ_betreff(betreff) and ((mtyp='B') or
  2447. ((uvs and 4 <> 0) or (ntyp and $4000<>0) or { codiert / signiert }
  2448. (groesse=dbReadInt(mbase,'groesse'))))
  2449. and (FormMsgid(msgid)=dbReadStrN(mbase,mb_msgid))
  2450. and not msgmarked then
  2451. begin
  2452. MsgAddmark;
  2453. uvf:=true;
  2454. end;
  2455. end;
  2456. dbSkip(mbase,-1);
  2457. until uvf or dbBOF(mbase) or (_brett<>_mbrett);
  2458. end;
  2459. if not uvf then
  2460. rfehler(426); { 'Nachricht ist nicht mehr in der Datenbank vorhanden!' }
  2461. inc(adr,groesse+hds);
  2462. end; // with hdp
  2463. end; // while ok and (adr<fsize)
  2464. close(f);
  2465. rc:= findnext(sr);
  2466. if (rc<>0) and not crashs then
  2467. begin
  2468. FindClose(sr);
  2469. rc:= findfirst('*.cp',faArchive,sr);
  2470. crashs:=true;
  2471. end;
  2472. end;
  2473. FindClose(sr);
  2474. Hdp.Free;
  2475. closebox;
  2476. if Marked.Count = 0 then
  2477. hinweis(getres(458)) { 'Keine unversandten Nachrichten vorhanden!' }
  2478. else begin
  2479. MarkUnversandt:=true;
  2480. uvs_active:=true;
  2481. select(11);
  2482. uvs_active:=false;
  2483. end;
  2484. aufbau:=true;
  2485. end;
  2486. procedure msg_info; { Zerberus-Header anzeigen }
  2487. var hdp : Theader;
  2488. hds : longint;
  2489. i : integer;
  2490. x,y : Integer;
  2491. dat : datetimest;
  2492. anz : byte;
  2493. xxs : array[1..20] of string;
  2494. netz : string;
  2495. p : byte;
  2496. elist : boolean; { mehrere Empfaenger }
  2497. rlist : boolean; { mehrere References }
  2498. spami : boolean; { hat SPAM-Informationen }
  2499. t : taste;
  2500. s : atext;
  2501. procedure apps(nr:xpWord; s:string);
  2502. begin
  2503. inc(anz);
  2504. xxs[anz]:=getres2(459,nr)+' '+LeftStr(s,53);
  2505. end;
  2506. function ddat:string;
  2507. begin
  2508. with hdp do
  2509. if ddatum='' then
  2510. ddat:=''
  2511. else
  2512. ddat:=', '+copy(ddatum,7,2)+'.'+copy(ddatum,5,2)+'.'+LeftStr(ddatum,4)+
  2513. ', '+copy(ddatum,9,2)+':'+copy(ddatum,11,2)+':'+copy(ddatum,13,2);
  2514. end;
  2515. procedure empfliste; { Fenster mit Empfaengerliste }
  2516. var ml : byte;
  2517. i,j : integer;
  2518. x,y : Integer;
  2519. begin
  2520. ml:=length(getres2(459,30))+8;
  2521. with hdp do begin
  2522. for i:=1 to Empfaenger.Count do
  2523. begin
  2524. ReadHeadEmpf:=i;
  2525. ReadHeader(hdp,hds,false);
  2526. ml:=max(ml,length(Firstempfaenger)+6);
  2527. end;
  2528. ml:=min(ml,72);
  2529. i:=min(Empfaenger.Count,screenlines-8);
  2530. msgbox(ml,i+4,getres2(459,30),x,y); { 'Empfaengerliste' }
  2531. for j:=1 to i do begin
  2532. ReadHeadEmpf:=j;
  2533. ReadHeader(hdp,hds,false);
  2534. mwrt(x+3,y+1+j,LeftStr(Firstempfaenger,72));
  2535. end;
  2536. wait(curoff);
  2537. if rlist and (UpperCase(lastkey)='R') then keyboard('R');
  2538. {$IFDEF Debug}
  2539. if (UpperCase(lastkey)='D') then keyboard('D');
  2540. {$ENDIF}
  2541. closebox;
  2542. end;
  2543. end;
  2544. procedure refliste; { Fenster mit Referenzliste }
  2545. var
  2546. ml, i: integer;
  2547. x, y: Integer;
  2548. begin
  2549. ml:=length(getres2(459,31))+8;
  2550. with hdp do
  2551. begin
  2552. for i := 0 to References.Count - 1 do
  2553. ml:=max(ml,length(References[i])+6);
  2554. ml:=min(ml,72);
  2555. i:=min(References.Count,screenlines-8);
  2556. msgbox(ml,i+4,getres2(459,31),x,y); { 'Empfaengerliste' }
  2557. for i := 0 to References.Count - 1 do
  2558. wrt(x+3,y+2+i,LeftStr(References[i],72));
  2559. wait(curoff);
  2560. if elist and (UpperCase(lastkey)='E') then keyboard('E');
  2561. {$IFDEF Debug}
  2562. if (UpperCase(lastkey)='D') then keyboard('D');
  2563. {$ENDIF}
  2564. closebox;
  2565. end;
  2566. end;
  2567. procedure spam_info;
  2568. var
  2569. i : integer;
  2570. x,y : Integer;
  2571. s : TRopeStream;
  2572. stat : TSpamStats;
  2573. begin
  2574. msgbox(34,5+
  2575. (High(stat.MostInteresting) - Low(stat.MostInteresting))+1+
  2576. (High(stat.LeastInteresting) - Low(stat.LeastInteresting))+1,
  2577. GetRes2(459,70),x,y);
  2578. s := TRopeStream.Create;
  2579. try
  2580. XReadS(0,s);
  2581. s.Seek(0,soFromBeginning);
  2582. calc_message_spamicity(s,stat);
  2583. finally
  2584. s.Free;
  2585. end;
  2586. inc(x,2);
  2587. inc(y);
  2588. wrt(x,y,Format(GetRes2(459,72),[Stat.Spamicity*100]));
  2589. inc(y,2);
  2590. for i:=Low(stat.MostInteresting) to High(stat.MostInteresting) do
  2591. begin
  2592. wrt(x,y,Format(GetRes2(459,73),[
  2593. stat.MostInteresting[i].Word,
  2594. stat.MostInteresting[i].GoodCount,
  2595. stat.MostInteresting[i].BadCount,
  2596. (1-stat.MostInteresting[i].Prob)*100]));
  2597. inc(y);
  2598. end;
  2599. inc(y,1);
  2600. for i:=Low(stat.LeastInteresting) to High(stat.LeastInteresting) do
  2601. begin
  2602. wrt(x,y,Format(GetRes2(459,73),[
  2603. stat.LeastInteresting[i].Word,
  2604. stat.LeastInteresting[i].GoodCount,
  2605. stat.LeastInteresting[i].BadCount,
  2606. (1-stat.LeastInteresting[i].Prob)*100]));
  2607. inc(y);
  2608. end;
  2609. wait(curoff);
  2610. closebox;
  2611. end;
  2612. {$IFDEF Debug}
  2613. procedure msgs_tuple; { Fenster mit Datenbankinfo }
  2614. var
  2615. x,y: Integer;
  2616. procedure _(id:integer;s:string);
  2617. begin
  2618. attrtxt(col.colmboxhigh); wrt(x,y,getres2(459,id)); { 'Empfangsdatum: ' }
  2619. attrtxt(col.colmbox); wrt(x+12,y,LeftStr(s,70-15));
  2620. inc(y);
  2621. end;
  2622. function brett(s:string):string;
  2623. var i: integer;
  2624. begin
  2625. case s[1] of
  2626. '$': result:=GetRes2(459,64);
  2627. '1': result:=GetRes2(459,65);
  2628. 'A': result:=GetRes2(459,66);
  2629. 'U': result:=GetRes2(459,66);
  2630. else result:=' ('+hex(Ord(s[1]),2)+')';
  2631. end;
  2632. for i:= 5 downto 2 do
  2633. result := Hex(Ord(s[i]),2)+result;
  2634. end;
  2635. begin
  2636. msgbox(70,23,getres2(459,32),x,y); { 'Empfaengerliste' }
  2637. inc(x,2); inc(y,2);
  2638. _(40,brett(dbReadStrN(mbase,mb_brett))); { 'Brett-Nr. :' }
  2639. _(41,dbReadStrN(mbase,mb_betreff)); { 'Betreff :' }
  2640. _(42,dbReadStrN(mbase,mb_absender)); { 'Absender :' }
  2641. _(43,StrS(dbReadIntN(mbase,mb_origdatum))); { 'OrigDatum :' }
  2642. _(44,StrS(dbReadIntN(mbase,mb_empfdatum))); { 'EmpfDatum :' }
  2643. _(45,StrS(dbReadIntN(mbase,mb_groesse))); { 'Groesse :' }
  2644. _(46,Chr(dbReadIntN(mbase,mb_typ))); { 'Typ :' }
  2645. _(47,StrS(dbReadIntN(mbase,mb_HalteFlags)));{ 'HalteFlags:' }
  2646. _(48,StrS(dbReadIntN(mbase,mb_gelesen))); { 'gelesen :' }
  2647. _(49,hex(dbReadIntN(mbase,mb_unversandt),4));{'unversandt:' }
  2648. _(50,StrS(dbReadIntN(mbase,mb_ablage))); { 'Ablage :' }
  2649. _(51,StrS(dbReadIntN(mbase,mb_adresse))); { 'Adresse :' }
  2650. _(52,StrS(dbReadIntN(mbase,mb_MsgSize))); { 'MsgSize :' }
  2651. _(53,StrS(dbReadIntN(mbase,mb_WVdatum))); { 'WVdatum :' }
  2652. _(54,dbReadStrN(mbase,mb_MsgID)); { 'MsgID :' }
  2653. _(55,hex(dbReadIntN(mbase,mb_netztyp),4)); { 'Netztyp :' }
  2654. _(57,dbReadStrN(mbase,mb_Name)); { 'Name :' }
  2655. _(58,hex(dbReadIntN(mbase,mb_flags),4)); { 'Flags :' }
  2656. _(59,dbReadStrN(mbase,mb_MimeTyp)); { 'Mimetyp :' }
  2657. wait(curoff);
  2658. if rlist and (UpperCase(lastkey)='R') then keyboard('R');
  2659. if elist and (UpperCase(lastkey)='E') then keyboard('E');
  2660. closebox;
  2661. end;
  2662. {$ENDIF}
  2663. function typstr(typ,mimetyp:string):string;
  2664. begin
  2665. if mimetyp<>'' then
  2666. typstr:=extmimetyp(mimetyp)
  2667. else begin
  2668. UpString(typ);
  2669. if typ='T' then typstr:=typ+getres2(459,1) else { ' (Text)' }
  2670. if typ='B' then typstr:=typ+getres2(459,2) else { ' (binaer)' }
  2671. typstr:=typ;
  2672. end;
  2673. end;
  2674. begin
  2675. hdp := THeader.Create;
  2676. ReadHeader(hdp,hds,true);
  2677. anz:=0;
  2678. with hdp do begin
  2679. apps(3,Firstempfaenger);
  2680. if fido_to<>'' then apps(4,fido_to);
  2681. apps(5,betreff);
  2682. apps(6,LeftStr(absender,53));
  2683. if realname<>'' then apps(7,realname);
  2684. if organisation<>'' then apps(8,LeftStr(organisation,53));
  2685. // if Replyto <> '' then apps(9,LeftStr(replyto,53));
  2686. apps(10,iifs(ntZDatum(netztyp),zdatum,datum)+
  2687. iifs(datum<>'',' ('+fdat(datum)+', '+ftime(datum)+
  2688. iifs(ntSec(netztyp),':'+copy(zdatum,13,2),'')+')',''));
  2689. apps(11,LeftStr(pfad,53));
  2690. repeat
  2691. pfad:=mid(pfad,54);
  2692. if pfad<>'' then apps(12,LeftStr(pfad,53));
  2693. until pfad='';
  2694. if msgid<>'' then apps(13,msgid);
  2695. if References.Count > 0 then apps(14, References[References.Count-1]);
  2696. if pm_bstat<>'' then apps(15,pm_bstat);
  2697. apps(16,typstr(typ,mime.contenttype.verb));
  2698. if programm<>'' then apps(17,programm);
  2699. if datei<>'' then apps(18,datei+ddat);
  2700. apps(19,strs(groesse)+getres(13));
  2701. if komlen>0 then apps(21,strs(komlen)+getres(13));
  2702. if attrib<>0 then
  2703. apps(22,hex(attrib,4)+' - '+
  2704. iifs(attrib and attrCrash<>0,'Crash ','')+
  2705. iifs(attrib and attrFile<>0,'File ','')+
  2706. iifs(attrib and attrReqEB<>0,'Req-EB ','')+
  2707. iifs(attrib and attrIsEB<>0,'EB ','')+
  2708. iifs(attrib and attrPmReply<>0,'PM-Reply ','')+
  2709. iifs(attrib and attrQuoteTo<>0,'QuoteTo ','')+
  2710. iifs(attrib and attrControl<>0,'Control ',''));
  2711. if netztyp in netsRFC then netz:=' / RFC'
  2712. else begin
  2713. netz:=ntName(netztyp);
  2714. if netz='???' then netz:=''
  2715. else netz:=' / '+netz;
  2716. end;
  2717. msgbox(70,anz+7,getres2(459,23)+' ('+ { 'Nachrichtenkopf' }
  2718. getres2(459,iif(ntZConnect(netztyp),24,25))+netz+')',x,y);
  2719. moff;
  2720. for i:=1 to anz do begin
  2721. if FirstChar(xxs[i])=' ' then p:=0
  2722. else p:=cpos(':',xxs[i]);
  2723. if p>0 then begin
  2724. attrtxt(col.colmboxhigh);
  2725. wrt(x+3,y+i+1,LeftStr(xxs[i],p));
  2726. end;
  2727. attrtxt(col.colmbox);
  2728. wrt(x+3+p,y+i+1,mid(xxs[i],p+1));
  2729. end;
  2730. attrtxt(col.colmboxhigh); wrt(x+3,y+anz+3,getres2(459,26)); { 'Groesse des Kopfes: ' }
  2731. attrtxt(col.colmbox); wrt(x+3+length(getres2(459,26)),y+anz+3,IntToStr(hds)+getres(13));
  2732. dat:=longdat(dbReadInt(mbase,'empfdatum'));
  2733. if smdl(IxDat('2712300000'),IxDat(dat)) then
  2734. dat:=longdat(dbReadInt(mbase,'wvdatum'));
  2735. attrtxt(col.colmboxhigh); wrt(x+40,y+anz+2,getres2(459,27)); { 'Empfangsdatum: ' }
  2736. attrtxt(col.colmbox); wrt(x+40+length(getres2(459,27)),y+anz+2,fdat(dat));
  2737. attrtxt(col.colmboxhigh); wrt(x+40,y+anz+3,getres2(459,28)); { 'Ablagedatei :' }
  2738. attrtxt(col.colmbox); wrt(x+40+length(getres2(459,28)),y+anz+3,
  2739. FileUpperCase('mpuffer.')+IntToStr(dbReadInt(mbase,'ablage')));
  2740. elist:=(Empfaenger.Count>1);
  2741. rlist:=(References.Count>1);
  2742. spami:=(FirstChar(dbReadStrN(mbase,mb_brett)) in ['1']) or
  2743. (dbReadStrN(bbase,bb_brettname) = '$/ŻSpam');
  2744. if elist then s:=' (E='+getres2(459,30)
  2745. else s:='';
  2746. if rlist then begin
  2747. if s<>'' then s:=s+', '
  2748. else s:=' (';
  2749. s:=s+'R='+getres2(459,31);
  2750. end;
  2751. if spami then begin
  2752. if s<>'' then s:=s+', '
  2753. else s:=' (';
  2754. s:=s+'S='+GetRes2(459,70);
  2755. end;
  2756. {$IFDEF Debug}
  2757. if s<>'' then s:=s+', '
  2758. else s:=' (';
  2759. s:=s+'D='+getres2(459,32);
  2760. {$ENDIF}
  2761. if s<>'' then s:=s+')';
  2762. wrt(x+3,y+anz+5,getres2(459,29)+s+' ...'); { Taste druecken / E=Empfaengerliste / R=Referenzliste }
  2763. mon;
  2764. x:=wherex; y:=wherey;
  2765. repeat
  2766. gotoxy(x,y);
  2767. repeat
  2768. get(t,curon);
  2769. until (t<mausfirstkey) or (t>mauslastkey) or (t=mausleft) or (t=mausright);
  2770. if elist and (UpperCase(t)='E') then empfliste;
  2771. if rlist and (UpperCase(t)='R') then refliste;
  2772. if spami and (UpperCase(t)='S') then spam_info;
  2773. {$IFDEF Debug}
  2774. if (UpperCase(t)='D') then msgs_tuple;
  2775. {$ENDIF}
  2776. until {$IFDEF Debug} (UpperCase(t)<>'D') and {$ENDIF}
  2777. (not elist or (UpperCase(t)<>'E')) and (not rlist or (UpperCase(t)<>'R'));
  2778. end;
  2779. closebox;
  2780. freeres;
  2781. Hdp.Free;
  2782. end;
  2783. procedure ShowHeader; { Header direkt so anzeigen wie er im PUFFER steht }
  2784. var fn : string;
  2785. f : file;
  2786. hdp : Theader;
  2787. hds : longint;
  2788. lm : Byte; { Makrozwischenspeicher... }
  2789. begin
  2790. hdp := THeader.Create;
  2791. ReadHeader(hdp,hds,true);
  2792. if hds>1 then begin
  2793. fn:=TempS(dbReadInt(mbase,'msgsize')+1000);
  2794. assign(f,fn);
  2795. rewrite(f,1);
  2796. XreadF(0,f);
  2797. seek(f,hds);
  2798. truncate(f);
  2799. close(f);
  2800. lm:=listmakros; { Aktuelle Makros merken, }
  2801. listmakros:=16; { Archivviewermakros aktivieren }
  2802. ListFile(fn,getres(460),true,false,false,0); { 'Nachrichten-Header' }
  2803. listmakros:=lm; { wieder alte Makros benutzen }
  2804. _era(fn);
  2805. end;
  2806. Hdp.Free;
  2807. end;
  2808. { Es wird nicht im Temp-, sondern im XP-Verzeichnis entpackt! }
  2809. { exdir='' -> Lister/ArcViewer; exdir<>'' -> Xtrakt }
  2810. { Fehler -> exdir:='' }
  2811. procedure ShowArch(const fn:string);
  2812. var decomp : string;
  2813. p : byte;
  2814. datei : string;
  2815. newarc : longint;
  2816. atyp : shortint;
  2817. spath : string;
  2818. ats : shortint;
  2819. MessageViewer: TMessageViewer;
  2820. begin
  2821. MessageViewer := TMessageViewer.Create;
  2822. ats:=arctyp_save;
  2823. atyp:=abuf[arcbufp].arcer_typ;
  2824. if atyp>arctypes then exit; { ??? }
  2825. if not getDecomp(atyp,decomp) then
  2826. exdir:=''
  2827. else begin
  2828. p:=pos('$DATEI',UpperCase(decomp));
  2829. datei:=trim(mid(fn, 80));
  2830. if (exdir='') and ((temppath='') or (UpperCase(temppath)=ownpath))
  2831. and FileExists(datei) then begin
  2832. rfehler(428); { 'extrahieren nicht moeglich - bitte Temp-Verzeichnis angeben!' }
  2833. exit;
  2834. end
  2835. else if ((exdir<>'') and FileExists(exdir+datei)) or
  2836. ((exdir='') and FileExists(temppath+datei)) then
  2837. if exdir=ownpath then begin
  2838. rfehler(429); { 'Datei schon vorhanden - bitte Extrakt-Verzeichnis angeben!' }
  2839. exit;
  2840. end
  2841. else
  2842. if not ReadJN(getreps(461,fitpath(exdir+datei,40)),false) { '%s existiert schon. ueberschreiben' }
  2843. then exit
  2844. else
  2845. _era(iifs(exdir<>'',exdir,temppath)+datei);
  2846. spath:=ShellPath;
  2847. if exdir<>'' then SetCurrentDir(exdir)
  2848. else SetCurrentDir(temppath);
  2849. decomp:=copy(decomp,1,p-1)+datei+copy(decomp,p+6,127);
  2850. p:=pos('$ARCHIV',UpperCase(decomp));
  2851. decomp:=copy(decomp,1,p-1)+'"'+abuf[arcbufp].arcname+'" "' + copy(decomp,p+8,127)+'"';
  2852. shell(decomp,400,3);
  2853. if exdir='' then begin
  2854. { !?! GoDir(temppath); } { wurde durch Shell zurueckgesetzt }
  2855. if not FileExists(temppath+datei) then
  2856. rfehler(430) { 'Datei wurde nicht korrekt entpackt.' }
  2857. else begin
  2858. newarc:=ArcType(TempPath+datei);
  2859. if ArcRestricted(newarc) then newarc:=0;
  2860. if newarc=0 then
  2861. begin
  2862. MessageViewer.GetFromExtension(ExtractFileExt(datei));
  2863. // if MessageViewer.IsInternal then TestGifLbmEtc(datei,false,viewer);
  2864. if MessageViewer.IsInternal then
  2865. ListFile(TempPath+datei,datei,true,false,false,0)
  2866. else
  2867. MessageViewer.ViewFile(TempPath+datei,false);
  2868. end
  2869. else
  2870. if arcbufp=max_arc then
  2871. rfehler(432) { 'Maximal 3 verschachtelte Archive moeglich!' }
  2872. else begin
  2873. decomp:=TempPath+datei; { Stack sparen ... }
  2874. if ViewArchive(decomp,newarc)<>0 then;
  2875. end;
  2876. SafeDeleteFile(temppath+datei);
  2877. end;
  2878. { GoDir(OwnPath); }
  2879. end;
  2880. ShellPath:=spath;
  2881. end;
  2882. arctyp_save:=ats;
  2883. attrtxt(col.colarcstat);
  2884. wrt(77,4,arcname[ats]);
  2885. keyboard(keydown);
  2886. MessageViewer.Free;
  2887. end;
  2888. function a_getfilename(nr,nn:byte):string;
  2889. var fn : string;
  2890. sex : string;
  2891. begin
  2892. //!! fn:=trim(copy(get_selection,2,12));
  2893. sex:=exdir; exdir:=TempPath;
  2894. ShowArch(fn);
  2895. exdir:=sex;
  2896. a_getfilename:=TempPath+fn;
  2897. end;
  2898. procedure ArcSpecial(LSelf: TLister; var t:taste);
  2899. var s : string;
  2900. dp : string;
  2901. x,y : Integer;
  2902. brk : boolean;
  2903. fk : string;
  2904. sex : string;
  2905. dd : string;
  2906. begin
  2907. if UpperCase(t)='X' then begin
  2908. dp:=ExtractPath;
  2909. dd:=getres(463);
  2910. dialog(47+length(dd),3,getres(462),x,y); { 'Extrakt' }
  2911. maddstring(3,2,dd,dp,40,79,'');
  2912. readmask(brk);
  2913. enddialog;
  2914. if brk then exit;
  2915. UpString(dp);
  2916. dp := IncludeTrailingPathDelimiter(dp);
  2917. if not validfilename(dp+'test.$$1') then
  2918. rfehler(433) { 'ungueltiges Verzeichnis' }
  2919. else begin
  2920. sex:=exdir;
  2921. exdir:=dp;
  2922. s:=LSelf.FirstMarked;
  2923. while (s<>#0) and (exdir<>'') do begin
  2924. ShowArch(s);
  2925. s:=LSelf.NextMarked;
  2926. end;
  2927. exdir:=sex;
  2928. end;
  2929. end
  2930. else begin
  2931. getfilename:=a_getfilename;
  2932. fk:=clearkeybuf; //forwardkeys; forwardkeys:='';
  2933. if test_fkeys(t) then;
  2934. keyboard(fk);
  2935. xp1o.listext(LSelf, t);
  2936. end;
  2937. end;
  2938. { 0=Esc, 1=minus, 2=plus }
  2939. function ViewArchive(var fn:string; typ:shortint):shortint;
  2940. var
  2941. List: TLister;
  2942. ar : ArchRec;
  2943. lm : byte;
  2944. function dt(d,t:xpWord):string;
  2945. begin
  2946. dt:=formi(d and 31,2)+'.'+formi((d shr 5) and 15,2)+'.'+
  2947. formi((d shr 9+80)mod 100,2)+' '+
  2948. formi(t shr 11,2)+':'+formi((t shr 5)and $3f,2)+':'+formi((t and $1f)*2,2);
  2949. end;
  2950. function prozent:string;
  2951. begin
  2952. with ar do
  2953. if (OrgSize>0) and (OrgSize >= CompSize) then
  2954. prozent:=strsrn(ar.CompSize/ar.OrgSize*100.0,3,1)
  2955. else
  2956. prozent:=' ';
  2957. end;
  2958. procedure renameDWC;
  2959. var f : file;
  2960. begin
  2961. assign(f,fn);
  2962. fn:=ExtractFilePath(fn) +'temp$$.dwc';
  2963. rename(f,fn);
  2964. end;
  2965. begin
  2966. if abs(typ)=ArcDWC then
  2967. renameDWC;
  2968. List := TLister.CreateWithOptions(1,ScreenWidth,5,screenlines-fnkeylines-1,1,'/NS/SB/M/NLR/');
  2969. OpenArchive(fn,typ,ar);
  2970. List.OnEnter := ShowArch;
  2971. List.OnKeypressed := ArcSpecial;
  2972. showkeys(11);
  2973. attrtxt(col.colarcstat);
  2974. mwrt(1,4,forms(getres(464), ScreenWidth)); { ' Name OrgGroesse CompGroesse % Methode Datum Uhrzeit' }
  2975. inc(arcbufp);
  2976. with ar do begin
  2977. arctyp_save:=arctyp;
  2978. abuf[arcbufp].arcer_typ:=arctyp;
  2979. abuf[arcbufp].arcname:=fn;
  2980. mwrt(77,4,arcname[arctyp]);
  2981. while not ende do begin
  2982. if (name<>'') or (path='') then
  2983. List.AddLine(iifc(path<>'','*',' ')+forms(name,12)+strsn(orgsize,11)+
  2984. strsn(compsize,11)+' '+ prozent+' '+forms(method,10)+
  2985. dt(datum,uhrzeit)+' ' + name)
  2986. else
  2987. List.AddLine(forms('*'+path+name,80)+path+name);
  2988. ArcNext(ar);
  2989. end;
  2990. end;
  2991. CloseArchive(ar);
  2992. exdir:='';
  2993. llh:=true; listexit:=0;
  2994. lm:=ListMakros; ListMakros:=16;
  2995. pushhp(67);
  2996. List.Show;
  2997. pophp;
  2998. ListMakros:=lm;
  2999. dec(arcbufp);
  3000. List.Free;
  3001. attrtxt(col.colkeys);
  3002. mwrt(1,2,sp(ScreenWidth));
  3003. showlastkeys;
  3004. if abs(typ)=ArcDWC then
  3005. _era(fn);
  3006. aufbau:=true;
  3007. ViewArchive:=listexit;
  3008. end;
  3009. procedure FileArcViewer(fn:string);
  3010. var useclip : boolean;
  3011. arc : shortint;
  3012. lm : byte;
  3013. ende : boolean;
  3014. begin
  3015. if (fn='') or multipos('?*',fn) then begin
  3016. if fn='' then fn:=WildCard;
  3017. useclip:=false;
  3018. if not ReadFilename(getres(465),fn,true,useclip) then { 'Archivdatei' }
  3019. exit;
  3020. fn:=ExpandFileName(fn);
  3021. end;
  3022. if FileExists(fn) then begin
  3023. arc:=ArcType(fn);
  3024. if ArcRestricted(arc) then arc:=0;
  3025. if arc=0 then begin { Wenns kein Archiv war... }
  3026. lm:=listmakros;
  3027. listmakros:=16; { Archivviewermacros benutzen! }
  3028. repeat
  3029. if listfile(fn,fn,true,false,false, 0) = -4 then ende:=false
  3030. else ende:=true; { und File einfach nur anzeigen }
  3031. until ende;
  3032. listmakros:=lm;
  3033. end
  3034. { rfehler(434) } { 'keine Archivdatei' }
  3035. else
  3036. if ViewArchive(fn,arc)=0 then;
  3037. end
  3038. else
  3039. rfehler(22); { 'Datei ist nicht vorhanden!' }
  3040. end;
  3041. procedure DupeKill(autodupekill:boolean);
  3042. var d : DB;
  3043. f1,f2 : file;
  3044. n,ll : longint;
  3045. x,y : Integer;
  3046. last,
  3047. next : string;
  3048. flags : byte;
  3049. log : text;
  3050. rec,rec2 : longint;
  3051. brk: boolean;
  3052. procedure show;
  3053. begin
  3054. wrt(x+22,y+3,strsn(n,7));
  3055. wrt(x+22,y+4,strsn(ll,7));
  3056. end;
  3057. procedure log_it;
  3058. var _brett : string;
  3059. begin
  3060. _brett := dbReadStr(d,'brett');
  3061. write(log,fdat(longdat(dbReadInt(d,'origdatum'))),' ');
  3062. if FirstChar(_brett)='U' then
  3063. write(log,forms(dbReadStr(d,'absender'),32))
  3064. else begin
  3065. dbSeek(bbase,biIntnr,copy(_brett,2,4));
  3066. if dbFound then write(log,forms(copy(dbReadStrN(bbase,bb_brettname),2,40),32));
  3067. end;
  3068. writeln(log,' ',LeftStr(dbReadStr(d,'betreff'),37));
  3069. end;
  3070. begin
  3071. if diskfree(0)<_filesize(MsgFile+dbExt)*2 then begin
  3072. rfehler(435); { 'zu wenig Festplatten-Platz' }
  3073. exit;
  3074. end;
  3075. message(getres2(466,1)); { 'Nachrichtendatei kopieren...' }
  3076. dbTempClose(mbase);
  3077. assign(f1,MsgFile+dbExt); reset(f1,1);
  3078. assign(f2,DupeFile+dbExt); rewrite(f2,1);
  3079. fmove(f1,f2);
  3080. close(f1);
  3081. close(f2);
  3082. SafeDeleteFile(DupeFile+dbIxExt);
  3083. closebox;
  3084. dbOpen(d,DupeFile,1); { indizieren }
  3085. n:=1; ll:=0;
  3086. msgbox(32,8,getres2(466,2),x,y); { 'DupeKill' }
  3087. wrt(x+3,y+2,getres2(466,3)); { 'Nachrichten gesamt:' }
  3088. wrt(x+3,y+3,getres2(466,4)); { ' bearbeitet:' }
  3089. wrt(x+3,y+4,getres2(466,5)); { ' geloescht:' }
  3090. attrtxt(col.colmboxhigh);
  3091. wrt(x+22,y+2,strsn(dbRecCount(d),7));
  3092. assign(log,logpath+DupeLogfile);
  3093. if existf(log) then append(log)
  3094. else rewrite(log);
  3095. writeln(log,getres2(466,6)+date+getres2(466,7)+time); { 'DupeKill gestartet am ' / ' um ' }
  3096. last:='';
  3097. dbGoTop(d);
  3098. brk := false;
  3099. while not brk and not dbEOF(d) and (dbReadInt(d,'halteflags')=0) do
  3100. begin
  3101. show;
  3102. repeat
  3103. inc(n);
  3104. next:=dbReadStr(d,'brett')+dbLongStr(dbReadInt(d,'origdatum'))+dbReadStr(d,'msgid');
  3105. if (length(next)>10) and (next=last) and (dbReadInt(d,'unversandt') and 1=0)
  3106. then begin
  3107. dbRead(d,'HalteFlags',flags);
  3108. rec:=dbRecno(d);
  3109. dbSkip(d,1); rec2:=dbRecno(d);
  3110. dbGo(d,rec);
  3111. flags:=2;
  3112. dbWrite(d,'HalteFlags',flags);
  3113. log_it;
  3114. dbGo(d,rec2);
  3115. inc(ll);
  3116. end
  3117. else
  3118. dbSkip(d,1);
  3119. Testbrk(brk);
  3120. until (next<>last) or dbEOF(d);
  3121. last:=next;
  3122. end;
  3123. dbClose(d);
  3124. DeleteFile(MsgFile+dbExt);
  3125. assign(f1,DupeFile+dbExt); rename(f1,MsgFile+dbExt);
  3126. DeleteFile(DupeFile+dbIxExt);
  3127. writeln(log);
  3128. close(log);
  3129. dbTempOpen(mbase);
  3130. if not autodupekill then
  3131. begin
  3132. signal;
  3133. attrtxt(col.colmbox);
  3134. wrt(x+2,y+6,' '+getres(12){+' '#8});
  3135. wait(curon);
  3136. end;
  3137. closebox;
  3138. freeres;
  3139. aufbau:=true; xaufbau:=true;
  3140. end;
  3141. //Wartung/Komplett
  3142. procedure CompleteMaintenance;
  3143. var brk: boolean;
  3144. begin
  3145. if true and(not brk) then
  3146. DupeKill(true);
  3147. if true and(not brk) then
  3148. begin
  3149. MsgReorgScan(true,false,brk);
  3150. if not brk then
  3151. MsgReorg;
  3152. end;
  3153. if true and(not brk) then
  3154. PackAll(false);
  3155. if true and(not brk) then
  3156. BU_reorg(false,false,true);
  3157. if true and(not brk) then
  3158. BU_reorg(true,true,true);
  3159. if true and(not brk) then
  3160. BU_reorg(true,false,true);
  3161. aufbau := true;
  3162. end;
  3163. procedure print_msg(initpr:boolean);
  3164. var t : text;
  3165. fn : string;
  3166. s : string;
  3167. begin
  3168. if dbReadInt(mbase,'typ')=ord('B') then
  3169. rfehler(436) { 'Drucken nicht moeglich - Binaernachricht' }
  3170. else begin
  3171. fn:=TempS(dbReadInt(mbase,'groesse')+1000);
  3172. extract_msg(1,'',fn,false,1);
  3173. assign(t,fn);
  3174. if existf(t) then begin
  3175. if initpr then begin
  3176. rmessage(119);
  3177. initprinter;
  3178. end;
  3179. if checklst then begin
  3180. reset(t);
  3181. while not eof(t) do begin
  3182. readln(t,s);
  3183. printline(s);
  3184. end;
  3185. close(t);
  3186. erase(t);
  3187. end;
  3188. if initpr then begin
  3189. exitprinter;
  3190. mdelay(200);
  3191. closebox;
  3192. end;
  3193. end;
  3194. end;
  3195. end;
  3196. Procedure Brettmarksuche;
  3197. var x,y : Integer;
  3198. brk : boolean;
  3199. nn,n,nf : longint;
  3200. suchst, bname : string;
  3201. rec : longint;
  3202. m1,m2,j : longint;
  3203. found, found_not : boolean;
  3204. begin
  3205. SuchSt := '';
  3206. rec:=dbRecno(bbase);
  3207. if not Suche(getres2(467,5),'#','') then exit;
  3208. diabox(52,7,getres2(467,5),x,y); { 'Brett-(markier)-Suche' }
  3209. brk:=false;
  3210. m1:=maxlongint;
  3211. attrtxt(col.coldialog);
  3212. wrt(x+3,y+4,getres2(467,3)); { 'Suchen... % gefunden:' }
  3213. nn:=dbRecCount(bbase); n:=0; nf:=0;
  3214. dbGoTop(bbase);
  3215. attrtxt(col.coldiahigh);
  3216. while not dbEOF(bbase) and not brk do
  3217. begin
  3218. inc(n);
  3219. FWrt(x+13, y+4, Format('%3d', [n*100 div nn]));
  3220. FWrt(x+35, y+4, Format('%4d', [nf]));
  3221. bname := dbReadNStr(bbase,bb_brettname);
  3222. j:=0;
  3223. repeat
  3224. suchst:= LeftStr(copy(sst,seekstart[j],seeklen[j]),40);
  3225. found:=((igcase and (pos(suchst,UpperCase(bname))>0)) or
  3226. (not igcase and (pos(suchst,bname)>0)));
  3227. found_not:=found and seeknot[j];
  3228. if suchand and not found and seeknot[j] then found:=true;
  3229. inc(j);
  3230. until (j=suchanz) or (suchand xor found) or found_not;
  3231. if found_not then found:=false;
  3232. if found then
  3233. begin
  3234. UBAddmark(dbRecno(bbase));
  3235. dbreadN(bbase,bb_index,m2);
  3236. if m2<m1 then
  3237. begin
  3238. m1:=m2;
  3239. rec:=dbRecno(bbase);
  3240. end;
  3241. inc(nf);
  3242. end;
  3243. dbNext(bbase);
  3244. if n mod 16=0 then testbrk(brk);
  3245. end;
  3246. dbGo(bbase,rec);
  3247. aufbau:=true;
  3248. closebox;
  3249. if not brk and (nf=0) then fehler(getres2(467,6)); { 'keine passenden User gefunden' }
  3250. freeres;
  3251. end;
  3252. { Ausgabe true -> UserMode umschalten }
  3253. function UserMarkSuche(allmode:boolean):boolean;
  3254. var suchst : string;
  3255. var x,y : Integer;
  3256. brk : boolean;
  3257. nn,n,nf : longint;
  3258. uname,
  3259. sname : string;
  3260. rec : longint;
  3261. mi,j : shortint;
  3262. found, found_not : boolean;
  3263. begin
  3264. UserMarkSuche:=false;
  3265. rec:=dbRecno(ubase);
  3266. if not Suche(getres2(467,1),'#','') then exit;
  3267. diabox(52,7,getres2(467,1),x,y); { 'User-(markier)-Suche' }
  3268. brk:=false;
  3269. sname:=#255;
  3270. attrtxt(col.coldialog);
  3271. wrt(x+3,y+4,getres2(467,3)); { 'Suchen... % gefunden:' }
  3272. nn:=dbRecCount(ubase); n:=0; nf:=0;
  3273. mi:=dbGetIndex(ubase); dbSetIndex(ubase,0);
  3274. dbGoTop(ubase);
  3275. attrtxt(col.coldiahigh);
  3276. while not dbEOF(ubase) and not brk do begin
  3277. inc(n);
  3278. FWrt(x+13, y+4, Format('%3d', [n*100 div nn]));
  3279. FWrt(x+35, y+4, Format('%4d', [nf]));
  3280. UName := dbReadNStr(ubase,ub_username);
  3281. j:=0;
  3282. repeat
  3283. suchst:= LeftStr(copy(sst,seekstart[j],seeklen[j]),40);
  3284. found:=((igcase and (pos(suchst,UpperCase(uname))>0)) or
  3285. (not igcase and (pos(suchst,uname)>0)));
  3286. found_not:=found and seeknot[j];
  3287. if suchand and not found and seeknot[j] then found:=true;
  3288. inc(j);
  3289. until (j=suchanz) or (suchand xor found) or found_not;
  3290. if found_not then found:=false;
  3291. if found then begin
  3292. UBAddmark(dbRecno(ubase));
  3293. if not allmode and (dbReadInt(ubase,'adrbuch')=0) then
  3294. UserMarkSuche:=true;
  3295. if uname<sname then begin
  3296. sname:=uname;
  3297. rec:=dbRecno(ubase);
  3298. end;
  3299. inc(nf);
  3300. end;
  3301. dbNext(ubase);
  3302. if n mod 16=0 then testbrk(brk);
  3303. end;
  3304. dbSetIndex(ubase,mi);
  3305. dbGo(ubase,rec);
  3306. aufbau:=true;
  3307. closebox;
  3308. if not brk and (nf=0) then fehler(getres2(467,4)); { 'keine passenden User gefunden' }
  3309. freeres;
  3310. end;
  3311. procedure BrettInfo;
  3312. var i : longint;
  3313. x,y : Integer;
  3314. brk : boolean;
  3315. begin
  3316. dbReadN(bbase,bb_index,i);
  3317. message(getres(468)+': '+strs(i)); { 'Brettindex-Nr.' }
  3318. wait(curoff);
  3319. closebox;
  3320. if lastkey=' ' then begin
  3321. dialog(30,1,'',x,y);
  3322. maddint(3,1,getres(468)+' ',i,6,8,0,99999999);
  3323. readmask(brk);
  3324. enddialog;
  3325. if not brk then begin
  3326. dbWriteN(bbase,bb_index,i);
  3327. aufbau:=true;
  3328. end;
  3329. end;
  3330. end;
  3331. procedure NtInfo;
  3332. var mnt : eNetz; //longint;
  3333. nts : string;
  3334. begin
  3335. mnt := dbNetztyp(mbase); //dbReadN(mbase,mb_netztyp,mnt);
  3336. nts:=' ('+ntName(mnt)+')';
  3337. message(getres(469)+strs(ord(mnt))+nts); { 'Netztyp: ' }
  3338. wait(curoff);
  3339. closebox;
  3340. end;
  3341. procedure do_bseek(fwd:boolean);
  3342. begin
  3343. repeat
  3344. if fwd then dbSkip(bbase,1)
  3345. else dbSkip(bbase,-1);
  3346. until dbBOF(bbase) or dbEOF(bbase) or brettok(false);
  3347. end;
  3348. procedure FidoMsgRequest(var nnode:string);
  3349. var files : string;
  3350. ic,id,
  3351. k,p : byte;
  3352. p1,s,s1,t,u : string;
  3353. v : char;
  3354. node : string;
  3355. secondtry,
  3356. mark,
  3357. lMagics : boolean;
  3358. dir, name, ext: string;
  3359. begin
  3360. nnode := '';
  3361. if not LastLister.Selbar and (LastLister.SelCount=0) then begin
  3362. rfehler(438); { 'keine Dateien markiert' }
  3363. exit
  3364. end;
  3365. if not TestNodelist or not TestDefbox then exit;
  3366. s := FMsgReqnode;
  3367. p := cpos('.',s);
  3368. if (p>0) then node:=LeftStr(s,p-1)
  3369. else node:=s;
  3370. files := '';
  3371. u := ''; t := '';
  3372. lMagics := Magics;
  3373. secondtry:=false;
  3374. s := LastLister.FirstMarked;
  3375. repeat
  3376. { Von Anfang an leer oder Liste komplett durchlaufen und nichts gefunden,
  3377. dann probieren wir's nochmal mit MAGICS }
  3378. if (s=#0) then begin
  3379. secondtry:=true;
  3380. s := LastLister.FirstMarked;
  3381. lMagics:=true;
  3382. end;
  3383. while (s<>#0) do begin
  3384. { --- komplett neu:oh (aus MultiReq uebernommen) --->> }
  3385. { if (s='') then lMagics:=false; }
  3386. { Usernamen vor Quotes killen }
  3387. k:=cPos('>',s);
  3388. if (k>0) then if (k<6) then delete(s,1,k);
  3389. k:=0;
  3390. if (s<>'') then
  3391. while (k<byte(FirstChar(s))) do begin
  3392. t:=''; v:=#0;
  3393. { Nach dem ersten erlaubten Zeichen suchen }
  3394. while (Length(s)>0)
  3395. and not (FirstChar(s) in ['a'..'z','A'..'Z','0'..'9','@','!','$','^']) do begin
  3396. v:=s[1];
  3397. delete(s,1,1);
  3398. continue
  3399. end;
  3400. { Vor dem Dateinamen muss ein Trennzeichen stehen }
  3401. if (v<>#0) then if not (v in [#32,'"','<','>','Ż','Ž','(','[','{',',',';',':','_','*']) then begin
  3402. while (Length(s)>0)
  3403. and not (s[1] in [#32,'"','<','>','Ż','Ž','(','[','{','_','*']) do begin
  3404. delete(s,1,1);
  3405. continue
  3406. end;
  3407. continue
  3408. end;
  3409. mark:=false;
  3410. if (v<>#0) then if (v='*') or (v='_') then mark:=true;
  3411. k:=1; { erstes Zeichen ist schon ok, also Rest testen }
  3412. while (k<Length(s))
  3413. and (s[k+1] in ['a'..'z','A'..'Z','0'..'9','_','@','.','!','/','?','*',
  3414. '$','%','-']) do inc(k);
  3415. t:=copy(s,1,k);
  3416. u:=UpperCase(t);
  3417. delete(s,1,Length(t));
  3418. { Auf den Dateinamen muss ein Trennzeichen folgen }
  3419. if (Length(s)>0) then if not (s[1] in [#32,'"','<','>','Ż','Ž',')',']','}',',',';',':','_','*']) then continue;
  3420. if (mark and (LastChar(t) in ['_','*'])) then DeleteLastChar(t);
  3421. while LastChar(t) in ['.','!','?','/'] do DeleteLastChar(t);
  3422. if (Length(t)<2) then continue;
  3423. k:=0;
  3424. for ic:=1 to Length(t) do if t[ic]='.' then inc(k);
  3425. if (k>1) then continue;
  3426. if (pos('**',t)>0) then continue;
  3427. if not lMagics then if (cPos('.',t)<3) and (Length(t)<5) then continue;
  3428. { Passwort suchen, erkennen und speichern }
  3429. p1:='';
  3430. ic:=cPos('/',t); if (ic>0) then begin
  3431. p1:=copy(t,ic,20); delete(t,ic,99)
  3432. end;
  3433. u:=UpperCase(t);
  3434. if (length(u)<2) then continue;
  3435. s1:=u;
  3436. if (s1='S0') or (s1='XP') then continue;
  3437. if (s1='ZMH') or (s1='NMH') then continue;
  3438. if (s1='V.FC') or (s1='VFC') then continue;
  3439. if (s1='ISDN') or (s1='USR') then continue;
  3440. if (s1='FQDN') or (s1='INC') then continue;
  3441. if (s1='IMHO') or (s1='YMMV') then continue;
  3442. if (s1='ORG') or (s1='PGP') then continue;
  3443. if (s1='FAQ') or (s1='OS') then continue;
  3444. if (s1='DOS') then continue;
  3445. if (length(s1)=3) then if (copy(s1,1,2)='RC') and (s1[3] in ['0'..'9']) then continue;
  3446. ic:=cPos('@',t); if (ic>1) and (ic<>Length(t)) then continue;
  3447. { Auf Beschreibungs-Datei testen }
  3448. FSplit(u,dir,name,ext);
  3449. if (ext='.DIZ') then continue;
  3450. if (name='FILES') or (name='FILE_ID') or (name='00GLOBAL')
  3451. or (name='DESCRIPT') then continue;
  3452. { Ist der String eine Versionsnummer? V42.3, 1.0, X75, V34B etc. }
  3453. if (Length(t)<8) then begin
  3454. u:=t;
  3455. if (UpperCase(copy(u,1,3))='VOL') then delete(u,1,3);
  3456. if (UpCase(u[1]) in ['V','X']) then delete(u,1,1);
  3457. id:=0;
  3458. for ic:=1 to length(u) do if not (UpCase(u[ic]) in ['0'..'9','.','A','B','G']) then id:=1;
  3459. if (id=0) then continue
  3460. end;
  3461. { Ist der String eine Baudrate oder Dateigroesse? xx.xK, x in [0..9] }
  3462. if (length(t)<10) then begin
  3463. u:=Uppercase(t);
  3464. { Zahl }
  3465. while ((u<>'') and (u[1] in ['0'..'9'])) do delete(u,1,1);
  3466. { . }
  3467. if (u<>'') then if (u[1]='.') then begin
  3468. delete(u,1,1);
  3469. { Zahl }
  3470. while (u<>'') and (u[1] in ['0'..'9']) do delete(u,1,1);
  3471. end;
  3472. if (u='K') or (u='KB')
  3473. or (u='M') or (u='MB')
  3474. or (u='B') or (u='BYTES')
  3475. then continue;
  3476. end;
  3477. { Telefonnummern ausblenden }
  3478. id:=0;
  3479. for ic:=1 to length(u) do if not (u[ic] in ['0'..'9','-','/','+','(',')']) then id:=1;
  3480. if (id=0) then continue;
  3481. if (lMagics) then if (Uppercase(t)=t) then begin
  3482. files:=files+' '+t;
  3483. continue
  3484. end;
  3485. u := Uppercase(t);
  3486. ic := cPos('.',u); if not (ic in [2..9]) then continue;
  3487. if (length(u)<4) then continue;
  3488. if (length(u)-ic>3) then continue;
  3489. if (p1<>'') then u:=u+p1; p1:='';
  3490. files:=files+' '+u;
  3491. continue
  3492. end; { while (k<byte(s[0])) }
  3493. { <<--- komplett neu:oh (aus MultiReq uebernommen) --- }
  3494. s:=LastLister.NextMarked;
  3495. end; { while (s<>#0) do begin }
  3496. files:=trim(files);
  3497. { Abbrechen, wenn was gefunden, oder zweiter Durchlauf oder schon beim
  3498. ersten mal MAGICS an waren und ein zweiter Durchlauf unnoetig ist }
  3499. until ((files<>'') or secondtry or lmagics);
  3500. if (files='') then
  3501. rfehler(438) { 'keine Dateien markiert' }
  3502. else
  3503. nnode:=FidoRequest(node,files);
  3504. end;
  3505. function _killit(ask:boolean):boolean;
  3506. var uv : byte;
  3507. _brett : string;
  3508. begin
  3509. _killit:=false;
  3510. dbReadN(mbase,mb_unversandt,uv);
  3511. if uv and 1<>0 then
  3512. rfehler(439) { 'Unversandte Nachricht mit "Nachricht/Unversandt/Loeschen" loeschen!' }
  3513. else
  3514. if not ask or ReadJN(getres(470)+ { 'Nachricht loeschen' }
  3515. iifs(KK and HasRef,getres(471),''),true) then
  3516. begin { ' (unterbricht Bezugsverkettung)' }
  3517. if msgmarked then
  3518. msgUnmark;
  3519. wrkilled;
  3520. _brett := dbReadStrN(mbase,mb_brett);
  3521. DelBezug;
  3522. dbDelete(mbase);
  3523. if FirstChar(_brett)<>'U' then RereadBrettdatum(_brett);
  3524. _killit:=true;
  3525. aufbau:=true; xaufbau:=true;
  3526. setbrettgelesen(_brett);
  3527. end;
  3528. end;
  3529. {
  3530. $Log: xp4o.pas,v $
  3531. Revision 1.169 2004/01/18 19:58:38 mk
  3532. - changed ^file to file
  3533. Revision 1.168 2004/01/18 15:06:12 mk
  3534. - use WildCard instead of * or *.*
  3535. Revision 1.167 2004/01/17 16:33:44 mk
  3536. - split xp0.pas in xp0.pas and xpconst.pas to remove some dependencies
  3537. xpconst.pas should be used for global constants (only!)
  3538. Revision 1.166 2003/11/09 14:35:12 mk
  3539. - fixed access of false ressources while /Wartung/Komplett in CompleteMaintainance
  3540. Revision 1.165 2003/11/02 12:07:06 cl
  3541. - BUGFIX: range check error during reorganisation with defective database,
  3542. see <news:8x4D6qprpVB@centermail.net>
  3543. Revision 1.164 2003/10/21 21:25:04 cl
  3544. - Changed THeader.MIME to use TMimeContentType and TMimeDisposition objects
  3545. - Changed MausTausch headers for Maus-internal IDs: MID/BEZ => maus_*, org_* => MID/BEZ,
  3546. Revision 1.163 2003/10/18 17:14:45 mk
  3547. - persistent open database boxenfile (DB: boxbase)
  3548. Revision 1.162 2003/09/29 18:26:17 mk
  3549. - create .mid in client directory
  3550. fixes #810685: Message-ID suchen (ALT+M)
  3551. Revision 1.161 2003/09/17 15:28:06 mk
  3552. - fixed drawing of status line in archiv viewer for screen width > 80
  3553. Revision 1.160 2003/08/28 14:13:01 mk
  3554. - TUniSelType for UniSel instead of numeric constants
  3555. Revision 1.159 2003/08/23 23:02:35 mk
  3556. - removed hints and warnings
  3557. Revision 1.158 2003/08/23 17:36:47 mk
  3558. - improved adding of new message ids
  3559. Revision 1.157 2003/04/25 21:11:17 mk
  3560. - added Headeronly and MessageID request
  3561. toggle with "m" in message view
  3562. Revision 1.156 2003/04/13 17:36:42 mk
  3563. - purge old mail one day faster than before (same as OpenXP 3.40)
  3564. Revision 1.155 2003/01/28 10:42:25 cl
  3565. - Added statistical SPAM filter
  3566. Revision 1.154 2003/01/07 00:56:46 cl
  3567. - send window rewrite -- part II:
  3568. . added support for Reply-To/(Mail-)Followup-To
  3569. . added support to add addresses from quoted message/group list/user list
  3570. - new address handling -- part II:
  3571. . added support for extended Reply-To syntax (multiple addresses and group syntax)
  3572. . added support for Mail-Followup-To, Mail-Reply-To (incoming)
  3573. - changed "reply-to-all":
  3574. . different default for Ctrl-P and Ctrl-B
  3575. . more addresses can be added directly from send window
  3576. Revision 1.153 2002/12/28 20:11:05 dodi
  3577. - start keyboard input redesign
  3578. Revision 1.152 2002/12/21 05:37:57 dodi
  3579. - removed questionable references to Word type
  3580. Revision 1.151 2002/12/14 07:31:34 dodi
  3581. - using new types
  3582. Revision 1.150 2002/12/12 11:58:46 dodi
  3583. - set $WRITEABLECONT OFF
  3584. Revision 1.149 2002/12/09 14:37:21 dodi
  3585. - merged include files, updated comments
  3586. Revision 1.148 2002/12/06 14:27:28 dodi
  3587. - updated uses, comments and todos
  3588. Revision 1.147 2002/12/02 14:04:30 dodi
  3589. made xpmenu internal tool
  3590. Revision 1.146 2002/09/09 08:33:53 mk
  3591. - some performance improvements
  3592. Revision 1.145 2002/08/01 20:46:46 mk
  3593. - fixed range check error, ansistring suchopt can be empty
  3594. Revision 1.144 2002/07/29 07:17:20 mk
  3595. - fixed AnsiString[1] to FirstChar(AnsiString)
  3596. Revision 1.143 2002/07/26 08:19:25 mk
  3597. - MarkedList is now a dynamically created list, instead of a fixed array,
  3598. removes limit of 5000 selected messages
  3599. Revision 1.142 2002/07/25 20:43:55 ma
  3600. - updated copyright notices
  3601. Revision 1.141 2002/07/22 09:58:46 mk
  3602. - added missing CloseBox in SucheWiedervorlage
  3603. Revision 1.140 2002/07/18 01:11:57 mk
  3604. - fixed potential AV with mbrettd calls
  3605. Revision 1.139 2002/04/14 22:25:36 cl
  3606. - added Wartung/Komplett
  3607. - changes for new address handling
  3608. Revision 1.138 2002/04/13 22:22:59 mk
  3609. - fixed Bug #497283, MsgID-Suche kaputt
  3610. Revision 1.137 2002/03/02 14:29:53 mk
  3611. - fixed regex search
  3612. Revision 1.136 2002/02/21 13:52:32 mk
  3613. - removed 21 hints and 28 warnings
  3614. Revision 1.135 2002/02/18 16:59:40 cl
  3615. - TYP: MIME no longer used for RFC and not written into database
  3616. Revision 1.134 2002/02/10 18:49:50 mk
  3617. - fixes misc bugs in Suche()
  3618. Revision 1.133 2002/02/10 13:10:25 mk
  3619. - fixed several ANSIString dbReadN
  3620. Revision 1.132 2002/02/04 17:26:36 mk
  3621. - after merge fixes
  3622. Revision 1.131 2002/01/30 17:34:14 mk
  3623. - use absolute FieldConsts in dbReadX
  3624. Revision 1.130 2002/01/28 20:32:25 mk
  3625. - completed 3.40 merge, source is compilable for dos and win
  3626. linux is still untested
  3627. Revision 1.129 2002/01/22 19:15:29 mk
  3628. - after 3.40 merge fixes
  3629. Revision 1.128 2002/01/13 15:15:52 mk
  3630. - new "empfaenger"-handling
  3631. Revision 1.127 2002/01/13 15:07:30 mk
  3632. - Big 3.40 Update Part I
  3633. Revision 1.126 2002/01/03 19:19:13 cl
  3634. - added and improved UTF-8/charset switching support
  3635. Revision 1.125 2001/12/31 16:24:33 mk
  3636. - removed unused variable
  3637. Revision 1.124 2001/12/30 19:56:48 cl
  3638. - Kylix 2 compile fixes
  3639. Revision 1.123 2001/12/26 01:35:31 cl
  3640. - renamed SaveDeleteFile --> SafeDeleteFile (cf. an English dictionary)
  3641. Revision 1.122 2001/11/11 00:47:14 ma
  3642. - added temporary debug log
  3643. Revision 1.121 2001/10/24 08:18:05 mk
  3644. - fixed two range check errors
  3645. Revision 1.120 2001/10/20 17:26:41 mk
  3646. - changed some Word to Integer
  3647. Word = Integer will be removed from xpglobal in a while
  3648. Revision 1.119 2001/10/12 23:27:07 mk
  3649. - fixed search with marked areas/users
  3650. Revision 1.118 2001/10/11 09:00:40 mk
  3651. - external viewer files now with correct file extension
  3652. Revision 1.117 2001/10/10 22:04:09 mk
  3653. - enabled use of external mime viewers again
  3654. Revision 1.116 2001/09/27 21:22:26 ml
  3655. - Kylix compatibility stage IV
  3656. Revision 1.115 2001/09/26 23:34:20 mk
  3657. - fixed FPC compile error with newest snapshot:
  3658. Error: Self can only be an explicit parameter in message handlers or class methods
  3659. Revision 1.114 2001/09/14 18:09:56 cl
  3660. - added database info to message <i>nfo screen
  3661. Revision 1.113 2001/09/10 15:58:02 ml
  3662. - Kylix-compatibility (xpdefines written small)
  3663. - removed div. hints and warnings
  3664. Revision 1.112 2001/09/08 16:29:34 mk
  3665. - use FirstChar/LastChar/DeleteFirstChar/DeleteLastChar when possible
  3666. - some AnsiString fixes
  3667. Revision 1.111 2001/09/08 14:31:31 cl
  3668. - cleaned up MIME-related fields in THeader
  3669. - adaptions/fixes for MIME support
  3670. Revision 1.110 2001/09/07 13:54:21 mk
  3671. - added SafeDeleteFile
  3672. - moved most file extensios to constant values in XP0
  3673. - added/changed some FileUpperCase
  3674. Revision 1.109 2001/09/06 19:31:20 mk
  3675. - removed some hints und warnings
  3676. Revision 1.108 2001/09/06 18:54:35 mk
  3677. - removed some warnings
  3678. - formatted source
  3679. - added comment about false compiler warning
  3680. Revision 1.107 2001/08/31 14:44:37 mk
  3681. - changed TxtSeek for Delphi/Kylix compatiblity
  3682. Revision 1.106 2001/08/29 19:30:38 mk
  3683. - added regex search for special search functions
  3684. Revision 1.105 2001/08/28 13:24:35 mk
  3685. - added support for regular expressions
  3686. Revision 1.104 2001/08/27 09:13:43 ma
  3687. - changes in net type handling (1)
  3688. Revision 1.103 2001/08/12 11:50:40 mk
  3689. - replaced dbRead/dbWrite with dbReadN/dbWriteN
  3690. Revision 1.102 2001/08/11 23:06:32 mk
  3691. - changed Pos() to cPos() when possible
  3692. Revision 1.101 2001/08/10 20:57:58 mk
  3693. - removed some hints and warnings
  3694. - fixed some minior bugs
  3695. Revision 1.100 2001/08/10 17:45:26 mk
  3696. - fixed litte type in SucheWiedervorlage
  3697. Revision 1.99 2001/07/30 08:41:24 ma
  3698. - fixed: Mail header info box was displayed incorrectly
  3699. Revision 1.98 2001/07/28 12:04:13 mk
  3700. - removed crt unit as much as possible
  3701. Revision 1.97 2001/07/27 18:10:12 mk
  3702. - ported Reply-To-All from 3.40, first part, untested
  3703. - replyto is now string instead of TStringList again
  3704. Revision 1.96 2001/07/23 16:05:20 mk
  3705. - added some const parameters
  3706. - changed most screen coordinates from byte to integer (saves some kb code)
  3707. Revision 1.95 2001/07/10 07:59:38 mk
  3708. JG:- added search Option "u"
  3709. Revision 1.94 2001/03/13 19:24:57 ma
  3710. - added GPL headers, PLEASE CHECK!
  3711. - removed unnecessary comments
  3712. Revision 1.93 2001/01/14 10:13:34 mk
  3713. - MakeHeader() integreated in new unit
  3714. Revision 1.92 2001/01/05 16:07:58 mo
  3715. -suchlen von 1000 auf 255, type byte
  3716. Revision 1.91 2001/01/04 10:11:20 mk
  3717. - max search length is now 1000 instead of 73
  3718. Revision 1.90 2001/01/02 10:05:25 mk
  3719. - implemented Header.References
  3720. Revision 1.89 2001/01/02 09:29:38 mo
  3721. -Kommentare hinzugefügt und ergänzt
  3722. Revision 1.88 2001/01/01 20:17:35 mo
  3723. -Spezialsuche in markierten Brettern -lter Satnd wieder hergesetllt
  3724. Revision 1.87 2000/12/31 11:52:10 mk
  3725. JG:- MsgId-Suche mit mehreren Strings
  3726. Revision 1.86 2000/12/30 18:45:17 mo
  3727. -Spezialsuche in markierten Bretter auch aus der Nachrichten/User Übersicht
  3728. Revision 1.85 2000/12/26 16:40:14 mk
  3729. - fixed fido request detection
  3730. Revision 1.84 2000/12/25 14:02:42 mk
  3731. - converted Lister to class TLister
  3732. Revision 1.83 2000/12/05 14:58:10 mk
  3733. - AddNewUser
  3734. Revision 1.82 2000/12/03 12:38:23 mk
  3735. - Header-Record is no an Object
  3736. Revision 1.81 2000/11/20 20:44:05 mk
  3737. - Suchlaenge auf 73 reduziert
  3738. Revision 1.80 2000/11/18 21:42:18 mk
  3739. - implemented new Viewer handling class TMessageViewer
  3740. Revision 1.79 2000/11/18 00:04:44 fe
  3741. Made compileable again. (Often a suboptimal way...)
  3742. Revision 1.78 2000/11/16 21:31:06 hd
  3743. - DOS Unit entfernt
  3744. Revision 1.77 2000/11/15 23:00:41 mk
  3745. - updated for sysutils and removed dos a little bit
  3746. Revision 1.76 2000/11/14 15:51:31 mk
  3747. - replaced Exist() with FileExists()
  3748. Revision 1.75 2000/11/14 11:14:33 mk
  3749. - removed unit dos from fileio and others as far as possible
  3750. Revision 1.74 2000/10/26 12:59:57 mk
  3751. - Fixed Bug #112798: Lange Dateinamen in Archiven
  3752. Revision 1.73 2000/10/26 12:06:33 mk
  3753. - THeader.Create/FreeHeaderMem Umstellung
  3754. Revision 1.72 2000/10/22 21:58:59 mk
  3755. - case of .pp and .epp is now UnixFS dependent
  3756. Revision 1.71 2000/10/19 20:52:22 mk
  3757. - removed Unit dosx.pas
  3758. Revision 1.70 2000/10/17 10:05:51 mk
  3759. - Left->LeftStr, Right->RightStr
  3760. Revision 1.69 2000/09/28 03:30:48 mk
  3761. - AnsiString-Fixes
  3762. Revision 1.68 2000/09/26 05:12:26 mk
  3763. - Archivviewer AnsiString-Fix
  3764. Revision 1.67 2000/09/25 17:56:13 mk
  3765. - nicht aktivierter Eintrag Bretter ist jetzt richtig verschwunden
  3766. Revision 1.66 2000/08/27 20:47:50 mk
  3767. OH: F3-Request, ist die automatische Magic-Erkennung abgeschaltet, werden
  3768. sie trotzdem erkannt, und zwar dann, wenn keine normalen Dateinamen gefunden
  3769. wurden
  3770. Revision 1.65 2000/08/22 19:48:47 mk
  3771. - unnoetige Umlautkonvertierung entfernt
  3772. Revision 1.64 2000/08/09 13:27:55 mk
  3773. - Ungelesen Bug beim (K)illen von Nachrichten aus der Markiert-Liste behoben
  3774. Revision 1.63 2000/08/08 09:23:54 mk
  3775. - Bugfixes fuer Suche
  3776. Revision 1.62 2000/08/08 00:03:57 mk
  3777. - TxtSeek auf Shortstring umgetsellt
  3778. Revision 1.61 2000/08/05 10:06:58 mk
  3779. - Ansistring Verbesserungen
  3780. Revision 1.60 2000/08/03 00:06:47 mk
  3781. - Crash bei leeren Suchoptionen beseitigt
  3782. Revision 1.59 2000/07/27 10:13:02 mk
  3783. - Video.pas Unit entfernt, da nicht mehr noetig
  3784. - alle Referenzen auf redundante ScreenLines-Variablen in screenLines geaendert
  3785. - an einigen Stellen die hart kodierte Bildschirmbreite in ScreenWidth geaendert
  3786. - Dialog zur Auswahl der Zeilen/Spalten erstellt
  3787. Revision 1.58 2000/07/23 10:01:01 mk
  3788. - memavail wo moeglich rausgenommen
  3789. Revision 1.57 2000/07/22 21:59:43 mk
  3790. - Zugriff auf nicht initialisierten String beseitigt
  3791. Revision 1.56 2000/07/22 14:05:27 hd
  3792. - Anpassung von dbRead, dbReadN, dbReadX, dbWrite, dbWriteN, dbWriteX
  3793. (sollte es jetzt gewesen sein)
  3794. Revision 1.55 2000/07/21 20:56:25 mk
  3795. - dbRead/Write in dbRead/WriteStr gewandelt, wenn mit AnsiStrings
  3796. Revision 1.54 2000/07/21 17:39:53 mk
  3797. - Umstellung auf AllocHeaderMem/FreeHeaderMem
  3798. Revision 1.53 2000/07/09 08:35:17 mk
  3799. - AnsiStrings Updates
  3800. Revision 1.52 2000/07/06 08:58:45 hd
  3801. - AnsiString
  3802. Revision 1.51 2000/07/05 16:10:29 mk
  3803. JG: - Weitersuchen bei Markierten Nachrichten: bei fehlgeschlagener Suche bleibt die alte Markierung erhalten
  3804. Revision 1.50 2000/07/04 12:04:24 hd
  3805. - UStr durch UpperCase ersetzt
  3806. - LStr durch LowerCase ersetzt
  3807. - FUStr durch FileUpperCase ersetzt
  3808. - Sysutils hier und da nachgetragen
  3809. Revision 1.49 2000/07/03 15:23:26 hd
  3810. - Neue Definition: hasXCurrentDir (RTL-Fkt: GetCurrentDir, SetCurrentDir)
  3811. - GoDir durch SetCurrentDir ersetzt
  3812. Revision 1.48 2000/06/23 15:59:21 mk
  3813. - 16 Bit Teile entfernt
  3814. Revision 1.47 2000/06/17 06:18:35 jg
  3815. - Bugfix: erfolglose Suche: Fensterhintergrund wurde nicht wiederhergestellt
  3816. Revision 1.46 2000/06/05 16:38:51 jg
  3817. Fix: (Suche) Stringvariable wurden vor initialisierung verwendet.
  3818. Revision 1.45 2000/06/05 16:16:22 mk
  3819. - 32 Bit MaxAvail-Probleme beseitigt
  3820. Revision 1.44 2000/06/01 16:03:05 mk
  3821. - Verschiedene Aufraeumarbeiten
  3822. Revision 1.43 2000/05/22 15:52:55 jg
  3823. - File-Kleinschreibungs-Bugfix: Suchoptionen
  3824. Revision 1.42 2000/05/20 02:07:39 mk
  3825. - 32 Bit/VP: FindFirst/FindNext aus Dos-Unit statta us SysTools verwendet
  3826. Revision 1.41 2000/05/14 10:00:43 hd
  3827. - Fix: SysUtils doppelt
  3828. Revision 1.40 2000/05/14 07:22:21 mk
  3829. - weiterer Fix fuer Debug-Modus
  3830. Revision 1.39 2000/05/13 23:17:54 mk
  3831. - jetzt mit FPC und Debug-Modus compilierbar
  3832. Revision 1.38 2000/05/07 10:28:03 hd
  3833. - Fix: (check_seekmode): wrt2 verlangt einen string, kein byte!
  3834. Revision 1.37 2000/05/06 17:29:22 mk
  3835. - DOS DPMI32 Portierung
  3836. Revision 1.36 2000/05/02 19:14:01 hd
  3837. xpcurses statt crt in den Units
  3838. Revision 1.35 2000/04/27 16:36:09 jg
  3839. - Nachricht/Aendern/Typ schaltet jetzt um zwischen Text,Bin und Mime
  3840. Revision 1.34 2000/04/23 07:58:53 mk
  3841. - OS/2-Portierung
  3842. Revision 1.33 2000/04/22 08:32:47 jg
  3843. - Bugfix: NOT - Verknuepfte Usersuche
  3844. Revision 1.32 2000/04/15 18:21:33 mk
  3845. - FindFirst-Fixes
  3846. Revision 1.31 2000/04/13 12:48:37 mk
  3847. - Anpassungen an Virtual Pascal
  3848. - Fehler bei FindFirst behoben
  3849. - Bugfixes bei 32 Bit Assembler-Routinen
  3850. - Einige unkritische Memory Leaks beseitigt
  3851. - Einge Write-Routinen durch Wrt/Wrt2 ersetzt
  3852. - fehlende CVS Keywords in einigen Units hinzugefuegt
  3853. - ZPR auf VP portiert
  3854. - Winxp.ConsoleWrite provisorisch auf DOS/Linux portiert
  3855. - Automatische Anpassung der Zeilenzahl an Consolengroesse in Win32
  3856. Revision 1.30 2000/04/10 00:43:04 oh
  3857. - F3-Request: Magicerkennung ein/ausschaltbar (C/O/e/V/Fido)
  3858. Revision 1.29 2000/03/22 05:06:37 jg
  3859. - Bugfix: Suchen-Spezial ohne Volltext aber mit Option "o" oder "a"
  3860. Vorbereitung der Such Teilstrings fuehrte zu nem RTE 201.
  3861. Revision 1.28 2000/03/21 15:22:10 jg
  3862. - Suche: Pfeil fuer Historyauswahl kommt nur noch
  3863. wenn auch was gewaehlt werden kann.
  3864. Revision 1.27 2000/03/18 10:39:06 jg
  3865. - Suche-MessageID Wahlmoeglichkeit: schnelle Bezugs-DB Suche
  3866. oder langsamere Msg-Base Suche mit Teilstrings und Suchoptionen
  3867. Revision 1.26 2000/03/14 15:15:40 mk
  3868. - Aufraeumen des Codes abgeschlossen (unbenoetigte Variablen usw.)
  3869. - Alle 16 Bit ASM-Routinen in 32 Bit umgeschrieben
  3870. - TPZCRC.PAS ist nicht mehr noetig, Routinen befinden sich in CRC16.PAS
  3871. - XP_DES.ASM in XP_DES integriert
  3872. - 32 Bit Windows Portierung (misc)
  3873. - lauffaehig jetzt unter FPC sowohl als DOS/32 und Win/32
  3874. Revision 1.25 2000/03/13 18:55:18 jg
  3875. - xp4o+typeform: Ukonv in UkonvStr umbenannt
  3876. - xp4o: Compilerschalter "History" entfernt,
  3877. "Debugsuche" durch "Debug" ersetzt
  3878. Revision 1.24 2000/03/09 23:39:33 mk
  3879. - Portierung: 32 Bit Version laeuft fast vollstaendig
  3880. Revision 1.23 2000/03/08 22:36:33 mk
  3881. - Bugfixes fuer die 32 Bit-Version und neue ASM-Routinen
  3882. Revision 1.22 2000/03/06 08:51:04 mk
  3883. - OpenXP/32 ist jetzt Realitaet
  3884. Revision 1.21 2000/03/04 18:34:18 jg
  3885. - Externe Viewer: zum Ansehen von Fileattaches wird keine Temp-Kopie
  3886. mehr erstellt, und nicht mehr gewartet, da kein Loeschen noetig ist
  3887. Revision 1.20 2000/03/02 20:09:31 jg
  3888. - NOT Operator (~) fuer Suchstrings und Such-History eingebaut
  3889. Revision 1.19 2000/03/01 13:17:41 jg
  3890. - Ukonv Aufrufe benutzen jetzt High() fuer Maxlaenge
  3891. - STRG + INS funktioniert in Texteingabefeldern wie STRG+C
  3892. Revision 1.18 2000/03/01 08:04:23 jg
  3893. - UND/ODER Suche mit Suchoptionen "o" + "u"
  3894. Debug-Checkfenster mit Suchoption "c"
  3895. - Umlautkonvertierungen beruecksichtigen
  3896. jetzt Maximalstringlaenge
  3897. Revision 1.17 2000/02/29 17:50:40 mk
  3898. OH: - Erkennung der Magics verbessert
  3899. Revision 1.16 2000/02/29 12:59:16 jg
  3900. - Bugfix: Umlautkonvertierung beachtet jetzt Originalstringlaenge
  3901. (Wurde akut bei Spezialsuche-Betreff)
  3902. Revision 1.15 2000/02/29 10:46:28 jg
  3903. -Bugfix Spezialsuche - Betreff
  3904. Revision 1.14 2000/02/23 19:11:04 jg
  3905. -Suchfunktionen im Lister benutzen Autosuche,
  3906. "Global_Suchstring" und dessen auswertung entfernt.
  3907. -!Todo.txt aktualisiiert
  3908. Revision 1.13 2000/02/22 15:51:20 jg
  3909. Bugfix fuer "O" im Lister/Archivviewer
  3910. Fix fuer Zusatz/Archivviewer - Achivviewer-Macros jetzt aktiv
  3911. O, I, ALT+M, ALT+U, ALT+V, ALT+B nur noch im Lister gueltig.
  3912. Archivviewer-Macros gueltig im MIME-Popup
  3913. Revision 1.12 2000/02/19 18:00:24 jg
  3914. Bugfix zu Rev 1.9+: Suchoptionen werden nicht mehr reseted
  3915. Umlautunabhaengige Suche kennt jetzt "‚"
  3916. Mailadressen mit "!" und "=" werden ebenfalls erkannt
  3917. Revision 1.11 2000/02/19 10:12:13 jg
  3918. Bugfix Gelesenstatus aendern per F4 im ungelesen Modus
  3919. Revision 1.10 2000/02/18 17:28:08 mk
  3920. AF: Kommandozeilenoption Dupekill hinzugefuegt
  3921. Revision 1.9 2000/02/18 15:54:52 jg
  3922. Suchoptionen-Laenderabfrage verbessert
  3923. Revision 1.8 2000/02/18 09:13:27 mk
  3924. JG: * Volltextsuche jettz Sprachabhaengig gestaltet
  3925. * XP3.ASM in XP3.PAS aufgenommen
  3926. Revision 1.7 2000/02/16 15:25:32 mk
  3927. OH: Schalter magics in FidoMsgRequest auf true gesetzt
  3928. Revision 1.6 2000/02/15 21:19:24 mk
  3929. JG: * Umlautkonvertierung von XP4O.Betreffsuche in Typeform verlagert
  3930. * wenn man eine markierte Nachricht liest, wird beim Verlassen
  3931. der Headeranzeige nicht gleich auch der Lister verlasssen
  3932. * Die Suchfunktionen "Absender/User", "Betreff" und "Fidoempfaenger"
  3933. koennen jetzt Umlautunabhaengig geschalten werden
  3934. Revision 1.5 2000/02/15 20:43:36 mk
  3935. MK: Aktualisierung auf Stand 15.02.2000
  3936. }
  3937. end.