utmp.pp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. unit Utmp;
  2. interface
  3. uses
  4. BaseUnix,
  5. Unix;
  6. const
  7. Device_name_length = 12;
  8. Host_name_length = 245;
  9. User_name_length = 32;
  10. type
  11. tTime = Longint;
  12. tPid = Longint;
  13. tIP_Address = array[1..4] of Byte;
  14. tDevice_name = String[Device_name_length];
  15. tUser_name = String[User_name_length];
  16. tHost_name = String[Host_name_length];
  17. tLogin_type = (Unkown, Run_level, Boot_time, New_time, Old_time,
  18. Init_process, Login_process, User_process, Dead_process);
  19. tLogin_types = set of tLogin_type;
  20. tParameter_type = (Include, Exclude);
  21. tUser = packed record
  22. Type_of_login : tLogin_type;
  23. Pid : tPid;
  24. Device : tDevice_name;
  25. Tty_name : String[4];
  26. Login_time : tTime;
  27. User_name : tUser_name;
  28. Host_name : tHost_name;
  29. IP_Address : tIP_Address;
  30. end;
  31. pUser = ^tUser;
  32. Const
  33. DefaultLoginType : TLogin_Types = [User_Process];
  34. Login_type_names : array [TLogin_type] of string[20] =
  35. ('Unkown', 'Run level', 'Boot time','New time', 'Old time',
  36. 'Init process', 'Login process', 'User process', 'Dead process');
  37. All_Login_types : TLogin_types = [Unkown, Run_level, Boot_time, New_time, Old_time,
  38. Init_process, Login_process, User_process, Dead_process];
  39. procedure Read_logged_users;
  40. function Get_next_user : tUser;
  41. function Get_next_user(var Last : Boolean) : tUser;
  42. procedure Set_search_parameters(
  43. const Parameter_type : tParameter_type;
  44. Login_types : tLogin_types);
  45. procedure Reset_user_search;
  46. function More_users : Boolean;
  47. function Number_of_logged_users : Word;
  48. {Low level rutines}
  49. function Number_of_utmp_entries : Word;
  50. procedure Set_utmp_file(const File_name : String);
  51. type
  52. texitstatus = record
  53. e_termination,
  54. e_exit : integer;
  55. end;
  56. tLL_Utmp = record
  57. ut_type : integer;
  58. ut_pid : longint;
  59. ut_line : tdevice_name;
  60. ut_id : array[1..4] of char;
  61. ut_user : tuser_name;
  62. ut_host : thost_name;
  63. ut_exit : texitstatus;
  64. ut_session : longint;
  65. ut_tv : Array [1..2] of longint;
  66. ut_addr : Array[1..4] of longint;
  67. pad : array [1..48] of char
  68. end;
  69. pUser_list = ^tUser_list;
  70. tUser_list = record
  71. User : tUser;
  72. Next : pUser_list;
  73. end;
  74. implementation
  75. Type
  76. tSearch_parameters = record
  77. Type_of_login_types : tParameter_type;
  78. Login_types : tLogin_types;
  79. end;
  80. var
  81. User_list : pUser_list;
  82. Current_user : pUser_list;
  83. Utmp_file : String;
  84. Search_parameters : tSearch_parameters;
  85. procedure Set_search_parameters(
  86. const Parameter_type : tParameter_type;
  87. Login_types : tLogin_types);
  88. begin
  89. Search_parameters.Type_of_login_types := Parameter_type;
  90. Search_parameters.Login_types := Login_types;
  91. end;
  92. function More_users : Boolean;
  93. var
  94. UL : pUser_list;
  95. Last : Boolean;
  96. begin
  97. UL := Current_user;
  98. Last := True;
  99. while (UL <> nil) and Last do begin
  100. if Search_parameters.Type_of_login_types = Exclude then begin
  101. Last := (UL^.User.Type_of_login in Search_parameters.Login_types);
  102. end else begin
  103. Last := not (UL^.User.Type_of_login in Search_parameters.Login_types);
  104. end;
  105. UL := UL^.Next;
  106. end;
  107. More_users := not Last;
  108. end;
  109. function Number_of_logged_users : Word;
  110. var
  111. I : Word;
  112. UL: pUser_list;
  113. begin
  114. I := 0;
  115. UL := User_list;
  116. while UL <> nil do begin
  117. if UL^.User.Type_of_login = User_process then begin
  118. I := I + 1;
  119. end;
  120. UL := UL^.Next;
  121. end;
  122. Number_of_logged_users := I;
  123. end;
  124. function Get_next_user : tUser;
  125. var
  126. Found : Boolean;
  127. User : pUser;
  128. begin
  129. if Current_user <> nil then begin
  130. Found := False;
  131. while (Current_user <> nil) and not Found do begin
  132. User := @Current_user^.User;
  133. if Search_parameters.Type_of_login_types = Exclude then begin
  134. Found := not (User^.Type_of_login in Search_parameters.Login_types);
  135. end else begin
  136. Found := (User^.Type_of_login in Search_parameters.Login_types);
  137. end;
  138. Current_user := Current_user^.Next;
  139. end;
  140. if Found then begin
  141. Get_next_user := User^;
  142. end else begin
  143. New(User);
  144. FillChar(User^, SizeOf(tUser), 0);
  145. Get_next_user := User^;
  146. Dispose(User);
  147. end;
  148. end else begin
  149. New(User);
  150. FillChar(User^, SizeOf(tUser), 0);
  151. Get_next_user := User^;
  152. Dispose(User);
  153. end;
  154. end;
  155. function Get_next_user(var Last : Boolean) : tUser;
  156. var
  157. Found : Boolean;
  158. User : pUser;
  159. UL : pUser_list;
  160. begin
  161. if Current_user <> nil then begin
  162. Found := False;
  163. while (Current_user <> nil) and not Found do begin
  164. User := @Current_user^.User;
  165. if Search_parameters.Type_of_login_types = Exclude then begin
  166. Found := not (User^.Type_of_login in Search_parameters.Login_types);
  167. end else begin
  168. Found := (User^.Type_of_login in Search_parameters.Login_types);
  169. end;
  170. Current_user := Current_user^.Next;
  171. end;
  172. if Found then begin
  173. Get_next_user := User^;
  174. UL := Current_user;
  175. Last := True;
  176. while (UL <> nil) and Last do begin
  177. if Search_parameters.Type_of_login_types = Exclude then begin
  178. Last := (UL^.User.Type_of_login in Search_parameters.Login_types);
  179. end else begin
  180. Last := not (UL^.User.Type_of_login in Search_parameters.Login_types);
  181. end;
  182. UL := UL^.Next;
  183. end;
  184. end else begin
  185. New(User);
  186. FillChar(User^, SizeOf(tUser), 0);
  187. Get_next_user := User^;
  188. Dispose(User);
  189. end;
  190. end else begin
  191. New(User);
  192. FillChar(User^, SizeOf(tUser), 0);
  193. Get_next_user := User^;
  194. Dispose(User);
  195. end;
  196. end;
  197. procedure Reset_user_search;
  198. begin
  199. Current_user := User_list;
  200. end;
  201. procedure Set_utmp_file(const File_name : String);
  202. begin
  203. Utmp_file := File_name;
  204. end;
  205. function Number_of_utmp_entries : Word;
  206. var
  207. S : Stat;
  208. begin
  209. fpstat(Utmp_file, S);
  210. Number_of_utmp_entries := s.st_size div System.SizeOf(tLL_Utmp);
  211. end;
  212. procedure Read_logged_users;
  213. procedure Read_entry(var F : File; var Entry : tUser; var User : Boolean);
  214. var
  215. LL_Entry : tLL_Utmp;
  216. I : Byte;
  217. begin
  218. BlockRead(F, LL_Entry, SizeOf(tLL_Utmp));
  219. //Byte(Entry.Type_of_login) := LL_Entry.ut_type;
  220. Entry.Type_of_login := tLogin_type(LL_Entry.ut_type);
  221. Entry.Pid := Longint(LL_Entry.ut_id);
  222. Entry.Device:=LL_entry.ut_line;
  223. Entry.TTy_Name:=LL_Entry.ut_id;
  224. Entry.Login_time := LL_Entry.ut_tv[1];
  225. Entry.User_name:=LL_entry.ut_user;
  226. Entry.Host_name:=LL_entry.ut_host;
  227. For I:=1 to 4 do
  228. Entry.Ip_Address[I] := LL_Entry.ut_addr[i];
  229. end;
  230. var
  231. F : File;
  232. I : Longint;
  233. UL: pUser_list;
  234. U : Boolean;
  235. begin
  236. System.Assign(F, Utmp_file);
  237. {$IFOPT I+}
  238. {$DEFINE I_was_on}
  239. {$ENDIF}
  240. {$I-}
  241. System.Reset(F,1);
  242. {$IFDEF I_was_on}
  243. {$UNDEF I_was_on}
  244. {$I+}
  245. {$ENDIF}
  246. UL := User_list;
  247. while UL <> nil do begin
  248. User_list := UL;
  249. UL := UL^.Next;
  250. Dispose(User_list);
  251. end;
  252. User_list := nil;
  253. if System.IOResult = 0 then begin
  254. for I := 1 to Number_of_utmp_entries do begin
  255. if User_list = nil then begin
  256. New(User_list);
  257. UL := User_list;
  258. UL^.Next := nil;
  259. end else begin
  260. New(UL^.Next);
  261. UL := UL^.Next;
  262. UL^.Next := nil;
  263. end;
  264. Read_entry(F, UL^.User, U);
  265. end;
  266. UL^.Next := nil;
  267. end else begin
  268. User_list := nil;
  269. end;
  270. System.Close(F);
  271. Current_user := User_list;
  272. end;
  273. begin
  274. User_list := nil;
  275. Current_user := nil;
  276. Utmp_file := '/var/run/utmp';
  277. Set_search_parameters(Include,DefaultLoginType);
  278. end.