/trunk/xp4o.pas

# · Pascal · 4422 lines · 3509 code · 231 blank · 682 comment · 475 complexity · 82439597a33e9b6db539ea369e8388a5 MD5 · raw file

Large files are truncated click here to view the full file

  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;