/*
 *
 * honggfuzz - the main file
 * -----------------------------------------
 *
 * Author:
 * Robert Swiecki <swiecki@google.com>
 * Felix Gröbert <groebert@google.com>
 *
 * Copyright 2010-2015 by Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 */

#include <inttypes.h>
#include <getopt.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include "common.h"
#include "cmdline.h"
#include "display.h"
#include "log.h"
#include "files.h"
#include "fuzz.h"
#include "util.h"

static int sigReceived = 0;

/*
 * CygWin/MinGW incorrectly copies stack during fork(), so we need to keep some
 * structures in the data section
 */
honggfuzz_t hfuzz;
char *myargs[1024];

void sigHandler(int sig)
{
    /* We should not terminate upon SIGALRM delivery */
    if (sig == SIGALRM) {
        return;
    }

    sigReceived = sig;
}

static void setupTimer(void)
{
    struct itimerval it = {
        .it_value = {.tv_sec = 0,.tv_usec = 1},
        .it_interval = {.tv_sec = 1,.tv_usec = 0},
    };
    if (setitimer(ITIMER_REAL, &it, NULL) == -1) {
        PLOG_F("setitimer(ITIMER_REAL)");
    }
}

static void setupSignalsPreThr(void)
{
    /* Block signals which should be handled by the main thread */
    sigset_t ss;
    sigemptyset(&ss);
    sigaddset(&ss, SIGTERM);
    sigaddset(&ss, SIGINT);
    sigaddset(&ss, SIGQUIT);
    sigaddset(&ss, SIGALRM);
    if (sigprocmask(SIG_BLOCK, &ss, NULL) != 0) {
        PLOG_F("pthread_sigmask(SIG_BLOCK)");
    }
}

static void setupSignalsPostThr(void)
{
    struct sigaction sa = {
        .sa_handler = sigHandler,
        .sa_flags = 0,
    };
    sigemptyset(&sa.sa_mask);
    if (sigaction(SIGTERM, &sa, NULL) == -1) {
        PLOG_F("sigaction(SIGTERM) failed");
    }
    if (sigaction(SIGINT, &sa, NULL) == -1) {
        PLOG_F("sigaction(SIGINT) failed");
    }
    if (sigaction(SIGQUIT, &sa, NULL) == -1) {
        PLOG_F("sigaction(SIGQUIT) failed");
    }
    if (sigaction(SIGALRM, &sa, NULL) == -1) {
        PLOG_F("sigaction(SIGALRM) failed");
    }
    /* Unblock signals which should be handled by the main thread */
    sigset_t ss;
    sigemptyset(&ss);
    sigaddset(&ss, SIGTERM);
    sigaddset(&ss, SIGINT);
    sigaddset(&ss, SIGQUIT);
    sigaddset(&ss, SIGALRM);
    if (sigprocmask(SIG_UNBLOCK, &ss, NULL) != 0) {
        PLOG_F("pthread_sigmask(SIG_BLOCK)");
    }
}

int main(int argc, char **argv)
{
    /*
     * Work around CygWin/MinGW
     */
    size_t i;
    for (i = 0U; i < (ARRAYSIZE(myargs) - 1); i++) {
        myargs[i] = argv[i];
    }
    myargs[i] = NULL;

    if (cmdlineParse(argc, myargs, &hfuzz) == false) {
        LOG_F("Parsing of the cmd-line arguments failed");
    }

    if (!files_init(&hfuzz)) {
        LOG_F("Couldn't load input files");
        exit(EXIT_FAILURE);
    }

    if (hfuzz.dictionaryFile && (files_parseDictionary(&hfuzz) == false)) {
        LOG_F("Couldn't parse dictionary file ('%s')", hfuzz.dictionaryFile);
    }

    if (hfuzz.blacklistFile && (files_parseBlacklist(&hfuzz) == false)) {
        LOG_F("Couldn't parse stackhash blacklist file ('%s')", hfuzz.blacklistFile);
    }

    setupSignalsPreThr();
    setupTimer();

    /*
     * So far so good
     */
    fuzz_threads(&hfuzz);
    setupSignalsPostThr();

    for (;;) {
        if (hfuzz.useScreen) {
            display_display(&hfuzz);
        }
        if (sigReceived > 0) {
            break;
        }
        if (__sync_fetch_and_add(&hfuzz.threadsFinished, 0UL) >= hfuzz.threadsMax) {
            break;
        }
        pause();
    }

    if (sigReceived > 0) {
        LOG_I("Signal %d (%s) received, terminating", sigReceived, strsignal(sigReceived));
    }

    /* Clean-up global buffers */
    free(hfuzz.files);
    free(hfuzz.dynamicFileBest);
    if (hfuzz.dictionary) {
        for (size_t i = 0; i < hfuzz.dictionaryCnt; i++) {
            free(hfuzz.dictionary[i]);
        }
        free(hfuzz.dictionary);
    }
    if (hfuzz.blacklist) {
        free(hfuzz.blacklist);
    }
    if (hfuzz.sanOpts.asanOpts) {
        free(hfuzz.sanOpts.asanOpts);
    }
    if (hfuzz.sanOpts.ubsanOpts) {
        free(hfuzz.sanOpts.ubsanOpts);
    }
    if (hfuzz.sanOpts.msanOpts) {
        free(hfuzz.sanOpts.msanOpts);
    }
    if (hfuzz.pidCmd) {
        free(hfuzz.pidCmd);
    }

    exit(EXIT_SUCCESS);
}
