Example #1
0
/*************************************************
 * The main function
 *************************************************/
int main(int argc, char *argv[])
{
    int result;
    const struct option opts[] =
        {
                { "conf",       required_argument, NULL, 'c' },
                { "config",     required_argument, NULL, 'c' },
                { "daemon",     no_argument,       NULL, 'd' },
                { "daemonize",  no_argument,       NULL, 'd' },
                { "file",       required_argument, NULL, 'f' },
                { "help",       no_argument,       NULL, 'h' },
                { "dotmode",    no_argument,       NULL, 's' },
                { "type",       required_argument, NULL, 't' },
                { "unregister", no_argument,       NULL, 'u' },
                { "version",    no_argument,       NULL, 'V' },
                { NULL,         no_argument,       NULL, '\0'}
        };


    setvbuf (stdout, NULL, _IOLBF, 0);
    setvbuf (stderr, NULL, _IOLBF, 0);
    setlocale(LC_ALL, "");
    Config config(DEFAULT_CONF);

    /* Parse the command line */
    while((result = getopt_long(argc,argv,"c:df:hst:uV", opts, NULL))>0)
    {
        switch(result)
        {
            case 'c':
            case 'f':
                config.SetFile(optarg);
                break;
            case 's':
                config.SetDotMode(true);
                break;
            case 'd':
                config.SetDaemonMode(true);
                break;
            case 't':
                config.SetType(optarg);
                break;
            case 'u':
                config.SetReverse(true);
                break;
            case 'h':
                help();
                return 0;
            case 'V':
                version();
                return 0;
            default:
                return -1;
        }
    }

    /* clean up environment */
    clearenv();
    /* make sure stdin, stdout and stderr exists */
    if (dup (2) < 3)
        return 1;

    /* Get the programs */
    puts("+ Parsing configuration file\n");
    if(config.Parse())
    {
        fputs("+ Parsing failed\n", stderr);
        return 1;
    }

    /* TODO check configuration */
    printf("+ %u programs loaded\n",config.Programs.size());
    if (config.Programs.size() == 0)
    {
        puts ("+ Nothing to do. Exiting.");
        return 0;
    }

    if(config.GetType() == TYPE_SAP)
    {
        printf("+ Packet TTL set to %u\n",config.GetTTL());
        printf("+ Running as %s.\n",
               config.GetDaemonMode() ? "daemon" : "program");

        /* Create the broadcast object */
        Broadcast broadcast (config.GetTTL (), config.GetInterface ());

        vector<Announce *> announces;

        for (unsigned int i = 0; i < config.Programs.size(); i++)
        {
            Program *program = config.Programs[i];

            Announce *announce = new Announce;
            if (broadcast.GuessDestination (program->GetAddress ().c_str (),
                                            &announce->addr,
                                            &announce->addrlen))
            {
                fputs("- Network initialization failed. Aborting\n", stderr);
                delete announce;
                /* FIXME memory leak in announces */
                return 1;
            }

            /* Create a new message */
            Message *message = new Message(0x4212+i, "1.2.3.4");
            /* Add the program */
            message->AddProgram(config.Programs[i]);

            announce->message = message;
            announces.push_back( announce );
        }

        /* Forking if necessary */
        if(config.GetDaemonMode())
        {
            puts("+ Forking ... \n");
            daemon(0,0);
        }

        unsigned n = config.Programs.size();
        lldiv_t d = lldiv (1000000000LL * config.GetDelay() / n, 1000000000);
        struct timespec delay;
        delay.tv_sec = d.quot;
        delay.tv_nsec = d.rem;

        signal (SIGINT, exit_handler);
        signal (SIGTERM, exit_handler);
        signal (SIGHUP, exit_handler);
        signal (SIGQUIT, exit_handler);
        setvbuf (stdout, NULL, _IONBF, 0);

        while(!should_exit)
        {
            for( unsigned int i = 0; i< announces.size() ; i ++ )
            {
                Announce *announce = announces[i];
                /* Send the message */
                if (broadcast.Send (announce->message ,
                                    (struct sockaddr *)&announce->addr,
                                    announce->addrlen))
                {
                    fputs ("- Message send failed\n", stderr);
                }
                else
                if(config.GetDotMode())
                    fputc('.', stdout);

                /* Wait for next sending */
                if(should_exit)
                    break;
                nanosleep( &delay, NULL );
            }
        }

        for( unsigned int i = 0; i < announces.size() ; i ++ )
        {
            Announce *announce = announces[i];
            delete announce->message;
            delete announce;
        }
    }
    else
    {
#ifndef CONFIG_SLP
        fputs("- SLP not compiled in...Aborting\n", stderr);
        return 1;
#endif
#ifdef CONFIG_SLP
        SLP slp;

        for(unsigned int i=0 ; i<config.Programs.size(); i++)
        {
            if(!config.GetReverse())
            {
                slp.Register(config.Programs[i]);
            }
            else
            {
                slp.UnRegister(config.Programs[i]);
            }
        }
        if(!config.GetReverse())
        {
            puts("+ Programs registered. To unregister them, run me with -u");
        }
        else
        {
            puts("+ Programs unregistered");
        }
#endif
    }

    puts("Done.");

    return 0;
}