#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);
                        exit(EXIT_FAILURE);
                } 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);
}
int lirc_deinit(void)
Release resources allocated by lirc_init(), basically disconnect from socket.
int lirc_readconfig(const char *file, struct lirc_config **config, int(check)(char *s))
Parse a lircrc configuration file.
void lirc_freeconfig(struct lirc_config *config)
Deallocate an object retrieved using lirc_readconfig().
int lirc_code2char(struct lirc_config *config, char *code, char **string)
Translate a code string to an application string using .lircrc.
int lirc_nextcode(char **code)
Get next available code from the lircd daemon.
int lirc_init(const char *prog, int verbose)
Initial setup: connect to lircd socket.
3-rd party application interface.
loglevel_t string2loglevel(const char *s)
Convert a string, either a number or 'info', 'trace1', error etc.
void lirc_log_set_file(const char *s)
Set logfile.
int lirc_log_open(const char *_progname, int _nodaemon, loglevel_t level)
Open the log for upcoming logging.
int lirc_log_get_clientlog(const char *basename, char *buffer, ssize_t size)
Retrieve a client path for logging according to freedesktop specs.
#define log_debug(fmt,...)
Log a debug message.
loglevel_t
The defined loglevels.
#define log_perror_err(fmt,...)
perror wrapper logging with level LIRC_ERROR.
logchannel_t
Log channels used to filter messages.