/***********************************************
 * released under (E) licensing ...            *
 *        (E) RULES AND REGULATIONS            *
 * permission to use/rewrite/add     : granted *
 * permission to trojan/steal        : denied  *
 * permission to use illegally       : denied  *
 * permission to use on /dev/urandom : denied  *
 ***********************************************/
/* contact el8@press.co.jp for full license    */
/* code copyrighted by ~el8 -- don't infringe! */

/* Parts (c) px25 Network Solutions */
#include "penis.h"
#include <signal.h>
#include <fcntl.h>

int con=0;
extern char *optarg;
extern int optind;
void getsig(int);
int main(int    argc,
         char **argv)
{
    int sockfd=0, addrlen=0, optz=0, bkg=0, port=0;
    struct sockaddr_in my_addr, your_addr;
    struct penis my_penis, your_penis;
    FILE *logf = NULL;
    char data[100] = "\0";
    time_t t1me;
    while ( EOF != (optz = getopt(argc,argv,"o:l:w:p:f")))
    {
        switch(optz)
        {
        case 'o':
            if ( NULL == (logf = fopen(optarg,"a+")))
            {
                perror(optarg);
                exit(-1);
            }
            break;
        case 'l':
            my_penis.p_length = atof(optarg);
            break;
        case 'w':
            my_penis.p_width  = atof(optarg);
            break;
        case 'p':
            port = atoi(optarg);
            break;
        case 'f':
            bkg = 1;
            break;
        default:
            goto usage;
            exit(-1);
        }
    }

    if (logf == NULL) logf = stdout;
    if (argv[optind]!=NULL)
    {
        goto usage;
        exit(-1);
    }
    signal(SIGTERM,getsig);
    signal(SIGKILL,getsig);
    signal(SIGINT ,getsig);
    if (my_penis.p_length < 0) my_penis.p_length = MY_LEN;
    if (my_penis.p_width  < 0) my_penis.p_width  = MY_WID;
    if (bkg > 0)
    {
        if (fork() != 0) exit(0);
        setsid();
    }
    if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("couldn't get a fuqn udp socket!");
        exit(-1);
    }
    bzero((char*)&data,sizeof(data));
    bzero((char*)&your_addr,sizeof(your_addr));
    bzero((char*)&my_addr,sizeof(my_addr));
    my_addr.sin_family        =   AF_INET;
    my_addr.sin_addr.s_addr   =   htons(INADDR_ANY);
    my_addr.sin_port          =   htons(port==0?PENIS_PORT:port);
    your_addr.sin_family      =   AF_INET;
    your_addr.sin_addr.s_addr =   htons(INADDR_ANY);

    if ((bind(sockfd,(struct sockaddr *)&my_addr,sizeof(my_addr)) <0))
    {
        perror("couldn't bind to udp port!");
        exit(-1);
    }
    // fcntl(sockfd,F_SETFL,O_NONBLOCK);
    for(;;)
    {

        if (recvfrom(sockfd,data,sizeof(data)-1,0,
                     (struct sockaddr *) &your_addr, &addrlen) > 0)
        {
            if ((sscanf(data,"L %f : W %f",
                        &your_penis.p_length,
                        &your_penis.p_width))==2)
            {
                con++;
                t1me = time(NULL);
                fprintf(logf,"%.24s: [%s] has a %s and %s penis than you.\n",
                        ctime(&t1me),
                        inet_ntoa(your_addr.sin_addr),
                        ((your_penis.p_length>my_penis.p_length)?
                         "longer":"shorter"),
                        ((your_penis.p_width > my_penis.p_width)?
                         "thicker":"thinner"));
            }
        }
        bzero((char*)&data,sizeof(data));
    }

    shutdown(sockfd,2);
    fclose(logf);
usage:
    fprintf(stderr,"usage: %s <-o file> <-l len> <-w width> <-p port> <-f>\n",argv[0]);
}
void getsig(int s)
{
#ifndef NONSTOP
    fprintf(stderr,"Caught signal %i, exiting...\n",s);
    fprintf(stderr,"[%i connections]\n",con);
#ifndef NOTELL
    exit(-1);
#endif
#endif
}



syntax highlighted by Code2HTML, v. 0.9.1