32 #include <sys/param.h> 33 #include <sys/socket.h> 35 #include <sys/types.h> 44 #define MAXPATHLEN 4096 48 static const struct timeval CMD_TIMEOUT = { .tv_sec = 1, .tv_usec = 0 };
52 #define logprintf(level, fmt, args ...) syslog(level, fmt, ## args) 53 #define LIRC_WARNING LOG_WARNING 54 #define LIRC_DEBUG LOG_DEBUG 55 #define LIRC_NOTICE LOG_NOTICE 56 #define LIRC_ERROR LOG_ERR 59 #define MAX_INCLUDES 10 61 #define LIRC_PACKET_SIZE 255 63 #define LIRC_TIMEOUT 3 70 struct filestack_t* parent;
91 unsigned int lirc_flags(
char*
string);
93 static int lirc_lircd;
94 static int lirc_verbose = 0;
95 static char* lirc_prog = NULL;
96 static char* lirc_buffer = NULL;
102 chk_write(
int fd,
const void* buf,
size_t count,
const char* msg)
104 if (write(fd, buf, count) == -1)
119 logprintf(LIRC_NOTICE,
"Message too big: %s", ctx->
packet);
140 (
const void*)&CMD_TIMEOUT,
141 sizeof(CMD_TIMEOUT));
144 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
145 logprintf(LIRC_NOTICE,
"fill_string: timeout\n");
157 static int read_string(
lirc_cmd_ctx* cmd,
int fd,
const char**
string)
171 if (cmd->
next == NULL || strchr(cmd->
next,
'\n') == NULL) {
172 r = fill_string(fd, cmd);
180 cmd->
next = strchr(cmd->
next,
'\n');
181 if (cmd->
next != NULL) {
192 const char*
string = NULL;
199 todo = strlen(ctx->
packet);
201 logprintf(LIRC_DEBUG,
"lirc_command_run: Sending: %s", data);
203 done = write(fd, (
void*)data, todo);
205 logprintf(LIRC_WARNING,
206 "%s: could not send packet\n", prog);
220 r = read_string(ctx, fd, &
string);
222 if (!
string || strlen(
string) == 0)
224 logprintf(LIRC_DEBUG,
225 "lirc_command_run, state: %d, input: \"%s\"\n",
226 state,
string ?
string :
"(Null)");
229 if (strcasecmp(
string,
"BEGIN") != 0)
234 if (strncasecmp(
string, ctx->
packet,
236 || strlen(
string) + 1 != strlen(ctx->
packet)) {
243 if (strcasecmp(
string,
"SUCCESS") == 0) {
245 }
else if (strcasecmp(
string,
"END") == 0) {
246 logprintf(LIRC_NOTICE,
247 "lirc_command_run: status:END");
249 }
else if (strcasecmp(
string,
"ERROR") == 0) {
250 logprintf(LIRC_WARNING,
251 "%s: command failed: %s",
260 if (strcasecmp(
string,
"END") == 0) {
261 logprintf(LIRC_NOTICE,
262 "lirc_command_run: data:END, status:%d",
265 }
else if (strcasecmp(
string,
"DATA") == 0) {
269 logprintf(LIRC_DEBUG,
270 "data: bad packet: %s\n",
275 data_n = (__u32)strtoul(
string, &endptr, 0);
276 if (!*
string || *endptr)
288 strcpy(ctx->
reply,
"");
291 chk_write(STDOUT_FILENO,
string, strlen(
string),
293 chk_write(STDOUT_FILENO,
"\n", 1,
"reply (2)");
304 if (strcasecmp(
string,
"END") == 0) {
305 logprintf(LIRC_NOTICE,
306 "lirc_command_run: status:END, status:%d",
314 logprintf(LIRC_WARNING,
"%s: bad return packet\n", prog);
315 logprintf(LIRC_DEBUG,
"State %d: bad packet: %s\n", status,
string);
320 static void lirc_printf(
const char* format_str, ...)
327 va_start(ap, format_str);
328 vfprintf(stderr, format_str, ap);
333 static void lirc_perror(
const char* s)
344 if (prog == NULL || lirc_prog != NULL)
347 if (lirc_lircd >= 0) {
348 lirc_verbose = verbose;
349 lirc_prog = strdup(prog);
350 if (lirc_prog == NULL) {
351 lirc_printf(
"%s: out of memory\n", prog);
356 lirc_printf(
"%s: could not open socket: %s\n",
358 strerror(-lirc_lircd));
365 if (lirc_prog != NULL) {
369 if (lirc_buffer != NULL) {
373 return close(lirc_lircd);
377 static int lirc_readline(
char** line, FILE* f)
384 newline = (
char*)malloc(LIRC_READ + 1);
385 if (newline == NULL) {
386 lirc_printf(
"%s: out of memory\n", lirc_prog);
391 ret = fgets(newline + len, LIRC_READ + 1, f);
393 if (feof(f) && len > 0) {
401 len = strlen(newline);
402 if (newline[len - 1] ==
'\n') {
403 newline[len - 1] = 0;
408 enlargeline = (
char*)realloc(newline, len + 1 + LIRC_READ);
409 if (enlargeline == NULL) {
411 lirc_printf(
"%s: out of memory\n", lirc_prog);
414 newline = enlargeline;
419 static char* lirc_trim(
char* s)
423 while (s[0] ==
' ' || s[0] ==
'\t')
428 if (s[len] ==
' ' || s[len] ==
'\t')
438 static char lirc_parse_escape(
char** s,
const char* name,
int line)
441 unsigned int i, overflow, count;
442 int digits_found, digit;
482 while (++count < 3) {
484 if (c >=
'0' && c <=
'7') {
485 i = (i << 3) + c -
'0';
491 if (i > (1 << CHAR_BIT) - 1) {
492 i &= (1 << CHAR_BIT) - 1;
494 "%s: octal escape sequence out of range in %s:%d\n",
495 lirc_prog, name, line);
505 if (c >=
'0' && c <=
'9') {
507 }
else if (c >=
'a' && c <=
'f') {
508 digit = c -
'a' + 10;
509 }
else if (c >=
'A' && c <=
'F') {
510 digit = c -
'A' + 10;
515 overflow |= i ^ (i << 4 >> 4);
516 i = (i << 4) + digit;
520 lirc_printf(
"%s: \\x used with no " 521 "following hex digits in %s:%d\n",
522 lirc_prog, name, line);
523 if (overflow || i > (1 << CHAR_BIT) - 1) {
524 i &= (1 << CHAR_BIT) - 1;
525 lirc_printf(
"%s: hex escape sequence out " 526 "of range in %s:%d\n", lirc_prog, name,
532 if (c >=
'@' && c <=
'Z')
539 static void lirc_parse_string(
char* s,
const char* name,
int line)
547 *t = lirc_parse_escape(&s, name, line);
559 static void lirc_parse_include(
char* s,
const char* name,
int line)
568 if (*s !=
'"' && *s !=
'<')
570 if (*s ==
'"' && last !=
'"')
572 else if (*s ==
'<' && last !=
'>')
575 memmove(s, s + 1, len - 2 + 1);
579 int lirc_mode(
char* token,
char* token2,
char** mode,
583 int (check) (
char* s),
589 new_entry = *new_config;
590 if (strcasecmp(token,
"begin") == 0) {
591 if (token2 == NULL) {
592 if (new_entry == NULL) {
595 if (new_entry == NULL) {
596 lirc_printf(
"%s: out of memory\n",
600 new_entry->prog = NULL;
601 new_entry->code = NULL;
602 new_entry->rep_delay = 0;
603 new_entry->ign_first_events = 0;
605 new_entry->config = NULL;
606 new_entry->change_mode = NULL;
607 new_entry->flags = none;
608 new_entry->mode = NULL;
609 new_entry->next_config = NULL;
610 new_entry->next_code = NULL;
611 new_entry->next = NULL;
612 *new_config = new_entry;
614 lirc_printf(
"%s: bad file format, %s:%d\n",
615 lirc_prog, name, line);
619 if (new_entry == NULL && *mode == NULL) {
620 *mode = strdup(token2);
624 lirc_printf(
"%s: bad file format, %s:%d\n",
625 lirc_prog, name, line);
629 }
else if (strcasecmp(token,
"end") == 0) {
630 if (token2 == NULL) {
631 if (new_entry != NULL) {
633 if (new_entry->prog == NULL) {
635 "%s: prog missing in config before line %d\n", lirc_prog,
637 lirc_freeconfigentries(new_entry);
641 if (strcasecmp(new_entry->prog,
643 lirc_freeconfigentries(new_entry);
648 new_entry->next_code = new_entry->code;
649 new_entry->next_config = new_entry->config;
650 if (*last_config == NULL) {
651 *first_config = new_entry;
652 *last_config = new_entry;
654 (*last_config)->next = new_entry;
655 *last_config = new_entry;
660 new_entry->mode = strdup(*mode);
661 if (new_entry->mode == NULL) {
663 "%s: out of memory\n",
670 new_entry->prog != NULL &&
671 strcasecmp(new_entry->prog,
675 list = new_entry->config;
676 while (list != NULL) {
677 if (check(list->string) == -1)
683 if (new_entry->rep_delay == 0 &&
685 new_entry->rep_delay = new_entry->rep -
689 "%s: %s:%d: 'end' without 'begin'\n",
690 lirc_prog, name, line);
695 if (new_entry != NULL) {
697 "%s: %s:%d: missing 'end' token\n",
698 lirc_prog, name, line);
701 if (strcasecmp(*mode, token2) == 0) {
705 lirc_printf(
"%s: \"%s\" doesn't " 706 "match mode \"%s\"\n",
707 lirc_prog, token2, *mode);
712 "%s: %s:%d: 'end %s' without 'begin'\n",
713 lirc_prog, name, line, token2);
718 lirc_printf(
"%s: unknown token \"%s\" in %s:%d ignored\n",
719 lirc_prog, token, name, line);
725 unsigned int lirc_flags(
char*
string)
731 s = strtok(
string,
" \t|");
733 if (strcasecmp(s,
"once") == 0)
735 else if (strcasecmp(s,
"quit") == 0)
737 else if (strcasecmp(s,
"mode") == 0)
739 else if (strcasecmp(s,
"startup_mode") == 0)
740 flags |= startup_mode;
741 else if (strcasecmp(s,
"toggle_reset") == 0)
742 flags |= toggle_reset;
744 lirc_printf(
"%s: unknown flag \"%s\"\n", lirc_prog, s);
745 s = strtok(NULL,
" \t");
760 static char* get_homepath(
void)
765 filename = malloc(MAXPATHLEN);
766 if (filename == NULL) {
767 lirc_printf(
"%s: out of memory\n", lirc_prog);
770 home = getenv(
"HOME");
771 home = home == NULL ?
"/" : home;
772 strncpy(filename, home, MAXPATHLEN);
773 if (filename[strlen(filename) - 1] ==
'/')
774 filename[strlen(filename) - 1] =
'\0';
784 static char* get_freedesktop_path(
void)
788 if (getenv(
"XDG_CONFIG_HOME") != NULL) {
789 path = malloc(MAXPATHLEN);
790 strncpy(path, getenv(
"XDG_CONFIG_HOME"), MAXPATHLEN);
791 strncat(path,
"/", MAXPATHLEN - strlen(path));
792 strncat(path,
CFG_LIRCRC, MAXPATHLEN - strlen(path));
794 path = get_homepath();
797 strncat(path,
"/.config/lircrc", MAXPATHLEN - strlen(path) - 1);
799 if (access(path, R_OK) != 0)
805 static char* lirc_getfilename(
const char* file,
const char* current_file)
810 filename = get_freedesktop_path();
811 if (filename == NULL) {
813 }
else if (strlen(filename) == 0) {
815 filename = get_homepath();
816 if (filename == NULL)
820 filename = realloc(filename, strlen(filename) + 1);
821 }
else if (strncmp(file,
"~/", 2) == 0) {
822 filename = get_homepath();
823 if (filename == NULL)
825 strcat(filename, file + 1);
826 filename = realloc(filename, strlen(filename) + 1);
827 }
else if (file[0] ==
'/' || current_file == NULL) {
829 filename = strdup(file);
830 if (filename == NULL) {
831 lirc_printf(
"%s: out of memory\n", lirc_prog);
836 int pathlen = strlen(current_file);
838 while (pathlen > 0 && current_file[pathlen - 1] !=
'/')
840 filename = (
char*)malloc(pathlen + strlen(file) + 1);
841 if (filename == NULL) {
842 lirc_printf(
"%s: out of memory\n", lirc_prog);
845 memcpy(filename, current_file, pathlen);
846 filename[pathlen] = 0;
847 strcat(filename, file);
853 static FILE* lirc_open(
const char* file,
854 const char* current_file,
860 filename = lirc_getfilename(file, current_file);
861 if (filename == NULL)
864 fin = fopen(filename,
"r");
865 if (fin == NULL && (file != NULL || errno != ENOENT)) {
866 lirc_printf(
"%s: could not open config file %s\n", lirc_prog,
868 lirc_perror(lirc_prog);
869 }
else if (fin == NULL) {
872 fin = fopen(root_file,
"r");
873 if (fin == NULL && errno == ENOENT) {
874 int save_errno = errno;
877 fin = fopen(root_file,
"r");
880 if (fin == NULL && errno != ENOENT) {
881 lirc_printf(
"%s: could not open config file %s\n",
883 lirc_perror(lirc_prog);
884 }
else if (fin == NULL) {
885 lirc_printf(
"%s: could not open config files " 886 "%s and %s\n", lirc_prog, filename,
888 lirc_perror(lirc_prog);
891 filename = strdup(root_file);
892 if (filename == NULL) {
894 lirc_printf(
"%s: out of memory\n", lirc_prog);
899 if (full_name && fin != NULL)
900 *full_name = filename;
907 static struct filestack_t* stack_push(
struct filestack_t* parent)
909 struct filestack_t* entry;
911 entry = malloc(
sizeof(
struct filestack_t));
913 lirc_printf(
"%s: out of memory\n", lirc_prog);
919 entry->parent = parent;
924 static struct filestack_t* stack_pop(
struct filestack_t* entry)
926 struct filestack_t* parent = NULL;
929 parent = entry->parent;
938 static void stack_free(
struct filestack_t* entry)
941 entry = stack_pop(entry);
953 while (scan != NULL) {
954 if (scan->flags & startup_mode) {
955 if (scan->change_mode != NULL) {
956 startupmode = scan->change_mode;
958 scan->change_mode = NULL;
961 lirc_printf(
"%s: startup_mode flags requires 'mode ='\n", lirc_prog);
967 if (startupmode == NULL) {
969 while (scan != NULL) {
970 if (scan->mode != NULL
971 && strcasecmp(lirc_prog, scan->mode) == 0) {
972 startupmode = lirc_prog;
979 if (startupmode == NULL)
982 while (scan != NULL) {
983 if (scan->change_mode != NULL
984 && scan->flags & once
985 && strcasecmp(startupmode, scan->change_mode) == 0)
1007 free(c->change_mode);
1012 while (code != NULL) {
1013 if (code->remote != NULL && code->remote != LIRC_ALL)
1015 if (code->button != NULL && code->button != LIRC_ALL)
1017 code_temp = code->next;
1023 while (list != NULL) {
1026 list_temp = list->next;
1030 config_temp = c->next;
1038 parse_shebang(
char* line,
int depth,
const char* path,
char* buff,
size_t size)
1042 const char*
const SHEBANG_MSG =
1043 "Warning: Use of deprecated lircrc shebang." 1044 " Use lircrc_class instead.\n";
1046 token = strtok(line,
"#! ");
1049 lirc_printf(
"Warning: ignoring shebang in included file.");
1052 if (strcmp(token,
"lircrc") == 0) {
1053 strncpy(my_path, path,
sizeof(my_path) - 1);
1054 strncat(buff, basename(my_path), size - 1);
1055 lirc_printf(SHEBANG_MSG);
1057 lirc_printf(
"Warning: bad shebang (ignored)");
1062 static int lirc_readconfig_only_internal(
const char* file,
1064 int (check)(
char* s),
1067 const char*
const INCLUDED_LIRCRC_CLASS =
1068 "Warning: lirc_class in included file (ignored)";
1074 struct filestack_t* filestack;
1075 struct filestack_t* stack_tmp;
1077 char lircrc_class[128] = {
'\0' };
1085 char* save_full_name = NULL;
1087 filestack = stack_push(NULL);
1088 if (filestack == NULL)
1090 filestack->file = lirc_open(file, NULL, &(filestack->name));
1091 if (filestack->file == NULL) {
1092 stack_free(filestack);
1095 filestack->line = 0;
1098 first = new_entry = last = NULL;
1102 ret = lirc_readline(&
string, filestack->file);
1103 if (ret == -1 ||
string == NULL) {
1104 fclose(filestack->file);
1105 if (open_files == 1 && full_name != NULL) {
1106 save_full_name = filestack->name;
1107 filestack->name = NULL;
1109 filestack = stack_pop(filestack);
1116 if (strncmp(
string,
"#!", 2) == 0) {
1117 parse_shebang(
string,
1121 sizeof(lircrc_class));
1125 eq = strchr(
string,
'=');
1127 token = strtok(
string,
" \t");
1128 if (token == NULL) {
1130 }
else if (token[0] ==
'#') {
1132 }
else if (strcasecmp(token,
"lircrc_class") == 0) {
1133 token2 = lirc_trim(strtok(NULL,
""));
1134 if (strlen(token2) == 0) {
1136 "Warning: no lircrc_class");
1137 }
else if (open_files == 1) {
1138 strncpy(lircrc_class,
1140 sizeof(lircrc_class) - 1);
1142 lirc_printf(INCLUDED_LIRCRC_CLASS);
1144 }
else if (strcasecmp(token,
"include") == 0) {
1145 if (open_files >= MAX_INCLUDES) {
1146 lirc_printf(
"%s: too many files " 1147 "included at %s:%d\n",
1148 lirc_prog, filestack->name,
1152 token2 = strtok(NULL,
"");
1153 token2 = lirc_trim(token2);
1154 lirc_parse_include(token2,
1157 stack_tmp = stack_push(filestack);
1158 if (stack_tmp == NULL) {
1166 stack_tmp->line = 0;
1167 if (stack_tmp->file) {
1169 filestack = stack_tmp;
1171 stack_pop(stack_tmp);
1177 token2 = strtok(NULL,
" \t");
1179 token3 = strtok(NULL,
" \t");
1180 if (token2 != NULL && token3 != NULL) {
1181 lirc_printf(
"%s: unexpected token in line %s:%d\n",
1182 lirc_prog, filestack->name, filestack->line);
1184 ret = lirc_mode(token, token2, &mode,
1187 check, filestack->name,
1190 if (remote != LIRC_ALL)
1198 if (new_entry != NULL) {
1199 lirc_freeconfigentries(
1208 token = lirc_trim(
string);
1209 token2 = lirc_trim(eq + 1);
1210 if (token[0] ==
'#') {
1212 }
else if (new_entry == NULL) {
1213 lirc_printf(
"%s: bad file format, %s:%d\n",
1214 lirc_prog, filestack->name,
1218 token2 = strdup(token2);
1219 if (token2 == NULL) {
1220 lirc_printf(
"%s: out of memory\n",
1223 }
else if (strcasecmp(token,
"prog") == 0) {
1224 if (new_entry->prog != NULL)
1225 free(new_entry->prog);
1226 new_entry->prog = token2;
1227 }
else if (strcasecmp(token,
"remote") == 0) {
1228 if (remote != LIRC_ALL)
1231 if (strcasecmp(
"*", token2) == 0) {
1237 }
else if (strcasecmp(token,
"button") == 0) {
1245 "%s: out of memory\n",
1249 code->remote = remote;
1252 code->button = LIRC_ALL;
1255 code->button = token2;
1259 if (new_entry->code == NULL)
1260 new_entry->code = code;
1262 new_entry->next_code->
1264 new_entry->next_code = code;
1265 if (remote != LIRC_ALL) {
1266 remote = strdup(remote);
1267 if (remote == NULL) {
1269 "%s: out of memory\n",
1275 }
else if (strcasecmp(token,
"delay") == 0) {
1279 new_entry->rep_delay = strtoul(token2,
1281 if ((new_entry->rep_delay ==
1282 ULONG_MAX && errno == ERANGE)
1283 || end[0] != 0 || strlen(token2) ==
1285 lirc_printf(
"%s: \"%s\" not" 1286 " a valid number for delay\n", lirc_prog,
1289 }
else if (strcasecmp(token,
"ignore_first_events") == 0) {
1293 new_entry->ign_first_events = strtoul(
1295 if ((new_entry->ign_first_events ==
1296 ULONG_MAX && errno == ERANGE)
1297 || end[0] != 0 || strlen(token2) ==
1299 lirc_printf(
"%s: \"%s\" not" 1300 " a valid number for ignore_first_events\n",
1303 }
else if (strcasecmp(token,
"repeat") == 0) {
1308 strtoul(token2, &end, 0);
1309 if ((new_entry->rep == ULONG_MAX &&
1311 || end[0] != 0 || strlen(token2) ==
1313 lirc_printf(
"%s: \"%s\" not" 1314 " a valid number for repeat\n", lirc_prog,
1317 }
else if (strcasecmp(token,
"config") == 0) {
1322 if (new_list == NULL) {
1325 "%s: out of memory\n",
1329 lirc_parse_string(token2,
1332 new_list->string = token2;
1333 new_list->next = NULL;
1334 if (new_entry->config == NULL)
1338 new_entry->next_config->
1340 new_entry->next_config =
1343 }
else if (strcasecmp(token,
"mode") == 0) {
1344 if (new_entry->change_mode != NULL)
1345 free(new_entry->change_mode);
1346 new_entry->change_mode = token2;
1347 }
else if (strcasecmp(token,
"flags") == 0) {
1348 new_entry->flags = lirc_flags(token2);
1353 "%s: unknown token \"%s\" in %s:%d ignored\n",
1354 lirc_prog, token, filestack->name,
1363 if (remote != LIRC_ALL)
1365 if (new_entry != NULL) {
1367 ret = lirc_mode(
"end", NULL, &mode, &new_entry, &first,
1368 &last, check,
"", 0);
1370 "%s: warning: end token missing at end of file\n",
1373 lirc_freeconfigentries(new_entry);
1380 "%s: warning: no end token found for mode \"%s\"\n", lirc_prog,
1389 if (*config == NULL) {
1390 lirc_printf(
"%s: out of memory\n", lirc_prog);
1391 lirc_freeconfigentries(first);
1394 (*config)->first = first;
1395 (*config)->next = first;
1396 startupmode = lirc_startupmode((*config)->first);
1397 (*config)->current_mode =
1398 startupmode ? strdup(startupmode) : NULL;
1399 if (lircrc_class[0] !=
'\0')
1400 (*config)->lircrc_class = strdup(lircrc_class);
1402 (*config)->lircrc_class = NULL;
1403 (*config)->sockfd = -1;
1404 if (full_name != NULL) {
1405 *full_name = save_full_name;
1406 save_full_name = NULL;
1410 lirc_freeconfigentries(first);
1413 stack_free(filestack);
1415 free(save_full_name);
1420 int lirc_identify(
int sockfd)
1430 while (ret == EAGAIN || ret == EWOULDBLOCK);
1438 int (check)(
char* s))
1440 struct sockaddr_un addr;
1447 if (lirc_readconfig_only_internal(file, config, check, &filename) == -1)
1450 if ((*config)->lircrc_class == NULL)
1451 goto lirc_readconfig_compat;
1455 addr.sun_family = AF_UNIX;
1458 sizeof(addr.sun_path)) >
sizeof(addr.sun_path)) {
1459 lirc_printf(
"%s: WARNING: file name too long\n", lirc_prog);
1460 goto lirc_readconfig_compat;
1462 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1464 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
1465 lirc_perror(lirc_prog);
1466 goto lirc_readconfig_compat;
1468 if (connect(sockfd, (
struct sockaddr*)&addr,
sizeof(addr)) != -1) {
1469 (*config)->sockfd = sockfd;
1473 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS)
1484 snprintf(command,
sizeof(command),
1485 "lircrcd %s", (*config)->lircrc_class);
1486 ret = system(command);
1487 if (ret == -1 || WEXITSTATUS(ret) != EXIT_SUCCESS)
1488 goto lirc_readconfig_compat;
1491 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1493 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
1494 lirc_perror(lirc_prog);
1495 goto lirc_readconfig_compat;
1497 if (connect(sockfd, (
struct sockaddr*)&addr,
sizeof(addr)) != -1) {
1498 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS) {
1499 (*config)->sockfd = sockfd;
1507 lirc_readconfig_compat:
1517 int (check) (
char* s))
1519 return lirc_readconfig_only_internal(file, config, check, NULL);
1525 if (config != NULL) {
1526 if (config->sockfd != -1) {
1527 (void)close(config->sockfd);
1528 config->sockfd = -1;
1532 lirc_freeconfigentries(config->first);
1533 free(config->current_mode);
1539 static void lirc_clearmode(
struct lirc_config* config)
1543 if (config->current_mode == NULL)
1545 scan = config->first;
1546 while (scan != NULL) {
1547 if (scan->change_mode != NULL)
1548 if (strcasecmp(scan->change_mode,
1549 config->current_mode) == 0)
1550 scan->flags &= ~ecno;
1553 free(config->current_mode);
1554 config->current_mode = NULL;
1558 static char* lirc_execute(
struct lirc_config* config,
1564 if (scan->flags & mode)
1565 lirc_clearmode(config);
1566 if (scan->change_mode != NULL) {
1567 free(config->current_mode);
1568 config->current_mode = strdup(scan->change_mode);
1569 if (scan->flags & once) {
1570 if (scan->flags & ecno)
1573 scan->flags |= ecno;
1576 if (scan->next_config != NULL
1577 && scan->prog != NULL
1578 && (lirc_prog == NULL || strcasecmp(scan->prog, lirc_prog) == 0)
1580 s = scan->next_config->string;
1581 scan->next_config = scan->next_config->next;
1582 if (scan->next_config == NULL)
1583 scan->next_config = scan->config;
1599 int delay_start, rep_delay;
1601 if (scan->ign_first_events) {
1602 if (scan->rep_delay && rep == 0)
1604 "%s: ignoring \"delay\" because \"ignore_first_events\" is also set\n",
1606 rep_delay = scan->ign_first_events;
1609 rep_delay = scan->rep_delay;
1613 if (rep < delay_start)
1616 if (scan->rep == 0 && rep_delay > 0 && rep == rep_delay + delay_start)
1619 if (scan->rep > 0 && rep >= rep_delay + delay_start) {
1620 rep -= rep_delay + delay_start;
1621 return (rep % scan->rep) == 0;
1634 if (scan->code == NULL)
1635 return rep_filter(scan, rep);
1638 if (scan->next_code->remote == LIRC_ALL
1639 || strcasecmp(scan->next_code->remote, remote) == 0) {
1640 if (scan->next_code->button == LIRC_ALL
1641 || strcasecmp(scan->next_code->button, button) == 0) {
1644 if (scan->code->next == NULL || rep == 0) {
1645 scan->next_code = scan->next_code->next;
1646 if (scan->code->next != NULL)
1650 if (scan->next_code == NULL) {
1651 scan->next_code = scan->code;
1652 if (scan->code->next != NULL ||
1653 rep_filter(scan, rep))
1664 if (scan->flags & toggle_reset)
1665 scan->next_config = scan->config;
1668 if (codes == scan->next_code)
1670 codes = codes->next;
1672 while (codes != scan->next_code->next) {
1679 while (next != scan->next_code) {
1680 if (prev->remote == LIRC_ALL
1681 || strcasecmp(prev->remote, next->remote) == 0) {
1682 if (prev->button == LIRC_ALL
1683 || strcasecmp(prev->button,
1684 next->button) == 0) {
1697 if (prev->remote == LIRC_ALL
1698 || strcasecmp(prev->remote, remote) == 0) {
1699 if (prev->button == LIRC_ALL
1700 || strcasecmp(prev->button, button) == 0) {
1702 scan->next_code = prev->next;
1708 codes = codes->next;
1710 scan->next_code = scan->code;
1717 static int warning = 1;
1721 fprintf(stderr,
"%s: warning: lirc_ir2char() is obsolete\n",
1731 static int lirc_code2char_internal(
struct lirc_config* config,
1746 if (sscanf(code,
"%*x %x %*s %*s\n", &rep) == 1) {
1747 backup = strdup(code);
1751 strtok(backup,
" ");
1753 button = strtok(NULL,
" ");
1754 remote = strtok(NULL,
"\n");
1756 if (button == NULL || remote == NULL) {
1761 scan = config->next;
1763 while (scan != NULL) {
1764 exec_level = lirc_iscode(scan, remote, button, rep);
1765 if (exec_level > 0 &&
1766 (scan->mode == NULL ||
1767 (scan->mode != NULL &&
1768 config->current_mode != NULL &&
1769 strcasecmp(scan->mode,
1770 config->current_mode) == 0)) &&
1771 quit_happened == 0) {
1772 if (exec_level > 1) {
1773 s = lirc_execute(config, scan);
1774 if (s != NULL && prog != NULL)
1779 if (scan->flags & quit) {
1781 config->next = NULL;
1784 }
else if (s != NULL) {
1785 config->next = scan->next;
1797 config->next = config->first;
1811 if (config->sockfd != -1) {
1814 while (ret == EAGAIN || ret == EWOULDBLOCK);
1817 *
string = static_buff;
1819 return ret == 0 ? 0 : -1;
1821 return lirc_code2char_internal(config, code,
string, NULL);
1825 int lirc_code2charprog(
struct lirc_config* config,
1836 ret = lirc_code2char_internal(config, code,
string, prog);
1845 static int warning = 1;
1850 fprintf(stderr,
"%s: warning: lirc_nextir() is obsolete\n",
1864 static int end_len = 0;
1870 if (lirc_buffer == NULL) {
1871 lirc_buffer = (
char*)malloc(packet_size + 1);
1872 if (lirc_buffer == NULL) {
1873 lirc_printf(
"%s: out of memory\n", lirc_prog);
1878 while ((end = strchr(lirc_buffer,
'\n')) == NULL) {
1879 if (end_len >= packet_size) {
1884 (
char*)realloc(lirc_buffer, packet_size + 1);
1885 if (new_buffer == NULL)
1887 lirc_buffer = new_buffer;
1889 len = read(lirc_lircd, lirc_buffer + end_len,
1890 packet_size - end_len);
1892 if (len == -1 && errno == EAGAIN)
1898 lirc_buffer[end_len] = 0;
1900 end = strchr(lirc_buffer,
'\n');
1907 end_len = strlen(end);
1910 *code = strdup(lirc_buffer);
1912 memmove(lirc_buffer, end, end_len + 1);
1921 id =
id != NULL ? id :
"default";
1922 snprintf(buf, size, VARRUNDIR
"/%d-%s-lircrcd.socket", getuid(),
id);
1934 if (config->sockfd != -1) {
1938 while (ret == EAGAIN || ret == EWOULDBLOCK);
1945 return config->current_mode;
1955 if (config->sockfd != -1) {
1964 while (r == EAGAIN || r == EWOULDBLOCK);
1971 free(config->current_mode);
1972 config->current_mode = mode ? strdup(mode) : NULL;
1973 return config->current_mode;
1987 while (r == EAGAIN);
2002 scancode, repeat, keysym, remote);
2007 while (r == EAGAIN);
2014 do_connect(
int domain,
struct sockaddr* addr,
size_t size,
int quiet)
2018 fd = socket(domain, SOCK_STREAM, 0);
2021 fprintf(stderr,
"do_connect: could not open socket\n");
2026 if (connect(fd, addr, size) == -1) {
2029 "do_connect: could not connect to socket\n");
2040 const char* socket_path;
2041 struct sockaddr_un addr_un;
2043 socket_path = path ? path : getenv(
"LIRC_SOCKET_PATH");
2044 socket_path = socket_path ? socket_path :
LIRCD;
2045 if (strlen(socket_path) + 1 >
sizeof(addr_un.sun_path)) {
2048 fprintf(stderr,
"%s: socket name is too long\n", prog);
2049 return -ENAMETOOLONG;
2051 addr_un.sun_family = AF_UNIX;
2052 strcpy(addr_un.sun_path, socket_path);
2053 return do_connect(AF_UNIX,
2054 (
struct sockaddr*)&addr_un,
2062 struct addrinfo* addrinfos;
2067 snprintf(service,
sizeof(service),
2069 r = getaddrinfo(address, service, NULL, &addrinfos);
2072 fprintf(stderr,
"get_remote_socket: host %s unknown\n",
2074 return -EADDRNOTAVAIL;
2076 for (a = addrinfos; a != NULL; a = a->ai_next) {
2077 r = do_connect(a->ai_family, a->ai_addr, a->ai_addrlen, quiet);
2081 freeaddrinfo(addrinfos);
#define chk_write(fd, buf, count)
void lirc_command_reply_to_stdout(lirc_cmd_ctx *ctx)
int lirc_init(const char *prog, int verbose)
const char * lirc_setmode(struct lirc_config *config, const char *mode)
char reply[PACKET_SIZE+1]
int lirc_get_local_socket(const char *path, int quiet)
char buffer[PACKET_SIZE+1]
int lirc_command_run(lirc_cmd_ctx *ctx, int fd)
#define LIRCRC_OLD_ROOT_FILE
const char * lirc_getmode(struct lirc_config *config)
int lirc_simulate(int fd, const char *remote, const char *keysym, int scancode, int repeat)
size_t lirc_getsocketname(const char *id, char *buf, size_t size)
int lirc_command_init(lirc_cmd_ctx *ctx, const char *fmt,...)
int lirc_nextcode(char **code)
int lirc_get_remote_socket(const char *address, int port, int quiet)
int lirc_code2char(struct lirc_config *config, char *code, char **string)
int lirc_readconfig_only(const char *file, struct lirc_config **config, int(check)(char *s))
char packet[PACKET_SIZE+1]
int lirc_readconfig(const char *file, struct lirc_config **config, int(check)(char *s))
int lirc_send_one(int fd, const char *remote, const char *keysym)
void lirc_freeconfig(struct lirc_config *config)
3-rd party application interface.
char * lirc_ir2char(struct lirc_config *config, char *code)