37 #include <sys/param.h>
38 #include <sys/socket.h>
40 #include <sys/types.h>
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) {
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");
159 static int read_string(
lirc_cmd_ctx* cmd,
int fd,
const char**
string)
170 if (cmd->
next == NULL || strchr(cmd->
next,
'\n') == NULL) {
171 r = fill_string(fd, cmd);
177 cmd->
next = strchr(cmd->
next,
'\n');
178 if (cmd->
next != NULL) {
189 const char*
string = NULL;
196 todo = strlen(ctx->
packet);
198 logprintf(LIRC_DEBUG,
"lirc_command_run: Sending: %s", data);
200 done = write(fd, (
void *)data, todo);
202 logprintf(LIRC_WARNING,
203 "%s: could not send packet\n", prog);
217 r = read_string(ctx, fd, &
string);
218 }
while (r == EAGAIN);
219 if (strlen(
string) == 0) {
222 logprintf(LIRC_DEBUG,
223 "lirc_command_run, state: %d, input: \"%s\"\n",
224 state,
string ?
string :
"(Null)");
227 if (strcasecmp(
string,
"BEGIN") != 0) {
233 if (strncasecmp(
string, ctx->
packet, strlen(
string)) != 0
234 || strlen(
string) + 1 != strlen(ctx->
packet))
242 if (strcasecmp(
string,
"SUCCESS") == 0) {
244 }
else if (strcasecmp(
string,
"END") == 0) {
245 logprintf(LIRC_NOTICE,
246 "lirc_command_run: status:END");
248 }
else if (strcasecmp(
string,
"ERROR") == 0) {
249 logprintf(LIRC_WARNING,
"%s: command failed: %s",
258 if (strcasecmp(
string,
"END") == 0) {
259 logprintf(LIRC_NOTICE,
260 "lirc_command_run: data:END, status:%d",
263 }
else if (strcasecmp(
string,
"DATA") == 0) {
267 logprintf(LIRC_DEBUG,
268 "data: bad packet: %s\n",
273 data_n = (__u32) strtoul(
string, &endptr, 0);
274 if (!*
string || *endptr) {
288 strcpy(ctx->
reply,
"");
305 if (strcasecmp(
string,
"END") == 0) {
306 logprintf(LIRC_NOTICE,
307 "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){
350 if (lirc_lircd >= 0) {
351 lirc_verbose = verbose;
352 lirc_prog = strdup(prog);
353 if (lirc_prog == NULL) {
354 lirc_printf(
"%s: out of memory\n", prog);
359 lirc_printf(
"%s: could not open socket: %s\n",
361 strerror(-lirc_lircd));
370 if (lirc_prog != NULL) {
374 if (lirc_buffer != NULL) {
378 return (close(lirc_lircd));
382 static int lirc_readline(
char **line, FILE * f)
384 char *newline, *ret, *enlargeline;
387 newline = (
char *)malloc(LIRC_READ + 1);
388 if (newline == NULL) {
389 lirc_printf(
"%s: out of memory\n", lirc_prog);
394 ret = fgets(newline + len, LIRC_READ + 1, f);
396 if (feof(f) && len > 0) {
404 len = strlen(newline);
405 if (newline[len - 1] ==
'\n') {
406 newline[len - 1] = 0;
411 enlargeline = (
char *)realloc(newline, len + 1 + LIRC_READ);
412 if (enlargeline == NULL) {
414 lirc_printf(
"%s: out of memory\n", lirc_prog);
417 newline = enlargeline;
422 static char *lirc_trim(
char *s)
426 while (s[0] ==
' ' || s[0] ==
'\t')
431 if (s[len] ==
' ' || s[len] ==
'\t')
441 static char lirc_parse_escape(
char **s,
const char *name,
int line)
445 unsigned int i, overflow, count;
446 int digits_found, digit;
486 while (++count < 3) {
488 if (c >=
'0' && c <=
'7') {
489 i = (i << 3) + c -
'0';
495 if (i > (1 << CHAR_BIT) - 1) {
496 i &= (1 << CHAR_BIT) - 1;
497 lirc_printf(
"%s: octal escape sequence out of range in %s:%d\n", lirc_prog, name, line);
507 if (c >=
'0' && c <=
'9')
509 else if (c >=
'a' && c <=
'f')
510 digit = c -
'a' + 10;
511 else if (c >=
'A' && c <=
'F')
512 digit = c -
'A' + 10;
517 overflow |= i ^ (i << 4 >> 4);
518 i = (i << 4) + digit;
522 lirc_printf(
"%s: \\x used with no "
523 "following hex digits in %s:%d\n", lirc_prog, name, line);
525 if (overflow || i > (1 << CHAR_BIT) - 1) {
526 i &= (1 << CHAR_BIT) - 1;
527 lirc_printf(
"%s: hex escape sequence out "
528 "of range in %s:%d\n", lirc_prog, name, line);
533 if (c >=
'@' && c <=
'Z')
540 static void lirc_parse_string(
char *s,
const char *name,
int line)
548 *t = lirc_parse_escape(&s, name, line);
560 static void lirc_parse_include(
char *s,
const char *name,
int line)
570 if (*s !=
'"' && *s !=
'<') {
573 if (*s ==
'"' && last !=
'"') {
575 }
else if (*s ==
'<' && last !=
'>') {
579 memmove(s, s + 1, len - 2 + 1);
583 int lirc_mode(
char *token,
char *token2,
char **mode,
587 int (check) (
char *s),
593 new_entry = *new_config;
594 if (strcasecmp(token,
"begin") == 0) {
595 if (token2 == NULL) {
596 if (new_entry == NULL) {
599 if (new_entry == NULL) {
600 lirc_printf(
"%s: out of memory\n", lirc_prog);
603 new_entry->prog = NULL;
604 new_entry->code = NULL;
605 new_entry->rep_delay = 0;
606 new_entry->ign_first_events = 0;
608 new_entry->config = NULL;
609 new_entry->change_mode = NULL;
610 new_entry->flags = none;
611 new_entry->mode = NULL;
612 new_entry->next_config = NULL;
613 new_entry->next_code = NULL;
614 new_entry->next = NULL;
616 *new_config = new_entry;
619 lirc_printf(
"%s: bad file format, %s:%d\n", lirc_prog, name, line);
623 if (new_entry == NULL && *mode == NULL) {
624 *mode = strdup(token2);
629 lirc_printf(
"%s: bad file format, %s:%d\n", lirc_prog, name, line);
633 }
else if (strcasecmp(token,
"end") == 0) {
634 if (token2 == NULL) {
635 if (new_entry != NULL) {
637 if (new_entry->prog == NULL) {
638 lirc_printf(
"%s: prog missing in config before line %d\n", lirc_prog, line);
639 lirc_freeconfigentries(new_entry);
643 if (strcasecmp(new_entry->prog, lirc_prog) != 0) {
644 lirc_freeconfigentries(new_entry);
649 new_entry->next_code = new_entry->code;
650 new_entry->next_config = new_entry->config;
651 if (*last_config == NULL) {
652 *first_config = new_entry;
653 *last_config = new_entry;
655 (*last_config)->next = new_entry;
656 *last_config = new_entry;
661 new_entry->mode = strdup(*mode);
662 if (new_entry->mode == NULL) {
663 lirc_printf(
"%s: out of memory\n", lirc_prog);
669 new_entry->prog != NULL && strcasecmp(new_entry->prog, lirc_prog) == 0) {
672 list = new_entry->config;
673 while (list != NULL) {
674 if (check(list->string) == -1) {
681 if (new_entry->rep_delay == 0 && new_entry->rep > 0) {
682 new_entry->rep_delay = new_entry->rep - 1;
685 lirc_printf(
"%s: %s:%d: 'end' without 'begin'\n", lirc_prog, name, line);
690 if (new_entry != NULL) {
691 lirc_printf(
"%s: %s:%d: missing 'end' token\n", lirc_prog, name, line);
694 if (strcasecmp(*mode, token2) == 0) {
698 lirc_printf(
"%s: \"%s\" doesn't "
699 "match mode \"%s\"\n", lirc_prog, token2, *mode);
703 lirc_printf(
"%s: %s:%d: 'end %s' without 'begin'\n", lirc_prog, name, line, token2);
708 lirc_printf(
"%s: unknown token \"%s\" in %s:%d ignored\n", lirc_prog, token, name, line);
714 unsigned int lirc_flags(
char *
string)
720 s = strtok(
string,
" \t|");
722 if (strcasecmp(s,
"once") == 0) {
724 }
else if (strcasecmp(s,
"quit") == 0) {
726 }
else if (strcasecmp(s,
"mode") == 0) {
728 }
else if (strcasecmp(s,
"startup_mode") == 0) {
729 flags |= startup_mode;
730 }
else if (strcasecmp(s,
"toggle_reset") == 0) {
731 flags |= toggle_reset;
733 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';
775 static char* get_freedesktop_path()
779 if (getenv(
"XDG_CONFIG_HOME") != NULL) {
780 path = malloc(MAXPATHLEN);
781 strncpy(path, getenv(
"XDG_CONFIG_HOME"), MAXPATHLEN);
782 strncat(path,
"/", MAXPATHLEN - strlen(path));
783 strncat(path,
CFG_LIRCRC, MAXPATHLEN - strlen(path));
785 path = get_homepath();
789 strncat(path,
"/.config/lircrc", MAXPATHLEN - strlen(path));
791 if (access(path, R_OK) != 0) {
798 static char *lirc_getfilename(
const char *file,
const char *current_file)
803 filename = get_freedesktop_path();
804 if (filename == NULL) {
806 }
else if (strlen(filename) == 0) {
808 filename = get_homepath();
809 if (filename == NULL) {
814 filename = realloc(filename, strlen(filename) + 1);
815 }
else if (strncmp(file,
"~/", 2) == 0) {
816 filename = get_homepath();
817 if (filename == NULL) {
820 strcat(filename, file + 1);
821 filename = realloc(filename, strlen(filename) + 1);
822 }
else if (file[0] ==
'/' || current_file == NULL) {
824 filename = strdup(file);
825 if (filename == NULL) {
826 lirc_printf(
"%s: out of memory\n", lirc_prog);
831 int pathlen = strlen(current_file);
832 while (pathlen > 0 && current_file[pathlen - 1] !=
'/')
834 filename = (
char *)malloc(pathlen + strlen(file) + 1);
835 if (filename == NULL) {
836 lirc_printf(
"%s: out of memory\n", lirc_prog);
839 memcpy(filename, current_file, pathlen);
840 filename[pathlen] = 0;
841 strcat(filename, file);
847 static FILE *lirc_open(
const char *file,
const char *current_file,
char **full_name)
852 filename = lirc_getfilename(file, current_file);
853 if (filename == NULL) {
857 fin = fopen(filename,
"r");
858 if (fin == NULL && (file != NULL || errno != ENOENT)) {
859 lirc_printf(
"%s: could not open config file %s\n", lirc_prog, filename);
860 lirc_perror(lirc_prog);
861 }
else if (fin == NULL) {
863 fin = fopen(root_file,
"r");
864 if (fin == NULL && errno == ENOENT) {
865 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", lirc_prog,
LIRCRC_ROOT_FILE);
872 lirc_perror(lirc_prog);
873 }
else if (fin == NULL) {
874 lirc_printf(
"%s: could not open config files "
876 lirc_perror(lirc_prog);
879 filename = strdup(root_file);
880 if (filename == NULL) {
882 lirc_printf(
"%s: out of memory\n", lirc_prog);
887 if (full_name && fin != NULL) {
888 *full_name = filename;
896 static struct filestack_t *stack_push(
struct filestack_t *parent)
898 struct filestack_t *entry;
899 entry = malloc(
sizeof(
struct filestack_t));
901 lirc_printf(
"%s: out of memory\n", lirc_prog);
907 entry->parent = parent;
912 static struct filestack_t *stack_pop(
struct filestack_t *entry)
914 struct filestack_t *parent = NULL;
916 parent = entry->parent;
925 static void stack_free(
struct filestack_t *entry)
928 entry = stack_pop(entry);
941 while (scan != NULL) {
942 if (scan->flags & startup_mode) {
943 if (scan->change_mode != NULL) {
944 startupmode = scan->change_mode;
946 scan->change_mode = NULL;
949 lirc_printf(
"%s: startup_mode flags requires 'mode ='\n", lirc_prog);
956 if (startupmode == NULL) {
958 while (scan != NULL) {
959 if (scan->mode != NULL && strcasecmp(lirc_prog, scan->mode) == 0) {
960 startupmode = lirc_prog;
967 if (startupmode == NULL)
970 while (scan != NULL) {
971 if (scan->change_mode != NULL && scan->flags & once && strcasecmp(startupmode, scan->change_mode) == 0) {
976 return (startupmode);
991 free(c->change_mode);
996 while (code != NULL) {
997 if (code->remote != NULL && code->remote != LIRC_ALL)
999 if (code->button != NULL && code->button != LIRC_ALL)
1001 code_temp = code->next;
1007 while (list != NULL) {
1010 list_temp = list->next;
1014 config_temp = c->next;
1022 parse_shebang(
char* line,
int depth,
const char* path,
char* buff,
size_t size)
1026 const char*
const SHEBANG_MSG =
1027 "Warning: Use of deprecated lircrc shebang."
1028 " Use lircrc_class instead.\n";
1030 token = strtok(line,
"#! ");
1033 lirc_printf(
"Warning: ignoring shebang in included file.");
1036 if (strcmp(token,
"lircrc") == 0) {
1037 strncpy(my_path, path,
sizeof(my_path) - 1);
1038 strncat(buff, basename(my_path), size - 1);
1039 lirc_printf(SHEBANG_MSG);
1041 lirc_printf(
"Warning: bad shebang (ignored)");
1046 static int lirc_readconfig_only_internal(
const char *file,
1048 int (check) (
char *s),
char **full_name)
1050 const char*
const INCLUDED_LIRCRC_CLASS =
1051 "Warning: lirc_class in included file (ignored)";
1052 char *string, *eq, *token, *token2, *token3;
1053 struct filestack_t *filestack, *stack_tmp;
1055 char lircrc_class[128] = {
'\0'};
1057 char *mode, *remote;
1060 char *save_full_name = NULL;
1062 filestack = stack_push(NULL);
1063 if (filestack == NULL) {
1066 filestack->file = lirc_open(file, NULL, &(filestack->name));
1067 if (filestack->file == NULL) {
1068 stack_free(filestack);
1071 filestack->line = 0;
1074 first = new_entry = last = NULL;
1078 if ((ret = lirc_readline(&
string, filestack->file)) == -1 ||
string == NULL) {
1079 fclose(filestack->file);
1080 if (open_files == 1 && full_name != NULL) {
1081 save_full_name = filestack->name;
1082 filestack->name = NULL;
1084 filestack = stack_pop(filestack);
1091 if (strncmp(
string,
"#!", 2) == 0) {
1092 parse_shebang(
string,
1096 sizeof(lircrc_class));
1100 eq = strchr(
string,
'=');
1102 token = strtok(
string,
" \t");
1103 if (token == NULL) {
1105 }
else if (token[0] ==
'#') {
1107 }
else if (strcasecmp(token,
"lircrc_class") == 0) {
1108 token2 = lirc_trim(strtok(NULL,
""));
1109 if (strlen(token2) == 0) {
1111 "Warning: no lircrc_class");
1112 }
else if (open_files == 1) {
1113 strncat(lircrc_class,
1115 sizeof(lircrc_class) - 1);
1117 lirc_printf(INCLUDED_LIRCRC_CLASS);
1119 }
else if (strcasecmp(token,
"include") == 0) {
1120 if (open_files >= MAX_INCLUDES) {
1121 lirc_printf(
"%s: too many files "
1122 "included at %s:%d\n", lirc_prog, filestack->name, filestack->line);
1125 token2 = strtok(NULL,
"");
1126 token2 = lirc_trim(token2);
1127 lirc_parse_include(token2, filestack->name, filestack->line);
1128 stack_tmp = stack_push(filestack);
1129 if (stack_tmp == NULL) {
1133 lirc_open(token2, filestack->name, &(stack_tmp->name));
1134 stack_tmp->line = 0;
1135 if (stack_tmp->file) {
1137 filestack = stack_tmp;
1139 stack_pop(stack_tmp);
1145 token2 = strtok(NULL,
" \t");
1146 if (token2 != NULL && (token3 = strtok(NULL,
" \t")) != NULL) {
1147 lirc_printf(
"%s: unexpected token in line %s:%d\n",
1148 lirc_prog, filestack->name, filestack->line);
1150 ret = lirc_mode(token, token2, &mode,
1151 &new_entry, &first, &last,
1152 check, filestack->name, filestack->line);
1154 if (remote != LIRC_ALL)
1162 if (new_entry != NULL) {
1163 lirc_freeconfigentries(new_entry);
1171 token = lirc_trim(
string);
1172 token2 = lirc_trim(eq + 1);
1173 if (token[0] ==
'#') {
1175 }
else if (new_entry == NULL) {
1176 lirc_printf(
"%s: bad file format, %s:%d\n",
1177 lirc_prog, filestack->name, filestack->line);
1180 token2 = strdup(token2);
1181 if (token2 == NULL) {
1182 lirc_printf(
"%s: out of memory\n", lirc_prog);
1184 }
else if (strcasecmp(token,
"prog") == 0) {
1185 if (new_entry->prog != NULL)
1186 free(new_entry->prog);
1187 new_entry->prog = token2;
1188 }
else if (strcasecmp(token,
"remote") == 0) {
1189 if (remote != LIRC_ALL)
1192 if (strcasecmp(
"*", token2) == 0) {
1198 }
else if (strcasecmp(token,
"button") == 0) {
1205 lirc_printf(
"%s: out of memory\n", lirc_prog);
1208 code->remote = remote;
1209 if (strcasecmp(
"*", token2) == 0) {
1210 code->button = LIRC_ALL;
1213 code->button = token2;
1217 if (new_entry->code == NULL) {
1218 new_entry->code = code;
1220 new_entry->next_code->next = code;
1222 new_entry->next_code = code;
1223 if (remote != LIRC_ALL) {
1224 remote = strdup(remote);
1225 if (remote == NULL) {
1226 lirc_printf(
"%s: out of memory\n", lirc_prog);
1231 }
else if (strcasecmp(token,
"delay") == 0) {
1235 new_entry->rep_delay = strtoul(token2, &end, 0);
1236 if ((new_entry->rep_delay == ULONG_MAX && errno == ERANGE)
1237 || end[0] != 0 || strlen(token2) == 0) {
1238 lirc_printf(
"%s: \"%s\" not"
1239 " a valid number for delay\n", lirc_prog, token2);
1242 }
else if (strcasecmp(token,
"ignore_first_events") == 0) {
1246 new_entry->ign_first_events = strtoul(token2, &end, 0);
1247 if ((new_entry->ign_first_events == ULONG_MAX && errno == ERANGE)
1248 || end[0] != 0 || strlen(token2) == 0) {
1249 lirc_printf(
"%s: \"%s\" not"
1250 " a valid number for ignore_first_events\n", lirc_prog, token2);
1253 }
else if (strcasecmp(token,
"repeat") == 0) {
1257 new_entry->rep = strtoul(token2, &end, 0);
1258 if ((new_entry->rep == ULONG_MAX && errno == ERANGE)
1259 || end[0] != 0 || strlen(token2) == 0) {
1260 lirc_printf(
"%s: \"%s\" not"
1261 " a valid number for repeat\n", lirc_prog, token2);
1264 }
else if (strcasecmp(token,
"config") == 0) {
1269 if (new_list == NULL) {
1271 lirc_printf(
"%s: out of memory\n", lirc_prog);
1274 lirc_parse_string(token2, filestack->name, filestack->line);
1275 new_list->string = token2;
1276 new_list->next = NULL;
1277 if (new_entry->config == NULL) {
1278 new_entry->config = new_list;
1280 new_entry->next_config->next = new_list;
1282 new_entry->next_config = new_list;
1284 }
else if (strcasecmp(token,
"mode") == 0) {
1285 if (new_entry->change_mode != NULL)
1286 free(new_entry->change_mode);
1287 new_entry->change_mode = token2;
1288 }
else if (strcasecmp(token,
"flags") == 0) {
1289 new_entry->flags = lirc_flags(token2);
1293 lirc_printf(
"%s: unknown token \"%s\" in %s:%d ignored\n",
1294 lirc_prog, token, filestack->name, filestack->line);
1302 if (remote != LIRC_ALL)
1304 if (new_entry != NULL) {
1306 ret = lirc_mode(
"end", NULL, &mode, &new_entry, &first, &last, check,
"", 0);
1307 lirc_printf(
"%s: warning: end token missing at end of file\n", lirc_prog);
1309 lirc_freeconfigentries(new_entry);
1315 lirc_printf(
"%s: warning: no end token found for mode \"%s\"\n", lirc_prog, mode);
1324 if (*config == NULL) {
1325 lirc_printf(
"%s: out of memory\n", lirc_prog);
1326 lirc_freeconfigentries(first);
1329 (*config)->first = first;
1330 (*config)->next = first;
1331 startupmode = lirc_startupmode((*config)->first);
1332 (*config)->current_mode = startupmode ? strdup(startupmode) : NULL;
1333 if (lircrc_class[0] !=
'\0') {
1334 (*config)->lircrc_class = strdup(lircrc_class);
1336 (*config)->lircrc_class = NULL;
1338 (*config)->sockfd = -1;
1339 if (full_name != NULL) {
1340 *full_name = save_full_name;
1341 save_full_name = NULL;
1345 lirc_freeconfigentries(first);
1348 stack_free(filestack);
1350 if (save_full_name) {
1351 free(save_full_name);
1357 int lirc_identify(
int sockfd)
1367 }
while (ret == EAGAIN || ret == EWOULDBLOCK);
1375 struct sockaddr_un addr;
1382 if (lirc_readconfig_only_internal(file, config, check, &filename) == -1) {
1386 if ((*config)->lircrc_class == NULL) {
1387 goto lirc_readconfig_compat;
1392 addr.sun_family = AF_UNIX;
1395 sizeof(addr.sun_path)) >
sizeof(addr.sun_path))
1397 lirc_printf(
"%s: WARNING: file name too long\n", lirc_prog);
1398 goto lirc_readconfig_compat;
1400 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1402 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
1403 lirc_perror(lirc_prog);
1404 goto lirc_readconfig_compat;
1406 if (connect(sockfd, (
struct sockaddr *)&addr,
sizeof(addr)) != -1) {
1407 (*config)->sockfd = sockfd;
1411 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS) {
1423 snprintf(command,
sizeof(command),
1424 "lircrcd %s", (*config)->lircrc_class);
1425 ret = system(command);
1426 if (ret == -1 || WEXITSTATUS(ret) != EXIT_SUCCESS) {
1427 goto lirc_readconfig_compat;
1431 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1433 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
1434 lirc_perror(lirc_prog);
1435 goto lirc_readconfig_compat;
1437 if (connect(sockfd, (
struct sockaddr *)&addr,
sizeof(addr)) != -1) {
1438 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS) {
1439 (*config)->sockfd = sockfd;
1447 lirc_readconfig_compat:
1458 return lirc_readconfig_only_internal(file, config, check, NULL);
1464 if (config != NULL) {
1465 if (config->sockfd != -1) {
1466 (void)close(config->sockfd);
1467 config->sockfd = -1;
1471 lirc_freeconfigentries(config->first);
1472 free(config->current_mode);
1478 static void lirc_clearmode(
struct lirc_config *config)
1482 if (config->current_mode == NULL) {
1485 scan = config->first;
1486 while (scan != NULL) {
1487 if (scan->change_mode != NULL) {
1488 if (strcasecmp(scan->change_mode, config->current_mode) == 0) {
1489 scan->flags &= ~ecno;
1494 free(config->current_mode);
1495 config->current_mode = NULL;
1504 if (scan->flags & mode) {
1505 lirc_clearmode(config);
1507 if (scan->change_mode != NULL) {
1508 free(config->current_mode);
1509 config->current_mode = strdup(scan->change_mode);
1510 if (scan->flags & once) {
1511 if (scan->flags & ecno) {
1514 scan->flags |= ecno;
1518 if (scan->next_config != NULL &&
1519 scan->prog != NULL && (lirc_prog == NULL || strcasecmp(scan->prog, lirc_prog) == 0) && do_once == 1) {
1520 s = scan->next_config->string;
1521 scan->next_config = scan->next_config->next;
1522 if (scan->next_config == NULL)
1523 scan->next_config = scan->config;
1539 int delay_start, rep_delay;
1540 if (scan->ign_first_events) {
1541 if (scan->rep_delay && rep == 0)
1542 lirc_printf(
"%s: ignoring \"delay\" because \"ignore_first_events\" is also set\n",
1544 rep_delay = scan->ign_first_events;
1547 rep_delay = scan->rep_delay;
1551 if (rep < delay_start)
1554 if (scan->rep == 0 && rep_delay > 0 && rep == rep_delay + delay_start)
1557 if (scan->rep > 0 && rep >= rep_delay + delay_start) {
1558 rep -= rep_delay + delay_start;
1559 return ((rep % scan->rep) == 0);
1564 static int lirc_iscode(
struct lirc_config_entry *scan,
char *remote,
char *button,
int rep)
1569 if (scan->code == NULL) {
1570 return rep_filter(scan, rep);
1574 if (scan->next_code->remote == LIRC_ALL || strcasecmp(scan->next_code->remote, remote) == 0) {
1575 if (scan->next_code->button == LIRC_ALL || strcasecmp(scan->next_code->button, button) == 0) {
1578 if (scan->code->next == NULL || rep == 0) {
1579 scan->next_code = scan->next_code->next;
1580 if (scan->code->next != NULL) {
1585 if (scan->next_code == NULL) {
1586 scan->next_code = scan->code;
1587 if (scan->code->next != NULL || rep_filter(scan, rep))
1598 if (scan->flags & toggle_reset) {
1599 scan->next_config = scan->config;
1603 if (codes == scan->next_code)
1605 codes = codes->next;
1607 while (codes != scan->next_code->next) {
1613 while (next != scan->next_code) {
1614 if (prev->remote == LIRC_ALL || strcasecmp(prev->remote, next->remote) == 0) {
1615 if (prev->button == LIRC_ALL || strcasecmp(prev->button, next->button) == 0) {
1628 if (prev->remote == LIRC_ALL || strcasecmp(prev->remote, remote) == 0) {
1629 if (prev->button == LIRC_ALL || strcasecmp(prev->button, button) == 0) {
1631 scan->next_code = prev->next;
1637 codes = codes->next;
1639 scan->next_code = scan->code;
1646 static int warning = 1;
1650 fprintf(stderr,
"%s: warning: lirc_ir2char() is obsolete\n", lirc_prog);
1659 static int lirc_code2char_internal(
struct lirc_config *config,
char *code,
char **
string,
char **prog)
1663 char *remote, *button;
1670 if (sscanf(code,
"%*x %x %*s %*s\n", &rep) == 1) {
1671 backup = strdup(code);
1675 strtok(backup,
" ");
1677 button = strtok(NULL,
" ");
1678 remote = strtok(NULL,
"\n");
1680 if (button == NULL || remote == NULL) {
1685 scan = config->next;
1687 while (scan != NULL) {
1688 exec_level = lirc_iscode(scan, remote, button, rep);
1689 if (exec_level > 0 &&
1690 (scan->mode == NULL ||
1691 (scan->mode != NULL &&
1692 config->current_mode != NULL &&
1693 strcasecmp(scan->mode, config->current_mode) == 0)) && quit_happened == 0) {
1694 if (exec_level > 1) {
1695 s = lirc_execute(config, scan);
1696 if (s != NULL && prog != NULL) {
1702 if (scan->flags & quit) {
1704 config->next = NULL;
1707 }
else if (s != NULL) {
1708 config->next = scan->next;
1720 config->next = config->first;
1734 if (config->sockfd != -1) {
1737 }
while (ret == EAGAIN || ret == EWOULDBLOCK);
1740 *
string = static_buff;
1742 return ret == 0 ? 0 : -1;
1744 return lirc_code2char_internal(config, code,
string, NULL);
1748 int lirc_code2charprog(
struct lirc_config *config,
char *code,
char **
string,
char **prog)
1756 ret = lirc_code2char_internal(config, code,
string, prog);
1765 static int warning = 1;
1770 fprintf(stderr,
"%s: warning: lirc_nextir() is obsolete\n", lirc_prog);
1783 static int end_len = 0;
1788 if (lirc_buffer == NULL) {
1789 lirc_buffer = (
char *)malloc(packet_size + 1);
1790 if (lirc_buffer == NULL) {
1791 lirc_printf(
"%s: out of memory\n", lirc_prog);
1796 while ((end = strchr(lirc_buffer,
'\n')) == NULL) {
1797 if (end_len >= packet_size) {
1801 new_buffer = (
char *)realloc(lirc_buffer, packet_size + 1);
1802 if (new_buffer == NULL) {
1805 lirc_buffer = new_buffer;
1807 len = read(lirc_lircd, lirc_buffer + end_len, packet_size - end_len);
1809 if (len == -1 && errno == EAGAIN)
1815 lirc_buffer[end_len] = 0;
1817 if ((end = strchr(lirc_buffer,
'\n')) == NULL) {
1824 end_len = strlen(end);
1827 *code = strdup(lirc_buffer);
1829 memmove(lirc_buffer, end, end_len + 1);
1838 id =
id != NULL ?
id :
"default";
1839 snprintf(buf, size, VARRUNDIR
"/%d-%s-lircrcd.socket", getuid(),
id);
1851 if (config->sockfd != -1) {
1855 }
while (ret == EAGAIN || ret == EWOULDBLOCK);
1862 return config->current_mode;
1872 if (config->sockfd != -1) {
1883 }
while (r == EAGAIN || r == EWOULDBLOCK);
1890 free(config->current_mode);
1891 config->current_mode = mode ? strdup(mode) : NULL;
1892 return config->current_mode;
1908 }
while (r == EAGAIN);
1923 scancode, repeat, keysym, remote);
1929 }
while (r == EAGAIN);
1936 do_connect(
int domain,
struct sockaddr* addr,
size_t size,
int quiet)
1940 fd = socket(domain, SOCK_STREAM, 0);
1943 fprintf(stderr,
"do_connect: could not open socket\n");
1948 if (connect(fd, addr, size) == -1) {
1951 "do_connect: could not connect to socket\n");
1962 const char* socket_path;
1963 struct sockaddr_un addr_un;
1965 socket_path = path ? path : getenv(
"LIRC_SOCKET_PATH");
1966 socket_path = socket_path ? socket_path :
LIRCD;
1967 if (strlen(socket_path) + 1 >
sizeof(addr_un.sun_path)) {
1970 fprintf(stderr,
"%s: socket name is too long\n", prog);
1972 return -ENAMETOOLONG;
1974 addr_un.sun_family = AF_UNIX;
1975 strcpy(addr_un.sun_path, socket_path);
1976 return do_connect(AF_UNIX,
1977 (
struct sockaddr *) &addr_un,
1985 struct sockaddr_in addr_in;
1986 struct hostent* hostInfo;
1988 hostInfo = gethostbyname(address);
1989 if (hostInfo == NULL) {
1991 fprintf(stderr,
"get_remote_socket: host %s unknown\n",
1994 return -EADDRNOTAVAIL;
1996 addr_in.sin_family = hostInfo->h_addrtype;
1997 memcpy((
char *) &addr_in.sin_addr.s_addr,
1998 hostInfo->h_addr_list[0],
1999 hostInfo->h_length);
2001 return do_connect(hostInfo->h_addrtype,
2002 (
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)