iso9660fs: initialize buffer cache
[minix.git] / commands / telnetd / wtmp.c
blob2fdba3d807d3e576b01bce956f8df143bf46edb5
1 /*
2 * TNET A server program for MINIX which implements the TCP/IP
3 * suite of networking protocols. It is based on the
4 * TCP/IP code written by Phil Karn et al, as found in
5 * his NET package for Packet Radio communications.
7 * This file contains an implementation of the "server"
8 * for the TELNET protocol. This protocol can be used to
9 * remote-login on other systems, just like a normal TTY
10 * session.
12 * Usage: telnetd [-dv]
14 * Version: @(#)telnetd.c 1.00 07/26/92
16 * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
17 * Michael Temari, <temari@temari.ae.ge.com>
19 #include <sys/types.h>
20 #include <fcntl.h>
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <utmp.h>
26 #include <time.h>
27 #include <stdio.h>
28 #include "telnetd.h"
30 static char PATH_UTMP[] = "/etc/utmp";
31 static char PATH_WTMP[] = "/usr/adm/wtmp";
33 void wtmp(int type, int linenr, char *line, pid_t pid, char *host);
34 void report(char *label);
36 void wtmp(type, linenr, line, pid, host)
37 int type; /* type of entry */
38 int linenr; /* line number in ttytab */
39 char *line; /* tty name (only good on login) */
40 pid_t pid; /* pid of process */
41 char *host; /* name of the remote host */
43 /* Log an event into the UTMP and WTMP files. */
45 struct utmp utmp; /* UTMP/WTMP User Accounting */
46 int fd;
48 /* Clear the utmp record. */
49 memset((void *) &utmp, 0, sizeof(utmp));
51 /* Fill in utmp. */
52 switch (type) {
53 case LOGIN_PROCESS:
54 /* A new login, fill in line and host name. */
55 strncpy(utmp.ut_line, line, sizeof(utmp.ut_line));
56 strncpy(utmp.ut_host, host, sizeof(utmp.ut_host));
57 break;
59 case DEAD_PROCESS:
60 /* A logout. Use the current utmp entry, but make sure it is a
61 * user process exiting, and not getty or login giving up.
63 if ((fd = open(PATH_UTMP, O_RDONLY)) < 0) {
64 if (errno != ENOENT) report(PATH_UTMP);
65 return;
67 if (lseek(fd, (off_t) (linenr+1) * sizeof(utmp), SEEK_SET) == -1
68 || read(fd, &utmp, sizeof(utmp)) == -1
69 ) {
70 report(PATH_UTMP);
71 close(fd);
72 return;
74 close(fd);
75 if (utmp.ut_type != USER_PROCESS) return;
76 strncpy(utmp.ut_name, "", sizeof(utmp.ut_name));
77 break;
80 /* Finish new utmp entry. */
81 utmp.ut_pid = pid;
82 utmp.ut_type = type;
83 utmp.ut_time = time((time_t *) 0);
85 /* Write new entry to utmp. */
86 if ((fd = open(PATH_UTMP, O_WRONLY)) < 0
87 || lseek(fd, (off_t) (linenr+1) * sizeof(utmp), SEEK_SET) == -1
88 || write(fd, &utmp, sizeof(utmp)) == -1
89 ) {
90 if (errno != ENOENT) report(PATH_UTMP);
92 if (fd != -1) close(fd);
94 if (type == DEAD_PROCESS) {
95 /* Add new wtmp entry. */
96 if ((fd = open(PATH_WTMP, O_WRONLY | O_APPEND)) < 0
97 || write(fd, &utmp, sizeof(utmp)) == -1
98 ) {
99 if (errno != ENOENT) report(PATH_WTMP);
101 if (fd != -1) close(fd);
105 void report(label)
106 char *label;
108 char message[128];
110 sprintf(message, "telnetd: %s: %s\r\n", strerror(errno));
111 (void) write(1, message, strlen(message));