install.pas 58 KB

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