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)