login.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include <errno.h>
  2. #include <limits.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <stdlib.h>
  6. #include <utmp.h>
  7. /* Write the given entry into utmp and wtmp.
  8. * Note: the match in utmp is done against ut_id field,
  9. * which is NOT set by this function - caller must set it.
  10. */
  11. void login(const struct utmp *entry)
  12. {
  13. struct utmp copy;
  14. char tty_name[sizeof(copy.ut_line) + 6];
  15. int fd;
  16. // Manpage:
  17. // login() takes the argument ut struct, fills the field ut->ut_type
  18. // (if there is such a field) with the value USER_PROCESS,
  19. // and fills the field ut->ut_pid (if there is such a field)
  20. // with the process ID of the calling process.
  21. copy = *entry;
  22. #if _HAVE_UT_TYPE - 0
  23. copy.ut_type = USER_PROCESS;
  24. #endif
  25. #if _HAVE_UT_PID - 0
  26. copy.ut_pid = getpid();
  27. #endif
  28. // Then it tries to fill the field ut->ut_line. It takes the first of stdin,
  29. // stdout, stderr that is a tty, and stores the corresponding pathname minus
  30. // a possible leading /dev/ into this field, and then writes the struct
  31. // to the utmp file. On the other hand, if no tty name was found,
  32. // this field is filled with "???" and the struct is not written
  33. // to the utmp file.
  34. fd = 0;
  35. while (fd != 3 && ttyname_r(fd, tty_name, sizeof(tty_name)) != 0)
  36. fd++;
  37. if (fd != 3) {
  38. if (strncmp(tty_name, "/dev/", 5) == 0)
  39. strncpy(copy.ut_line, tty_name + 5, sizeof(copy.ut_line)-1);
  40. else
  41. strncpy(copy.ut_line, tty_name, sizeof(copy.ut_line)-1);
  42. copy.ut_line[sizeof(copy.ut_line)-1] = '\0';
  43. /* utmpname(_PATH_UTMP); - why?
  44. * this makes it impossible for caller to use other file!
  45. * Does any standard or historical precedent says this must be done? */
  46. setutent();
  47. /* Replaces record with matching ut_id, or appends new one: */
  48. pututline(&copy);
  49. endutent();
  50. } else {
  51. strncpy(copy.ut_line, "???", sizeof(copy.ut_line));
  52. }
  53. // After this, the struct is written to the wtmp file.
  54. updwtmp(_PATH_WTMP, &copy);
  55. }