33 #include <sys/param.h> 
   34 #include <sys/socket.h> 
   36 #include <sys/types.h> 
   45 #define MAXPATHLEN 4096 
   49 static const struct timeval CMD_TIMEOUT = { .tv_sec = 1, .tv_usec = 0 };
 
   53 #define logprintf(level, fmt, args ...)  syslog(level, fmt, ## args) 
   54 #define LIRC_WARNING    LOG_WARNING 
   55 #define LIRC_DEBUG      LOG_DEBUG 
   56 #define LIRC_NOTICE     LOG_NOTICE 
   57 #define LIRC_ERROR      LOG_ERR 
   60 #define MAX_INCLUDES 10 
   62 #define LIRC_PACKET_SIZE 255 
   64 #define LIRC_TIMEOUT 3 
   71         struct filestack_t*     parent;
 
   92 unsigned int lirc_flags(
char* 
string);
 
   94 static int lirc_lircd = -1;
 
   95 static int lirc_verbose = 0;
 
   96 static char* lirc_prog = NULL;
 
   97 static char* lirc_buffer = NULL;
 
  103 chk_write(
int fd, 
const void* buf, 
size_t count, 
const char* msg)
 
  105         if (write(fd, buf, count) == -1)
 
  120                 logprintf(LIRC_NOTICE, 
"Message too big: %s", ctx->
packet);
 
  141                    (
const void*)&CMD_TIMEOUT,
 
  142                    sizeof(CMD_TIMEOUT));
 
  145                 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
 
  146                         logprintf(LIRC_NOTICE, 
"fill_string: timeout\n");
 
  158 static int read_string(
lirc_cmd_ctx* cmd, 
int fd, 
const char** 
string)
 
  172         if (cmd->
next == NULL || strchr(cmd->
next, 
'\n') == NULL) {
 
  173                 r = fill_string(fd, cmd);
 
  181         cmd->
next = strchr(cmd->
next, 
'\n');
 
  182         if (cmd->
next != NULL) {
 
  193         const char* 
string = NULL;
 
  200         todo = strlen(ctx->
packet);
 
  202         logprintf(LIRC_DEBUG, 
"lirc_command_run: Sending: %s", data);
 
  204                 done = write(fd, (
void*)data, todo);
 
  206                         logprintf(LIRC_WARNING,
 
  207                                   "%s: could not send packet\n", prog);
 
  221                         r = read_string(ctx, fd, &
string);
 
  223                 if (!
string || strlen(
string) == 0)
 
  225                 logprintf(LIRC_DEBUG,
 
  226                           "lirc_command_run, state: %d, input: \"%s\"\n",
 
  227                           state, 
string ? 
string : 
"(Null)");
 
  230                         if (strcasecmp(
string, 
"BEGIN") != 0)
 
  235                         if (strncasecmp(
string, ctx->
packet,
 
  237                             || strcspn(
string, 
"\n")
 
  238                                         != strcspn(ctx->
packet, 
"\n")) {
 
  245                         if (strcasecmp(
string, 
"SUCCESS") == 0) {
 
  247                         } 
else if (strcasecmp(
string, 
"END") == 0) {
 
  248                                 logprintf(LIRC_NOTICE,
 
  249                                           "lirc_command_run: status:END");
 
  251                         } 
else if (strcasecmp(
string, 
"ERROR") == 0) {
 
  252                                 logprintf(LIRC_WARNING,
 
  253                                           "%s: command failed: %s",
 
  262                         if (strcasecmp(
string, 
"END") == 0) {
 
  263                                 logprintf(LIRC_NOTICE,
 
  264                                           "lirc_command_run: data:END, status:%d",
 
  267                         } 
else if (strcasecmp(
string, 
"DATA") == 0) {
 
  271                         logprintf(LIRC_DEBUG,
 
  272                                   "data: bad packet: %s\n",
 
  277                         data_n = (uint32_t)strtoul(
string, &endptr, 0);
 
  278                         if (!*
string || *endptr)
 
  290                                         strcpy(ctx->
reply, 
"");
 
  293                                 chk_write(STDOUT_FILENO, 
string, strlen(
string),
 
  295                                 chk_write(STDOUT_FILENO, 
"\n", 1, 
"reply (2)");
 
  306                         if (strcasecmp(
string, 
"END") == 0) {
 
  307                                 logprintf(LIRC_NOTICE,
 
  308                                           "lirc_command_run: status:END, status:%d",
 
  316         logprintf(LIRC_WARNING, 
"%s: bad return packet\n", prog);
 
  317         logprintf(LIRC_DEBUG, 
"State %d: bad packet: %s\n", status, 
string);
 
  322 static void lirc_printf(
const char* format_str, ...)
 
  329         va_start(ap, format_str);
 
  330         vfprintf(stderr, format_str, ap);
 
  335 static void lirc_perror(
const char* s)
 
  346         if (prog == NULL || lirc_prog != NULL)
 
  349         if (lirc_lircd >= 0) {
 
  350                 lirc_verbose = verbose;
 
  351                 lirc_prog = strdup(prog);
 
  352                 if (lirc_prog == NULL) {
 
  353                         lirc_printf(
"%s: out of memory\n", prog);
 
  358         lirc_printf(
"%s: could not open socket: %s\n",
 
  360                     strerror(-lirc_lircd));
 
  369         if (lirc_prog != NULL) {
 
  373         if (lirc_buffer != NULL) {
 
  377         if (lirc_lircd != -1) {
 
  378                 r = close(lirc_lircd);
 
  381         return r == 0 ? 1 : 0;
 
  387 static int lirc_readline(
char** line, FILE* f)
 
  394         newline = (
char*)malloc(LIRC_READ + 1);
 
  395         if (newline == NULL) {
 
  396                 lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  401                 ret = fgets(newline + len, LIRC_READ + 1, f);
 
  403                         if (feof(f) && len > 0) {
 
  411                 len = strlen(newline);
 
  412                 if (newline[len - 1] == 
'\n') {
 
  413                         newline[len - 1] = 0;
 
  418                 enlargeline = (
char*)realloc(newline, len + 1 + LIRC_READ);
 
  419                 if (enlargeline == NULL) {
 
  421                         lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  424                 newline = enlargeline;
 
  429 static char* lirc_trim(
char* s)
 
  433         while (s[0] == 
' ' || s[0] == 
'\t')
 
  438                 if (s[len] == 
' ' || s[len] == 
'\t')
 
  448 static char lirc_parse_escape(
char** s, 
const char* name, 
int line)
 
  451         unsigned int i, overflow, count;
 
  452         int digits_found, digit;
 
  492                 while (++count < 3) {
 
  494                         if (c >= 
'0' && c <= 
'7') {
 
  495                                 i = (i << 3) + c - 
'0';
 
  501                 if (i > (1 << CHAR_BIT) - 1) {
 
  502                         i &= (1 << CHAR_BIT) - 1;
 
  504                                 "%s: octal escape sequence out of range in %s:%d\n",
 
  505                                 lirc_prog, name, line);
 
  515                         if (c >= 
'0' && c <= 
'9') {
 
  517                         } 
else if (c >= 
'a' && c <= 
'f') {
 
  518                                 digit = c - 
'a' + 10;
 
  519                         } 
else if (c >= 
'A' && c <= 
'F') {
 
  520                                 digit = c - 
'A' + 10;
 
  525                         overflow |= i ^ (i << 4 >> 4);
 
  526                         i = (i << 4) + digit;
 
  530                         lirc_printf(
"%s: \\x used with no " 
  531                                     "following hex digits in %s:%d\n",
 
  532                                     lirc_prog, name, line);
 
  533                 if (overflow || i > (1 << CHAR_BIT) - 1) {
 
  534                         i &= (1 << CHAR_BIT) - 1;
 
  535                         lirc_printf(
"%s: hex escape sequence out " 
  536                                     "of range in %s:%d\n", lirc_prog, name,
 
  542                 if (c >= 
'@' && c <= 
'Z')
 
  549 static void lirc_parse_string(
char* s, 
const char* name, 
int line)
 
  557                         *t = lirc_parse_escape(&s, name, line);
 
  569 static void lirc_parse_include(
char* s, 
const char* name, 
int line)
 
  578         if (*s != 
'"' && *s != 
'<')
 
  580         if (*s == 
'"' && last != 
'"')
 
  582         else if (*s == 
'<' && last != 
'>')
 
  585         memmove(s, s + 1, len - 2 + 1); 
 
  589 int lirc_mode(
char* token, 
char* token2, 
char** mode,
 
  593               int (check) (
char* s),
 
  599         new_entry = *new_config;
 
  600         if (strcasecmp(token, 
"begin") == 0) {
 
  601                 if (token2 == NULL) {
 
  602                         if (new_entry == NULL) {
 
  605                                 if (new_entry == NULL) {
 
  606                                         lirc_printf(
"%s: out of memory\n",
 
  610                                 new_entry->prog = NULL;
 
  611                                 new_entry->code = NULL;
 
  612                                 new_entry->rep_delay = 0;
 
  613                                 new_entry->ign_first_events = 0;
 
  615                                 new_entry->config = NULL;
 
  616                                 new_entry->change_mode = NULL;
 
  617                                 new_entry->flags = none;
 
  618                                 new_entry->mode = NULL;
 
  619                                 new_entry->next_config = NULL;
 
  620                                 new_entry->next_code = NULL;
 
  621                                 new_entry->next = NULL;
 
  622                                 *new_config = new_entry;
 
  624                                 lirc_printf(
"%s: bad file format, %s:%d\n",
 
  625                                             lirc_prog, name, line);
 
  629                         if (new_entry == NULL && *mode == NULL) {
 
  630                                 *mode = strdup(token2);
 
  634                                 lirc_printf(
"%s: bad file format, %s:%d\n",
 
  635                                             lirc_prog, name, line);
 
  639         } 
else if (strcasecmp(token, 
"end") == 0) {
 
  640                 if (token2 == NULL) {
 
  641                         if (new_entry != NULL) {
 
  643                                 if (new_entry->prog == NULL) {
 
  645                                                 "%s: prog missing in config before line %d\n", lirc_prog,
 
  647                                         lirc_freeconfigentries(new_entry);
 
  651                                 if (strcasecmp(new_entry->prog,
 
  653                                         lirc_freeconfigentries(new_entry);
 
  658                                 new_entry->next_code = new_entry->code;
 
  659                                 new_entry->next_config = new_entry->config;
 
  660                                 if (*last_config == NULL) {
 
  661                                         *first_config = new_entry;
 
  662                                         *last_config = new_entry;
 
  664                                         (*last_config)->next = new_entry;
 
  665                                         *last_config = new_entry;
 
  670                                         new_entry->mode = strdup(*mode);
 
  671                                         if (new_entry->mode == NULL) {
 
  673                                                         "%s: out of memory\n",
 
  680                                     new_entry->prog != NULL &&
 
  681                                     strcasecmp(new_entry->prog,
 
  685                                         list = new_entry->config;
 
  686                                         while (list != NULL) {
 
  687                                                 if (check(list->string) == -1)
 
  693                                 if (new_entry->rep_delay == 0 &&
 
  695                                         new_entry->rep_delay = new_entry->rep -
 
  699                                         "%s: %s:%d: 'end' without 'begin'\n",
 
  700                                         lirc_prog, name, line);
 
  705                                 if (new_entry != NULL) {
 
  707                                                 "%s: %s:%d: missing 'end' token\n",
 
  708                                                 lirc_prog, name, line);
 
  711                                 if (strcasecmp(*mode, token2) == 0) {
 
  715                                         lirc_printf(
"%s: \"%s\" doesn't " 
  716                                                     "match mode \"%s\"\n",
 
  717                                                     lirc_prog, token2, *mode);
 
  722                                         "%s: %s:%d: 'end %s' without 'begin'\n",
 
  723                                         lirc_prog, name, line, token2);
 
  728                 lirc_printf(
"%s: unknown token \"%s\" in %s:%d ignored\n",
 
  729                             lirc_prog, token, name, line);
 
  735 unsigned int lirc_flags(
char* 
string)
 
  741         s = strtok(
string, 
" \t|");
 
  743                 if (strcasecmp(s, 
"once") == 0)
 
  745                 else if (strcasecmp(s, 
"quit") == 0)
 
  747                 else if (strcasecmp(s, 
"mode") == 0)
 
  749                 else if (strcasecmp(s, 
"startup_mode") == 0)
 
  750                         flags |= startup_mode;
 
  751                 else if (strcasecmp(s, 
"toggle_reset") == 0)
 
  752                         flags |= toggle_reset;
 
  754                         lirc_printf(
"%s: unknown flag \"%s\"\n", lirc_prog, s);
 
  755                 s = strtok(NULL, 
" \t");
 
  770 static char* get_homepath(
void)
 
  775         filename = malloc(MAXPATHLEN);
 
  776         if (filename == NULL) {
 
  777                 lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  780         home = getenv(
"HOME");
 
  781         home = home == NULL ? 
"/" : home;
 
  782         strncpy(filename, home, MAXPATHLEN);
 
  783         if (filename[strlen(filename) - 1] == 
'/')
 
  784                 filename[strlen(filename) - 1] = 
'\0';
 
  794 static char* get_freedesktop_path(
void)
 
  798         if (getenv(
"XDG_CONFIG_HOME") != NULL) {
 
  799                 path = malloc(MAXPATHLEN);
 
  800                 strncpy(path, getenv(
"XDG_CONFIG_HOME"), MAXPATHLEN);
 
  801                 strncat(path, 
"/", MAXPATHLEN - strlen(path));
 
  802                 strncat(path, 
CFG_LIRCRC, MAXPATHLEN - strlen(path));
 
  804                 path = get_homepath();
 
  807                 strncat(path, 
"/.config/lircrc", MAXPATHLEN - strlen(path) - 1);
 
  809         if (access(path, R_OK) != 0)
 
  815 static char* lirc_getfilename(
const char* file, 
const char* current_file)
 
  820                 filename = get_freedesktop_path();
 
  821                 if (filename == NULL) {
 
  823                 } 
else if (strlen(filename) == 0) {
 
  825                         filename = get_homepath();
 
  826                         if (filename == NULL)
 
  830                 filename = realloc(filename, strlen(filename) + 1);
 
  831         } 
else if (strncmp(file, 
"~/", 2) == 0) {
 
  832                 filename = get_homepath();
 
  833                 if (filename == NULL)
 
  835                 strcat(filename, file + 1);
 
  836                 filename = realloc(filename, strlen(filename) + 1);
 
  837         } 
else if (file[0] == 
'/' || current_file == NULL) {
 
  839                 filename = strdup(file);
 
  840                 if (filename == NULL) {
 
  841                         lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  846                 int pathlen = strlen(current_file);
 
  848                 while (pathlen > 0 && current_file[pathlen - 1] != 
'/')
 
  850                 filename = (
char*)malloc(pathlen + strlen(file) + 1);
 
  851                 if (filename == NULL) {
 
  852                         lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  855                 memcpy(filename, current_file, pathlen);
 
  856                 filename[pathlen] = 0;
 
  857                 strcat(filename, file);
 
  863 static FILE* lirc_open(
const char*      file,
 
  864                        const char*      current_file,
 
  870         filename = lirc_getfilename(file, current_file);
 
  871         if (filename == NULL)
 
  874         fin = fopen(filename, 
"r");
 
  875         if (fin == NULL && (file != NULL || errno != ENOENT)) {
 
  876                 lirc_printf(
"%s: could not open config file %s\n", lirc_prog,
 
  878                 lirc_perror(lirc_prog);
 
  879         } 
else if (fin == NULL) {
 
  882                 fin = fopen(root_file, 
"r");
 
  883                 if (fin == NULL && errno == ENOENT) {
 
  884                         int save_errno = errno;
 
  887                         fin = fopen(root_file, 
"r");
 
  890                 if (fin == NULL && errno != ENOENT) {
 
  891                         lirc_printf(
"%s: could not open config file %s\n",
 
  893                         lirc_perror(lirc_prog);
 
  894                 } 
else if (fin == NULL) {
 
  895                         lirc_printf(
"%s: could not open config files " 
  896                                     "%s and %s\n", lirc_prog, filename,
 
  898                         lirc_perror(lirc_prog);
 
  901                         filename = strdup(root_file);
 
  902                         if (filename == NULL) {
 
  904                                 lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  909         if (full_name && fin != NULL)
 
  910                 *full_name = filename;
 
  917 static struct filestack_t* stack_push(
struct filestack_t* parent)
 
  919         struct filestack_t* entry;
 
  921         entry = malloc(
sizeof(
struct filestack_t));
 
  923                 lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  929         entry->parent = parent;
 
  934 static struct filestack_t* stack_pop(
struct filestack_t* entry)
 
  936         struct filestack_t* parent = NULL;
 
  939                 parent = entry->parent;
 
  948 static void stack_free(
struct filestack_t* entry)
 
  951                 entry = stack_pop(entry);
 
  963         while (scan != NULL) {
 
  964                 if (scan->flags & startup_mode) {
 
  965                         if (scan->change_mode != NULL) {
 
  966                                 startupmode = scan->change_mode;
 
  968                                 scan->change_mode = NULL;
 
  971                         lirc_printf(
"%s: startup_mode flags requires 'mode ='\n", lirc_prog);
 
  977         if (startupmode == NULL) {
 
  979                 while (scan != NULL) {
 
  980                         if (scan->mode != NULL
 
  982                             && strcasecmp(lirc_prog, scan->mode) == 0) {
 
  983                                 startupmode = lirc_prog;
 
  990         if (startupmode == NULL)
 
  993         while (scan != NULL) {
 
  994                 if (scan->change_mode != NULL
 
  995                     && scan->flags & once
 
  996                     && strcasecmp(startupmode, scan->change_mode) == 0)
 
 1018                         free(c->change_mode);
 
 1023                 while (code != NULL) {
 
 1024                         if (code->remote != NULL && code->remote != LIRC_ALL)
 
 1026                         if (code->button != NULL && code->button != LIRC_ALL)
 
 1028                         code_temp = code->next;
 
 1034                 while (list != NULL) {
 
 1037                         list_temp = list->next;
 
 1041                 config_temp = c->next;
 
 1049 parse_shebang(
char* line, 
int depth, 
const char* path, 
char* buff, 
size_t size)
 
 1053         const char* 
const SHEBANG_MSG =
 
 1054                 "Warning: Use of deprecated lircrc shebang." 
 1055                 " Use lircrc_class instead.\n";
 
 1057         token = strtok(line, 
"#! ");
 
 1060                 lirc_printf(
"Warning: ignoring shebang in included file.");
 
 1063         if (strcmp(token, 
"lircrc") == 0) {
 
 1064                 strncpy(my_path, path, 
sizeof(my_path) - 1);
 
 1065                 strncat(buff, basename(my_path), size - 1);
 
 1066                 lirc_printf(SHEBANG_MSG);
 
 1068                 lirc_printf(
"Warning: bad shebang (ignored)");
 
 1073 static int lirc_readconfig_only_internal(
const char*            file,
 
 1075                                          int                    (check)(
char* s),
 
 1078         const char* 
const INCLUDED_LIRCRC_CLASS =
 
 1079                 "Warning: lirc_class in included file (ignored)";
 
 1085         struct filestack_t* filestack;
 
 1086         struct filestack_t* stack_tmp;
 
 1088         char lircrc_class[128] = { 
'\0' };
 
 1096         char* save_full_name = NULL;
 
 1098         filestack = stack_push(NULL);
 
 1099         if (filestack == NULL)
 
 1101         filestack->file = lirc_open(file, NULL, &(filestack->name));
 
 1102         if (filestack->file == NULL) {
 
 1103                 stack_free(filestack);
 
 1106         filestack->line = 0;
 
 1109         first = new_entry = last = NULL;
 
 1113                 ret = lirc_readline(&
string, filestack->file);
 
 1114                 if (ret == -1 || 
string == NULL) {
 
 1115                         fclose(filestack->file);
 
 1116                         if (open_files == 1 && full_name != NULL) {
 
 1117                                 save_full_name = filestack->name;
 
 1118                                 filestack->name = NULL;
 
 1120                         filestack = stack_pop(filestack);
 
 1127                         if (strncmp(
string, 
"#!", 2) == 0) {
 
 1128                                 parse_shebang(
string,
 
 1132                                               sizeof(lircrc_class));
 
 1136                 eq = strchr(
string, 
'=');
 
 1138                         token = strtok(
string, 
" \t");
 
 1139                         if (token == NULL) {
 
 1141                         } 
else if (token[0] == 
'#') {
 
 1143                         } 
else if (strcasecmp(token, 
"lircrc_class") == 0) {
 
 1144                                 token2 = lirc_trim(strtok(NULL, 
""));
 
 1145                                 if (strlen(token2) == 0) {
 
 1147                                                 "Warning: no lircrc_class");
 
 1148                                 } 
else if (open_files == 1) {
 
 1149                                         strncpy(lircrc_class,
 
 1151                                                 sizeof(lircrc_class) - 1);
 
 1153                                         lirc_printf(INCLUDED_LIRCRC_CLASS);
 
 1155                         } 
else if (strcasecmp(token, 
"include") == 0) {
 
 1156                                 if (open_files >= MAX_INCLUDES) {
 
 1157                                         lirc_printf(
"%s: too many files " 
 1158                                                     "included at %s:%d\n",
 
 1159                                                     lirc_prog, filestack->name,
 
 1163                                         token2 = strtok(NULL, 
"");
 
 1164                                         token2 = lirc_trim(token2);
 
 1165                                         lirc_parse_include(token2,
 
 1168                                         stack_tmp = stack_push(filestack);
 
 1169                                         if (stack_tmp == NULL) {
 
 1177                                                 stack_tmp->line = 0;
 
 1178                                                 if (stack_tmp->file) {
 
 1180                                                         filestack = stack_tmp;
 
 1182                                                         stack_pop(stack_tmp);
 
 1188                                 token2 = strtok(NULL, 
" \t");
 
 1190                                         token3 = strtok(NULL, 
" \t");
 
 1191                                 if (token2 != NULL && token3 != NULL) {
 
 1192                                         lirc_printf(
"%s: unexpected token in line %s:%d\n",
 
 1193                                                     lirc_prog, filestack->name, filestack->line);
 
 1195                                         ret = lirc_mode(token, token2, &mode,
 
 1198                                                         check, filestack->name,
 
 1201                                                 if (remote != LIRC_ALL)
 
 1209                                                 if (new_entry != NULL) {
 
 1210                                                         lirc_freeconfigentries(
 
 1219                         token = lirc_trim(
string);
 
 1220                         token2 = lirc_trim(eq + 1);
 
 1221                         if (token[0] == 
'#') {
 
 1223                         } 
else if (new_entry == NULL) {
 
 1224                                 lirc_printf(
"%s: bad file format, %s:%d\n",
 
 1225                                             lirc_prog, filestack->name,
 
 1229                                 token2 = strdup(token2);
 
 1230                                 if (token2 == NULL) {
 
 1231                                         lirc_printf(
"%s: out of memory\n",
 
 1234                                 } 
else if (strcasecmp(token, 
"prog") == 0) {
 
 1235                                         if (new_entry->prog != NULL)
 
 1236                                                 free(new_entry->prog);
 
 1237                                         new_entry->prog = token2;
 
 1238                                 } 
else if (strcasecmp(token, 
"remote") == 0) {
 
 1239                                         if (remote != LIRC_ALL)
 
 1242                                         if (strcasecmp(
"*", token2) == 0) {
 
 1248                                 } 
else if (strcasecmp(token, 
"button") == 0) {
 
 1256                                                         "%s: out of memory\n",
 
 1260                                                 code->remote = remote;
 
 1263                                                         code->button = LIRC_ALL;
 
 1266                                                         code->button = token2;
 
 1270                                                 if (new_entry->code == NULL)
 
 1271                                                         new_entry->code = code;
 
 1273                                                         new_entry->next_code->
 
 1275                                                 new_entry->next_code = code;
 
 1276                                                 if (remote != LIRC_ALL) {
 
 1277                                                         remote = strdup(remote);
 
 1278                                                         if (remote == NULL) {
 
 1280                                                                         "%s: out of memory\n",
 
 1286                                 } 
else if (strcasecmp(token, 
"delay") == 0) {
 
 1290                                         new_entry->rep_delay = strtoul(token2,
 
 1292                                         if ((new_entry->rep_delay ==
 
 1293                                              ULONG_MAX && errno == ERANGE)
 
 1294                                             || end[0] != 0 || strlen(token2) ==
 
 1296                                                 lirc_printf(
"%s: \"%s\" not" 
 1297                                                             " a  valid number for delay\n", lirc_prog,
 
 1300                                 } 
else if (strcasecmp(token, 
"ignore_first_events") == 0) {
 
 1304                                         new_entry->ign_first_events = strtoul(
 
 1306                                         if ((new_entry->ign_first_events ==
 
 1307                                              ULONG_MAX && errno == ERANGE)
 
 1308                                             || end[0] != 0 || strlen(token2) ==
 
 1310                                                 lirc_printf(
"%s: \"%s\" not" 
 1311                                                             " a  valid number for ignore_first_events\n",
 
 1314                                 } 
else if (strcasecmp(token, 
"repeat") == 0) {
 
 1319                                                 strtoul(token2, &end, 0);
 
 1320                                         if ((new_entry->rep == ULONG_MAX &&
 
 1322                                             || end[0] != 0 || strlen(token2) ==
 
 1324                                                 lirc_printf(
"%s: \"%s\" not" 
 1325                                                             " a  valid number for repeat\n", lirc_prog,
 
 1328                                 } 
else if (strcasecmp(token, 
"config") == 0) {
 
 1333                                         if (new_list == NULL) {
 
 1336                                                         "%s: out of memory\n",
 
 1340                                                 lirc_parse_string(token2,
 
 1343                                                 new_list->string = token2;
 
 1344                                                 new_list->next = NULL;
 
 1345                                                 if (new_entry->config == NULL)
 
 1349                                                         new_entry->next_config->
 
 1351                                                 new_entry->next_config =
 
 1354                                 } 
else if (strcasecmp(token, 
"mode") == 0) {
 
 1355                                         if (new_entry->change_mode != NULL)
 
 1356                                                 free(new_entry->change_mode);
 
 1357                                         new_entry->change_mode = token2;
 
 1358                                 } 
else if (strcasecmp(token, 
"flags") == 0) {
 
 1359                                         new_entry->flags = lirc_flags(token2);
 
 1364                                                 "%s: unknown token \"%s\" in %s:%d ignored\n",
 
 1365                                                 lirc_prog, token, filestack->name,
 
 1374         if (remote != LIRC_ALL)
 
 1376         if (new_entry != NULL) {
 
 1378                         ret = lirc_mode(
"end", NULL, &mode, &new_entry, &first,
 
 1379                                         &last, check, 
"", 0);
 
 1381                                 "%s: warning: end token missing at end of file\n",
 
 1384                         lirc_freeconfigentries(new_entry);
 
 1391                                 "%s: warning: no end token found for mode \"%s\"\n", lirc_prog,
 
 1400                 if (*config == NULL) {
 
 1401                         lirc_printf(
"%s: out of memory\n", lirc_prog);
 
 1402                         lirc_freeconfigentries(first);
 
 1405                 (*config)->first = first;
 
 1406                 (*config)->next = first;
 
 1407                 startupmode = lirc_startupmode((*config)->first);
 
 1408                 (*config)->current_mode =
 
 1409                         startupmode ? strdup(startupmode) : NULL;
 
 1413                         (*config)->lircrc_class = NULL;
 
 1414                 (*config)->sockfd = -1;
 
 1415                 if (full_name != NULL) {
 
 1416                         *full_name = save_full_name;
 
 1417                         save_full_name = NULL;
 
 1421                 lirc_freeconfigentries(first);
 
 1424                 stack_free(filestack);
 
 1426                 free(save_full_name);
 
 1431 int lirc_identify(
int sockfd)
 
 1441         while (ret == EAGAIN || ret == EWOULDBLOCK);
 
 1442         return ret == 0 ? LIRC_RET_SUCCESS : -1;
 
 1449                     int (check)(
char* s))
 
 1451         struct sockaddr_un addr;
 
 1458         if (lirc_readconfig_only_internal(file, config, check, &filename) == -1)
 
 1461         if ((*config)->lircrc_class == NULL)
 
 1462                 goto lirc_readconfig_compat;
 
 1466         addr.sun_family = AF_UNIX;
 
 1469                                sizeof(addr.sun_path)) > 
sizeof(addr.sun_path)) {
 
 1470                 lirc_printf(
"%s: WARNING: file name too long\n", lirc_prog);
 
 1471                 goto lirc_readconfig_compat;
 
 1473         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
 
 1475                 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
 
 1476                 lirc_perror(lirc_prog);
 
 1477                 goto lirc_readconfig_compat;
 
 1479         if (connect(sockfd, (
struct sockaddr*)&addr, 
sizeof(addr)) != -1) {
 
 1480                 (*config)->sockfd = sockfd;
 
 1484                 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS)
 
 1495         snprintf(command, 
sizeof(command),
 
 1496                  "lircrcd %s", (*config)->lircrc_class);
 
 1497         ret = system(command);
 
 1498         if (ret == -1 || WEXITSTATUS(ret) != EXIT_SUCCESS)
 
 1499                 goto lirc_readconfig_compat;
 
 1502         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
 
 1504                 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
 
 1505                 lirc_perror(lirc_prog);
 
 1506                 goto lirc_readconfig_compat;
 
 1508         if (connect(sockfd, (
struct sockaddr*)&addr, 
sizeof(addr)) != -1) {
 
 1509                 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS) {
 
 1510                         (*config)->sockfd = sockfd;
 
 1518 lirc_readconfig_compat:
 
 1528                          int                    (check) (
char* s))
 
 1530         return lirc_readconfig_only_internal(file, config, check, NULL);
 
 1536         if (config != NULL) {
 
 1537                 if (config->sockfd != -1) {
 
 1538                         (void)close(config->sockfd);
 
 1539                         config->sockfd = -1;
 
 1543                 lirc_freeconfigentries(config->first);
 
 1544                 free(config->current_mode);
 
 1550 static void lirc_clearmode(
struct lirc_config* config)
 
 1554         if (config->current_mode == NULL)
 
 1556         scan = config->first;
 
 1557         while (scan != NULL) {
 
 1558                 if (scan->change_mode != NULL)
 
 1559                         if (strcasecmp(scan->change_mode,
 
 1560                                        config->current_mode) == 0)
 
 1561                                 scan->flags &= ~ecno;
 
 1564         free(config->current_mode);
 
 1565         config->current_mode = NULL;
 
 1569 static char* lirc_execute(
struct lirc_config*           config,
 
 1575         if (scan->flags & mode)
 
 1576                 lirc_clearmode(config);
 
 1577         if (scan->change_mode != NULL) {
 
 1578                 free(config->current_mode);
 
 1579                 config->current_mode = strdup(scan->change_mode);
 
 1580                 if (scan->flags & once) {
 
 1581                         if (scan->flags & ecno)
 
 1584                                 scan->flags |= ecno;
 
 1587         if (scan->next_config != NULL
 
 1588             && scan->prog != NULL
 
 1589             && (lirc_prog == NULL || strcasecmp(scan->prog, lirc_prog) == 0)
 
 1591                 s = scan->next_config->string;
 
 1592                 scan->next_config = scan->next_config->next;
 
 1593                 if (scan->next_config == NULL)
 
 1594                         scan->next_config = scan->config;
 
 1610         int delay_start, rep_delay;
 
 1612         if (scan->ign_first_events) {
 
 1613                 if (scan->rep_delay && rep == 0)        
 
 1615                                 "%s: ignoring \"delay\" because \"ignore_first_events\" is also set\n",
 
 1617                 rep_delay = scan->ign_first_events;
 
 1620                 rep_delay = scan->rep_delay;
 
 1624         if (rep < delay_start)
 
 1627         if (scan->rep == 0 && rep_delay > 0 && rep == rep_delay + delay_start)
 
 1630         if (scan->rep > 0 && rep >= rep_delay + delay_start) {
 
 1631                 rep -= rep_delay + delay_start;
 
 1632                 return (rep % scan->rep) == 0;
 
 1645         if (scan->code == NULL)
 
 1646                 return rep_filter(scan, rep);
 
 1649         if (scan->next_code->remote == LIRC_ALL
 
 1650             || strcasecmp(scan->next_code->remote, remote) == 0) {
 
 1651                 if (scan->next_code->button == LIRC_ALL
 
 1652                     || strcasecmp(scan->next_code->button, button) == 0) {
 
 1655                         if (scan->code->next == NULL || rep == 0) {
 
 1656                                 scan->next_code = scan->next_code->next;
 
 1657                                 if (scan->code->next != NULL)
 
 1661                         if (scan->next_code == NULL) {
 
 1662                                 scan->next_code = scan->code;
 
 1663                                 if (scan->code->next != NULL ||
 
 1664                                     rep_filter(scan, rep))
 
 1675         if (scan->flags & toggle_reset)
 
 1676                 scan->next_config = scan->config;
 
 1679         if (codes == scan->next_code)
 
 1681         codes = codes->next;
 
 1683         while (codes != scan->next_code->next) {
 
 1690                 while (next != scan->next_code) {
 
 1691                         if (prev->remote == LIRC_ALL
 
 1692                             || strcasecmp(prev->remote, next->remote) == 0) {
 
 1693                                 if (prev->button == LIRC_ALL
 
 1694                                     || strcasecmp(prev->button,
 
 1695                                                   next->button) == 0) {
 
 1708                         if (prev->remote == LIRC_ALL
 
 1709                             || strcasecmp(prev->remote, remote) == 0) {
 
 1710                                 if (prev->button == LIRC_ALL
 
 1711                                     || strcasecmp(prev->button, button) == 0) {
 
 1713                                                 scan->next_code = prev->next;
 
 1719                 codes = codes->next;
 
 1721         scan->next_code = scan->code;
 
 1728         static int warning = 1;
 
 1732                 fprintf(stderr, 
"%s: warning: lirc_ir2char() is obsolete\n",
 
 1742 static int lirc_code2char_internal(
struct lirc_config*  config,
 
 1757         if (sscanf(code, 
"%*x %x %*s %*s\n", &rep) == 1) {
 
 1758                 backup = strdup(code);
 
 1762                 strtok(backup, 
" ");
 
 1764                 button = strtok(NULL, 
" ");
 
 1765                 remote = strtok(NULL, 
"\n");
 
 1767                 if (button == NULL || remote == NULL) {
 
 1772                 scan = config->next;
 
 1774                 while (scan != NULL) {
 
 1775                         exec_level = lirc_iscode(scan, remote, button, rep);
 
 1776                         if (exec_level > 0 &&
 
 1777                             (scan->mode == NULL ||
 
 1778                              (scan->mode != NULL &&
 
 1779                               config->current_mode != NULL &&
 
 1780                               strcasecmp(scan->mode,
 
 1781                                          config->current_mode) == 0)) &&
 
 1782                             quit_happened == 0) {
 
 1783                                 if (exec_level > 1) {
 
 1784                                         s = lirc_execute(config, scan);
 
 1785                                         if (s != NULL && prog != NULL)
 
 1790                                 if (scan->flags & quit) {
 
 1792                                         config->next = NULL;
 
 1795                                 } 
else if (s != NULL) {
 
 1796                                         config->next = scan->next;
 
 1808         config->next = config->first;
 
 1821         my_code = strdup(code);
 
 1822         pos = rindex(my_code, 
'\n');
 
 1829         if (config->sockfd != -1) {
 
 1832                 while (ret == EAGAIN || ret == EWOULDBLOCK);
 
 1835                         *
string = static_buff;
 
 1837                 return ret == 0 ? 0 : -1;
 
 1839         return lirc_code2char_internal(config, code, 
string, NULL);
 
 1843 int lirc_code2charprog(
struct lirc_config*      config,
 
 1854         ret = lirc_code2char_internal(config, code, 
string, prog);
 
 1863         static int warning = 1;
 
 1868                 fprintf(stderr, 
"%s: warning: lirc_nextir() is obsolete\n",
 
 1882         static int end_len = 0;
 
 1888         if (lirc_buffer == NULL) {
 
 1889                 lirc_buffer = (
char*)malloc(packet_size + 1);
 
 1890                 if (lirc_buffer == NULL) {
 
 1891                         lirc_printf(
"%s: out of memory\n", lirc_prog);
 
 1896         while ((end = strchr(lirc_buffer, 
'\n')) == NULL) {
 
 1897                 if (end_len >= packet_size) {
 
 1902                                 (
char*)realloc(lirc_buffer, packet_size + 1);
 
 1903                         if (new_buffer == NULL)
 
 1905                         lirc_buffer = new_buffer;
 
 1907                 len = read(lirc_lircd, lirc_buffer + end_len,
 
 1908                            packet_size - end_len);
 
 1910                         if (len == -1 && errno == EAGAIN)
 
 1916                 lirc_buffer[end_len] = 0;
 
 1918                 end = strchr(lirc_buffer, 
'\n');
 
 1925         end_len = strlen(end);
 
 1928         *code = strdup(lirc_buffer);
 
 1930         memmove(lirc_buffer, end, end_len + 1);
 
 1939         id = 
id != NULL ? id : 
"default";
 
 1940         snprintf(buf, size, VARRUNDIR 
"/%d-%s-lircrcd.socket", getuid(), 
id);
 
 1952         if (config->sockfd != -1) {
 
 1956                 while (ret == EAGAIN || ret == EWOULDBLOCK);
 
 1963         return config->current_mode;
 
 1973         if (config->sockfd != -1) {
 
 1982                 while (r == EAGAIN || r == EWOULDBLOCK);
 
 1989         free(config->current_mode);
 
 1990         config->current_mode = mode ? strdup(mode) : NULL;
 
 1991         return config->current_mode;
 
 2005         while (r == EAGAIN);
 
 2020                               scancode, repeat, keysym, remote);
 
 2025         while (r == EAGAIN);
 
 2032 do_connect(
int domain, 
struct sockaddr* addr, 
size_t size, 
int quiet)
 
 2036         fd = socket(domain, SOCK_STREAM, 0);
 
 2039                         fprintf(stderr, 
"do_connect: could not open socket\n");
 
 2044         if (connect(fd, addr, size) == -1) {
 
 2047                                 "do_connect: could not connect to socket\n");
 
 2058         const char* socket_path;
 
 2059         struct sockaddr_un addr_un;
 
 2061         socket_path = path ? path : getenv(
"LIRC_SOCKET_PATH");
 
 2062         socket_path = socket_path ? socket_path : 
LIRCD;
 
 2063         if (strlen(socket_path) + 1 > 
sizeof(addr_un.sun_path)) {
 
 2066                         fprintf(stderr, 
"%s: socket name is too long\n", prog);
 
 2067                 return -ENAMETOOLONG;
 
 2069         addr_un.sun_family = AF_UNIX;
 
 2070         strcpy(addr_un.sun_path, socket_path);
 
 2071         return do_connect(AF_UNIX,
 
 2072                           (
struct sockaddr*)&addr_un,
 
 2080         struct addrinfo* addrinfos;
 
 2085         snprintf(service, 
sizeof(service),
 
 2087         r = getaddrinfo(address, service, NULL, &addrinfos);
 
 2090                         fprintf(stderr, 
"get_remote_socket: host %s unknown\n",
 
 2092                 return -EADDRNOTAVAIL;
 
 2094         for (a = addrinfos; a != NULL; a = a->ai_next) {
 
 2095                 r = do_connect(a->ai_family, a->ai_addr, a->ai_addrlen, quiet);
 
 2099         freeaddrinfo(addrinfos);
 
int lirc_send_one(int fd, const char *remote, const char *keysym)
Send keysym using given remote.
int lirc_get_local_socket(const char *path, int quiet)
Return an opened and connected file descriptor to local lirc socket.
const char * lirc_setmode(struct lirc_config *config, const char *mode)
Set mode defined in lircrc.
int lirc_command_init(lirc_cmd_ctx *ctx, const char *fmt,...)
Initiate a lirc_cmd_ctx to run a command.
int lirc_deinit(void)
Release resources allocated by lirc_init(), basically disconnect from socket.
const char * lirc_getmode(struct lirc_config *config)
Get mode defined in lircrc.
void lirc_set_verbose(int v)
Dynamically change the verbose level defined by lirc_init().
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_get_remote_socket(const char *address, int port, int quiet)
Return an opened and connected file descriptor to remote lirc socket.
int lirc_command_run(lirc_cmd_ctx *ctx, int fd)
Run a command in non-blocking mode.
int lirc_code2char(struct lirc_config *config, char *code, char **string)
Translate a code string to an application string using .lircrc.
int lirc_readconfig_only(const char *file, struct lirc_config **config, int(check)(char *s))
Parse a lircrc configuration file without connecting to lircrcd.
char * lirc_ir2char(struct lirc_config *config, char *code)
size_t lirc_getsocketname(const char *id, char *buf, size_t size)
Retrieve default lircrcd socket path.
void lirc_command_reply_to_stdout(lirc_cmd_ctx *ctx)
Set command_ctx write_to_stdout flag.
int lirc_simulate(int fd, const char *remote, const char *keysym, int scancode, int repeat)
Send a simulated lirc event.This call might block for some time since it involves communication with ...
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.
packet_state
protocol state.
3-rd party application interface.
#define LIRCRC_OLD_ROOT_FILE
Compatibility: Old system-wide lircrc path.
#define LIRC_INET_PORT
default port number for UDP driver
#define LIRCRC_USER_FILE
User lircrc file name.
#define CFG_LIRCRC
config file names - beneath $HOME or SYSCONFDIR
#define LIRCD
Complete lircd socket path.
#define PACKET_SIZE
IR transmission packet size.
#define LIRCRC_ROOT_FILE
System-wide lircrc path.
#define chk_write(fd, buf, count)
Wrapper for write(2) which logs errors.
The data needed to run a command on remote server.
char buffer[PACKET_SIZE+1]
Reply IO buffer.
int reply_to_stdout
If true, write reply on stdout.
char * next
Next newline-separated word in buffer.
int head
First free buffer index.
char packet[PACKET_SIZE+1]
The packet to send.
char reply[PACKET_SIZE+1]
Command reply payload.
char * lircrc_class
The lircrc instance used, if any.