#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/wait.h>
static const char* const USAGE =
        "Usage: irexec [options] [lircrc config_file]\n"
        "\t-d --daemon\t\tRun in background\n"
        "\t-D --loglevel=level\t'error', 'info', 'notice',... or 0..10\n"
        "\t-n --name=progname\tUse this program name for lircrc matching\n"
        "\t-h --help\t\tDisplay usage summary\n"
        "\t-v --version\t\tDisplay version\n";
static const struct option options[] = {
        { "help",     no_argument,       NULL, 'h' },
        { "version",  no_argument,       NULL, 'v' },
        { "daemon",   no_argument,       NULL, 'd' },
        { "name",     required_argument, NULL, 'n' },
        { "loglevel", required_argument, NULL, 'D' },
        { 0,          0,                 0,    0   }
};
static int opt_daemonize        = 0;
static const char* opt_progname = "irexec";
static char path[256] = {0};
static void run_command(const char* cmd)
{
        pid_t pid1;
        pid_t pid2;
        pid1 = fork();
        if (pid1 < 0) {
                perror("Cannot fork()");
                exit(EXIT_FAILURE);
        }
        if (pid1 == 0) {
                pid2 = fork();
                if (pid2 < 0) {
                        exit(EXIT_FAILURE);
                }
                if (pid2 == 0) {
                        char* const vp[] = {strdup(SH_PATH),
                              strdup("-c"),
                              strdup(cmd),
                              NULL
                        };
                        execvp(SH_PATH, vp);
                        
                        fputs("execvp failed\n", stderr);
                } else {
                        waitpid(pid2, NULL, WNOHANG);
                        exit(0);
                }
        } else {
                waitpid(pid1, NULL, 0);
        }
}
{
        char* code;
        char* c;
        int r;
                if (code == NULL)
                        continue;
                while (r == 0 && c != NULL) {
                        run_command(c);
                }
                free(code);
                if (r == -1)
                        break;
        }
}
int irexec(const char* configfile)
{
        if (opt_daemonize) {
                if (daemon(0, 0) == -1) {
                        perror("Can't daemonize");
                        return EXIT_FAILURE;
                }
        }
        if (
lirc_init(opt_progname, opt_daemonize ? 0 : 1) == -1)
                 return EXIT_FAILURE;
                fputs("Cannot parse config file\n", stderr);
                return EXIT_FAILURE;
        }
        unlink(path);
        process_input(config);
        return EXIT_SUCCESS;
}
int main(int argc, char* argv[])
{
        int c;
        while ((c = getopt_long(argc, argv, "D:hvdn:", options, NULL)) != -1) {
                switch (c) {
                case 'h':
                        puts(USAGE);
                        return EXIT_SUCCESS;
                case 'v':
                        puts("irexec " VERSION);
                        return EXIT_SUCCESS;
                case 'd':
                        opt_daemonize = 1;
                        break;
                case 'n':
                        opt_progname = optarg;
                        break;
                case 'D':
                        break;
                default:
                        fputs(USAGE, stderr);
                        return EXIT_FAILURE;
                }
        }
        if (optind < argc - 1) {
                fputs("Too many arguments\n", stderr);
                return EXIT_FAILURE;
        }
        if (opt_loglevel == LIRC_BADLEVEL) {
                fprintf(stderr, "Bad debug level: %s\n", optarg);
                return EXIT_FAILURE;
        }
        return irexec(optind != argc ? argv[optind] : NULL);
}