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