📄 logging.c
字号:
/*--------------------------------*-C-*---------------------------------* * File: logging.c *----------------------------------------------------------------------* * * All portions of code are copyright by their respective author/s. * Copyright (c) 1992 John Bovey <jdb@ukc.ac.uk> * Copyright (c) 1993 lipka * Copyright (c) 1993 Brian Stempien <stempien@cs.wmich.edu> * Copyright (c) 1995 Raul Garcia Garcia <rgg@tid.es> * Copyright (c) 1995 Piet W. Plomp <piet@idefix.icce.rug.nl> * Copyright (c) 1997 Raul Garcia Garcia <rgg@tid.es> * Copyright (c) 1998-2001 Geoff Wing <gcw@pobox.com> * Copyright (c) 1999 D J Hawkey Jr <hawkeyd@visi.com> * Copyright (c) 2004 Jingmin Zhou <jimmyzhou@users.sourceforge.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------------*/#include "../config.h"#include "rxvt.h"#ifdef UTMP_SUPPORT# if defined(HAVE_UPDWTMP) && defined(OS_SOLARIS)void updwtmp(char *wfile, struct utmp *utmp);# endif# if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) && defined(OS_SOLARIS)void updwtmpx(char *wfile, struct utmpx *utmp);# endif/*--------------------------------------------------------------------* * BEGIN `INTERNAL' ROUTINE PROTOTYPES * *--------------------------------------------------------------------*/#ifdef HAVE_UTMP_H# ifndef UTEMPTER_SUPPORTint rxvt_write_bsd_utmp (int utmp_pos, struct utmp* wu);# endif#endif#if defined(WTMP_SUPPORT) && !defined(HAVE_UPDWTMP)# ifndef UTEMPTER_SUPPORTvoid rxvt_update_wtmp (const char *fname, const struct utmp *putmp);# endif#endif#ifdef LASTLOG_SUPPORTvoid rxvt_update_lastlog (const char *fname, const char *pty, const char *host);#endif/*--------------------------------------------------------------------* * END `INTERNAL' ROUTINE PROTOTYPES * *--------------------------------------------------------------------*//* * BSD style utmp entry * ut_line, ut_name, ut_host, ut_time * SYSV style utmp (and utmpx) entry * ut_user, ut_id, ut_line, ut_pid, ut_type, ut_exit, ut_time *//* ------------------------------------------------------------------------- *//* * make and write utmp and wtmp entries *//* EXTPROTO */voidrxvt_makeutent(rxvt_t *r, int page, const char *pty, const char *hostname){#ifdef UTEMPTER_SUPPORT utempter_add_record (PVTS(r, page)->cmd_fd, hostname);#else /* UTEMPTER_SUPPORT */#ifdef HAVE_STRUCT_UTMP struct utmp *ut = &(PVTS(r, page)->ut);#endif#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) struct utmpx *utx = &(PVTS(r, page)->utx);#endif#ifdef HAVE_UTMP_PID int i;#endif char ut_id[5]; struct passwd *pwent = getpwuid(getuid()); if (!STRNCMP(pty, "/dev/", 5)) pty += 5; /* skip /dev/ prefix */ if (!STRNCMP(pty, "pty", 3) || !STRNCMP(pty, "tty", 3)) { STRNCPY(ut_id, (pty + 3), sizeof(ut_id)); }#ifdef HAVE_UTMP_PID else if (sscanf(pty, "pts/%d", &i) == 1) sprintf(ut_id, "vt%02x", (i & 0xff)); /* sysv naming */#endif else if (STRNCMP(pty, "pty", 3) && STRNCMP(pty, "tty", 3)) { rxvt_msg (DBG_ERROR, DBG_LOGGING, "can't parse tty name \"%s\"", pty); return; }#ifdef HAVE_STRUCT_UTMP MEMSET(ut, 0, sizeof(struct utmp));# ifdef HAVE_UTMP_PID setutent(); STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id)); ut->ut_type = DEAD_PROCESS; getutid(ut); /* position to entry in utmp file */ STRNCPY(PVTS(r, page)->ut_id, ut_id, sizeof(PVTS(r, page)->ut_id));# endif#endif#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) MEMSET(utx, 0, sizeof(struct utmpx)); setutxent(); STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id)); utx->ut_type = DEAD_PROCESS; getutxid(utx); /* position to entry in utmp file */ STRNCPY(PVTS(r, page)->ut_id, ut_id, sizeof(PVTS(r, page)->ut_id));#endif#ifdef HAVE_STRUCT_UTMP STRNCPY(ut->ut_line, pty, sizeof(ut->ut_line)); ut->ut_time = time(NULL);# ifdef HAVE_UTMP_PID STRNCPY(ut->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?", sizeof(ut->ut_user)); STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id)); ut->ut_time = time(NULL); ut->ut_pid = PVTS(r, page)->cmd_pid;# ifdef HAVE_UTMP_HOST STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host));# endif ut->ut_type = USER_PROCESS; pututline(ut); endutent(); /* close the file */ PVTS(r, page)->utmp_pos = 0;# else STRNCPY(ut->ut_name, (pwent && pwent->pw_name) ? pwent->pw_name : "?", sizeof(ut->ut_name));# ifdef HAVE_UTMP_HOST STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host));# endif# endif#endif#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) STRNCPY(utx->ut_line, pty, sizeof(utx->ut_line)); STRNCPY(utx->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?", sizeof(utx->ut_user)); STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id));# ifdef HAVE_UTMPX_SESSION utx->ut_session = getsid(0);# endif utx->ut_tv.tv_sec = time(NULL); utx->ut_tv.tv_usec = 0; utx->ut_pid = PVTS(r, page)->cmd_pid;# ifdef HAVE_UTMPX_HOST STRNCPY(utx->ut_host, hostname, sizeof(utx->ut_host));# endif utx->ut_type = USER_PROCESS; pututxline(utx); endutxent(); /* close the file */ PVTS(r, page)->utmp_pos = 0;#endif#if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID) { int i;# ifdef HAVE_TTYSLOT i = ttyslot(); if (rxvt_write_bsd_utmp(i, ut)) PVTS(r, page)->utmp_pos = i;# else FILE *fd0; if (NOT_NULL(fd0 = fopen(TTYTAB_FILENAME, "r"))) { char buf[256], name[256]; buf[sizeof(buf) - 1] = '\0'; for (i = 1; NOT_NULL(fgets(buf, sizeof(buf) - 1, fd0)); ) { if (*buf == '#' || sscanf(buf, "%s", name) != 1) continue; if (!STRCMP(ut->ut_line, name)) { if (!rxvt_write_bsd_utmp(i, ut)) i = 0; PVTS(r, page)->utmp_pos = i; fclose(fd0); break; } i++; } fclose(fd0); }# endif }#endif#ifdef WTMP_SUPPORT# ifdef WTMP_ONLY_ON_LOGIN if (ISSET_OPTION(r, Opt_loginShell))# endif {# ifdef HAVE_STRUCT_UTMP# ifdef HAVE_UPDWTMP updwtmp(RXVT_WTMP_FILE, ut);# else rxvt_update_wtmp(RXVT_WTMP_FILE, ut);# endif# endif# if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)# ifdef HAVE_UPDWTMPX updwtmpx(RXVT_WTMPX_FILE, utx);# else pututxline (utx);# endif# endif }#endif#endif /* UTEMPTER_SUPPORT */#if defined(LASTLOG_SUPPORT) && defined(RXVT_LASTLOG_FILE) if (ISSET_OPTION(r, Opt_loginShell)) rxvt_update_lastlog(RXVT_LASTLOG_FILE, pty, hostname);#endif}/* ------------------------------------------------------------------------- *//* * remove utmp and wtmp entries *//* EXTPROTO */voidrxvt_cleanutent(rxvt_t *r, int page){#ifdef UTEMPTER_SUPPORT utempter_remove_record (PVTS(r, page)->cmd_fd);#else /* UTEMPTER_SUPPORT */#ifdef HAVE_STRUCT_UTMP struct utmp *ut = &(PVTS(r, page)->ut);#endif#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) struct utmpx *tmputx, *utx = &(PVTS(r, page)->utx);#endif#ifdef HAVE_STRUCT_UTMP# ifdef HAVE_UTMP_PID MEMSET(ut, 0, sizeof(struct utmp)); setutent(); STRNCPY(ut->ut_id, PVTS(r, page)->ut_id, sizeof(ut->ut_id)); ut->ut_type = USER_PROCESS; { struct utmp *tmput = getutid(ut); if (tmput) /* position to entry in utmp file */ ut = tmput; } ut->ut_type = DEAD_PROCESS;# else MEMSET(ut->ut_name, 0, sizeof(ut->ut_name));# ifdef HAVE_UTMP_HOST MEMSET(ut->ut_host, 0, sizeof(ut->ut_host));# endif# endif ut->ut_time = time(NULL);#endif#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) MEMSET(utx, 0, sizeof(struct utmpx)); setutxent(); STRNCPY(utx->ut_id, PVTS(r, page)->ut_id, sizeof(utx->ut_id)); utx->ut_type = USER_PROCESS; if ((tmputx = getutxid(utx))) /* position to entry in utmp file */ utx = tmputx; utx->ut_type = DEAD_PROCESS;# ifdef HAVE_UTMPX_SESSION utx->ut_session = getsid(0);# endif utx->ut_tv.tv_sec = time(NULL); utx->ut_tv.tv_usec = 0;#endif /* * Write ending wtmp entry */#ifdef WTMP_SUPPORT# ifdef WTMP_ONLY_ON_LOGIN if (ISSET_OPTION(r, Opt_loginShell))# endif {# ifdef HAVE_STRUCT_UTMP# ifdef HAVE_UPDWTMP updwtmp(RXVT_WTMP_FILE, ut);# else rxvt_update_wtmp(RXVT_WTMP_FILE, ut);# endif# endif# if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)# ifdef HAVE_UPDWTMPX updwtmpx(RXVT_WTMPX_FILE, utx);# else pututxline (utx);# endif# endif }#endif /* * Write utmp entry */#ifdef HAVE_STRUCT_UTMP# ifdef HAVE_UTMP_PID if (ut->ut_pid == PVTS(r, page)->cmd_pid) pututline(ut); endutent();# else MEMSET(ut, 0, sizeof(struct utmp)); rxvt_write_bsd_utmp(PVTS(r, page)->utmp_pos, ut);# endif#endif#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) if (utx->ut_pid == PVTS(r, page)->cmd_pid) pututxline(utx); endutxent();#endif#endif /* UTEMPTER_SUPPORT */}/* ------------------------------------------------------------------------- *//* * Write a BSD style utmp entry */#ifdef HAVE_UTMP_H# ifndef UTEMPTER_SUPPORT/* INTPROTO */intrxvt_write_bsd_utmp(int utmp_pos, struct utmp *wu){ int fd; if (utmp_pos <= 0 || (fd = open(RXVT_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 /* UTEMPTER_SUPPORT */#endif/* ------------------------------------------------------------------------- *//* * Update a BSD style wtmp entry */#if defined(WTMP_SUPPORT) && !defined(HAVE_UPDWTMP)# ifndef UTEMPTER_SUPPORT/* INTPROTO */voidrxvt_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 /* UTEMPTER_SUPPORT */#endif/* ------------------------------------------------------------------------- */#ifdef LASTLOG_SUPPORT/* INTPROTO */voidrxvt_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(RXVT_LASTLOGX_FILE, getuid(), &llx);# endif# ifdef HAVE_STRUCT_LASTLOG pwent = getpwuid(getuid()); if (!pwent) { rxvt_msg (DBG_ERROR, DBG_LOGGING, "no entry in password file"); 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 *//* ------------------------------------------------------------------------- */#endif /* UTMP_SUPPORT *//*----------------------- end-of-file (C source) -----------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -