install.pas 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993-98 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. This is the install program for the DOS and OS/2 versions of Free Pascal
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. program install;
  14. { $DEFINE DLL} (* TH - if defined, UNZIP32.DLL library is used to unpack. *)
  15. { $DEFINE DOSSTUB} (* TH - should _not_ be defined unless creating a bound DOS and OS/2 installer!!! *)
  16. (* Defining DOSSTUB causes adding a small piece of code *)
  17. (* for starting the OS/2 part from the DOS part of a bound *)
  18. (* application if running in OS/2 VDM (DOS) window. Used *)
  19. (* only if compiling with TP/BP (see conditionals below). *)
  20. {$IFDEF OS2}
  21. {$DEFINE DLL}
  22. {$ENDIF DLL}
  23. {$IFDEF VER60}
  24. {$DEFINE TP}
  25. {$ENDIF}
  26. {$IFDEF VER70}
  27. {$DEFINE TP}
  28. {$ENDIF}
  29. {$IFNDEF TP}
  30. {$UNDEF DOSSTUB}
  31. {$ELSE}
  32. {$IFDEF OS2}
  33. {$UNDEF DOSSTUB}
  34. {$ENDIF}
  35. {$ENDIF}
  36. {$IFDEF DPMI}
  37. {$UNDEF DOSSTUB}
  38. {$ENDIF}
  39. {$ifdef go32v2}
  40. {$define MAYBE_LFN}
  41. {$endif}
  42. {$ifdef debug}
  43. {$ifdef win32}
  44. {$define MAYBE_LFN}
  45. {$endif win32}
  46. {$endif debug}
  47. {$ifdef TP}
  48. {$define MAYBE_LFN}
  49. {$endif}
  50. uses
  51. {$IFDEF OS2}
  52. {$IFDEF FPC}
  53. DosCalls,
  54. {$ELSE FPC}
  55. {$IFDEF VirtualPascal}
  56. OS2Base,
  57. {$ELSE VirtualPascal}
  58. BseDos,
  59. {$ENDIF VirtualPascal}
  60. {$ENDIF FPC}
  61. {$ENDIF OS2}
  62. {$IFDEF GO32V2}
  63. emu387,
  64. {$ENDIF}
  65. {$ifdef HEAPTRC}
  66. heaptrc,
  67. {$endif HEAPTRC}
  68. strings,dos,objects,drivers,
  69. {$IFNDEF FVISION}
  70. commands,
  71. HelpCtx,
  72. {$ENDIF}
  73. unzip,ziptypes,
  74. {$IFDEF DLL}
  75. unzipdll,
  76. {$ENDIF}
  77. app,dialogs,views,menus,msgbox,colortxt,tabs,scroll,
  78. WHTMLScn;
  79. const
  80. installerversion='1.0.8';
  81. installercopyright='Copyright (c) 1993-2004 Florian Klaempfl';
  82. maxpacks=30;
  83. maxpackages=20;
  84. maxdefcfgs=1024;
  85. HTMLIndexExt = '.htx';
  86. CfgExt = '.dat';
  87. MaxStatusPos = 4;
  88. StatusChars: string [MaxStatusPos] = '/-\|';
  89. StatusPos: byte = 1;
  90. { this variable is set to true if an ide is installed }
  91. haside : boolean = false;
  92. hashtmlhelp : boolean = false;
  93. {$ifdef Unix}
  94. DirSep='/';
  95. {$else}
  96. DirSep='\';
  97. {$endif}
  98. type
  99. tpackage=record
  100. name : string[60];
  101. zip : string[40]; { default zipname }
  102. zipshort : string[12]; { 8.3 zipname }
  103. diskspace : int64; { diskspace required }
  104. end;
  105. tpack=record
  106. name : string[12];
  107. binsub : string[40];
  108. ppc386 : string[20];
  109. targetname : string[40];
  110. defidecfgfile,
  111. defideinifile,
  112. defcfgfile,
  113. setpathfile : string[12];
  114. include : boolean;
  115. { filechk : string[40]; Obsolete }
  116. packages : longint;
  117. package : array[1..maxpackages] of tpackage;
  118. end;
  119. tcfgarray = array[1..maxdefcfgs] of pstring;
  120. cfgrec=record
  121. title : string[80];
  122. version : string[20];
  123. helpidx,
  124. docsub,
  125. basepath : DirStr;
  126. packs : word;
  127. pack : array[1..maxpacks] of tpack;
  128. defideinis,
  129. defidecfgs,
  130. defcfgs,
  131. defsetpaths : longint;
  132. defideini,
  133. defidecfg,
  134. defcfg,
  135. defsetpath : tcfgarray;
  136. end;
  137. datarec=record
  138. basepath : DirStr;
  139. cfgval : word;
  140. packmask : array[1..maxpacks] of sw_word;
  141. end;
  142. punzipdialog=^tunzipdialog;
  143. tunzipdialog=object(tdialog)
  144. filetext : pstatictext;
  145. extractfiletext : pstatictext;
  146. currentfile : string;
  147. constructor Init(var Bounds: TRect; ATitle: TTitleStr);
  148. procedure do_unzip(s,topath:string);
  149. end;
  150. penddialog = ^tenddialog;
  151. tenddialog = object(tdialog)
  152. constructor init;
  153. end;
  154. pinstalldialog = ^tinstalldialog;
  155. tinstalldialog = object(tdialog)
  156. constructor init;
  157. procedure handleevent(var event : tevent);virtual;
  158. end;
  159. PFPHTMLFileLinkScanner = ^TFPHTMLFileLinkScanner;
  160. TFPHTMLFileLinkScanner = object(THTMLFileLinkScanner)
  161. function CheckURL(const URL: string): boolean; virtual;
  162. function CheckText(const Text: string): boolean; virtual;
  163. procedure ProcessDoc(Doc: PHTMLLinkScanFile); virtual;
  164. end;
  165. phtmlindexdialog = ^thtmlindexdialog;
  166. thtmlindexdialog = object(tdialog)
  167. text : pstatictext;
  168. constructor init(var Bounds: TRect; ATitle: TTitleStr);
  169. end;
  170. tapp = object(tapplication)
  171. procedure initmenubar;virtual;
  172. procedure handleevent(var event : tevent);virtual;
  173. procedure do_installdialog;
  174. procedure readcfg(const fn:string);
  175. procedure checkavailpack;
  176. end;
  177. PSpecialInputLine= ^TSpecialInputLine;
  178. TSpecialInputLine = object (TInputLine)
  179. procedure GetData(var Rec); virtual;
  180. end;
  181. {$IFDEF DOSSTUB}
  182. PByte = ^byte;
  183. PRunBlock = ^TRunBlock;
  184. TRunBlock = record
  185. Length: word;
  186. Dependent: word;
  187. Background: word;
  188. TraceLevel: word;
  189. PrgTitle: PChar;
  190. PrgName: PChar;
  191. Args: PChar;
  192. TermQ: longint;
  193. Environment: pointer;
  194. Inheritance: word;
  195. SesType: word;
  196. Icon: pointer;
  197. PgmHandle: longint;
  198. PgmControl: word;
  199. Column: word;
  200. Row: word;
  201. Width: word;
  202. Height: word;
  203. end;
  204. {$ENDIF}
  205. var
  206. installapp : tapp;
  207. startpath : string;
  208. successfull : boolean;
  209. cfg : cfgrec;
  210. data : datarec;
  211. CfgName: NameStr;
  212. DStr: DirStr;
  213. EStr: ExtStr;
  214. UnzDlg : punzipdialog;
  215. log : text;
  216. createlog : boolean;
  217. {$IFNDEF DLL}
  218. const
  219. UnzipErr: longint = 0;
  220. {$ENDIF}
  221. {$ifdef MAYBE_LFN}
  222. const
  223. locallfnsupport : boolean = false;
  224. {$endif MAYBE_LFN}
  225. {*****************************************************************************
  226. Helpers
  227. *****************************************************************************}
  228. procedure errorhalt;
  229. begin
  230. installapp.done;
  231. if CreateLog then
  232. begin
  233. WriteLn (Log, 'Installation hasn''t been completed.');
  234. Close (Log);
  235. end;
  236. halt(1);
  237. end;
  238. function packagemask(i:longint):longint;
  239. begin
  240. packagemask:=1 shl (i-1);
  241. end;
  242. function upper(const s : string):string;
  243. var
  244. i : integer;
  245. begin
  246. for i:=1 to length(s) do
  247. if s[i] in ['a'..'z'] then
  248. upper[i]:=chr(ord(s[i])-32)
  249. else
  250. upper[i]:=s[i];
  251. upper[0]:=s[0];
  252. end;
  253. procedure Replace(var s:string;const s1,s2:string);
  254. var
  255. i : longint;
  256. begin
  257. repeat
  258. i:=pos(s1,s);
  259. if i>0 then
  260. begin
  261. Delete(s,i,length(s1));
  262. Insert(s2,s,i);
  263. end;
  264. until i=0;
  265. end;
  266. function DotStr(l:longint):string;
  267. var
  268. TmpStr : string[32];
  269. i : longint;
  270. begin
  271. Str(l,TmpStr);
  272. i:=Length(TmpStr);
  273. while (i>3) do
  274. begin
  275. i:=i-3;
  276. if TmpStr[i]<>'-' then
  277. Insert('.',TmpStr,i+1);
  278. end;
  279. DotStr:=TmpStr;
  280. end;
  281. function file_exists(const f : string;const path : string) : boolean;
  282. begin
  283. file_exists:=fsearch(f,path)<>'';
  284. end;
  285. function createdir(s:string):boolean;
  286. var
  287. s1,start : string;
  288. err : boolean;
  289. i : longint;
  290. begin
  291. err:=false;
  292. {$I-}
  293. getdir(0,start);
  294. {$ifndef Unix}
  295. if (s[2]=':') and (s[3]=DirSep) then
  296. begin
  297. chdir(Copy(s,1,3));
  298. Delete(S,1,3);
  299. end;
  300. {$endif}
  301. repeat
  302. i:=Pos(DirSep,s);
  303. if i=0 then
  304. i:=255;
  305. s1:=Copy(s,1,i-1);
  306. Delete(s,1,i);
  307. ChDir(s1);
  308. if ioresult<>0 then
  309. begin
  310. mkdir(s1);
  311. chdir(s1);
  312. if ioresult<>0 then
  313. begin
  314. err:=true;
  315. break;
  316. end;
  317. end;
  318. until s='';
  319. chdir(start);
  320. {$I+}
  321. createdir:=err;
  322. end;
  323. function DiskSpaceN(const zipfile : string) : longint;
  324. var
  325. compressed,uncompressed : longint;
  326. s : string;
  327. begin
  328. s:=zipfile+#0;
  329. if not (IsZip (@S [1])) then
  330. DiskSpaceN := -1
  331. else
  332. begin
  333. Uncompressed:=UnzipSize(@s[1],compressed);
  334. DiskSpaceN:=uncompressed shr 10;
  335. end;
  336. end;
  337. function diskspacestr(uncompressed : longint) : string;
  338. begin
  339. if Uncompressed = -1 then
  340. DiskSpacestr := ' [INVALID]'
  341. else
  342. diskspacestr:=' ('+DotStr(uncompressed)+' KB)';
  343. end;
  344. function createinstalldir(s : string) : boolean;
  345. var
  346. err : boolean;
  347. dir : searchrec;
  348. params : array[0..0] of pointer;
  349. begin
  350. if s[length(s)]=DirSep then
  351. dec(s[0]);
  352. FindFirst(s,AnyFile,dir);
  353. if doserror=0 then
  354. begin
  355. if Dir.Attr and Directory = 0 then
  356. begin
  357. messagebox('A file with the name chosen as the installation '+
  358. 'directory exists already. Cannot create this directory!',nil,
  359. mferror+mfokbutton);
  360. createinstalldir:=false;
  361. end else
  362. createinstalldir:=messagebox('The installation directory exists already. '+
  363. 'Do you want to continue ?',nil,
  364. mferror+mfyesbutton+mfnobutton)=cmYes;
  365. exit;
  366. end;
  367. err:=Createdir(s);
  368. if err then
  369. begin
  370. params[0]:=@s;
  371. messagebox('The installation directory %s couldn''t be created',
  372. @params,mferror+mfokbutton);
  373. createinstalldir:=false;
  374. exit;
  375. end;
  376. {$ifndef TP}
  377. {$IFNDEF OS2}
  378. FindClose (dir);
  379. {$ENDIF}
  380. {$endif}
  381. createinstalldir:=true;
  382. end;
  383. function GetProgDir: DirStr;
  384. var
  385. D: DirStr;
  386. N: NameStr;
  387. E: ExtStr;
  388. begin
  389. FSplit (FExpand (ParamStr (0)), D, N, E);
  390. if (D [0] <> #0) and (D [byte (D [0])] = '\') then Dec (D [0]);
  391. GetProgDir := D;
  392. end;
  393. function RTrim(const S: string): string;
  394. var
  395. i : longint;
  396. begin
  397. i:=length(s);
  398. while (i>0) and (s[i]=' ') do
  399. dec(i);
  400. RTrim:=Copy(s,1,i);
  401. end;
  402. function LTrim(const S: string): string;
  403. var
  404. i : longint;
  405. begin
  406. i:=1;
  407. while (i<length(s)) and (s[i]=' ') do
  408. inc(i);
  409. LTrim:=Copy(s,i,255);
  410. end;
  411. function Trim(const S: string): string;
  412. begin
  413. Trim:=RTrim(LTrim(S));
  414. end;
  415. function CompareText(S1, S2: string): integer;
  416. var R: integer;
  417. begin
  418. S1:=Upcase(S1);
  419. S2:=Upcase(S2);
  420. if S1<S2 then R:=-1 else
  421. if S1>S2 then R:= 1 else
  422. R:=0;
  423. CompareText:=R;
  424. end;
  425. function ExtOf(const S: string): string;
  426. var D: DirStr; E: ExtStr; N: NameStr;
  427. begin
  428. FSplit(S,D,N,E);
  429. ExtOf:=E;
  430. end;
  431. function DirAndNameOf(const S: string): string;
  432. var D: DirStr; E: ExtStr; N: NameStr;
  433. begin
  434. FSplit(S,D,N,E);
  435. DirAndNameOf:=D+N;
  436. end;
  437. function DirOf(const S: string): string;
  438. var D: DirStr; E: ExtStr; N: NameStr;
  439. begin
  440. FSplit(S,D,N,E);
  441. DirOf:=D;
  442. end;
  443. function GetZipErrorInfo(error : longint) : string;
  444. var
  445. ErrorStr : string;
  446. begin
  447. case error of
  448. unzip_CRCErr : GetZipErrorInfo:='CRC error';
  449. unzip_WriteErr : GetZipErrorInfo:='Write error';
  450. unzip_ReadErr : GetZipErrorInfo:='Read error';
  451. unzip_ZipFileErr : GetZipErrorInfo:='ZipFile erroe';
  452. unzip_UserAbort : GetZipErrorInfo:='User abort';
  453. unzip_NotSupported : GetZipErrorInfo:='Not supported';
  454. unzip_Encrypted : GetZipErrorInfo:='File is encrypted';
  455. unzip_InUse : GetZipErrorInfo:='Fie is in use';
  456. unzip_InternalError : GetZipErrorInfo:='Internal error'; {Error in zip format}
  457. unzip_NoMoreItems : GetZipErrorInfo:='No more items';
  458. unzip_FileError : GetZipErrorInfo:='File error'; {Error Accessing file}
  459. unzip_NotZipfile : GetZipErrorInfo:='Not a zipfile'; {not a zip file}
  460. unzip_SeriousError : GetZipErrorInfo:='Serious error'; {serious error}
  461. unzip_MissingParameter : GetZipErrorInfo:='Missing parameter'; {missing parameter}
  462. else
  463. begin
  464. Str(Error,ErrorStr);
  465. GetZipErrorInfo:='Unknown error '+errorstr;
  466. end;
  467. end;
  468. end;
  469. {*****************************************************************************
  470. HTML-Index Generation
  471. *****************************************************************************}
  472. var
  473. indexdlg : phtmlindexdialog;
  474. constructor thtmlindexdialog.Init(var Bounds: TRect; ATitle: TTitleStr);
  475. var
  476. r : trect;
  477. begin
  478. inherited init(bounds,atitle);
  479. Options:=Options or ofCentered;
  480. R.Assign (4, 2,bounds.B.X-Bounds.A.X-2, 4);
  481. text:=new(pstatictext,init(r,'Please wait ...'));
  482. insert(text);
  483. end;
  484. procedure TFPHTMLFileLinkScanner.ProcessDoc(Doc: PHTMLLinkScanFile);
  485. var
  486. oldtext : pstring;
  487. begin
  488. oldtext:=indexdlg^.text^.text;
  489. indexdlg^.text^.text:=newstr('Processing '+Doc^.GetDocumentURL);
  490. indexdlg^.text^.drawview;
  491. inherited ProcessDoc(Doc);
  492. disposestr(indexdlg^.text^.text);
  493. indexdlg^.text^.text:=oldtext;
  494. indexdlg^.text^.drawview;
  495. end;
  496. function TFPHTMLFileLinkScanner.CheckURL(const URL: string): boolean;
  497. var OK: boolean;
  498. const HTTPPrefix = 'http:';
  499. FTPPrefix = 'ftp:';
  500. begin
  501. OK:=inherited CheckURL(URL);
  502. if OK then OK:=DirAndNameOf(URL)<>'';
  503. if OK then OK:=CompareText(copy(ExtOf(URL),1,4),'.HTM')=0;
  504. if OK then OK:=CompareText(copy(URL,1,length(HTTPPrefix)),HTTPPrefix)<>0;
  505. if OK then OK:=CompareText(copy(URL,1,length(FTPPrefix)),FTPPrefix)<>0;
  506. CheckURL:=OK;
  507. end;
  508. function TFPHTMLFileLinkScanner.CheckText(const Text: string): boolean;
  509. var OK: boolean;
  510. S: string;
  511. begin
  512. S:=Trim(Text);
  513. OK:=(S<>'') and (copy(S,1,1)<>'[');
  514. CheckText:=OK;
  515. end;
  516. procedure writehlpindex(filename : string);
  517. var
  518. LS : PFPHTMLFileLinkScanner;
  519. BS : PBufStream;
  520. Re : Word;
  521. params : array[0..0] of pointer;
  522. dir : searchrec;
  523. r : trect;
  524. begin
  525. r.assign(10,10,70,15);
  526. indexdlg:=new(phtmlindexdialog,init(r,'Creating HTML index file, please wait ...'));
  527. desktop^.insert(indexdlg);
  528. { warning FIXME !!!!, don't know what is to fix here ... PM }
  529. New(LS, Init(DirOf(FileName)));
  530. LS^.ProcessDocument(FileName,[soSubDocsOnly]);
  531. if LS^.GetDocumentCount=0 then
  532. begin
  533. params[0]:=@filename;
  534. MessageBox('Problem creating help index %1, aborting',@params,
  535. mferror+mfokbutton);
  536. end
  537. else
  538. begin
  539. FileName:=DirAndNameOf(FileName)+HTMLIndexExt;
  540. findfirst(filename,AnyFile,dir);
  541. if doserror=0 then
  542. begin
  543. params[0]:=@filename;
  544. Re:=MessageBox('Help index %s already exists, overwrite it?',@params,
  545. mfinformation+mfyesbutton+mfnobutton);
  546. end
  547. else
  548. Re:=cmYes;
  549. if Re<>cmNo then
  550. begin
  551. New(BS, Init(FileName, stCreate, 4096));
  552. if Assigned(BS)=false then
  553. begin
  554. MessageBox('Error while writing help index! '+
  555. 'No help index is created',@params,
  556. mferror+mfokbutton);
  557. Re:=cmCancel;
  558. end
  559. else
  560. begin
  561. LS^.StoreDocuments(BS^);
  562. if BS^.Status<>stOK then
  563. begin
  564. MessageBox('Error while writing help index!'#13+
  565. 'No help index is created',@params,
  566. mferror+mfokbutton);
  567. Re:=cmCancel;
  568. end;
  569. Dispose(BS, Done);
  570. end;
  571. end;
  572. end;
  573. Dispose(LS, Done);
  574. desktop^.delete(indexdlg);
  575. dispose(indexdlg,done);
  576. end;
  577. {*****************************************************************************
  578. Writing of fpc.cfg
  579. *****************************************************************************}
  580. procedure writedefcfg(const fn:string;const cfgdata : tcfgarray;count : longint;const targetname : string);
  581. var
  582. t : text;
  583. i : longint;
  584. s : string;
  585. dir : searchrec;
  586. params : array[0..0] of pointer;
  587. d : dirstr;
  588. n : namestr;
  589. e : extstr;
  590. begin
  591. { already exists }
  592. findfirst(fn,AnyFile,dir);
  593. if doserror=0 then
  594. begin
  595. params[0]:=@fn;
  596. if MessageBox('Config %s already exists, continue writing default config?',@params,
  597. mfinformation+mfyesbutton+mfnobutton)=cmNo then
  598. exit;
  599. end;
  600. { create directory }
  601. fsplit(fn,d,n,e);
  602. createdir(d);
  603. { create the fpc.cfg }
  604. assign(t,fn);
  605. {$I-}
  606. rewrite(t);
  607. {$I+}
  608. if ioresult<>0 then
  609. begin
  610. params[0]:=@fn;
  611. MessageBox(#3'A config not written.'#13#3'%s'#13#3'couldn''t be created',@params,mfinformation+mfokbutton);
  612. exit;
  613. end;
  614. for i:=1 to count do
  615. if assigned(cfgdata[i]) then
  616. begin
  617. s:=cfgdata[i]^;
  618. Replace(s,'%basepath%',data.basepath);
  619. Replace(s,'%targetname%',targetname);
  620. if pos('-',targetname)=0 then
  621. Replace(s,'%fpctargetmacro%','$FPCOS')
  622. else
  623. Replace(s,'%fpctargetmacro%','$FPCTARGET');
  624. writeln(t,s);
  625. end
  626. else
  627. writeln(t,'');
  628. close(t);
  629. end;
  630. {*****************************************************************************
  631. TUnZipDialog
  632. *****************************************************************************}
  633. constructor tunzipdialog.Init(var Bounds: TRect; ATitle: TTitleStr);
  634. var
  635. r : trect;
  636. begin
  637. inherited init(bounds,atitle);
  638. Options:=Options or ofCentered;
  639. (* R.Assign (11, 4, 38, 6);*)
  640. R.Assign (1, 4,bounds.B.X-Bounds.A.X-2, 6);
  641. filetext:=new(pstatictext,init(r,#3'File: '));
  642. insert(filetext);
  643. R.Assign (1, 7,bounds.B.X-Bounds.A.X-2, 9);
  644. extractfiletext:=new(pstatictext,init(r,#3' '));
  645. insert(extractfiletext);
  646. end;
  647. {$IFNDEF DLL}
  648. procedure UnzipCheckFn (Retcode: longint; Rec: pReportRec );{$ifdef Delphi32}STDCALL;{$endif}
  649. {$ifndef fpc}{$IFNDEF BIT32} FAR;{$ENDIF BIT32}{$endif}
  650. var
  651. name : string;
  652. begin
  653. case Rec^.Status of
  654. unzip_starting:
  655. UnzipErr := 0;
  656. file_starting:
  657. begin
  658. with UnzDlg^.extractfiletext^ do
  659. begin
  660. Disposestr(text);
  661. name:=Strpas(Rec^.FileName);
  662. UnzDlg^.currentfile:=name;
  663. Text:=NewStr(#3+name);
  664. DrawView;
  665. end;
  666. end;
  667. file_failure:
  668. UnzipErr := RetCode;
  669. file_unzipping:
  670. begin
  671. with UnzDlg^.FileText^ do
  672. begin
  673. Inc (StatusPos);
  674. if StatusPos > MaxStatusPos then StatusPos := 1;
  675. Text^ [Length (Text^)] := StatusChars [StatusPos];
  676. DrawView;
  677. end;
  678. end;
  679. end;
  680. end;
  681. {$ENDIF}
  682. procedure tunzipdialog.do_unzip(s,topath : string);
  683. var
  684. {$ifdef MAYBE_LFN}
  685. p : pathstr;
  686. n : namestr;
  687. e : extstr;
  688. islfn : boolean;
  689. {$endif MAYBE_LFN}
  690. again : boolean;
  691. st2,fn,dir,wild : string;
  692. begin
  693. Disposestr(filetext^.text);
  694. filetext^.Text:=NewStr(#3'File: '+s + #13#3' ');
  695. filetext^.drawview;
  696. if not(file_exists(s,startpath)) then
  697. begin
  698. messagebox('File "'+s+'" missing for the selected installation. '+
  699. 'Installation hasn''t been completed.',nil,mferror+mfokbutton);
  700. if CreateLog then
  701. WriteLn (Log, 'File "' + S +
  702. '" missing for the selected installation!');
  703. errorhalt;
  704. end;
  705. {$IFNDEF DLL}
  706. {$IFDEF FPC}
  707. SetUnzipReportProc (@UnzipCheckFn);
  708. {$ELSE FPC}
  709. SetUnzipReportProc (UnzipCheckFn);
  710. {$ENDIF FPC}
  711. {$ENDIF DLL}
  712. if CreateLog then
  713. WriteLn (Log, 'Unpacking ' + AllFiles + ' from '
  714. + StartPath + DirSep + S + ' to ' + ToPath);
  715. repeat
  716. fn:=startpath+DirSep+s+#0;
  717. dir:=topath+#0;
  718. wild:=AllFiles + #0;
  719. again:=false;
  720. FileUnzipEx(@fn[1],@dir[1],@wild[1]);
  721. if (UnzipErr <> 0) and (UnzipErr <> 1) then
  722. begin
  723. if CreateLog then
  724. WriteLn (Log, 'Error ', UnzipErr, ' while unpacking!');
  725. s:=GetZipErrorInfo(UnzipErr);
  726. { Str(UnzipErr,s);}
  727. st2:='';
  728. if UnzipErr=unzip_WriteErr then
  729. begin
  730. {$ifdef MAYBE_LFN}
  731. if not(locallfnsupport) then
  732. begin
  733. islfn:=false;
  734. fsplit(currentfile,p,n,e);
  735. if (length(n)>8) or (length(e)>4) or
  736. (pos('.',n)>0) or (upper(p+n+e)<>upper(currentfile)) then
  737. islfn:=true;
  738. if islfn then
  739. begin
  740. if CreateLog then
  741. begin
  742. WriteLn (Log, 'Error while extracting ' +
  743. CurrentFile + ' because of missing LFN support,');
  744. WriteLn (Log, ' skipping rest of ZIP file.');
  745. end;
  746. messagebox('Error while extracting '+currentfile+
  747. #13#3'because of missing lfn support'+
  748. #13#3'skipping rest of zipfile '+s
  749. ,nil,mferror+mfOkButton);
  750. again:=false;
  751. exit;
  752. end;
  753. end
  754. else
  755. {$endif MAYBE_LFN}
  756. st2:=' Disk full?';
  757. end;
  758. if CreateLog then
  759. WriteLn (Log, 'Error (' + S + ') while extracting.' + ST2);
  760. if messagebox('Error (' + S + ') while extracting.'+st2+#13+
  761. #13#3'Try again?',nil,mferror+mfyesbutton+mfnobutton)=cmYes then
  762. again:=true
  763. else
  764. errorhalt;
  765. end;
  766. until not again;
  767. end;
  768. {*****************************************************************************
  769. TEndDialog
  770. *****************************************************************************}
  771. constructor tenddialog.init;
  772. var
  773. R : TRect;
  774. P : PStaticText;
  775. Control : PButton;
  776. YB: word;
  777. {$IFNDEF UNIX}
  778. i : longint;
  779. S: string;
  780. WPath: boolean;
  781. MixedCasePath: boolean;
  782. {$ENDIF}
  783. {$IFDEF OS2}
  784. ErrPath: array [0..259] of char;
  785. Handle: longint;
  786. WLibPath: boolean;
  787. const
  788. EMXName: array [1..4] of char = 'EMX'#0;
  789. {$ENDIF}
  790. begin
  791. if haside then
  792. YB := 15
  793. else
  794. YB := 14;
  795. {$IFNDEF UNIX}
  796. s:='';
  797. for i:=1 to cfg.packs do
  798. if cfg.pack[i].binsub<>'' then
  799. begin
  800. if s<>'' then
  801. s:=s+';';
  802. S := s+Data.BasePath + Cfg.pack[i].BinSub;
  803. end;
  804. if Pos (Upper (S), Upper (GetEnv ('PATH'))) = 0 then
  805. begin
  806. WPath := true;
  807. Inc (YB, 3);
  808. end
  809. else
  810. WPath := false;
  811. { look if path is set as Path,
  812. this leads to problems for mingw32 make PM }
  813. MixedCasePath:=false;
  814. for i:=1 to EnvCount do
  815. begin
  816. if Pos('PATH=',Upper(EnvStr(i)))=1 then
  817. if Pos('PATH=',EnvStr(i))<>1 then
  818. Begin
  819. MixedCasePath:=true;
  820. Inc(YB, 2);
  821. End;
  822. end;
  823. {$IFDEF OS2}
  824. if DosLoadModule (@ErrPath, SizeOf (ErrPath), @EMXName, Handle) = 0 then
  825. begin
  826. WLibPath := false;
  827. DosFreeModule (Handle);
  828. end
  829. else
  830. begin
  831. WLibPath := true;
  832. Inc (YB, 2);
  833. end;
  834. {$ENDIF}
  835. {$ENDIF}
  836. R.Assign(6, 6, 74, YB);
  837. inherited init(r,'Installation Successful.');
  838. Options:=Options or ofCentered;
  839. {$IFNDEF UNIX}
  840. if WPath then
  841. begin
  842. R.Assign(2, 3, 64, 5);
  843. P:=new(pstatictext,init(r,'Extend your PATH variable with '''+S+''''));
  844. insert(P);
  845. end;
  846. if MixedCasePath then
  847. begin
  848. R.Assign(2, 5, 64, 6);
  849. P:=new(pstatictext,init(r,'You need to use setpath.bat file if you want to use Makefiles'));
  850. insert(P);
  851. end;
  852. {$IFDEF OS2}
  853. if WLibPath then
  854. begin
  855. if WPath then
  856. S := 'and your LIBPATH with ''' + S + '\dll'''
  857. else
  858. S := 'Extend your LIBPATH with ''' + S + '\dll''';
  859. R.Assign (2, YB - 14, 64, YB - 12);
  860. P := New (PStaticText, Init (R, S));
  861. Insert (P);
  862. end;
  863. {$ENDIF}
  864. {$ENDIF}
  865. R.Assign(2, YB - 13, 64, YB - 12);
  866. P:=new(pstatictext,init(r,'To compile files enter fpc [file]'''));
  867. insert(P);
  868. if haside then
  869. begin
  870. R.Assign(2, YB - 12, 64, YB - 10);
  871. P:=new(pstatictext,init(r,'To start the IDE (Integrated Development Environment) type ''fp'' at a command line prompt'));
  872. insert(P);
  873. end;
  874. R.Assign (29, YB - 9, 39, YB - 7);
  875. Control := New (PButton, Init (R,'~O~k', cmOK, bfDefault));
  876. Insert (Control);
  877. end;
  878. {*****************************************************************************
  879. TInstallDialog
  880. *****************************************************************************}
  881. {$ifdef MAYBE_LFN}
  882. var
  883. islfn : boolean;
  884. procedure lfnreport( Retcode : longint;Rec : pReportRec );
  885. var
  886. p : pathstr;
  887. n : namestr;
  888. e : extstr;
  889. begin
  890. fsplit(strpas(rec^.Filename),p,n,e);
  891. if (length(n)>8) or (length(e)>4) or
  892. (pos('.',n)>0) or (upper(p+n+e)<>upper(strpas(rec^.Filename))) then
  893. islfn:=true;
  894. end;
  895. function haslfn(const zipfile : string) : boolean;
  896. var
  897. buf : array[0..255] of char;
  898. begin
  899. strpcopy(buf,zipfile);
  900. islfn:=false;
  901. {$ifdef FPC}
  902. ViewZip(buf,AllFiles,@lfnreport);
  903. {$else FPC}
  904. ViewZip(buf,AllFiles,lfnreport);
  905. {$endif FPC}
  906. haslfn:=islfn;
  907. end;
  908. {$endif MAYBE_LFN}
  909. var
  910. AllFilesPresent : boolean;
  911. procedure presentreport( Retcode : longint;Rec : pReportRec );
  912. var
  913. st : string;
  914. f : file;
  915. size,time : longint;
  916. p : pathstr;
  917. n : namestr;
  918. e : extstr;
  919. begin
  920. if not ALLFilesPresent then
  921. exit;
  922. st:=Data.BasePath+strpas(rec^.Filename);
  923. fsplit(st,p,n,e);
  924. if not file_exists(n+e,p) then
  925. AllFilesPresent:=false
  926. else
  927. begin
  928. Assign(f,st);
  929. Reset(f,1);
  930. if IOresult<>0 then
  931. begin
  932. ALLfilesPresent:=false;
  933. exit;
  934. end;
  935. GetFtime(f,time);
  936. size:=FileSize(f);
  937. if (rec^.Time<>time) or (rec^.size<>size) then
  938. ALLFilesPresent:=false;
  939. close(f);
  940. end;
  941. end;
  942. function AreAllFilesPresent(const zipfile : string) : boolean;
  943. var
  944. buf : array[0..255] of char;
  945. begin
  946. strpcopy(buf,zipfile);
  947. AllFilesPresent:=true;
  948. {$ifdef FPC}
  949. ViewZip(buf,AllFiles,@presentreport);
  950. {$else FPC}
  951. ViewZip(buf,AllFiles,presentreport);
  952. {$endif FPC}
  953. AreAllFilesPresent:=AllFilesPresent;
  954. end;
  955. constructor tinstalldialog.init;
  956. const
  957. width = 76;
  958. height = 20;
  959. x1 = (79-width) div 2;
  960. y1 = (23-height) div 2;
  961. x2 = x1+width;
  962. y2 = y1+height;
  963. var
  964. tabr,tabir,r : trect;
  965. packmask : array[1..maxpacks] of longint;
  966. enabmask : array[1..maxpacks] of longint;
  967. i,line,j : integer;
  968. items : array[1..maxpacks] of psitem;
  969. f : pview;
  970. found : boolean;
  971. okbut,cancelbut : pbutton;
  972. firstitem : array[1..maxpacks] of integer;
  973. packcbs : array[1..maxpacks] of pcheckboxes;
  974. packtd : ptabdef;
  975. labpath : plabel;
  976. ilpath : pspecialinputline;
  977. tab : ptab;
  978. titletext : pcoloredtext;
  979. labcfg : plabel;
  980. cfgcb : pcheckboxes;
  981. scrollbox: pscrollbox;
  982. sbr,sbsbr: trect;
  983. sbsb: pscrollbar;
  984. zipfile : string;
  985. begin
  986. f:=nil;
  987. { walk packages reverse and insert a newsitem for each, and set the mask }
  988. for j:=1 to cfg.packs do
  989. with cfg.pack[j] do
  990. begin
  991. firstitem[j]:=0;
  992. items[j]:=nil;
  993. packmask[j]:=0;
  994. enabmask[j]:=0;
  995. for i:=packages downto 1 do
  996. begin
  997. zipfile:='';
  998. if file_exists(package[i].zip,startpath) then
  999. zipfile:=startpath+DirSep+package[i].zip
  1000. else if file_exists(package[i].zipshort,startpath) then
  1001. begin
  1002. zipfile:=startpath+DirSep+package[i].zipshort;
  1003. { update package to replace the full zipname with the short name }
  1004. package[i].zip:=package[i].zipshort;
  1005. end;
  1006. if zipfile<>'' then
  1007. begin
  1008. { get diskspace required }
  1009. package[i].diskspace:=diskspaceN(zipfile);
  1010. {$ifdef MAYBE_LFN}
  1011. if not(locallfnsupport) then
  1012. begin
  1013. if not(haslfn(zipfile)) then
  1014. begin
  1015. items[j]:=newsitem(package[i].name+diskspacestr(package[i].diskspace),items[j]);
  1016. packmask[j]:=packmask[j] or packagemask(i);
  1017. enabmask[j]:=enabmask[j] or packagemask(i);
  1018. firstitem[j]:=i-1;
  1019. if createlog then
  1020. writeln(log,'Checking lfn usage for ',zipfile,' ... no lfn');
  1021. end
  1022. else
  1023. begin
  1024. items[j]:=newsitem(package[i].name+' (requires LFN support)',items[j]);
  1025. enabmask[j]:=enabmask[j] or packagemask(i);
  1026. firstitem[j]:=i-1;
  1027. if createlog then
  1028. writeln(log,'Checking lfn usage for ',zipfile,' ... uses lfn');
  1029. end;
  1030. end
  1031. else
  1032. {$endif MAYBE_LFN}
  1033. begin
  1034. items[j]:=newsitem(package[i].name+diskspacestr(package[i].diskspace),items[j]);
  1035. packmask[j]:=packmask[j] or packagemask(i);
  1036. enabmask[j]:=enabmask[j] or packagemask(i);
  1037. firstitem[j]:=i-1;
  1038. end;
  1039. end
  1040. else
  1041. items[j]:=newsitem(package[i].name,items[j]);
  1042. end;
  1043. end;
  1044. { If no component found abort }
  1045. found:=false;
  1046. for j:=1 to cfg.packs do
  1047. if packmask[j]<>0 then
  1048. found:=true;
  1049. if not found then
  1050. begin
  1051. messagebox('No components found to install, aborting.',nil,mferror+mfokbutton);
  1052. if CreateLog then
  1053. WriteLn (Log, 'No components found to install, aborting.');
  1054. errorhalt;
  1055. end;
  1056. r.assign(x1,y1,x2,y2);
  1057. inherited init(r,'');
  1058. Options:=Options or ofCentered;
  1059. GetExtent(R);
  1060. R.Grow(-2,-1);
  1061. Dec(R.B.Y,2);
  1062. TabR.Copy(R);
  1063. TabIR.Copy(R);
  1064. TabIR.Grow(-2,-2);
  1065. TabIR.Move(-2,0);
  1066. {-------- General Sheets ----------}
  1067. R.Copy(TabIR);
  1068. r.move(0,1);
  1069. r.b.x:=r.a.x+40;
  1070. r.b.y:=r.a.y+1;
  1071. new(titletext,init(r,cfg.title,$71));
  1072. r.move(0,2);
  1073. r.b.x:=r.a.x+40;
  1074. new(labpath,init(r,'~B~ase path',f));
  1075. r.move(0,1);
  1076. r.b.x:=r.a.x+40;
  1077. r.b.y:=r.a.y+1;
  1078. new(ilpath,init(r,high(DirStr)));
  1079. r.move(0,2);
  1080. r.b.x:=r.a.x+40;
  1081. new(labcfg,init(r,'Con~f~ig',f));
  1082. r.move(0,1);
  1083. r.b.x:=r.a.x+40;
  1084. r.b.y:=r.a.y+1;
  1085. new(cfgcb,init(r,newsitem('create fpc.cfg',nil)));
  1086. data.cfgval:=1;
  1087. {-------- Pack Sheets ----------}
  1088. for j:=1 to cfg.packs do
  1089. begin
  1090. R.Copy(TabIR);
  1091. if R.A.Y+cfg.pack[j].packages>R.B.Y then
  1092. R.B.Y:=R.A.Y+cfg.pack[j].packages;
  1093. new(packcbs[j],init(r,items[j]));
  1094. if data.packmask[j]=high(sw_word) then
  1095. data.packmask[j]:=packmask[j];
  1096. packcbs[j]^.enablemask:={$ifdef DEV}$7fffffff{$else}enabmask[j]{$endif};
  1097. packcbs[j]^.sel:=firstitem[j];
  1098. end;
  1099. {--------- Main ---------}
  1100. packtd:=nil;
  1101. sbr.assign(1,3,tabr.b.x-tabr.a.x-3,tabr.b.y-tabr.a.y-1);
  1102. for j:=cfg.packs downto 1 do
  1103. begin
  1104. if (sbr.b.y-sbr.a.y)<cfg.pack[j].packages then
  1105. begin
  1106. sbsbr.assign(sbr.b.x,sbr.a.y,sbr.b.x+1,sbr.b.y);
  1107. New(sbsb, init(sbsbr));
  1108. end
  1109. else
  1110. sbsb:=nil;
  1111. New(ScrollBox, Init(sbr, nil, sbsb));
  1112. PackCbs[j]^.MoveTo(0,0);
  1113. ScrollBox^.Insert(PackCbs[j]);
  1114. packtd:=NewTabDef(
  1115. cfg.pack[j].name,ScrollBox,
  1116. NewTabItem(sbsb,
  1117. NewTabItem(ScrollBox,
  1118. nil)),
  1119. packtd);
  1120. end;
  1121. New(Tab, Init(TabR,
  1122. NewTabDef('~G~eneral',IlPath,
  1123. NewTabItem(TitleText,
  1124. NewTabItem(LabPath,
  1125. NewTabItem(ILPath,
  1126. NewTabItem(LabCfg,
  1127. NewTabItem(CfgCB,
  1128. nil))))),
  1129. packtd)
  1130. ));
  1131. Tab^.GrowMode:=0;
  1132. Insert(Tab);
  1133. line:=tabr.b.y;
  1134. r.assign((width div 2)-18,line,(width div 2)-4,line+2);
  1135. new(okbut,init(r,'~C~ontinue',cmok,bfdefault));
  1136. Insert(OkBut);
  1137. r.assign((width div 2)+4,line,(width div 2)+14,line+2);
  1138. new(cancelbut,init(r,'~Q~uit',cmcancel,bfnormal));
  1139. Insert(CancelBut);
  1140. Tab^.Select;
  1141. end;
  1142. procedure tinstalldialog.handleevent(var event : tevent);
  1143. begin
  1144. if event.what=evcommand then
  1145. if event.command=cmquit then
  1146. begin
  1147. putevent(event);
  1148. event.command:=cmCancel;
  1149. end;
  1150. inherited handleevent(event);
  1151. end;
  1152. {*****************************************************************************
  1153. TSpecialInputLine
  1154. *****************************************************************************}
  1155. { this should use AreAllFilesPresent if the base dir is changed...
  1156. but what if the installer has already choosen which files he wants ... }
  1157. procedure TSpecialInputLine.GetData(var Rec);
  1158. begin
  1159. inherited GetData(Rec);
  1160. end;
  1161. {*****************************************************************************
  1162. TApp
  1163. *****************************************************************************}
  1164. const
  1165. cmstart = 1000;
  1166. procedure tapp.do_installdialog;
  1167. var
  1168. p : pinstalldialog;
  1169. p3 : penddialog;
  1170. r : trect;
  1171. result,
  1172. c : word;
  1173. i,j : longint;
  1174. found : boolean;
  1175. {$ifndef Unix}
  1176. DSize,Space,ASpace : int64;
  1177. S: DirStr;
  1178. {$endif}
  1179. procedure doconfigwrite;
  1180. var
  1181. i : longint;
  1182. begin
  1183. for i:=1 to cfg.packs do
  1184. begin
  1185. if cfg.pack[i].defcfgfile<>'' then
  1186. writedefcfg(data.basepath+cfg.pack[i].binsub+DirSep+cfg.pack[i].defcfgfile,cfg.defcfg,cfg.defcfgs,cfg.pack[i].targetname);
  1187. if cfg.pack[i].setpathfile<>'' then
  1188. writedefcfg(data.basepath+cfg.pack[i].binsub+DirSep+cfg.pack[i].setpathfile,cfg.defsetpath,cfg.defsetpaths,cfg.pack[i].targetname);
  1189. end;
  1190. if haside then
  1191. begin
  1192. for i:=1 to cfg.packs do
  1193. if cfg.pack[i].defidecfgfile<>'' then
  1194. writedefcfg(data.basepath+cfg.pack[i].binsub+DirSep+cfg.pack[i].defidecfgfile,cfg.defidecfg,cfg.defidecfgs,cfg.pack[i].targetname);
  1195. for i:=1 to cfg.packs do
  1196. if cfg.pack[i].defideinifile<>'' then
  1197. writedefcfg(data.basepath+cfg.pack[i].binsub+DirSep+cfg.pack[i].defideinifile,cfg.defideini,cfg.defideinis,cfg.pack[i].targetname);
  1198. if hashtmlhelp then
  1199. writehlpindex(data.basepath+DirSep+cfg.DocSub+DirSep+cfg.helpidx);
  1200. end;
  1201. end;
  1202. begin
  1203. data.basepath:=cfg.basepath;
  1204. data.cfgval:=0;
  1205. for j:=1 to cfg.packs do
  1206. data.packmask[j]:=high(sw_word);
  1207. repeat
  1208. { select components }
  1209. p:=new(pinstalldialog,init);
  1210. c:=executedialog(p,@data);
  1211. if (c=cmok) then
  1212. begin
  1213. if Data.BasePath = '' then
  1214. messagebox('Please, choose the directory for installation first.',nil,mferror+mfokbutton)
  1215. else
  1216. begin
  1217. found:=false;
  1218. for j:=1 to cfg.packs do
  1219. if data.packmask[j]>0 then
  1220. found:=true;
  1221. if found then
  1222. begin
  1223. {$IFNDEF UNIX}
  1224. { TH - check the available disk space here }
  1225. DSize := 0;
  1226. for j:=1 to cfg.packs do
  1227. with cfg.pack[j] do
  1228. begin
  1229. for i:=1 to packages do
  1230. begin
  1231. if data.packmask[j] and packagemask(i)<>0 then
  1232. begin
  1233. ASpace := package[i].diskspace;
  1234. if ASpace = -1 then
  1235. MessageBox ('File ' + package[i].zip +
  1236. ' is probably corrupted!', nil,
  1237. mferror + mfokbutton)
  1238. else Inc (DSize, ASpace);
  1239. end;
  1240. end;
  1241. end;
  1242. if CreateLog then
  1243. WriteLn (Log, 'Diskspace needed: ',DotStr(DSize),' Kb');
  1244. S := FExpand (Data.BasePath);
  1245. if S [Length (S)] = DirSep then
  1246. Dec (S [0]);
  1247. Space := DiskFree (byte (Upcase(S [1])) - 64);
  1248. { -1 means that the drive is invalid }
  1249. if Space=-1 then
  1250. begin
  1251. if CreateLog then
  1252. WriteLn (Log, 'The drive '+S[1]+': is not valid');
  1253. if messagebox('The drive '+S[1]+': is not valid. Do you ' +
  1254. 'want to change the installation path?',nil,
  1255. mferror+mfyesbutton+mfnobutton) = cmYes then
  1256. Continue;
  1257. Space:=0;
  1258. end;
  1259. Space := Space shr 10;
  1260. if CreateLog then
  1261. WriteLn (Log, 'Free space on drive '+S[1]+': ',DotStr(Space),' Kb');
  1262. if Space < DSize then
  1263. S := 'is not '
  1264. else
  1265. S := '';
  1266. if (Space < DSize + 500) then
  1267. begin
  1268. if S = '' then
  1269. S := 'might not be ';
  1270. if messagebox('There ' + S + 'enough space on the target ' +
  1271. 'drive for all the selected components. Do you ' +
  1272. 'want to change the installation path?',nil,
  1273. mferror+mfyesbutton+mfnobutton) = cmYes then
  1274. Continue;
  1275. end;
  1276. {$ENDIF}
  1277. if createinstalldir(data.basepath) then
  1278. break;
  1279. end
  1280. else
  1281. begin
  1282. { maybe only config }
  1283. if (data.cfgval and 1)<>0 then
  1284. begin
  1285. result:=messagebox('No components selected.'#13#13'Create a configfile ?',nil,
  1286. mfinformation+mfyesbutton+mfnobutton);
  1287. if (result=cmYes) and createinstalldir(data.basepath) then
  1288. doconfigwrite;
  1289. exit;
  1290. end
  1291. else
  1292. begin
  1293. result:=messagebox('No components selected.'#13#13'Abort installation?',nil,
  1294. mferror+mfyesbutton+mfnobutton);
  1295. if result=cmYes then
  1296. exit;
  1297. end;
  1298. end;
  1299. end;
  1300. end
  1301. else
  1302. exit;
  1303. until false;
  1304. { extract packages }
  1305. for j:=1 to cfg.packs do
  1306. with cfg.pack[j] do
  1307. begin
  1308. r.assign(10,7,70,18);
  1309. UnzDlg:=new(punzipdialog,init(r,'Extracting Packages'));
  1310. desktop^.insert(UnzDlg);
  1311. for i:=1 to packages do
  1312. begin
  1313. if data.packmask[j] and packagemask(i)<>0 then
  1314. begin
  1315. UnzDlg^.do_unzip(package[i].zip,data.basepath);
  1316. { gather some information about the installed files }
  1317. if copy(package[i].zip,1,3)='ide' then
  1318. haside:=true;
  1319. if copy(package[i].zip,1,7)='doc-htm' then
  1320. begin
  1321. hashtmlhelp:=true;
  1322. { correct the fpctoc file name if .html files are used }
  1323. if package[i].zip='doc-html.zip' then
  1324. if copy(cfg.helpidx,length(cfg.helpidx)-3,4)='.htm' then
  1325. cfg.helpidx:=cfg.helpidx+'l';
  1326. end;
  1327. end;
  1328. end;
  1329. desktop^.delete(UnzDlg);
  1330. dispose(UnzDlg,done);
  1331. end;
  1332. { write config }
  1333. if (data.cfgval and 1)<>0 then
  1334. doconfigwrite;
  1335. { show end message }
  1336. p3:=new(penddialog,init);
  1337. executedialog(p3,nil);
  1338. end;
  1339. procedure tapp.readcfg(const fn:string);
  1340. var
  1341. t : text;
  1342. i,j,k,
  1343. line : longint;
  1344. item,
  1345. s,hs : string;
  1346. params : array[0..0] of pointer;
  1347. {$ifndef FPC}
  1348. procedure readln(var t:text;var s:string);
  1349. var
  1350. c : char;
  1351. i : longint;
  1352. begin
  1353. c:=#0;
  1354. i:=0;
  1355. while (not eof(t)) and (c<>#10) do
  1356. begin
  1357. read(t,c);
  1358. if c<>#10 then
  1359. begin
  1360. inc(i);
  1361. s[i]:=c;
  1362. end;
  1363. end;
  1364. if (i>0) and (s[i]=#13) then
  1365. dec(i);
  1366. s[0]:=chr(i);
  1367. end;
  1368. {$endif}
  1369. begin
  1370. assign(t,StartPath + DirSep + fn);
  1371. {$I-}
  1372. reset(t);
  1373. {$I+}
  1374. if ioresult<>0 then
  1375. begin
  1376. StartPath := GetProgDir;
  1377. assign(t,StartPath + DirSep + fn);
  1378. {$I-}
  1379. reset(t);
  1380. {$I+}
  1381. if ioresult<>0 then
  1382. begin
  1383. params[0]:=@fn;
  1384. messagebox('File %s not found!',@params,mferror+mfokbutton);
  1385. if CreateLog then
  1386. WriteLn (Log, 'File "' + fn + '" not found!');
  1387. errorhalt;
  1388. end;
  1389. end;
  1390. line:=0;
  1391. while not eof(t) do
  1392. begin
  1393. readln(t,s);
  1394. inc(line);
  1395. if (s<>'') and not(s[1] in ['#',';']) then
  1396. begin
  1397. i:=pos('=',s);
  1398. if i>0 then
  1399. begin
  1400. item:=upper(Copy(s,1,i-1));
  1401. system.delete(s,1,i);
  1402. if item='VERSION' then
  1403. cfg.version:=s
  1404. else
  1405. if item='TITLE' then
  1406. cfg.title:=s
  1407. else
  1408. if item='BASEPATH' then
  1409. cfg.basepath:=s
  1410. else
  1411. if item='HELPIDX' then
  1412. cfg.helpidx:=s
  1413. else
  1414. if item='DOCSUB' then
  1415. cfg.docsub:=s
  1416. else
  1417. if item='DEFAULTCFG' then
  1418. begin
  1419. repeat
  1420. readln(t,s);
  1421. if upper(s)='ENDCFG' then
  1422. break;
  1423. if cfg.defcfgs<maxdefcfgs then
  1424. begin
  1425. inc(cfg.defcfgs);
  1426. cfg.defcfg[cfg.defcfgs]:=newstr(s);
  1427. end;
  1428. until false;
  1429. end
  1430. else
  1431. if item='DEFAULTIDECFG' then
  1432. begin
  1433. repeat
  1434. readln(t,s);
  1435. if upper(s)='ENDCFG' then
  1436. break;
  1437. if cfg.defidecfgs<maxdefcfgs then
  1438. begin
  1439. inc(cfg.defidecfgs);
  1440. cfg.defidecfg[cfg.defidecfgs]:=newstr(s);
  1441. end;
  1442. until false;
  1443. end
  1444. else
  1445. if item='DEFAULTSETPATH' then
  1446. begin
  1447. repeat
  1448. readln(t,s);
  1449. if upper(s)='ENDCFG' then
  1450. break;
  1451. if cfg.defsetpaths<maxdefcfgs then
  1452. begin
  1453. inc(cfg.defsetpaths);
  1454. cfg.defsetpath[cfg.defsetpaths]:=newstr(s);
  1455. end;
  1456. until false;
  1457. end
  1458. else
  1459. if item='DEFAULTIDEINI' then
  1460. begin
  1461. repeat
  1462. readln(t,s);
  1463. if upper(s)='ENDCFG' then
  1464. break;
  1465. if cfg.defideinis<maxdefcfgs then
  1466. begin
  1467. inc(cfg.defideinis);
  1468. cfg.defideini[cfg.defideinis]:=newstr(s);
  1469. end;
  1470. until false;
  1471. end
  1472. else
  1473. if item='PACK' then
  1474. begin
  1475. inc(cfg.packs);
  1476. if cfg.packs>maxpacks then
  1477. begin
  1478. writeln('Too many packs');
  1479. if CreateLog then
  1480. begin
  1481. WriteLn (Log, 'Too many packs');
  1482. close(log);
  1483. end;
  1484. halt(1);
  1485. end;
  1486. cfg.pack[cfg.packs].name:=s;
  1487. end
  1488. else
  1489. if item='CFGFILE' then
  1490. begin
  1491. if cfg.packs=0 then
  1492. begin
  1493. writeln('No pack set');
  1494. if CreateLog then
  1495. begin
  1496. WriteLn (Log, 'No pack set');
  1497. close(Log);
  1498. end;
  1499. halt(1);
  1500. end;
  1501. cfg.pack[cfg.packs].defcfgfile:=s
  1502. end
  1503. else
  1504. if item='IDECFGFILE' then
  1505. begin
  1506. if cfg.packs=0 then
  1507. begin
  1508. writeln('No pack set');
  1509. if CreateLog then
  1510. begin
  1511. WriteLn (Log, 'No pack set');
  1512. Close(Log);
  1513. end;
  1514. halt(1);
  1515. end;
  1516. cfg.pack[cfg.packs].defidecfgfile:=s
  1517. end
  1518. else
  1519. if item='SETPATHFILE' then
  1520. begin
  1521. if cfg.packs=0 then
  1522. begin
  1523. writeln('No pack set');
  1524. if CreateLog then
  1525. begin
  1526. WriteLn (Log, 'No pack set');
  1527. close(Log);
  1528. end;
  1529. halt(1);
  1530. end;
  1531. cfg.pack[cfg.packs].setpathfile:=s
  1532. end
  1533. else
  1534. if item='IDEINIFILE' then
  1535. begin
  1536. if cfg.packs=0 then
  1537. begin
  1538. writeln('No pack set');
  1539. if CreateLog then
  1540. begin
  1541. WriteLn (Log, 'No pack set');
  1542. Close(Log);
  1543. end;
  1544. halt(1);
  1545. end;
  1546. cfg.pack[cfg.packs].defideinifile:=s
  1547. end
  1548. else
  1549. if item='PPC386' then
  1550. begin
  1551. if cfg.packs=0 then
  1552. begin
  1553. writeln('No pack set');
  1554. if CreateLog then
  1555. begin
  1556. WriteLn (Log, 'No pack set');
  1557. Close(Log);
  1558. end;
  1559. halt(1);
  1560. end;
  1561. cfg.pack[cfg.packs].ppc386:=s;
  1562. end
  1563. else
  1564. if item='BINSUB' then
  1565. begin
  1566. if cfg.packs=0 then
  1567. begin
  1568. writeln('No pack set');
  1569. if CreateLog then
  1570. begin
  1571. WriteLn (Log, 'No pack set');
  1572. Close(Log);
  1573. end;
  1574. halt(1);
  1575. end;
  1576. cfg.pack[cfg.packs].binsub:=s;
  1577. end
  1578. {else: Obsolete PM }
  1579. { if item='FILECHECK' then
  1580. begin
  1581. if cfg.packs=0 then
  1582. begin
  1583. writeln('No pack set');
  1584. if CreateLog then
  1585. WriteLn (Log, 'No pack set');
  1586. halt(1);
  1587. end;
  1588. cfg.pack[cfg.packs].filechk:=s;
  1589. end }
  1590. else
  1591. if item='TARGETNAME' then
  1592. begin
  1593. if cfg.packs=0 then
  1594. begin
  1595. writeln('No pack set');
  1596. if CreateLog then
  1597. begin
  1598. WriteLn (Log, 'No pack set');
  1599. Close(Log);
  1600. end;
  1601. halt(1);
  1602. end;
  1603. cfg.pack[cfg.packs].targetname:=s;
  1604. end
  1605. else
  1606. if item='PACKAGE' then
  1607. begin
  1608. if cfg.packs=0 then
  1609. begin
  1610. writeln('No pack set');
  1611. if CreateLog then
  1612. begin
  1613. WriteLn (Log, 'No pack set');
  1614. Close(Log);
  1615. end;
  1616. halt(1);
  1617. end;
  1618. with cfg.pack[cfg.packs] do
  1619. begin
  1620. j:=pos(',',s);
  1621. if (j>0) and (packages<maxpackages) then
  1622. begin
  1623. inc(packages);
  1624. hs:=copy(s,1,j-1);
  1625. k:=pos('[',hs);
  1626. if (k>0) then
  1627. begin
  1628. package[packages].zip:=Copy(hs,1,k-1);
  1629. package[packages].zipshort:=Copy(hs,k+1,length(hs)-k-1);
  1630. end
  1631. else
  1632. package[packages].zip:=hs;
  1633. package[packages].name:=copy(s,j+1,255);
  1634. end;
  1635. package[packages].diskspace:=-1;
  1636. end;
  1637. end
  1638. end;
  1639. end;
  1640. end;
  1641. close(t);
  1642. end;
  1643. procedure tapp.checkavailpack;
  1644. var
  1645. i, j : longint;
  1646. one_found : boolean;
  1647. begin
  1648. { check the packages }
  1649. j:=0;
  1650. while (j<cfg.packs) do
  1651. begin
  1652. inc(j);
  1653. one_found:=false;
  1654. {if cfg.pack[j].filechk<>'' then}
  1655. for i:=1 to cfg.pack[j].packages do
  1656. begin
  1657. if file_exists(cfg.pack[j].package[i].zip,startpath) or
  1658. file_exists(cfg.pack[j].package[i].zipshort,startpath) then
  1659. begin
  1660. one_found:=true;
  1661. break;
  1662. end;
  1663. end;
  1664. if not one_found then
  1665. begin
  1666. { remove the package }
  1667. move(cfg.pack[j+1],cfg.pack[j],sizeof(tpack)*(cfg.packs-j));
  1668. dec(cfg.packs);
  1669. dec(j);
  1670. end;
  1671. end;
  1672. end;
  1673. procedure tapp.initmenubar;
  1674. var
  1675. r : trect;
  1676. begin
  1677. getextent(r);
  1678. r.b.y:=r.a.y+1;
  1679. menubar:=new(pmenubar,init(r,newmenu(
  1680. newsubmenu('Free Pascal Installer',hcnocontext,newmenu(nil
  1681. ),
  1682. nil))));
  1683. end;
  1684. procedure tapp.handleevent(var event : tevent);
  1685. begin
  1686. inherited handleevent(event);
  1687. if event.what=evcommand then
  1688. if event.command=cmstart then
  1689. begin
  1690. clearevent(event);
  1691. do_installdialog;
  1692. if successfull then
  1693. begin
  1694. event.what:=evcommand;
  1695. event.command:=cmquit;
  1696. handleevent(event);
  1697. end;
  1698. end;
  1699. end;
  1700. {$IFDEF DOSSTUB}
  1701. function CheckOS2: boolean;
  1702. var
  1703. OwnName: PathStr;
  1704. OwnDir: DirStr;
  1705. Name: NameStr;
  1706. Ext: ExtStr;
  1707. DosV, W: word;
  1708. P: PChar;
  1709. const
  1710. Title: string [15] = 'FPC Installer'#0;
  1711. RunBlock: TRunBlock = (Length: $32;
  1712. Dependent: 0;
  1713. Background: 0;
  1714. TraceLevel: 0;
  1715. PrgTitle: @Title [1];
  1716. PrgName: nil;
  1717. Args: nil;
  1718. TermQ: 0;
  1719. Environment: nil;
  1720. Inheritance: 0;
  1721. SesType: 2;
  1722. Icon: nil;
  1723. PgmHandle: 0;
  1724. PgmControl: 2;
  1725. Column: 0;
  1726. Row: 0;
  1727. Width: 80;
  1728. Height: 25);
  1729. begin
  1730. CheckOS2 := false;
  1731. asm
  1732. mov ah, 30h
  1733. int 21h
  1734. xchg ah, al
  1735. mov DosV, ax
  1736. mov ax, 4010h
  1737. int 2Fh
  1738. cmp ax, 4010h
  1739. jnz @0
  1740. xor bx, bx
  1741. @0:
  1742. mov W, bx
  1743. end;
  1744. if DosV > 3 shl 8 then
  1745. begin
  1746. OwnName := FExpand (ParamStr (0));
  1747. FSplit (OwnName, OwnDir, Name, Ext);
  1748. if (DosV >= 20 shl 8 + 10) and (W >= 20 shl 8 + 10) then
  1749. (* OS/2 version 2.1 or later running (double-checked) *)
  1750. begin
  1751. OwnName [Succ (byte (OwnName [0]))] := #0;
  1752. RunBlock.PrgName := @OwnName [1];
  1753. P := Ptr (PrefixSeg, $80);
  1754. if PByte (P)^ <> 0 then
  1755. begin
  1756. Inc (P);
  1757. RunBlock.Args := Ptr (PrefixSeg, $81);
  1758. end;
  1759. asm
  1760. mov ax, 6400h
  1761. mov bx, 0025h
  1762. mov cx, 636Ch
  1763. mov si, offset RunBlock
  1764. int 21h
  1765. jc @0
  1766. mov DosV, 0
  1767. @0:
  1768. end;
  1769. CheckOS2 := DosV = 0;
  1770. end;
  1771. end;
  1772. end;
  1773. {$ENDIF}
  1774. procedure usagescreen;
  1775. begin
  1776. writeln('FPC Installer ',installerversion,' ',installercopyright);
  1777. writeln('Command line options:');
  1778. writeln(' -l create log file');
  1779. {$ifdef MAYBE_LFN}
  1780. writeln(' --nolfn force installation with short file names');
  1781. {$endif MAYBE_LFN}
  1782. writeln;
  1783. writeln(' -h displays this help');
  1784. end;
  1785. var
  1786. i : longint;
  1787. vm : tvideomode;
  1788. begin
  1789. { register objects for help streaming }
  1790. RegisterWHTMLScan;
  1791. {$IFDEF OS2}
  1792. { TH - no error boxes if checking an inaccessible disk etc. }
  1793. {$IFDEF FPC}
  1794. DosCalls.DosError (0);
  1795. {$ELSE FPC}
  1796. {$IFDEF VirtualPascal}
  1797. OS2Base.DosError (ferr_DisableHardErr);
  1798. {$ELSE VirtualPascal}
  1799. BseDos.DosError (0);
  1800. {$ENDIF VirtualPascal}
  1801. {$ENDIF FPC}
  1802. {$ENDIF}
  1803. {$IFDEF DOSSTUB}
  1804. if CheckOS2 then Halt;
  1805. {$ENDIF}
  1806. createlog:=false;
  1807. {$ifdef MAYBE_LFN}
  1808. locallfnsupport:=system.lfnsupport;
  1809. {$endif MAYBE_LFN}
  1810. for i:=1 to paramcount do
  1811. begin
  1812. if paramstr(i)='-l' then
  1813. createlog:=true
  1814. {$ifdef MAYBE_LFN}
  1815. else if paramstr(i)='--nolfn' then
  1816. begin
  1817. locallfnsupport:=false;
  1818. {$ifdef GO32V2}
  1819. { lfnsupport is a const in win32 RTL }
  1820. system.lfnsupport:=locallfnsupport;
  1821. {$endif GO32V2}
  1822. end
  1823. {$endif MAYBE_LFN}
  1824. else if paramstr(i)='-h' then
  1825. begin
  1826. usagescreen;
  1827. halt(0);
  1828. end
  1829. else
  1830. begin
  1831. usagescreen;
  1832. halt(1);
  1833. end;
  1834. end;
  1835. if createlog then
  1836. begin
  1837. assign(log,'install.log');
  1838. rewrite(log);
  1839. {$ifdef MAYBE_LFN}
  1840. if not(locallfnsupport) then
  1841. writeln(log,'OS doesn''t have LFN support');
  1842. {$endif}
  1843. end;
  1844. getdir(0,startpath);
  1845. successfull:=false;
  1846. fillchar(cfg, SizeOf(cfg), 0);
  1847. fillchar(data, SizeOf(data), 0);
  1848. installapp.init;
  1849. vm.col:=80;
  1850. vm.row:=25;
  1851. vm.color:=true;
  1852. installapp.SetScreenVideoMode(vm);
  1853. FSplit (FExpand (ParamStr (0)), DStr, CfgName, EStr);
  1854. installapp.readcfg(CfgName + CfgExt);
  1855. installapp.checkavailpack;
  1856. { installapp.readcfg(startpath+dirsep+cfgfile);}
  1857. {$ifdef GO32V2}
  1858. if not(lfnsupport) then
  1859. MessageBox('The operating system doesn''t support LFN (long file names),'+
  1860. ' so some packages will get shorten filenames when installed',nil,mfinformation or mfokbutton);
  1861. {$endif}
  1862. installapp.do_installdialog;
  1863. installapp.done;
  1864. if createlog then
  1865. close(log);
  1866. end.
  1867. {
  1868. $Log$
  1869. Revision 1.26 2005-01-05 17:43:44 armin
  1870. * maxpacks increased tp 30, close logfile before halt
  1871. Revision 1.25 2004/12/31 18:36:44 florian
  1872. * spelling fixed
  1873. * compiler is fpc instead ppc386
  1874. Revision 1.24 2004/12/23 17:36:53 peter
  1875. use %token% macros instead of $1 and $2
  1876. Revision 1.23 2004/12/22 15:28:48 peter
  1877. * more fixes for win32 installer
  1878. Revision 1.22 2004/12/21 18:52:31 peter
  1879. checkbox mask works, scrollbox still not
  1880. Revision 1.21 2004/12/20 18:27:00 peter
  1881. * win32 fixes
  1882. Revision 1.20 2004/12/18 16:19:57 peter
  1883. win32 fixes
  1884. Revision 1.19 2003/04/06 15:56:25 carl
  1885. * Use FPC user screen for Win32 target
  1886. Revision 1.18 2003/03/05 21:12:32 hajny
  1887. * missing quotes in GO32v2-specific part
  1888. Revision 1.17 2003/03/01 16:15:42 hajny
  1889. + logging enhanced
  1890. Revision 1.16 2003/02/08 21:49:59 carl
  1891. * DOS : fix user screen problem
  1892. DOS: emu386 reinstated
  1893. Revision 1.15 2003/01/22 14:15:13 pierre
  1894. * center all dialogs
  1895. Revision 1.14 2003/01/22 13:42:35 pierre
  1896. * fix problem with Alt-X (webbug 1959)
  1897. + use fpusrscr unit to restore console at exit.
  1898. Revision 1.13 2002/09/07 15:40:59 peter
  1899. * old logs removed and tabs fixed
  1900. Revision 1.12 2002/07/06 11:51:04 carl
  1901. + Unzip DLL fixes for warnings
  1902. Revision 1.11 2002/06/02 17:24:27 marco
  1903. * Renamefest
  1904. Revision 1.10 2002/06/01 19:43:07 marco
  1905. * Renamefest
  1906. Revision 1.9 2002/04/11 13:20:27 pierre
  1907. + several go32v2 related fixes
  1908. Revision 1.8 2002/04/10 21:18:42 pierre
  1909. * explicitly check if one of the files from the list of each package exists
  1910. Revision 1.7 2002/04/03 12:46:02 pierre
  1911. + create setpath.bat file if Path is mixed
  1912. Revision 1.6 2002/03/19 09:14:56 pierre
  1913. * fix fpctoc.html problem
  1914. Revision 1.5 2002/03/13 22:27:36 pierre
  1915. * fix problem if invalid drive is given
  1916. Revision 1.4 2002/02/28 21:30:34 peter
  1917. * regenated
  1918. Revision 1.3 2002/02/28 17:02:08 pierre
  1919. * fix win32 compilation if DEBUG cond is set
  1920. Revision 1.2 2002/01/29 22:01:17 peter
  1921. * support fvision
  1922. Revision 1.1 2002/01/29 17:59:15 peter
  1923. * moved installer
  1924. }