dos.pp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728
  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. {Bitmasks for CPU Flags}
  26. fcarry = $0001;
  27. fparity = $0004;
  28. fauxiliary = $0010;
  29. fzero = $0040;
  30. fsign = $0080;
  31. foverflow = $0800;
  32. {Bitmasks for file attribute}
  33. readonly = $01;
  34. hidden = $02;
  35. sysfile = $04;
  36. volumeid = $08;
  37. directory = $10;
  38. archive = $20;
  39. anyfile = $3F;
  40. {File Status}
  41. fmclosed = $D7B0;
  42. fminput = $D7B1;
  43. fmoutput = $D7B2;
  44. fminout = $D7B3;
  45. Type
  46. ComStr = String[255]; { size increased to be more compatible with Unix}
  47. PathStr = String[255]; { size increased to be more compatible with Unix}
  48. DirStr = String[255]; { size increased to be more compatible with Unix}
  49. NameStr = String[255]; { size increased to be more compatible with Unix}
  50. ExtStr = String[255]; { size increased to be more compatible with Unix}
  51. {
  52. filerec.inc contains the definition of the filerec.
  53. textrec.inc contains the definition of the textrec.
  54. It is in a separate file to make it available in other units without
  55. having to use the DOS unit for it.
  56. }
  57. {$i filerec.inc}
  58. {$i textrec.inc}
  59. Type
  60. SearchRec = Packed Record
  61. { watch out this is correctly aligned for all processors }
  62. { don't modify. }
  63. { Replacement for Fill }
  64. {0} AnchorPtr : Pointer; { Pointer to the Anchorpath structure }
  65. {4} Fill: Array[1..15] of Byte; {future use}
  66. {End of replacement for fill}
  67. Attr : BYTE; {attribute of found file}
  68. Time : LongInt; {last modify date of found file}
  69. Size : LongInt; {file size of found file}
  70. Name : String[255]; {name of found file}
  71. End;
  72. DateTime = packed record
  73. Year: Word;
  74. Month: Word;
  75. Day: Word;
  76. Hour: Word;
  77. Min: Word;
  78. Sec: word;
  79. End;
  80. registers = packed record
  81. case i : integer of
  82. 0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
  83. 1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
  84. 2 : (eax, ebx, ecx, edx, ebp, esi, edi : longint);
  85. end;
  86. Var
  87. DosError : integer;
  88. {Interrupt}
  89. Procedure Intr(intno: byte; var regs: registers);
  90. Procedure MSDos(var regs: registers);
  91. {Info/Date/Time}
  92. Function DosVersion: Word;
  93. Procedure GetDate(var year, month, mday, wday: word);
  94. Procedure GetTime(var hour, minute, second, sec100: word);
  95. procedure SetDate(year,month,day: word);
  96. Procedure SetTime(hour,minute,second,sec100: word);
  97. Procedure UnpackTime(p: longint; var t: datetime);
  98. Procedure PackTime(var t: datetime; var p: longint);
  99. {Exec}
  100. Procedure Exec(const path: pathstr; const comline: comstr);
  101. Function DosExitCode: word;
  102. {Disk}
  103. Function DiskFree(drive: byte) : longint;
  104. Function DiskSize(drive: byte) : longint;
  105. Procedure FindFirst(path: pathstr; attr: word; var f: searchRec);
  106. Procedure FindNext(var f: searchRec);
  107. Procedure FindClose(Var f: SearchRec);
  108. {File}
  109. Procedure GetFAttr(var f; var attr: word);
  110. Procedure GetFTime(var f; var time: longint);
  111. Function FSearch(path: pathstr; dirlist: string): pathstr;
  112. Function FExpand(path: pathstr): pathstr;
  113. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  114. {Environment}
  115. Function EnvCount: longint;
  116. Function EnvStr(index: integer): string;
  117. Function GetEnv(envvar: string): string;
  118. {Misc}
  119. Procedure SetFAttr(var f; attr: word);
  120. Procedure SetFTime(var f; time: longint);
  121. Procedure GetCBreak(var breakvalue: boolean);
  122. Procedure SetCBreak(breakvalue: boolean);
  123. Procedure GetVerify(var verify: boolean);
  124. Procedure SetVerify(verify: boolean);
  125. {Do Nothing Functions}
  126. Procedure SwapVectors;
  127. Procedure GetIntVec(intno: byte; var vector: pointer);
  128. Procedure SetIntVec(intno: byte; vector: pointer);
  129. Procedure Keep(exitcode: word);
  130. implementation
  131. const
  132. DaysPerMonth : Array[1..12] of ShortInt =
  133. (031,028,031,030,031,030,031,031,030,031,030,031);
  134. DaysPerYear : Array[1..12] of Integer =
  135. (031,059,090,120,151,181,212,243,273,304,334,365);
  136. DaysPerLeapYear : Array[1..12] of Integer =
  137. (031,060,091,121,152,182,213,244,274,305,335,366);
  138. SecsPerYear : LongInt = 31536000;
  139. SecsPerLeapYear : LongInt = 31622400;
  140. SecsPerDay : LongInt = 86400;
  141. SecsPerHour : Integer = 3600;
  142. SecsPerMinute : ShortInt = 60;
  143. TICKSPERSECOND = 50;
  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 : longint; { sigs allocated }
  201. tc_SigWait : longint; { sigs we are waiting for }
  202. tc_SigRecvd : longint; { sigs we have received }
  203. tc_SigExcept : longint; { 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. _LVOSetFileDate = -396;
  359. LDF_READ = 1;
  360. LDF_DEVICES = 4;
  361. ERROR_NO_MORE_ENTRIES = 232;
  362. FIBF_SCRIPT = 64; { program is a script }
  363. FIBF_PURE = 32; { program is reentrant }
  364. FIBF_ARCHIVE = 16; { cleared whenever file is changed }
  365. FIBF_READ = 8; { ignoed by old filesystem }
  366. FIBF_WRITE = 4; { ignored by old filesystem }
  367. FIBF_EXECUTE = 2; { ignored by system, used by shell }
  368. FIBF_DELETE = 1; { prevent file from being deleted }
  369. SHARED_LOCK = -2;
  370. {******************************************************************************
  371. --- Internal routines ---
  372. ******************************************************************************}
  373. procedure CurrentTime(var Seconds, Micros : Longint);
  374. Begin
  375. asm
  376. MOVE.L A6,-(A7)
  377. MOVE.L Seconds,a0
  378. MOVE.L Micros,a1
  379. MOVE.L _IntuitionBase,A6
  380. JSR -084(A6)
  381. MOVE.L (A7)+,A6
  382. end;
  383. end;
  384. function Date2Amiga(date : pClockData) : Longint;
  385. Begin
  386. asm
  387. MOVE.L A6,-(A7)
  388. MOVE.L date,a0
  389. MOVE.L _UtilityBase,A6
  390. JSR -126(A6)
  391. MOVE.L (A7)+,A6
  392. MOVE.L d0,@RESULT
  393. end;
  394. end;
  395. procedure Amiga2Date(amigatime : Longint;
  396. resultat : pClockData);
  397. Begin
  398. asm
  399. MOVE.L A6,-(A7)
  400. MOVE.L amigatime,d0
  401. MOVE.L resultat,a0
  402. MOVE.L _UtilityBase,A6
  403. JSR -120(A6)
  404. MOVE.L (A7)+,A6
  405. end;
  406. end;
  407. FUNCTION Examine(lock : BPTR; fileInfoBlock : pFileInfoBlock) : BOOLEAN;
  408. BEGIN
  409. ASM
  410. MOVE.L A6,-(A7)
  411. MOVE.L lock,D1
  412. MOVE.L fileInfoBlock,D2
  413. MOVEA.L _DOSBase,A6
  414. JSR -102(A6)
  415. MOVEA.L (A7)+,A6
  416. TST.L D0
  417. BEQ.B @end
  418. MOVE.B #1,D0
  419. @end: MOVE.B D0,@RESULT
  420. END;
  421. END;
  422. function Lock(const name : string;
  423. accessmode : Longint) : BPTR;
  424. var
  425. buffer: Array[0..255] of char;
  426. Begin
  427. move(name[1],buffer,length(name));
  428. buffer[length(name)]:=#0;
  429. asm
  430. MOVEM.L d2/a6,-(A7)
  431. LEA buffer,a0
  432. MOVE.L a0,d1
  433. MOVE.L accessmode,d2
  434. MOVE.L _DOSBase,A6
  435. JSR -084(A6)
  436. MOVEM.L (A7)+,d2/a6
  437. MOVE.L d0,@RESULT
  438. end;
  439. end;
  440. procedure UnLock(lock : BPTR);
  441. Begin
  442. asm
  443. MOVE.L A6,-(A7)
  444. MOVE.L lock,d1
  445. MOVE.L _DOSBase,A6
  446. JSR -090(A6)
  447. MOVE.L (A7)+,A6
  448. end;
  449. end;
  450. FUNCTION Info(lock : BPTR; parameterBlock : pInfoData) : BOOLEAN;
  451. BEGIN
  452. ASM
  453. MOVE.L A6,-(A7)
  454. MOVE.L lock,D1
  455. MOVE.L parameterBlock,D2
  456. MOVEA.L _DOSBase,A6
  457. JSR -114(A6)
  458. MOVEA.L (A7)+,A6
  459. TST.L D0
  460. BEQ.B @end
  461. MOVE.B #1,D0
  462. @end:
  463. MOVE.B D0,@RESULT
  464. END;
  465. END;
  466. FUNCTION NameFromLock(lock : BPTR; buffer : pCHAR; len : LONGINT) : BOOLEAN;
  467. BEGIN
  468. ASM
  469. MOVE.L A6,-(A7)
  470. MOVE.L lock,D1
  471. MOVE.L buffer,D2
  472. MOVE.L len,D3
  473. MOVEA.L _DOSBase,A6
  474. JSR -402(A6)
  475. MOVEA.L (A7)+,A6
  476. TST.L D0
  477. BEQ.B @end
  478. MOVE.B #1,D0
  479. @end: MOVE.B D0,@RESULT
  480. END;
  481. END;
  482. FUNCTION GetVar(name : pCHAR; buffer : pCHAR; size : LONGINT; flags : LONGINT) : LONGINT;
  483. BEGIN
  484. ASM
  485. MOVE.L A6,-(A7)
  486. MOVE.L name,D1
  487. MOVE.L buffer,D2
  488. MOVE.L size,D3
  489. MOVE.L flags,D4
  490. MOVEA.L _DOSBase,A6
  491. JSR -906(A6)
  492. MOVEA.L (A7)+,A6
  493. MOVE.L D0,@RESULT
  494. END;
  495. END;
  496. FUNCTION FindTask(name : pCHAR) : pTask;
  497. BEGIN
  498. ASM
  499. MOVE.L A6,-(A7)
  500. MOVEA.L name,A1
  501. MOVEA.L _ExecBase,A6
  502. JSR -294(A6)
  503. MOVEA.L (A7)+,A6
  504. MOVE.L D0,@RESULT
  505. END;
  506. END;
  507. FUNCTION MatchFirst(pat : pCHAR; anchor : pAnchorPath) : LONGINT;
  508. BEGIN
  509. ASM
  510. MOVE.L A6,-(A7)
  511. MOVE.L pat,D1
  512. MOVE.L anchor,D2
  513. MOVEA.L _DOSBase,A6
  514. JSR -822(A6)
  515. MOVEA.L (A7)+,A6
  516. MOVE.L D0,@RESULT
  517. END;
  518. END;
  519. FUNCTION MatchNext(anchor : pAnchorPath) : LONGINT;
  520. BEGIN
  521. ASM
  522. MOVE.L A6,-(A7)
  523. MOVE.L anchor,D1
  524. MOVEA.L _DOSBase,A6
  525. JSR -828(A6)
  526. MOVEA.L (A7)+,A6
  527. MOVE.L D0,@RESULT
  528. END;
  529. END;
  530. PROCEDURE MatchEnd(anchor : pAnchorPath);
  531. BEGIN
  532. ASM
  533. MOVE.L A6,-(A7)
  534. MOVE.L anchor,D1
  535. MOVEA.L _DOSBase,A6
  536. JSR -834(A6)
  537. MOVEA.L (A7)+,A6
  538. END;
  539. END;
  540. FUNCTION Cli : pCommandLineInterface;
  541. BEGIN
  542. ASM
  543. MOVE.L A6,-(A7)
  544. MOVEA.L _DOSBase,A6
  545. JSR -492(A6)
  546. MOVEA.L (A7)+,A6
  547. MOVE.L D0,@RESULT
  548. END;
  549. END;
  550. Function _Execute(p: pchar): longint;
  551. Begin
  552. asm
  553. move.l a6,d6 { save base pointer }
  554. move.l d2,-(sp)
  555. move.l p,d1 { command to execute }
  556. clr.l d2 { No TagList for command }
  557. move.l _DosBase,a6
  558. jsr _LVOSystemTagList(a6)
  559. move.l (sp)+,d2
  560. move.l d6,a6 { restore base pointer }
  561. move.l d0,@RESULT
  562. end;
  563. end;
  564. FUNCTION LockDosList(flags : longint) : pDosList;
  565. BEGIN
  566. ASM
  567. MOVE.L A6,-(A7)
  568. MOVE.L flags,D1
  569. MOVEA.L _DOSBase,A6
  570. JSR -654(A6)
  571. MOVEA.L (A7)+,A6
  572. MOVE.L D0,@RESULT
  573. END;
  574. END;
  575. PROCEDURE UnLockDosList(flags : longint);
  576. BEGIN
  577. ASM
  578. MOVE.L A6,-(A7)
  579. MOVE.L flags,D1
  580. MOVEA.L _DOSBase,A6
  581. JSR -660(A6)
  582. MOVEA.L (A7)+,A6
  583. END;
  584. END;
  585. FUNCTION NextDosEntry(dlist : pDosList; flags : longint) : pDosList;
  586. BEGIN
  587. ASM
  588. MOVE.L A6,-(A7)
  589. MOVE.L dlist,D1
  590. MOVE.L flags,D2
  591. MOVEA.L _DOSBase,A6
  592. JSR -690(A6)
  593. MOVEA.L (A7)+,A6
  594. MOVE.L D0,@RESULT
  595. END;
  596. END;
  597. FUNCTION BADDR(bval : BPTR): POINTER;
  598. BEGIN
  599. BADDR := POINTER( bval shl 2);
  600. END;
  601. function PasToC(var s: string): Pchar;
  602. var i: integer;
  603. begin
  604. i := Length(s) + 1;
  605. if i > 255 then
  606. begin
  607. Delete(s, 255, 1); { ensure there is a spare byte }
  608. Dec(i)
  609. end;
  610. s[i] := #0;
  611. PasToC := @s[1]
  612. end;
  613. Procedure AmigaToDt(SecsPast: LongInt; Var Dt: DateTime);
  614. var
  615. cd : pClockData;
  616. Begin
  617. New(cd);
  618. Amiga2Date(SecsPast,cd);
  619. Dt.sec := cd^.sec;
  620. Dt.min := cd^.min;
  621. Dt.hour := cd^.hour;
  622. Dt.day := cd^.mday;
  623. Dt.month := cd^.month;
  624. Dt.year := cd^.year;
  625. Dispose(cd);
  626. End;
  627. Function DtToAmiga(DT: DateTime): LongInt;
  628. var
  629. cd : pClockData;
  630. temp : Longint;
  631. Begin
  632. New(cd);
  633. cd^.sec := Dt.sec;
  634. cd^.min := Dt.min;
  635. cd^.hour := Dt.hour;
  636. cd^.mday := Dt.day;
  637. cd^.month := Dt.month;
  638. cd^.year := Dt.year;
  639. temp := Date2Amiga(cd);
  640. Dispose(cd);
  641. DtToAmiga := temp;
  642. end;
  643. Function SetProtection(const name: string; mask:longint): longint;
  644. var
  645. buffer : array[0..255] of char;
  646. Begin
  647. move(name[1],buffer,length(name));
  648. buffer[length(name)]:=#0;
  649. asm
  650. move.l a6,d6
  651. lea buffer,a0
  652. move.l a0,d1
  653. move.l mask,d2
  654. move.l _DosBase,a6
  655. jsr -186(a6)
  656. move.l d6,a6
  657. move.l d0,@RESULT
  658. end;
  659. end;
  660. Function IsLeapYear(Source : Word) : Boolean;
  661. Begin
  662. If (Source Mod 4 = 0) Then
  663. IsLeapYear := True
  664. Else
  665. IsLeapYear := False;
  666. End;
  667. Procedure Amiga2DateStamp(Date : LongInt; Var TotalDays,Minutes,Ticks: longint);
  668. { Converts a value in seconds past 1978 to a value in AMIGA DateStamp format }
  669. { Taken from SWAG and modified to work with the Amiga format - CEC }
  670. Var
  671. LocalDate : LongInt; Done : Boolean; X : ShortInt; TotDays : Integer;
  672. Y: Word;
  673. M: Word;
  674. D: Word;
  675. H: Word;
  676. Min: Word;
  677. S : Word;
  678. Begin
  679. Y := 1978; M := 1; D := 1; H := 0; Min := 0; S := 0;
  680. TotalDays := 0;
  681. Minutes := 0;
  682. Ticks := 0;
  683. LocalDate := Date;
  684. Done := False;
  685. While Not Done Do
  686. Begin
  687. If LocalDate >= SecsPerYear Then
  688. Begin
  689. Inc(Y,1);
  690. Dec(LocalDate,SecsPerYear);
  691. Inc(TotalDays,DaysPerYear[12]);
  692. End
  693. Else
  694. Done := True;
  695. If (IsLeapYear(Y+1)) And (LocalDate >= SecsPerLeapYear) And
  696. (Not Done) Then
  697. Begin
  698. Inc(Y,1);
  699. Dec(LocalDate,SecsPerLeapYear);
  700. Inc(TotalDays,DaysPerLeapYear[12]);
  701. End;
  702. End; { END WHILE }
  703. M := 1; D := 1;
  704. Done := False;
  705. TotDays := LocalDate Div SecsPerDay;
  706. { Total number of days }
  707. TotalDays := TotalDays + TotDays;
  708. Dec(LocalDate,TotDays*SecsPerDay);
  709. { Absolute hours since start of day }
  710. H := LocalDate Div SecsPerHour;
  711. { Convert to minutes }
  712. Minutes := H*60;
  713. Dec(LocalDate,(H * SecsPerHour));
  714. { Find the remaining minutes to add }
  715. Min := LocalDate Div SecsPerMinute;
  716. Dec(LocalDate,(Min * SecsPerMinute));
  717. Minutes:=Minutes+Min;
  718. { Find the number of seconds and convert to ticks }
  719. S := LocalDate;
  720. Ticks:=TICKSPERSECOND*S;
  721. End;
  722. Function SetFileDate(name: string; p : pDateStamp): longint;
  723. var
  724. buffer : array[0..255] of char;
  725. Begin
  726. move(name[1],buffer,length(name));
  727. buffer[length(name)]:=#0;
  728. asm
  729. move.l a6,d6 { save base pointer }
  730. move.l d2,-(sp) { save reserved reg }
  731. lea buffer,a0
  732. move.l a0,d1
  733. move.l p,d2
  734. move.l _DosBase,a6
  735. jsr _LVOSetFileDate(a6)
  736. move.l (sp)+,d2 { restore reserved reg }
  737. move.l d6,a6 { restore base pointer }
  738. move.l d0,@Result
  739. end;
  740. end;
  741. {******************************************************************************
  742. --- Dos Interrupt ---
  743. ******************************************************************************}
  744. Procedure Intr (intno: byte; var regs: registers);
  745. Begin
  746. { Does not apply to Linux - not implemented }
  747. End;
  748. Procedure SwapVectors;
  749. Begin
  750. { Does not apply to Linux - Do Nothing }
  751. End;
  752. Procedure msdos(var regs : registers);
  753. Begin
  754. { ! Not implemented in Linux ! }
  755. End;
  756. Procedure getintvec(intno : byte;var vector : pointer);
  757. Begin
  758. { ! Not implemented in Linux ! }
  759. End;
  760. Procedure setintvec(intno : byte;vector : pointer);
  761. Begin
  762. { ! Not implemented in Linux ! }
  763. End;
  764. {******************************************************************************
  765. --- Info / Date / Time ---
  766. ******************************************************************************}
  767. Function DosVersion: Word;
  768. var p: pLibrary;
  769. Begin
  770. p:=pLibrary(_DosBase);
  771. DosVersion:= p^.lib_Version or (p^.lib_Revision shl 8);
  772. End;
  773. Procedure GetDate(Var Year, Month, MDay, WDay: Word);
  774. Var
  775. cd : pClockData;
  776. mysec,
  777. tick : Longint;
  778. begin
  779. New(cd);
  780. CurrentTime(mysec,tick);
  781. Amiga2Date(mysec,cd);
  782. Year := cd^.year;
  783. Month := cd^.month;
  784. MDay := cd^.mday;
  785. WDay := cd^.wday;
  786. Dispose(cd);
  787. end;
  788. Procedure SetDate(Year, Month, Day: Word);
  789. Begin
  790. { !! }
  791. End;
  792. Procedure GetTime(Var Hour, Minute, Second, Sec100: Word);
  793. Var
  794. mysec,
  795. tick : Longint;
  796. cd : pClockData;
  797. begin
  798. New(cd);
  799. CurrentTime(mysec,tick);
  800. Amiga2Date(mysec,cd);
  801. Hour := cd^.hour;
  802. Minute := cd^.min;
  803. Second := cd^.sec;
  804. Sec100 := 0;
  805. Dispose(cd);
  806. END;
  807. Procedure SetTime(Hour, Minute, Second, Sec100: Word);
  808. Begin
  809. { !! }
  810. End;
  811. Procedure unpacktime(p : longint;var t : datetime);
  812. Begin
  813. AmigaToDt(p,t);
  814. End;
  815. Procedure packtime(var t : datetime;var p : longint);
  816. Begin
  817. p := DtToAmiga(t);
  818. end;
  819. {******************************************************************************
  820. --- Exec ---
  821. ******************************************************************************}
  822. Var
  823. LastDosExitCode: word;
  824. Procedure Exec (Const Path: PathStr; Const ComLine: ComStr);
  825. var
  826. p : string;
  827. buf: array[0..255] of char;
  828. result : longint;
  829. MyLock : longint;
  830. i : Integer;
  831. Begin
  832. DosError := 0;
  833. LastdosExitCode := 0;
  834. p:=Path+' '+ComLine;
  835. { allow backslash as slash }
  836. for i:=1 to length(p) do
  837. if p[i]='\' then p[i]:='/';
  838. Move(p[1],buf,length(p));
  839. buf[Length(p)]:=#0;
  840. { Here we must first check if the command we wish to execute }
  841. { actually exists, because this is NOT handled by the }
  842. { _SystemTagList call (program will abort!!) }
  843. { Try to open with shared lock }
  844. MyLock:=Lock(path,SHARED_LOCK);
  845. if MyLock <> 0 then
  846. Begin
  847. { File exists - therefore unlock it }
  848. Unlock(MyLock);
  849. result:=_Execute(buf);
  850. { on return of -1 the shell could not be executed }
  851. { probably because there was not enough memory }
  852. if result = -1 then
  853. DosError:=8
  854. else
  855. LastDosExitCode:=word(result);
  856. end
  857. else
  858. DosError:=3;
  859. End;
  860. Function DosExitCode: Word;
  861. Begin
  862. DosExitCode:=LastdosExitCode;
  863. End;
  864. Procedure GetCBreak(Var BreakValue: Boolean);
  865. Begin
  866. breakvalue := system.BreakOn;
  867. End;
  868. Procedure SetCBreak(BreakValue: Boolean);
  869. Begin
  870. system.Breakon := BreakValue;
  871. End;
  872. Procedure GetVerify(Var Verify: Boolean);
  873. Begin
  874. verify:=true;
  875. End;
  876. Procedure SetVerify(Verify: Boolean);
  877. Begin
  878. End;
  879. {******************************************************************************
  880. --- Disk ---
  881. ******************************************************************************}
  882. { How to solve the problem with this: }
  883. { We could walk through the device list }
  884. { at startup to determine possible devices }
  885. const
  886. not_to_use_devs : array[0..12] of string =(
  887. 'DF0:',
  888. 'DF1:',
  889. 'DF2:',
  890. 'DF3:',
  891. 'PED:',
  892. 'PRJ:',
  893. 'PIPE:',
  894. 'RAM:',
  895. 'CON:',
  896. 'RAW:',
  897. 'SER:',
  898. 'PAR:',
  899. 'PRT:');
  900. var
  901. deviceids : array[1..20] of byte;
  902. devicenames : array[1..20] of string[20];
  903. numberofdevices : Byte;
  904. Function DiskFree(Drive: Byte): Longint;
  905. Var
  906. MyLock : BPTR;
  907. Inf : pInfoData;
  908. Free : Longint;
  909. myproc : pProcess;
  910. OldWinPtr : Pointer;
  911. Begin
  912. Free := -1;
  913. { Here we stop systemrequesters to appear }
  914. myproc := pProcess(FindTask(nil));
  915. OldWinPtr := myproc^.pr_WindowPtr;
  916. myproc^.pr_WindowPtr := Pointer(-1);
  917. { End of systemrequesterstop }
  918. New(Inf);
  919. MyLock := Lock(devicenames[deviceids[Drive]],SHARED_LOCK);
  920. If MyLock <> 0 then begin
  921. if Info(MyLock,Inf) then begin
  922. Free := (Inf^.id_NumBlocks * Inf^.id_BytesPerBlock) -
  923. (Inf^.id_NumBlocksUsed * Inf^.id_BytesPerBlock);
  924. end;
  925. Unlock(MyLock);
  926. end;
  927. Dispose(Inf);
  928. { Restore systemrequesters }
  929. myproc^.pr_WindowPtr := OldWinPtr;
  930. diskfree := Free;
  931. end;
  932. Function DiskSize(Drive: Byte): Longint;
  933. Var
  934. MyLock : BPTR;
  935. Inf : pInfoData;
  936. Size : Longint;
  937. myproc : pProcess;
  938. OldWinPtr : Pointer;
  939. Begin
  940. Size := -1;
  941. { Here we stop systemrequesters to appear }
  942. myproc := pProcess(FindTask(nil));
  943. OldWinPtr := myproc^.pr_WindowPtr;
  944. myproc^.pr_WindowPtr := Pointer(-1);
  945. { End of systemrequesterstop }
  946. New(Inf);
  947. MyLock := Lock(devicenames[deviceids[Drive]],SHARED_LOCK);
  948. If MyLock <> 0 then begin
  949. if Info(MyLock,Inf) then begin
  950. Size := (Inf^.id_NumBlocks * Inf^.id_BytesPerBlock);
  951. end;
  952. Unlock(MyLock);
  953. end;
  954. Dispose(Inf);
  955. { Restore systemrequesters }
  956. myproc^.pr_WindowPtr := OldWinPtr;
  957. disksize := Size;
  958. end;
  959. Procedure FindFirst(Path: PathStr; Attr: Word; Var f: SearchRec);
  960. var
  961. buf: Array[0..255] of char;
  962. Anchor : pAnchorPath;
  963. Result : Longint;
  964. index : Integer;
  965. s : string;
  966. j : integer;
  967. Begin
  968. DosError:=0;
  969. New(Anchor);
  970. {----- allow backslash as slash -----}
  971. for index:=1 to length(path) do
  972. if path[index]='\' then path[index]:='/';
  973. { remove any dot characters and replace by their current }
  974. { directory equivalent. }
  975. if pos('../',path) = 1 then
  976. { look for parent directory }
  977. Begin
  978. delete(path,1,3);
  979. getdir(0,s);
  980. j:=length(s);
  981. while (s[j] <> '/') AND (s[j] <> ':') AND (j > 0 ) do
  982. dec(j);
  983. if j > 0 then
  984. s:=copy(s,1,j);
  985. path:=s+path;
  986. end
  987. else
  988. if pos('./',path) = 1 then
  989. { look for current directory }
  990. Begin
  991. delete(path,1,2);
  992. getdir(0,s);
  993. if (s[length(s)] <> '/') and (s[length(s)] <> ':') then
  994. s:=s+'/';
  995. path:=s+path;
  996. end;
  997. {----- replace * by #? AmigaOs strings -----}
  998. repeat
  999. index:= pos('*',Path);
  1000. if index <> 0 then
  1001. Begin
  1002. delete(Path,index,1);
  1003. insert('#?',Path,index);
  1004. end;
  1005. until index =0;
  1006. {--------------------------------------------}
  1007. FillChar(Anchor^,sizeof(TAnchorPath),#0);
  1008. move(path[1],buf,length(path));
  1009. buf[length(path)]:=#0;
  1010. Result:=MatchFirst(@buf,Anchor);
  1011. f.AnchorPtr:=Anchor;
  1012. if Result = ERROR_NO_MORE_ENTRIES then
  1013. DosError:=18
  1014. else
  1015. if Result <> 0 then
  1016. DosError:=3;
  1017. { If there is an error, deallocate }
  1018. { the anchorpath structure }
  1019. if DosError <> 0 then
  1020. Begin
  1021. MatchEnd(Anchor);
  1022. if assigned(Anchor) then
  1023. Dispose(Anchor);
  1024. end
  1025. else
  1026. {-------------------------------------------------------------------}
  1027. { Here we fill up the SearchRec attribute, but we also do check }
  1028. { something else, if the it does not match the mask we are looking }
  1029. { for we should go to the next file or directory. }
  1030. {-------------------------------------------------------------------}
  1031. Begin
  1032. with Anchor^.ap_Info do
  1033. Begin
  1034. f.Time := fib_Date.ds_Days * (24 * 60 * 60) +
  1035. fib_Date.ds_Minute * 60 +
  1036. fib_Date.ds_Tick div 50;
  1037. {*------------------------------------*}
  1038. {* Determine if is a file or a folder *}
  1039. {*------------------------------------*}
  1040. if fib_DirEntryType > 0 then
  1041. f.attr:=f.attr OR DIRECTORY;
  1042. {*------------------------------------*}
  1043. {* Determine if Read only *}
  1044. {* Readonly if R flag on and W flag *}
  1045. {* off. *}
  1046. {* Should we check also that EXEC *}
  1047. {* is zero? for read only? *}
  1048. {*------------------------------------*}
  1049. if ((fib_Protection and FIBF_READ) <> 0)
  1050. AND ((fib_Protection and FIBF_WRITE) = 0)
  1051. then
  1052. f.attr:=f.attr or READONLY;
  1053. f.Name := strpas(fib_FileName);
  1054. f.Size := fib_Size;
  1055. end; { end with }
  1056. end;
  1057. End;
  1058. Procedure FindNext(Var f: SearchRec);
  1059. var
  1060. Result: longint;
  1061. Anchor : pAnchorPath;
  1062. Begin
  1063. DosError:=0;
  1064. Result:=MatchNext(f.AnchorPtr);
  1065. if Result = ERROR_NO_MORE_ENTRIES then
  1066. DosError:=18
  1067. else
  1068. if Result <> 0 then
  1069. DosError:=3;
  1070. { If there is an error, deallocate }
  1071. { the anchorpath structure }
  1072. if DosError <> 0 then
  1073. Begin
  1074. MatchEnd(f.AnchorPtr);
  1075. if assigned(f.AnchorPtr) then
  1076. {Dispose}FreeMem(f.AnchorPtr);
  1077. end
  1078. else
  1079. { Fill up the Searchrec information }
  1080. { and also check if the files are with }
  1081. { the correct attributes }
  1082. Begin
  1083. Anchor:=pAnchorPath(f.AnchorPtr);
  1084. with Anchor^.ap_Info do
  1085. Begin
  1086. f.Time := fib_Date.ds_Days * (24 * 60 * 60) +
  1087. fib_Date.ds_Minute * 60 +
  1088. fib_Date.ds_Tick div 50;
  1089. {*------------------------------------*}
  1090. {* Determine if is a file or a folder *}
  1091. {*------------------------------------*}
  1092. if fib_DirEntryType > 0 then
  1093. f.attr:=f.attr OR DIRECTORY;
  1094. {*------------------------------------*}
  1095. {* Determine if Read only *}
  1096. {* Readonly if R flag on and W flag *}
  1097. {* off. *}
  1098. {* Should we check also that EXEC *}
  1099. {* is zero? for read only? *}
  1100. {*------------------------------------*}
  1101. if ((fib_Protection and FIBF_READ) <> 0)
  1102. AND ((fib_Protection and FIBF_WRITE) = 0)
  1103. then
  1104. f.attr:=f.attr or READONLY;
  1105. f.Name := strpas(fib_FileName);
  1106. f.Size := fib_Size;
  1107. end; { end with }
  1108. end;
  1109. End;
  1110. Procedure FindClose(Var f: SearchRec);
  1111. begin
  1112. end;
  1113. {******************************************************************************
  1114. --- File ---
  1115. ******************************************************************************}
  1116. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  1117. var
  1118. I: Word;
  1119. begin
  1120. { allow backslash as slash }
  1121. for i:=1 to length(path) do
  1122. if path[i]='\' then path[i]:='/';
  1123. I := Length(Path);
  1124. while (I > 0) and not ((Path[I] = '/') or (Path[I] = ':'))
  1125. do Dec(I);
  1126. if Path[I] = '/' then
  1127. dir := Copy(Path, 0, I)
  1128. else dir := Copy(Path,0,I);
  1129. if Length(Path) > Length(dir) then
  1130. name := Copy(Path, I + 1, Length(Path)-I)
  1131. else
  1132. name := '';
  1133. { Remove extension }
  1134. if pos('.',name) <> 0 then
  1135. delete(name,pos('.',name),length(name));
  1136. I := Pos('.',Path);
  1137. if I > 0 then
  1138. ext := Copy(Path,I,Length(Path)-(I-1))
  1139. else ext := '';
  1140. end;
  1141. Function FExpand(Path: PathStr): PathStr;
  1142. var
  1143. FLock : BPTR;
  1144. buffer : array[0..255] of char;
  1145. i :integer;
  1146. j :integer;
  1147. temp : string;
  1148. begin
  1149. { allow backslash as slash }
  1150. for i:=1 to length(path) do
  1151. if path[i]='\' then path[i]:='/';
  1152. temp:=path;
  1153. if pos('../',temp) = 1 then
  1154. delete(temp,1,3);
  1155. if pos('./',temp) = 1 then
  1156. delete(temp,1,2);
  1157. {First remove all references to '/./'}
  1158. while pos('/./',temp)<>0 do
  1159. delete(temp,pos('/./',temp),3);
  1160. {Now remove also all references to '/../' + of course previous dirs..}
  1161. repeat
  1162. i:=pos('/../',temp);
  1163. {Find the pos of the previous dir}
  1164. if i>1 then
  1165. begin
  1166. j:=i-1;
  1167. while (j>1) and (temp[j]<>'/') do
  1168. dec (j);{temp[1] is always '/'}
  1169. delete(temp,j,i-j+4);
  1170. end
  1171. else
  1172. if i=1 then {i=1, so we have temp='/../something', just delete '/../'}
  1173. delete(temp,1,4);
  1174. until i=0;
  1175. FLock := Lock(temp,-2);
  1176. if FLock <> 0 then begin
  1177. if NameFromLock(FLock,buffer,255) then begin
  1178. Unlock(FLock);
  1179. FExpand := strpas(buffer);
  1180. end else begin
  1181. Unlock(FLock);
  1182. FExpand := '';
  1183. end;
  1184. end else FExpand := '';
  1185. end;
  1186. Function fsearch(path : pathstr;dirlist : string) : pathstr;
  1187. var
  1188. i,p1 : longint;
  1189. s : searchrec;
  1190. newdir : pathstr;
  1191. begin
  1192. { No wildcards allowed in these things }
  1193. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  1194. fsearch:=''
  1195. else
  1196. begin
  1197. { allow slash as backslash }
  1198. for i:=1 to length(dirlist) do
  1199. if dirlist[i]='\' then dirlist[i]:='/';
  1200. repeat
  1201. p1:=pos(';',dirlist);
  1202. if p1<>0 then
  1203. begin
  1204. newdir:=copy(dirlist,1,p1-1);
  1205. delete(dirlist,1,p1);
  1206. end
  1207. else
  1208. begin
  1209. newdir:=dirlist;
  1210. dirlist:='';
  1211. end;
  1212. if (newdir<>'') and (not (newdir[length(newdir)] in ['/',':'])) then
  1213. newdir:=newdir+'/';
  1214. findfirst(newdir+path,anyfile,s);
  1215. if doserror=0 then
  1216. newdir:=newdir+path
  1217. else
  1218. newdir:='';
  1219. until (dirlist='') or (newdir<>'');
  1220. fsearch:=newdir;
  1221. end;
  1222. end;
  1223. Procedure getftime (var f; var time : longint);
  1224. {
  1225. This function returns a file's date and time as the number of
  1226. seconds after January 1, 1978 that the file was created.
  1227. }
  1228. var
  1229. FInfo : pFileInfoBlock;
  1230. FTime : Longint;
  1231. FLock : Longint;
  1232. Str : String;
  1233. i : integer;
  1234. begin
  1235. DosError:=0;
  1236. FTime := 0;
  1237. Str := StrPas(filerec(f).name);
  1238. for i:=1 to length(Str) do
  1239. if str[i]='\' then str[i]:='/';
  1240. FLock := Lock(Str, SHARED_LOCK);
  1241. IF FLock <> 0 then begin
  1242. New(FInfo);
  1243. if Examine(FLock, FInfo) then begin
  1244. with FInfo^.fib_Date do
  1245. FTime := ds_Days * (24 * 60 * 60) +
  1246. ds_Minute * 60 +
  1247. ds_Tick div 50;
  1248. end else begin
  1249. FTime := 0;
  1250. end;
  1251. Unlock(FLock);
  1252. Dispose(FInfo);
  1253. end
  1254. else
  1255. DosError:=6;
  1256. time := FTime;
  1257. end;
  1258. Procedure setftime(var f; time : longint);
  1259. var
  1260. DateStamp: pDateStamp;
  1261. Str: String;
  1262. i: Integer;
  1263. Days, Minutes,Ticks: longint;
  1264. FLock: longint;
  1265. Begin
  1266. new(DateStamp);
  1267. Str := StrPas(filerec(f).name);
  1268. for i:=1 to length(Str) do
  1269. if str[i]='\' then str[i]:='/';
  1270. { Check first of all, if file exists }
  1271. FLock := Lock(Str, SHARED_LOCK);
  1272. IF FLock <> 0 then
  1273. begin
  1274. Unlock(FLock);
  1275. Amiga2DateStamp(time,Days,Minutes,ticks);
  1276. DateStamp^.ds_Days:=Days;
  1277. DateStamp^.ds_Minute:=Minutes;
  1278. DateStamp^.ds_Tick:=Ticks;
  1279. if SetFileDate(Str,DateStamp) <> 0 then
  1280. DosError:=0
  1281. else
  1282. DosError:=6;
  1283. end
  1284. else
  1285. DosError:=2;
  1286. if assigned(DateStamp) then Dispose(DateStamp);
  1287. End;
  1288. Procedure getfattr(var f; var attr : word);
  1289. var
  1290. info : pFileInfoBlock;
  1291. MyLock : Longint;
  1292. flags: word;
  1293. Str: String;
  1294. i: integer;
  1295. Begin
  1296. DosError:=0;
  1297. flags:=0;
  1298. New(info);
  1299. Str := StrPas(filerec(f).name);
  1300. for i:=1 to length(Str) do
  1301. if str[i]='\' then str[i]:='/';
  1302. { open with shared lock to check if file exists }
  1303. MyLock:=Lock(Str,SHARED_LOCK);
  1304. if MyLock <> 0 then
  1305. Begin
  1306. Examine(MyLock,info);
  1307. {*------------------------------------*}
  1308. {* Determine if is a file or a folder *}
  1309. {*------------------------------------*}
  1310. if info^.fib_DirEntryType > 0 then
  1311. flags:=flags OR DIRECTORY;
  1312. {*------------------------------------*}
  1313. {* Determine if Read only *}
  1314. {* Readonly if R flag on and W flag *}
  1315. {* off. *}
  1316. {* Should we check also that EXEC *}
  1317. {* is zero? for read only? *}
  1318. {*------------------------------------*}
  1319. if ((info^.fib_Protection and FIBF_READ) <> 0)
  1320. AND ((info^.fib_Protection and FIBF_WRITE) = 0)
  1321. then
  1322. flags:=flags OR ReadOnly;
  1323. Unlock(mylock);
  1324. end
  1325. else
  1326. DosError:=3;
  1327. attr:=flags;
  1328. Dispose(info);
  1329. End;
  1330. Procedure setfattr (var f;attr : word);
  1331. var
  1332. flags: longint;
  1333. MyLock : longint;
  1334. str: string;
  1335. i: integer;
  1336. Begin
  1337. DosError:=0;
  1338. flags:=FIBF_WRITE;
  1339. { open with shared lock }
  1340. Str := StrPas(filerec(f).name);
  1341. for i:=1 to length(Str) do
  1342. if str[i]='\' then str[i]:='/';
  1343. MyLock:=Lock(Str,SHARED_LOCK);
  1344. { By default files are read-write }
  1345. if attr AND ReadOnly <> 0 then
  1346. { Clear the Fibf_write flags }
  1347. flags:=FIBF_READ;
  1348. if MyLock <> 0 then
  1349. Begin
  1350. Unlock(MyLock);
  1351. if SetProtection(Str,flags) = 0 then
  1352. DosError:=5;
  1353. end
  1354. else
  1355. DosError:=3;
  1356. End;
  1357. {******************************************************************************
  1358. --- Environment ---
  1359. ******************************************************************************}
  1360. var
  1361. StrofPaths : string[255];
  1362. function getpathstring: string;
  1363. var
  1364. f : text;
  1365. s : string;
  1366. found : boolean;
  1367. temp : string[255];
  1368. begin
  1369. found := true;
  1370. temp := '';
  1371. assign(f,'ram:makepathstr');
  1372. rewrite(f);
  1373. writeln(f,'path >ram:temp.lst');
  1374. close(f);
  1375. exec('c:protect','ram:makepathstr sarwed');
  1376. exec('C:execute','ram:makepathstr');
  1377. exec('c:delete','ram:makepathstr quiet');
  1378. assign(f,'ram:temp.lst');
  1379. reset(f);
  1380. { skip the first line, garbage }
  1381. if not eof(f) then readln(f,s);
  1382. while not eof(f) do begin
  1383. readln(f,s);
  1384. if found then begin
  1385. temp := s;
  1386. found := false;
  1387. end else begin;
  1388. if (length(s) + length(temp)) < 255 then
  1389. temp := temp + ';' + s;
  1390. end;
  1391. end;
  1392. close(f);
  1393. exec('C:delete','ram:temp.lst quiet');
  1394. getpathstring := temp;
  1395. end;
  1396. Function EnvCount: Longint;
  1397. { HOW TO GET THIS VALUE: }
  1398. { Each time this function is called, we look at the }
  1399. { local variables in the Process structure (2.0+) }
  1400. { And we also read all files in the ENV: directory }
  1401. Begin
  1402. End;
  1403. Function EnvStr(Index: Integer): String;
  1404. Begin
  1405. EnvStr:='';
  1406. End;
  1407. function GetEnv(envvar : String): String;
  1408. var
  1409. bufarr : array[0..255] of char;
  1410. strbuffer : array[0..255] of char;
  1411. temp : Longint;
  1412. begin
  1413. if UpCase(envvar) = 'PATH' then begin
  1414. if StrOfpaths = '' then StrOfPaths := GetPathString;
  1415. GetEnv := StrofPaths;
  1416. end else begin
  1417. move(envvar,strbuffer,length(envvar));
  1418. strbuffer[length(envvar)] := #0;
  1419. temp := GetVar(strbuffer,bufarr,255,$100);
  1420. if temp = -1 then
  1421. GetEnv := ''
  1422. else GetEnv := StrPas(bufarr);
  1423. end;
  1424. end;
  1425. {******************************************************************************
  1426. --- Not Supported ---
  1427. ******************************************************************************}
  1428. Procedure keep(exitcode : word);
  1429. Begin
  1430. { ! Not implemented in Linux ! }
  1431. End;
  1432. procedure AddDevice(str : String);
  1433. begin
  1434. inc(numberofdevices);
  1435. deviceids[numberofdevices] := numberofdevices;
  1436. devicenames[numberofdevices] := str;
  1437. end;
  1438. function MakeDeviceName(str : pchar): string;
  1439. var
  1440. temp : string[20];
  1441. begin
  1442. temp := strpas(str);
  1443. temp := temp + ':';
  1444. MakeDeviceName := temp;
  1445. end;
  1446. function IsInDeviceList(str : string): boolean;
  1447. var
  1448. i : byte;
  1449. theresult : boolean;
  1450. begin
  1451. theresult := false;
  1452. for i := low(not_to_use_devs) to high(not_to_use_devs) do
  1453. begin
  1454. if str = not_to_use_devs[i] then begin
  1455. theresult := true;
  1456. break;
  1457. end;
  1458. end;
  1459. IsInDeviceList := theresult;
  1460. end;
  1461. function BSTR2STRING(s : BSTR): pchar;
  1462. begin
  1463. BSTR2STRING := Pointer(Longint(BADDR(s))+1);
  1464. end;
  1465. procedure ReadInDevices;
  1466. var
  1467. dl : pDosList;
  1468. temp : pchar;
  1469. str : string[20];
  1470. begin
  1471. dl := LockDosList(LDF_DEVICES or LDF_READ );
  1472. repeat
  1473. dl := NextDosEntry(dl,LDF_DEVICES );
  1474. if dl <> nil then begin
  1475. temp := BSTR2STRING(dl^.dol_Name);
  1476. str := MakeDeviceName(temp);
  1477. if not IsInDeviceList(str) then
  1478. AddDevice(str);
  1479. end;
  1480. until dl = nil;
  1481. UnLockDosList(LDF_DEVICES or LDF_READ );
  1482. end;
  1483. Begin
  1484. DosError:=0;
  1485. numberofdevices := 0;
  1486. StrOfPaths := '';
  1487. AddDevice('DF0:');
  1488. AddDevice('DF1:');
  1489. AddDevice('DF2:');
  1490. AddDevice('DF3:');
  1491. ReadInDevices;
  1492. End.
  1493. {
  1494. $Log$
  1495. Revision 1.4 2002-09-07 16:01:16 peter
  1496. * old logs removed and tabs fixed
  1497. }