#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.