install.pas 53 KB

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