beos.pp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. unit beos;
  2. interface
  3. type
  4. Stat = packed record
  5. dev:longint; {"device" that this file resides on}
  6. ino:int64; {this file's inode #, unique per device}
  7. mode:dword; {mode bits (rwx for user, group, etc)}
  8. nlink:longint; {number of hard links to this file}
  9. uid:dword; {user id of the owner of this file}
  10. gid:dword; {group id of the owner of this file}
  11. size:int64; {size of this file (in bytes)}
  12. rdev:longint; {device type (not used)}
  13. blksize:longint; {preferref block size for i/o}
  14. atime:longint; {last access time}
  15. mtime:longint; {last modification time}
  16. ctime:longint; {last change time, not creation time}
  17. crtime:longint; {creation time}
  18. end;
  19. PStat=^Stat;
  20. TStat=Stat;
  21. ComStr = String[255];
  22. PathStr = String[255];
  23. DirStr = String[255];
  24. NameStr = String[255];
  25. ExtStr = String[255];
  26. function FStat(Path:String;Var Info:stat):Boolean;
  27. function FStat(var f:File;Var Info:stat):Boolean;
  28. function GetEnv(P: string): pchar;
  29. function FExpand(Const Path: PathStr):PathStr;
  30. function FSearch(const path:pathstr;dirlist:string):pathstr;
  31. procedure FSplit(const Path:PathStr;Var Dir:DirStr;Var Name:NameStr;Var Ext:ExtStr);
  32. function Dirname(Const path:pathstr):pathstr;
  33. function Basename(Const path:pathstr;Const suf:pathstr):pathstr;
  34. function FNMatch(const Pattern,Name:string):Boolean;
  35. {function StringToPPChar(Var S:STring):ppchar;}
  36. function PExists(path:string):boolean;
  37. function FExists(path:string):boolean;
  38. Function Shell(const Command:String):Longint;
  39. implementation
  40. uses strings;
  41. {$i filerec.inc}
  42. {$i textrec.inc}
  43. function sys_stat (a:cardinal;path:pchar;info:pstat;n:longint):longint; cdecl; external name 'sys_stat';
  44. function FStat(Path:String;Var Info:stat):Boolean;
  45. {
  46. Get all information on a file, and return it in Info.
  47. }
  48. var tmp:string;
  49. var p:pchar;
  50. begin
  51. tmp:=path+#0;
  52. p:=@tmp[1];
  53. FStat:=(sys_stat($FF000000,p,@Info,0)=0);
  54. end;
  55. function FStat(var f:File;Var Info:stat):Boolean;
  56. {
  57. Get all information on a file, and return it in Info.
  58. }
  59. begin
  60. FStat:=(sys_stat($FF000000,PChar(@FileRec(f).Name),@Info,0)=0);
  61. end;
  62. Function GetEnv(P:string):Pchar;
  63. {
  64. Searches the environment for a string with name p and
  65. returns a pchar to it's value.
  66. A pchar is used to accomodate for strings of length > 255
  67. }
  68. var
  69. ep : ppchar;
  70. found : boolean;
  71. Begin
  72. p:=p+'='; {Else HOST will also find HOSTNAME, etc}
  73. ep:=envp;
  74. found:=false;
  75. if ep<>nil then
  76. begin
  77. while (not found) and (ep^<>nil) do
  78. begin
  79. if strlcomp(@p[1],(ep^),length(p))=0 then
  80. found:=true
  81. else
  82. inc(ep);
  83. end;
  84. end;
  85. if found then
  86. getenv:=ep^+length(p)
  87. else
  88. getenv:=nil;
  89. { writeln ('GETENV (',P,') =',getenv);}
  90. end;
  91. Function StringToPPChar(Var S:String; Var nr:longint):ppchar;
  92. {
  93. Create a PPChar to structure of pchars which are the arguments specified
  94. in the string S. Especially usefull for creating an ArgV for Exec-calls
  95. }
  96. var
  97. Buf : ^char;
  98. p : ppchar;
  99. begin
  100. s:=s+#0;
  101. buf:=@s[1];
  102. nr:=0;
  103. while(buf^<>#0) do
  104. begin
  105. while (buf^ in [' ',#8,#10]) do
  106. inc(buf);
  107. inc(nr);
  108. while not (buf^ in [' ',#0,#8,#10]) do
  109. inc(buf);
  110. end;
  111. getmem(p,nr*4);
  112. StringToPPChar:=p;
  113. if p=nil then
  114. begin
  115. { LinuxError:=sys_enomem;}
  116. exit;
  117. end;
  118. buf:=@s[1];
  119. while (buf^<>#0) do
  120. begin
  121. while (buf^ in [' ',#8,#10]) do
  122. begin
  123. buf^:=#0;
  124. inc(buf);
  125. end;
  126. p^:=buf;
  127. inc(p);
  128. p^:=nil;
  129. while not (buf^ in [' ',#0,#8,#10]) do
  130. inc(buf);
  131. end;
  132. end;
  133. {
  134. function FExpand (const Path: PathStr): PathStr;
  135. - declared in fexpand.inc
  136. }
  137. {$DEFINE FPC_FEXPAND_TILDE} { Tilde is expanded to home }
  138. {$DEFINE FPC_FEXPAND_GETENVPCHAR} { GetEnv result is a PChar }
  139. {$I fexpand.inc}
  140. {$UNDEF FPC_FEXPAND_GETENVPCHAR}
  141. {$UNDEF FPC_FEXPAND_TILDE}
  142. Function FSearch(const path:pathstr;dirlist:string):pathstr;
  143. {
  144. Searches for a file 'path' in the list of direcories in 'dirlist'.
  145. returns an empty string if not found. Wildcards are NOT allowed.
  146. If dirlist is empty, it is set to '.'
  147. }
  148. Var
  149. NewDir : PathStr;
  150. p1 : Longint;
  151. Info : Stat;
  152. Begin
  153. {Replace ':' with ';'}
  154. for p1:=1to length(dirlist) do
  155. if dirlist[p1]=':' then
  156. dirlist[p1]:=';';
  157. {Check for WildCards}
  158. If (Pos('?',Path) <> 0) or (Pos('*',Path) <> 0) Then
  159. FSearch:='' {No wildcards allowed in these things.}
  160. Else
  161. Begin
  162. Dirlist:='.;'+dirlist;{Make sure current dir is first to be searched.}
  163. Repeat
  164. p1:=Pos(';',DirList);
  165. If p1=0 Then
  166. p1:=255;
  167. NewDir:=Copy(DirList,1,P1 - 1);
  168. if NewDir[Length(NewDir)]<>'/' then
  169. NewDir:=NewDir+'/';
  170. NewDir:=NewDir+Path;
  171. Delete(DirList,1,p1);
  172. if FStat(NewDir,Info) then
  173. Begin
  174. If Pos('./',NewDir)=1 Then
  175. Delete(NewDir,1,2);
  176. {DOS strips off an initial .\}
  177. End
  178. Else
  179. NewDir:='';
  180. Until (DirList='') or (Length(NewDir) > 0);
  181. FSearch:=NewDir;
  182. End;
  183. End;
  184. Procedure FSplit(const Path:PathStr;Var Dir:DirStr;Var Name:NameStr;Var Ext:ExtStr);
  185. Var
  186. DotPos,SlashPos,i : longint;
  187. Begin
  188. SlashPos:=0;
  189. DotPos:=256;
  190. i:=Length(Path);
  191. While (i>0) and (SlashPos=0) Do
  192. Begin
  193. If (DotPos=256) and (Path[i]='.') Then
  194. DotPos:=i;
  195. If (Path[i]='/') Then
  196. SlashPos:=i;
  197. Dec(i);
  198. End;
  199. Ext:=Copy(Path,DotPos,255);
  200. Dir:=Copy(Path,1,SlashPos);
  201. Name:=Copy(Path,SlashPos + 1,DotPos - SlashPos - 1);
  202. End;
  203. Function Dirname(Const path:pathstr):pathstr;
  204. {
  205. This function returns the directory part of a complete path.
  206. Unless the directory is root '/', The last character is not
  207. a slash.
  208. }
  209. var
  210. Dir : PathStr;
  211. Name : NameStr;
  212. Ext : ExtStr;
  213. begin
  214. FSplit(Path,Dir,Name,Ext);
  215. if length(Dir)>1 then
  216. Delete(Dir,length(Dir),1);
  217. DirName:=Dir;
  218. end;
  219. Function Basename(Const path:pathstr;Const suf:pathstr):pathstr;
  220. {
  221. This function returns the filename part of a complete path. If suf is
  222. supplied, it is cut off the filename.
  223. }
  224. var
  225. Dir : PathStr;
  226. Name : NameStr;
  227. Ext : ExtStr;
  228. begin
  229. FSplit(Path,Dir,Name,Ext);
  230. if Suf<>Ext then
  231. Name:=Name+Ext;
  232. BaseName:=Name;
  233. end;
  234. Function FNMatch(const Pattern,Name:string):Boolean;
  235. Var
  236. LenPat,LenName : longint;
  237. Function DoFNMatch(i,j:longint):Boolean;
  238. Var
  239. Found : boolean;
  240. Begin
  241. Found:=true;
  242. While Found and (i<=LenPat) Do
  243. Begin
  244. Case Pattern[i] of
  245. '?' : Found:=(j<=LenName);
  246. '*' : Begin
  247. {find the next character in pattern, different of ? and *}
  248. while Found and (i<LenPat) do
  249. begin
  250. inc(i);
  251. case Pattern[i] of
  252. '*' : ;
  253. '?' : begin
  254. inc(j);
  255. Found:=(j<=LenName);
  256. end;
  257. else
  258. Found:=false;
  259. end;
  260. end;
  261. {Now, find in name the character which i points to, if the * or ?
  262. wasn't the last character in the pattern, else, use up all the
  263. chars in name}
  264. Found:=true;
  265. if (i<=LenPat) then
  266. begin
  267. repeat
  268. {find a letter (not only first !) which maches pattern[i]}
  269. while (j<=LenName) and (name[j]<>pattern[i]) do
  270. inc (j);
  271. if (j<LenName) then
  272. begin
  273. if DoFnMatch(i+1,j+1) then
  274. begin
  275. i:=LenPat;
  276. j:=LenName;{we can stop}
  277. Found:=true;
  278. end
  279. else
  280. inc(j);{We didn't find one, need to look further}
  281. end;
  282. until (j>=LenName);
  283. end
  284. else
  285. j:=LenName;{we can stop}
  286. end;
  287. else {not a wildcard character in pattern}
  288. Found:=(j<=LenName) and (pattern[i]=name[j]);
  289. end;
  290. inc(i);
  291. inc(j);
  292. end;
  293. DoFnMatch:=Found and (j>LenName);
  294. end;
  295. Begin {start FNMatch}
  296. LenPat:=Length(Pattern);
  297. LenName:=Length(Name);
  298. FNMatch:=DoFNMatch(1,1);
  299. End;
  300. function PExists(path:string):boolean;
  301. begin
  302. PExists:=FExists(path);
  303. end;
  304. function FExists(path:string):boolean;
  305. var
  306. info:stat;
  307. begin
  308. FExists:=Fstat(path,info);
  309. end;
  310. function sys_load_image(a:cardinal; argp:ppchar; envp:ppchar):longint; cdecl; external name 'sys_load_image';
  311. function sys_wait_for_thread (th:longint; var exitcode:longint):longint; cdecl; external name 'sys_wait_for_thread';
  312. Function Shell(const Command:String):Longint;
  313. var s:string;
  314. argv:ppchar;
  315. argc:longint;
  316. th:longint;
  317. begin
  318. s:=Command;
  319. argv:=StringToPPChar(s,argc);
  320. th:=0;
  321. { writeln ('argc = ',argc);
  322. while argv[th]<>Nil do begin
  323. writeln ('argv[',th,'] = ',argv[th]);
  324. th:=th+1;
  325. end;
  326. }
  327. th:=sys_load_image(argc,argv,system.envp);
  328. if th<0 then begin
  329. shell:=0;
  330. exit;
  331. end;
  332. sys_wait_for_thread(th,Shell);
  333. end;
  334. end.