]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
login: utmp code refactoring
authorKarel Zak <kzak@redhat.com>
Fri, 26 Aug 2011 10:15:09 +0000 (12:15 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 26 Oct 2011 21:17:16 +0000 (23:17 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
configure.ac
login-utils/login.c

index 66d0794f577959183dd380214112ac27f8126d2b..0baff219264617b8be5cfbe5964cc8df5dd3ab21 100644 (file)
@@ -194,7 +194,6 @@ AC_CHECK_FUNCS(
        usleep \
        nanosleep \
        personality \
-       updwtmp \
        jrand48 \
        lchown \
        llseek \
index 91f5b815cfbe1897c0c6e5a2245b93da209dd3fe..c4f3d9cd0e74fbb76d6c5c4c81dbe27084972ba8 100644 (file)
@@ -289,9 +289,8 @@ static void logbtmp(struct login_context *cxt)
                        memcpy(&ut.ut_addr_v6, cxt->hostaddress,
                               sizeof(ut.ut_addr_v6));
        }
-#if HAVE_UPDWTMP               /* bad luck for ancient systems */
+
        updwtmp(_PATH_BTMP, &ut);
-#endif
 }
 
 static int child_pid = 0;
@@ -390,6 +389,81 @@ static void log_lastlog(struct login_context *cxt)
        close(fd);
 }
 
+/*
+ * Update wtmp and utmp logs
+ */
+static void log_utmp(struct login_context *cxt)
+{
+       struct utmp ut;
+       struct utmp *utp;
+       struct timeval tv;
+
+       utmpname(_PATH_UTMP);
+       setutent();
+
+       /* Find pid in utmp.
+        *
+        * login sometimes overwrites the runlevel entry in /var/run/utmp,
+        * confusing sysvinit. I added a test for the entry type, and the
+        * problem was gone. (In a runlevel entry, st_pid is not really a pid
+        * but some number calculated from the previous and current runlevel).
+        * -- Michael Riepe <michael@stud.uni-hannover.de>
+        */
+       while ((utp = getutent()))
+               if (utp->ut_pid == cxt->pid
+                   && utp->ut_type >= INIT_PROCESS
+                   && utp->ut_type <= DEAD_PROCESS)
+                       break;
+
+       /* If we can't find a pre-existing entry by pid, try by line.
+        * BSD network daemons may rely on this.
+        */
+       if (utp == NULL) {
+               setutent();
+               ut.ut_type = LOGIN_PROCESS;
+               strncpy(ut.ut_line, cxt->tty_name, sizeof(ut.ut_line));
+               utp = getutline(&ut);
+       }
+
+       if (utp)
+               memcpy(&ut, utp, sizeof(ut));
+       else
+               /* some gettys/telnetds don't initialize utmp... */
+               memset(&ut, 0, sizeof(ut));
+
+       if (ut.ut_id[0] == 0)
+               strncpy(ut.ut_id, cxt->tty_number, sizeof(ut.ut_id));
+
+       strncpy(ut.ut_user, cxt->username, sizeof(ut.ut_user));
+       xstrncpy(ut.ut_line, cxt->tty_name, sizeof(ut.ut_line));
+
+#ifdef _HAVE_UT_TV             /* in <utmpbits.h> included by <utmp.h> */
+       gettimeofday(&tv, NULL);
+       ut.ut_tv.tv_sec = tv.tv_sec;
+       ut.ut_tv.tv_usec = tv.tv_usec;
+#else
+       {
+               time_t t;
+               time(&t);
+               ut.ut_time = t; /* ut_time is not always a time_t */
+                               /* glibc2 #defines it as ut_tv.tv_sec */
+       }
+#endif
+       ut.ut_type = USER_PROCESS;
+       ut.ut_pid = cxt->pid;
+       if (cxt->hostname) {
+               xstrncpy(ut.ut_host, cxt->hostname, sizeof(ut.ut_host));
+               if (cxt->hostaddress && *cxt->hostaddress)
+                       memcpy(&ut.ut_addr_v6, cxt->hostaddress,
+                              sizeof(ut.ut_addr_v6));
+       }
+
+       pututline(&ut);
+       endutent();
+
+       updwtmp(_PATH_WTMP, &ut);
+}
+
 /* encapsulate stupid "void **" pam_get_item() API */
 static int loginpam_get_username(pam_handle_t * pamh, char **name)
 {
@@ -772,97 +846,7 @@ int main(int argc, char **argv)
                }
        }
 
-       /* for linux, write entries in utmp and wtmp */
-       {
-               struct utmp ut;
-               struct utmp *utp;
-               struct timeval tv;
-
-               utmpname(_PATH_UTMP);
-               setutent();
-
-               /* Find pid in utmp.
-                  login sometimes overwrites the runlevel entry in /var/run/utmp,
-                  confusing sysvinit. I added a test for the entry type, and the problem
-                  was gone. (In a runlevel entry, st_pid is not really a pid but some number
-                  calculated from the previous and current runlevel).
-                  Michael Riepe <michael@stud.uni-hannover.de>
-                */
-               while ((utp = getutent()))
-                       if (utp->ut_pid == cxt.pid
-                           && utp->ut_type >= INIT_PROCESS
-                           && utp->ut_type <= DEAD_PROCESS)
-                               break;
-
-               /* If we can't find a pre-existing entry by pid, try by line.
-                  BSD network daemons may rely on this. (anonymous) */
-               if (utp == NULL) {
-                       setutent();
-                       ut.ut_type = LOGIN_PROCESS;
-                       strncpy(ut.ut_line, cxt.tty_name, sizeof(ut.ut_line));
-                       utp = getutline(&ut);
-               }
-
-               if (utp) {
-                       memcpy(&ut, utp, sizeof(ut));
-               } else {
-                       /* some gettys/telnetds don't initialize utmp... */
-                       memset(&ut, 0, sizeof(ut));
-               }
-
-               if (ut.ut_id[0] == 0)
-                       strncpy(ut.ut_id, cxt.tty_number, sizeof(ut.ut_id));
-
-               strncpy(ut.ut_user, cxt.username, sizeof(ut.ut_user));
-               xstrncpy(ut.ut_line, cxt.tty_name, sizeof(ut.ut_line));
-#ifdef _HAVE_UT_TV             /* in <utmpbits.h> included by <utmp.h> */
-               gettimeofday(&tv, NULL);
-               ut.ut_tv.tv_sec = tv.tv_sec;
-               ut.ut_tv.tv_usec = tv.tv_usec;
-#else
-               {
-                       time_t t;
-                       time(&t);
-                       ut.ut_time = t; /* ut_time is not always a time_t */
-                       /* glibc2 #defines it as ut_tv.tv_sec */
-               }
-#endif
-               ut.ut_type = USER_PROCESS;
-               ut.ut_pid = cxt.pid;
-               if (cxt.hostname) {
-                       xstrncpy(ut.ut_host, cxt.hostname, sizeof(ut.ut_host));
-                       if (cxt.hostaddress[0])
-                               memcpy(&ut.ut_addr_v6, cxt.hostaddress,
-                                      sizeof(ut.ut_addr_v6));
-               }
-
-               pututline(&ut);
-               endutent();
-
-#if HAVE_UPDWTMP
-               updwtmp(_PATH_WTMP, &ut);
-#else
-               /* Probably all this locking below is just nonsense,
-                  and the short version is OK as well. */
-               {
-                       int lf, wtmp;
-                       if ((lf =
-                            open(_PATH_WTMPLOCK, O_CREAT | O_WRONLY,
-                                 0660)) >= 0) {
-                               flock(lf, LOCK_EX);
-                               if ((wtmp =
-                                    open(_PATH_WTMP,
-                                         O_APPEND | O_WRONLY)) >= 0) {
-                                       write(wtmp, (char *)&ut, sizeof(ut));
-                                       close(wtmp);
-                               }
-                               flock(lf, LOCK_UN);
-                               close(lf);
-                       }
-               }
-#endif
-       }
-
+       log_utmp(&cxt);
        log_audit(&cxt, pwd, 1);
        log_lastlog(&cxt);