#include <unistd.h>
#include <time.h>
-#if HAVE_STRUCT_UTMP
-static int write_bsd_utmp (int utmp_pos, struct utmp *wu);
-static void update_wtmp (const char *fname, const struct utmp *putmp);
-#endif
-
-static void update_lastlog (const char *fname, const char *pty, const char *host);
-
/*
* BSD style utmp entry
* ut_line, ut_name, ut_host, ut_time
* ut_user, ut_id, ut_line, ut_pid, ut_type, ut_exit, ut_time
*/
+/* ------------------------------------------------------------------------- */
+/*
+ * Write a BSD style utmp entry
+ */
+#if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID)
+static int
+write_bsd_utmp (int utmp_pos, struct utmp *wu)
+{
+ int fd;
+
+ if (utmp_pos <= 0 || (fd = open (UTMP_FILE, O_WRONLY)) == -1)
+ return 0;
+
+ if (lseek (fd, (off_t) (utmp_pos * sizeof (struct utmp)), SEEK_SET) != -1)
+ write (fd, wu, sizeof (struct utmp));
+ close (fd);
+ return 1;
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+/*
+ * Update a BSD style wtmp entry
+ */
+#if defined(WTMP_SUPPORT) && !defined(HAVE_UPDWTMP) && defined(HAVE_STRUCT_UTMP)
+static void
+update_wtmp (const char *fname, const struct utmp *putmp)
+{
+ int fd, gotlock, retry;
+ struct flock lck; /* fcntl locking scheme */
+ struct stat sbuf;
+
+ if ((fd = open (fname, O_WRONLY | O_APPEND, 0)) < 0)
+ return;
+
+ lck.l_whence = SEEK_END; /* start lock at current eof */
+ lck.l_len = 0; /* end at ``largest possible eof'' */
+ lck.l_start = 0;
+ lck.l_type = F_WRLCK; /* we want a write lock */
+
+ /* attempt lock with F_SETLK; F_SETLKW would cause a deadlock! */
+ for (retry = 10, gotlock = 0; retry--;)
+ if (fcntl (fd, F_SETLK, &lck) != -1)
+ {
+ gotlock = 1;
+ break;
+ }
+ else if (errno != EAGAIN && errno != EACCES)
+ break;
+ if (!gotlock)
+ { /* give it up */
+ close (fd);
+ return;
+ }
+ if (fstat (fd, &sbuf) == 0)
+ if (write (fd, putmp, sizeof (struct utmp)) != sizeof (struct utmp))
+ ftruncate (fd, sbuf.st_size); /* remove bad writes */
+
+ lck.l_type = F_UNLCK; /* unlocking the file */
+ fcntl (fd, F_SETLK, &lck);
+ close (fd);
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+#ifdef LASTLOG_SUPPORT
+static void
+update_lastlog (const char *fname, const char *pty, const char *host)
+{
+# if defined(HAVE_STRUCT_LASTLOGX) && defined(HAVE_UPDLASTLOGX)
+ struct lastlogx llx;
+# endif
+# ifdef HAVE_STRUCT_LASTLOG
+ int fd;
+ struct lastlog ll;
+ char lastlogfile[256];
+ struct passwd *pwent;
+ struct stat st;
+# endif
+
+# if defined(HAVE_STRUCT_LASTLOGX) && defined(HAVE_UPDLASTLOGX)
+ memset (&llx, 0, sizeof (llx));
+ llx.ll_tv.tv_sec = time (NULL);
+ llx.ll_tv.tv_usec = 0;
+ strncpy (llx.ll_line, pty, sizeof (llx.ll_line));
+ strncpy (llx.ll_host, host, sizeof (llx.ll_host));
+ updlastlogx (LASTLOGX_FILE, getuid (), &llx);
+# endif
+
+# ifdef HAVE_STRUCT_LASTLOG
+ pwent = getpwuid (getuid ());
+ if (!pwent)
+ {
+ ptytty_warn ("no entry in password file, not updating lastlog.\n", 0);
+ return;
+ }
+
+ memset (&ll, 0, sizeof (ll));
+ ll.ll_time = time (NULL);
+ strncpy (ll.ll_line, pty, sizeof (ll.ll_line));
+ strncpy (ll.ll_host, host, sizeof (ll.ll_host));
+ if (stat (fname, &st) != 0)
+ return;
+ if (S_ISDIR (st.st_mode))
+ {
+ sprintf (lastlogfile, "%.*s/%.*s",
+ sizeof (lastlogfile) - sizeof (pwent->pw_name) - 2, fname,
+ sizeof (pwent->pw_name),
+ (!pwent->pw_name || pwent->pw_name[0] == '\0') ? "unknown"
+ : pwent->pw_name);
+ if ((fd = open (lastlogfile, O_WRONLY | O_CREAT, 0644)) >= 0)
+ {
+ write (fd, &ll, sizeof (ll));
+ close (fd);
+ }
+ }
+ else if (S_ISREG (st.st_mode))
+ if ((fd = open (fname, O_RDWR)) != -1)
+ {
+ if (lseek (fd, (off_t) ((long)pwent->pw_uid * sizeof (ll)),
+ SEEK_SET) != -1)
+ write (fd, &ll, sizeof (ll));
+ close (fd);
+ }
+# endif /* HAVE_STRUCT_LASTLOG */
+}
+#endif /* LASTLOG_SUPPORT */
+
/* ------------------------------------------------------------------------- */
/*
#if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID)
{
-# ifdef HAVE_TTYSLOT
+# if 1
int fdstdin = dup (STDIN_FILENO);
dup2 (tty, STDIN_FILENO);
dup2 (fdstdin, STDIN_FILENO);
close (fdstdin);
-# else
- FILE *fd0;
-
- if ((fd0 = fopen (TTYTAB_FILENAME, "r")) != NULL)
- {
- char buf[256], name[256];
-
- buf[sizeof (buf) - 1] = '\0';
- for (i = 1; (fgets (buf, sizeof (buf) - 1, fd0) != NULL);)
- {
- if (*buf == '#' || sscanf (buf, "%s", name) != 1)
- continue;
- if (!strcmp (ut->ut_line, name))
- {
- if (!write_bsd_utmp (i, ut))
- i = 0;
- utmp_pos = i;
- fclose (fd0);
- break;
- }
- i++;
- }
- fclose (fd0);
- }
# endif
}
#endif
cmd_pid = 0;
}
-/* ------------------------------------------------------------------------- */
-/*
- * Write a BSD style utmp entry
- */
-#if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID)
-static int
-write_bsd_utmp (int utmp_pos, struct utmp *wu)
-{
- int fd;
-
- if (utmp_pos <= 0 || (fd = open (UTMP_FILE, O_WRONLY)) == -1)
- return 0;
-
- if (lseek (fd, (off_t) (utmp_pos * sizeof (struct utmp)), SEEK_SET) != -1)
- write (fd, wu, sizeof (struct utmp));
- close (fd);
- return 1;
-}
-#endif
-
-/* ------------------------------------------------------------------------- */
-/*
- * Update a BSD style wtmp entry
- */
-#if defined(WTMP_SUPPORT) && !defined(HAVE_UPDWTMP) && defined(HAVE_STRUCT_UTMP)
-static void
-update_wtmp (const char *fname, const struct utmp *putmp)
-{
- int fd, gotlock, retry;
- struct flock lck; /* fcntl locking scheme */
- struct stat sbuf;
-
- if ((fd = open (fname, O_WRONLY | O_APPEND, 0)) < 0)
- return;
-
- lck.l_whence = SEEK_END; /* start lock at current eof */
- lck.l_len = 0; /* end at ``largest possible eof'' */
- lck.l_start = 0;
- lck.l_type = F_WRLCK; /* we want a write lock */
-
- /* attempt lock with F_SETLK; F_SETLKW would cause a deadlock! */
- for (retry = 10, gotlock = 0; retry--;)
- if (fcntl (fd, F_SETLK, &lck) != -1)
- {
- gotlock = 1;
- break;
- }
- else if (errno != EAGAIN && errno != EACCES)
- break;
- if (!gotlock)
- { /* give it up */
- close (fd);
- return;
- }
- if (fstat (fd, &sbuf) == 0)
- if (write (fd, putmp, sizeof (struct utmp)) != sizeof (struct utmp))
- ftruncate (fd, sbuf.st_size); /* remove bad writes */
-
- lck.l_type = F_UNLCK; /* unlocking the file */
- fcntl (fd, F_SETLK, &lck);
- close (fd);
-}
-#endif
-
-/* ------------------------------------------------------------------------- */
-#ifdef LASTLOG_SUPPORT
-static void
-update_lastlog (const char *fname, const char *pty, const char *host)
-{
-# ifdef HAVE_STRUCT_LASTLOGX
- struct lastlogx llx;
-# endif
-# ifdef HAVE_STRUCT_LASTLOG
- int fd;
- struct lastlog ll;
-# ifdef LASTLOG_IS_DIR
- char lastlogfile[256];
-# endif
- struct passwd *pwent;
-# endif
-
-# ifdef HAVE_STRUCT_LASTLOGX
- memset (&llx, 0, sizeof (llx));
- llx.ll_tv.tv_sec = time (NULL);
- llx.ll_tv.tv_usec = 0;
- strncpy (llx.ll_line, pty, sizeof (llx.ll_line));
- strncpy (llx.ll_host, host, sizeof (llx.ll_host));
- updlastlogx (LASTLOGX_FILE, getuid (), &llx);
-# endif
-
-# ifdef HAVE_STRUCT_LASTLOG
- pwent = getpwuid (getuid ());
- if (!pwent)
- {
- ptytty_warn ("no entry in password file, not updating lastlog.\n", 0);
- return;
- }
-
- memset (&ll, 0, sizeof (ll));
- ll.ll_time = time (NULL);
- strncpy (ll.ll_line, pty, sizeof (ll.ll_line));
- strncpy (ll.ll_host, host, sizeof (ll.ll_host));
-# ifdef LASTLOG_IS_DIR
- sprintf (lastlogfile, "%.*s/%.*s",
- sizeof (lastlogfile) - sizeof (pwent->pw_name) - 2, fname,
- sizeof (pwent->pw_name),
- (!pwent->pw_name || pwent->pw_name[0] == '\0') ? "unknown"
- : pwent->pw_name);
- if ((fd = open (lastlogfile, O_WRONLY | O_CREAT, 0644)) >= 0)
- {
- write (fd, &ll, sizeof (ll));
- close (fd);
- }
-# else
- if ((fd = open (fname, O_RDWR)) != -1)
- {
- if (lseek (fd, (off_t) ((long)pwent->pw_uid * sizeof (ll)),
- SEEK_SET) != -1)
- write (fd, &ll, sizeof (ll));
- close (fd);
- }
-# endif /* LASTLOG_IS_DIR */
-# endif /* HAVE_STRUCT_LASTLOG */
-}
-#endif /* LASTLOG_SUPPORT */
-
#else
void
ptytty_unix::login (int cmd_pid, bool login_shell, const char *hostname)