dos.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  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. unit dos;
  13. interface
  14. Const
  15. FileNameLen = 255;
  16. Type
  17. searchrec = packed record
  18. DirP : POINTER; { used for opendir }
  19. EntryP: POINTER; { and readdir }
  20. Magic : WORD;
  21. fill : array[1..11] of byte;
  22. attr : byte;
  23. time : longint;
  24. { reserved : word; not in DJGPP V2 }
  25. size : longint;
  26. name : string[255]; { NW uses only [12] but more can't hurt }
  27. end;
  28. registers = packed record
  29. case i : integer of
  30. 0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
  31. 1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
  32. 2 : (eax, ebx, ecx, edx, ebp, esi, edi : longint);
  33. end;
  34. {$i dosh.inc}
  35. implementation
  36. uses
  37. strings;
  38. {$ASMMODE ATT}
  39. {$I nwsys.inc }
  40. {*****************************************************************************
  41. --- Info / Date / Time ---
  42. ******************************************************************************}
  43. {$PACKRECORDS 4}
  44. function dosversion : word;
  45. VAR F : FILE_SERV_INFO;
  46. begin
  47. IF GetServerInformation(SIZEOF(F),@F) = 0 THEN
  48. dosversion := WORD (F.netwareVersion) SHL 8 + F.netwareSubVersion;
  49. end;
  50. procedure getdate(var year,month,mday,wday : word);
  51. VAR N : NWdateAndTime;
  52. begin
  53. GetFileServerDateAndTime (N);
  54. wday:=N.DayOfWeek;
  55. year:=1900 + N.Year;
  56. month:=N.Month;
  57. mday:=N.Day;
  58. end;
  59. procedure setdate(year,month,day : word);
  60. VAR N : NWdateAndTime;
  61. begin
  62. GetFileServerDateAndTime (N);
  63. SetFileServerDateAndTime(year,month,day,N.Hour,N.Minute,N.Second);
  64. end;
  65. procedure gettime(var hour,minute,second,sec100 : word);
  66. VAR N : NWdateAndTime;
  67. begin
  68. GetFileServerDateAndTime (N);
  69. hour := N.Hour;
  70. Minute:= N.Minute;
  71. Second := N.Second;
  72. sec100 := 0;
  73. end;
  74. procedure settime(hour,minute,second,sec100 : word);
  75. VAR N : NWdateAndTime;
  76. begin
  77. GetFileServerDateAndTime (N);
  78. SetFileServerDateAndTime(N.year,N.month,N.day,hour,minute,second);
  79. end;
  80. Procedure packtime(var t : datetime;var p : longint);
  81. Begin
  82. 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);
  83. End;
  84. Procedure unpacktime(p : longint;var t : datetime);
  85. Begin
  86. with t do
  87. begin
  88. sec:=(p and 31) shl 1;
  89. min:=(p shr 5) and 63;
  90. hour:=(p shr 11) and 31;
  91. day:=(p shr 16) and 31;
  92. month:=(p shr 21) and 15;
  93. year:=(p shr 25)+1980;
  94. end;
  95. End;
  96. {******************************************************************************
  97. --- Exec ---
  98. ******************************************************************************}
  99. {$ifdef HASTHREADVAR}
  100. threadvar
  101. {$else HASTHREADVAR}
  102. var
  103. {$endif HASTHREADVAR}
  104. lastdosexitcode : word;
  105. const maxargs=256;
  106. procedure exec(const path : pathstr;const comline : comstr);
  107. var c : comstr;
  108. i : integer;
  109. args : array[0..maxargs] of pchar;
  110. arg0 : pathstr;
  111. numargs : integer;
  112. begin
  113. //writeln ('dos.exec (',path,',',comline,')');
  114. arg0 := fexpand (path)+#0;
  115. args[0] := @arg0[1];
  116. numargs := 0;
  117. c:=comline;
  118. i:=1;
  119. while i<=length(c) do
  120. begin
  121. if c[i]<>' ' then
  122. begin
  123. {Commandline argument found. append #0 and set pointer in args }
  124. inc(numargs);
  125. args[numargs]:=@c[i];
  126. while (i<=length(c)) and (c[i]<>' ') do
  127. inc(i);
  128. c[i] := #0;
  129. end;
  130. inc(i);
  131. end;
  132. args[numargs+1] := nil;
  133. i := spawnvp (P_WAIT,args[0],@args);
  134. if i >= 0 then
  135. begin
  136. doserror := 0;
  137. lastdosexitcode := i;
  138. end else
  139. begin
  140. doserror := 8; // for now, what about errno ?
  141. end;
  142. end;
  143. function dosexitcode : word;
  144. begin
  145. dosexitcode:=lastdosexitcode;
  146. end;
  147. procedure getcbreak(var breakvalue : boolean);
  148. begin
  149. breakvalue := _SetCtrlCharCheckMode (false); { get current setting }
  150. if breakvalue then
  151. _SetCtrlCharCheckMode (breakvalue); { and restore old setting }
  152. end;
  153. procedure setcbreak(breakvalue : boolean);
  154. begin
  155. _SetCtrlCharCheckMode (breakvalue);
  156. end;
  157. procedure getverify(var verify : boolean);
  158. begin
  159. verify := true;
  160. end;
  161. procedure setverify(verify : boolean);
  162. begin
  163. end;
  164. {******************************************************************************
  165. --- Disk ---
  166. ******************************************************************************}
  167. function getvolnum (drive : byte) : longint;
  168. var dir : STRING[255];
  169. P,PS,
  170. V : LONGINT;
  171. begin
  172. if drive = 0 then
  173. begin // get volume name from current directory (i.e. SERVER-NAME/VOL2:TEST)
  174. getdir (0,dir);
  175. p := pos (':', dir);
  176. if p = 0 then
  177. begin
  178. getvolnum := -1;
  179. exit;
  180. end;
  181. byte (dir[0]) := p-1;
  182. dir[p] := #0;
  183. PS := pos ('/', dir);
  184. INC (PS);
  185. if _GetVolumeNumber (@dir[PS], V) <> 0 then
  186. getvolnum := -1
  187. else
  188. getvolnum := V;
  189. end else
  190. getvolnum := drive-1;
  191. end;
  192. function diskfree(drive : byte) : int64;
  193. VAR Buf : ARRAY [0..255] OF CHAR;
  194. TotalBlocks : WORD;
  195. SectorsPerBlock : WORD;
  196. availableBlocks : WORD;
  197. totalDirectorySlots : WORD;
  198. availableDirSlots : WORD;
  199. volumeisRemovable : WORD;
  200. volumeNumber : LONGINT;
  201. begin
  202. volumeNumber := getvolnum (drive);
  203. if volumeNumber >= 0 then
  204. begin
  205. {i think thats not the right function but for others i need a connection handle}
  206. if _GetVolumeInfoWithNumber (byte(volumeNumber),@Buf,
  207. TotalBlocks,
  208. SectorsPerBlock,
  209. availableBlocks,
  210. totalDirectorySlots,
  211. availableDirSlots,
  212. volumeisRemovable) = 0 THEN
  213. begin
  214. diskfree := int64 (availableBlocks) * int64 (SectorsPerBlock) * 512;
  215. end else
  216. diskfree := 0;
  217. end else
  218. diskfree := 0;
  219. end;
  220. function disksize(drive : byte) : int64;
  221. VAR Buf : ARRAY [0..255] OF CHAR;
  222. TotalBlocks : WORD;
  223. SectorsPerBlock : WORD;
  224. availableBlocks : WORD;
  225. totalDirectorySlots : WORD;
  226. availableDirSlots : WORD;
  227. volumeisRemovable : WORD;
  228. volumeNumber : LONGINT;
  229. begin
  230. volumeNumber := getvolnum (drive);
  231. if volumeNumber >= 0 then
  232. begin
  233. {i think thats not the right function but for others i need a connection handle}
  234. if _GetVolumeInfoWithNumber (byte(volumeNumber),@Buf,
  235. TotalBlocks,
  236. SectorsPerBlock,
  237. availableBlocks,
  238. totalDirectorySlots,
  239. availableDirSlots,
  240. volumeisRemovable) = 0 THEN
  241. begin
  242. disksize := int64 (TotalBlocks) * int64 (SectorsPerBlock) * 512;
  243. end else
  244. disksize := 0;
  245. end else
  246. disksize := 0;
  247. end;
  248. {******************************************************************************
  249. --- Findfirst FindNext ---
  250. ******************************************************************************}
  251. PROCEDURE find_setfields (VAR f : searchRec);
  252. BEGIN
  253. WITH F DO
  254. BEGIN
  255. IF Magic = $AD01 THEN
  256. BEGIN
  257. attr := WORD (PNWDirEnt(EntryP)^.d_attr); // lowest 16 bit -> same as dos
  258. time := PNWDirEnt(EntryP)^.d_time + (LONGINT (PNWDirEnt(EntryP)^.d_date) SHL 16);
  259. size := PNWDirEnt(EntryP)^.d_size;
  260. name := strpas (PNWDirEnt(EntryP)^.d_name);
  261. if name = '' then
  262. name := strpas (PNWDirEnt(EntryP)^.d_nameDOS);
  263. doserror := 0;
  264. END ELSE
  265. BEGIN
  266. FillChar (f,SIZEOF(f),0);
  267. doserror := 18;
  268. END;
  269. END;
  270. END;
  271. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  272. var
  273. path0 : array[0..256] of char;
  274. begin
  275. IF path = '' then
  276. begin
  277. doserror := 18;
  278. exit;
  279. end;
  280. strpcopy(path0,path);
  281. PNWDirEnt(f.DirP) := _opendir (path0);
  282. IF f.DirP = NIL THEN
  283. doserror := 18
  284. ELSE
  285. BEGIN
  286. IF attr <> anyfile THEN
  287. _SetReaddirAttribute (PNWDirEnt(f.DirP), attr);
  288. F.Magic := $AD01;
  289. PNWDirEnt(f.EntryP) := _readdir (PNWDirEnt(f.DirP));
  290. IF F.EntryP = NIL THEN
  291. BEGIN
  292. _closedir (PNWDirEnt(f.DirP));
  293. f.Magic := 0;
  294. doserror := 18;
  295. END ELSE
  296. find_setfields (f);
  297. END;
  298. end;
  299. procedure findnext(var f : searchRec);
  300. begin
  301. IF F.Magic <> $AD01 THEN
  302. BEGIN
  303. doserror := 18;
  304. EXIT;
  305. END;
  306. doserror:=0;
  307. PNWDirEnt(f.EntryP) := _readdir (PNWDirEnt(f.DirP));
  308. IF F.EntryP = NIL THEN
  309. doserror := 18
  310. ELSE
  311. find_setfields (f);
  312. end;
  313. Procedure FindClose(Var f: SearchRec);
  314. begin
  315. IF F.Magic <> $AD01 THEN
  316. BEGIN
  317. doserror := 18;
  318. EXIT;
  319. END;
  320. doserror:=0;
  321. _closedir (PNWDirEnt(f.DirP));
  322. f.Magic := 0;
  323. f.DirP := NIL;
  324. f.EntryP := NIL;
  325. end;
  326. procedure swapvectors;
  327. begin
  328. end;
  329. {******************************************************************************
  330. --- File ---
  331. ******************************************************************************}
  332. procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;var ext : extstr);
  333. var
  334. dotpos,p1,i : longint;
  335. begin
  336. { allow backslash as slash }
  337. for i:=1 to length(path) do
  338. if path[i]='\' then path[i]:='/';
  339. { get volume name }
  340. p1:=pos(':',path);
  341. if p1>0 then
  342. begin
  343. dir:=copy(path,1,p1);
  344. delete(path,1,p1);
  345. end
  346. else
  347. dir:='';
  348. { split the path and the name, there are no more path informtions }
  349. { if path contains no backslashes }
  350. while true do
  351. begin
  352. p1:=pos('/',path);
  353. if p1=0 then
  354. break;
  355. dir:=dir+copy(path,1,p1);
  356. delete(path,1,p1);
  357. end;
  358. { try to find out a extension }
  359. //if LFNSupport then
  360. begin
  361. Ext:='';
  362. i:=Length(Path);
  363. DotPos:=256;
  364. While (i>0) Do
  365. Begin
  366. If (Path[i]='.') Then
  367. begin
  368. DotPos:=i;
  369. break;
  370. end;
  371. Dec(i);
  372. end;
  373. Ext:=Copy(Path,DotPos,255);
  374. Name:=Copy(Path,1,DotPos - 1);
  375. end
  376. (* else
  377. begin
  378. p1:=pos('.',path);
  379. if p1>0 then
  380. begin
  381. ext:=copy(path,p1,4);
  382. delete(path,p1,length(path)-p1+1);
  383. end
  384. else
  385. ext:='';
  386. name:=path;
  387. end;*)
  388. end;
  389. function GetShortName(var p : String) : boolean;
  390. begin
  391. GetShortName := false;
  392. end;
  393. function GetLongName(var p : String) : boolean;
  394. begin
  395. GetLongName := false;
  396. end;
  397. {$define FPC_FEXPAND_DRIVES}
  398. {$define FPC_FEXPAND_VOLUMES}
  399. {$define FPC_FEXPAND_NO_DEFAULT_PATHS}
  400. {$i fexpand.inc}
  401. Function FSearch(path: pathstr; dirlist: string): pathstr;
  402. var
  403. i,p1 : longint;
  404. s : searchrec;
  405. newdir : pathstr;
  406. begin
  407. write ('FSearch ("',path,'","',dirlist,'"');
  408. { check if the file specified exists }
  409. findfirst(path,anyfile,s);
  410. if doserror=0 then
  411. begin
  412. findclose(s);
  413. fsearch:=path;
  414. exit;
  415. end;
  416. { No wildcards allowed in these things }
  417. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  418. fsearch:=''
  419. else
  420. begin
  421. { allow backslash as slash }
  422. for i:=1 to length(dirlist) do
  423. if dirlist[i]='\' then dirlist[i]:='/';
  424. repeat
  425. p1:=pos(';',dirlist);
  426. if p1<>0 then
  427. begin
  428. newdir:=copy(dirlist,1,p1-1);
  429. delete(dirlist,1,p1);
  430. end
  431. else
  432. begin
  433. newdir:=dirlist;
  434. dirlist:='';
  435. end;
  436. if (newdir<>'') and (not (newdir[length(newdir)] in ['/',':'])) then
  437. newdir:=newdir+'/';
  438. findfirst(newdir+path,anyfile,s);
  439. if doserror=0 then
  440. newdir:=newdir+path
  441. else
  442. newdir:='';
  443. until (dirlist='') or (newdir<>'');
  444. fsearch:=newdir;
  445. end;
  446. findclose(s);
  447. end;
  448. {******************************************************************************
  449. --- Get/Set File Time,Attr ---
  450. ******************************************************************************}
  451. procedure getftime(var f;var time : longint);
  452. VAR StatBuf : NWStatBufT;
  453. T : DateTime;
  454. DosDate,
  455. DosTime : WORD;
  456. begin
  457. IF _fstat (FileRec (f).Handle, StatBuf) = 0 THEN
  458. BEGIN
  459. _ConvertTimeToDos (StatBuf.st_mtime, DosDate, DosTime);
  460. time := DosTime + (LONGINT (DosDate) SHL 16);
  461. END ELSE
  462. time := 0;
  463. end;
  464. procedure setftime(var f;time : longint);
  465. begin
  466. {is there a netware function to do that ?????}
  467. ConsolePrintf ('warning: fpc dos.setftime not implemented'#13#10,0);
  468. end;
  469. procedure getfattr(var f;var attr : word);
  470. VAR StatBuf : NWStatBufT;
  471. begin
  472. IF _fstat (FileRec (f).Handle, StatBuf) = 0 THEN
  473. BEGIN
  474. attr := word (StatBuf.st_attr);
  475. END ELSE
  476. attr := 0;
  477. end;
  478. procedure setfattr(var f;attr : word);
  479. begin
  480. {is there a netware function to do that ?????}
  481. ConsolePrintf ('warning: fpc dos.setfattr not implemented'#13#10,0);
  482. end;
  483. {******************************************************************************
  484. --- Environment ---
  485. ******************************************************************************}
  486. function envcount : longint;
  487. begin
  488. envcount := 0; {is there a netware function to do that ?????}
  489. ConsolePrintf ('warning: fpc dos.envcount not implemented'#13#10,0);
  490. end;
  491. function envstr (index: longint) : string;
  492. begin
  493. envstr := ''; {is there a netware function to do that ?????}
  494. ConsolePrintf ('warning: fpc dos.envstr not implemented'#13#10,0);
  495. end;
  496. { works fine (at least with netware 6.5) }
  497. Function GetEnv(envvar: string): string;
  498. var envvar0 : array[0..512] of char;
  499. p : pchar;
  500. i,isDosPath,res : longint;
  501. begin
  502. if upcase(envvar) = 'PATH' then
  503. begin // netware does not have search paths in the environment var PATH
  504. // return it here (needed for the compiler)
  505. GetEnv := '';
  506. i := 1;
  507. res := _NWGetSearchPathElement (i, isdosPath, @envvar0[0]);
  508. while res = 0 do
  509. begin
  510. if GetEnv <> '' then GetEnv := GetEnv + ';';
  511. GetEnv := GetEnv + envvar0;
  512. inc (i);
  513. res := _NWGetSearchPathElement (i, isdosPath, @envvar0[0]);
  514. end;
  515. for i := 1 to length(GetEnv) do
  516. if GetEnv[i] = '\' then
  517. GetEnv[i] := '/';
  518. end else
  519. begin
  520. strpcopy(envvar0,envvar);
  521. p := _getenv (envvar0);
  522. if p = NIL then
  523. GetEnv := ''
  524. else
  525. GetEnv := strpas (p);
  526. end;
  527. end;
  528. {******************************************************************************
  529. --- Not Supported ---
  530. ******************************************************************************}
  531. Procedure keep(exitcode : word);
  532. Begin
  533. { simply wait until nlm will be unloaded }
  534. while true do _delay (60000);
  535. End;
  536. Procedure getintvec(intno : byte;var vector : pointer);
  537. Begin
  538. { no netware equivalent }
  539. End;
  540. Procedure setintvec(intno : byte;vector : pointer);
  541. Begin
  542. { no netware equivalent }
  543. End;
  544. procedure intr(intno : byte;var regs : registers);
  545. begin
  546. { no netware equivalent }
  547. end;
  548. procedure msdos(var regs : registers);
  549. begin
  550. { no netware equivalent }
  551. end;
  552. end.
  553. {
  554. $Log$
  555. Revision 1.11 2004-08-01 20:02:48 armin
  556. * changed dir separator from \ to /
  557. * long namespace by default
  558. * dos.exec implemented
  559. * getenv ('PATH') is now supported
  560. * changed FExpand to global version
  561. * fixed heaplist growth error
  562. * support SysOSFree
  563. * stackcheck was without saveregisters
  564. * fpc can compile itself on netware
  565. Revision 1.10 2004/02/17 17:37:26 daniel
  566. * Enable threadvars again
  567. Revision 1.9 2004/02/16 22:16:59 hajny
  568. * LastDosExitCode changed back from threadvar temporarily
  569. Revision 1.8 2004/02/15 21:34:06 hajny
  570. * overloaded ExecuteProcess added, EnvStr param changed to longint
  571. Revision 1.7 2004/02/09 12:03:16 michael
  572. + Switched to single interface in dosh.inc
  573. Revision 1.6 2003/03/25 18:17:54 armin
  574. * support for fcl, support for linking without debug info
  575. * renamed winsock2 to winsock for win32 compatinility
  576. * new sockets unit for netware
  577. * changes for compiler warnings
  578. Revision 1.5 2002/09/07 16:01:20 peter
  579. * old logs removed and tabs fixed
  580. }