dos.pp 47 KB

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