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;
 
  385 static int lirc_readline(
char** line, FILE* f)
 
  392         newline = (
char*)malloc(LIRC_READ + 1);
 
  393         if (newline == NULL) {
 
  394                 lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  399                 ret = fgets(newline + len, LIRC_READ + 1, f);
 
  401                         if (feof(f) && len > 0) {
 
  409                 len = strlen(newline);
 
  410                 if (newline[len - 1] == 
'\n') {
 
  411                         newline[len - 1] = 0;
 
  416                 enlargeline = (
char*)realloc(newline, len + 1 + LIRC_READ);
 
  417                 if (enlargeline == NULL) {
 
  419                         lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  422                 newline = enlargeline;
 
  427 static char* lirc_trim(
char* s)
 
  431         while (s[0] == 
' ' || s[0] == 
'\t')
 
  436                 if (s[len] == 
' ' || s[len] == 
'\t')
 
  446 static char lirc_parse_escape(
char** s, 
const char* name, 
int line)
 
  449         unsigned int i, overflow, count;
 
  450         int digits_found, digit;
 
  490                 while (++count < 3) {
 
  492                         if (c >= 
'0' && c <= 
'7') {
 
  493                                 i = (i << 3) + c - 
'0';
 
  499                 if (i > (1 << CHAR_BIT) - 1) {
 
  500                         i &= (1 << CHAR_BIT) - 1;
 
  502                                 "%s: octal escape sequence out of range in %s:%d\n",
 
  503                                 lirc_prog, name, line);
 
  513                         if (c >= 
'0' && c <= 
'9') {
 
  515                         } 
else if (c >= 
'a' && c <= 
'f') {
 
  516                                 digit = c - 
'a' + 10;
 
  517                         } 
else if (c >= 
'A' && c <= 
'F') {
 
  518                                 digit = c - 
'A' + 10;
 
  523                         overflow |= i ^ (i << 4 >> 4);
 
  524                         i = (i << 4) + digit;
 
  528                         lirc_printf(
"%s: \\x used with no " 
  529                                     "following hex digits in %s:%d\n",
 
  530                                     lirc_prog, name, line);
 
  531                 if (overflow || i > (1 << CHAR_BIT) - 1) {
 
  532                         i &= (1 << CHAR_BIT) - 1;
 
  533                         lirc_printf(
"%s: hex escape sequence out " 
  534                                     "of range in %s:%d\n", lirc_prog, name,
 
  540                 if (c >= 
'@' && c <= 
'Z')
 
  547 static void lirc_parse_string(
char* s, 
const char* name, 
int line)
 
  555                         *t = lirc_parse_escape(&s, name, line);
 
  567 static void lirc_parse_include(
char* s, 
const char* name, 
int line)
 
  576         if (*s != 
'"' && *s != 
'<')
 
  578         if (*s == 
'"' && last != 
'"')
 
  580         else if (*s == 
'<' && last != 
'>')
 
  583         memmove(s, s + 1, len - 2 + 1); 
 
  587 int lirc_mode(
char* token, 
char* token2, 
char** mode,
 
  591               int (check) (
char* s),
 
  597         new_entry = *new_config;
 
  598         if (strcasecmp(token, 
"begin") == 0) {
 
  599                 if (token2 == NULL) {
 
  600                         if (new_entry == NULL) {
 
  603                                 if (new_entry == NULL) {
 
  604                                         lirc_printf(
"%s: out of memory\n",
 
  608                                 new_entry->prog = NULL;
 
  609                                 new_entry->code = NULL;
 
  610                                 new_entry->rep_delay = 0;
 
  611                                 new_entry->ign_first_events = 0;
 
  613                                 new_entry->config = NULL;
 
  614                                 new_entry->change_mode = NULL;
 
  615                                 new_entry->flags = none;
 
  616                                 new_entry->mode = NULL;
 
  617                                 new_entry->next_config = NULL;
 
  618                                 new_entry->next_code = NULL;
 
  619                                 new_entry->next = NULL;
 
  620                                 *new_config = new_entry;
 
  622                                 lirc_printf(
"%s: bad file format, %s:%d\n",
 
  623                                             lirc_prog, name, line);
 
  627                         if (new_entry == NULL && *mode == NULL) {
 
  628                                 *mode = strdup(token2);
 
  632                                 lirc_printf(
"%s: bad file format, %s:%d\n",
 
  633                                             lirc_prog, name, line);
 
  637         } 
else if (strcasecmp(token, 
"end") == 0) {
 
  638                 if (token2 == NULL) {
 
  639                         if (new_entry != NULL) {
 
  641                                 if (new_entry->prog == NULL) {
 
  643                                                 "%s: prog missing in config before line %d\n", lirc_prog,
 
  645                                         lirc_freeconfigentries(new_entry);
 
  649                                 if (strcasecmp(new_entry->prog,
 
  651                                         lirc_freeconfigentries(new_entry);
 
  656                                 new_entry->next_code = new_entry->code;
 
  657                                 new_entry->next_config = new_entry->config;
 
  658                                 if (*last_config == NULL) {
 
  659                                         *first_config = new_entry;
 
  660                                         *last_config = new_entry;
 
  662                                         (*last_config)->next = new_entry;
 
  663                                         *last_config = new_entry;
 
  668                                         new_entry->mode = strdup(*mode);
 
  669                                         if (new_entry->mode == NULL) {
 
  671                                                         "%s: out of memory\n",
 
  678                                     new_entry->prog != NULL &&
 
  679                                     strcasecmp(new_entry->prog,
 
  683                                         list = new_entry->config;
 
  684                                         while (list != NULL) {
 
  685                                                 if (check(list->string) == -1)
 
  691                                 if (new_entry->rep_delay == 0 &&
 
  693                                         new_entry->rep_delay = new_entry->rep -
 
  697                                         "%s: %s:%d: 'end' without 'begin'\n",
 
  698                                         lirc_prog, name, line);
 
  703                                 if (new_entry != NULL) {
 
  705                                                 "%s: %s:%d: missing 'end' token\n",
 
  706                                                 lirc_prog, name, line);
 
  709                                 if (strcasecmp(*mode, token2) == 0) {
 
  713                                         lirc_printf(
"%s: \"%s\" doesn't " 
  714                                                     "match mode \"%s\"\n",
 
  715                                                     lirc_prog, token2, *mode);
 
  720                                         "%s: %s:%d: 'end %s' without 'begin'\n",
 
  721                                         lirc_prog, name, line, token2);
 
  726                 lirc_printf(
"%s: unknown token \"%s\" in %s:%d ignored\n",
 
  727                             lirc_prog, token, name, line);
 
  733 unsigned int lirc_flags(
char* 
string)
 
  739         s = strtok(
string, 
" \t|");
 
  741                 if (strcasecmp(s, 
"once") == 0)
 
  743                 else if (strcasecmp(s, 
"quit") == 0)
 
  745                 else if (strcasecmp(s, 
"mode") == 0)
 
  747                 else if (strcasecmp(s, 
"startup_mode") == 0)
 
  748                         flags |= startup_mode;
 
  749                 else if (strcasecmp(s, 
"toggle_reset") == 0)
 
  750                         flags |= toggle_reset;
 
  752                         lirc_printf(
"%s: unknown flag \"%s\"\n", lirc_prog, s);
 
  753                 s = strtok(NULL, 
" \t");
 
  768 static char* get_homepath(
void)
 
  773         filename = malloc(MAXPATHLEN);
 
  774         if (filename == NULL) {
 
  775                 lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  778         home = getenv(
"HOME");
 
  779         home = home == NULL ? 
"/" : home;
 
  780         strncpy(filename, home, MAXPATHLEN);
 
  781         if (filename[strlen(filename) - 1] == 
'/')
 
  782                 filename[strlen(filename) - 1] = 
'\0';
 
  792 static char* get_freedesktop_path(
void)
 
  796         if (getenv(
"XDG_CONFIG_HOME") != NULL) {
 
  797                 path = malloc(MAXPATHLEN);
 
  798                 strncpy(path, getenv(
"XDG_CONFIG_HOME"), MAXPATHLEN);
 
  799                 strncat(path, 
"/", MAXPATHLEN - strlen(path));
 
  800                 strncat(path, 
CFG_LIRCRC, MAXPATHLEN - strlen(path));
 
  802                 path = get_homepath();
 
  805                 strncat(path, 
"/.config/lircrc", MAXPATHLEN - strlen(path) - 1);
 
  807         if (access(path, R_OK) != 0)
 
  813 static char* lirc_getfilename(
const char* file, 
const char* current_file)
 
  818                 filename = get_freedesktop_path();
 
  819                 if (filename == NULL) {
 
  821                 } 
else if (strlen(filename) == 0) {
 
  823                         filename = get_homepath();
 
  824                         if (filename == NULL)
 
  828                 filename = realloc(filename, strlen(filename) + 1);
 
  829         } 
else if (strncmp(file, 
"~/", 2) == 0) {
 
  830                 filename = get_homepath();
 
  831                 if (filename == NULL)
 
  833                 strcat(filename, file + 1);
 
  834                 filename = realloc(filename, strlen(filename) + 1);
 
  835         } 
else if (file[0] == 
'/' || current_file == NULL) {
 
  837                 filename = strdup(file);
 
  838                 if (filename == NULL) {
 
  839                         lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  844                 int pathlen = strlen(current_file);
 
  846                 while (pathlen > 0 && current_file[pathlen - 1] != 
'/')
 
  848                 filename = (
char*)malloc(pathlen + strlen(file) + 1);
 
  849                 if (filename == NULL) {
 
  850                         lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  853                 memcpy(filename, current_file, pathlen);
 
  854                 filename[pathlen] = 0;
 
  855                 strcat(filename, file);
 
  861 static FILE* lirc_open(
const char*      file,
 
  862                        const char*      current_file,
 
  868         filename = lirc_getfilename(file, current_file);
 
  869         if (filename == NULL)
 
  872         fin = fopen(filename, 
"r");
 
  873         if (fin == NULL && (file != NULL || errno != ENOENT)) {
 
  874                 lirc_printf(
"%s: could not open config file %s\n", lirc_prog,
 
  876                 lirc_perror(lirc_prog);
 
  877         } 
else if (fin == NULL) {
 
  880                 fin = fopen(root_file, 
"r");
 
  881                 if (fin == NULL && errno == ENOENT) {
 
  882                         int save_errno = errno;
 
  885                         fin = fopen(root_file, 
"r");
 
  888                 if (fin == NULL && errno != ENOENT) {
 
  889                         lirc_printf(
"%s: could not open config file %s\n",
 
  891                         lirc_perror(lirc_prog);
 
  892                 } 
else if (fin == NULL) {
 
  893                         lirc_printf(
"%s: could not open config files " 
  894                                     "%s and %s\n", lirc_prog, filename,
 
  896                         lirc_perror(lirc_prog);
 
  899                         filename = strdup(root_file);
 
  900                         if (filename == NULL) {
 
  902                                 lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  907         if (full_name && fin != NULL)
 
  908                 *full_name = filename;
 
  915 static struct filestack_t* stack_push(
struct filestack_t* parent)
 
  917         struct filestack_t* entry;
 
  919         entry = malloc(
sizeof(
struct filestack_t));
 
  921                 lirc_printf(
"%s: out of memory\n", lirc_prog);
 
  927         entry->parent = parent;
 
  932 static struct filestack_t* stack_pop(
struct filestack_t* entry)
 
  934         struct filestack_t* parent = NULL;
 
  937                 parent = entry->parent;
 
  946 static void stack_free(
struct filestack_t* entry)
 
  949                 entry = stack_pop(entry);
 
  961         while (scan != NULL) {
 
  962                 if (scan->flags & startup_mode) {
 
  963                         if (scan->change_mode != NULL) {
 
  964                                 startupmode = scan->change_mode;
 
  966                                 scan->change_mode = NULL;
 
  969                         lirc_printf(
"%s: startup_mode flags requires 'mode ='\n", lirc_prog);
 
  975         if (startupmode == NULL) {
 
  977                 while (scan != NULL) {
 
  978                         if (scan->mode != NULL
 
  980                             && strcasecmp(lirc_prog, scan->mode) == 0) {
 
  981                                 startupmode = lirc_prog;
 
  988         if (startupmode == NULL)
 
  991         while (scan != NULL) {
 
  992                 if (scan->change_mode != NULL
 
  993                     && scan->flags & once
 
  994                     && strcasecmp(startupmode, scan->change_mode) == 0)
 
 1016                         free(c->change_mode);
 
 1021                 while (code != NULL) {
 
 1022                         if (code->remote != NULL && code->remote != LIRC_ALL)
 
 1024                         if (code->button != NULL && code->button != LIRC_ALL)
 
 1026                         code_temp = code->next;
 
 1032                 while (list != NULL) {
 
 1035                         list_temp = list->next;
 
 1039                 config_temp = c->next;
 
 1047 parse_shebang(
char* line, 
int depth, 
const char* path, 
char* buff, 
size_t size)
 
 1051         const char* 
const SHEBANG_MSG =
 
 1052                 "Warning: Use of deprecated lircrc shebang." 
 1053                 " Use lircrc_class instead.\n";
 
 1055         token = strtok(line, 
"#! ");
 
 1058                 lirc_printf(
"Warning: ignoring shebang in included file.");
 
 1061         if (strcmp(token, 
"lircrc") == 0) {
 
 1062                 strncpy(my_path, path, 
sizeof(my_path) - 1);
 
 1063                 strncat(buff, basename(my_path), size - 1);
 
 1064                 lirc_printf(SHEBANG_MSG);
 
 1066                 lirc_printf(
"Warning: bad shebang (ignored)");
 
 1071 static int lirc_readconfig_only_internal(
const char*            file,
 
 1073                                          int                    (check)(
char* s),
 
 1076         const char* 
const INCLUDED_LIRCRC_CLASS =
 
 1077                 "Warning: lirc_class in included file (ignored)";
 
 1083         struct filestack_t* filestack;
 
 1084         struct filestack_t* stack_tmp;
 
 1086         char lircrc_class[128] = { 
'\0' };
 
 1094         char* save_full_name = NULL;
 
 1096         filestack = stack_push(NULL);
 
 1097         if (filestack == NULL)
 
 1099         filestack->file = lirc_open(file, NULL, &(filestack->name));
 
 1100         if (filestack->file == NULL) {
 
 1101                 stack_free(filestack);
 
 1104         filestack->line = 0;
 
 1107         first = new_entry = last = NULL;
 
 1111                 ret = lirc_readline(&
string, filestack->file);
 
 1112                 if (ret == -1 || 
string == NULL) {
 
 1113                         fclose(filestack->file);
 
 1114                         if (open_files == 1 && full_name != NULL) {
 
 1115                                 save_full_name = filestack->name;
 
 1116                                 filestack->name = NULL;
 
 1118                         filestack = stack_pop(filestack);
 
 1125                         if (strncmp(
string, 
"#!", 2) == 0) {
 
 1126                                 parse_shebang(
string,
 
 1130                                               sizeof(lircrc_class));
 
 1134                 eq = strchr(
string, 
'=');
 
 1136                         token = strtok(
string, 
" \t");
 
 1137                         if (token == NULL) {
 
 1139                         } 
else if (token[0] == 
'#') {
 
 1141                         } 
else if (strcasecmp(token, 
"lircrc_class") == 0) {
 
 1142                                 token2 = lirc_trim(strtok(NULL, 
""));
 
 1143                                 if (strlen(token2) == 0) {
 
 1145                                                 "Warning: no lircrc_class");
 
 1146                                 } 
else if (open_files == 1) {
 
 1147                                         strncpy(lircrc_class,
 
 1149                                                 sizeof(lircrc_class) - 1);
 
 1151                                         lirc_printf(INCLUDED_LIRCRC_CLASS);
 
 1153                         } 
else if (strcasecmp(token, 
"include") == 0) {
 
 1154                                 if (open_files >= MAX_INCLUDES) {
 
 1155                                         lirc_printf(
"%s: too many files " 
 1156                                                     "included at %s:%d\n",
 
 1157                                                     lirc_prog, filestack->name,
 
 1161                                         token2 = strtok(NULL, 
"");
 
 1162                                         token2 = lirc_trim(token2);
 
 1163                                         lirc_parse_include(token2,
 
 1166                                         stack_tmp = stack_push(filestack);
 
 1167                                         if (stack_tmp == NULL) {
 
 1175                                                 stack_tmp->line = 0;
 
 1176                                                 if (stack_tmp->file) {
 
 1178                                                         filestack = stack_tmp;
 
 1180                                                         stack_pop(stack_tmp);
 
 1186                                 token2 = strtok(NULL, 
" \t");
 
 1188                                         token3 = strtok(NULL, 
" \t");
 
 1189                                 if (token2 != NULL && token3 != NULL) {
 
 1190                                         lirc_printf(
"%s: unexpected token in line %s:%d\n",
 
 1191                                                     lirc_prog, filestack->name, filestack->line);
 
 1193                                         ret = lirc_mode(token, token2, &mode,
 
 1196                                                         check, filestack->name,
 
 1199                                                 if (remote != LIRC_ALL)
 
 1207                                                 if (new_entry != NULL) {
 
 1208                                                         lirc_freeconfigentries(
 
 1217                         token = lirc_trim(
string);
 
 1218                         token2 = lirc_trim(eq + 1);
 
 1219                         if (token[0] == 
'#') {
 
 1221                         } 
else if (new_entry == NULL) {
 
 1222                                 lirc_printf(
"%s: bad file format, %s:%d\n",
 
 1223                                             lirc_prog, filestack->name,
 
 1227                                 token2 = strdup(token2);
 
 1228                                 if (token2 == NULL) {
 
 1229                                         lirc_printf(
"%s: out of memory\n",
 
 1232                                 } 
else if (strcasecmp(token, 
"prog") == 0) {
 
 1233                                         if (new_entry->prog != NULL)
 
 1234                                                 free(new_entry->prog);
 
 1235                                         new_entry->prog = token2;
 
 1236                                 } 
else if (strcasecmp(token, 
"remote") == 0) {
 
 1237                                         if (remote != LIRC_ALL)
 
 1240                                         if (strcasecmp(
"*", token2) == 0) {
 
 1246                                 } 
else if (strcasecmp(token, 
"button") == 0) {
 
 1254                                                         "%s: out of memory\n",
 
 1258                                                 code->remote = remote;
 
 1261                                                         code->button = LIRC_ALL;
 
 1264                                                         code->button = token2;
 
 1268                                                 if (new_entry->code == NULL)
 
 1269                                                         new_entry->code = code;
 
 1271                                                         new_entry->next_code->
 
 1273                                                 new_entry->next_code = code;
 
 1274                                                 if (remote != LIRC_ALL) {
 
 1275                                                         remote = strdup(remote);
 
 1276                                                         if (remote == NULL) {
 
 1278                                                                         "%s: out of memory\n",
 
 1284                                 } 
else if (strcasecmp(token, 
"delay") == 0) {
 
 1288                                         new_entry->rep_delay = strtoul(token2,
 
 1290                                         if ((new_entry->rep_delay ==
 
 1291                                              ULONG_MAX && errno == ERANGE)
 
 1292                                             || end[0] != 0 || strlen(token2) ==
 
 1294                                                 lirc_printf(
"%s: \"%s\" not" 
 1295                                                             " a  valid number for delay\n", lirc_prog,
 
 1298                                 } 
else if (strcasecmp(token, 
"ignore_first_events") == 0) {
 
 1302                                         new_entry->ign_first_events = strtoul(
 
 1304                                         if ((new_entry->ign_first_events ==
 
 1305                                              ULONG_MAX && errno == ERANGE)
 
 1306                                             || end[0] != 0 || strlen(token2) ==
 
 1308                                                 lirc_printf(
"%s: \"%s\" not" 
 1309                                                             " a  valid number for ignore_first_events\n",
 
 1312                                 } 
else if (strcasecmp(token, 
"repeat") == 0) {
 
 1317                                                 strtoul(token2, &end, 0);
 
 1318                                         if ((new_entry->rep == ULONG_MAX &&
 
 1320                                             || end[0] != 0 || strlen(token2) ==
 
 1322                                                 lirc_printf(
"%s: \"%s\" not" 
 1323                                                             " a  valid number for repeat\n", lirc_prog,
 
 1326                                 } 
else if (strcasecmp(token, 
"config") == 0) {
 
 1331                                         if (new_list == NULL) {
 
 1334                                                         "%s: out of memory\n",
 
 1338                                                 lirc_parse_string(token2,
 
 1341                                                 new_list->string = token2;
 
 1342                                                 new_list->next = NULL;
 
 1343                                                 if (new_entry->config == NULL)
 
 1347                                                         new_entry->next_config->
 
 1349                                                 new_entry->next_config =
 
 1352                                 } 
else if (strcasecmp(token, 
"mode") == 0) {
 
 1353                                         if (new_entry->change_mode != NULL)
 
 1354                                                 free(new_entry->change_mode);
 
 1355                                         new_entry->change_mode = token2;
 
 1356                                 } 
else if (strcasecmp(token, 
"flags") == 0) {
 
 1357                                         new_entry->flags = lirc_flags(token2);
 
 1362                                                 "%s: unknown token \"%s\" in %s:%d ignored\n",
 
 1363                                                 lirc_prog, token, filestack->name,
 
 1372         if (remote != LIRC_ALL)
 
 1374         if (new_entry != NULL) {
 
 1376                         ret = lirc_mode(
"end", NULL, &mode, &new_entry, &first,
 
 1377                                         &last, check, 
"", 0);
 
 1379                                 "%s: warning: end token missing at end of file\n",
 
 1382                         lirc_freeconfigentries(new_entry);
 
 1389                                 "%s: warning: no end token found for mode \"%s\"\n", lirc_prog,
 
 1398                 if (*config == NULL) {
 
 1399                         lirc_printf(
"%s: out of memory\n", lirc_prog);
 
 1400                         lirc_freeconfigentries(first);
 
 1403                 (*config)->first = first;
 
 1404                 (*config)->next = first;
 
 1405                 startupmode = lirc_startupmode((*config)->first);
 
 1406                 (*config)->current_mode =
 
 1407                         startupmode ? strdup(startupmode) : NULL;
 
 1408                 if (lircrc_class[0] != 
'\0')
 
 1409                         (*config)->lircrc_class = strdup(lircrc_class);
 
 1411                         (*config)->lircrc_class = NULL;
 
 1412                 (*config)->sockfd = -1;
 
 1413                 if (full_name != NULL) {
 
 1414                         *full_name = save_full_name;
 
 1415                         save_full_name = NULL;
 
 1419                 lirc_freeconfigentries(first);
 
 1422                 stack_free(filestack);
 
 1424                 free(save_full_name);
 
 1429 int lirc_identify(
int sockfd)
 
 1439         while (ret == EAGAIN || ret == EWOULDBLOCK);
 
 1440         return ret == 0 ? LIRC_RET_SUCCESS : -1;
 
 1447                     int (check)(
char* s))
 
 1449         struct sockaddr_un addr;
 
 1456         if (lirc_readconfig_only_internal(file, config, check, &filename) == -1)
 
 1459         if ((*config)->lircrc_class == NULL)
 
 1460                 goto lirc_readconfig_compat;
 
 1464         addr.sun_family = AF_UNIX;
 
 1467                                sizeof(addr.sun_path)) > 
sizeof(addr.sun_path)) {
 
 1468                 lirc_printf(
"%s: WARNING: file name too long\n", lirc_prog);
 
 1469                 goto lirc_readconfig_compat;
 
 1471         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
 
 1473                 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
 
 1474                 lirc_perror(lirc_prog);
 
 1475                 goto lirc_readconfig_compat;
 
 1477         if (connect(sockfd, (
struct sockaddr*)&addr, 
sizeof(addr)) != -1) {
 
 1478                 (*config)->sockfd = sockfd;
 
 1482                 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS)
 
 1493         snprintf(command, 
sizeof(command),
 
 1494                  "lircrcd %s", (*config)->lircrc_class);
 
 1495         ret = system(command);
 
 1496         if (ret == -1 || WEXITSTATUS(ret) != EXIT_SUCCESS)
 
 1497                 goto lirc_readconfig_compat;
 
 1500         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
 
 1502                 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
 
 1503                 lirc_perror(lirc_prog);
 
 1504                 goto lirc_readconfig_compat;
 
 1506         if (connect(sockfd, (
struct sockaddr*)&addr, 
sizeof(addr)) != -1) {
 
 1507                 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS) {
 
 1508                         (*config)->sockfd = sockfd;
 
 1516 lirc_readconfig_compat:
 
 1526                          int                    (check) (
char* s))
 
 1528         return lirc_readconfig_only_internal(file, config, check, NULL);
 
 1534         if (config != NULL) {
 
 1535                 if (config->sockfd != -1) {
 
 1536                         (void)close(config->sockfd);
 
 1537                         config->sockfd = -1;
 
 1541                 lirc_freeconfigentries(config->first);
 
 1542                 free(config->current_mode);
 
 1548 static void lirc_clearmode(
struct lirc_config* config)
 
 1552         if (config->current_mode == NULL)
 
 1554         scan = config->first;
 
 1555         while (scan != NULL) {
 
 1556                 if (scan->change_mode != NULL)
 
 1557                         if (strcasecmp(scan->change_mode,
 
 1558                                        config->current_mode) == 0)
 
 1559                                 scan->flags &= ~ecno;
 
 1562         free(config->current_mode);
 
 1563         config->current_mode = NULL;
 
 1567 static char* lirc_execute(
struct lirc_config*           config,
 
 1573         if (scan->flags & mode)
 
 1574                 lirc_clearmode(config);
 
 1575         if (scan->change_mode != NULL) {
 
 1576                 free(config->current_mode);
 
 1577                 config->current_mode = strdup(scan->change_mode);
 
 1578                 if (scan->flags & once) {
 
 1579                         if (scan->flags & ecno)
 
 1582                                 scan->flags |= ecno;
 
 1585         if (scan->next_config != NULL
 
 1586             && scan->prog != NULL
 
 1587             && (lirc_prog == NULL || strcasecmp(scan->prog, lirc_prog) == 0)
 
 1589                 s = scan->next_config->string;
 
 1590                 scan->next_config = scan->next_config->next;
 
 1591                 if (scan->next_config == NULL)
 
 1592                         scan->next_config = scan->config;
 
 1608         int delay_start, rep_delay;
 
 1610         if (scan->ign_first_events) {
 
 1611                 if (scan->rep_delay && rep == 0)        
 
 1613                                 "%s: ignoring \"delay\" because \"ignore_first_events\" is also set\n",
 
 1615                 rep_delay = scan->ign_first_events;
 
 1618                 rep_delay = scan->rep_delay;
 
 1622         if (rep < delay_start)
 
 1625         if (scan->rep == 0 && rep_delay > 0 && rep == rep_delay + delay_start)
 
 1628         if (scan->rep > 0 && rep >= rep_delay + delay_start) {
 
 1629                 rep -= rep_delay + delay_start;
 
 1630                 return (rep % scan->rep) == 0;
 
 1643         if (scan->code == NULL)
 
 1644                 return rep_filter(scan, rep);
 
 1647         if (scan->next_code->remote == LIRC_ALL
 
 1648             || strcasecmp(scan->next_code->remote, remote) == 0) {
 
 1649                 if (scan->next_code->button == LIRC_ALL
 
 1650                     || strcasecmp(scan->next_code->button, button) == 0) {
 
 1653                         if (scan->code->next == NULL || rep == 0) {
 
 1654                                 scan->next_code = scan->next_code->next;
 
 1655                                 if (scan->code->next != NULL)
 
 1659                         if (scan->next_code == NULL) {
 
 1660                                 scan->next_code = scan->code;
 
 1661                                 if (scan->code->next != NULL ||
 
 1662                                     rep_filter(scan, rep))
 
 1673         if (scan->flags & toggle_reset)
 
 1674                 scan->next_config = scan->config;
 
 1677         if (codes == scan->next_code)
 
 1679         codes = codes->next;
 
 1681         while (codes != scan->next_code->next) {
 
 1688                 while (next != scan->next_code) {
 
 1689                         if (prev->remote == LIRC_ALL
 
 1690                             || strcasecmp(prev->remote, next->remote) == 0) {
 
 1691                                 if (prev->button == LIRC_ALL
 
 1692                                     || strcasecmp(prev->button,
 
 1693                                                   next->button) == 0) {
 
 1706                         if (prev->remote == LIRC_ALL
 
 1707                             || strcasecmp(prev->remote, remote) == 0) {
 
 1708                                 if (prev->button == LIRC_ALL
 
 1709                                     || strcasecmp(prev->button, button) == 0) {
 
 1711                                                 scan->next_code = prev->next;
 
 1717                 codes = codes->next;
 
 1719         scan->next_code = scan->code;
 
 1726         static int warning = 1;
 
 1730                 fprintf(stderr, 
"%s: warning: lirc_ir2char() is obsolete\n",
 
 1740 static int lirc_code2char_internal(
struct lirc_config*  config,
 
 1755         if (sscanf(code, 
"%*x %x %*s %*s\n", &rep) == 1) {
 
 1756                 backup = strdup(code);
 
 1760                 strtok(backup, 
" ");
 
 1762                 button = strtok(NULL, 
" ");
 
 1763                 remote = strtok(NULL, 
"\n");
 
 1765                 if (button == NULL || remote == NULL) {
 
 1770                 scan = config->next;
 
 1772                 while (scan != NULL) {
 
 1773                         exec_level = lirc_iscode(scan, remote, button, rep);
 
 1774                         if (exec_level > 0 &&
 
 1775                             (scan->mode == NULL ||
 
 1776                              (scan->mode != NULL &&
 
 1777                               config->current_mode != NULL &&
 
 1778                               strcasecmp(scan->mode,
 
 1779                                          config->current_mode) == 0)) &&
 
 1780                             quit_happened == 0) {
 
 1781                                 if (exec_level > 1) {
 
 1782                                         s = lirc_execute(config, scan);
 
 1783                                         if (s != NULL && prog != NULL)
 
 1788                                 if (scan->flags & quit) {
 
 1790                                         config->next = NULL;
 
 1793                                 } 
else if (s != NULL) {
 
 1794                                         config->next = scan->next;
 
 1806         config->next = config->first;
 
 1819         my_code = strdup(code);
 
 1820         pos = rindex(my_code, 
'\n');
 
 1827         if (config->sockfd != -1) {
 
 1830                 while (ret == EAGAIN || ret == EWOULDBLOCK);
 
 1833                         *
string = static_buff;
 
 1835                 return ret == 0 ? 0 : -1;
 
 1837         return lirc_code2char_internal(config, code, 
string, NULL);
 
 1841 int lirc_code2charprog(
struct lirc_config*      config,
 
 1852         ret = lirc_code2char_internal(config, code, 
string, prog);
 
 1861         static int warning = 1;
 
 1866                 fprintf(stderr, 
"%s: warning: lirc_nextir() is obsolete\n",
 
 1880         static int end_len = 0;
 
 1886         if (lirc_buffer == NULL) {
 
 1887                 lirc_buffer = (
char*)malloc(packet_size + 1);
 
 1888                 if (lirc_buffer == NULL) {
 
 1889                         lirc_printf(
"%s: out of memory\n", lirc_prog);
 
 1894         while ((end = strchr(lirc_buffer, 
'\n')) == NULL) {
 
 1895                 if (end_len >= packet_size) {
 
 1900                                 (
char*)realloc(lirc_buffer, packet_size + 1);
 
 1901                         if (new_buffer == NULL)
 
 1903                         lirc_buffer = new_buffer;
 
 1905                 len = read(lirc_lircd, lirc_buffer + end_len,
 
 1906                            packet_size - end_len);
 
 1908                         if (len == -1 && errno == EAGAIN)
 
 1914                 lirc_buffer[end_len] = 0;
 
 1916                 end = strchr(lirc_buffer, 
'\n');
 
 1923         end_len = strlen(end);
 
 1926         *code = strdup(lirc_buffer);
 
 1928         memmove(lirc_buffer, end, end_len + 1);
 
 1937         id = 
id != NULL ? 
id : 
"default";
 
 1938         snprintf(buf, size, VARRUNDIR 
"/%d-%s-lircrcd.socket", getuid(), 
id);
 
 1950         if (config->sockfd != -1) {
 
 1954                 while (ret == EAGAIN || ret == EWOULDBLOCK);
 
 1961         return config->current_mode;
 
 1971         if (config->sockfd != -1) {
 
 1980                 while (r == EAGAIN || r == EWOULDBLOCK);
 
 1987         free(config->current_mode);
 
 1988         config->current_mode = mode ? strdup(mode) : NULL;
 
 1989         return config->current_mode;
 
 2003         while (r == EAGAIN);
 
 2018                               scancode, repeat, keysym, remote);
 
 2023         while (r == EAGAIN);
 
 2030 do_connect(
int domain, 
struct sockaddr* addr, 
size_t size, 
int quiet)
 
 2034         fd = socket(domain, SOCK_STREAM, 0);
 
 2037                         fprintf(stderr, 
"do_connect: could not open socket\n");
 
 2042         if (connect(fd, addr, size) == -1) {
 
 2045                                 "do_connect: could not connect to socket\n");
 
 2056         const char* socket_path;
 
 2057         struct sockaddr_un addr_un;
 
 2059         socket_path = path ? path : getenv(
"LIRC_SOCKET_PATH");
 
 2060         socket_path = socket_path ? socket_path : 
LIRCD;
 
 2061         if (strlen(socket_path) + 1 > 
sizeof(addr_un.sun_path)) {
 
 2064                         fprintf(stderr, 
"%s: socket name is too long\n", prog);
 
 2065                 return -ENAMETOOLONG;
 
 2067         addr_un.sun_family = AF_UNIX;
 
 2068         strcpy(addr_un.sun_path, socket_path);
 
 2069         return do_connect(AF_UNIX,
 
 2070                           (
struct sockaddr*)&addr_un,
 
 2078         struct addrinfo* addrinfos;
 
 2083         snprintf(service, 
sizeof(service),
 
 2085         r = getaddrinfo(address, service, NULL, &addrinfos);
 
 2088                         fprintf(stderr, 
"get_remote_socket: host %s unknown\n",
 
 2090                 return -EADDRNOTAVAIL;
 
 2092         for (a = addrinfos; a != NULL; a = a->ai_next) {
 
 2093                 r = do_connect(a->ai_family, a->ai_addr, a->ai_addrlen, quiet);
 
 2097         freeaddrinfo(addrinfos);
 
#define LIRCRC_ROOT_FILE
System-wide lircrc path. 
 
#define chk_write(fd, buf, count)
Wrapper for write(2) which logs errors. 
 
void lirc_command_reply_to_stdout(lirc_cmd_ctx *ctx)
Set command_ctx write_to_stdout flag. 
 
int lirc_init(const char *prog, int verbose)
Initial setup: connect to lircd socket. 
 
const char * lirc_setmode(struct lirc_config *config, const char *mode)
Set mode defined in lircrc. 
 
char reply[PACKET_SIZE+1]
Command reply payload. 
 
int lirc_get_local_socket(const char *path, int quiet)
Return an opened and connected file descriptor to local lirc socket. 
 
char buffer[PACKET_SIZE+1]
Reply IO buffer. 
 
int lirc_command_run(lirc_cmd_ctx *ctx, int fd)
Run a command in non-blocking mode. 
 
#define LIRCRC_OLD_ROOT_FILE
Compatibility: Old system-wide lircrc path. 
 
char * lircrc_class
The lircrc instance used, if any. 
 
const char * lirc_getmode(struct lirc_config *config)
Get mode defined in lircrc. 
 
#define PACKET_SIZE
IR transmission packet size. 
 
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 ...
 
size_t lirc_getsocketname(const char *id, char *buf, size_t size)
Retrieve default lircrcd socket path. 
 
int lirc_command_init(lirc_cmd_ctx *ctx, const char *fmt,...)
Initiate a lirc_cmd_ctx to run a command. 
 
packet_state
protocol state. 
 
#define LIRC_INET_PORT
default port number for UDP driver 
 
int head
First free buffer index. 
 
int lirc_nextcode(char **code)
Get next available code from the lircd daemon. 
 
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_code2char(struct lirc_config *config, char *code, char **string)
Translate a code string to an application string using .lircrc. 
 
The data needed to run a command on remote server. 
 
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 packet[PACKET_SIZE+1]
The packet to send. 
 
int lirc_readconfig(const char *file, struct lirc_config **config, int(check)(char *s))
Parse a lircrc configuration file. 
 
char * next
Next newline-separated word in buffer. 
 
int lirc_send_one(int fd, const char *remote, const char *keysym)
Send keysym using given remote. 
 
int reply_to_stdout
If true, write reply on stdout. 
 
void lirc_freeconfig(struct lirc_config *config)
Deallocate an object retrieved using lirc_readconfig(). 
 
#define LIRCRC_USER_FILE
User lircrc file name. 
 
#define CFG_LIRCRC
config file names - beneath $HOME or SYSCONFDIR 
 
3-rd party application interface. 
 
#define LIRCD
Complete lircd socket path. 
 
int lirc_deinit(void)
Release resources allocated by lirc_init(), basically disconnect from socket. 
 
char * lirc_ir2char(struct lirc_config *config, char *code)