install.pas 28 KB

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