dos.pp 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1998 by Nils Sjoholm and Carl Eric Codere
  5. members of the Free Pascal development team
  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. {
  14. History:
  15. 10.02.1998 First version for Amiga.
  16. Just GetDate and GetTime.
  17. 11.02.1998 Added AmigaToDt and DtToAmiga
  18. Changed GetDate and GetTime to
  19. use AmigaToDt and DtToAmiga.
  20. Added DiskSize and DiskFree.
  21. They are using a string as arg
  22. have to try to fix that.
  23. 12.02.1998 Added Fsplit and FExpand.
  24. Cleaned up the unit and removed
  25. stuff that was not used yet.
  26. 13.02.1998 Added CToPas and PasToC and removed
  27. the uses of strings.
  28. 14.02.1998 Removed AmigaToDt and DtToAmiga
  29. from public area.
  30. Added deviceids and devicenames
  31. arrays so now diskfree and disksize
  32. is compatible with dos.
  33. }
  34. {--------------------------------------------------------------------}
  35. { LEFT TO DO: }
  36. {--------------------------------------------------------------------}
  37. { o DiskFree / Disksize don't work as expected }
  38. { o Implement SetDate and SetTime }
  39. { o Implement Setftime }
  40. { o Implement EnvCount,EnvStr }
  41. { o FindFirst should only work with correct attributes }
  42. {--------------------------------------------------------------------}
  43. Interface
  44. {$I os.inc}
  45. Const
  46. {Bitmasks for CPU Flags}
  47. fcarry = $0001;
  48. fparity = $0004;
  49. fauxiliary = $0010;
  50. fzero = $0040;
  51. fsign = $0080;
  52. foverflow = $0800;
  53. {Bitmasks for file attribute}
  54. readonly = $01;
  55. hidden = $02;
  56. sysfile = $04;
  57. volumeid = $08;
  58. directory = $10;
  59. archive = $20;
  60. anyfile = $3F;
  61. {File Status}
  62. fmclosed = $D7B0;
  63. fminput = $D7B1;
  64. fmoutput = $D7B2;
  65. fminout = $D7B3;
  66. Type
  67. ComStr = String[255]; { size increased to be more compatible with Unix}
  68. PathStr = String[255]; { size increased to be more compatible with Unix}
  69. DirStr = String[255]; { size increased to be more compatible with Unix}
  70. NameStr = String[255]; { size increased to be more compatible with Unix}
  71. ExtStr = String[255]; { size increased to be more compatible with Unix}
  72. {
  73. filerec.inc contains the definition of the filerec.
  74. textrec.inc contains the definition of the textrec.
  75. It is in a separate file to make it available in other units without
  76. having to use the DOS unit for it.
  77. }
  78. {$i filerec.inc}
  79. {$i textrec.inc}
  80. Type
  81. SearchRec = Packed Record
  82. { Replacement for Fill }
  83. AnchorPtr : Pointer; { Pointer to the Anchorpath structure }
  84. Fill: Array[1..14] of Byte; {future use}
  85. {End of replacement for fill}
  86. Attr : BYTE; {attribute of found file}
  87. Time : LongInt; {last modify date of found file}
  88. Size : LongInt; {file size of found file}
  89. Name : String[255]; {name of found file}
  90. End;
  91. DateTime = packed record
  92. Year: Word;
  93. Month: Word;
  94. Day: Word;
  95. Hour: Word;
  96. Min: Word;
  97. Sec: word;
  98. End;
  99. Var
  100. DosError : integer;
  101. {Interrupt}
  102. {Procedure Intr(intno: byte; var regs: registers);
  103. Procedure MSDos(var regs: registers);}
  104. {Info/Date/Time}
  105. Function DosVersion: Word;
  106. Procedure GetDate(var year, month, mday, wday: word);
  107. Procedure GetTime(var hour, minute, second, sec100: word);
  108. procedure SetDate(year,month,day: word);
  109. Procedure SetTime(hour,minute,second,sec100: word);
  110. Procedure UnpackTime(p: longint; var t: datetime);
  111. Procedure PackTime(var t: datetime; var p: longint);
  112. {Exec}
  113. Procedure Exec(const path: pathstr; const comline: comstr);
  114. Function DosExitCode: word;
  115. {Disk}
  116. Function DiskFree(drive: byte) : longint;
  117. Function DiskSize(drive: byte) : longint;
  118. Procedure FindFirst(path: pathstr; attr: word; var f: searchRec);
  119. Procedure FindNext(var f: searchRec);
  120. Procedure FindClose(Var f: SearchRec);
  121. {File}
  122. Procedure GetFAttr(var f; var attr: word);
  123. Procedure GetFTime(var f; var time: longint);
  124. Function FSearch(path: pathstr; dirlist: string): pathstr;
  125. Function FExpand(path: pathstr): pathstr;
  126. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  127. {Environment}
  128. Function EnvCount: longint;
  129. Function EnvStr(index: integer): string;
  130. Function GetEnv(envvar: string): string;
  131. {Misc}
  132. Procedure SetFAttr(var f; attr: word);
  133. Procedure SetFTime(var f; time: longint);
  134. Procedure GetCBreak(var breakvalue: boolean);
  135. Procedure SetCBreak(breakvalue: boolean);
  136. Procedure GetVerify(var verify: boolean);
  137. Procedure SetVerify(verify: boolean);
  138. {Do Nothing Functions}
  139. Procedure SwapVectors;
  140. Procedure GetIntVec(intno: byte; var vector: pointer);
  141. Procedure SetIntVec(intno: byte; vector: pointer);
  142. Procedure Keep(exitcode: word);
  143. implementation
  144. Type
  145. pClockData = ^tClockData;
  146. tClockData = packed Record
  147. sec : Word;
  148. min : Word;
  149. hour : Word;
  150. mday : Word;
  151. month : Word;
  152. year : Word;
  153. wday : Word;
  154. END;
  155. BPTR = Longint;
  156. BSTR = Longint;
  157. pMinNode = ^tMinNode;
  158. tMinNode = Packed Record
  159. mln_Succ,
  160. mln_Pred : pMinNode;
  161. End;
  162. pMinList = ^tMinList;
  163. tMinList = Packed record
  164. mlh_Head : pMinNode;
  165. mlh_Tail : pMinNode;
  166. mlh_TailPred : pMinNode;
  167. end;
  168. { * List Node Structure. Each member in a list starts with a Node * }
  169. pNode = ^tNode;
  170. tNode = Packed Record
  171. ln_Succ, { * Pointer to next (successor) * }
  172. ln_Pred : pNode; { * Pointer to previous (predecessor) * }
  173. ln_Type : Byte;
  174. ln_Pri : Shortint; { * Priority, for sorting * }
  175. ln_Name : PCHAR; { * ID string, null terminated * }
  176. End; { * Note: Integer aligned * }
  177. pList = ^tList;
  178. tList = Packed record
  179. lh_Head : pNode;
  180. lh_Tail : pNode;
  181. lh_TailPred : pNode;
  182. lh_Type : Byte;
  183. l_pad : Byte;
  184. end;
  185. pMsgPort = ^tMsgPort;
  186. tMsgPort = Packed record
  187. mp_Node : tNode;
  188. mp_Flags : Byte;
  189. mp_SigBit : Byte; { signal bit number }
  190. mp_SigTask : Pointer; { task to be signalled (TaskPtr) }
  191. mp_MsgList : tList; { message linked list }
  192. end;
  193. pTask = ^tTask;
  194. tTask = Packed record
  195. tc_Node : tNode;
  196. tc_Flags : Byte;
  197. tc_State : Byte;
  198. tc_IDNestCnt : Shortint; { intr disabled nesting }
  199. tc_TDNestCnt : Shortint; { task disabled nesting }
  200. tc_SigAlloc : Cardinal { sigs allocated }
  201. tc_SigWait : Cardinal; { sigs we are waiting for }
  202. tc_SigRecvd : Cardinal; { sigs we have received }
  203. tc_SigExcept : Cardinal; { sigs we will take excepts for }
  204. tc_TrapAlloc : Word; { traps allocated }
  205. tc_TrapAble : Word; { traps enabled }
  206. tc_ExceptData : Pointer; { points to except data }
  207. tc_ExceptCode : Pointer; { points to except code }
  208. tc_TrapData : Pointer; { points to trap data }
  209. tc_TrapCode : Pointer; { points to trap code }
  210. tc_SPReg : Pointer; { stack pointer }
  211. tc_SPLower : Pointer; { stack lower bound }
  212. tc_SPUpper : Pointer; { stack upper bound + 2 }
  213. tc_Switch : Pointer; { task losing CPU }
  214. tc_Launch : Pointer; { task getting CPU }
  215. tc_MemEntry : tList; { allocated memory }
  216. tc_UserData : Pointer; { per task data }
  217. end;
  218. TDateStamp = packed record
  219. ds_Days : Longint; { Number of days since Jan. 1, 1978 }
  220. ds_Minute : Longint; { Number of minutes past midnight }
  221. ds_Tick : Longint; { Number of ticks past minute }
  222. end;
  223. PDateStamp = ^TDateStamp;
  224. { Returned by Examine() and ExInfo(), must be on a 4 byte boundary }
  225. PFileInfoBlock = ^TfileInfoBlock;
  226. TFileInfoBlock = packed record
  227. fib_DiskKey : Longint;
  228. fib_DirEntryType : Longint;
  229. { Type of Directory. If < 0, then a plain file.
  230. If > 0 a directory }
  231. fib_FileName : Array [0..107] of Char;
  232. { Null terminated. Max 30 chars used for now }
  233. fib_Protection : Longint;
  234. { bit mask of protection, rwxd are 3-0. }
  235. fib_EntryType : Longint;
  236. fib_Size : Longint; { Number of bytes in file }
  237. fib_NumBlocks : Longint; { Number of blocks in file }
  238. fib_Date : TDateStamp; { Date file last changed }
  239. fib_Comment : Array [0..79] of Char;
  240. { Null terminated comment associated with file }
  241. fib_Reserved : Array [0..35] of Char;
  242. end;
  243. { returned by Info(), must be on a 4 byte boundary }
  244. pInfoData = ^tInfoData;
  245. tInfoData = packed record
  246. id_NumSoftErrors : Longint; { number of soft errors on disk }
  247. id_UnitNumber : Longint; { Which unit disk is (was) mounted on }
  248. id_DiskState : Longint; { See defines below }
  249. id_NumBlocks : Longint; { Number of blocks on disk }
  250. id_NumBlocksUsed : Longint; { Number of block in use }
  251. id_BytesPerBlock : Longint;
  252. id_DiskType : Longint; { Disk Type code }
  253. id_VolumeNode : BPTR; { BCPL pointer to volume node }
  254. id_InUse : Longint; { Flag, zero if not in use }
  255. end;
  256. { ------ Library Base Structure ---------------------------------- }
  257. { Also used for Devices and some Resources }
  258. pLibrary = ^tLibrary;
  259. tLibrary = packed record
  260. lib_Node : tNode;
  261. lib_Flags,
  262. lib_pad : Byte;
  263. lib_NegSize, { number of bytes before library }
  264. lib_PosSize, { number of bytes after library }
  265. lib_Version, { major }
  266. lib_Revision : Word; { minor }
  267. lib_IdString : PCHAR; { ASCII identification }
  268. lib_Sum : LONGINT; { the checksum itself }
  269. lib_OpenCnt : Word; { number of current opens }
  270. end; { * Warning: size is not a longword multiple ! * }
  271. PChain = ^TChain;
  272. TChain = packed record
  273. an_Child : PChain;
  274. an_Parent: PChain;
  275. an_Lock : BPTR;
  276. an_info : TFileInfoBlock;
  277. an_Flags : shortint;
  278. an_string: Array[0..0] of char;
  279. end;
  280. PAnchorPath = ^TAnchorPath;
  281. TAnchorPath = packed record
  282. ap_Base : PChain; {* pointer to first anchor *}
  283. ap_First : PChain; {* pointer to last anchor *}
  284. ap_BreakBits : LONGINT; {* Bits we want to break on *}
  285. ap_FondBreak : LONGINT; {* Bits we broke on. Also returns ERROR_BREAK *}
  286. ap_Flags : shortint; {* New use for extra word. *}
  287. ap_reserved : BYTE;
  288. ap_StrLen : WORD;
  289. ap_Info : TFileInfoBlock;
  290. ap_Buf : Array[0..0] of Char; {* Buffer for path name, allocated by user *}
  291. END;
  292. pCommandLineInterface = ^TCommandLineInterface;
  293. TCommandLineInterface = packed record
  294. cli_result2 : longint; {* Value of IoErr from last command *}
  295. cli_SetName : BSTR; {* Name of current directory *}
  296. cli_CommandDir : BPTR; {* Head of the path locklist *}
  297. cli_ReturnCode : longint; {* Return code from last command *}
  298. cli_CommandName : BSTR; {* Name of current command *}
  299. cli_FailLevel : longint; {* Fail level (set by FAILAT) *}
  300. cli_Prompt : BSTR; {* Current prompt (set by PROMPT) *}
  301. cli_StandardInput: BPTR; {* Default (terminal) CLI input *}
  302. cli_CurrentInput : BPTR; {* Current CLI input *}
  303. cli_CommandFile : BSTR; {* Name of EXECUTE command file *}
  304. cli_Interactive : longint; {* Boolean; True if prompts required *}
  305. cli_Background : longint {* Boolean; True if CLI created by RUN*}
  306. cli_CurrentOutput: BPTR; {* Current CLI output *}
  307. cli_DefautlStack : longint; {* Stack size to be obtained in long words *}
  308. cli_StandardOutput : BPTR; {* Default (terminal) CLI output *}
  309. cli_Module : BPTR; {* SegList of currently loaded command*}
  310. END;
  311. pDosList = ^tDosList;
  312. tDosList = packed record
  313. dol_Next : BPTR; { bptr to next device on list }
  314. dol_Type : Longint; { see DLT below }
  315. dol_Task : Pointer; { ptr to handler task }
  316. dol_Lock : BPTR;
  317. dol_Misc : Array[0..23] of Shortint;
  318. dol_Name : BSTR; { bptr to bcpl name }
  319. END;
  320. TProcess = packed record
  321. pr_Task : TTask;
  322. pr_MsgPort : TMsgPort; { This is BPTR address from DOS functions }
  323. {126} pr_Pad : Word; { Remaining variables on 4 byte boundaries }
  324. {128} pr_SegList : Pointer; { Array of seg lists used by this process }
  325. {132} pr_StackSize : Longint; { Size of process stack in bytes }
  326. {136} pr_GlobVec : Pointer; { Global vector for this process (BCPL) }
  327. {140} pr_TaskNum : Longint; { CLI task number of zero if not a CLI }
  328. {144} pr_StackBase : BPTR; { Ptr to high memory end of process stack }
  329. {148} pr_Result2 : Longint; { Value of secondary result from last call }
  330. {152} pr_CurrentDir : BPTR; { Lock associated with current directory }
  331. {156} pr_CIS : BPTR; { Current CLI Input Stream }
  332. {160} pr_COS : BPTR; { Current CLI Output Stream }
  333. {164} pr_ConsoleTask : Pointer; { Console handler process for current window}
  334. {168} pr_FileSystemTask : Pointer; { File handler process for current drive }
  335. {172} pr_CLI : BPTR; { pointer to ConsoleLineInterpreter }
  336. pr_ReturnAddr : Pointer; { pointer to previous stack frame }
  337. pr_PktWait : Pointer; { Function to be called when awaiting msg }
  338. pr_WindowPtr : Pointer; { Window for error printing }
  339. { following definitions are new with 2.0 }
  340. pr_HomeDir : BPTR; { Home directory of executing program }
  341. pr_Flags : Longint; { flags telling dos about process }
  342. pr_ExitCode : Pointer; { code to call on exit of program OR NULL }
  343. pr_ExitData : Longint; { Passed as an argument to pr_ExitCode. }
  344. pr_Arguments : PChar; { Arguments passed to the process at start }
  345. pr_LocalVars : TMinList; { Local environment variables }
  346. pr_ShellPrivate : Longint; { for the use of the current shell }
  347. pr_CES : BPTR; { Error stream - IF NULL, use pr_COS }
  348. end;
  349. PProcess = ^TProcess;
  350. CONST
  351. { DOS Lib Offsets }
  352. _LVOMatchFirst = -822;
  353. _LVOMatchNext = -828;
  354. _LVOMatchEnd = -834;
  355. _LVOCli = -492;
  356. _LVOExecute = -222;
  357. _LVOSystemTagList = -606;
  358. LDF_READ = 1;
  359. LDF_DEVICES = 4;
  360. ERROR_NO_MORE_ENTRIES = 232;
  361. FIBF_SCRIPT = 64; { program is a script }
  362. FIBF_PURE = 32; { program is reentrant }
  363. FIBF_ARCHIVE = 16; { cleared whenever file is changed }
  364. FIBF_READ = 8; { ignoed by old filesystem }
  365. FIBF_WRITE = 4; { ignored by old filesystem }
  366. FIBF_EXECUTE = 2; { ignored by system, used by shell }
  367. FIBF_DELETE = 1; { prevent file from being deleted }
  368. SHARED_LOCK = -2;
  369. {******************************************************************************
  370. --- Internal routines ---
  371. ******************************************************************************}
  372. procedure CurrentTime(var Seconds, Micros : Longint);
  373. Begin
  374. asm
  375. MOVE.L A6,-(A7)
  376. MOVE.L Seconds,a0
  377. MOVE.L Micros,a1
  378. MOVE.L _IntuitionBase,A6
  379. JSR -084(A6)
  380. MOVE.L (A7)+,A6
  381. end;
  382. end;
  383. function Date2Amiga(date : pClockData) : Longint;
  384. Begin
  385. asm
  386. MOVE.L A6,-(A7)
  387. MOVE.L date,a0
  388. MOVE.L _UtilityBase,A6
  389. JSR -126(A6)
  390. MOVE.L (A7)+,A6
  391. MOVE.L d0,@RESULT
  392. end;
  393. end;
  394. procedure Amiga2Date(amigatime : Longint;
  395. resultat : pClockData);
  396. Begin
  397. asm
  398. MOVE.L A6,-(A7)
  399. MOVE.L amigatime,d0
  400. MOVE.L resultat,a0
  401. MOVE.L _UtilityBase,A6
  402. JSR -120(A6)
  403. MOVE.L (A7)+,A6
  404. end;
  405. end;
  406. FUNCTION Examine(lock : BPTR; fileInfoBlock : pFileInfoBlock) : BOOLEAN;
  407. BEGIN
  408. ASM
  409. MOVE.L A6,-(A7)
  410. MOVE.L lock,D1
  411. MOVE.L fileInfoBlock,D2
  412. MOVEA.L _DOSBase,A6
  413. JSR -102(A6)
  414. MOVEA.L (A7)+,A6
  415. TST.L D0
  416. BEQ.B @end
  417. MOVEQ #1,D0
  418. @end: MOVE.B D0,@RESULT
  419. END;
  420. END;
  421. function Lock(const name : string;
  422. accessmode : Longint) : BPTR;
  423. var
  424. buffer: Array[0..50] of char;
  425. Begin
  426. move(name[1],buffer,length(name));
  427. buffer[length(name)]:=#0;
  428. asm
  429. MOVEM.L d2/a6,-(A7)
  430. LEA buffer,a0
  431. MOVE.L a0,d1
  432. MOVE.L accessmode,d2
  433. MOVE.L _DOSBase,A6
  434. JSR -084(A6)
  435. MOVEM.L (A7)+,d2/a6
  436. MOVE.L d0,@RESULT
  437. end;
  438. end;
  439. procedure UnLock(lock : BPTR);
  440. Begin
  441. asm
  442. MOVE.L A6,-(A7)
  443. MOVE.L lock,d1
  444. MOVE.L _DOSBase,A6
  445. JSR -090(A6)
  446. MOVE.L (A7)+,A6
  447. end;
  448. end;
  449. FUNCTION Info(lock : BPTR; parameterBlock : pInfoData) : BOOLEAN;
  450. BEGIN
  451. ASM
  452. MOVE.L A6,-(A7)
  453. MOVE.L lock,D1
  454. MOVE.L parameterBlock,D2
  455. MOVEA.L _DOSBase,A6
  456. JSR -114(A6)
  457. MOVEA.L (A7)+,A6
  458. TST.L D0
  459. BEQ.B @end
  460. MOVEQ #1,D0
  461. @end: MOVE.B D0,@RESULT
  462. END;
  463. END;
  464. FUNCTION NameFromLock(lock : BPTR; buffer : pCHAR; len : LONGINT) : BOOLEAN;
  465. BEGIN
  466. ASM
  467. MOVE.L A6,-(A7)
  468. MOVE.L lock,D1
  469. MOVE.L buffer,D2
  470. MOVE.L len,D3
  471. MOVEA.L _DOSBase,A6
  472. JSR -402(A6)
  473. MOVEA.L (A7)+,A6
  474. TST.L D0
  475. BEQ.B @end
  476. MOVEQ #1,D0
  477. @end: MOVE.B D0,@RESULT
  478. END;
  479. END;
  480. FUNCTION GetVar(name : pCHAR; buffer : pCHAR; size : LONGINT; flags : LONGINT) : LONGINT;
  481. BEGIN
  482. ASM
  483. MOVE.L A6,-(A7)
  484. MOVE.L name,D1
  485. MOVE.L buffer,D2
  486. MOVE.L size,D3
  487. MOVE.L flags,D4
  488. MOVEA.L _DOSBase,A6
  489. JSR -906(A6)
  490. MOVEA.L (A7)+,A6
  491. MOVE.L D0,@RESULT
  492. END;
  493. END;
  494. FUNCTION FindTask(name : pCHAR) : pTask;
  495. BEGIN
  496. ASM
  497. MOVE.L A6,-(A7)
  498. MOVEA.L name,A1
  499. MOVEA.L _ExecBase,A6
  500. JSR -294(A6)
  501. MOVEA.L (A7)+,A6
  502. MOVE.L D0,@RESULT
  503. END;
  504. END;
  505. FUNCTION MatchFirst(pat : pCHAR; anchor : pAnchorPath) : LONGINT;
  506. BEGIN
  507. ASM
  508. MOVE.L A6,-(A7)
  509. MOVE.L pat,D1
  510. MOVE.L anchor,D2
  511. MOVEA.L _DOSBase,A6
  512. JSR -822(A6)
  513. MOVEA.L (A7)+,A6
  514. MOVE.L D0,@RESULT
  515. END;
  516. END;
  517. FUNCTION MatchNext(anchor : pAnchorPath) : LONGINT;
  518. BEGIN
  519. ASM
  520. MOVE.L A6,-(A7)
  521. MOVE.L anchor,D1
  522. MOVEA.L _DOSBase,A6
  523. JSR -828(A6)
  524. MOVEA.L (A7)+,A6
  525. MOVE.L D0,@RESULT
  526. END;
  527. END;
  528. PROCEDURE MatchEnd(anchor : pAnchorPath);
  529. BEGIN
  530. ASM
  531. MOVE.L A6,-(A7)
  532. MOVE.L anchor,D1
  533. MOVEA.L _DOSBase,A6
  534. JSR -834(A6)
  535. MOVEA.L (A7)+,A6
  536. END;
  537. END;
  538. FUNCTION Cli : pCommandLineInterface;
  539. BEGIN
  540. ASM
  541. MOVE.L A6,-(A7)
  542. MOVEA.L _DOSBase,A6
  543. JSR -492(A6)
  544. MOVEA.L (A7)+,A6
  545. MOVE.L D0,@RESULT
  546. END;
  547. END;
  548. Function _Execute(p: pchar): longint;
  549. Begin
  550. asm
  551. move.l a6,d6 { save base pointer }
  552. move.l d2,-(sp)
  553. move.l p,d1 { command to execute }
  554. clr.l d2 { No TagList for command }
  555. move.l _DosBase,a6
  556. jsr _LVOSystemTagList(a6)
  557. move.l (sp)+,d2
  558. move.l d6,a6 { restore base pointer }
  559. move.l d0,@RESULT
  560. end;
  561. end;
  562. FUNCTION LockDosList(flags : CARDINAL) : pDosList;
  563. BEGIN
  564. ASM
  565. MOVE.L A6,-(A7)
  566. MOVE.L flags,D1
  567. MOVEA.L _DOSBase,A6
  568. JSR -654(A6)
  569. MOVEA.L (A7)+,A6
  570. MOVE.L D0,@RESULT
  571. END;
  572. END;
  573. PROCEDURE UnLockDosList(flags : CARDINAL);
  574. BEGIN
  575. ASM
  576. MOVE.L A6,-(A7)
  577. MOVE.L flags,D1
  578. MOVEA.L _DOSBase,A6
  579. JSR -660(A6)
  580. MOVEA.L (A7)+,A6
  581. END;
  582. END;
  583. FUNCTION NextDosEntry(dlist : pDosList; flags : CARDINAL) : pDosList;
  584. BEGIN
  585. ASM
  586. MOVE.L A6,-(A7)
  587. MOVE.L dlist,D1
  588. MOVE.L flags,D2
  589. MOVEA.L _DOSBase,A6
  590. JSR -690(A6)
  591. MOVEA.L (A7)+,A6
  592. MOVE.L D0,@RESULT
  593. END;
  594. END;
  595. FUNCTION BADDR(bval : BPTR): POINTER;
  596. BEGIN
  597. BADDR := POINTER( bval shl 2);
  598. END;
  599. function PasToC(var s: string): Pchar;
  600. var i: integer;
  601. begin
  602. i := Length(s) + 1;
  603. if i > 255 then
  604. begin
  605. Delete(s, 255, 1); { ensure there is a spare byte }
  606. Dec(i)
  607. end;
  608. s[i] := #0;
  609. PasToC := @s[1]
  610. end;
  611. Procedure AmigaToDt(SecsPast: LongInt; Var Dt: DateTime);
  612. var
  613. cd : pClockData;
  614. Begin
  615. New(cd);
  616. Amiga2Date(SecsPast,cd);
  617. Dt.sec := cd^.sec;
  618. Dt.min := cd^.min;
  619. Dt.hour := cd^.hour;
  620. Dt.day := cd^.mday;
  621. Dt.month := cd^.month;
  622. Dt.year := cd^.year;
  623. Dispose(cd);
  624. End;
  625. Function DtToAmiga(DT: DateTime): LongInt;
  626. var
  627. cd : pClockData;
  628. temp : Longint;
  629. Begin
  630. New(cd);
  631. cd^.sec := Dt.sec;
  632. cd^.min := Dt.min;
  633. cd^.hour := Dt.hour;
  634. cd^.mday := Dt.day;
  635. cd^.month := Dt.month;
  636. cd^.year := Dt.year;
  637. temp := Date2Amiga(cd);
  638. Dispose(cd);
  639. DtToAmiga := temp;
  640. end;
  641. Function SetProtection(const name: string; mask:longint): longint;
  642. var
  643. buffer : array[0..255] of char;
  644. Begin
  645. move(name[1],buffer,length(name));
  646. buffer[length(name)]:=#0;
  647. asm
  648. move.l a6,d6
  649. lea buffer,a0
  650. move.l a0,d1
  651. move.l mask,d2
  652. move.l _DosBase,a6
  653. jsr -186(a6)
  654. move.l d6,a6
  655. move.l d0,@RESULT
  656. end;
  657. end;
  658. {******************************************************************************
  659. --- Dos Interrupt ---
  660. ******************************************************************************}
  661. (*Procedure Intr (intno: byte; var regs: registers);
  662. Begin
  663. { Does not apply to Linux - not implemented }
  664. End;*)
  665. Procedure SwapVectors;
  666. Begin
  667. { Does not apply to Linux - Do Nothing }
  668. End;
  669. (*Procedure msdos(var regs : registers);
  670. Begin
  671. { ! Not implemented in Linux ! }
  672. End;*)
  673. Procedure getintvec(intno : byte;var vector : pointer);
  674. Begin
  675. { ! Not implemented in Linux ! }
  676. End;
  677. Procedure setintvec(intno : byte;vector : pointer);
  678. Begin
  679. { ! Not implemented in Linux ! }
  680. End;
  681. {******************************************************************************
  682. --- Info / Date / Time ---
  683. ******************************************************************************}
  684. Function DosVersion: Word;
  685. var p: pLibrary;
  686. Begin
  687. p:=pLibrary(_DosBase);
  688. DosVersion:= p^.lib_Version or (p^.lib_Revision shl 8);
  689. End;
  690. Procedure GetDate(Var Year, Month, MDay, WDay: Word);
  691. Var
  692. cd : pClockData;
  693. mysec,
  694. tick : Longint;
  695. begin
  696. New(cd);
  697. CurrentTime(mysec,tick);
  698. Amiga2Date(mysec,cd);
  699. Year := cd^.year;
  700. Month := cd^.month;
  701. MDay := cd^.mday;
  702. WDay := cd^.wday;
  703. Dispose(cd);
  704. end;
  705. Procedure SetDate(Year, Month, Day: Word);
  706. Begin
  707. { !! }
  708. End;
  709. Procedure GetTime(Var Hour, Minute, Second, Sec100: Word);
  710. Var
  711. mysec,
  712. tick : Longint;
  713. cd : pClockData;
  714. begin
  715. New(cd);
  716. CurrentTime(mysec,tick);
  717. Amiga2Date(mysec,cd);
  718. Hour := cd^.hour;
  719. Minute := cd^.min;
  720. Second := cd^.sec;
  721. Sec100 := 0;
  722. Dispose(cd);
  723. END;
  724. Procedure SetTime(Hour, Minute, Second, Sec100: Word);
  725. Begin
  726. { !! }
  727. End;
  728. Procedure unpacktime(p : longint;var t : datetime);
  729. Begin
  730. AmigaToDt(p,t);
  731. End;
  732. Procedure packtime(var t : datetime;var p : longint);
  733. Begin
  734. p := DtToAmiga(t);
  735. end;
  736. {******************************************************************************
  737. --- Exec ---
  738. ******************************************************************************}
  739. Var
  740. LastDosExitCode: word;
  741. breakflag : Boolean;
  742. ver: Boolean;
  743. Procedure Exec (Const Path: PathStr; Const ComLine: ComStr);
  744. var
  745. p : string;
  746. buf: array[0..255] of char;
  747. result : longint;
  748. MyLock : longint;
  749. i : Integer;
  750. Begin
  751. DosError := 0;
  752. LastdosExitCode := 0;
  753. p:=Path+' '+ComLine;
  754. { allow backslash as slash }
  755. for i:=1 to length(p) do
  756. if p[i]='\' then p[i]:='/';
  757. Move(p[1],buf,length(p));
  758. buf[Length(p)]:=#0;
  759. { Here we must first check if the command we wish to execute }
  760. { actually exists, because this is NOT handled by the }
  761. { _SystemTagList call (program will abort!!) }
  762. { Try to open with shared lock }
  763. MyLock:=Lock(path,SHARED_LOCK);
  764. if MyLock <> 0 then
  765. Begin
  766. { File exists - therefore unlock it }
  767. Unlock(MyLock);
  768. result:=_Execute(buf);
  769. { on return of -1 the shell could not be executed }
  770. { probably because there was not enough memory }
  771. if result = -1 then
  772. DosError:=8
  773. else
  774. LastDosExitCode:=word(result);
  775. end
  776. else
  777. DosError:=3;
  778. End;
  779. Function DosExitCode: Word;
  780. Begin
  781. DosExitCode:=LastdosExitCode;
  782. End;
  783. Procedure GetCBreak(Var BreakValue: Boolean);
  784. Begin
  785. breakvalue:=breakflag;
  786. End;
  787. Procedure SetCBreak(BreakValue: Boolean);
  788. Begin
  789. breakflag:=BreakValue;
  790. End;
  791. Procedure GetVerify(Var Verify: Boolean);
  792. Begin
  793. verify:=ver;
  794. End;
  795. Procedure SetVerify(Verify: Boolean);
  796. Begin
  797. ver:=Verify;
  798. End;
  799. {******************************************************************************
  800. --- Disk ---
  801. ******************************************************************************}
  802. { How to solve the problem with this: }
  803. { We could walk through the device list }
  804. { at startup to determine possible devices }
  805. const
  806. not_to_use_devs : array[0..12] of string =(
  807. 'DF0:',
  808. 'DF1:',
  809. 'DF2:',
  810. 'DF3:',
  811. 'PED:',
  812. 'PRJ:',
  813. 'PIPE:',
  814. 'RAM:',
  815. 'CON:',
  816. 'RAW:',
  817. 'SER:',
  818. 'PAR:',
  819. 'PRT:');
  820. var
  821. deviceids : array[1..20] of byte;
  822. devicenames : array[1..20] of string[20];
  823. numberofdevices : Byte;
  824. Function DiskFree(Drive: Byte): Longint;
  825. Var
  826. MyLock : BPTR;
  827. Inf : pInfoData;
  828. Free : Longint;
  829. myproc : pProcess;
  830. OldWinPtr : Pointer;
  831. Begin
  832. Free := -1;
  833. { Here we stop systemrequesters to appear }
  834. myproc := pProcess(FindTask(nil));
  835. OldWinPtr := myproc^.pr_WindowPtr;
  836. myproc^.pr_WindowPtr := Pointer(-1);
  837. { End of systemrequesterstop }
  838. New(Inf);
  839. MyLock := Lock(devicenames[deviceids[Drive]],SHARED_LOCK);
  840. If MyLock <> 0 then begin
  841. if Info(MyLock,Inf) then begin
  842. Free := (Inf^.id_NumBlocks * Inf^.id_BytesPerBlock) -
  843. (Inf^.id_NumBlocksUsed * Inf^.id_BytesPerBlock);
  844. end;
  845. Unlock(MyLock);
  846. end;
  847. Dispose(Inf);
  848. { Restore systemrequesters }
  849. myproc^.pr_WindowPtr := OldWinPtr;
  850. diskfree := Free;
  851. end;
  852. Function DiskSize(Drive: Byte): Longint;
  853. Var
  854. MyLock : BPTR;
  855. Inf : pInfoData;
  856. Size : Longint;
  857. myproc : pProcess;
  858. OldWinPtr : Pointer;
  859. Begin
  860. Size := -1;
  861. { Here we stop systemrequesters to appear }
  862. myproc := pProcess(FindTask(nil));
  863. OldWinPtr := myproc^.pr_WindowPtr;
  864. myproc^.pr_WindowPtr := Pointer(-1);
  865. { End of systemrequesterstop }
  866. New(Inf);
  867. MyLock := Lock(devicenames[deviceids[Drive]],SHARED_LOCK);
  868. If MyLock <> 0 then begin
  869. if Info(MyLock,Inf) then begin
  870. Size := (Inf^.id_NumBlocks * Inf^.id_BytesPerBlock);
  871. end;
  872. Unlock(MyLock);
  873. end;
  874. Dispose(Inf);
  875. { Restore systemrequesters }
  876. myproc^.pr_WindowPtr := OldWinPtr;
  877. disksize := Size;
  878. end;
  879. Procedure FindFirst(Path: PathStr; Attr: Word; Var f: SearchRec);
  880. var
  881. buf: Array[0..255] of char;
  882. Anchor : pAnchorPath;
  883. Result : Longint;
  884. index : Integer;
  885. Begin
  886. DosError:=0;
  887. New(Anchor);
  888. {----- allow backslash as slash -----}
  889. for index:=1 to length(path) do
  890. if path[index]='\' then path[index]:='/';
  891. {----- replace * by #? AmigaOs strings -----}
  892. repeat
  893. index:= pos('*',Path);
  894. if index <> 0 then
  895. Begin
  896. delete(Path,index,1);
  897. insert('#?',Path,index);
  898. end;
  899. until index =0;
  900. {--------------------------------------------}
  901. FillChar(Anchor^,sizeof(TAnchorPath),#0);
  902. move(path[1],buf,length(path));
  903. buf[length(path)]:=#0;
  904. Result:=MatchFirst(@buf,Anchor);
  905. f.AnchorPtr:=Anchor;
  906. if Result = ERROR_NO_MORE_ENTRIES then
  907. DosError:=18
  908. else
  909. if Result <> 0 then
  910. DosError:=3;
  911. { If there is an error, deallocate }
  912. { the anchorpath structure }
  913. if DosError <> 0 then
  914. Begin
  915. MatchEnd(Anchor);
  916. if assigned(Anchor) then
  917. Dispose(Anchor);
  918. end
  919. else
  920. {-------------------------------------------------------------------}
  921. { Here we fill up the SearchRec attribute, but we also do check }
  922. { something else, if the it does not match the mask we are looking }
  923. { for we should go to the next file or directory. }
  924. {-------------------------------------------------------------------}
  925. Begin
  926. with Anchor^.ap_Info do
  927. Begin
  928. f.Time := fib_Date.ds_Days * (24 * 60 * 60) +
  929. fib_Date.ds_Minute * 60 +
  930. fib_Date.ds_Tick div 50;
  931. {*------------------------------------*}
  932. {* Determine if is a file or a folder *}
  933. {*------------------------------------*}
  934. if fib_DirEntryType > 0 then
  935. f.attr:=f.attr OR DIRECTORY;
  936. {*------------------------------------*}
  937. {* Determine if Read only *}
  938. {* Readonly if R flag on and W flag *}
  939. {* off. *}
  940. {* Should we check also that EXEC *}
  941. {* is zero? for read only? *}
  942. {*------------------------------------*}
  943. if ((fib_Protection and FIBF_READ) <> 0)
  944. AND ((fib_Protection and FIBF_WRITE) = 0)
  945. then
  946. f.attr:=f.attr or READONLY;
  947. f.Name := strpas(fib_FileName);
  948. f.Size := fib_Size;
  949. end; { end with }
  950. end;
  951. End;
  952. Procedure FindNext(Var f: SearchRec);
  953. var
  954. Result: longint;
  955. Anchor : pAnchorPath;
  956. Begin
  957. DosError:=0;
  958. Result:=MatchNext(f.AnchorPtr);
  959. if Result = ERROR_NO_MORE_ENTRIES then
  960. DosError:=18
  961. else
  962. if Result <> 0 then
  963. DosError:=3;
  964. { If there is an error, deallocate }
  965. { the anchorpath structure }
  966. if DosError <> 0 then
  967. Begin
  968. MatchEnd(f.AnchorPtr);
  969. if assigned(f.AnchorPtr) then
  970. Dispose(f.AnchorPtr);
  971. end
  972. else
  973. { Fill up the Searchrec information }
  974. { and also check if the files are with }
  975. { the correct attributes }
  976. Begin
  977. Anchor:=pAnchorPath(f.AnchorPtr);
  978. with Anchor^.ap_Info do
  979. Begin
  980. f.Time := fib_Date.ds_Days * (24 * 60 * 60) +
  981. fib_Date.ds_Minute * 60 +
  982. fib_Date.ds_Tick div 50;
  983. {*------------------------------------*}
  984. {* Determine if is a file or a folder *}
  985. {*------------------------------------*}
  986. if fib_DirEntryType > 0 then
  987. f.attr:=f.attr OR DIRECTORY;
  988. {*------------------------------------*}
  989. {* Determine if Read only *}
  990. {* Readonly if R flag on and W flag *}
  991. {* off. *}
  992. {* Should we check also that EXEC *}
  993. {* is zero? for read only? *}
  994. {*------------------------------------*}
  995. if ((fib_Protection and FIBF_READ) <> 0)
  996. AND ((fib_Protection and FIBF_WRITE) = 0)
  997. then
  998. f.attr:=f.attr or READONLY;
  999. f.Name := strpas(fib_FileName);
  1000. f.Size := fib_Size;
  1001. end; { end with }
  1002. end;
  1003. End;
  1004. Procedure FindClose(Var f: SearchRec);
  1005. begin
  1006. end;
  1007. {******************************************************************************
  1008. --- File ---
  1009. ******************************************************************************}
  1010. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  1011. var
  1012. I: Word;
  1013. begin
  1014. { allow backslash as slash }
  1015. for i:=1 to length(path) do
  1016. if path[i]='\' then path[i]:='/';
  1017. I := Length(Path);
  1018. while (I > 0) and not ((Path[I] = '/') or (Path[I] = ':'))
  1019. do Dec(I);
  1020. if Path[I] = '/' then
  1021. dir := Copy(Path, 0, I)
  1022. else dir := Copy(Path,0,I);
  1023. if Length(Path) > Length(dir) then
  1024. name := Copy(Path, I + 1, Length(Path)-I)
  1025. else
  1026. name := '';
  1027. { Remove extension }
  1028. if pos('.',name) <> 0 then
  1029. delete(name,pos('.',name),length(name));
  1030. I := Pos('.',Path);
  1031. if I > 0 then
  1032. ext := Copy(Path,I,Length(Path)-(I-1))
  1033. else ext := '';
  1034. end;
  1035. Function FExpand(Path: PathStr): PathStr;
  1036. var
  1037. FLock : BPTR;
  1038. buffer : array[0..255] of char;
  1039. i :integer;
  1040. begin
  1041. { allow backslash as slash }
  1042. for i:=1 to length(path) do
  1043. if path[i]='\' then path[i]:='/';
  1044. FLock := Lock(Path,-2);
  1045. if FLock <> 0 then begin
  1046. if NameFromLock(FLock,buffer,255) then begin
  1047. Unlock(FLock);
  1048. FExpand := strpas(buffer);
  1049. end else begin
  1050. Unlock(FLock);
  1051. FExpand := '';
  1052. end;
  1053. end else FExpand := '';
  1054. end;
  1055. Function fsearch(path : pathstr;dirlist : string) : pathstr;
  1056. var
  1057. i,p1 : longint;
  1058. s : searchrec;
  1059. newdir : pathstr;
  1060. begin
  1061. { No wildcards allowed in these things }
  1062. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  1063. fsearch:=''
  1064. else
  1065. begin
  1066. { allow slash as backslash }
  1067. for i:=1 to length(dirlist) do
  1068. if dirlist[i]='\' then dirlist[i]:='/';
  1069. repeat
  1070. p1:=pos(';',dirlist);
  1071. if p1<>0 then
  1072. begin
  1073. newdir:=copy(dirlist,1,p1-1);
  1074. delete(dirlist,1,p1);
  1075. end
  1076. else
  1077. begin
  1078. newdir:=dirlist;
  1079. dirlist:='';
  1080. end;
  1081. if (newdir<>'') and (not (newdir[length(newdir)] in ['/',':'])) then
  1082. newdir:=newdir+'/';
  1083. findfirst(newdir+path,anyfile,s);
  1084. if doserror=0 then
  1085. newdir:=newdir+path
  1086. else
  1087. newdir:='';
  1088. until (dirlist='') or (newdir<>'');
  1089. fsearch:=newdir;
  1090. end;
  1091. end;
  1092. Procedure getftime (var f; var time : longint);
  1093. {
  1094. This function returns a file's date and time as the number of
  1095. seconds after January 1, 1978 that the file was created.
  1096. }
  1097. var
  1098. FInfo : pFileInfoBlock;
  1099. FTime : Longint;
  1100. FLock : Longint;
  1101. Str : String;
  1102. i : integer;
  1103. begin
  1104. DosError:=0;
  1105. FTime := 0;
  1106. Str := StrPas(filerec(f).name);
  1107. for i:=1 to length(Str) do
  1108. if str[i]='\' then str[i]:='/';
  1109. FLock := Lock(Str, SHARED_LOCK);
  1110. IF FLock <> 0 then begin
  1111. New(FInfo);
  1112. if Examine(FLock, FInfo) then begin
  1113. with FInfo^.fib_Date do
  1114. FTime := ds_Days * (24 * 60 * 60) +
  1115. ds_Minute * 60 +
  1116. ds_Tick div 50;
  1117. end else begin
  1118. FTime := 0;
  1119. end;
  1120. Unlock(FLock);
  1121. Dispose(FInfo);
  1122. end
  1123. else
  1124. DosError:=6;
  1125. time := FTime;
  1126. end;
  1127. Procedure setftime(var f; time : longint);
  1128. var
  1129. ClockData: pClockData;
  1130. Begin
  1131. DosError:=0;
  1132. New(ClockData);
  1133. (* { We must find the number of days since jan-1978 }
  1134. ds_Days:=Time div 3600;
  1135. ds_Minute:=Time mod 3600;
  1136. ds_Tick:=
  1137. Amiga2Date(Time, ClockData);
  1138. ds_Days : Longint; { Number of days since Jan. 1, 1978 }
  1139. ds_Minute : Longint; { Number of minutes past midnight }
  1140. ds_Tick : Longint; { Number of ticks past minute }*)
  1141. Dispose(ClockData);
  1142. End;
  1143. Procedure getfattr(var f; var attr : word);
  1144. var
  1145. info : pFileInfoBlock;
  1146. MyLock : Longint;
  1147. flags: word;
  1148. Str: String;
  1149. i: integer;
  1150. Begin
  1151. DosError:=0;
  1152. flags:=0;
  1153. New(info);
  1154. { open with shared lock }
  1155. Str := StrPas(filerec(f).name);
  1156. for i:=1 to length(Str) do
  1157. if str[i]='\' then str[i]:='/';
  1158. MyLock:=Lock(Str,SHARED_LOCK);
  1159. if MyLock <> 0 then
  1160. Begin
  1161. Examine(MyLock,info);
  1162. {*------------------------------------*}
  1163. {* Determine if is a file or a folder *}
  1164. {*------------------------------------*}
  1165. if info^.fib_DirEntryType > 0 then
  1166. flags:=flags OR DIRECTORY;
  1167. {*------------------------------------*}
  1168. {* Determine if Read only *}
  1169. {* Readonly if R flag on and W flag *}
  1170. {* off. *}
  1171. {* Should we check also that EXEC *}
  1172. {* is zero? for read only? *}
  1173. {*------------------------------------*}
  1174. if ((info^.fib_Protection and FIBF_READ) <> 0)
  1175. AND ((info^.fib_Protection and FIBF_WRITE) = 0)
  1176. then
  1177. flags:=flags OR ReadOnly;
  1178. Unlock(mylock);
  1179. end
  1180. else
  1181. DosError:=3;
  1182. attr:=flags;
  1183. Dispose(info);
  1184. End;
  1185. Procedure setfattr (var f;attr : word);
  1186. var
  1187. flags: longint;
  1188. MyLock : longint;
  1189. str: string;
  1190. i: integer;
  1191. Begin
  1192. DosError:=0;
  1193. flags:=FIBF_WRITE;
  1194. { open with shared lock }
  1195. Str := StrPas(filerec(f).name);
  1196. for i:=1 to length(Str) do
  1197. if str[i]='\' then str[i]:='/';
  1198. MyLock:=Lock(Str,SHARED_LOCK);
  1199. { By default files are read-write }
  1200. if attr AND ReadOnly <> 0 then
  1201. { Clear the Fibf_write flags }
  1202. flags:=FIBF_READ;
  1203. if MyLock <> 0 then
  1204. Begin
  1205. Unlock(MyLock);
  1206. if SetProtection(Str,flags) = 0 then
  1207. DosError:=5;
  1208. end
  1209. else
  1210. DosError:=3;
  1211. End;
  1212. {******************************************************************************
  1213. --- Environment ---
  1214. ******************************************************************************}
  1215. Function EnvCount: Longint;
  1216. { HOW TO GET THIS VALUE: }
  1217. { Each time this function is called, we look at the }
  1218. { local variables in the Process structure (2.0+) }
  1219. { And we also read all files in the ENV: directory }
  1220. Begin
  1221. End;
  1222. Function EnvStr(Index: Integer): String;
  1223. Begin
  1224. EnvStr:='';
  1225. End;
  1226. function GetEnv(envvar : String): String;
  1227. var
  1228. buffer : Pchar;
  1229. bufarr : array[0..255] of char;
  1230. strbuffer : array[0..255] of char;
  1231. temp : Longint;
  1232. begin
  1233. move(envvar[1],strbuffer,length(envvar));
  1234. strbuffer[length(envvar)] := #0;
  1235. buffer := @bufarr;
  1236. temp := GetVar(strbuffer,buffer,255,$100);
  1237. if temp = -1 then
  1238. GetEnv := ''
  1239. else GetEnv := StrPas(buffer);
  1240. end;
  1241. {******************************************************************************
  1242. --- Not Supported ---
  1243. ******************************************************************************}
  1244. Procedure keep(exitcode : word);
  1245. Begin
  1246. { ! Not implemented in Linux ! }
  1247. End;
  1248. procedure AddDevice(str : String);
  1249. begin
  1250. inc(numberofdevices);
  1251. deviceids[numberofdevices] := numberofdevices;
  1252. devicenames[numberofdevices] := str;
  1253. end;
  1254. function MakeDeviceName(str : pchar): string;
  1255. var
  1256. temp : string[20];
  1257. begin
  1258. temp := strpas(str);
  1259. temp := temp + ':';
  1260. MakeDeviceName := temp;
  1261. end;
  1262. function IsInDeviceList(str : string): boolean;
  1263. var
  1264. i : byte;
  1265. theresult : boolean;
  1266. begin
  1267. theresult := false;
  1268. for i := low(not_to_use_devs) to high(not_to_use_devs) do
  1269. begin
  1270. if str = not_to_use_devs[i] then begin
  1271. theresult := true;
  1272. break;
  1273. end;
  1274. end;
  1275. IsInDeviceList := theresult;
  1276. end;
  1277. function BSTR2STRING(s : BSTR): pchar;
  1278. begin
  1279. BSTR2STRING := Pointer(Longint(BADDR(s))+1);
  1280. end;
  1281. procedure ReadInDevices;
  1282. var
  1283. dl : pDosList;
  1284. temp : pchar;
  1285. str : string[20];
  1286. begin
  1287. dl := LockDosList(LDF_DEVICES or LDF_READ );
  1288. repeat
  1289. dl := NextDosEntry(dl,LDF_DEVICES );
  1290. if dl <> nil then begin
  1291. temp := BSTR2STRING(dl^.dol_Name);
  1292. str := MakeDeviceName(temp);
  1293. if not IsInDeviceList(str) then
  1294. AddDevice(str);
  1295. end;
  1296. until dl = nil;
  1297. UnLockDosList(LDF_DEVICES or LDF_READ );
  1298. end;
  1299. Begin
  1300. DosError:=0;
  1301. ver:=TRUE;
  1302. breakflag:=TRUE;
  1303. numberofdevices := 0;
  1304. AddDevice('DF0:');
  1305. AddDevice('DF1:');
  1306. AddDevice('DF2:');
  1307. AddDevice('DF3:');
  1308. ReadInDevices;
  1309. End.
  1310. {
  1311. $Log$
  1312. Revision 1.6 1998-08-13 13:18:45 carl
  1313. * FSearch bugfix
  1314. * FSplit bugfix
  1315. + GetFAttr,SetFAttr and GetFTime accept dos dir separators
  1316. Revision 1.5 1998/08/04 13:37:10 carl
  1317. * bugfix of findfirst, was not convberting correctl backslahes
  1318. }