dos.pp 22 KB

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