dos.pp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team.
  5. Dos unit for BP7 compatible RTL (novell netware)
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. { 2000/09/03 armin: first version
  13. 2001/04/08 armin: implemented more functions
  14. OK: Implemented and tested
  15. NI: not implemented
  16. 2001/04/15 armin: FindFirst bug corrected, FExpand and FSearch tested, GetCBreak, SetCBreak
  17. implemented
  18. }
  19. unit dos;
  20. interface
  21. CONST LFNSupport = FALSE;
  22. Const
  23. {Bitmasks for CPU Flags}
  24. fcarry = $0001;
  25. fparity = $0004;
  26. fauxiliary = $0010;
  27. fzero = $0040;
  28. fsign = $0080;
  29. foverflow = $0800;
  30. {Bitmasks for file attribute}
  31. readonly = $01;
  32. hidden = $02;
  33. sysfile = $04;
  34. volumeid = $08;
  35. nwexeconly= $08;
  36. directory = $10;
  37. archive = $20;
  38. sharable = $80;
  39. anyfile = $3F;
  40. {File Status}
  41. fmclosed = $D7B0;
  42. fminput = $D7B1;
  43. fmoutput = $D7B2;
  44. fminout = $D7B3;
  45. Type
  46. { Needed for LFN Support }
  47. ComStr = String[255];
  48. PathStr = String[255];
  49. DirStr = String[255];
  50. NameStr = String[255];
  51. ExtStr = String[255];
  52. {
  53. filerec.inc contains the definition of the filerec.
  54. textrec.inc contains the definition of the textrec.
  55. It is in a separate file to make it available in other units without
  56. having to use the DOS unit for it.
  57. }
  58. {$i filerec.inc}
  59. {$i textrec.inc}
  60. DateTime = packed record
  61. Year,
  62. Month,
  63. Day,
  64. Hour,
  65. Min,
  66. Sec : word;
  67. End;
  68. searchrec = packed record
  69. DirP : POINTER; { used for opendir }
  70. EntryP: POINTER; { and readdir }
  71. Magic : WORD;
  72. fill : array[1..11] of byte;
  73. attr : byte;
  74. time : longint;
  75. { reserved : word; not in DJGPP V2 }
  76. size : longint;
  77. name : string[255]; { NW uses only [12] but more can't hurt }
  78. end;
  79. registers = packed record
  80. case i : integer of
  81. 0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
  82. 1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
  83. 2 : (eax, ebx, ecx, edx, ebp, esi, edi : longint);
  84. end;
  85. Var
  86. DosError : integer;
  87. {Info/Date/Time}
  88. Function DosVersion: Word; {ok}
  89. Procedure GetDate(var year, month, mday, wday: word); {ok}
  90. Procedure GetTime(var hour, minute, second, sec100: word); {ok}
  91. procedure SetDate(year,month,day: word); {ok}
  92. Procedure SetTime(hour,minute,second,sec100: word); {ok}
  93. Procedure UnpackTime(p: longint; var t: datetime); {ok}
  94. Procedure PackTime(var t: datetime; var p: longint); {ok}
  95. {Exec}
  96. Procedure Exec(const path: pathstr; const comline: comstr); {ni}
  97. Function DosExitCode: word; {ni}
  98. {Disk}
  99. {$ifdef Int64}
  100. Function DiskFree(drive: byte) : int64; {ok}
  101. Function DiskSize(drive: byte) : int64; {ok}
  102. {$else}
  103. Function DiskFree(drive: byte) : longint; {ok}
  104. Function DiskSize(drive: byte) : longint; {ok}
  105. {$endif}
  106. {FincClose has to be called to avoid memory leaks}
  107. Procedure FindFirst(const path: pathstr; attr: word; {ok}
  108. var f: searchRec);
  109. Procedure FindNext(var f: searchRec); {ok}
  110. Procedure FindClose(Var f: SearchRec); {ok}
  111. {File}
  112. Procedure GetFAttr(var f; var attr: word); {ok}
  113. Procedure GetFTime(var f; var time: longint); {ok}
  114. Function FSearch(path: pathstr; dirlist: string): pathstr; {ok}
  115. Function FExpand(const path: pathstr): pathstr; {ok}
  116. Procedure FSplit(path: pathstr; var dir: dirstr; var name: {untested}
  117. namestr; var ext: extstr);
  118. {Environment}
  119. Function EnvCount: longint; {ni}
  120. Function EnvStr(index: integer): string; {ni}
  121. Function GetEnv(envvar: string): string; {ok}
  122. {Misc}
  123. Procedure SetFAttr(var f; attr: word); {ni}
  124. Procedure SetFTime(var f; time: longint); {ni}
  125. Procedure GetCBreak(var breakvalue: boolean); {ni}
  126. Procedure SetCBreak(breakvalue: boolean); {ni}
  127. Procedure GetVerify(var verify: boolean); {ni}
  128. Procedure SetVerify(verify: boolean); {ni}
  129. {Do Nothing Functions}
  130. Procedure SwapVectors; {ni}
  131. Procedure GetIntVec(intno: byte; var vector: pointer); {ni}
  132. Procedure SetIntVec(intno: byte; vector: pointer); {ni}
  133. Procedure Keep(exitcode: word); {ni}
  134. Procedure Intr(intno: byte; var regs: registers); {ni}
  135. Procedure MSDos(var regs: registers); {ni}
  136. implementation
  137. uses
  138. strings;
  139. {$ASMMODE ATT}
  140. {$I nwsys.inc }
  141. {*****************************************************************************
  142. --- Info / Date / Time ---
  143. ******************************************************************************}
  144. {$PACKRECORDS 4}
  145. function dosversion : word;
  146. VAR F : FILE_SERV_INFO;
  147. begin
  148. IF GetServerInformation(SIZEOF(F),@F) = 0 THEN
  149. dosversion := WORD (F.netwareVersion) SHL 8 + F.netwareSubVersion;
  150. end;
  151. procedure getdate(var year,month,mday,wday : word);
  152. VAR N : NWdateAndTime;
  153. begin
  154. GetFileServerDateAndTime (N);
  155. wday:=N.DayOfWeek;
  156. year:=1900 + N.Year;
  157. month:=N.Month;
  158. mday:=N.Day;
  159. end;
  160. procedure setdate(year,month,day : word);
  161. VAR N : NWdateAndTime;
  162. begin
  163. GetFileServerDateAndTime (N);
  164. SetFileServerDateAndTime(year,month,day,N.Hour,N.Minute,N.Second);
  165. end;
  166. procedure gettime(var hour,minute,second,sec100 : word);
  167. VAR N : NWdateAndTime;
  168. begin
  169. GetFileServerDateAndTime (N);
  170. hour := N.Hour;
  171. Minute:= N.Minute;
  172. Second := N.Second;
  173. sec100 := 0;
  174. end;
  175. procedure settime(hour,minute,second,sec100 : word);
  176. VAR N : NWdateAndTime;
  177. begin
  178. GetFileServerDateAndTime (N);
  179. SetFileServerDateAndTime(N.year,N.month,N.day,hour,minute,second);
  180. end;
  181. Procedure packtime(var t : datetime;var p : longint);
  182. Begin
  183. p:=(t.sec shr 1)+(t.min shl 5)+(t.hour shl 11)+(t.day shl 16)+(t.month shl 21)+((t.year-1980) shl 25);
  184. End;
  185. Procedure unpacktime(p : longint;var t : datetime);
  186. Begin
  187. with t do
  188. begin
  189. sec:=(p and 31) shl 1;
  190. min:=(p shr 5) and 63;
  191. hour:=(p shr 11) and 31;
  192. day:=(p shr 16) and 31;
  193. month:=(p shr 21) and 15;
  194. year:=(p shr 25)+1980;
  195. end;
  196. End;
  197. {******************************************************************************
  198. --- Exec ---
  199. ******************************************************************************}
  200. var
  201. lastdosexitcode : word;
  202. procedure exec(const path : pathstr;const comline : comstr);
  203. begin
  204. ConsolePrintf ('warning: fpc dos.exec not implemented'#13#10,0);
  205. end;
  206. function dosexitcode : word;
  207. begin
  208. dosexitcode:=lastdosexitcode;
  209. end;
  210. procedure getcbreak(var breakvalue : boolean);
  211. begin
  212. breakvalue := _SetCtrlCharCheckMode (false); { get current setting }
  213. if breakvalue then
  214. _SetCtrlCharCheckMode (breakvalue); { and restore old setting }
  215. end;
  216. procedure setcbreak(breakvalue : boolean);
  217. begin
  218. _SetCtrlCharCheckMode (breakvalue);
  219. end;
  220. procedure getverify(var verify : boolean);
  221. begin
  222. verify := true;
  223. end;
  224. procedure setverify(verify : boolean);
  225. begin
  226. end;
  227. {******************************************************************************
  228. --- Disk ---
  229. ******************************************************************************}
  230. function getvolnum (drive : byte) : longint;
  231. var dir : STRING[255];
  232. P,PS: BYTE;
  233. V : LONGINT;
  234. begin
  235. if drive = 0 then
  236. begin // get volume name from current directory (i.e. SERVER-NAME/VOL2:TEST)
  237. getdir (0,dir);
  238. p := pos (':', dir);
  239. if p = 0 then
  240. begin
  241. getvolnum := -1;
  242. exit;
  243. end;
  244. byte (dir[0]) := p-1;
  245. dir[p] := #0;
  246. PS := pos ('/', dir);
  247. INC (PS);
  248. if _GetVolumeNumber (@dir[PS], V) <> 0 then
  249. getvolnum := -1
  250. else
  251. getvolnum := V;
  252. end else
  253. getvolnum := drive-1;
  254. end;
  255. {$ifdef Int64}
  256. function diskfree(drive : byte) : int64;
  257. VAR Buf : ARRAY [0..255] OF CHAR;
  258. TotalBlocks : WORD;
  259. SectorsPerBlock : WORD;
  260. availableBlocks : WORD;
  261. totalDirectorySlots : WORD;
  262. availableDirSlots : WORD;
  263. volumeisRemovable : WORD;
  264. volumeNumber : LONGINT;
  265. begin
  266. volumeNumber := getvolnum (drive);
  267. if volumeNumber >= 0 then
  268. begin
  269. {i think thats not the right function but for others i need a connection handle}
  270. if _GetVolumeInfoWithNumber (volumeNumber,@Buf,
  271. TotalBlocks,
  272. SectorsPerBlock,
  273. availableBlocks,
  274. totalDirectorySlots,
  275. availableDirSlots,
  276. volumeisRemovable) = 0 THEN
  277. begin
  278. diskfree := int64 (availableBlocks) * int64 (SectorsPerBlock) * 512;
  279. end else
  280. diskfree := 0;
  281. end else
  282. diskfree := 0;
  283. end;
  284. function disksize(drive : byte) : int64;
  285. VAR Buf : ARRAY [0..255] OF CHAR;
  286. TotalBlocks : WORD;
  287. SectorsPerBlock : WORD;
  288. availableBlocks : WORD;
  289. totalDirectorySlots : WORD;
  290. availableDirSlots : WORD;
  291. volumeisRemovable : WORD;
  292. volumeNumber : LONGINT;
  293. begin
  294. volumeNumber := getvolnum (drive);
  295. if volumeNumber >= 0 then
  296. begin
  297. {i think thats not the right function but for others i need a connection handle}
  298. if _GetVolumeInfoWithNumber (volumeNumber,@Buf,
  299. TotalBlocks,
  300. SectorsPerBlock,
  301. availableBlocks,
  302. totalDirectorySlots,
  303. availableDirSlots,
  304. volumeisRemovable) = 0 THEN
  305. begin
  306. disksize := int64 (TotalBlocks) * int64 (SectorsPerBlock) * 512;
  307. end else
  308. disksize := 0;
  309. end else
  310. disksize := 0;
  311. end;
  312. {$else}
  313. function diskfree(drive : byte) : longint;
  314. VAR Buf : ARRAY [0..255] OF CHAR;
  315. TotalBlocks : WORD;
  316. SectorsPerBlock : WORD;
  317. availableBlocks : WORD;
  318. totalDirectorySlots : WORD;
  319. availableDirSlots : WORD;
  320. volumeisRemovable : WORD;
  321. volumeNumber : LONGINT;
  322. begin
  323. volumeNumber := getvolnum (drive);
  324. if volumeNumber >= 0 then
  325. begin
  326. {i think thats not the right function but for others i need a connection handle}
  327. if _GetVolumeInfoWithNumber (volumeNumber,@Buf,
  328. TotalBlocks,
  329. SectorsPerBlock,
  330. availableBlocks,
  331. totalDirectorySlots,
  332. availableDirSlots,
  333. volumeisRemovable) = 0 THEN
  334. begin
  335. diskfree := availableBlocks * SectorsPerBlock * 512;
  336. end else
  337. diskfree := 0;
  338. end else
  339. diskfree := 0;
  340. end;
  341. function disksize(drive : byte) : longint;
  342. VAR Buf : ARRAY [0..255] OF CHAR;
  343. TotalBlocks : WORD;
  344. SectorsPerBlock : WORD;
  345. availableBlocks : WORD;
  346. totalDirectorySlots : WORD;
  347. availableDirSlots : WORD;
  348. volumeisRemovable : WORD;
  349. volumeNumber : LONGINT;
  350. begin
  351. volumeNumber := getvolnum (drive);
  352. if volumeNumber >= 0 then
  353. begin
  354. {i think thats not the right function but for others i need a connection handle}
  355. if _GetVolumeInfoWithNumber (volumeNumber,@Buf,
  356. TotalBlocks,
  357. SectorsPerBlock,
  358. availableBlocks,
  359. totalDirectorySlots,
  360. availableDirSlots,
  361. volumeisRemovable) = 0 THEN
  362. begin
  363. disksize := TotalBlocks * SectorsPerBlock * 512;
  364. end else
  365. disksize := 0;
  366. end else
  367. disksize := 0;
  368. end;
  369. {$endif}
  370. {******************************************************************************
  371. --- Findfirst FindNext ---
  372. ******************************************************************************}
  373. PROCEDURE find_setfields (VAR f : searchRec);
  374. BEGIN
  375. WITH F DO
  376. BEGIN
  377. IF Magic = $AD01 THEN
  378. BEGIN
  379. attr := WORD (PNWDirEnt(EntryP)^.d_attr); // lowest 16 bit -> same as dos
  380. time := PNWDirEnt(EntryP)^.d_time + (LONGINT (PNWDirEnt(EntryP)^.d_date) SHL 16);
  381. size := PNWDirEnt(EntryP)^.d_size;
  382. name := strpas (PNWDirEnt(EntryP)^.d_nameDOS);
  383. doserror := 0;
  384. END ELSE
  385. BEGIN
  386. FillChar (f,SIZEOF(f),0);
  387. doserror := 18;
  388. END;
  389. END;
  390. END;
  391. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  392. var
  393. path0 : array[0..256] of char;
  394. begin
  395. IF path = '' then
  396. begin
  397. doserror := 18;
  398. exit;
  399. end;
  400. strpcopy(path0,path);
  401. PNWDirEnt(f.DirP) := _opendir (path0);
  402. IF f.DirP = NIL THEN
  403. doserror := 18
  404. ELSE
  405. BEGIN
  406. IF attr <> anyfile THEN
  407. _SetReaddirAttribute (PNWDirEnt(f.DirP), attr);
  408. F.Magic := $AD01;
  409. PNWDirEnt(f.EntryP) := _readdir (PNWDirEnt(f.DirP));
  410. IF F.EntryP = NIL THEN
  411. BEGIN
  412. _closedir (PNWDirEnt(f.DirP));
  413. f.Magic := 0;
  414. doserror := 18;
  415. END ELSE
  416. find_setfields (f);
  417. END;
  418. end;
  419. procedure findnext(var f : searchRec);
  420. begin
  421. IF F.Magic <> $AD01 THEN
  422. BEGIN
  423. doserror := 18;
  424. EXIT;
  425. END;
  426. doserror:=0;
  427. PNWDirEnt(f.EntryP) := _readdir (PNWDirEnt(f.DirP));
  428. IF F.EntryP = NIL THEN
  429. doserror := 18
  430. ELSE
  431. find_setfields (f);
  432. end;
  433. Procedure FindClose(Var f: SearchRec);
  434. begin
  435. IF F.Magic <> $AD01 THEN
  436. BEGIN
  437. doserror := 18;
  438. EXIT;
  439. END;
  440. doserror:=0;
  441. _closedir (PNWDirEnt(f.DirP));
  442. f.Magic := 0;
  443. f.DirP := NIL;
  444. f.EntryP := NIL;
  445. end;
  446. procedure swapvectors;
  447. begin
  448. end;
  449. {******************************************************************************
  450. --- File ---
  451. ******************************************************************************}
  452. procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;var ext : extstr);
  453. var
  454. dotpos,p1,i : longint;
  455. begin
  456. { allow slash as backslash }
  457. for i:=1 to length(path) do
  458. if path[i]='/' then path[i]:='\';
  459. { get drive name }
  460. p1:=pos(':',path);
  461. if p1>0 then
  462. begin
  463. dir:=path[1]+':';
  464. delete(path,1,p1);
  465. end
  466. else
  467. dir:='';
  468. { split the path and the name, there are no more path informtions }
  469. { if path contains no backslashes }
  470. while true do
  471. begin
  472. p1:=pos('\',path);
  473. if p1=0 then
  474. break;
  475. dir:=dir+copy(path,1,p1);
  476. delete(path,1,p1);
  477. end;
  478. { try to find out a extension }
  479. if LFNSupport then
  480. begin
  481. Ext:='';
  482. i:=Length(Path);
  483. DotPos:=256;
  484. While (i>0) Do
  485. Begin
  486. If (Path[i]='.') Then
  487. begin
  488. DotPos:=i;
  489. break;
  490. end;
  491. Dec(i);
  492. end;
  493. Ext:=Copy(Path,DotPos,255);
  494. Name:=Copy(Path,1,DotPos - 1);
  495. end
  496. else
  497. begin
  498. p1:=pos('.',path);
  499. if p1>0 then
  500. begin
  501. ext:=copy(path,p1,4);
  502. delete(path,p1,length(path)-p1+1);
  503. end
  504. else
  505. ext:='';
  506. name:=path;
  507. end;
  508. end;
  509. function fexpand(const path : pathstr) : pathstr;
  510. var
  511. s,pa : pathstr;
  512. i,j : longint;
  513. begin
  514. getdir(0,s);
  515. i:=ioresult;
  516. if LFNSupport then
  517. begin
  518. pa:=path;
  519. end
  520. else
  521. if FileNameCaseSensitive then
  522. pa:=path
  523. else
  524. pa:=upcase(path);
  525. { allow slash as backslash }
  526. for i:=1 to length(pa) do
  527. if pa[i]='/' then
  528. pa[i]:='\';
  529. if (length(pa)>1) and (pa[2]=':') and (pa[1] in ['A'..'Z','a'..'z']) then
  530. begin
  531. { Always uppercase driveletter }
  532. if (pa[1] in ['a'..'z']) then
  533. pa[1]:=Chr(Ord(Pa[1])-32);
  534. { we must get the right directory }
  535. getdir(ord(pa[1])-ord('A')+1,s);
  536. i:=ioresult;
  537. if (ord(pa[0])>2) and (pa[3]<>'\') then
  538. if pa[1]=s[1] then
  539. begin
  540. { remove ending slash if it already exists }
  541. if s[length(s)]='\' then
  542. dec(s[0]);
  543. pa:=s+'\'+copy (pa,3,length(pa));
  544. end
  545. else
  546. pa:=pa[1]+':\'+copy (pa,3,length(pa))
  547. end
  548. else
  549. if pa[1]='\' then
  550. begin
  551. { Do not touch Network drive names if LFNSupport is true }
  552. if not ((Length(pa)>1) and (pa[2]='\') and LFNSupport) then
  553. pa:=s[1]+':'+pa;
  554. end
  555. else if s[0]=#3 then
  556. pa:=s+pa
  557. else
  558. pa:=s+'\'+pa;
  559. { Turbo Pascal gives current dir on drive if only drive given as parameter! }
  560. if length(pa) = 2 then
  561. begin
  562. getdir(byte(pa[1])-64,s);
  563. pa := s;
  564. end;
  565. {First remove all references to '\.\'}
  566. while pos ('\.\',pa)<>0 do
  567. delete (pa,pos('\.\',pa),2);
  568. {Now remove also all references to '\..\' + of course previous dirs..}
  569. repeat
  570. i:=pos('\..\',pa);
  571. if i<>0 then
  572. begin
  573. j:=i-1;
  574. while (j>1) and (pa[j]<>'\') do
  575. dec (j);
  576. if pa[j+1] = ':' then j := 3;
  577. delete (pa,j,i-j+3);
  578. end;
  579. until i=0;
  580. { Turbo Pascal gets rid of a \.. at the end of the path }
  581. { Now remove also any reference to '\..' at end of line
  582. + of course previous dir.. }
  583. i:=pos('\..',pa);
  584. if i<>0 then
  585. begin
  586. if i = length(pa) - 2 then
  587. begin
  588. j:=i-1;
  589. while (j>1) and (pa[j]<>'\') do
  590. dec (j);
  591. delete (pa,j,i-j+3);
  592. end;
  593. pa := pa + '\';
  594. end;
  595. { Remove End . and \}
  596. if (length(pa)>0) and (pa[length(pa)]='.') then
  597. dec(byte(pa[0]));
  598. { if only the drive + a '\' is left then the '\' should be left to prevtn the program
  599. accessing the current directory on the drive rather than the root!}
  600. { if the last char of path = '\' then leave it in as this is what TP does! }
  601. if ((length(pa)>3) and (pa[length(pa)]='\')) and (path[length(path)] <> '\') then
  602. dec(byte(pa[0]));
  603. { if only a drive is given in path then there should be a '\' at the
  604. end of the string given back }
  605. if length(pa) = 2 then pa := pa + '\';
  606. fexpand:=pa;
  607. end;
  608. Function FSearch(path: pathstr; dirlist: string): pathstr;
  609. var
  610. i,p1 : longint;
  611. s : searchrec;
  612. newdir : pathstr;
  613. begin
  614. { check if the file specified exists }
  615. findfirst(path,anyfile,s);
  616. if doserror=0 then
  617. begin
  618. findclose(s);
  619. fsearch:=path;
  620. exit;
  621. end;
  622. { No wildcards allowed in these things }
  623. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  624. fsearch:=''
  625. else
  626. begin
  627. { allow slash as backslash }
  628. for i:=1 to length(dirlist) do
  629. if dirlist[i]='/' then dirlist[i]:='\';
  630. repeat
  631. p1:=pos(';',dirlist);
  632. if p1<>0 then
  633. begin
  634. newdir:=copy(dirlist,1,p1-1);
  635. delete(dirlist,1,p1);
  636. end
  637. else
  638. begin
  639. newdir:=dirlist;
  640. dirlist:='';
  641. end;
  642. if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
  643. newdir:=newdir+'\';
  644. findfirst(newdir+path,anyfile,s);
  645. if doserror=0 then
  646. newdir:=newdir+path
  647. else
  648. newdir:='';
  649. until (dirlist='') or (newdir<>'');
  650. fsearch:=newdir;
  651. end;
  652. findclose(s);
  653. end;
  654. {******************************************************************************
  655. --- Get/Set File Time,Attr ---
  656. ******************************************************************************}
  657. procedure getftime(var f;var time : longint);
  658. VAR StatBuf : NWStatBufT;
  659. T : DateTime;
  660. DosDate,
  661. DosTime : WORD;
  662. begin
  663. IF _fstat (FileRec (f).Handle, StatBuf) = 0 THEN
  664. BEGIN
  665. _ConvertTimeToDos (StatBuf.st_mtime, DosDate, DosTime);
  666. time := DosTime + (LONGINT (DosDate) SHL 16);
  667. END ELSE
  668. time := 0;
  669. end;
  670. procedure setftime(var f;time : longint);
  671. begin
  672. {is there a netware function to do that ?????}
  673. ConsolePrintf ('warning: fpc dos.setftime not implemented'#13#10,0);
  674. end;
  675. procedure getfattr(var f;var attr : word);
  676. VAR StatBuf : NWStatBufT;
  677. begin
  678. IF _fstat (FileRec (f).Handle, StatBuf) = 0 THEN
  679. BEGIN
  680. attr := word (StatBuf.st_attr);
  681. END ELSE
  682. attr := 0;
  683. end;
  684. procedure setfattr(var f;attr : word);
  685. begin
  686. {is there a netware function to do that ?????}
  687. ConsolePrintf ('warning: fpc dos.setfattr not implemented'#13#10,0);
  688. end;
  689. {******************************************************************************
  690. --- Environment ---
  691. ******************************************************************************}
  692. function envcount : longint;
  693. begin
  694. envcount := 0; {is there a netware function to do that ?????}
  695. ConsolePrintf ('warning: fpc dos.envcount not implemented'#13#10,0);
  696. end;
  697. function envstr(index : integer) : string;
  698. begin
  699. envstr := ''; {is there a netware function to do that ?????}
  700. ConsolePrintf ('warning: fpc dos.envstr not implemented'#13#10,0);
  701. end;
  702. { the function exists in clib but i dont know how to set environment vars.
  703. may be it's only a dummy in clib }
  704. Function GetEnv(envvar: string): string;
  705. var
  706. envvar0 : array[0..256] of char;
  707. p : pchar;
  708. begin
  709. strpcopy(envvar0,envvar);
  710. p := _getenv (envvar0);
  711. if p = NIL then
  712. GetEnv := ''
  713. else
  714. GetEnv := strpas (p);
  715. end;
  716. {******************************************************************************
  717. --- Not Supported ---
  718. ******************************************************************************}
  719. Procedure keep(exitcode : word);
  720. Begin
  721. { no netware equivalent }
  722. End;
  723. Procedure getintvec(intno : byte;var vector : pointer);
  724. Begin
  725. { no netware equivalent }
  726. End;
  727. Procedure setintvec(intno : byte;vector : pointer);
  728. Begin
  729. { no netware equivalent }
  730. End;
  731. procedure intr(intno : byte;var regs : registers);
  732. begin
  733. { no netware equivalent }
  734. end;
  735. procedure msdos(var regs : registers);
  736. begin
  737. { no netware equivalent }
  738. end;
  739. end.
  740. {
  741. $Log$
  742. Revision 1.3 2001-04-16 18:39:50 florian
  743. * updates from Armin commited
  744. Revision 1.2 2001/04/11 14:17:00 florian
  745. * added logs, fixed email address of Armin, it is
  746. [email protected]
  747. Revision 1.1 2001/04/11 14:14:12 florian
  748. * initial commit, thanks to Armin Diehl ([email protected])
  749. }