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) {
118 logprintf(LIRC_NOTICE,
"Message too big: %s", ctx->
packet);
139 (
const void *)&CMD_TIMEOUT,
140 sizeof(CMD_TIMEOUT));
143 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR){
144 logprintf(LIRC_NOTICE,
"fill_string: timeout\n");
157 static int read_string(
lirc_cmd_ctx* cmd,
int fd,
const char**
string)
168 if (cmd->
next == NULL || strchr(cmd->
next,
'\n') == NULL) {
169 r = fill_string(fd, cmd);
175 cmd->
next = strchr(cmd->
next,
'\n');
176 if (cmd->
next != NULL) {
187 const char*
string = NULL;
194 todo = strlen(ctx->
packet);
196 logprintf(LIRC_DEBUG,
"lirc_command_run: Sending: %s", data);
198 done = write(fd, (
void *)data, todo);
200 logprintf(LIRC_WARNING,
201 "%s: could not send packet\n", prog);
215 r = read_string(ctx, fd, &
string);
216 }
while (r == EAGAIN);
217 if (strlen(
string) == 0) {
220 logprintf(LIRC_DEBUG,
221 "lirc_command_run, state: %d, input: \"%s\"\n",
222 state,
string ?
string :
"(Null)");
225 if (strcasecmp(
string,
"BEGIN") != 0) {
231 if (strncasecmp(
string, ctx->
packet, strlen(
string)) != 0
232 || strlen(
string) + 1 != strlen(ctx->
packet))
240 if (strcasecmp(
string,
"SUCCESS") == 0) {
242 }
else if (strcasecmp(
string,
"END") == 0) {
243 logprintf(LIRC_NOTICE,
244 "lirc_command_run: status:END");
246 }
else if (strcasecmp(
string,
"ERROR") == 0) {
247 logprintf(LIRC_WARNING,
"%s: command failed: %s",
256 if (strcasecmp(
string,
"END") == 0) {
257 logprintf(LIRC_NOTICE,
258 "lirc_command_run: data:END, status:%d",
261 }
else if (strcasecmp(
string,
"DATA") == 0) {
265 logprintf(LIRC_DEBUG,
266 "data: bad packet: %s\n",
271 data_n = (__u32) strtoul(
string, &endptr, 0);
272 if (!*
string || *endptr) {
286 strcpy(ctx->
reply,
"");
303 if (strcasecmp(
string,
"END") == 0) {
304 logprintf(LIRC_NOTICE,
305 "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){
348 if (lirc_lircd >= 0) {
349 lirc_verbose = verbose;
350 lirc_prog = strdup(prog);
351 if (lirc_prog == NULL) {
352 lirc_printf(
"%s: out of memory\n", prog);
357 lirc_printf(
"%s: could not open socket: %s\n",
359 strerror(-lirc_lircd));
368 if (lirc_prog != NULL) {
372 if (lirc_buffer != NULL) {
376 return (close(lirc_lircd));
380 static int lirc_readline(
char **line, FILE * f)
382 char *newline, *ret, *enlargeline;
385 newline = (
char *)malloc(LIRC_READ + 1);
386 if (newline == NULL) {
387 lirc_printf(
"%s: out of memory\n", lirc_prog);
392 ret = fgets(newline + len, LIRC_READ + 1, f);
394 if (feof(f) && len > 0) {
402 len = strlen(newline);
403 if (newline[len - 1] ==
'\n') {
404 newline[len - 1] = 0;
409 enlargeline = (
char *)realloc(newline, len + 1 + LIRC_READ);
410 if (enlargeline == NULL) {
412 lirc_printf(
"%s: out of memory\n", lirc_prog);
415 newline = enlargeline;
420 static char *lirc_trim(
char *s)
424 while (s[0] ==
' ' || s[0] ==
'\t')
429 if (s[len] ==
' ' || s[len] ==
'\t')
439 static char lirc_parse_escape(
char **s,
const char *name,
int line)
443 unsigned int i, overflow, count;
444 int digits_found, digit;
484 while (++count < 3) {
486 if (c >=
'0' && c <=
'7') {
487 i = (i << 3) + c -
'0';
493 if (i > (1 << CHAR_BIT) - 1) {
494 i &= (1 << CHAR_BIT) - 1;
495 lirc_printf(
"%s: octal escape sequence out of range in %s:%d\n", 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", 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, line);
531 if (c >=
'@' && c <=
'Z')
538 static void lirc_parse_string(
char *s,
const char *name,
int line)
546 *t = lirc_parse_escape(&s, name, line);
558 static void lirc_parse_include(
char *s,
const char *name,
int line)
568 if (*s !=
'"' && *s !=
'<') {
571 if (*s ==
'"' && last !=
'"') {
573 }
else if (*s ==
'<' && last !=
'>') {
577 memmove(s, s + 1, len - 2 + 1);
581 int lirc_mode(
char *token,
char *token2,
char **mode,
585 int (check) (
char *s),
591 new_entry = *new_config;
592 if (strcasecmp(token,
"begin") == 0) {
593 if (token2 == NULL) {
594 if (new_entry == NULL) {
597 if (new_entry == NULL) {
598 lirc_printf(
"%s: out of memory\n", lirc_prog);
601 new_entry->prog = NULL;
602 new_entry->code = NULL;
603 new_entry->rep_delay = 0;
604 new_entry->ign_first_events = 0;
606 new_entry->config = NULL;
607 new_entry->change_mode = NULL;
608 new_entry->flags = none;
609 new_entry->mode = NULL;
610 new_entry->next_config = NULL;
611 new_entry->next_code = NULL;
612 new_entry->next = NULL;
614 *new_config = new_entry;
617 lirc_printf(
"%s: bad file format, %s:%d\n", lirc_prog, name, line);
621 if (new_entry == NULL && *mode == NULL) {
622 *mode = strdup(token2);
627 lirc_printf(
"%s: bad file format, %s:%d\n", lirc_prog, name, line);
631 }
else if (strcasecmp(token,
"end") == 0) {
632 if (token2 == NULL) {
633 if (new_entry != NULL) {
635 if (new_entry->prog == NULL) {
636 lirc_printf(
"%s: prog missing in config before line %d\n", lirc_prog, line);
637 lirc_freeconfigentries(new_entry);
641 if (strcasecmp(new_entry->prog, lirc_prog) != 0) {
642 lirc_freeconfigentries(new_entry);
647 new_entry->next_code = new_entry->code;
648 new_entry->next_config = new_entry->config;
649 if (*last_config == NULL) {
650 *first_config = new_entry;
651 *last_config = new_entry;
653 (*last_config)->next = new_entry;
654 *last_config = new_entry;
659 new_entry->mode = strdup(*mode);
660 if (new_entry->mode == NULL) {
661 lirc_printf(
"%s: out of memory\n", lirc_prog);
667 new_entry->prog != NULL && strcasecmp(new_entry->prog, lirc_prog) == 0) {
670 list = new_entry->config;
671 while (list != NULL) {
672 if (check(list->string) == -1) {
679 if (new_entry->rep_delay == 0 && new_entry->rep > 0) {
680 new_entry->rep_delay = new_entry->rep - 1;
683 lirc_printf(
"%s: %s:%d: 'end' without 'begin'\n", lirc_prog, name, line);
688 if (new_entry != NULL) {
689 lirc_printf(
"%s: %s:%d: missing 'end' token\n", lirc_prog, name, line);
692 if (strcasecmp(*mode, token2) == 0) {
696 lirc_printf(
"%s: \"%s\" doesn't "
697 "match mode \"%s\"\n", lirc_prog, token2, *mode);
701 lirc_printf(
"%s: %s:%d: 'end %s' without 'begin'\n", lirc_prog, name, line, token2);
706 lirc_printf(
"%s: unknown token \"%s\" in %s:%d ignored\n", lirc_prog, token, name, line);
712 unsigned int lirc_flags(
char *
string)
718 s = strtok(
string,
" \t|");
720 if (strcasecmp(s,
"once") == 0) {
722 }
else if (strcasecmp(s,
"quit") == 0) {
724 }
else if (strcasecmp(s,
"mode") == 0) {
726 }
else if (strcasecmp(s,
"startup_mode") == 0) {
727 flags |= startup_mode;
728 }
else if (strcasecmp(s,
"toggle_reset") == 0) {
729 flags |= toggle_reset;
731 lirc_printf(
"%s: unknown flag \"%s\"\n", lirc_prog, s);
733 s = strtok(NULL,
" \t");
748 static char* get_homepath(
void)
753 filename = malloc(MAXPATHLEN);
754 if (filename == NULL) {
755 lirc_printf(
"%s: out of memory\n", lirc_prog);
758 home = getenv(
"HOME");
759 home = home == NULL ?
"/" : home;
760 strncpy(filename, home, MAXPATHLEN);
761 if (filename[strlen(filename) - 1] ==
'/') {
762 filename[strlen(filename) - 1] =
'\0';
773 static char* get_freedesktop_path()
777 if (getenv(
"XDG_CONFIG_HOME") != NULL) {
778 path = malloc(MAXPATHLEN);
779 strncpy(path, getenv(
"XDG_CONFIG_HOME"), MAXPATHLEN);
780 strncat(path,
"/", MAXPATHLEN - strlen(path));
781 strncat(path,
CFG_LIRCRC, MAXPATHLEN - strlen(path));
783 path = get_homepath();
787 strncat(path,
"/.config/lircrc", MAXPATHLEN - strlen(path));
789 if (access(path, R_OK) != 0) {
796 static char *lirc_getfilename(
const char *file,
const char *current_file)
801 filename = get_freedesktop_path();
802 if (filename == NULL) {
804 }
else if (strlen(filename) == 0) {
806 filename = get_homepath();
807 if (filename == NULL) {
812 filename = realloc(filename, strlen(filename) + 1);
813 }
else if (strncmp(file,
"~/", 2) == 0) {
814 filename = get_homepath();
815 if (filename == NULL) {
818 strcat(filename, file + 1);
819 filename = realloc(filename, strlen(filename) + 1);
820 }
else if (file[0] ==
'/' || current_file == NULL) {
822 filename = strdup(file);
823 if (filename == NULL) {
824 lirc_printf(
"%s: out of memory\n", lirc_prog);
829 int pathlen = strlen(current_file);
830 while (pathlen > 0 && current_file[pathlen - 1] !=
'/')
832 filename = (
char *)malloc(pathlen + strlen(file) + 1);
833 if (filename == NULL) {
834 lirc_printf(
"%s: out of memory\n", lirc_prog);
837 memcpy(filename, current_file, pathlen);
838 filename[pathlen] = 0;
839 strcat(filename, file);
845 static FILE *lirc_open(
const char *file,
const char *current_file,
char **full_name)
850 filename = lirc_getfilename(file, current_file);
851 if (filename == NULL) {
855 fin = fopen(filename,
"r");
856 if (fin == NULL && (file != NULL || errno != ENOENT)) {
857 lirc_printf(
"%s: could not open config file %s\n", lirc_prog, filename);
858 lirc_perror(lirc_prog);
859 }
else if (fin == NULL) {
861 fin = fopen(root_file,
"r");
862 if (fin == NULL && errno == ENOENT) {
863 int save_errno = errno;
865 fin = fopen(root_file,
"r");
868 if (fin == NULL && errno != ENOENT) {
869 lirc_printf(
"%s: could not open config file %s\n", lirc_prog,
LIRCRC_ROOT_FILE);
870 lirc_perror(lirc_prog);
871 }
else if (fin == NULL) {
872 lirc_printf(
"%s: could not open config files "
874 lirc_perror(lirc_prog);
877 filename = strdup(root_file);
878 if (filename == NULL) {
880 lirc_printf(
"%s: out of memory\n", lirc_prog);
885 if (full_name && fin != NULL) {
886 *full_name = filename;
894 static struct filestack_t *stack_push(
struct filestack_t *parent)
896 struct filestack_t *entry;
897 entry = malloc(
sizeof(
struct filestack_t));
899 lirc_printf(
"%s: out of memory\n", lirc_prog);
905 entry->parent = parent;
910 static struct filestack_t *stack_pop(
struct filestack_t *entry)
912 struct filestack_t *parent = NULL;
914 parent = entry->parent;
923 static void stack_free(
struct filestack_t *entry)
926 entry = stack_pop(entry);
939 while (scan != NULL) {
940 if (scan->flags & startup_mode) {
941 if (scan->change_mode != NULL) {
942 startupmode = scan->change_mode;
944 scan->change_mode = NULL;
947 lirc_printf(
"%s: startup_mode flags requires 'mode ='\n", lirc_prog);
954 if (startupmode == NULL) {
956 while (scan != NULL) {
957 if (scan->mode != NULL && strcasecmp(lirc_prog, scan->mode) == 0) {
958 startupmode = lirc_prog;
965 if (startupmode == NULL)
968 while (scan != NULL) {
969 if (scan->change_mode != NULL && scan->flags & once && strcasecmp(startupmode, scan->change_mode) == 0) {
974 return (startupmode);
989 free(c->change_mode);
994 while (code != NULL) {
995 if (code->remote != NULL && code->remote != LIRC_ALL)
997 if (code->button != NULL && code->button != LIRC_ALL)
999 code_temp = code->next;
1005 while (list != NULL) {
1008 list_temp = list->next;
1012 config_temp = c->next;
1020 parse_shebang(
char* line,
int depth,
const char* path,
char* buff,
size_t size)
1024 const char*
const SHEBANG_MSG =
1025 "Warning: Use of deprecated lircrc shebang."
1026 " Use lircrc_class instead.\n";
1028 token = strtok(line,
"#! ");
1031 lirc_printf(
"Warning: ignoring shebang in included file.");
1034 if (strcmp(token,
"lircrc") == 0) {
1035 strncpy(my_path, path,
sizeof(my_path) - 1);
1036 strncat(buff, basename(my_path), size - 1);
1037 lirc_printf(SHEBANG_MSG);
1039 lirc_printf(
"Warning: bad shebang (ignored)");
1044 static int lirc_readconfig_only_internal(
const char *file,
1046 int (check) (
char *s),
char **full_name)
1048 const char*
const INCLUDED_LIRCRC_CLASS =
1049 "Warning: lirc_class in included file (ignored)";
1050 char *string, *eq, *token, *token2, *token3;
1051 struct filestack_t *filestack, *stack_tmp;
1053 char lircrc_class[128] = {
'\0'};
1055 char *mode, *remote;
1058 char *save_full_name = NULL;
1060 filestack = stack_push(NULL);
1061 if (filestack == NULL) {
1064 filestack->file = lirc_open(file, NULL, &(filestack->name));
1065 if (filestack->file == NULL) {
1066 stack_free(filestack);
1069 filestack->line = 0;
1072 first = new_entry = last = NULL;
1076 if ((ret = lirc_readline(&
string, filestack->file)) == -1 ||
string == NULL) {
1077 fclose(filestack->file);
1078 if (open_files == 1 && full_name != NULL) {
1079 save_full_name = filestack->name;
1080 filestack->name = NULL;
1082 filestack = stack_pop(filestack);
1089 if (strncmp(
string,
"#!", 2) == 0) {
1090 parse_shebang(
string,
1094 sizeof(lircrc_class));
1098 eq = strchr(
string,
'=');
1100 token = strtok(
string,
" \t");
1101 if (token == NULL) {
1103 }
else if (token[0] ==
'#') {
1105 }
else if (strcasecmp(token,
"lircrc_class") == 0) {
1106 token2 = lirc_trim(strtok(NULL,
""));
1107 if (strlen(token2) == 0) {
1109 "Warning: no lircrc_class");
1110 }
else if (open_files == 1) {
1111 strncat(lircrc_class,
1113 sizeof(lircrc_class) - 1);
1115 lirc_printf(INCLUDED_LIRCRC_CLASS);
1117 }
else if (strcasecmp(token,
"include") == 0) {
1118 if (open_files >= MAX_INCLUDES) {
1119 lirc_printf(
"%s: too many files "
1120 "included at %s:%d\n", lirc_prog, filestack->name, filestack->line);
1123 token2 = strtok(NULL,
"");
1124 token2 = lirc_trim(token2);
1125 lirc_parse_include(token2, filestack->name, filestack->line);
1126 stack_tmp = stack_push(filestack);
1127 if (stack_tmp == NULL) {
1131 lirc_open(token2, filestack->name, &(stack_tmp->name));
1132 stack_tmp->line = 0;
1133 if (stack_tmp->file) {
1135 filestack = stack_tmp;
1137 stack_pop(stack_tmp);
1143 token2 = strtok(NULL,
" \t");
1144 if (token2 != NULL && (token3 = strtok(NULL,
" \t")) != NULL) {
1145 lirc_printf(
"%s: unexpected token in line %s:%d\n",
1146 lirc_prog, filestack->name, filestack->line);
1148 ret = lirc_mode(token, token2, &mode,
1149 &new_entry, &first, &last,
1150 check, filestack->name, filestack->line);
1152 if (remote != LIRC_ALL)
1160 if (new_entry != NULL) {
1161 lirc_freeconfigentries(new_entry);
1169 token = lirc_trim(
string);
1170 token2 = lirc_trim(eq + 1);
1171 if (token[0] ==
'#') {
1173 }
else if (new_entry == NULL) {
1174 lirc_printf(
"%s: bad file format, %s:%d\n",
1175 lirc_prog, filestack->name, filestack->line);
1178 token2 = strdup(token2);
1179 if (token2 == NULL) {
1180 lirc_printf(
"%s: out of memory\n", lirc_prog);
1182 }
else if (strcasecmp(token,
"prog") == 0) {
1183 if (new_entry->prog != NULL)
1184 free(new_entry->prog);
1185 new_entry->prog = token2;
1186 }
else if (strcasecmp(token,
"remote") == 0) {
1187 if (remote != LIRC_ALL)
1190 if (strcasecmp(
"*", token2) == 0) {
1196 }
else if (strcasecmp(token,
"button") == 0) {
1203 lirc_printf(
"%s: out of memory\n", lirc_prog);
1206 code->remote = remote;
1207 if (strcasecmp(
"*", token2) == 0) {
1208 code->button = LIRC_ALL;
1211 code->button = token2;
1215 if (new_entry->code == NULL) {
1216 new_entry->code = code;
1218 new_entry->next_code->next = code;
1220 new_entry->next_code = code;
1221 if (remote != LIRC_ALL) {
1222 remote = strdup(remote);
1223 if (remote == NULL) {
1224 lirc_printf(
"%s: out of memory\n", lirc_prog);
1229 }
else if (strcasecmp(token,
"delay") == 0) {
1233 new_entry->rep_delay = strtoul(token2, &end, 0);
1234 if ((new_entry->rep_delay == ULONG_MAX && errno == ERANGE)
1235 || end[0] != 0 || strlen(token2) == 0) {
1236 lirc_printf(
"%s: \"%s\" not"
1237 " a valid number for delay\n", lirc_prog, token2);
1240 }
else if (strcasecmp(token,
"ignore_first_events") == 0) {
1244 new_entry->ign_first_events = strtoul(token2, &end, 0);
1245 if ((new_entry->ign_first_events == ULONG_MAX && errno == ERANGE)
1246 || end[0] != 0 || strlen(token2) == 0) {
1247 lirc_printf(
"%s: \"%s\" not"
1248 " a valid number for ignore_first_events\n", lirc_prog, token2);
1251 }
else if (strcasecmp(token,
"repeat") == 0) {
1255 new_entry->rep = strtoul(token2, &end, 0);
1256 if ((new_entry->rep == ULONG_MAX && errno == ERANGE)
1257 || end[0] != 0 || strlen(token2) == 0) {
1258 lirc_printf(
"%s: \"%s\" not"
1259 " a valid number for repeat\n", lirc_prog, token2);
1262 }
else if (strcasecmp(token,
"config") == 0) {
1267 if (new_list == NULL) {
1269 lirc_printf(
"%s: out of memory\n", lirc_prog);
1272 lirc_parse_string(token2, filestack->name, filestack->line);
1273 new_list->string = token2;
1274 new_list->next = NULL;
1275 if (new_entry->config == NULL) {
1276 new_entry->config = new_list;
1278 new_entry->next_config->next = new_list;
1280 new_entry->next_config = new_list;
1282 }
else if (strcasecmp(token,
"mode") == 0) {
1283 if (new_entry->change_mode != NULL)
1284 free(new_entry->change_mode);
1285 new_entry->change_mode = token2;
1286 }
else if (strcasecmp(token,
"flags") == 0) {
1287 new_entry->flags = lirc_flags(token2);
1291 lirc_printf(
"%s: unknown token \"%s\" in %s:%d ignored\n",
1292 lirc_prog, token, filestack->name, filestack->line);
1300 if (remote != LIRC_ALL)
1302 if (new_entry != NULL) {
1304 ret = lirc_mode(
"end", NULL, &mode, &new_entry, &first, &last, check,
"", 0);
1305 lirc_printf(
"%s: warning: end token missing at end of file\n", lirc_prog);
1307 lirc_freeconfigentries(new_entry);
1313 lirc_printf(
"%s: warning: no end token found for mode \"%s\"\n", lirc_prog, mode);
1322 if (*config == NULL) {
1323 lirc_printf(
"%s: out of memory\n", lirc_prog);
1324 lirc_freeconfigentries(first);
1327 (*config)->first = first;
1328 (*config)->next = first;
1329 startupmode = lirc_startupmode((*config)->first);
1330 (*config)->current_mode = startupmode ? strdup(startupmode) : NULL;
1331 if (lircrc_class[0] !=
'\0') {
1332 (*config)->lircrc_class = strdup(lircrc_class);
1334 (*config)->lircrc_class = NULL;
1336 (*config)->sockfd = -1;
1337 if (full_name != NULL) {
1338 *full_name = save_full_name;
1339 save_full_name = NULL;
1343 lirc_freeconfigentries(first);
1346 stack_free(filestack);
1348 if (save_full_name) {
1349 free(save_full_name);
1355 int lirc_identify(
int sockfd)
1365 }
while (ret == EAGAIN || ret == EWOULDBLOCK);
1373 struct sockaddr_un addr;
1380 if (lirc_readconfig_only_internal(file, config, check, &filename) == -1) {
1384 if ((*config)->lircrc_class == NULL) {
1385 goto lirc_readconfig_compat;
1390 addr.sun_family = AF_UNIX;
1393 sizeof(addr.sun_path)) >
sizeof(addr.sun_path))
1395 lirc_printf(
"%s: WARNING: file name too long\n", lirc_prog);
1396 goto lirc_readconfig_compat;
1398 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1400 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
1401 lirc_perror(lirc_prog);
1402 goto lirc_readconfig_compat;
1404 if (connect(sockfd, (
struct sockaddr *)&addr,
sizeof(addr)) != -1) {
1405 (*config)->sockfd = sockfd;
1409 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS) {
1421 snprintf(command,
sizeof(command),
1422 "lircrcd %s", (*config)->lircrc_class);
1423 ret = system(command);
1424 if (ret == -1 || WEXITSTATUS(ret) != EXIT_SUCCESS) {
1425 goto lirc_readconfig_compat;
1429 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1431 lirc_printf(
"%s: WARNING: could not open socket\n", lirc_prog);
1432 lirc_perror(lirc_prog);
1433 goto lirc_readconfig_compat;
1435 if (connect(sockfd, (
struct sockaddr *)&addr,
sizeof(addr)) != -1) {
1436 if (lirc_identify(sockfd) == LIRC_RET_SUCCESS) {
1437 (*config)->sockfd = sockfd;
1445 lirc_readconfig_compat:
1456 return lirc_readconfig_only_internal(file, config, check, NULL);
1462 if (config != NULL) {
1463 if (config->sockfd != -1) {
1464 (void)close(config->sockfd);
1465 config->sockfd = -1;
1469 lirc_freeconfigentries(config->first);
1470 free(config->current_mode);
1476 static void lirc_clearmode(
struct lirc_config *config)
1480 if (config->current_mode == NULL) {
1483 scan = config->first;
1484 while (scan != NULL) {
1485 if (scan->change_mode != NULL) {
1486 if (strcasecmp(scan->change_mode, config->current_mode) == 0) {
1487 scan->flags &= ~ecno;
1492 free(config->current_mode);
1493 config->current_mode = NULL;
1502 if (scan->flags & mode) {
1503 lirc_clearmode(config);
1505 if (scan->change_mode != NULL) {
1506 free(config->current_mode);
1507 config->current_mode = strdup(scan->change_mode);
1508 if (scan->flags & once) {
1509 if (scan->flags & ecno) {
1512 scan->flags |= ecno;
1516 if (scan->next_config != NULL &&
1517 scan->prog != NULL && (lirc_prog == NULL || strcasecmp(scan->prog, lirc_prog) == 0) && do_once == 1) {
1518 s = scan->next_config->string;
1519 scan->next_config = scan->next_config->next;
1520 if (scan->next_config == NULL)
1521 scan->next_config = scan->config;
1537 int delay_start, rep_delay;
1538 if (scan->ign_first_events) {
1539 if (scan->rep_delay && rep == 0)
1540 lirc_printf(
"%s: ignoring \"delay\" because \"ignore_first_events\" is also set\n",
1542 rep_delay = scan->ign_first_events;
1545 rep_delay = scan->rep_delay;
1549 if (rep < delay_start)
1552 if (scan->rep == 0 && rep_delay > 0 && rep == rep_delay + delay_start)
1555 if (scan->rep > 0 && rep >= rep_delay + delay_start) {
1556 rep -= rep_delay + delay_start;
1557 return ((rep % scan->rep) == 0);
1562 static int lirc_iscode(
struct lirc_config_entry *scan,
char *remote,
char *button,
int rep)
1567 if (scan->code == NULL) {
1568 return rep_filter(scan, rep);
1572 if (scan->next_code->remote == LIRC_ALL || strcasecmp(scan->next_code->remote, remote) == 0) {
1573 if (scan->next_code->button == LIRC_ALL || strcasecmp(scan->next_code->button, button) == 0) {
1576 if (scan->code->next == NULL || rep == 0) {
1577 scan->next_code = scan->next_code->next;
1578 if (scan->code->next != NULL) {
1583 if (scan->next_code == NULL) {
1584 scan->next_code = scan->code;
1585 if (scan->code->next != NULL || rep_filter(scan, rep))
1596 if (scan->flags & toggle_reset) {
1597 scan->next_config = scan->config;
1601 if (codes == scan->next_code)
1603 codes = codes->next;
1605 while (codes != scan->next_code->next) {
1611 while (next != scan->next_code) {
1612 if (prev->remote == LIRC_ALL || strcasecmp(prev->remote, next->remote) == 0) {
1613 if (prev->button == LIRC_ALL || strcasecmp(prev->button, next->button) == 0) {
1626 if (prev->remote == LIRC_ALL || strcasecmp(prev->remote, remote) == 0) {
1627 if (prev->button == LIRC_ALL || strcasecmp(prev->button, button) == 0) {
1629 scan->next_code = prev->next;
1635 codes = codes->next;
1637 scan->next_code = scan->code;
1644 static int warning = 1;
1648 fprintf(stderr,
"%s: warning: lirc_ir2char() is obsolete\n", lirc_prog);
1657 static int lirc_code2char_internal(
struct lirc_config *config,
char *code,
char **
string,
char **prog)
1661 char *remote, *button;
1668 if (sscanf(code,
"%*x %x %*s %*s\n", &rep) == 1) {
1669 backup = strdup(code);
1673 strtok(backup,
" ");
1675 button = strtok(NULL,
" ");
1676 remote = strtok(NULL,
"\n");
1678 if (button == NULL || remote == NULL) {
1683 scan = config->next;
1685 while (scan != NULL) {
1686 exec_level = lirc_iscode(scan, remote, button, rep);
1687 if (exec_level > 0 &&
1688 (scan->mode == NULL ||
1689 (scan->mode != NULL &&
1690 config->current_mode != NULL &&
1691 strcasecmp(scan->mode, config->current_mode) == 0)) && quit_happened == 0) {
1692 if (exec_level > 1) {
1693 s = lirc_execute(config, scan);
1694 if (s != NULL && prog != NULL) {
1700 if (scan->flags & quit) {
1702 config->next = NULL;
1705 }
else if (s != NULL) {
1706 config->next = scan->next;
1718 config->next = config->first;
1732 if (config->sockfd != -1) {
1735 }
while (ret == EAGAIN || ret == EWOULDBLOCK);
1738 *
string = static_buff;
1740 return ret == 0 ? 0 : -1;
1742 return lirc_code2char_internal(config, code,
string, NULL);
1746 int lirc_code2charprog(
struct lirc_config *config,
char *code,
char **
string,
char **prog)
1754 ret = lirc_code2char_internal(config, code,
string, prog);
1763 static int warning = 1;
1768 fprintf(stderr,
"%s: warning: lirc_nextir() is obsolete\n", lirc_prog);
1781 static int end_len = 0;
1786 if (lirc_buffer == NULL) {
1787 lirc_buffer = (
char *)malloc(packet_size + 1);
1788 if (lirc_buffer == NULL) {
1789 lirc_printf(
"%s: out of memory\n", lirc_prog);
1794 while ((end = strchr(lirc_buffer,
'\n')) == NULL) {
1795 if (end_len >= packet_size) {
1799 new_buffer = (
char *)realloc(lirc_buffer, packet_size + 1);
1800 if (new_buffer == NULL) {
1803 lirc_buffer = new_buffer;
1805 len = read(lirc_lircd, lirc_buffer + end_len, packet_size - end_len);
1807 if (len == -1 && errno == EAGAIN)
1813 lirc_buffer[end_len] = 0;
1815 if ((end = strchr(lirc_buffer,
'\n')) == NULL) {
1822 end_len = strlen(end);
1825 *code = strdup(lirc_buffer);
1827 memmove(lirc_buffer, end, end_len + 1);
1836 id =
id != NULL ?
id :
"default";
1837 snprintf(buf, size, VARRUNDIR
"/%d-%s-lircrcd.socket", getuid(),
id);
1849 if (config->sockfd != -1) {
1853 }
while (ret == EAGAIN || ret == EWOULDBLOCK);
1860 return config->current_mode;
1870 if (config->sockfd != -1) {
1881 }
while (r == EAGAIN || r == EWOULDBLOCK);
1888 free(config->current_mode);
1889 config->current_mode = mode ? strdup(mode) : NULL;
1890 return config->current_mode;
1906 }
while (r == EAGAIN);
1921 scancode, repeat, keysym, remote);
1927 }
while (r == EAGAIN);
1934 do_connect(
int domain,
struct sockaddr* addr,
size_t size,
int quiet)
1938 fd = socket(domain, SOCK_STREAM, 0);
1941 fprintf(stderr,
"do_connect: could not open socket\n");
1946 if (connect(fd, addr, size) == -1) {
1949 "do_connect: could not connect to socket\n");
1960 const char* socket_path;
1961 struct sockaddr_un addr_un;
1963 socket_path = path ? path : getenv(
"LIRC_SOCKET_PATH");
1964 socket_path = socket_path ? socket_path :
LIRCD;
1965 if (strlen(socket_path) + 1 >
sizeof(addr_un.sun_path)) {
1968 fprintf(stderr,
"%s: socket name is too long\n", prog);
1970 return -ENAMETOOLONG;
1972 addr_un.sun_family = AF_UNIX;
1973 strcpy(addr_un.sun_path, socket_path);
1974 return do_connect(AF_UNIX,
1975 (
struct sockaddr *) &addr_un,
1983 struct sockaddr_in addr_in;
1984 struct hostent* hostInfo;
1986 hostInfo = gethostbyname(address);
1987 if (hostInfo == NULL) {
1989 fprintf(stderr,
"get_remote_socket: host %s unknown\n",
1992 return -EADDRNOTAVAIL;
1994 addr_in.sin_family = hostInfo->h_addrtype;
1995 memcpy((
char *) &addr_in.sin_addr.s_addr,
1996 hostInfo->h_addr_list[0],
1997 hostInfo->h_length);
1999 return do_connect(hostInfo->h_addrtype,
2000 (
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)