dos.pp 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1998-2001 by Nils Sjoholm and Carl Eric Codere
  5. members of the Free Pascal development team
  6. Date conversion routine taken from SWAG
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. Unit Dos;
  14. {--------------------------------------------------------------------}
  15. { LEFT TO DO: }
  16. {--------------------------------------------------------------------}
  17. { o DiskFree / Disksize don't work as expected }
  18. { o Implement SetDate and SetTime }
  19. { o Implement EnvCount,EnvStr }
  20. { o FindFirst should only work with correct attributes }
  21. {--------------------------------------------------------------------}
  22. Interface
  23. {$I os.inc}
  24. Const
  25. FileNameLen = 255;
  26. type
  27. SearchRec = Packed Record
  28. { watch out this is correctly aligned for all processors }
  29. { don't modify. }
  30. { Replacement for Fill }
  31. {0} AnchorPtr : Pointer; { Pointer to the Anchorpath structure }
  32. {4} Fill: Array[1..15] of Byte; {future use}
  33. {End of replacement for fill}
  34. Attr : BYTE; {attribute of found file}
  35. Time : LongInt; {last modify date of found file}
  36. Size : LongInt; {file size of found file}
  37. Name : String[255]; {name of found file}
  38. End;
  39. registers = packed record
  40. case i : integer of
  41. 0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
  42. 1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
  43. 2 : (eax, ebx, ecx, edx, ebp, esi, edi : longint);
  44. end;
  45. {$i dosh.inc}
  46. implementation
  47. const
  48. DaysPerMonth : Array[1..12] of ShortInt =
  49. (031,028,031,030,031,030,031,031,030,031,030,031);
  50. DaysPerYear : Array[1..12] of Integer =
  51. (031,059,090,120,151,181,212,243,273,304,334,365);
  52. DaysPerLeapYear : Array[1..12] of Integer =
  53. (031,060,091,121,152,182,213,244,274,305,335,366);
  54. SecsPerYear : LongInt = 31536000;
  55. SecsPerLeapYear : LongInt = 31622400;
  56. SecsPerDay : LongInt = 86400;
  57. SecsPerHour : Integer = 3600;
  58. SecsPerMinute : ShortInt = 60;
  59. TICKSPERSECOND = 50;
  60. Type
  61. pClockData = ^tClockData;
  62. tClockData = packed Record
  63. sec : Word;
  64. min : Word;
  65. hour : Word;
  66. mday : Word;
  67. month : Word;
  68. year : Word;
  69. wday : Word;
  70. END;
  71. BPTR = Longint;
  72. BSTR = Longint;
  73. pMinNode = ^tMinNode;
  74. tMinNode = Packed Record
  75. mln_Succ,
  76. mln_Pred : pMinNode;
  77. End;
  78. pMinList = ^tMinList;
  79. tMinList = Packed record
  80. mlh_Head : pMinNode;
  81. mlh_Tail : pMinNode;
  82. mlh_TailPred : pMinNode;
  83. end;
  84. { * List Node Structure. Each member in a list starts with a Node * }
  85. pNode = ^tNode;
  86. tNode = Packed Record
  87. ln_Succ, { * Pointer to next (successor) * }
  88. ln_Pred : pNode; { * Pointer to previous (predecessor) * }
  89. ln_Type : Byte;
  90. ln_Pri : Shortint; { * Priority, for sorting * }
  91. ln_Name : PCHAR; { * ID string, null terminated * }
  92. End; { * Note: Integer aligned * }
  93. pList = ^tList;
  94. tList = Packed record
  95. lh_Head : pNode;
  96. lh_Tail : pNode;
  97. lh_TailPred : pNode;
  98. lh_Type : Byte;
  99. l_pad : Byte;
  100. end;
  101. pMsgPort = ^tMsgPort;
  102. tMsgPort = Packed record
  103. mp_Node : tNode;
  104. mp_Flags : Byte;
  105. mp_SigBit : Byte; { signal bit number }
  106. mp_SigTask : Pointer; { task to be signalled (TaskPtr) }
  107. mp_MsgList : tList; { message linked list }
  108. end;
  109. pTask = ^tTask;
  110. tTask = Packed record
  111. tc_Node : tNode;
  112. tc_Flags : Byte;
  113. tc_State : Byte;
  114. tc_IDNestCnt : Shortint; { intr disabled nesting }
  115. tc_TDNestCnt : Shortint; { task disabled nesting }
  116. tc_SigAlloc : longint; { sigs allocated }
  117. tc_SigWait : longint; { sigs we are waiting for }
  118. tc_SigRecvd : longint; { sigs we have received }
  119. tc_SigExcept : longint; { sigs we will take excepts for }
  120. tc_TrapAlloc : Word; { traps allocated }
  121. tc_TrapAble : Word; { traps enabled }
  122. tc_ExceptData : Pointer; { points to except data }
  123. tc_ExceptCode : Pointer; { points to except code }
  124. tc_TrapData : Pointer; { points to trap data }
  125. tc_TrapCode : Pointer; { points to trap code }
  126. tc_SPReg : Pointer; { stack pointer }
  127. tc_SPLower : Pointer; { stack lower bound }
  128. tc_SPUpper : Pointer; { stack upper bound + 2 }
  129. tc_Switch : Pointer; { task losing CPU }
  130. tc_Launch : Pointer; { task getting CPU }
  131. tc_MemEntry : tList; { allocated memory }
  132. tc_UserData : Pointer; { per task data }
  133. end;
  134. TDateStamp = packed record
  135. ds_Days : Longint; { Number of days since Jan. 1, 1978 }
  136. ds_Minute : Longint; { Number of minutes past midnight }
  137. ds_Tick : Longint; { Number of ticks past minute }
  138. end;
  139. PDateStamp = ^TDateStamp;
  140. { Returned by Examine() and ExInfo(), must be on a 4 byte boundary }
  141. PFileInfoBlock = ^TfileInfoBlock;
  142. TFileInfoBlock = packed record
  143. fib_DiskKey : Longint;
  144. fib_DirEntryType : Longint;
  145. { Type of Directory. If < 0, then a plain file.
  146. If > 0 a directory }
  147. fib_FileName : Array [0..107] of Char;
  148. { Null terminated. Max 30 chars used for now }
  149. fib_Protection : Longint;
  150. { bit mask of protection, rwxd are 3-0. }
  151. fib_EntryType : Longint;
  152. fib_Size : Longint; { Number of bytes in file }
  153. fib_NumBlocks : Longint; { Number of blocks in file }
  154. fib_Date : TDateStamp; { Date file last changed }
  155. fib_Comment : Array [0..79] of Char;
  156. { Null terminated comment associated with file }
  157. fib_Reserved : Array [0..35] of Char;
  158. end;
  159. { returned by Info(), must be on a 4 byte boundary }
  160. pInfoData = ^tInfoData;
  161. tInfoData = packed record
  162. id_NumSoftErrors : Longint; { number of soft errors on disk }
  163. id_UnitNumber : Longint; { Which unit disk is (was) mounted on }
  164. id_DiskState : Longint; { See defines below }
  165. id_NumBlocks : Longint; { Number of blocks on disk }
  166. id_NumBlocksUsed : Longint; { Number of block in use }
  167. id_BytesPerBlock : Longint;
  168. id_DiskType : Longint; { Disk Type code }
  169. id_VolumeNode : BPTR; { BCPL pointer to volume node }
  170. id_InUse : Longint; { Flag, zero if not in use }
  171. end;
  172. { ------ Library Base Structure ---------------------------------- }
  173. { Also used for Devices and some Resources }
  174. pLibrary = ^tLibrary;
  175. tLibrary = packed record
  176. lib_Node : tNode;
  177. lib_Flags,
  178. lib_pad : Byte;
  179. lib_NegSize, { number of bytes before library }
  180. lib_PosSize, { number of bytes after library }
  181. lib_Version, { major }
  182. lib_Revision : Word; { minor }
  183. lib_IdString : PCHAR; { ASCII identification }
  184. lib_Sum : LONGINT; { the checksum itself }
  185. lib_OpenCnt : Word; { number of current opens }
  186. end; { * Warning: size is not a longword multiple ! * }
  187. PChain = ^TChain;
  188. TChain = packed record
  189. an_Child : PChain;
  190. an_Parent: PChain;
  191. an_Lock : BPTR;
  192. an_info : TFileInfoBlock;
  193. an_Flags : shortint;
  194. an_string: Array[0..0] of char;
  195. end;
  196. PAnchorPath = ^TAnchorPath;
  197. TAnchorPath = packed record
  198. ap_Base : PChain; {* pointer to first anchor *}
  199. ap_First : PChain; {* pointer to last anchor *}
  200. ap_BreakBits : LONGINT; {* Bits we want to break on *}
  201. ap_FondBreak : LONGINT; {* Bits we broke on. Also returns ERROR_BREAK *}
  202. ap_Flags : shortint; {* New use for extra word. *}
  203. ap_reserved : BYTE;
  204. ap_StrLen : WORD;
  205. ap_Info : TFileInfoBlock;
  206. ap_Buf : Array[0..0] of Char; {* Buffer for path name, allocated by user *}
  207. END;
  208. pCommandLineInterface = ^TCommandLineInterface;
  209. TCommandLineInterface = packed record
  210. cli_result2 : longint; {* Value of IoErr from last command *}
  211. cli_SetName : BSTR; {* Name of current directory *}
  212. cli_CommandDir : BPTR; {* Head of the path locklist *}
  213. cli_ReturnCode : longint; {* Return code from last command *}
  214. cli_CommandName : BSTR; {* Name of current command *}
  215. cli_FailLevel : longint; {* Fail level (set by FAILAT) *}
  216. cli_Prompt : BSTR; {* Current prompt (set by PROMPT) *}
  217. cli_StandardInput: BPTR; {* Default (terminal) CLI input *}
  218. cli_CurrentInput : BPTR; {* Current CLI input *}
  219. cli_CommandFile : BSTR; {* Name of EXECUTE command file *}
  220. cli_Interactive : longint; {* Boolean; True if prompts required *}
  221. cli_Background : longint; {* Boolean; True if CLI created by RUN*}
  222. cli_CurrentOutput: BPTR; {* Current CLI output *}
  223. cli_DefautlStack : longint; {* Stack size to be obtained in long words *}
  224. cli_StandardOutput : BPTR; {* Default (terminal) CLI output *}
  225. cli_Module : BPTR; {* SegList of currently loaded command*}
  226. END;
  227. pDosList = ^tDosList;
  228. tDosList = packed record
  229. dol_Next : BPTR; { bptr to next device on list }
  230. dol_Type : Longint; { see DLT below }
  231. dol_Task : Pointer; { ptr to handler task }
  232. dol_Lock : BPTR;
  233. dol_Misc : Array[0..23] of Shortint;
  234. dol_Name : BSTR; { bptr to bcpl name }
  235. END;
  236. TProcess = packed record
  237. pr_Task : TTask;
  238. pr_MsgPort : TMsgPort; { This is BPTR address from DOS functions }
  239. {126} pr_Pad : Word; { Remaining variables on 4 byte boundaries }
  240. {128} pr_SegList : Pointer; { Array of seg lists used by this process }
  241. {132} pr_StackSize : Longint; { Size of process stack in bytes }
  242. {136} pr_GlobVec : Pointer; { Global vector for this process (BCPL) }
  243. {140} pr_TaskNum : Longint; { CLI task number of zero if not a CLI }
  244. {144} pr_StackBase : BPTR; { Ptr to high memory end of process stack }
  245. {148} pr_Result2 : Longint; { Value of secondary result from last call }
  246. {152} pr_CurrentDir : BPTR; { Lock associated with current directory }
  247. {156} pr_CIS : BPTR; { Current CLI Input Stream }
  248. {160} pr_COS : BPTR; { Current CLI Output Stream }
  249. {164} pr_ConsoleTask : Pointer; { Console handler process for current window}
  250. {168} pr_FileSystemTask : Pointer; { File handler process for current drive }
  251. {172} pr_CLI : BPTR; { pointer to ConsoleLineInterpreter }
  252. pr_ReturnAddr : Pointer; { pointer to previous stack frame }
  253. pr_PktWait : Pointer; { Function to be called when awaiting msg }
  254. pr_WindowPtr : Pointer; { Window for error printing }
  255. { following definitions are new with 2.0 }
  256. pr_HomeDir : BPTR; { Home directory of executing program }
  257. pr_Flags : Longint; { flags telling dos about process }
  258. pr_ExitCode : Pointer; { code to call on exit of program OR NULL }
  259. pr_ExitData : Longint; { Passed as an argument to pr_ExitCode. }
  260. pr_Arguments : PChar; { Arguments passed to the process at start }
  261. pr_LocalVars : TMinList; { Local environment variables }
  262. pr_ShellPrivate : Longint; { for the use of the current shell }
  263. pr_CES : BPTR; { Error stream - IF NULL, use pr_COS }
  264. end;
  265. PProcess = ^TProcess;
  266. CONST
  267. { DOS Lib Offsets }
  268. _LVOMatchFirst = -822;
  269. _LVOMatchNext = -828;
  270. _LVOMatchEnd = -834;
  271. _LVOCli = -492;
  272. _LVOExecute = -222;
  273. _LVOSystemTagList = -606;
  274. _LVOSetFileDate = -396;
  275. LDF_READ = 1;
  276. LDF_DEVICES = 4;
  277. ERROR_NO_MORE_ENTRIES = 232;
  278. FIBF_SCRIPT = 64; { program is a script }
  279. FIBF_PURE = 32; { program is reentrant }
  280. FIBF_ARCHIVE = 16; { cleared whenever file is changed }
  281. FIBF_READ = 8; { ignoed by old filesystem }
  282. FIBF_WRITE = 4; { ignored by old filesystem }
  283. FIBF_EXECUTE = 2; { ignored by system, used by shell }
  284. FIBF_DELETE = 1; { prevent file from being deleted }
  285. SHARED_LOCK = -2;
  286. {******************************************************************************
  287. --- Internal routines ---
  288. ******************************************************************************}
  289. procedure CurrentTime(var Seconds, Micros : Longint);
  290. Begin
  291. asm
  292. MOVE.L A6,-(A7)
  293. MOVE.L Seconds,a0
  294. MOVE.L Micros,a1
  295. MOVE.L _IntuitionBase,A6
  296. JSR -084(A6)
  297. MOVE.L (A7)+,A6
  298. end;
  299. end;
  300. function Date2Amiga(date : pClockData) : Longint;
  301. Begin
  302. asm
  303. MOVE.L A6,-(A7)
  304. MOVE.L date,a0
  305. MOVE.L _UtilityBase,A6
  306. JSR -126(A6)
  307. MOVE.L (A7)+,A6
  308. MOVE.L d0,@RESULT
  309. end;
  310. end;
  311. procedure Amiga2Date(amigatime : Longint;
  312. resultat : pClockData);
  313. Begin
  314. asm
  315. MOVE.L A6,-(A7)
  316. MOVE.L amigatime,d0
  317. MOVE.L resultat,a0
  318. MOVE.L _UtilityBase,A6
  319. JSR -120(A6)
  320. MOVE.L (A7)+,A6
  321. end;
  322. end;
  323. FUNCTION Examine(lock : BPTR; fileInfoBlock : pFileInfoBlock) : BOOLEAN;
  324. BEGIN
  325. ASM
  326. MOVE.L A6,-(A7)
  327. MOVE.L lock,D1
  328. MOVE.L fileInfoBlock,D2
  329. MOVEA.L _DOSBase,A6
  330. JSR -102(A6)
  331. MOVEA.L (A7)+,A6
  332. TST.L D0
  333. BEQ.B @end
  334. MOVE.B #1,D0
  335. @end: MOVE.B D0,@RESULT
  336. END;
  337. END;
  338. function Lock(const name : string;
  339. accessmode : Longint) : BPTR;
  340. var
  341. buffer: Array[0..255] of char;
  342. Begin
  343. move(name[1],buffer,length(name));
  344. buffer[length(name)]:=#0;
  345. asm
  346. MOVEM.L d2/a6,-(A7)
  347. LEA buffer,a0
  348. MOVE.L a0,d1
  349. MOVE.L accessmode,d2
  350. MOVE.L _DOSBase,A6
  351. JSR -084(A6)
  352. MOVEM.L (A7)+,d2/a6
  353. MOVE.L d0,@RESULT
  354. end;
  355. end;
  356. procedure UnLock(lock : BPTR);
  357. Begin
  358. asm
  359. MOVE.L A6,-(A7)
  360. MOVE.L lock,d1
  361. MOVE.L _DOSBase,A6
  362. JSR -090(A6)
  363. MOVE.L (A7)+,A6
  364. end;
  365. end;
  366. FUNCTION Info(lock : BPTR; parameterBlock : pInfoData) : BOOLEAN;
  367. BEGIN
  368. ASM
  369. MOVE.L A6,-(A7)
  370. MOVE.L lock,D1
  371. MOVE.L parameterBlock,D2
  372. MOVEA.L _DOSBase,A6
  373. JSR -114(A6)
  374. MOVEA.L (A7)+,A6
  375. TST.L D0
  376. BEQ.B @end
  377. MOVE.B #1,D0
  378. @end:
  379. MOVE.B D0,@RESULT
  380. END;
  381. END;
  382. FUNCTION NameFromLock(lock : BPTR; buffer : pCHAR; len : LONGINT) : BOOLEAN;
  383. BEGIN
  384. ASM
  385. MOVE.L A6,-(A7)
  386. MOVE.L lock,D1
  387. MOVE.L buffer,D2
  388. MOVE.L len,D3
  389. MOVEA.L _DOSBase,A6
  390. JSR -402(A6)
  391. MOVEA.L (A7)+,A6
  392. TST.L D0
  393. BEQ.B @end
  394. MOVE.B #1,D0
  395. @end: MOVE.B D0,@RESULT
  396. END;
  397. END;
  398. FUNCTION GetVar(name : pCHAR; buffer : pCHAR; size : LONGINT; flags : LONGINT) : LONGINT;
  399. BEGIN
  400. ASM
  401. MOVE.L A6,-(A7)
  402. MOVE.L name,D1
  403. MOVE.L buffer,D2
  404. MOVE.L size,D3
  405. MOVE.L flags,D4
  406. MOVEA.L _DOSBase,A6
  407. JSR -906(A6)
  408. MOVEA.L (A7)+,A6
  409. MOVE.L D0,@RESULT
  410. END;
  411. END;
  412. FUNCTION FindTask(name : pCHAR) : pTask;
  413. BEGIN
  414. ASM
  415. MOVE.L A6,-(A7)
  416. MOVEA.L name,A1
  417. MOVEA.L _ExecBase,A6
  418. JSR -294(A6)
  419. MOVEA.L (A7)+,A6
  420. MOVE.L D0,@RESULT
  421. END;
  422. END;
  423. FUNCTION MatchFirst(pat : pCHAR; anchor : pAnchorPath) : LONGINT;
  424. BEGIN
  425. ASM
  426. MOVE.L A6,-(A7)
  427. MOVE.L pat,D1
  428. MOVE.L anchor,D2
  429. MOVEA.L _DOSBase,A6
  430. JSR -822(A6)
  431. MOVEA.L (A7)+,A6
  432. MOVE.L D0,@RESULT
  433. END;
  434. END;
  435. FUNCTION MatchNext(anchor : pAnchorPath) : LONGINT;
  436. BEGIN
  437. ASM
  438. MOVE.L A6,-(A7)
  439. MOVE.L anchor,D1
  440. MOVEA.L _DOSBase,A6
  441. JSR -828(A6)
  442. MOVEA.L (A7)+,A6
  443. MOVE.L D0,@RESULT
  444. END;
  445. END;
  446. PROCEDURE MatchEnd(anchor : pAnchorPath);
  447. BEGIN
  448. ASM
  449. MOVE.L A6,-(A7)
  450. MOVE.L anchor,D1
  451. MOVEA.L _DOSBase,A6
  452. JSR -834(A6)
  453. MOVEA.L (A7)+,A6
  454. END;
  455. END;
  456. FUNCTION Cli : pCommandLineInterface;
  457. BEGIN
  458. ASM
  459. MOVE.L A6,-(A7)
  460. MOVEA.L _DOSBase,A6
  461. JSR -492(A6)
  462. MOVEA.L (A7)+,A6
  463. MOVE.L D0,@RESULT
  464. END;
  465. END;
  466. Function _Execute(p: pchar): longint;
  467. Begin
  468. asm
  469. move.l a6,d6 { save base pointer }
  470. move.l d2,-(sp)
  471. move.l p,d1 { command to execute }
  472. clr.l d2 { No TagList for command }
  473. move.l _DosBase,a6
  474. jsr _LVOSystemTagList(a6)
  475. move.l (sp)+,d2
  476. move.l d6,a6 { restore base pointer }
  477. move.l d0,@RESULT
  478. end;
  479. end;
  480. FUNCTION LockDosList(flags : longint) : pDosList;
  481. BEGIN
  482. ASM
  483. MOVE.L A6,-(A7)
  484. MOVE.L flags,D1
  485. MOVEA.L _DOSBase,A6
  486. JSR -654(A6)
  487. MOVEA.L (A7)+,A6
  488. MOVE.L D0,@RESULT
  489. END;
  490. END;
  491. PROCEDURE UnLockDosList(flags : longint);
  492. BEGIN
  493. ASM
  494. MOVE.L A6,-(A7)
  495. MOVE.L flags,D1
  496. MOVEA.L _DOSBase,A6
  497. JSR -660(A6)
  498. MOVEA.L (A7)+,A6
  499. END;
  500. END;
  501. FUNCTION NextDosEntry(dlist : pDosList; flags : longint) : pDosList;
  502. BEGIN
  503. ASM
  504. MOVE.L A6,-(A7)
  505. MOVE.L dlist,D1
  506. MOVE.L flags,D2
  507. MOVEA.L _DOSBase,A6
  508. JSR -690(A6)
  509. MOVEA.L (A7)+,A6
  510. MOVE.L D0,@RESULT
  511. END;
  512. END;
  513. FUNCTION BADDR(bval : BPTR): POINTER;
  514. BEGIN
  515. BADDR := POINTER( bval shl 2);
  516. END;
  517. function PasToC(var s: string): Pchar;
  518. var i: integer;
  519. begin
  520. i := Length(s) + 1;
  521. if i > 255 then
  522. begin
  523. Delete(s, 255, 1); { ensure there is a spare byte }
  524. Dec(i)
  525. end;
  526. s[i] := #0;
  527. PasToC := @s[1]
  528. end;
  529. Procedure AmigaToDt(SecsPast: LongInt; Var Dt: DateTime);
  530. var
  531. cd : pClockData;
  532. Begin
  533. New(cd);
  534. Amiga2Date(SecsPast,cd);
  535. Dt.sec := cd^.sec;
  536. Dt.min := cd^.min;
  537. Dt.hour := cd^.hour;
  538. Dt.day := cd^.mday;
  539. Dt.month := cd^.month;
  540. Dt.year := cd^.year;
  541. Dispose(cd);
  542. End;
  543. Function DtToAmiga(DT: DateTime): LongInt;
  544. var
  545. cd : pClockData;
  546. temp : Longint;
  547. Begin
  548. New(cd);
  549. cd^.sec := Dt.sec;
  550. cd^.min := Dt.min;
  551. cd^.hour := Dt.hour;
  552. cd^.mday := Dt.day;
  553. cd^.month := Dt.month;
  554. cd^.year := Dt.year;
  555. temp := Date2Amiga(cd);
  556. Dispose(cd);
  557. DtToAmiga := temp;
  558. end;
  559. Function SetProtection(const name: string; mask:longint): longint;
  560. var
  561. buffer : array[0..255] of char;
  562. Begin
  563. move(name[1],buffer,length(name));
  564. buffer[length(name)]:=#0;
  565. asm
  566. move.l a6,d6
  567. lea buffer,a0
  568. move.l a0,d1
  569. move.l mask,d2
  570. move.l _DosBase,a6
  571. jsr -186(a6)
  572. move.l d6,a6
  573. move.l d0,@RESULT
  574. end;
  575. end;
  576. Function IsLeapYear(Source : Word) : Boolean;
  577. Begin
  578. If (Source Mod 4 = 0) Then
  579. IsLeapYear := True
  580. Else
  581. IsLeapYear := False;
  582. End;
  583. Procedure Amiga2DateStamp(Date : LongInt; Var TotalDays,Minutes,Ticks: longint);
  584. { Converts a value in seconds past 1978 to a value in AMIGA DateStamp format }
  585. { Taken from SWAG and modified to work with the Amiga format - CEC }
  586. Var
  587. LocalDate : LongInt; Done : Boolean; X : ShortInt; TotDays : Integer;
  588. Y: Word;
  589. M: Word;
  590. D: Word;
  591. H: Word;
  592. Min: Word;
  593. S : Word;
  594. Begin
  595. Y := 1978; M := 1; D := 1; H := 0; Min := 0; S := 0;
  596. TotalDays := 0;
  597. Minutes := 0;
  598. Ticks := 0;
  599. LocalDate := Date;
  600. Done := False;
  601. While Not Done Do
  602. Begin
  603. If LocalDate >= SecsPerYear Then
  604. Begin
  605. Inc(Y,1);
  606. Dec(LocalDate,SecsPerYear);
  607. Inc(TotalDays,DaysPerYear[12]);
  608. End
  609. Else
  610. Done := True;
  611. If (IsLeapYear(Y+1)) And (LocalDate >= SecsPerLeapYear) And
  612. (Not Done) Then
  613. Begin
  614. Inc(Y,1);
  615. Dec(LocalDate,SecsPerLeapYear);
  616. Inc(TotalDays,DaysPerLeapYear[12]);
  617. End;
  618. End; { END WHILE }
  619. M := 1; D := 1;
  620. Done := False;
  621. TotDays := LocalDate Div SecsPerDay;
  622. { Total number of days }
  623. TotalDays := TotalDays + TotDays;
  624. Dec(LocalDate,TotDays*SecsPerDay);
  625. { Absolute hours since start of day }
  626. H := LocalDate Div SecsPerHour;
  627. { Convert to minutes }
  628. Minutes := H*60;
  629. Dec(LocalDate,(H * SecsPerHour));
  630. { Find the remaining minutes to add }
  631. Min := LocalDate Div SecsPerMinute;
  632. Dec(LocalDate,(Min * SecsPerMinute));
  633. Minutes:=Minutes+Min;
  634. { Find the number of seconds and convert to ticks }
  635. S := LocalDate;
  636. Ticks:=TICKSPERSECOND*S;
  637. End;
  638. Function SetFileDate(name: string; p : pDateStamp): longint;
  639. var
  640. buffer : array[0..255] of char;
  641. Begin
  642. move(name[1],buffer,length(name));
  643. buffer[length(name)]:=#0;
  644. asm
  645. move.l a6,d6 { save base pointer }
  646. move.l d2,-(sp) { save reserved reg }
  647. lea buffer,a0
  648. move.l a0,d1
  649. move.l p,d2
  650. move.l _DosBase,a6
  651. jsr _LVOSetFileDate(a6)
  652. move.l (sp)+,d2 { restore reserved reg }
  653. move.l d6,a6 { restore base pointer }
  654. move.l d0,@Result
  655. end;
  656. end;
  657. {******************************************************************************
  658. --- Dos Interrupt ---
  659. ******************************************************************************}
  660. Procedure Intr (intno: byte; var regs: registers);
  661. Begin
  662. { Does not apply to Linux - not implemented }
  663. End;
  664. Procedure SwapVectors;
  665. Begin
  666. { Does not apply to Linux - Do Nothing }
  667. End;
  668. Procedure msdos(var regs : registers);
  669. Begin
  670. { ! Not implemented in Linux ! }
  671. End;
  672. Procedure getintvec(intno : byte;var vector : pointer);
  673. Begin
  674. { ! Not implemented in Linux ! }
  675. End;
  676. Procedure setintvec(intno : byte;vector : pointer);
  677. Begin
  678. { ! Not implemented in Linux ! }
  679. End;
  680. {******************************************************************************
  681. --- Info / Date / Time ---
  682. ******************************************************************************}
  683. Function DosVersion: Word;
  684. var p: pLibrary;
  685. Begin
  686. p:=pLibrary(_DosBase);
  687. DosVersion:= p^.lib_Version or (p^.lib_Revision shl 8);
  688. End;
  689. Procedure GetDate(Var Year, Month, MDay, WDay: Word);
  690. Var
  691. cd : pClockData;
  692. mysec,
  693. tick : Longint;
  694. begin
  695. New(cd);
  696. CurrentTime(mysec,tick);
  697. Amiga2Date(mysec,cd);
  698. Year := cd^.year;
  699. Month := cd^.month;
  700. MDay := cd^.mday;
  701. WDay := cd^.wday;
  702. Dispose(cd);
  703. end;
  704. Procedure SetDate(Year, Month, Day: Word);
  705. Begin
  706. { !! }
  707. End;
  708. Procedure GetTime(Var Hour, Minute, Second, Sec100: Word);
  709. Var
  710. mysec,
  711. tick : Longint;
  712. cd : pClockData;
  713. begin
  714. New(cd);
  715. CurrentTime(mysec,tick);
  716. Amiga2Date(mysec,cd);
  717. Hour := cd^.hour;
  718. Minute := cd^.min;
  719. Second := cd^.sec;
  720. Sec100 := 0;
  721. Dispose(cd);
  722. END;
  723. Procedure SetTime(Hour, Minute, Second, Sec100: Word);
  724. Begin
  725. { !! }
  726. End;
  727. Procedure unpacktime(p : longint;var t : datetime);
  728. Begin
  729. AmigaToDt(p,t);
  730. End;
  731. Procedure packtime(var t : datetime;var p : longint);
  732. Begin
  733. p := DtToAmiga(t);
  734. end;
  735. {******************************************************************************
  736. --- Exec ---
  737. ******************************************************************************}
  738. {$ifdef HASTHREADVAR}
  739. threadvar
  740. {$else HASTHREADVAR}
  741. var
  742. {$endif HASTHREADVAR}
  743. LastDosExitCode: word;
  744. Procedure Exec (Const Path: PathStr; Const ComLine: ComStr);
  745. var
  746. p : string;
  747. buf: array[0..255] of char;
  748. result : longint;
  749. MyLock : longint;
  750. i : Integer;
  751. Begin
  752. DosError := 0;
  753. LastdosExitCode := 0;
  754. p:=Path+' '+ComLine;
  755. { allow backslash as slash }
  756. for i:=1 to length(p) do
  757. if p[i]='\' then p[i]:='/';
  758. Move(p[1],buf,length(p));
  759. buf[Length(p)]:=#0;
  760. { Here we must first check if the command we wish to execute }
  761. { actually exists, because this is NOT handled by the }
  762. { _SystemTagList call (program will abort!!) }
  763. { Try to open with shared lock }
  764. MyLock:=Lock(path,SHARED_LOCK);
  765. if MyLock <> 0 then
  766. Begin
  767. { File exists - therefore unlock it }
  768. Unlock(MyLock);
  769. result:=_Execute(buf);
  770. { on return of -1 the shell could not be executed }
  771. { probably because there was not enough memory }
  772. if result = -1 then
  773. DosError:=8
  774. else
  775. LastDosExitCode:=word(result);
  776. end
  777. else
  778. DosError:=3;
  779. End;
  780. Function DosExitCode: Word;
  781. Begin
  782. DosExitCode:=LastdosExitCode;
  783. End;
  784. Procedure GetCBreak(Var BreakValue: Boolean);
  785. Begin
  786. breakvalue := system.BreakOn;
  787. End;
  788. Procedure SetCBreak(BreakValue: Boolean);
  789. Begin
  790. system.Breakon := BreakValue;
  791. End;
  792. Procedure GetVerify(Var Verify: Boolean);
  793. Begin
  794. verify:=true;
  795. End;
  796. Procedure SetVerify(Verify: Boolean);
  797. Begin
  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. s : string;
  886. j : integer;
  887. Begin
  888. DosError:=0;
  889. New(Anchor);
  890. {----- allow backslash as slash -----}
  891. for index:=1 to length(path) do
  892. if path[index]='\' then path[index]:='/';
  893. { remove any dot characters and replace by their current }
  894. { directory equivalent. }
  895. if pos('../',path) = 1 then
  896. { look for parent directory }
  897. Begin
  898. delete(path,1,3);
  899. getdir(0,s);
  900. j:=length(s);
  901. while (s[j] <> '/') AND (s[j] <> ':') AND (j > 0 ) do
  902. dec(j);
  903. if j > 0 then
  904. s:=copy(s,1,j);
  905. path:=s+path;
  906. end
  907. else
  908. if pos('./',path) = 1 then
  909. { look for current directory }
  910. Begin
  911. delete(path,1,2);
  912. getdir(0,s);
  913. if (s[length(s)] <> '/') and (s[length(s)] <> ':') then
  914. s:=s+'/';
  915. path:=s+path;
  916. end;
  917. {----- replace * by #? AmigaOs strings -----}
  918. repeat
  919. index:= pos('*',Path);
  920. if index <> 0 then
  921. Begin
  922. delete(Path,index,1);
  923. insert('#?',Path,index);
  924. end;
  925. until index =0;
  926. {--------------------------------------------}
  927. FillChar(Anchor^,sizeof(TAnchorPath),#0);
  928. move(path[1],buf,length(path));
  929. buf[length(path)]:=#0;
  930. Result:=MatchFirst(@buf,Anchor);
  931. f.AnchorPtr:=Anchor;
  932. if Result = ERROR_NO_MORE_ENTRIES then
  933. DosError:=18
  934. else
  935. if Result <> 0 then
  936. DosError:=3;
  937. { If there is an error, deallocate }
  938. { the anchorpath structure }
  939. if DosError <> 0 then
  940. Begin
  941. MatchEnd(Anchor);
  942. if assigned(Anchor) then
  943. Dispose(Anchor);
  944. end
  945. else
  946. {-------------------------------------------------------------------}
  947. { Here we fill up the SearchRec attribute, but we also do check }
  948. { something else, if the it does not match the mask we are looking }
  949. { for we should go to the next file or directory. }
  950. {-------------------------------------------------------------------}
  951. Begin
  952. with Anchor^.ap_Info do
  953. Begin
  954. f.Time := fib_Date.ds_Days * (24 * 60 * 60) +
  955. fib_Date.ds_Minute * 60 +
  956. fib_Date.ds_Tick div 50;
  957. {*------------------------------------*}
  958. {* Determine if is a file or a folder *}
  959. {*------------------------------------*}
  960. if fib_DirEntryType > 0 then
  961. f.attr:=f.attr OR DIRECTORY;
  962. {*------------------------------------*}
  963. {* Determine if Read only *}
  964. {* Readonly if R flag on and W flag *}
  965. {* off. *}
  966. {* Should we check also that EXEC *}
  967. {* is zero? for read only? *}
  968. {*------------------------------------*}
  969. if ((fib_Protection and FIBF_READ) <> 0)
  970. AND ((fib_Protection and FIBF_WRITE) = 0)
  971. then
  972. f.attr:=f.attr or READONLY;
  973. f.Name := strpas(fib_FileName);
  974. f.Size := fib_Size;
  975. end; { end with }
  976. end;
  977. End;
  978. Procedure FindNext(Var f: SearchRec);
  979. var
  980. Result: longint;
  981. Anchor : pAnchorPath;
  982. Begin
  983. DosError:=0;
  984. Result:=MatchNext(f.AnchorPtr);
  985. if Result = ERROR_NO_MORE_ENTRIES then
  986. DosError:=18
  987. else
  988. if Result <> 0 then
  989. DosError:=3;
  990. { If there is an error, deallocate }
  991. { the anchorpath structure }
  992. if DosError <> 0 then
  993. Begin
  994. MatchEnd(f.AnchorPtr);
  995. if assigned(f.AnchorPtr) then
  996. {Dispose}FreeMem(f.AnchorPtr);
  997. end
  998. else
  999. { Fill up the Searchrec information }
  1000. { and also check if the files are with }
  1001. { the correct attributes }
  1002. Begin
  1003. Anchor:=pAnchorPath(f.AnchorPtr);
  1004. with Anchor^.ap_Info do
  1005. Begin
  1006. f.Time := fib_Date.ds_Days * (24 * 60 * 60) +
  1007. fib_Date.ds_Minute * 60 +
  1008. fib_Date.ds_Tick div 50;
  1009. {*------------------------------------*}
  1010. {* Determine if is a file or a folder *}
  1011. {*------------------------------------*}
  1012. if fib_DirEntryType > 0 then
  1013. f.attr:=f.attr OR DIRECTORY;
  1014. {*------------------------------------*}
  1015. {* Determine if Read only *}
  1016. {* Readonly if R flag on and W flag *}
  1017. {* off. *}
  1018. {* Should we check also that EXEC *}
  1019. {* is zero? for read only? *}
  1020. {*------------------------------------*}
  1021. if ((fib_Protection and FIBF_READ) <> 0)
  1022. AND ((fib_Protection and FIBF_WRITE) = 0)
  1023. then
  1024. f.attr:=f.attr or READONLY;
  1025. f.Name := strpas(fib_FileName);
  1026. f.Size := fib_Size;
  1027. end; { end with }
  1028. end;
  1029. End;
  1030. Procedure FindClose(Var f: SearchRec);
  1031. begin
  1032. end;
  1033. {******************************************************************************
  1034. --- File ---
  1035. ******************************************************************************}
  1036. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  1037. var
  1038. I: Word;
  1039. begin
  1040. { allow backslash as slash }
  1041. for i:=1 to length(path) do
  1042. if path[i]='\' then path[i]:='/';
  1043. I := Length(Path);
  1044. while (I > 0) and not ((Path[I] = '/') or (Path[I] = ':'))
  1045. do Dec(I);
  1046. if Path[I] = '/' then
  1047. dir := Copy(Path, 0, I)
  1048. else dir := Copy(Path,0,I);
  1049. if Length(Path) > Length(dir) then
  1050. name := Copy(Path, I + 1, Length(Path)-I)
  1051. else
  1052. name := '';
  1053. { Remove extension }
  1054. if pos('.',name) <> 0 then
  1055. delete(name,pos('.',name),length(name));
  1056. I := Pos('.',Path);
  1057. if I > 0 then
  1058. ext := Copy(Path,I,Length(Path)-(I-1))
  1059. else ext := '';
  1060. end;
  1061. Function FExpand(Path: PathStr): PathStr;
  1062. var
  1063. FLock : BPTR;
  1064. buffer : array[0..255] of char;
  1065. i :integer;
  1066. j :integer;
  1067. temp : string;
  1068. begin
  1069. { allow backslash as slash }
  1070. for i:=1 to length(path) do
  1071. if path[i]='\' then path[i]:='/';
  1072. temp:=path;
  1073. if pos('../',temp) = 1 then
  1074. delete(temp,1,3);
  1075. if pos('./',temp) = 1 then
  1076. delete(temp,1,2);
  1077. {First remove all references to '/./'}
  1078. while pos('/./',temp)<>0 do
  1079. delete(temp,pos('/./',temp),3);
  1080. {Now remove also all references to '/../' + of course previous dirs..}
  1081. repeat
  1082. i:=pos('/../',temp);
  1083. {Find the pos of the previous dir}
  1084. if i>1 then
  1085. begin
  1086. j:=i-1;
  1087. while (j>1) and (temp[j]<>'/') do
  1088. dec (j);{temp[1] is always '/'}
  1089. delete(temp,j,i-j+4);
  1090. end
  1091. else
  1092. if i=1 then {i=1, so we have temp='/../something', just delete '/../'}
  1093. delete(temp,1,4);
  1094. until i=0;
  1095. FLock := Lock(temp,-2);
  1096. if FLock <> 0 then begin
  1097. if NameFromLock(FLock,buffer,255) then begin
  1098. Unlock(FLock);
  1099. FExpand := strpas(buffer);
  1100. end else begin
  1101. Unlock(FLock);
  1102. FExpand := '';
  1103. end;
  1104. end else FExpand := '';
  1105. end;
  1106. Function fsearch(path : pathstr;dirlist : string) : pathstr;
  1107. var
  1108. i,p1 : longint;
  1109. s : searchrec;
  1110. newdir : pathstr;
  1111. begin
  1112. { No wildcards allowed in these things }
  1113. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  1114. fsearch:=''
  1115. else
  1116. begin
  1117. { allow slash as backslash }
  1118. for i:=1 to length(dirlist) do
  1119. if dirlist[i]='\' then dirlist[i]:='/';
  1120. repeat
  1121. p1:=pos(';',dirlist);
  1122. if p1<>0 then
  1123. begin
  1124. newdir:=copy(dirlist,1,p1-1);
  1125. delete(dirlist,1,p1);
  1126. end
  1127. else
  1128. begin
  1129. newdir:=dirlist;
  1130. dirlist:='';
  1131. end;
  1132. if (newdir<>'') and (not (newdir[length(newdir)] in ['/',':'])) then
  1133. newdir:=newdir+'/';
  1134. findfirst(newdir+path,anyfile,s);
  1135. if doserror=0 then
  1136. newdir:=newdir+path
  1137. else
  1138. newdir:='';
  1139. until (dirlist='') or (newdir<>'');
  1140. fsearch:=newdir;
  1141. end;
  1142. end;
  1143. Procedure getftime (var f; var time : longint);
  1144. {
  1145. This function returns a file's date and time as the number of
  1146. seconds after January 1, 1978 that the file was created.
  1147. }
  1148. var
  1149. FInfo : pFileInfoBlock;
  1150. FTime : Longint;
  1151. FLock : Longint;
  1152. Str : String;
  1153. i : integer;
  1154. begin
  1155. DosError:=0;
  1156. FTime := 0;
  1157. Str := StrPas(filerec(f).name);
  1158. for i:=1 to length(Str) do
  1159. if str[i]='\' then str[i]:='/';
  1160. FLock := Lock(Str, SHARED_LOCK);
  1161. IF FLock <> 0 then begin
  1162. New(FInfo);
  1163. if Examine(FLock, FInfo) then begin
  1164. with FInfo^.fib_Date do
  1165. FTime := ds_Days * (24 * 60 * 60) +
  1166. ds_Minute * 60 +
  1167. ds_Tick div 50;
  1168. end else begin
  1169. FTime := 0;
  1170. end;
  1171. Unlock(FLock);
  1172. Dispose(FInfo);
  1173. end
  1174. else
  1175. DosError:=6;
  1176. time := FTime;
  1177. end;
  1178. Procedure setftime(var f; time : longint);
  1179. var
  1180. DateStamp: pDateStamp;
  1181. Str: String;
  1182. i: Integer;
  1183. Days, Minutes,Ticks: longint;
  1184. FLock: longint;
  1185. Begin
  1186. new(DateStamp);
  1187. Str := StrPas(filerec(f).name);
  1188. for i:=1 to length(Str) do
  1189. if str[i]='\' then str[i]:='/';
  1190. { Check first of all, if file exists }
  1191. FLock := Lock(Str, SHARED_LOCK);
  1192. IF FLock <> 0 then
  1193. begin
  1194. Unlock(FLock);
  1195. Amiga2DateStamp(time,Days,Minutes,ticks);
  1196. DateStamp^.ds_Days:=Days;
  1197. DateStamp^.ds_Minute:=Minutes;
  1198. DateStamp^.ds_Tick:=Ticks;
  1199. if SetFileDate(Str,DateStamp) <> 0 then
  1200. DosError:=0
  1201. else
  1202. DosError:=6;
  1203. end
  1204. else
  1205. DosError:=2;
  1206. if assigned(DateStamp) then Dispose(DateStamp);
  1207. End;
  1208. Procedure getfattr(var f; var attr : word);
  1209. var
  1210. info : pFileInfoBlock;
  1211. MyLock : Longint;
  1212. flags: word;
  1213. Str: String;
  1214. i: integer;
  1215. Begin
  1216. DosError:=0;
  1217. flags:=0;
  1218. New(info);
  1219. Str := StrPas(filerec(f).name);
  1220. for i:=1 to length(Str) do
  1221. if str[i]='\' then str[i]:='/';
  1222. { open with shared lock to check if file exists }
  1223. MyLock:=Lock(Str,SHARED_LOCK);
  1224. if MyLock <> 0 then
  1225. Begin
  1226. Examine(MyLock,info);
  1227. {*------------------------------------*}
  1228. {* Determine if is a file or a folder *}
  1229. {*------------------------------------*}
  1230. if info^.fib_DirEntryType > 0 then
  1231. flags:=flags OR DIRECTORY;
  1232. {*------------------------------------*}
  1233. {* Determine if Read only *}
  1234. {* Readonly if R flag on and W flag *}
  1235. {* off. *}
  1236. {* Should we check also that EXEC *}
  1237. {* is zero? for read only? *}
  1238. {*------------------------------------*}
  1239. if ((info^.fib_Protection and FIBF_READ) <> 0)
  1240. AND ((info^.fib_Protection and FIBF_WRITE) = 0)
  1241. then
  1242. flags:=flags OR ReadOnly;
  1243. Unlock(mylock);
  1244. end
  1245. else
  1246. DosError:=3;
  1247. attr:=flags;
  1248. Dispose(info);
  1249. End;
  1250. Procedure setfattr (var f;attr : word);
  1251. var
  1252. flags: longint;
  1253. MyLock : longint;
  1254. str: string;
  1255. i: integer;
  1256. Begin
  1257. DosError:=0;
  1258. flags:=FIBF_WRITE;
  1259. { open with shared lock }
  1260. Str := StrPas(filerec(f).name);
  1261. for i:=1 to length(Str) do
  1262. if str[i]='\' then str[i]:='/';
  1263. MyLock:=Lock(Str,SHARED_LOCK);
  1264. { By default files are read-write }
  1265. if attr AND ReadOnly <> 0 then
  1266. { Clear the Fibf_write flags }
  1267. flags:=FIBF_READ;
  1268. if MyLock <> 0 then
  1269. Begin
  1270. Unlock(MyLock);
  1271. if SetProtection(Str,flags) = 0 then
  1272. DosError:=5;
  1273. end
  1274. else
  1275. DosError:=3;
  1276. End;
  1277. {******************************************************************************
  1278. --- Environment ---
  1279. ******************************************************************************}
  1280. var
  1281. StrofPaths : string[255];
  1282. function getpathstring: string;
  1283. var
  1284. f : text;
  1285. s : string;
  1286. found : boolean;
  1287. temp : string[255];
  1288. begin
  1289. found := true;
  1290. temp := '';
  1291. assign(f,'ram:makepathstr');
  1292. rewrite(f);
  1293. writeln(f,'path >ram:temp.lst');
  1294. close(f);
  1295. exec('c:protect','ram:makepathstr sarwed');
  1296. exec('C:execute','ram:makepathstr');
  1297. exec('c:delete','ram:makepathstr quiet');
  1298. assign(f,'ram:temp.lst');
  1299. reset(f);
  1300. { skip the first line, garbage }
  1301. if not eof(f) then readln(f,s);
  1302. while not eof(f) do begin
  1303. readln(f,s);
  1304. if found then begin
  1305. temp := s;
  1306. found := false;
  1307. end else begin;
  1308. if (length(s) + length(temp)) < 255 then
  1309. temp := temp + ';' + s;
  1310. end;
  1311. end;
  1312. close(f);
  1313. exec('C:delete','ram:temp.lst quiet');
  1314. getpathstring := temp;
  1315. end;
  1316. Function EnvCount: Longint;
  1317. { HOW TO GET THIS VALUE: }
  1318. { Each time this function is called, we look at the }
  1319. { local variables in the Process structure (2.0+) }
  1320. { And we also read all files in the ENV: directory }
  1321. Begin
  1322. End;
  1323. Function EnvStr(Index: longint): String;
  1324. Begin
  1325. EnvStr:='';
  1326. End;
  1327. function GetEnv(envvar : String): String;
  1328. var
  1329. bufarr : array[0..255] of char;
  1330. strbuffer : array[0..255] of char;
  1331. temp : Longint;
  1332. begin
  1333. if UpCase(envvar) = 'PATH' then begin
  1334. if StrOfpaths = '' then StrOfPaths := GetPathString;
  1335. GetEnv := StrofPaths;
  1336. end else begin
  1337. move(envvar,strbuffer,length(envvar));
  1338. strbuffer[length(envvar)] := #0;
  1339. temp := GetVar(strbuffer,bufarr,255,$100);
  1340. if temp = -1 then
  1341. GetEnv := ''
  1342. else GetEnv := StrPas(bufarr);
  1343. end;
  1344. end;
  1345. {******************************************************************************
  1346. --- Not Supported ---
  1347. ******************************************************************************}
  1348. Procedure keep(exitcode : word);
  1349. Begin
  1350. { ! Not implemented in Linux ! }
  1351. End;
  1352. procedure AddDevice(str : String);
  1353. begin
  1354. inc(numberofdevices);
  1355. deviceids[numberofdevices] := numberofdevices;
  1356. devicenames[numberofdevices] := str;
  1357. end;
  1358. function MakeDeviceName(str : pchar): string;
  1359. var
  1360. temp : string[20];
  1361. begin
  1362. temp := strpas(str);
  1363. temp := temp + ':';
  1364. MakeDeviceName := temp;
  1365. end;
  1366. function IsInDeviceList(str : string): boolean;
  1367. var
  1368. i : byte;
  1369. theresult : boolean;
  1370. begin
  1371. theresult := false;
  1372. for i := low(not_to_use_devs) to high(not_to_use_devs) do
  1373. begin
  1374. if str = not_to_use_devs[i] then begin
  1375. theresult := true;
  1376. break;
  1377. end;
  1378. end;
  1379. IsInDeviceList := theresult;
  1380. end;
  1381. function BSTR2STRING(s : BSTR): pchar;
  1382. begin
  1383. BSTR2STRING := Pointer(Longint(BADDR(s))+1);
  1384. end;
  1385. procedure ReadInDevices;
  1386. var
  1387. dl : pDosList;
  1388. temp : pchar;
  1389. str : string[20];
  1390. begin
  1391. dl := LockDosList(LDF_DEVICES or LDF_READ );
  1392. repeat
  1393. dl := NextDosEntry(dl,LDF_DEVICES );
  1394. if dl <> nil then begin
  1395. temp := BSTR2STRING(dl^.dol_Name);
  1396. str := MakeDeviceName(temp);
  1397. if not IsInDeviceList(str) then
  1398. AddDevice(str);
  1399. end;
  1400. until dl = nil;
  1401. UnLockDosList(LDF_DEVICES or LDF_READ );
  1402. end;
  1403. Begin
  1404. DosError:=0;
  1405. numberofdevices := 0;
  1406. StrOfPaths := '';
  1407. AddDevice('DF0:');
  1408. AddDevice('DF1:');
  1409. AddDevice('DF2:');
  1410. AddDevice('DF3:');
  1411. ReadInDevices;
  1412. End.
  1413. {
  1414. $Log$
  1415. Revision 1.8 2004-02-17 17:37:25 daniel
  1416. * Enable threadvars again
  1417. Revision 1.7 2004/02/16 22:16:55 hajny
  1418. * LastDosExitCode changed back from threadvar temporarily
  1419. Revision 1.6 2004/02/15 21:26:37 hajny
  1420. * overloaded ExecuteProcess added, EnvStr param changed to longint
  1421. Revision 1.5 2004/02/09 12:03:16 michael
  1422. + Switched to single interface in dosh.inc
  1423. Revision 1.4 2002/09/07 16:01:16 peter
  1424. * old logs removed and tabs fixed
  1425. }