@@ -283,6 +283,11 @@ s! {
283283 pub msg_len: :: c_uint,
284284 }
285285
286+ pub struct __exit_status {
287+ pub e_termination: u16 ,
288+ pub e_exit: u16 ,
289+ }
290+
286291 pub struct shmid_ds {
287292 pub shm_perm: :: ipc_perm,
288293 pub shm_segsz: :: size_t,
@@ -297,6 +302,28 @@ s! {
297302}
298303
299304s_no_extra_traits ! {
305+
306+ pub struct utmpx {
307+ pub ut_name: [ :: c_char; _UTX_USERSIZE] ,
308+ pub ut_id: [ :: c_char; _UTX_IDSIZE] ,
309+ pub ut_line: [ :: c_char; _UTX_LINESIZE] ,
310+ pub ut_host: [ :: c_char; _UTX_HOSTSIZE] ,
311+ pub ut_session: u16 ,
312+ pub ut_type: u16 ,
313+ pub ut_pid: :: pid_t,
314+ pub ut_exit: __exit_status,
315+ pub ut_ss: sockaddr_storage,
316+ pub ut_tv: :: timeval,
317+ pub ut_pad: [ u8 ; _UTX_PADSIZE] ,
318+ }
319+
320+ pub struct lastlogx {
321+ pub ll_tv: :: timeval,
322+ pub ll_line: [ :: c_char; _UTX_LINESIZE] ,
323+ pub ll_host: [ :: c_char; _UTX_HOSTSIZE] ,
324+ pub ll_ss: sockaddr_storage,
325+ }
326+
300327 pub struct in_pktinfo {
301328 pub ipi_addr: :: in_addr,
302329 pub ipi_ifindex: :: c_uint,
@@ -390,6 +417,101 @@ s_no_extra_traits! {
390417
391418cfg_if ! {
392419 if #[ cfg( feature = "extra_traits" ) ] {
420+ impl PartialEq for utmpx {
421+ fn eq( & self , other: & utmpx) -> bool {
422+ self . ut_type == other. ut_type
423+ && self . ut_pid == other. ut_pid
424+ && self . ut_name == other. ut_name
425+ && self . ut_line == other. ut_line
426+ && self . ut_id == other. ut_id
427+ && self . ut_exit == other. ut_exit
428+ && self . ut_session == other. ut_session
429+ && self . ut_tv == other. ut_tv
430+ && self . ut_ss == other. ut_ss
431+ && self
432+ . ut_pad
433+ . iter( )
434+ . zip( other. ut_pad. iter( ) )
435+ . all( |( a, b) | a == b)
436+ && self
437+ . ut_host
438+ . iter( )
439+ . zip( other. ut_host. iter( ) )
440+ . all( |( a, b) | a == b)
441+ }
442+ }
443+
444+ impl Eq for utmpx { }
445+
446+ impl :: fmt:: Debug for utmpx {
447+ fn fmt( & self , f: & mut :: fmt:: Formatter ) -> :: fmt:: Result {
448+ f. debug_struct( "utmpx" )
449+ . field( "ut_name" , & self . ut_name)
450+ . field( "ut_id" , & self . ut_id)
451+ . field( "ut_line" , & self . ut_line)
452+ // FIXME .field("ut_host", &self.ut_host)
453+ . field( "ut_session" , & self . ut_session)
454+ . field( "ut_type" , & self . ut_type)
455+ . field( "ut_pid" , & self . ut_pid)
456+ . field( "ut_exit" , & self . ut_exit)
457+ . field( "ut_ss" , & self . ut_ss)
458+ . field( "ut_tv" , & self . ut_tv)
459+ // FIXME .field("ut_pad", &self.ut_pad)
460+ . finish( )
461+ }
462+ }
463+
464+ impl :: hash:: Hash for utmpx {
465+ fn hash<H : :: hash:: Hasher >( & self , state: & mut H ) {
466+ self . ut_name. hash( state) ;
467+ self . ut_type. hash( state) ;
468+ self . ut_pid. hash( state) ;
469+ self . ut_line. hash( state) ;
470+ self . ut_id. hash( state) ;
471+ self . ut_host. hash( state) ;
472+ self . ut_exit. hash( state) ;
473+ self . ut_session. hash( state) ;
474+ self . ut_tv. hash( state) ;
475+ self . ut_ss. hash( state) ;
476+ self . ut_pad. hash( state) ;
477+ }
478+ }
479+
480+ impl PartialEq for lastlogx {
481+ fn eq( & self , other: & lastlogx) -> bool {
482+ self . ll_tv == other. ll_tv
483+ && self . ll_line == other. ll_line
484+ && self . ll_ss == other. ll_ss
485+ && self
486+ . ll_host
487+ . iter( )
488+ . zip( other. ll_host. iter( ) )
489+ . all( |( a, b) | a == b)
490+ }
491+ }
492+
493+ impl Eq for lastlogx { }
494+
495+ impl :: fmt:: Debug for lastlogx {
496+ fn fmt( & self , f: & mut :: fmt:: Formatter ) -> :: fmt:: Result {
497+ f. debug_struct( "lastlogx" )
498+ . field( "ll_tv" , & self . ll_tv)
499+ . field( "ll_line" , & self . ll_line)
500+ // FIXME.field("ll_host", &self.ll_host)
501+ . field( "ll_ss" , & self . ll_ss)
502+ . finish( )
503+ }
504+ }
505+
506+ impl :: hash:: Hash for lastlogx {
507+ fn hash<H : :: hash:: Hasher >( & self , state: & mut H ) {
508+ self . ll_tv. hash( state) ;
509+ self . ll_line. hash( state) ;
510+ self . ll_host. hash( state) ;
511+ self . ll_ss. hash( state) ;
512+ }
513+ }
514+
393515 impl PartialEq for in_pktinfo {
394516 fn eq( & self , other: & in_pktinfo) -> bool {
395517 self . ipi_addr == other. ipi_addr
@@ -1391,6 +1513,28 @@ pub const ONLRET: ::tcflag_t = 0x40;
13911513pub const CDTRCTS : :: tcflag_t = 0x00020000 ;
13921514pub const CHWFLOW : :: tcflag_t = :: MDMBUF | :: CRTSCTS | :: CDTRCTS ;
13931515
1516+ // pub const _PATH_UTMPX: &[::c_char; 14] = b"/var/run/utmpx";
1517+ // pub const _PATH_WTMPX: &[::c_char; 14] = b"/var/log/wtmpx";
1518+ // pub const _PATH_LASTLOGX: &[::c_char; 17] = b"/var/log/lastlogx";
1519+ // pub const _PATH_UTMP_UPDATE: &[::c_char; 24] = b"/usr/libexec/utmp_update";
1520+ pub const _UTX_USERSIZE: usize = 32 ;
1521+ pub const _UTX_LINESIZE: usize = 32 ;
1522+ pub const _UTX_PADSIZE: usize = 40 ;
1523+ pub const _UTX_IDSIZE: usize = 4 ;
1524+ pub const _UTX_HOSTSIZE: usize = 256 ;
1525+ pub const EMPTY : u16 = 0 ;
1526+ pub const RUN_LVL : u16 = 1 ;
1527+ pub const BOOT_TIME : u16 = 2 ;
1528+ pub const OLD_TIME : u16 = 3 ;
1529+ pub const NEW_TIME : u16 = 4 ;
1530+ pub const INIT_PROCESS : u16 = 5 ;
1531+ pub const LOGIN_PROCESS : u16 = 6 ;
1532+ pub const USER_PROCESS : u16 = 7 ;
1533+ pub const DEAD_PROCESS : u16 = 8 ;
1534+ pub const ACCOUNTING : u16 = 9 ;
1535+ pub const SIGNATURE : u16 = 10 ;
1536+ pub const DOWN_TIME : u16 = 11 ;
1537+
13941538pub const SOCK_CLOEXEC : :: c_int = 0x10000000 ;
13951539pub const SOCK_NONBLOCK : :: c_int = 0x20000000 ;
13961540
@@ -1751,6 +1895,28 @@ extern "C" {
17511895 buflen : :: size_t ,
17521896 result : * mut * mut :: group ,
17531897 ) -> :: c_int ;
1898+
1899+ pub fn updwtmpx ( file : * const :: c_char , ut : * const utmpx ) -> :: c_int ;
1900+ pub fn getlastlogx (
1901+ fname : * const :: c_char ,
1902+ uid : :: uid_t ,
1903+ ll : * mut lastlogx ,
1904+ ) -> * mut lastlogx ;
1905+ pub fn updlastlogx (
1906+ fname : * const :: c_char ,
1907+ uid : :: uid_t ,
1908+ ll : * mut lastlogx ,
1909+ ) -> :: c_int ;
1910+ pub fn utmpxname ( file : * const :: c_char ) -> :: c_int ;
1911+ pub fn getutxent ( ) -> * mut utmpx ;
1912+ pub fn getutxid ( ut : * const utmpx ) -> * mut utmpx ;
1913+ pub fn getutxline ( ut : * const utmpx ) -> * mut utmpx ;
1914+ pub fn pututxline ( ut : * const utmpx ) -> * mut utmpx ;
1915+ pub fn setutxent ( ) ;
1916+ pub fn endutxent ( ) ;
1917+ // TODO: uncomment after utmp implementation
1918+ // pub fn getutmp(ux: *const utmpx, u: *mut utmp);
1919+ // pub fn getutmpx(u: *const utmp, ux: *mut utmpx);
17541920}
17551921
17561922cfg_if ! {
0 commit comments