
1: /* Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc. 2: This file is part of the GNU C Library. 3: Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. 4: 5: The GNU C Library is free software; you can redistribute it and/or 6: modify it under the terms of the GNU Lesser General Public 7: License as published by the Free Software Foundation; either 8: version 2.1 of the License, or (at your option) any later version. 9: 10: The GNU C Library is distributed in the hope that it will be useful, 11: but WITHOUT ANY WARRANTY; without even the implied warranty of 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13: Lesser General Public License for more details. 14: 15: You should have received a copy of the GNU Lesser General Public 16: License along with the GNU C Library; if not, write to the Free 17: Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18: 02111-1307 USA. */ 19: 20: #include <assert.h> 21: #include <errno.h> 22: #include <limits.h> 23: #include <string.h> 24: #include <unistd.h> 25: #include <stdlib.h> 26: #include <utmp.h> 27: 28: 29: /* Return the result of ttyname in the buffer pointed to by TTY, which should 30: be of length BUF_LEN. If it is too long to fit in this buffer, a 31: sufficiently long buffer is allocated using malloc, and returned in TTY. 32: 0 is returned upon success, -1 otherwise. */ 33: static int 34: tty_name (int fd, char **tty, size_t buf_len) 35: { 36: int rv; /* Return value. 0 = success. */ 37: char *buf = *tty; /* Buffer for ttyname, initially the user's. */ 38: 39: for (;;) 40: { 41: char *new_buf; 42: 43: if (buf_len) 44: { 45: rv = ttyname_r (fd, buf, buf_len); 46: 47: if (rv != 0 || memchr (buf, '\0', buf_len)) 48: /* We either got an error, or we succeeded and the 49: returned name fit in the buffer. */ 50: break; 51: 52: /* Try again with a longer buffer. */ 53: buf_len += buf_len; /* Double it */ 54: } 55: else 56: /* No initial buffer; start out by mallocing one. */ 57: buf_len = 128; /* First time guess. */ 58: 59: if (buf != *tty) 60: /* We've already malloced another buffer at least once. */ 61: new_buf = realloc (buf, buf_len); 62: else 63: new_buf = malloc (buf_len); 64: if (! new_buf) 65: { 66: rv = -1; 67: __set_errno (ENOMEM); 68: break; 69: } 70: buf = new_buf; 71: } 72: 73: if (rv == 0) 74: *tty = buf; /* Return buffer to the user. */ 75: else if (buf != *tty) 76: free (buf); /* Free what we malloced when returning an error. */ 77: 78: return rv; 79: } 80: ^L 81: void 82: login (const struct utmp *ut) 83: { 84: #ifdef PATH_MAX 85: char _tty[PATH_MAX + UT_LINESIZE]; 86: #else 87: char _tty[512 + UT_LINESIZE]; 88: #endif 89: char *tty = _tty; 90: int found_tty; 91: const char *ttyp; 92: struct utmp copy = *ut; 93: 94: /* Fill in those fields we supply. */ 95: #if _HAVE_UT_TYPE - 0 96: copy.ut_type = USER_PROCESS; 97: #endif 98: #if _HAVE_UT_PID - 0 99: copy.ut_pid = getpid (); 100: #endif 101: 102: /* Seek tty. */ 103: found_tty = tty_name (STDIN_FILENO, &tty, sizeof (_tty)); 104: if (found_tty < 0) 105: found_tty = tty_name (STDOUT_FILENO, &tty, sizeof (_tty)); 106: if (found_tty < 0) 107: found_tty = tty_name (STDERR_FILENO, &tty, sizeof (_tty)); 108: 109: if (found_tty >= 0) 110: { 111: /* We only want to insert the name of the tty without path. 112: But take care of name like /dev/pts/3. */ 113: if (strncmp (tty, "/dev/", 5) == 0) 114: ttyp = tty + 5; /* Skip the "/dev/". */ 115: else 116: ttyp = basename (tty); 117: 118: /* Position to record for this tty. */ 119: strncpy (copy.ut_line, ttyp, UT_LINESIZE); 120: 121: /* Tell that we want to use the UTMP file. */ 122: if (utmpname (_PATH_UTMP) == 0) 123: { 124: /* Open UTMP file. */ 125: setutent (); 126: 127: /* Write the entry. */ 128: pututline (©); 129: 130: /* Close UTMP file. */ 131: endutent (); 132: } 133: 134: if (tty != _tty) 135: free (tty); /* Free buffer malloced by tty_name. */ 136: } 137: else 138: /* We provide a default value so that the output does not contain 139: an random bytes in this field. */ 140: strncpy (copy.ut_line, "???", UT_LINESIZE); 141: 142: /* Update the WTMP file. Here we have to add a new entry. */ 143: updwtmp (_PATH_WTMP, ©); 144: }