/* Program : loginlog.c * Version : 1.7 * Author : Mark mark@netsys.com * Date : 29th Sep 1994 * Distribution : Unrestricted, copyright remains with the author * Distribution : Bundling with a product constitutes commercial use. See author * Compile : cc -s -O -o loginlog loginlog.1.7.c * Compile : gcc -O2 -o loginlog loginlog.1.7.c (Solaris 2.3) * Tested : NeXTStep 3.1, Linux 1.1.11, Solaris 2.3, SunOS 4.1.3 * Note : You may need to tweak the values below to match your * Note : If you do, email me the diffs. */ /* Ver 1.7 29th Sep 1994 Added login/logout notification for Solaris 2.3 */ /* Ver 1.6 29th Sep 1994 Really fixed dual lines. Tidied up code for Solaris */ /* Ver 1.5 24th Sep 1994 Cured the dual line on user logout */ /* Ver 1.4 8th Jul 1994 Ported it to Solaris 2.3 */ /* Ver 1.3 10th May 1994 Added mips daemon exiting checks */ /* Ver 1.2 16th Jan 1994 Fixed syslog facility/severity mix up */ /* Ver 1.1 14th Jan 1994 basename fix */ /* Ver 1.0 27th Dec 1993 Initial revision */ #define SOLARIS_GCC (defined(sun) && defined(__svr4__)) #include #include #include #include #include #include #include #include #if SOLARIS_GCC #include #else /* SOLARIS_GCC */ #include #endif /* SOLARIS_GCC */ #define FACILITY LOG_AUTH #define SEVERITY LOG_NOTICE #ifndef WTMP_FILE #define WTMP_FILE "/usr/adm/wtmp" #endif WTMP_FILE #define FORMAT "%s %-*.*s %-*.*s %-*.*s" #if SOLARIS_GCC #define bzero(a,b) memset(a,0,b) #define utmp utmpx #define L_XTND SEEK_END #undef WTMP_FILE #define WTMP_FILE WTMPX_FILE #endif /* SOLARIS_GCC */ #if SOLARIS_GCC #define HMAX strlen(utmpbufp->ut_host) #define NMAX strlen(utmpbufp->ut_name) #define LMAX strlen(utmpbufp->ut_line) #else /* SOLARIS_GCC */ #define NMAX sizeof(utmpbufp->ut_name) #define HMAX sizeof(utmpbufp->ut_host) #define LMAX sizeof(utmpbufp->ut_line) #endif /* SOLARIS_GCC */ struct utmp *utmpbufp; int logout(); main(int argc,char **argv) { register int n; char *progname; char buf[350]; char type[10]; char name[50]; char line[50]; char host[256]; (void)close(0); if (fork()) exit(0); /* orphan ourselves and let init take us */ if (open(WTMP_FILE,0)!=0) { perror(WTMP_FILE); exit(1); } close(1); close(2); if ((progname = (char *)strrchr(argv[0], '/')) == NULL) { /* kill path */ progname = argv[0]; } else { progname++; } utmpbufp = (struct utmp *) malloc(sizeof(struct utmp)); (void) openlog(progname, LOG_NDELAY|LOG_PID, FACILITY); /* syslog(SEVERITY, "running"); */ (void)lseek(0,(off_t)0,L_XTND); /* seek to end of wtmp */ for (;;) { /* sit here and wait for people to log in */ sleep(10); /* they can [maybe] zap themselves in this 10 seconds */ while ((n = read (0, utmpbufp, sizeof(struct utmp))) > 0) { if ((strncmp(utmpbufp->ut_name, "", NMAX)) #ifdef mips && (strncmp(utmpbp->ut_name, "telnet", 6)) /* Dont want any of */ && (strncmp(utmpbp->ut_name, "rlogin", 6)) /* these matches */ #endif mips #if SOLARIS_GCC && (strncmp(utmpbufp->ut_name, ".", 1)) #endif /* SOLARIS_GCC */ ) { /* some one logged in or out, lets syslog it */ if (logout()) strcpy(type, "logout:"); else strcpy(type, "login:"); strncpy((char *)name, utmpbufp->ut_name, NMAX); strncpy((char *)line, utmpbufp->ut_line, LMAX); strncpy((char *)host, utmpbufp->ut_host, HMAX); sprintf(buf, FORMAT, type, NMAX, NMAX, name, LMAX, LMAX, line, HMAX, HMAX, host); syslog(SEVERITY, buf); bzero((char *)line, (int)LMAX); bzero((char *)name, (int)NMAX); bzero((char *)host, (int)HMAX); bzero((char *)buf, (int)sizeof(buf)); } } } } /* Add checks to this as they come along */ int logout() { #if SOLARIS_GCC if (utmpbufp->ut_type == DEAD_PROCESS) return(1); #endif /* SOLARIS_GCC */ return(0); }