/*
   Common Routines
   --------------------------------------------------------------------
   Protolog - The Internet Protocols logger

   Copyright (C) 1998, 1999 Diego Javier Grigna <diego@grigna.com>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "common.h"

/* If set Protolog won't resolve domain names */
int flag_dont_resolve;

/* If set, don't send output to stdout */
int flag_quiet;

/* The program name, argv[ 0] */
char *progname;

/*
 * Initialize signals
 */
void init_signals( void)
{
 signal( SIGINT , SIG_IGN);
 signal( SIGHUP , SIG_IGN);
 signal( SIGTERM, SIG_IGN);
 signal( SIGQUIT, SIG_IGN);
 signal( SIGKILL, SIG_IGN);
 signal( SIGPIPE, SIG_IGN);
 signal( SIGSTOP, SIG_IGN);
 signal( SIGTSTP, SIG_IGN);
 signal( SIGTTIN, SIG_IGN);
 signal( SIGTTOU, SIG_IGN);
}

void gobackground( void)
{
 int pid, fd;

 if( (pid = fork()))
     exit(0);
 else 
     if( pid == -1) {
         fprintf( stderr, "\n%s: %s\n", progname, strerror( errno));
         exit( -1);
     }

 fd = open( "/dev/tty", O_RDWR);

 if( fd >= 0) {
     ioctl( fd, TIOCNOTTY, 0);
     close( fd);
 }

 close( 0);
 close( 1);
 close( 2);

 setsid();
 chdir( "/");
}

char *resolve_host_name( unsigned long int addr)
{
 static char buf[ 4096];
 struct in_addr ina;
 struct hostent *he;

 if( flag_dont_resolve) {
     strcpy( buf, "not resolving");
     return buf;
 }

 ina.s_addr = addr;

 he = gethostbyaddr( (char *) &ina, sizeof( struct in_addr), AF_INET);

 if( he == NULL)
     strcpy( buf, inet_ntoa( ina));
 else
     strcpy( buf, he->h_name);

 return buf;
}

char *get_serv_name( unsigned short port, const char *proto)
{
 struct servent *se;
 static char buf[ 2048];

 se = getservbyport( port, proto);

 if( se == NULL)
     sprintf( buf, "%d", ntohs( port));
 else
     sprintf( buf, "%s", se->s_name);

 return buf;
}

/*
 * Run only if we are root.
 */

void check_uid( void)
{
 if( geteuid() || getuid()) {
     fprintf( stderr,"%s: Only root can run this program!\n", progname);
     exit( -1);
 }
}

char *replicate( char c, int size)
{
 static char rstr[ 2048];

 memset( &rstr, c, size);

 return rstr;
}

int plog_inet_dtoa( char *mask, struct in_addr *inetmask)
{
 static struct in_addr retaddr;
 char *buffer;
 char *ptr;
 char *dot;
 long number;
 int i = 0;

 buffer = ( char *) plog_calloc( strlen( mask) + 2);

 sprintf( buffer, "%s.", mask);

 ptr = buffer;

 retaddr.s_addr = 0;

 while( i < 4) {
        dot = strchr( ptr, '.');
        if( dot == NULL) {
            free( buffer);
            return -1;
        } else {
            *dot = 0;
            number = atol( ptr);
            if( number < 0 || number > 255) {
                free( buffer);
                return -1;
            } else
                retaddr.s_addr += number << ( 8 * i);
        }
        ptr = dot + 1;
        i++;
 }
 
 free( buffer);

 inetmask->s_addr = retaddr.s_addr;
 return 1;
}

void plog_parse_mask( char *mask, struct in_addr *inetmask)
{
 static struct in_addr ipmask;
 long bits = 0;

 if( mask == NULL) {
     inetmask->s_addr = 0xFFFFFFFF;
     return;
 } else if( plog_inet_dtoa( mask, &ipmask) != -1) {
            inetmask->s_addr = ipmask.s_addr;
            return;
        }

 bits = atol( mask);

 if( bits < 0 || bits > 32) {
     fprintf( stderr, "\n%s: Invalid mask [%s]\n\n", progname, mask);
     exit( -1);
 }
 else if( bits == 0)
          ipmask.s_addr = 0L;
      else
          ipmask.s_addr = htonl( 0xFFFFFFFF << ( 32 - bits));

 inetmask->s_addr = ipmask.s_addr;
 return;
}

void process_host_and_mask( char *str, struct in_addr *mask, struct in_addr *host)
{
 struct hostent *he;
 struct in_addr ipignore;
 struct in_addr ipmask;
 char *hostname;
 char *buffer;
 int size = 0;

 hostname = strtok( str, "/");

 if( hostname == NULL) {
     fprintf( stderr, "\n%s: hostname missing.\n\n", progname);
     exit( -1);
 }

 if( inet_aton( hostname, &ipignore) == 0) {
     he = gethostbyname( hostname);

     if( he == NULL) {
         size = strlen( progname) + strlen( hostname) + 32;
         buffer = ( char *) plog_calloc( size);
         sprintf( buffer, "\n%s: [%s] ", progname, hostname);
         herror( buffer);
         free( buffer);
         fprintf( stderr, "\n");
         exit( -1);
     } else
         memcpy( &ipignore, he->h_addr_list[ 0], sizeof( struct in_addr));
 }

 plog_parse_mask( strtok( NULL, "/"), &ipmask);

 mask->s_addr  = ipmask.s_addr;
 host->s_addr  = ipmask.s_addr & ipignore.s_addr;

 if( flag_quiet == 0) {
     printf( "\nIgnore hostname/mask enabled.\n\n");
     printf( "Mask            : %s\n", inet_ntoa( *mask));
     printf( "Ignore host mask: %s\n", inet_ntoa( *host));
 }
}

char *plog_basename( char *name)
{
 char *base;

 if( name == NULL) {
     fprintf( stderr, "\n%s: plog_basename called with NULL argument\n\n", progname);
     exit( -1);
 }

 base = strrchr( name, '/');

 return ( ( base != NULL) ? base + 1 : name);
}

void *plog_calloc( int size)
{
 void *ptr;

 if( (ptr = calloc( 1, size + 1)) == NULL) {
      fprintf( stderr, "\n%s: Not enough memory.\n\n", progname);
      exit( 1);
 } else
      return ptr;
}

