32 #include <sys/param.h>
33 #include <sys/socket.h>
35 #include <sys/types.h>
43 static const struct timeval CMD_TIMEOUT = { .tv_sec = 1, .tv_usec = 0 };
47 #define logprintf(level, fmt, args ...) syslog(level, fmt, ## args)
48 #define LIRC_WARNING LOG_WARNING
49 #define LIRC_DEBUG LOG_DEBUG
50 #define LIRC_NOTICE LOG_NOTICE
51 #define LIRC_ERROR LOG_ERR
54 #define MAX_INCLUDES 10
56 #define LIRC_PACKET_SIZE 255
58 #define LIRC_TIMEOUT 3
65 struct filestack_t* parent;
86 unsigned int lirc_flags(
char*
string);
88 static int lirc_lircd;
89 static int lirc_verbose = 0;
90 static char* lirc_prog = NULL;
91 static char* lirc_buffer = NULL;
97 chk_write(
int fd,
const void* buf,
size_t count,
const char* msg)
99 if (write(fd, buf, count) == -1)
114 logprintf(LIRC_NOTICE,
"Message too big: %s", ctx->
packet);
135 (
const void*)&CMD_TIMEOUT,
136 sizeof(CMD_TIMEOUT));
139 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
140 logprintf(LIRC_NOTICE,
"fill_string: timeout\n");
152 static int read_string(
lirc_cmd_ctx* cmd,
int fd,
const char**
string)
163 if (cmd->
next == NULL || strchr(cmd->
next,
'\n') == NULL) {
164 r = fill_string(fd, cmd);
170 cmd->
next = strchr(cmd->
next,
'\n');
171 if (cmd->
next != NULL) {
182 const char*
string = NULL;
189 todo = strlen(ctx->
packet);
191 logprintf(LIRC_DEBUG,
"lirc_command_run: Sending: %s", data);
193 done = write(fd, (
void*)data, todo);
195 logprintf(LIRC_WARNING,
196 "%s: could not send packet\n", prog);
210 r = read_string(ctx, fd, &
string);
212 if (!
string || strlen(
string) == 0)
214 logprintf(LIRC_DEBUG,
215 "lirc_command_run, state: %d, input: \"%s\"\n",
216 state,
string ?
string :
"(Null)");
219 if (strcasecmp(
string,
"BEGIN") != 0)
224 if (strncasecmp(
string, ctx->
packet,
226 || strlen(
string) + 1 != strlen(ctx->
packet)) {
233 if (strcasecmp(
string,
"SUCCESS") == 0) {
235 }
else if (strcasecmp(
string,
"END") == 0) {
236 logprintf(LIRC_NOTICE,
237 "lirc_command_run: status:END");
239 }
else if (strcasecmp(
string,
"ERROR") == 0) {
240 logprintf(LIRC_WARNING,
241 "%s: command failed: %s",
250 if (strcasecmp(
string,
"END") == 0) {
251 logprintf(LIRC_NOTICE,
252 "lirc_command_run: data:END, status:%d",
255 }
else if (strcasecmp(
string,
"DATA") == 0) {
259 logprintf(LIRC_DEBUG,
260 "data: bad packet: %s\n",
265 data_n = (__u32)strtoul(
string, &endptr, 0);
266 if (!*
string || *endptr)
278 strcpy(ctx->
reply,
"");
294 if (strcasecmp(
string,
"END") == 0) {
295 logprintf(LIRC_NOTICE,
296 "lirc_command_run: status:END, status:%d",
304 logprintf(LIRC_WARNING,
"%s: bad return packet\n", prog);
305 logprintf(LIRC_DEBUG,
"State %d: bad packet: %s\n", status,
string);
310 static void lirc_printf(
const char* format_str, ...)
317 va_start(ap, format_str);
318 vfprintf(stderr, format_str, ap);
323 static void lirc_perror(
const char* s)
334 if (prog == NULL || lirc_prog != NULL)
337 if (lirc_lircd >= 0) {
338 lirc_verbose = verbose;
339 lirc_prog = strdup(prog);
340 if (lirc_prog == NULL) {
341 lirc_printf(
"%s: out of memory\n", prog);
346 lirc_printf(
"%s: could not open socket: %s\n",
348 strerror(-lirc_lircd));
355 if (lirc_prog != NULL) {
359 if (lirc_buffer != NULL) {
363 return close(lirc_lircd);
367 static int lirc_readline(
char** line, FILE* f)
374 newline = (
char*)malloc(LIRC_READ + 1);
375 if (newline == NULL) {
376 lirc_printf(
"%s: out of memory\n", lirc_prog);
381 ret = fgets(newline + len, LIRC_READ + 1, f);
383 if (feof(f) && len > 0) {
391 len = strlen(newline);
392 if (newline[len - 1] ==
'\n') {
393 newline[len - 1] = 0;
398 enlargeline = (
char*)realloc(newline, len + 1 + LIRC_READ);
399 if (enlargeline == NULL) {
401 lirc_printf(
"%s: out of memory\n", lirc_prog);
404 newline = enlargeline;
409 static char* lirc_trim(
char* s)
413 while (s[0] ==
' ' || s[0] ==
'\t')
418 if (s[len] ==
' ' || s[len] ==
'\t')
428 static char lirc_parse_escape(
char** s,
const char* name,
int line)
431 unsigned int i, overflow, count;
432 int digits_found, digit;
472 while (++count < 3) {
474 if (c >=
'0' && c <=
'7') {
475 i = (i << 3) + c -
'0';
481 if (i > (1 << CHAR_BIT) - 1) {
482 i &= (1 << CHAR_BIT) - 1;
484 "%s: octal escape sequence out of range in %s:%d\n",
485 lirc_prog, name, line);
495 if (c >=
'0' && c <=
'9') {
497 }
else if (c >=
'a' && c <=
'f') {
498 digit = c -
'a' + 10;
499 }
else if (c >=
'A' && c <=
'F') {
500 digit = c -
'A' + 10;
505 overflow |= i ^ (i << 4 >> 4);
506 i = (i << 4) + digit;
510 lirc_printf(
"%s: \\x used with no "
511 "following hex digits in %s:%d\n",
512 lirc_prog, name, line);
513 if (overflow || i > (1 << CHAR_BIT) - 1) {
514 i &= (1 << CHAR_BIT) - 1;
515 lirc_printf(
"%s: hex escape sequence out "
516 "of range in %s:%d\n", lirc_prog, name,
522 if (c >=
'@' && c <=
'Z')
529 static void lirc_parse_string(
char* s,
const char* name,
int line)
537 *t = lirc_parse_escape(&s, name, line);
549 static void lirc_parse_include(
char* s,
const char* name,
int line)
558 if (*s !=
'"' && *s !=
'<')
560 if (*s ==
'"' && last !=
'"')
562 else if (*s ==
'<' && last !=
'>')
565 memmove(s, s + 1, len - 2 + 1);
569 int lirc_mode(
char* token,
char* token2,
char** mode,
573 int (check) (
char* s),
579 new_entry = *new_config;
580 if (strcasecmp(token,
"begin") == 0) {
581 if (token2 == NULL) {
582 if (new_entry == NULL) {
585 if (new_entry == NULL) {
586 lirc_printf(
"%s: out of memory\n",
590 new_entry->prog = NULL;
591 new_entry->code = NULL;
592 new_entry->rep_delay = 0;
593 new_entry->ign_first_events = 0;
595 new_entry->config = NULL;
596 new_entry->change_mode = NULL;
597 new_entry->flags = none;
598 new_entry->mode = NULL;
599 new_entry->next_config = NULL;
600 new_entry->next_code = NULL;
601 new_entry->next = NULL;
602 *new_config = new_entry;
604 lirc_printf(
"%s: bad file format, %s:%d\n",
605 lirc_prog, name, line);
609 if (new_entry == NULL && *mode == NULL) {
610 *mode = strdup(token2);
614 lirc_printf(
"%s: bad file format, %s:%d\n",
615 lirc_prog, name, line);
619 }
else if (strcasecmp(token,
"end") == 0) {
620 if (token2 == NULL) {
621 if (new_entry != NULL) {
623 if (new_entry->prog == NULL) {
625 "%s: prog missing in config before line %d\n", lirc_prog,
627 lirc_freeconfigentries(new_entry);
631 if (strcasecmp(new_entry->prog,
633 lirc_freeconfigentries(new_entry);
638 new_entry->next_code = new_entry->code;
639 new_entry->next_config = new_entry->config;
640 if (*last_config == NULL) {
641 *first_config = new_entry;
642 *last_config = new_entry;
644 (*last_config)->next = new_entry;
645 *last_config = new_entry;
650 new_entry->mode = strdup(*mode);
651 if (new_entry->mode == NULL) {
653 "%s: out of memory\n",
660 new_entry->prog != NULL &&
661 strcasecmp(new_entry->prog,
665 list = new_entry->config;
666 while (list != NULL) {
667 if (check(list->string) == -1)
673 if (new_entry->rep_delay == 0 &&
675 new_entry->rep_delay = new_entry->rep -
679 "%s: %s:%d: 'end' without 'begin'\n",
680 lirc_prog, name, line);
685 if (new_entry != NULL) {
687 "%s: %s:%d: missing 'end' token\n",
688 lirc_prog, name, line);
691 if (strcasecmp(*mode, token2) == 0) {
695 lirc_printf(
"%s: \"%s\" doesn't "
696 "match mode \"%s\"\n",
697 lirc_prog, token2, *mode);
702 "%s: %s:%d: 'end %s' without 'begin'\n",
703 lirc_prog, name, line, token2);
708 lirc_printf(
"%s: unknown token \"%s\" in %s:%d ignored\n",
709 lirc_prog, token, name, line);
715 unsigned int lirc_flags(
char*
string)
721 s = strtok(
string,
" \t|");
723 if (strcasecmp(s,
"once") == 0)
725 else if (strcasecmp(s,
"quit") == 0)
727 else if (strcasecmp(s,
"mode") == 0)
729 else if (strcasecmp(s,
"startup_mode") == 0)
730 flags |= startup_mode;
731 else if (strcasecmp(s,
"toggle_reset") == 0)
732 flags |= toggle_reset;
734 lirc_printf(
"%s: unknown flag \"%s\"\n", lirc_prog, s);
735 s = strtok(NULL,
" \t");
750 static char* get_homepath(
void)
755 filename = malloc(MAXPATHLEN);
756 if (filename == NULL) {
757 lirc_printf(
"%s: out of memory\n", lirc_prog);
760 home = getenv(
"HOME");
761 home = home == NULL ?
"/" : home;
762 strncpy(filename, home, MAXPATHLEN);
763 if (filename[strlen(filename) - 1] ==
'/')
764 filename[strlen(filename) - 1] =
'\0';
774 static char* get_freedesktop_path(
void)
778 if (getenv(
"XDG_CONFIG_HOME") != NULL) {
779 path = malloc(MAXPATHLEN);
780 strncpy(path, getenv(
"XDG_CONFIG_HOME"), MAXPATHLEN);
781 strncat(path,
"/", MAXPATHLEN - strlen(path));
782 strncat(path,
CFG_LIRCRC, MAXPATHLEN - strlen(path));
784 path = get_homepath();
787 strncat(path,
"/.config/lircrc", MAXPATHLEN - strlen(path) - 1);
789 if (access(path, R_OK) != 0)
795 static char* lirc_getfilename(
const char* file,
const char* current_file)
800 filename = get_freedesktop_path();
801 if (filename == NULL) {
803 }
else if (strlen(filename) == 0) {
805 filename = get_homepath();
806 if (filename == NULL)
810 filename = realloc(filename, strlen(filename) + 1);
811 }
else if (strncmp(file,
"~/", 2) == 0) {
812 filename = get_homepath();
813 if (filename == NULL)
815 strcat(filename, file + 1);
816 filename = realloc(filename, strlen(filename) + 1);
817 }
else if (file[0] ==
'/' || current_file == NULL) {
819 filename = strdup(file);
820 if (filename == NULL) {
821 lirc_printf(
"%s: out of memory\n", lirc_prog);
826 int pathlen = strlen(current_file);
828 while (pathlen > 0 && current_file[pathlen - 1] !=
'/')
830 filename = (
char*)malloc(pathlen + strlen(file) + 1);
831 if (filename == NULL) {
832 lirc_printf(
"%s: out of memory\n", lirc_prog);
835 memcpy(filename, current_file, pathlen);
836 filename[pathlen] = 0;
837 strcat(filename, file);
843 static FILE* lirc_open(
const char* file,
844 const char* current_file,
850 filename = lirc_getfilename(file, current_file);
851 if (filename == NULL)
854 fin = fopen(filename,
"r");
855 if (fin == NULL && (file != NULL || errno != ENOENT)) {
856 lirc_printf(
"%s: could not open config file %s\n", lirc_prog,
858 lirc_perror(lirc_prog);
859 }
else if (fin == NULL) {
862 fin = fopen(root_file,
"r");
863 if (fin == NULL && errno == ENOENT) {
864 int save_errno = errno;
867 fin = fopen(root_file,
"r");
870 if (fin == NULL && errno != ENOENT) {
871 lirc_printf(
"%s: could not open config file %s\n",
873 lirc_perror(lirc_prog);
874 }
else if (fin == NULL) {
875 lirc_printf(
"%s: could not open config files "
876 "%s and %s\n", lirc_prog, filename,
878 lirc_perror(lirc_prog);
881 filename = strdup(root_file);
882 if (filename == NULL) {
884 lirc_printf(
"%s: out of memory\n", lirc_prog);
889 if (full_name && fin != NULL)
890 *full_name = filename;
897 static struct filestack_t* stack_push(
struct filestack_t* parent)
899 struct filestack_t* entry;
901 entry = malloc(
sizeof(
struct filestack_t));
903 lirc_printf(
"%s: out of memory\n", lirc_prog);
909 entry->parent = parent;
914 static struct filestack_t* stack_pop(
struct filestack_t* entry)
916 struct filestack_t* parent = NULL;
919 parent = entry->parent;
928 static void stack_free(
struct filestack_t* entry)
931 entry = stack_pop(entry);
943 while (scan != NULL) {
944 if (scan->flags & startup_mode) {
945 if (scan->change_mode != NULL) {
946 startupmode = scan->change_mode;
948 scan->change_mode = NULL;
951 lirc_printf(
"%s: startup_mode flags requires 'mode ='\n", lirc_prog);
957 if (startupmode == NULL) {
959 while (scan != NULL) {
960 if (scan->mode != NULL
961 && strcasecmp(lirc_prog, scan->mode) == 0) {
962 startupmode = lirc_prog;
969 if (startupmode == NULL)
972 while (scan != NULL) {
973 if (scan->change_mode != NULL
974 && scan->flags & once
975 && strcasecmp(startupmode, scan->change_mode) == 0)
997 free(c->change_mode);
1002 while (code != NULL) {
1003 if (code->remote != NULL && code->remote != LIRC_ALL)
1005 if (code->button != NULL && code->button != LIRC_ALL)
1007 code_temp = code->next;
1013 while (list != NULL) {
1016 list_temp = list->next;
1020 config_temp = c->next;
1028 parse_shebang(
char* line,
int depth,
const char* path,
char* buff,
size_t size)
1032 const char*
const SHEBANG_MSG =
1033 "Warning: Use of deprecated lircrc shebang."
1034 " Use lircrc_class instead.\n";
1036 token = strtok(line,
"#! ");
1039 lirc_printf(
"Warning: ignoring shebang in included file.");
1042 if (strcmp(token,
"lircrc") == 0) {
1043 strncpy(my_path, path,
sizeof(my_path) - 1);
1044 strncat(buff, basename(my_path), size - 1);
1045 lirc_printf(SHEBANG_MSG);
1047 lirc_printf(
"Warning: bad shebang (ignored)");
1052 static int lirc_readconfig_only_internal(
const char* file,
1054 int (check)(
char* s),
1057 const char*
const INCLUDED_LIRCRC_CLASS =
1058 "Warning: lirc_class in included file (ignored)";
1064 struct filestack_t* filestack;
1065 struct filestack_t* stack_tmp;
1067 char lircrc_class[128] = {
'\0' };
1075 char* save_full_name = NULL;
1077 filestack = stack_push(NULL);
1078 if (filestack == NULL)
1080 filestack->file = lirc_open(file, NULL, &(filestack->name));
1081 if (filestack->file == NULL) {
1082 stack_free(filestack);
1085 filestack->line = 0;
1088 first = new_entry = last = NULL;
1092 ret = lirc_readline(&
string, filestack->file);
1093 if (ret == -1 ||
string == NULL) {
1094 fclose(filestack->file);
1095 if (open_files == 1 && full_name != NULL) {
1096 save_full_name = filestack->name;
1097 filestack->name = NULL;
1099 filestack = stack_pop(filestack);
1106 if (strncmp(
string,
"#!", 2) == 0) {
1107 parse_shebang(
string,
1111 sizeof(lircrc_class));
1115 eq = strchr(
string,
'=');
1117 token = strtok(
string,
" \t");
1118 if (token == NULL) {
1120 }
else if (token[0] ==
'#') {
1122 }
else if (strcasecmp(token,
"lircrc_class") == 0) {
1123 token2 = lirc_trim(strtok(NULL,
""));
1124 if (strlen(token2) == 0) {
1126 "Warning: no lircrc_class");
1127 }
else if (open_files == 1) {
1128 strncpy(lircrc_class,
1130 sizeof(lircrc_class) - 1);
1132 lirc_printf(INCLUDED_LIRCRC_CLASS);
1134 }
else if (strcasecmp(token,
"include") == 0) {
1135 if (open_files >= MAX_INCLUDES) {
1136 lirc_printf(
"%s: too many files "
1137 "included at %s:%d\n",
1138 lirc_prog, filestack->name,
1142 token2 = strtok(NULL,
"");
1143 token2 = lirc_trim(token2);
1144 lirc_parse_include(token2,
1147 stack_tmp = stack_push(filestack);
1148 if (stack_tmp == NULL) {
1156 stack_tmp->line = 0;
1157 if (stack_tmp->file) {
1159 filestack = stack_tmp;
1161 stack_pop(stack_tmp);
1167 token2 = strtok(NULL,
" \t");
1169 token3 = strtok(NULL,
" \t");
1170 if (token2 != NULL && token3 != NULL) {
1171 lirc_printf(
"%s: unexpected token in line %s:%d\n",
1172 lirc_prog, filestack->name, filestack->line);
1174 ret = lirc_mode(token, token2, &mode,
1177 check, filestack->name,
1180 if (remote != LIRC_ALL)
1188 if (new_entry != NULL) {
1189 lirc_freeconfigentries(
1198 token = lirc_trim(
string);
1199 token2 = lirc_trim(eq + 1);
1200 if (token[0] ==
'#') {
1202 }
else if (new_entry == NULL) {
1203 lirc_printf(
"%s: bad file format, %s:%d\n",
1204 lirc_prog, filestack->name,
1208 token2 = strdup(token2);
1209 if (token2 == NULL) {
1210 lirc_printf(
"%s: out of memory\n",
1213 }
else if (strcasecmp(token,
"prog") == 0) {
1214 if (new_entry->prog != NULL)
1215 free(new_entry->prog);
1216 new_entry->prog = token2;
1217 }
else if (strcasecmp(token,
"remote") == 0) {
1218 if (remote != LIRC_ALL)
1221 if (strcasecmp(
"*", token2) == 0) {
1227 }
else if (strcasecmp(token,
"button") == 0) {
1235 "%s: out of memory\n",
1239 code->remote = remote;
1242 code->button = LIRC_ALL;
1245 code->button = token2;
1249 if (new_entry->code == NULL)
1250 new_entry->code = code;
1252 new_entry->next_code->
1254 new_entry->next_code = code;
1255 if (remote != LIRC_ALL) {
1256 remote = strdup(remote);
1257 if (remote == NULL) {
1259 "%s: out of memory\n",
1265 }
else if (strcasecmp(token,
"delay") == 0) {
1269 new_entry->rep_delay = strtoul(token2,
1271 if ((new_entry->rep_delay ==
1272 ULONG_MAX && errno == ERANGE)
1273 || end[0] != 0 || strlen(token2) ==
1275 lirc_printf(
"%s: \"%s\" not"
1276 " a valid number for delay\n", lirc_prog,
1279 }
else if (strcasecmp(token,
"ignore_first_events") == 0) {
1283 new_entry->ign_first_events = strtoul(
1285 if ((new_entry->ign_first_events ==
1286 ULONG_MAX && errno == ERANGE)
1287 || end[0] != 0 || strlen(token2) ==
1289 lirc_printf(
"%s: \"%s\" not"
1290 " a valid number for ignore_first_events\n",
1293 }
else if (strcasecmp(token,
"repeat") == 0) {
1298 strtoul(token2, &end, 0);
1299 if ((new_entry->rep == ULONG_MAX &&
1301 || end[0] != 0 || strlen(token2) ==
1303 lirc_printf(
"%s: \"%s\" not"
1304 " a valid number for repeat\n", lirc_prog,
1307 }
else if (strcasecmp(token,
"config") == 0) {
1312 if (new_list == NULL) {
1315 "%s: out of memory\n",
1319 lirc_parse_string(token2,
1322 new_list->string = token2;
1323 new_list->next = NULL;
1324 if (new_entry->config == NULL)
1328 new_entry->next_config->
1330 new_entry->next_config =
1333 }
else if (strcasecmp(token,
"mode") == 0) {
1334 if (new_entry->change_mode != NULL)
1335 free(new_entry->change_mode);
1336 new_entry->change_mode = token2;
1337 }
else if (strcasecmp(token,
"flags") == 0) {
1338 new_entry->flags = lirc_flags(token2);
1343 "%s: unknown token \"%s\" in %s:%d ignored\n",
1344 lirc_prog, token, filestack->name,
1353 if (remote != LIRC_ALL)
1355 if (new_entry != NULL) {
1357 ret = lirc_mode(
"end", NULL, &mode, &new_entry, &first,
1358 &last, check,
"", 0);
1360 "%s: warning: end token missing at end of file\n",
1363 lirc_freeconfigentries(new_entry);
1370 "%s: warning: no end token found for mode \"%s\"\n", lirc_prog,
1379 if (*config == NULL) {
1380 lirc_printf(
"%s: out of memory\n", lirc_prog);
1381 lirc_freeconfigentries(first);
1384 (*config)->first = first;
1385 (*config)->next = first;
1386 startupmode = lirc_startupmode((*config)->first);
1387 (*config)->current_mode =
1388 startupmode ? strdup(startupmode) : NULL;
1389 if (lircrc_class[0] !=
'\0')
1390 (*config)->lircrc_class = strdup(lircrc_class);
1392 (*config)->lircrc_class = NULL;
1393 (*config)->sockfd = -1;
1394 if (full_name != NULL) {
1395 *full_name = save_full_name;
1396 save_full_name = NULL;
1400 lirc_freeconfigentries(first);
1403 stack_free(filestack);
1405 free(save_full_name);
1410 int lirc_identify(
int sockfd)
1420 while (ret == EAGAIN || ret == EWOULDBLOCK);
1428 int (check)(
char* s))
1430 struct sockaddr_un addr;
1437 if (lirc_readconfig_only_internal(file, config, check, &filename) == -1)
1440 if ((*config)->lircrc_class == NULL)
1441 goto lirc_readconfig_compat;
1445 addr.sun_family = AF_UNIX;
1448 sizeof(addr.sun_path)) >
sizeof(addr.sun_path)) {
1449 lirc_printf(
"%s: WARNING: file name too long\n", lirc_prog);
1450 goto lirc_readconfig_compat;
1452 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1454 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
1455 lirc_perror(lirc_prog);
1456 goto lirc_readconfig_compat;
1458 if (connect(sockfd, (
struct sockaddr*)&addr,
sizeof(addr)) != -1) {
1459 (*config)->sockfd = sockfd;
1463 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS)
1474 snprintf(command,
sizeof(command),
1475 "lircrcd %s", (*config)->lircrc_class);
1476 ret = system(command);
1477 if (ret == -1 || WEXITSTATUS(ret) != EXIT_SUCCESS)
1478 goto lirc_readconfig_compat;
1481 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1483 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
1484 lirc_perror(lirc_prog);
1485 goto lirc_readconfig_compat;
1487 if (connect(sockfd, (
struct sockaddr*)&addr,
sizeof(addr)) != -1) {
1488 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS) {
1489 (*config)->sockfd = sockfd;
1497 lirc_readconfig_compat:
1507 int (check) (
char* s))
1509 return lirc_readconfig_only_internal(file, config, check, NULL);
1515 if (config != NULL) {
1516 if (config->sockfd != -1) {
1517 (void)close(config->sockfd);
1518 config->sockfd = -1;
1522 lirc_freeconfigentries(config->first);
1523 free(config->current_mode);
1529 static void lirc_clearmode(
struct lirc_config* config)
1533 if (config->current_mode == NULL)
1535 scan = config->first;
1536 while (scan != NULL) {
1537 if (scan->change_mode != NULL)
1538 if (strcasecmp(scan->change_mode,
1539 config->current_mode) == 0)
1540 scan->flags &= ~ecno;
1543 free(config->current_mode);
1544 config->current_mode = NULL;
1548 static char* lirc_execute(
struct lirc_config* config,
1554 if (scan->flags & mode)
1555 lirc_clearmode(config);
1556 if (scan->change_mode != NULL) {
1557 free(config->current_mode);
1558 config->current_mode = strdup(scan->change_mode);
1559 if (scan->flags & once) {
1560 if (scan->flags & ecno)
1563 scan->flags |= ecno;
1566 if (scan->next_config != NULL
1567 && scan->prog != NULL
1568 && (lirc_prog == NULL || strcasecmp(scan->prog, lirc_prog) == 0)
1570 s = scan->next_config->string;
1571 scan->next_config = scan->next_config->next;
1572 if (scan->next_config == NULL)
1573 scan->next_config = scan->config;
1589 int delay_start, rep_delay;
1591 if (scan->ign_first_events) {
1592 if (scan->rep_delay && rep == 0)
1594 "%s: ignoring \"delay\" because \"ignore_first_events\" is also set\n",
1596 rep_delay = scan->ign_first_events;
1599 rep_delay = scan->rep_delay;
1603 if (rep < delay_start)
1606 if (scan->rep == 0 && rep_delay > 0 && rep == rep_delay + delay_start)
1609 if (scan->rep > 0 && rep >= rep_delay + delay_start) {
1610 rep -= rep_delay + delay_start;
1611 return (rep % scan->rep) == 0;
1624 if (scan->code == NULL)
1625 return rep_filter(scan, rep);
1628 if (scan->next_code->remote == LIRC_ALL
1629 || strcasecmp(scan->next_code->remote, remote) == 0) {
1630 if (scan->next_code->button == LIRC_ALL
1631 || strcasecmp(scan->next_code->button, button) == 0) {
1634 if (scan->code->next == NULL || rep == 0) {
1635 scan->next_code = scan->next_code->next;
1636 if (scan->code->next != NULL)
1640 if (scan->next_code == NULL) {
1641 scan->next_code = scan->code;
1642 if (scan->code->next != NULL ||
1643 rep_filter(scan, rep))
1654 if (scan->flags & toggle_reset)
1655 scan->next_config = scan->config;
1658 if (codes == scan->next_code)
1660 codes = codes->next;
1662 while (codes != scan->next_code->next) {
1669 while (next != scan->next_code) {
1670 if (prev->remote == LIRC_ALL
1671 || strcasecmp(prev->remote, next->remote) == 0) {
1672 if (prev->button == LIRC_ALL
1673 || strcasecmp(prev->button,
1674 next->button) == 0) {
1687 if (prev->remote == LIRC_ALL
1688 || strcasecmp(prev->remote, remote) == 0) {
1689 if (prev->button == LIRC_ALL
1690 || strcasecmp(prev->button, button) == 0) {
1692 scan->next_code = prev->next;
1698 codes = codes->next;
1700 scan->next_code = scan->code;
1707 static int warning = 1;
1711 fprintf(stderr,
"%s: warning: lirc_ir2char() is obsolete\n",
1721 static int lirc_code2char_internal(
struct lirc_config* config,
1736 if (sscanf(code,
"%*x %x %*s %*s\n", &rep) == 1) {
1737 backup = strdup(code);
1741 strtok(backup,
" ");
1743 button = strtok(NULL,
" ");
1744 remote = strtok(NULL,
"\n");
1746 if (button == NULL || remote == NULL) {
1751 scan = config->next;
1753 while (scan != NULL) {
1754 exec_level = lirc_iscode(scan, remote, button, rep);
1755 if (exec_level > 0 &&
1756 (scan->mode == NULL ||
1757 (scan->mode != NULL &&
1758 config->current_mode != NULL &&
1759 strcasecmp(scan->mode,
1760 config->current_mode) == 0)) &&
1761 quit_happened == 0) {
1762 if (exec_level > 1) {
1763 s = lirc_execute(config, scan);
1764 if (s != NULL && prog != NULL)
1769 if (scan->flags & quit) {
1771 config->next = NULL;
1774 }
else if (s != NULL) {
1775 config->next = scan->next;
1787 config->next = config->first;
1801 if (config->sockfd != -1) {
1804 while (ret == EAGAIN || ret == EWOULDBLOCK);
1807 *
string = static_buff;
1809 return ret == 0 ? 0 : -1;
1811 return lirc_code2char_internal(config, code,
string, NULL);
1815 int lirc_code2charprog(
struct lirc_config* config,
1826 ret = lirc_code2char_internal(config, code,
string, prog);
1835 static int warning = 1;
1840 fprintf(stderr,
"%s: warning: lirc_nextir() is obsolete\n",
1854 static int end_len = 0;
1860 if (lirc_buffer == NULL) {
1861 lirc_buffer = (
char*)malloc(packet_size + 1);
1862 if (lirc_buffer == NULL) {
1863 lirc_printf(
"%s: out of memory\n", lirc_prog);
1868 while ((end = strchr(lirc_buffer,
'\n')) == NULL) {
1869 if (end_len >= packet_size) {
1874 (
char*)realloc(lirc_buffer, packet_size + 1);
1875 if (new_buffer == NULL)
1877 lirc_buffer = new_buffer;
1879 len = read(lirc_lircd, lirc_buffer + end_len,
1880 packet_size - end_len);
1882 if (len == -1 && errno == EAGAIN)
1888 lirc_buffer[end_len] = 0;
1890 end = strchr(lirc_buffer,
'\n');
1897 end_len = strlen(end);
1900 *code = strdup(lirc_buffer);
1902 memmove(lirc_buffer, end, end_len + 1);
1911 id =
id != NULL ?
id :
"default";
1912 snprintf(buf, size, VARRUNDIR
"/%d-%s-lircrcd.socket", getuid(),
id);
1924 if (config->sockfd != -1) {
1928 while (ret == EAGAIN || ret == EWOULDBLOCK);
1935 return config->current_mode;
1945 if (config->sockfd != -1) {
1954 while (r == EAGAIN || r == EWOULDBLOCK);
1961 free(config->current_mode);
1962 config->current_mode = mode ? strdup(mode) : NULL;
1963 return config->current_mode;
1977 while (r == EAGAIN);
1992 scancode, repeat, keysym, remote);
1997 while (r == EAGAIN);
2004 do_connect(
int domain,
struct sockaddr* addr,
size_t size,
int quiet)
2008 fd = socket(domain, SOCK_STREAM, 0);
2011 fprintf(stderr,
"do_connect: could not open socket\n");
2016 if (connect(fd, addr, size) == -1) {
2019 "do_connect: could not connect to socket\n");
2030 const char* socket_path;
2031 struct sockaddr_un addr_un;
2033 socket_path = path ? path : getenv(
"LIRC_SOCKET_PATH");
2034 socket_path = socket_path ? socket_path :
LIRCD;
2035 if (strlen(socket_path) + 1 >
sizeof(addr_un.sun_path)) {
2038 fprintf(stderr,
"%s: socket name is too long\n", prog);
2039 return -ENAMETOOLONG;
2041 addr_un.sun_family = AF_UNIX;
2042 strcpy(addr_un.sun_path, socket_path);
2043 return do_connect(AF_UNIX,
2044 (
struct sockaddr*)&addr_un,
2052 struct sockaddr_in addr_in;
2053 struct hostent* hostInfo;
2055 hostInfo = gethostbyname(address);
2056 if (hostInfo == NULL) {
2058 fprintf(stderr,
"get_remote_socket: host %s unknown\n",
2060 return -EADDRNOTAVAIL;
2062 addr_in.sin_family = hostInfo->h_addrtype;
2063 memcpy((
char*)&addr_in.sin_addr.s_addr,
2064 hostInfo->h_addr_list[0],
2065 hostInfo->h_length);
2067 return do_connect(hostInfo->h_addrtype,
2068 (
struct sockaddr*)&addr_in,
#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)