install.pas 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183
  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 FV} (* TH - added to make use of the original Turbo Vision possible. *)
  15. { $DEFINE DLL} (* TH - if defined, UNZIP32.DLL library is used to unpack. *)
  16. { $DEFINE DOSSTUB} (* TH - should _not_ be defined unless creating a bound DOS and OS/2 installer!!! *)
  17. (* Defining DOSSTUB causes adding a small piece of code *)
  18. (* for starting the OS/2 part from the DOS part of a bound *)
  19. (* application if running in OS/2 VDM (DOS) window. Used *)
  20. (* only if compiling with TP/BP (see conditionals below). *)
  21. {$IFDEF VER60}
  22. {$DEFINE TP}
  23. {$ENDIF}
  24. {$IFDEF VER70}
  25. {$DEFINE TP}
  26. {$ENDIF}
  27. {$IFNDEF TP}
  28. {$UNDEF DOSSTUB}
  29. {$ELSE}
  30. {$IFDEF OS2}
  31. {$UNDEF DOSSTUB}
  32. {$ENDIF}
  33. {$ENDIF}
  34. {$IFDEF OS2}
  35. {$UNDEF FV}
  36. {$IFDEF VIRTUALPASCAL}
  37. {$DEFINE DLL}
  38. {$ENDIF}
  39. {$ENDIF}
  40. {$IFDEF DPMI}
  41. {$UNDEF DOSSTUB}
  42. {$ENDIF}
  43. uses
  44. {$IFDEF OS2}
  45. {$IFDEF FPC}
  46. DosCalls,
  47. {$ELSE FPC}
  48. {$IFDEF VirtualPascal}
  49. OS2Base,
  50. {$ELSE VirtualPascal}
  51. BseDos,
  52. {$ENDIF VirtualPascal}
  53. {$ENDIF FPC}
  54. {$ENDIF OS2}
  55. {$ifdef HEAPTRC}
  56. heaptrc,
  57. {$endif HEAPTRC}
  58. strings,dos,objects,drivers,
  59. {$IFDEF FV}
  60. commands,
  61. {$ENDIF}
  62. unzip,ziptypes,
  63. {$IFDEF DLL}
  64. unzipdll,
  65. {$ENDIF}
  66. app,dialogs,views,menus,msgbox,colortxt,tabs;
  67. const
  68. installerversion='0.99.14';
  69. maxpacks=10;
  70. maxpackages=20;
  71. maxdefcfgs=1024;
  72. CfgExt = '.dat';
  73. {$ifdef linux}
  74. DirSep='/';
  75. {$else}
  76. DirSep='\';
  77. {$endif}
  78. type
  79. tpackage=record
  80. name : string[60];
  81. zip : string[12];
  82. end;
  83. tpack=record
  84. name : string[12];
  85. include : boolean;
  86. filechk : string[40];
  87. packages : longint;
  88. package : array[1..maxpackages] of tpackage;
  89. end;
  90. cfgrec=record
  91. title : string[80];
  92. version : string[20];
  93. basepath : DirStr;
  94. binsub : string[12];
  95. ppc386 : string[12];
  96. packs : word;
  97. pack : array[1..maxpacks] of tpack;
  98. defcfgfile : string[12];
  99. defcfgs : longint;
  100. defcfg : array[1..maxdefcfgs] of pstring;
  101. end;
  102. datarec=packed record
  103. basepath : DirStr;
  104. cfgval : word;
  105. packmask : array[1..maxpacks] of word;
  106. end;
  107. punzipdialog=^tunzipdialog;
  108. tunzipdialog=object(tdialog)
  109. filetext : pstatictext;
  110. constructor Init(var Bounds: TRect; ATitle: TTitleStr);
  111. procedure do_unzip(s,topath:string);
  112. end;
  113. penddialog = ^tenddialog;
  114. tenddialog = object(tdialog)
  115. constructor init;
  116. end;
  117. pinstalldialog = ^tinstalldialog;
  118. tinstalldialog = object(tdialog)
  119. constructor init;
  120. end;
  121. tapp = object(tapplication)
  122. procedure initmenubar;virtual;
  123. procedure handleevent(var event : tevent);virtual;
  124. procedure do_installdialog;
  125. procedure readcfg(const fn:string);
  126. procedure checkavailpack;
  127. end;
  128. {$IFDEF DOSSTUB}
  129. PByte = ^byte;
  130. PRunBlock = ^TRunBlock;
  131. TRunBlock = record
  132. Length: word;
  133. Dependent: word;
  134. Background: word;
  135. TraceLevel: word;
  136. PrgTitle: PChar;
  137. PrgName: PChar;
  138. Args: PChar;
  139. TermQ: longint;
  140. Environment: pointer;
  141. Inheritance: word;
  142. SesType: word;
  143. Icon: pointer;
  144. PgmHandle: longint;
  145. PgmControl: word;
  146. Column: word;
  147. Row: word;
  148. Width: word;
  149. Height: word;
  150. end;
  151. {$ENDIF}
  152. var
  153. installapp : tapp;
  154. startpath : string;
  155. successfull : boolean;
  156. cfg : cfgrec;
  157. data : datarec;
  158. CfgName: NameStr;
  159. DStr: DirStr;
  160. EStr: ExtStr;
  161. {*****************************************************************************
  162. Helpers
  163. *****************************************************************************}
  164. procedure errorhalt;
  165. begin
  166. installapp.done;
  167. halt(1);
  168. end;
  169. function packagemask(i:longint):longint;
  170. begin
  171. packagemask:=1 shl (i-1);
  172. end;
  173. function upper(const s : string):string;
  174. var
  175. i : integer;
  176. begin
  177. for i:=1 to length(s) do
  178. if s[i] in ['a'..'z'] then
  179. upper[i]:=chr(ord(s[i])-32)
  180. else
  181. upper[i]:=s[i];
  182. upper[0]:=s[0];
  183. end;
  184. procedure Replace(var s:string;const s1,s2:string);
  185. var
  186. i : longint;
  187. begin
  188. repeat
  189. i:=pos(s1,s);
  190. if i>0 then
  191. begin
  192. Delete(s,i,length(s1));
  193. Insert(s2,s,i);
  194. end;
  195. until i=0;
  196. end;
  197. function file_exists(const f : string;const path : string) : boolean;
  198. begin
  199. file_exists:=fsearch(f,path)<>'';
  200. end;
  201. function createdir(s:string):boolean;
  202. var
  203. s1,start : string;
  204. err : boolean;
  205. i : longint;
  206. begin
  207. err:=false;
  208. {$I-}
  209. getdir(0,start);
  210. {$ifndef linux}
  211. if (s[2]=':') and (s[3]=DirSep) then
  212. begin
  213. chdir(Copy(s,1,3));
  214. Delete(S,1,3);
  215. end;
  216. {$endif}
  217. repeat
  218. i:=Pos(DirSep,s);
  219. if i=0 then
  220. i:=255;
  221. s1:=Copy(s,1,i-1);
  222. Delete(s,1,i);
  223. ChDir(s1);
  224. if ioresult<>0 then
  225. begin
  226. mkdir(s1);
  227. chdir(s1);
  228. if ioresult<>0 then
  229. begin
  230. err:=true;
  231. break;
  232. end;
  233. end;
  234. until s='';
  235. chdir(start);
  236. {$I+}
  237. createdir:=err;
  238. end;
  239. function DiskSpaceN(const zipfile : string) : longint;
  240. var
  241. compressed,uncompressed : longint;
  242. s : string;
  243. begin
  244. s:=zipfile+#0;
  245. uncompressed:=UnzipSize(@s[1],compressed);
  246. DiskSpaceN:=uncompressed shr 10;
  247. end;
  248. function diskspace(const zipfile : string) : string;
  249. var
  250. uncompressed : longint;
  251. s : string;
  252. begin
  253. uncompressed:=DiskSpaceN (zipfile);
  254. str(uncompressed,s);
  255. diskspace:=' ('+s+' KB)';
  256. end;
  257. function createinstalldir(s : string) : boolean;
  258. var
  259. err : boolean;
  260. dir : searchrec;
  261. params : array[0..0] of pointer;
  262. begin
  263. if s[length(s)]=DirSep then
  264. dec(s[0]);
  265. FindFirst(s,AnyFile,dir);
  266. if doserror=0 then
  267. begin
  268. if Dir.Attr and Directory = 0 then
  269. begin
  270. messagebox('A file with the name chosen as the installation '+
  271. 'directory exists already. Cannot create this directory!',nil,
  272. mferror+mfokbutton);
  273. createinstalldir:=false;
  274. end else
  275. createinstalldir:=messagebox('The installation directory exists already. '+
  276. 'Do you want to continue ?',nil,
  277. mferror+mfyesbutton+mfnobutton)=cmYes;
  278. exit;
  279. end;
  280. err:=Createdir(s);
  281. if err then
  282. begin
  283. params[0]:=@s;
  284. messagebox('The installation directory %s couldn''t be created',
  285. @params,mferror+mfokbutton);
  286. createinstalldir:=false;
  287. exit;
  288. end;
  289. {$ifndef TP}
  290. {$IFNDEF OS2}
  291. FindClose (dir);
  292. {$ENDIF}
  293. {$endif}
  294. createinstalldir:=true;
  295. end;
  296. function GetProgDir: DirStr;
  297. var
  298. D: DirStr;
  299. N: NameStr;
  300. E: ExtStr;
  301. begin
  302. FSplit (FExpand (ParamStr (0)), D, N, E);
  303. if (D [0] <> #0) and (D [byte (D [0])] = '\') then Dec (D [0]);
  304. GetProgDir := D;
  305. end;
  306. {*****************************************************************************
  307. Writing of ppc386.cfg
  308. *****************************************************************************}
  309. procedure writedefcfg(const fn:string);
  310. var
  311. t : text;
  312. i : longint;
  313. s : string;
  314. dir : searchrec;
  315. params : array[0..0] of pointer;
  316. d : dirstr;
  317. n : namestr;
  318. e : extstr;
  319. begin
  320. { already exists }
  321. findfirst(fn,AnyFile,dir);
  322. if doserror=0 then
  323. begin
  324. params[0]:=@fn;
  325. if MessageBox('Config %s already exists, continue writing default config?',@params,
  326. mfinformation+mfyesbutton+mfnobutton)=cmNo then
  327. exit;
  328. end;
  329. { create directory }
  330. fsplit(fn,d,n,e);
  331. createdir(d);
  332. { create the ppc386.cfg }
  333. assign(t,fn);
  334. {$I-}
  335. rewrite(t);
  336. {$I+}
  337. if ioresult<>0 then
  338. begin
  339. params[0]:=@fn;
  340. MessageBox(#3'Default config not written.'#13#3'%s'#13#3'couldn''t be created',@params,mfinformation+mfokbutton);
  341. exit;
  342. end;
  343. for i:=1 to cfg.defcfgs do
  344. if assigned(cfg.defcfg[i]) then
  345. begin
  346. s:=cfg.defcfg[i]^;
  347. Replace(s,'$1',data.basepath);
  348. writeln(t,s);
  349. end
  350. else
  351. writeln(t,'');
  352. close(t);
  353. end;
  354. {*****************************************************************************
  355. TUnZipDialog
  356. *****************************************************************************}
  357. constructor tunzipdialog.Init(var Bounds: TRect; ATitle: TTitleStr);
  358. var
  359. r : trect;
  360. begin
  361. inherited init(bounds,atitle);
  362. R.Assign(11, 4, 38, 5);
  363. filetext:=new(pstatictext,init(r,'File: '));
  364. insert(filetext);
  365. end;
  366. procedure tunzipdialog.do_unzip(s,topath : string);
  367. var
  368. again : boolean;
  369. fn,dir,wild : string;
  370. begin
  371. Disposestr(filetext^.text);
  372. filetext^.Text:=NewStr('File: '+s);
  373. filetext^.drawview;
  374. if not(file_exists(s,startpath)) then
  375. begin
  376. messagebox('File: '+s+' missed for the selected installation. '+
  377. 'Installation doesn''t becomes complete',nil,mferror+mfokbutton);
  378. errorhalt;
  379. end;
  380. repeat
  381. fn:=startpath+DirSep+s+#0;
  382. dir:=topath+#0;
  383. wild:=AllFiles + #0;
  384. DosError := 0;
  385. again:=false;
  386. {$IFDEF DLL}
  387. if FileUnzipEx(@fn[1],@dir[1],@wild[1])=0 then
  388. {$ELSE}
  389. FileUnzipEx(@fn[1],@dir[1],@wild[1]);
  390. if (doserror<>0) then
  391. {$ENDIF}
  392. begin
  393. if messagebox('Error when extracting. Disk full?'#13+
  394. #13#3'Try again?',nil,mferror+mfyesbutton+mfnobutton)=cmNo then
  395. errorhalt
  396. else
  397. again:=true;
  398. end;
  399. until not again;
  400. end;
  401. {*****************************************************************************
  402. TEndDialog
  403. *****************************************************************************}
  404. constructor tenddialog.init;
  405. var
  406. R : TRect;
  407. P : PStaticText;
  408. Control : PButton;
  409. YB: word;
  410. {$IFNDEF LINUX}
  411. S: string;
  412. WPath: boolean;
  413. {$ENDIF}
  414. {$IFDEF OS2}
  415. ErrPath: array [0..259] of char;
  416. Handle: longint;
  417. WLibPath: boolean;
  418. const
  419. EMXName: array [1..4] of char = 'EMX'#0;
  420. {$ENDIF}
  421. begin
  422. YB := 14;
  423. {$IFNDEF LINUX}
  424. S := Data.BasePath + Cfg.BinSub;
  425. if Pos (Upper (S), Upper (GetEnv ('PATH'))) = 0 then
  426. begin
  427. WPath := true;
  428. Inc (YB, 2);
  429. end else WPath := false;
  430. {$IFDEF OS2}
  431. if DosLoadModule (@ErrPath, SizeOf (ErrPath), @EMXName, Handle) = 0 then
  432. begin
  433. WLibPath := false;
  434. DosFreeModule (Handle);
  435. end else
  436. begin
  437. WLibPath := true;
  438. Inc (YB, 2);
  439. end;
  440. {$ENDIF}
  441. {$ENDIF}
  442. R.Assign(6, 6, 74, YB);
  443. inherited init(r,'Installation Successfull');
  444. {$IFNDEF LINUX}
  445. if WPath then
  446. begin
  447. R.Assign(2, 3, 64, 5);
  448. P:=new(pstatictext,init(r,'Extend your PATH variable with '''+S+''''));
  449. insert(P);
  450. end;
  451. {$IFDEF OS2}
  452. if WLibPath then
  453. begin
  454. if WPath then S := 'and your LIBPATH with ''' + S + '\dll''' else
  455. S := 'Extend your LIBPATH with ''' + S + '\dll''';
  456. R.Assign (2, YB - 13, 64, YB - 11);
  457. P := New (PStaticText, Init (R, S));
  458. Insert (P);
  459. end;
  460. {$ENDIF}
  461. {$ENDIF}
  462. R.Assign(2, YB - 11, 64, YB - 10);
  463. P:=new(pstatictext,init(r,'To compile files enter '''+cfg.ppc386+' [file]'''));
  464. insert(P);
  465. R.Assign (29, YB - 9, 39, YB - 7);
  466. Control := New (PButton, Init (R,'~O~k', cmOK, bfDefault));
  467. Insert (Control);
  468. end;
  469. {*****************************************************************************
  470. TInstallDialog
  471. *****************************************************************************}
  472. constructor tinstalldialog.init;
  473. const
  474. width = 76;
  475. height = 20;
  476. x1 = (79-width) div 2;
  477. y1 = (23-height) div 2;
  478. x2 = x1+width;
  479. y2 = y1+height;
  480. var
  481. tabr,tabir,r : trect;
  482. packmask : array[1..maxpacks] of longint;
  483. i,line,j : integer;
  484. items : array[1..maxpacks] of psitem;
  485. f : pview;
  486. found : boolean;
  487. okbut,cancelbut : pbutton;
  488. firstitem : array[1..maxpacks] of integer;
  489. packcbs : array[1..maxpacks] of pcheckboxes;
  490. packtd : ptabdef;
  491. labpath : plabel;
  492. ilpath : pinputline;
  493. tab : ptab;
  494. titletext : pcoloredtext;
  495. labcfg : plabel;
  496. cfgcb : pcheckboxes;
  497. begin
  498. f:=nil;
  499. { walk packages reverse and insert a newsitem for each, and set the mask }
  500. for j:=1to cfg.packs do
  501. with cfg.pack[j] do
  502. begin
  503. firstitem[j]:=0;
  504. items[j]:=nil;
  505. packmask[j]:=0;
  506. for i:=packages downto 1 do
  507. begin
  508. if file_exists(package[i].zip,startpath) then
  509. begin
  510. items[j]:=newsitem(package[i].name+diskspace(startpath+DirSep+package[i].zip),items[j]);
  511. packmask[j]:=packmask[j] or packagemask(i);
  512. firstitem[j]:=i;
  513. end
  514. else
  515. items[j]:=newsitem(package[i].name,items[j]);
  516. end;
  517. end;
  518. { If no component found abort }
  519. found:=false;
  520. for j:=1to cfg.packs do
  521. if packmask[j]<>0 then
  522. found:=true;
  523. if not found then
  524. begin
  525. messagebox('No components found to install, aborting.',nil,mferror+mfokbutton);
  526. errorhalt;
  527. end;
  528. r.assign(x1,y1,x2,y2);
  529. inherited init(r,'');
  530. GetExtent(R);
  531. R.Grow(-2,-1);
  532. Dec(R.B.Y,2);
  533. TabR.Copy(R);
  534. TabIR.Copy(R);
  535. TabIR.Grow(-2,-2);
  536. TabIR.Move(-2,0);
  537. {-------- General Sheets ----------}
  538. R.Copy(TabIR);
  539. r.move(0,1);
  540. r.b.x:=r.a.x+40;
  541. r.b.y:=r.a.y+1;
  542. new(titletext,init(r,cfg.title,$71));
  543. r.move(0,2);
  544. r.b.x:=r.a.x+40;
  545. new(labpath,init(r,'~B~ase path',f));
  546. r.move(0,1);
  547. r.b.x:=r.a.x+40;
  548. r.b.y:=r.a.y+1;
  549. new(ilpath,init(r,high(DirStr)));
  550. r.move(0,2);
  551. r.b.x:=r.a.x+40;
  552. new(labcfg,init(r,'Con~f~ig',f));
  553. r.move(0,1);
  554. r.b.x:=r.a.x+40;
  555. r.b.y:=r.a.y+1;
  556. new(cfgcb,init(r,newsitem('create ppc386.cfg',nil)));
  557. data.cfgval:=1;
  558. {-------- Pack Sheets ----------}
  559. for j:=1to cfg.packs do
  560. begin
  561. R.Copy(TabIR);
  562. new(packcbs[j],init(r,items[j]));
  563. if data.packmask[j]=$ffff then
  564. data.packmask[j]:=packmask[j];
  565. packcbs[j]^.enablemask:=packmask[j];
  566. packcbs[j]^.movedto(firstitem[j]);
  567. end;
  568. {--------- Main ---------}
  569. packtd:=nil;
  570. for j:=cfg.packs downto 1 do
  571. packtd:=NewTabDef(cfg.pack[j].name,PackCbs[j],NewTabItem(PackCbs[j],nil),packtd);
  572. New(Tab, Init(TabR,
  573. NewTabDef('~G~eneral',IlPath,
  574. NewTabItem(TitleText,
  575. NewTabItem(LabPath,
  576. NewTabItem(ILPath,
  577. NewTabItem(LabCfg,
  578. NewTabItem(CfgCB,
  579. nil))))),
  580. packtd)
  581. ));
  582. Tab^.GrowMode:=0;
  583. Insert(Tab);
  584. line:=tabr.b.y;
  585. r.assign((width div 2)-18,line,(width div 2)-4,line+2);
  586. new(okbut,init(r,'~C~ontinue',cmok,bfdefault));
  587. Insert(OkBut);
  588. r.assign((width div 2)+4,line,(width div 2)+14,line+2);
  589. new(cancelbut,init(r,'~Q~uit',cmcancel,bfnormal));
  590. Insert(CancelBut);
  591. Tab^.Select;
  592. end;
  593. {*****************************************************************************
  594. TApp
  595. *****************************************************************************}
  596. const
  597. cmstart = 1000;
  598. procedure tapp.do_installdialog;
  599. var
  600. p : pinstalldialog;
  601. p2 : punzipdialog;
  602. p3 : penddialog;
  603. r : trect;
  604. result,
  605. c : word;
  606. i,j : longint;
  607. found : boolean;
  608. {$ifndef linux}
  609. DSize,Space : longint;
  610. S: DirStr;
  611. {$endif}
  612. begin
  613. data.basepath:=cfg.basepath;
  614. data.cfgval:=0;
  615. for j:=1to cfg.packs do
  616. data.packmask[j]:=$ffff;
  617. repeat
  618. { select components }
  619. p:=new(pinstalldialog,init);
  620. c:=executedialog(p,@data);
  621. if (c=cmok) then
  622. begin
  623. if Data.BasePath = '' then
  624. messagebox('Please, choose the directory for installation first.',nil,mferror+mfokbutton)
  625. else
  626. begin
  627. found:=false;
  628. for j:=1to cfg.packs do
  629. if data.packmask[j]>0 then
  630. found:=true;
  631. if found then
  632. begin
  633. {$IFNDEF LINUX}
  634. { TH - check the available disk space here }
  635. DSize := 0;
  636. for j:=1to cfg.packs do
  637. with cfg.pack[j] do
  638. begin
  639. for i:=1 to packages do
  640. begin
  641. if data.packmask[j] and packagemask(i)<>0 then
  642. Inc (DSize, DiskSpaceN(package[i].zip));
  643. end;
  644. end;
  645. S := FExpand (Data.BasePath);
  646. if S [Length (S)] = DirSep then
  647. Dec (S [0]);
  648. Space := DiskFree (byte (S [1]) - 64) shr 10;
  649. if Space < DSize then
  650. S := 'is not'
  651. else
  652. S := '';
  653. if true or (Space < DSize + 500) then
  654. begin
  655. if S = '' then
  656. S := 'might not be';
  657. if messagebox('There ' + S + ' enough space on the target ' +
  658. 'drive for all the selected components. Do you ' +
  659. 'want to change the installation path?',nil,
  660. mferror+mfyesbutton+mfnobutton) = cmYes then
  661. Continue;
  662. end;
  663. {$ENDIF}
  664. if createinstalldir(data.basepath) then
  665. break;
  666. end
  667. else
  668. begin
  669. { maybe only config }
  670. if (data.cfgval and 1)<>0 then
  671. begin
  672. result:=messagebox('No components selected.'#13#13'Create a configfile ?',nil,mfinformation+mfyesbutton+mfnobutton);
  673. if (result=cmYes) and createinstalldir(data.basepath) then
  674. writedefcfg(data.basepath+cfg.binsub+DirSep+cfg.defcfgfile);
  675. exit;
  676. end
  677. else
  678. begin
  679. result:=messagebox('No components selected.'#13#13'Abort installation?',nil,mferror+mfyesbutton+mfnobutton);
  680. if result=cmYes then
  681. exit;
  682. end;
  683. end;
  684. end;
  685. end
  686. else
  687. exit;
  688. until false;
  689. { extract packages }
  690. for j:=1 to cfg.packs do
  691. with cfg.pack[j] do
  692. begin
  693. r.assign(20,7,60,16);
  694. p2:=new(punzipdialog,init(r,'Extracting Packages'));
  695. desktop^.insert(p2);
  696. for i:=1 to packages do
  697. begin
  698. if data.packmask[j] and packagemask(i)<>0 then
  699. p2^.do_unzip(package[i].zip,data.basepath);
  700. end;
  701. desktop^.delete(p2);
  702. dispose(p2,done);
  703. end;
  704. { write config }
  705. if (data.cfgval and 1)<>0 then
  706. writedefcfg(data.basepath+cfg.binsub+DirSep+cfg.defcfgfile);
  707. { show end message }
  708. p3:=new(penddialog,init);
  709. executedialog(p3,nil);
  710. end;
  711. procedure tapp.readcfg(const fn:string);
  712. var
  713. t : text;
  714. i,j,
  715. line : longint;
  716. item,
  717. s : string;
  718. params : array[0..0] of pointer;
  719. {$ifndef FPC}
  720. procedure readln(var t:text;var s:string);
  721. var
  722. c : char;
  723. i : longint;
  724. begin
  725. c:=#0;
  726. i:=0;
  727. while (not eof(t)) and (c<>#10) do
  728. begin
  729. read(t,c);
  730. if c<>#10 then
  731. begin
  732. inc(i);
  733. s[i]:=c;
  734. end;
  735. end;
  736. if (i>0) and (s[i]=#13) then
  737. dec(i);
  738. s[0]:=chr(i);
  739. end;
  740. {$endif}
  741. begin
  742. assign(t,StartPath + DirSep + fn);
  743. {$I-}
  744. reset(t);
  745. {$I+}
  746. if ioresult<>0 then
  747. begin
  748. StartPath := GetProgDir;
  749. assign(t,StartPath + DirSep + fn);
  750. {$I-}
  751. reset(t);
  752. {$I+}
  753. if ioresult<>0 then
  754. begin
  755. params[0]:=@fn;
  756. messagebox('File %s not found!',@params,mferror+mfokbutton);
  757. errorhalt;
  758. end;
  759. end;
  760. line:=0;
  761. while not eof(t) do
  762. begin
  763. readln(t,s);
  764. inc(line);
  765. if (s<>'') and not(s[1] in ['#',';']) then
  766. begin
  767. i:=pos('=',s);
  768. if i>0 then
  769. begin
  770. item:=upper(Copy(s,1,i-1));
  771. system.delete(s,1,i);
  772. if item='VERSION' then
  773. cfg.version:=s
  774. else
  775. if item='TITLE' then
  776. cfg.title:=s
  777. else
  778. if item='BASEPATH' then
  779. cfg.basepath:=s
  780. else
  781. if item='PPC386' then
  782. cfg.ppc386:=s
  783. else
  784. if item='BINSUB' then
  785. cfg.binsub:=s
  786. else
  787. if item='CFGFILE' then
  788. cfg.defcfgfile:=s
  789. else
  790. if item='DEFAULTCFG' then
  791. begin
  792. repeat
  793. readln(t,s);
  794. if upper(s)='ENDCFG' then
  795. break;
  796. if cfg.defcfgs<maxdefcfgs then
  797. begin
  798. inc(cfg.defcfgs);
  799. cfg.defcfg[cfg.defcfgs]:=newstr(s);
  800. end;
  801. until false;
  802. end
  803. else
  804. if item='PACK' then
  805. begin
  806. inc(cfg.packs);
  807. if cfg.packs>maxpacks then
  808. begin
  809. writeln('Too much packs');
  810. halt(1);
  811. end;
  812. cfg.pack[cfg.packs].name:=s;
  813. end
  814. else
  815. if item='FILECHECK' then
  816. begin
  817. if cfg.packs=0 then
  818. begin
  819. writeln('No pack set');
  820. halt(1);
  821. end;
  822. cfg.pack[cfg.packs].filechk:=s;
  823. end
  824. else
  825. if item='PACKAGE' then
  826. begin
  827. if cfg.packs=0 then
  828. begin
  829. writeln('No pack set');
  830. halt(1);
  831. end;
  832. with cfg.pack[cfg.packs] do
  833. begin
  834. j:=pos(',',s);
  835. if (j>0) and (packages<maxpackages) then
  836. begin
  837. inc(packages);
  838. package[packages].zip:=copy(s,1,j-1);
  839. package[packages].name:=copy(s,j+1,255);
  840. end;
  841. end;
  842. end
  843. end;
  844. end;
  845. end;
  846. close(t);
  847. end;
  848. procedure tapp.checkavailpack;
  849. var
  850. j : longint;
  851. dir : searchrec;
  852. begin
  853. { check the packages }
  854. j:=0;
  855. while (j<cfg.packs) do
  856. begin
  857. inc(j);
  858. if cfg.pack[j].filechk<>'' then
  859. begin
  860. findfirst(cfg.pack[j].filechk,$20,dir);
  861. if doserror<>0 then
  862. begin
  863. { remove the package }
  864. move(cfg.pack[j+1],cfg.pack[j],sizeof(tpack)*(cfg.packs-j));
  865. dec(cfg.packs);
  866. dec(j);
  867. end;
  868. findclose(dir);
  869. end;
  870. end;
  871. end;
  872. procedure tapp.initmenubar;
  873. var
  874. r : trect;
  875. begin
  876. getextent(r);
  877. r.b.y:=r.a.y+1;
  878. menubar:=new(pmenubar,init(r,newmenu(
  879. newsubmenu('Free Pascal Installer',hcnocontext,newmenu(nil
  880. ),
  881. nil))));
  882. end;
  883. procedure tapp.handleevent(var event : tevent);
  884. begin
  885. inherited handleevent(event);
  886. if event.what=evcommand then
  887. if event.command=cmstart then
  888. begin
  889. clearevent(event);
  890. do_installdialog;
  891. if successfull then
  892. begin
  893. event.what:=evcommand;
  894. event.command:=cmquit;
  895. handleevent(event);
  896. end;
  897. end;
  898. end;
  899. {$IFDEF DOSSTUB}
  900. function CheckOS2: boolean;
  901. var
  902. OwnName: PathStr;
  903. OwnDir: DirStr;
  904. Name: NameStr;
  905. Ext: ExtStr;
  906. DosV, W: word;
  907. P: PChar;
  908. const
  909. Title: string [15] = 'FPC Installer'#0;
  910. RunBlock: TRunBlock = (Length: $32;
  911. Dependent: 0;
  912. Background: 0;
  913. TraceLevel: 0;
  914. PrgTitle: @Title [1];
  915. PrgName: nil;
  916. Args: nil;
  917. TermQ: 0;
  918. Environment: nil;
  919. Inheritance: 0;
  920. SesType: 2;
  921. Icon: nil;
  922. PgmHandle: 0;
  923. PgmControl: 2;
  924. Column: 0;
  925. Row: 0;
  926. Width: 80;
  927. Height: 25);
  928. begin
  929. CheckOS2 := false;
  930. asm
  931. mov ah, 30h
  932. int 21h
  933. xchg ah, al
  934. mov DosV, ax
  935. mov ax, 4010h
  936. int 2Fh
  937. cmp ax, 4010h
  938. jnz @0
  939. xor bx, bx
  940. @0:
  941. mov W, bx
  942. end;
  943. if DosV > 3 shl 8 then
  944. begin
  945. OwnName := FExpand (ParamStr (0));
  946. FSplit (OwnName, OwnDir, Name, Ext);
  947. if (DosV >= 20 shl 8 + 10) and (W >= 20 shl 8 + 10) then
  948. (* OS/2 version 2.1 or later running (double-checked) *)
  949. begin
  950. OwnName [Succ (byte (OwnName [0]))] := #0;
  951. RunBlock.PrgName := @OwnName [1];
  952. P := Ptr (PrefixSeg, $80);
  953. if PByte (P)^ <> 0 then
  954. begin
  955. Inc (P);
  956. RunBlock.Args := Ptr (PrefixSeg, $81);
  957. end;
  958. asm
  959. mov ax, 6400h
  960. mov bx, 0025h
  961. mov cx, 636Ch
  962. mov si, offset RunBlock
  963. int 21h
  964. jc @0
  965. mov DosV, 0
  966. @0:
  967. end;
  968. CheckOS2 := DosV = 0;
  969. end;
  970. end;
  971. end;
  972. {$ENDIF}
  973. begin
  974. (* TH - no error boxes if checking an inaccessible disk etc. *)
  975. {$IFDEF OS2}
  976. {$IFDEF FPC}
  977. DosCalls.DosError (0);
  978. {$ELSE FPC}
  979. {$IFDEF VirtualPascal}
  980. OS2Base.DosError (ferr_DisableHardErr);
  981. {$ELSE VirtualPascal}
  982. BseDos.DosError (0);
  983. {$ENDIF VirtualPascal}
  984. {$ENDIF FPC}
  985. {$ENDIF}
  986. {$IFDEF DOSSTUB}
  987. if CheckOS2 then Halt;
  988. {$ENDIF}
  989. getdir(0,startpath);
  990. successfull:=false;
  991. fillchar(cfg, SizeOf(cfg), 0);
  992. fillchar(data, SizeOf(data), 0);
  993. installapp.init;
  994. FSplit (FExpand (ParamStr (0)), DStr, CfgName, EStr);
  995. installapp.readcfg(CfgName + CfgExt);
  996. installapp.checkavailpack;
  997. { installapp.readcfg(startpath+dirsep+cfgfile);}
  998. installapp.do_installdialog;
  999. installapp.done;
  1000. end.
  1001. {
  1002. $Log$
  1003. Revision 1.11 2000-01-24 22:21:48 peter
  1004. * new install version (keys not wrong correct yet)
  1005. Revision 1.10 2000/01/18 00:22:48 peter
  1006. * fixed uninited local var
  1007. Revision 1.9 1999/08/03 20:21:53 peter
  1008. * fixed sources mask which was not set correctly
  1009. Revision 1.7 1999/07/01 07:56:58 hajny
  1010. * installation to root fixed
  1011. Revision 1.6 1999/06/29 22:20:19 peter
  1012. * updated to use tab pages
  1013. Revision 1.5 1999/06/25 07:06:30 hajny
  1014. + searching for installation script updated
  1015. Revision 1.4 1999/06/10 20:01:23 peter
  1016. + fcl,fv,gtk support
  1017. Revision 1.3 1999/06/10 15:00:14 peter
  1018. * fixed to compile for not os2
  1019. * update install.dat
  1020. Revision 1.2 1999/06/10 07:28:27 hajny
  1021. * compilable with TP again
  1022. Revision 1.1 1999/02/19 16:45:26 peter
  1023. * moved to fpinst/ directory
  1024. + makefile
  1025. Revision 1.15 1999/02/17 22:34:08 peter
  1026. * updates from TH for OS2
  1027. Revision 1.14 1998/12/22 22:47:34 peter
  1028. * updates for OS2
  1029. * small fixes
  1030. Revision 1.13 1998/12/21 13:11:39 peter
  1031. * updates for 0.99.10
  1032. Revision 1.12 1998/12/16 00:25:34 peter
  1033. * updated for 0.99.10
  1034. * new end dialogbox
  1035. Revision 1.11 1998/11/01 20:32:25 peter
  1036. * packed record
  1037. Revision 1.10 1998/10/25 23:38:35 peter
  1038. * removed warnings
  1039. Revision 1.9 1998/10/23 16:57:40 pierre
  1040. * compiles without -So option
  1041. * the main dialog init was buggy !!
  1042. Revision 1.8 1998/09/22 21:10:31 jonas
  1043. * initialize cfg and data with 0 at startup
  1044. Revision 1.7 1998/09/16 16:46:37 peter
  1045. + updates
  1046. Revision 1.6 1998/09/15 13:11:14 pierre
  1047. small fix to cleanup if no package
  1048. Revision 1.5 1998/09/15 12:06:06 peter
  1049. * install updated to support w32 and dos and config file
  1050. Revision 1.4 1998/09/10 10:50:49 florian
  1051. * DOS install program updated
  1052. Revision 1.3 1998/09/09 13:39:58 peter
  1053. + internal unzip
  1054. * dialog is showed automaticly
  1055. Revision 1.2 1998/04/07 22:47:57 florian
  1056. + version/release/patch numbers as string added
  1057. }