linuxvcs.pp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. unit linuxvcs;
  2. {*****************************************************************************}
  3. interface
  4. {*****************************************************************************}
  5. const vcs_device:shortint=-1;
  6. function try_grab_vcsa:boolean;
  7. {*****************************************************************************}
  8. implementation
  9. {*****************************************************************************}
  10. uses baseunix,strings;
  11. function try_grab_vcsa_in_path(path:Pchar;len:cardinal):boolean;
  12. const grab_vcsa='/grab_vcsa';
  13. grab_vcsa_s:array[1..length(grab_vcsa)] of char=grab_vcsa;
  14. var p:Pchar;
  15. child:Tpid;
  16. status:cint;
  17. pstat:stat;
  18. begin
  19. getmem(p,len+length(grab_vcsa)+1);
  20. move(path^,p^,len);
  21. move(grab_vcsa_s,(p+len)^,length(grab_vcsa));
  22. (p+len+length(grab_vcsa))^:=#0;
  23. {Check if file exists.}
  24. if fpstat(p,pstat)<>0 then
  25. begin
  26. try_grab_vcsa_in_path:=false;
  27. exit;
  28. end;
  29. child:=fpfork;
  30. if child=0 then
  31. begin
  32. fpexecve(p,nil,nil);
  33. halt(255); {fpexec must have failed...}
  34. end;
  35. fpwaitpid(child,status,0);
  36. try_grab_vcsa_in_path:=status=0; {Return true if success.}
  37. freemem(p);
  38. end;
  39. function try_grab_vcsa:boolean;
  40. {If we cannot open /dev/vcsa0-31 it usually because we do not have
  41. permission. At login the owner of the tty you login is set to yourself.
  42. This is not done for vcsa, which is kinda strange as vcsa is revoke from
  43. you when you log out. We try to call a setuid root helper which chowns
  44. the vcsa device so we can get access to the screen buffer...}
  45. var path,p:Pchar;
  46. begin
  47. try_grab_vcsa:=false;
  48. path:=fpgetenv('PATH');
  49. if path=nil then
  50. exit;
  51. p:=strscan(path,':');
  52. while p<>nil do
  53. begin
  54. if try_grab_vcsa_in_path(path,p-path) then
  55. begin
  56. try_grab_vcsa:=true;
  57. exit;
  58. end;
  59. path:=p+1;
  60. p:=strscan(path,':');
  61. end;
  62. if try_grab_vcsa_in_path(path,strlen(path)) then
  63. exit;
  64. end;
  65. procedure detect_linuxvcs;
  66. var f:text;
  67. c:char;
  68. pid,ppid,dummy:integer;
  69. device:longint;
  70. s:string[15];
  71. begin
  72. {Extremely aggressive VCSA detection. Works even through Midnight
  73. Commander. Idea from the C++ Turbo Vision project, credits go
  74. to Martynas Kunigelis <[email protected]>.}
  75. pid:=fpgetpid;
  76. repeat
  77. str(pid,s);
  78. assign(f,'/proc/'+s+'/stat');
  79. reset(f);
  80. if ioresult<>0 then
  81. break;
  82. read(f,dummy);
  83. read(f,c);
  84. repeat
  85. read(f,c);
  86. until c=' ';
  87. repeat
  88. read(f,c);
  89. until c=' ';
  90. ppid:=pid;
  91. read(f,pid);
  92. read(f,dummy);
  93. read(f,dummy);
  94. read(f,device);
  95. close(f);
  96. if device and $ffffffc0=$00000400 then {/dev/tty*}
  97. begin
  98. vcs_device:=device and $3f;
  99. break;
  100. end;
  101. until (device=0) {Not attached to a terminal, i.e. an xterm.}
  102. or (pid=-1)
  103. or (ppid=pid);
  104. end;
  105. begin
  106. {Put in procedure because there are quite a bit of variables which are made
  107. temporary this way.}
  108. detect_linuxvcs;
  109. end.