#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif
#include <getopt.h>
#include <errno.h>
#include <limits.h>
static const char* const help =
        "\nSynopsis:\n"
        "    irsend [options] SEND_ONCE remote code [code...]\n"
        "    irsend [options] SEND_START remote code\n"
        "    irsend [options] SEND_STOP remote code\n"
        "    irsend [options] LIST remote\n"
        "    irsend [options] SET_TRANSMITTERS remote num [num...]\n"
        "    irsend [options] SIMULATE \"scancode repeat keysym remote\"\n"
        "Options:\n"
        "    -h --help\t\t\tdisplay usage summary\n"
        "    -v --version\t\tdisplay version\n"
        "    -d --device=device\t\tuse given lircd socket [" LIRCD "]\n"         "    -a --address=host[:port]\tconnect to lircd at this address\n"
        "    -# --count=n\t\tsend command n times\n";
const char* prog;
{
        int r;
        do {
                if (r != 0 && r != EAGAIN)
                        fprintf(stderr,
                                "Error running command: %s\n", strerror(r));
        } while (r == EAGAIN);
        return r == 0 ? 0 : -1;
}
void reformat_simarg(char* code, char buffer[])
{
        unsigned int scancode;
        unsigned int repeat;
        char keysym[32];
        char remote[64];
        char trash[32];
        int r;
        r = sscanf(code, "%x %x %32s %64s %32s",
                   &scancode, &repeat, keysym, remote, trash);
        if (r != 4) {
                fprintf(stderr, "Bad simulate argument: %s\n", code);
                exit(EXIT_FAILURE);
        }
                 scancode, repeat, keysym, remote);
}
int main(int argc, char** argv)
{
        char* directive;
        char* remote;
        char* code;
        const char* lircd = NULL;
        char* address = NULL;
        unsigned long count = 1;
        int fd;
        int r;
        prog = "irsend";
        while (1) {
                int c;
                static struct option long_options[] = {
                        { "help",    no_argument,       NULL, 'h' },
                        { "version", no_argument,       NULL, 'v' },
                        { "device",  required_argument, NULL, 'd' },
                        { "address", required_argument, NULL, 'a' },
                        { "count",   required_argument, NULL, '#' },
                        { 0,         0,                 0,    0   }
                };
                c = getopt_long(argc, argv, "hvd:a:#:", long_options, NULL);
                if (c == -1)
                        break;
                switch (c) {
                case 'h':
                        fputs(help, stdout);
                        return EXIT_SUCCESS;
                case 'v':
                        printf("%s %s\n", prog, VERSION);
                        return EXIT_SUCCESS;
                case 'd':
                        lircd = optarg;
                        break;
                case 'a':
                {
                        char* p;
                        char* end;
                        unsigned long val;
                        address = strdup(optarg);
                        if (!address) {
                                fprintf(stderr, "%s: out of memory\n", prog);
                                return EXIT_FAILURE;
                        }
                        p = strchr(address, ':');
                        if (p != NULL) {
                                val = strtoul(p + 1, &end, 10);
                                if (!(*(p + 1)) || *end || val < 1 || val > USHRT_MAX) {
                                        fprintf(stderr, "%s: invalid port number: %s\n", prog, p + 1);
                                        return EXIT_FAILURE;
                                }
                                port = (unsigned short)val;
                                *p = 0;
                        }
                        break;
                }
                case '#':
                {
                        char* end;
                        count = strtoul(optarg, &end, 10);
                        if (!*optarg || *end) {
                                fprintf(stderr, "%s: invalid count value: %s\n", prog, optarg);
                                return EXIT_FAILURE;
                        }
                        break;
                }
                default:
                        return EXIT_FAILURE;
                }
        }
        if (optind + 2 > argc) {
                fprintf(stderr, "%s: not enough arguments\n", prog);
                return EXIT_FAILURE;
        }
        if (lircd == NULL)
        if (address == NULL)
        else
        if (fd < 0) {
                lircd = lircd ? lircd : getenv("LIRC_SOCKET_PATH");
                lircd = lircd ? lircd : 
LIRCD;
                perrorf(
"Cannot open socket %s", lircd);
                 exit(EXIT_FAILURE);
        }
        if (address)
                free(address);
        address = NULL;
        directive = argv[optind++];
        if (strcasecmp(directive, "set_transmitters") == 0) {
                code = argv[optind++];
                if (strlen(directive) + strlen(code) + 2 < 
PACKET_SIZE) {
                         sprintf(buffer, "%s %s", directive, code);
                } else {
                        fprintf(stderr, "%s: input too long\n", prog);
                        exit(EXIT_FAILURE);
                }
                while (optind < argc) {
                        code = argv[optind++];
                                sprintf(buffer + strlen(buffer), " %s", code);
                        } else {
                                fprintf(stderr, "%s: input too long\n", prog);
                                exit(EXIT_FAILURE);
                        }
                }
                strcat(buffer, "\n");
                if (send_packet(&ctx, fd) == -1)
                        exit(EXIT_FAILURE);
        }
        if (strcasecmp(directive, "simulate") == 0) {
                code = argv[optind++];
                if (optind != argc) {
                        fprintf(stderr, "%s: invalid argument count\n", prog);
                        exit(EXIT_FAILURE);
                }
                reformat_simarg(code, buffer);
                if (r != 0) {
                        fprintf(stderr, "%s: %s\n", prog, strerror(r));
                        exit(EXIT_FAILURE);
                }
                if (send_packet(&ctx, fd) == -1)
                        exit(EXIT_FAILURE);
        } else {
                remote = argv[optind++];
                if (optind == argc) {
                        fprintf(stderr, "%s: not enough arguments\n", prog);
                        exit(EXIT_FAILURE);
                }
                while (optind < argc) {
                        code = argv[optind++];
                        if (strcasecmp(directive, "SEND_ONCE") == 0 && count > 1)
                                                      directive, remote, code, count);
                        else
                                                      directive, remote, code);
                        if (r != 0) {
                                fprintf(stderr, "%s: input too long\n", prog);
                                exit(EXIT_FAILURE);
                        }
                        if (send_packet(&ctx, fd) == -1)
                                exit(EXIT_FAILURE);
                }
        }
        close(fd);
        return EXIT_SUCCESS;
}