/* my_ip.c
      tell (on stdout) what the IP address is.
 
   Released to public domain by Bob Rasmussen (ras@anzio.com). NO WARRANTY
   STATED OR IMPLIED.
 
   Compile with, for instance:
      cc -DUTMPX -o my_ip my_ip.c -lsocket
   If Unix system doesn't have a utmpx file, remove the "-DUTMPX".
*/
 
#define PROGVERSION "my_ip version 1.02"
 
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <fcntl.h>
#include <utmp.h>
#ifdef UTMPX
#include <utmpx.h>
#endif
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
 
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif
 
#ifdef UTMPX_FILE
#define PATH UTMPX_FILE
#else
#ifdef _PATH_UTMP
#define PATH _PATH_UTMP
#else
#define PATH UTMP_FILE
#endif
#endif
 
/* typedef unsigned long in_addr_t; */
 
int debugl;
 
extern  int h_errno;
 
main(ac,av)
int ac;
char    *av[];
{
    int     s;
    struct  sockaddr_in sin;
    int     c;
    struct  hostent *hp;
    struct  hostent he;
    char    *pmyaddr;
    /*unsigned long myaddr;*/
    /* in_addr_t myaddr; */
    struct in_addr myaddr;
    char    buf[1024];
    int     bufr,bufw;
    char    *hostname;
    int     port;
    int     eret;
    char    *iam;
#ifdef UTMPX
    struct utmpx u;
#else
    struct utmp u;
#endif
    FILE    *u_file;
    char    myhostname[100];
    char    mytty[100];
    char    *p;
    int     mypid;
    int     trycount = 5;
 
    iam = av[0];
    hostname = (char *)0;
    port = 9100;
    mypid = getpid();
 
    while(ac>1) {
       av++;
       ac--;
       if (strcmp(*av,"-d")==0) {
          debugl = 1;
          ac--;
          if (debugl) {
             fprintf(stderr, "%s\n", PROGVERSION);
             fprintf(stderr,"debugl = %d\n",debugl);
           }
       }
    }
 
#ifndef NODYNAMIC
    u_file = fopen(PATH, "r");
    strcpy(mytty, ttyname(2)); /* use stderr in case stdin/stdout redirected */
    p = &mytty[5];  /* past "/dev/" */
    if (debugl)
       fprintf(stderr, "tty=%s\n", p);
    if (u_file) {
       while (fread(&u, sizeof(u), 1, u_file)) {
          /*printf(u.ut_line); printf(inet_ntop(u.ut_addr_v6)); printf("\n\r");*/
          if (strcmp(u.ut_line, p) == 0 && u.ut_type == USER_PROCESS)
          {
#ifdef HAVEADDR6
             inet_ntop(AF_INET, u.ut_addr_v6, myhostname, sizeof(myhostname));
#else
             strcpy(myhostname, u.ut_host);
#endif
             hostname = myhostname;
             break;
          }
       }
       fclose(u_file);
    }
#endif    /* NODYNAMIC */
 
    eret=0;
 
    setbuf(stderr,NULL);
 
    /* try to resolve a numeric IP first */
    hp = &he;
    he.h_addr_list = &pmyaddr;
    pmyaddr = (char *)&myaddr;
#ifdef AF_INET6
    if (inet_pton(AF_INET6, hostname, hp->h_addr)) {
       hp->h_addrtype = AF_INET6;
       hp->h_length = 16;
       if (debugl)
          fprintf(stderr, "using address (IPv6) %s\n", hostname);
       printf(hostname);
    } else
#endif
    if (inet_addr(hostname) != INADDR_NONE) {
#ifdef OLDAIX
       myaddr.s_addr = ((struct in_addr)inet_addr(hostname)).s_addr;
#else
       myaddr.s_addr = inet_addr(hostname);
#endif
       hp->h_addrtype = AF_INET;
       hp->h_length = 4;
       /* if (debugl)
          fprintf(stderr, "using address (IPv4) %s\n", inet_ntoa((struct in_addr)(&myaddr)));  */
       printf(inet_ntoa(myaddr));
    } else
    {
       hp = gethostbyname(hostname);
       if (hp) {
 #ifdef AF_INET6
          inet_ntop(AF_INET, hp->h_addr, buf, sizeof(buf));
          if (debugl)
             fprintf(stderr,"gethostbyname()=%s\n",buf);
          printf(buf);
 #else
          if (debugl)
             fprintf(stderr,"gethostbyname()=%s\n",inet_ntoa(*(struct in_addr *)hp->h_addr));
          printf(inet_ntoa(*(struct in_addr *)(hp->h_addr)));
 #endif
       }
       if (!hp) {
          if (debugl)
             fprintf(stderr, "unable to resolve host %s\n", hostname);
          herror(hostname);
          return(2);
       }
    }
    return(0);
}
 
 
