/*******************************************************************-*-C-*- * * loginhost - Copyright (C) 1997 Pat Thoyts * * Searches through utmp(5) for the controlling terminal and returns * the login hostname entry. We might need some checks for validity * and to ensure we don't screw up when we are at the console. * * This is for use setting the DISPLAY envar properly at login. * We use something like this in /etc/zshrc or /etc/bashrc: * * if [ -z "$DISPLAY" ]; then * LOGINADDR="`/usr/local/bin/loginhost`" * if [ ! $LOGINADDR = "0.0.0.0" ]; then * export DISPLAY="$LOGINADDR:0.0" * fi * fi * * * gcc -Wall loginhost.c -o loginhost * Works on Linux with libc5 and glibc 2.0. * **************************************************************************/ #include #include #include #include #include #include #include #ifndef UTMP_FILE # define UTMP_FILE "/var/run/utmp" #endif char* getipaddr(unsigned long addr); int main ( int argc, char** argv ) { struct utmp utmp; int fd = 0, size = 0; char* my_tty; my_tty = ttyname(0); my_tty += 5; fd = open(UTMP_FILE, O_RDONLY); if (fd == -1) { fprintf(stderr, "Oops. Failed to open %s\n", UTMP_FILE); exit(1); } size = read(fd, &utmp, sizeof(struct utmp)); do { if ( utmp.ut_type == USER_PROCESS && strncmp(utmp.ut_line, my_tty, UT_LINESIZE + 1) == 0) { printf("%s", getipaddr(utmp.ut_addr)); } size = read(fd, &utmp, sizeof(struct utmp)); } while ( size == sizeof(struct utmp) ); close(fd); return 0; } char* getipaddr(unsigned long addr) { typedef union { unsigned long ul; unsigned char uc[5]; } ad_t; ad_t ad = {0}; char* ans = NULL; ad = addr; ans = (char*)malloc(sizeof(char) * 255); if (ans == NULL) exit(1); sprintf(ans, "%d.%d.%d.%d", (int)ad.uc[0], (int)ad.uc[1], (int)ad.uc[2], (int)ad.uc[3]); return ans; }