logged in or logged out?

I have wrote a service with c++ which is always run and now I want to get with it the exact time in that the user log in or log out and then run a script. but the problem is that how could i find that the user logged in or logged out with out checking something frequently?
thanks

you can use wtmp & utmp / implementation of who.

thanks, but i think this can't be useful.i think i did not describe the problem correctly. the service should do an action when user logged in and another when user logged out.

the service has to send a message to a server and one part of the message is that if any body logged in or out.

Running the moral equivalent of tail -f on wtmp will block until the file is written to with a new record, so it might fit your needs after all.

See also http://groups.google.com/group/comp.unix.shell/browse_thread/thread/b5b13d0044b81e72/1c3d5311b1fec584?hl=en&lnk=st\#1c3d5311b1fec584

sorry! but I think the program again has to always wait for a change

The read() blocks when no data is available. The sleep(1) happens when no data is available; you can adjust for how long it sleeps before it tries again, obviously. But this is admittedly a workaround. I don't think there is a platform-independent way to trigger on log-in or log-out events. If you have dbus or similar, maybe that has the facility you are looking for.

There are many ways to do this, but none of them is simple (I guess).

  1. Try creating linked lists (if you want to store many things) or an array which you can search easily from a certain entry.
  2. Then, there are many ways of seeing who's online:
    2.1 You can check the activity of terminals in /dev (but that won't do for nasty users who detach their backdoor/exploit from the terminal)
    2.2 You can have something more accurate by continually reading /proc and having an active list of which users are running at least ONE program (pushing and pop'ing to/from the array/linked lists) -- will mess with cron, phpsuexec, suphp, suexec, and any other program that runs with the user's UID (false positives)
    2.3 You can #include <utmp.h>, and use the utmp struct which holds everything you need:
           struct utmp {
               short ut_type;              /* type of login */
               pid_t ut_pid;               /* PID of login process */
               char ut_line[UT_LINESIZE];  /* device name of tty - "/dev/" */
               char ut_id[4];              /* init id or abbrev. ttyname */
               char ut_user[UT_NAMESIZE];  /* user name */
               char ut_host[UT_HOSTSIZE];  /* hostname for remote login */
               struct exit_status ut_exit; /* The exit status of a process
                                              marked as DEAD_PROCESS */

               /* The ut_session and ut_tv fields must be the same size when
                  compiled 32- and 64-bit.  This allows data files and shared
                  memory to be shared between 32- and 64-bit applications */
           #if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
               int32_t ut_session;         /* Session ID, used for windowing */
               struct {
                   int32_t tv_sec;         /* Seconds */
                   int32_t tv_usec;        /* Microseconds */
               } ut_tv;                    /* Time entry was made */
           #else
                long int ut_session;       /* Session ID, used for windowing */
                struct timeval ut_tv;      /* Time entry was made */
           #endif

               int32_t ut_addr_v6[4];      /* IP address of remote host */
               char __unused[20];          /* Reserved for future use */
           };

then you can use functions like getutent() (see the man file). NOTE that you still have to run this very often to see who got in and out by comparing results.

Don't forget that utmp is not the safest way to go because many programs just don't use it. (specially malicious programs)

If I understand correctly, short of changing the behavior of init, which is a terrible idea, you should consider finding a way to implement change notify - like inotify in Linux, on an accounting file - other posters mentioned those files. init DOES in fact write to those files on login and logout. Based on your comments it does not seem to me that you are aware of init behavior or you would already be aimed in that direction....

I didn't see your OS mentioned. inotify is Linux- only kernel 2.6.13 and higher.

i'm very interesting with this threads, because i have learned about utmp but i found only a little.... I can't make the code that can read the utmp file, would you like to show me how to make program that can read the utmp file or use getutent() function?

thanx