LIRC libraries
LinuxInfraredRemoteControl
lirc_client.c
Go to the documentation of this file.
1 /****************************************************************************
2 ** lirc_client.c ***********************************************************
3 ****************************************************************************
4 *
5 * lirc_client - common routines for lircd clients
6 *
7 * Copyright (C) 1998 Trent Piepho <xyzzy@u.washington.edu>
8 * Copyright (C) 1998 Christoph Bartelmus <lirc@bartelmus.de>
9 *
10 * System wide LIRCRC support by Michal Svec <rebel@atrey.karlin.mff.cuni.cz>
11 */
12 
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22 
23 #include <errno.h>
24 #include <libgen.h>
25 #include <limits.h>
26 #include <netdb.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <string.h>
31 #include <strings.h>
32 #include <sys/param.h>
33 #include <sys/socket.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <sys/time.h>
37 #include <sys/wait.h>
38 #include <sys/un.h>
39 #include <unistd.h>
40 
41 #include "lirc_client.h"
42 
44 static const struct timeval CMD_TIMEOUT = { .tv_sec = 1, .tv_usec = 0 };
45 
46 
47 // Until we have working client logging...
48 #define logprintf(level, fmt, args ...) syslog(level, fmt, ## args)
49 #define LIRC_WARNING LOG_WARNING
50 #define LIRC_DEBUG LOG_DEBUG
51 #define LIRC_NOTICE LOG_NOTICE
52 #define LIRC_ERROR LOG_ERR
53 
54 /* internal defines */
55 #define MAX_INCLUDES 10
56 #define LIRC_READ 255
57 #define LIRC_PACKET_SIZE 255
58 /* three seconds */
59 #define LIRC_TIMEOUT 3
60 
61 /* internal data structures */
62 struct filestack_t {
63  FILE* file;
64  char* name;
65  int line;
66  struct filestack_t* parent;
67 };
68 
69 
72  P_BEGIN,
73  P_MESSAGE,
74  P_STATUS,
75  P_DATA,
76  P_N,
77  P_DATA_N,
78  P_END
79 };
80 
81 
82 /*
83  * lircrc_config relies on this function, hence don't make it static
84  * but it's not part of the official interface, so there's no guarantee
85  * that it will stay available in the future
86  */
87 unsigned int lirc_flags(char* string);
88 
89 static int lirc_lircd;
90 static int lirc_verbose = 0;
91 static char* lirc_prog = NULL;
92 static char* lirc_buffer = NULL;
93 
94 char* prog;
95 
97 static inline void
98 chk_write(int fd, const void* buf, size_t count, const char* msg)
99 {
100  if (write(fd, buf, count) == -1)
101  perror(msg);
102 }
103 
104 
105 int lirc_command_init(lirc_cmd_ctx* ctx, const char* fmt, ...)
106 {
107  va_list ap;
108  int n;
109 
110  memset(ctx, 0, sizeof(lirc_cmd_ctx));
111  va_start(ap, fmt);
112  n = vsnprintf(ctx->packet, PACKET_SIZE, fmt, ap);
113  va_end(ap);
114  if (n >= PACKET_SIZE) {
115  logprintf(LIRC_NOTICE, "Message too big: %s", ctx->packet);
116  return EMSGSIZE;
117  }
118  return 0;
119 }
120 
121 
123 {
124  ctx->reply_to_stdout = 1;
125 }
126 
127 
129 static int fill_string(int fd, lirc_cmd_ctx* cmd)
130 {
131  ssize_t n;
132 
133  setsockopt(fd,
134  SOL_SOCKET,
135  SO_RCVTIMEO,
136  (const void*)&CMD_TIMEOUT,
137  sizeof(CMD_TIMEOUT));
138  n = read(fd, cmd->buffer + cmd->head, PACKET_SIZE - cmd->head);
139  if (n == -1) {
140  if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
141  logprintf(LIRC_NOTICE, "fill_string: timeout\n");
142  return EAGAIN;
143  }
144  cmd->head = 0;
145  return errno;
146  }
147  cmd->head += n;
148  return 0;
149 }
150 
151 
153 static int read_string(lirc_cmd_ctx* cmd, int fd, const char** string)
154 {
155  int r;
156  int skip;
157 
158  if (cmd->next != NULL && cmd->next != cmd->buffer) {
159  skip = cmd->next - cmd->buffer;
160  memmove(cmd->buffer, cmd->next, cmd->head - skip);
161  cmd->head -= skip;
162  cmd->next = cmd->buffer;
163  }
164  if (cmd->next == NULL || strchr(cmd->next, '\n') == NULL) {
165  r = fill_string(fd, cmd);
166  if (r > 0)
167  return r;
168  cmd->next = cmd->buffer;
169  }
170  *string = cmd->next;
171  cmd->next = strchr(cmd->next, '\n');
172  if (cmd->next != NULL) {
173  *(cmd->next) = '\0';
174  cmd->next++;
175  }
176  return 0;
177 }
178 
179 
181 {
182  int done, todo;
183  const char* string = NULL;
184  const char* data;
185  char* endptr;
186  enum packet_state state;
187  int status, n, r;
188  __u32 data_n = 0;
189 
190  todo = strlen(ctx->packet);
191  data = ctx->packet;
192  logprintf(LIRC_DEBUG, "lirc_command_run: Sending: %s", data);
193  while (todo > 0) {
194  done = write(fd, (void*)data, todo);
195  if (done < 0) {
196  logprintf(LIRC_WARNING,
197  "%s: could not send packet\n", prog);
198  perror(prog);
199  return done;
200  }
201  data += done;
202  todo -= done;
203  }
204 
205  /* get response */
206  status = 0;
207  n = 0;
208  state = P_BEGIN;
209  while (1) {
210  do
211  r = read_string(ctx, fd, &string);
212  while (r == EAGAIN);
213  if (!string || strlen(string) == 0)
214  goto bad_packet;
215  logprintf(LIRC_DEBUG,
216  "lirc_command_run, state: %d, input: \"%s\"\n",
217  state, string ? string : "(Null)");
218  switch (state) {
219  case P_BEGIN:
220  if (strcasecmp(string, "BEGIN") != 0)
221  break;
222  state = P_MESSAGE;
223  continue;
224  case P_MESSAGE:
225  if (strncasecmp(string, ctx->packet,
226  strlen(string)) != 0
227  || strlen(string) + 1 != strlen(ctx->packet)) {
228  state = P_BEGIN;
229  break;
230  }
231  state = P_STATUS;
232  continue;
233  case P_STATUS:
234  if (strcasecmp(string, "SUCCESS") == 0) {
235  status = 0;
236  } else if (strcasecmp(string, "END") == 0) {
237  logprintf(LIRC_NOTICE,
238  "lirc_command_run: status:END");
239  return 0;
240  } else if (strcasecmp(string, "ERROR") == 0) {
241  logprintf(LIRC_WARNING,
242  "%s: command failed: %s",
243  prog, ctx->packet);
244  status = EIO;
245  } else {
246  goto bad_packet;
247  }
248  state = P_DATA;
249  break;
250  case P_DATA:
251  if (strcasecmp(string, "END") == 0) {
252  logprintf(LIRC_NOTICE,
253  "lirc_command_run: data:END, status:%d",
254  status);
255  return status;
256  } else if (strcasecmp(string, "DATA") == 0) {
257  state = P_N;
258  break;
259  }
260  logprintf(LIRC_DEBUG,
261  "data: bad packet: %s\n",
262  string);
263  goto bad_packet;
264  case P_N:
265  errno = 0;
266  data_n = (__u32)strtoul(string, &endptr, 0);
267  if (!*string || *endptr)
268  goto bad_packet;
269  if (data_n == 0)
270  state = P_END;
271  else
272  state = P_DATA_N;
273  break;
274  case P_DATA_N:
275  if (n == 0) {
276  if (ctx->reply_to_stdout)
277  puts("");
278  else
279  strcpy(ctx->reply, "");
280  }
281  if (ctx->reply_to_stdout) {
282  chk_write(0, string, strlen(string),
283  "reply (1)");
284  chk_write(0, "\n", 1, "reply (2)");
285  } else {
286  strncpy(ctx->reply,
287  string,
288  PACKET_SIZE - strlen(ctx->reply));
289  }
290  n++;
291  if (n == data_n)
292  state = P_END;
293  break;
294  case P_END:
295  if (strcasecmp(string, "END") == 0) {
296  logprintf(LIRC_NOTICE,
297  "lirc_command_run: status:END, status:%d",
298  status);
299  return status;
300  }
301  goto bad_packet;
302  }
303  }
304 bad_packet:
305  logprintf(LIRC_WARNING, "%s: bad return packet\n", prog);
306  logprintf(LIRC_DEBUG, "State %d: bad packet: %s\n", status, string);
307  return EPROTO;
308 }
309 
310 
311 static void lirc_printf(const char* format_str, ...)
312 {
313  va_list ap;
314 
315  if (!lirc_verbose)
316  return;
317 
318  va_start(ap, format_str);
319  vfprintf(stderr, format_str, ap);
320  va_end(ap);
321 }
322 
323 
324 static void lirc_perror(const char* s)
325 {
326  if (!lirc_verbose)
327  return;
328 
329  perror(s);
330 }
331 
332 
333 int lirc_init(const char* prog, int verbose)
334 {
335  if (prog == NULL || lirc_prog != NULL)
336  return -1;
337  lirc_lircd = lirc_get_local_socket(NULL, !verbose);
338  if (lirc_lircd >= 0) {
339  lirc_verbose = verbose;
340  lirc_prog = strdup(prog);
341  if (lirc_prog == NULL) {
342  lirc_printf("%s: out of memory\n", prog);
343  return -1;
344  }
345  return lirc_lircd;
346  }
347  lirc_printf("%s: could not open socket: %s\n",
348  lirc_prog,
349  strerror(-lirc_lircd));
350  return -1;
351 }
352 
353 
354 int lirc_deinit(void)
355 {
356  if (lirc_prog != NULL) {
357  free(lirc_prog);
358  lirc_prog = NULL;
359  }
360  if (lirc_buffer != NULL) {
361  free(lirc_buffer);
362  lirc_buffer = NULL;
363  }
364  return close(lirc_lircd);
365 }
366 
367 
368 static int lirc_readline(char** line, FILE* f)
369 {
370  char* newline;
371  char* ret;
372  char* enlargeline;
373  int len;
374 
375  newline = (char*)malloc(LIRC_READ + 1);
376  if (newline == NULL) {
377  lirc_printf("%s: out of memory\n", lirc_prog);
378  return -1;
379  }
380  len = 0;
381  while (1) {
382  ret = fgets(newline + len, LIRC_READ + 1, f);
383  if (ret == NULL) {
384  if (feof(f) && len > 0) {
385  *line = newline;
386  } else {
387  free(newline);
388  *line = NULL;
389  }
390  return 0;
391  }
392  len = strlen(newline);
393  if (newline[len - 1] == '\n') {
394  newline[len - 1] = 0;
395  *line = newline;
396  return 0;
397  }
398 
399  enlargeline = (char*)realloc(newline, len + 1 + LIRC_READ);
400  if (enlargeline == NULL) {
401  free(newline);
402  lirc_printf("%s: out of memory\n", lirc_prog);
403  return -1;
404  }
405  newline = enlargeline;
406  }
407 }
408 
409 
410 static char* lirc_trim(char* s)
411 {
412  int len;
413 
414  while (s[0] == ' ' || s[0] == '\t')
415  s++;
416  len = strlen(s);
417  while (len > 0) {
418  len--;
419  if (s[len] == ' ' || s[len] == '\t')
420  s[len] = 0;
421  else
422  break;
423  }
424  return s;
425 }
426 
427 
428 /* parse standard C escape sequences + \@,\A-\Z is ^@,^A-^Z */
429 static char lirc_parse_escape(char** s, const char* name, int line)
430 {
431  char c;
432  unsigned int i, overflow, count;
433  int digits_found, digit;
434 
435  c = **s;
436  (*s)++;
437  switch (c) {
438  case 'a':
439  return '\a';
440  case 'b':
441  return '\b';
442  case 'e':
443 #if 0
444  case 'E': /* this should become ^E */
445 #endif
446  return 033;
447  case 'f':
448  return '\f';
449  case 'n':
450  return '\n';
451  case 'r':
452  return '\r';
453  case 't':
454  return '\t';
455  case 'v':
456  return '\v';
457  case '\n':
458  return 0;
459  case 0:
460  (*s)--;
461  return 0;
462  case '0':
463  case '1':
464  case '2':
465  case '3':
466  case '4':
467  case '5':
468  case '6':
469  case '7':
470  i = c - '0';
471  count = 0;
472 
473  while (++count < 3) {
474  c = *(*s)++;
475  if (c >= '0' && c <= '7') {
476  i = (i << 3) + c - '0';
477  } else {
478  (*s)--;
479  break;
480  }
481  }
482  if (i > (1 << CHAR_BIT) - 1) {
483  i &= (1 << CHAR_BIT) - 1;
484  lirc_printf(
485  "%s: octal escape sequence out of range in %s:%d\n",
486  lirc_prog, name, line);
487  }
488  return (char)i;
489  case 'x':
490  {
491  i = 0;
492  overflow = 0;
493  digits_found = 0;
494  for (;; ) {
495  c = *(*s)++;
496  if (c >= '0' && c <= '9') {
497  digit = c - '0';
498  } else if (c >= 'a' && c <= 'f') {
499  digit = c - 'a' + 10;
500  } else if (c >= 'A' && c <= 'F') {
501  digit = c - 'A' + 10;
502  } else {
503  (*s)--;
504  break;
505  }
506  overflow |= i ^ (i << 4 >> 4);
507  i = (i << 4) + digit;
508  digits_found = 1;
509  }
510  if (!digits_found)
511  lirc_printf("%s: \\x used with no "
512  "following hex digits in %s:%d\n",
513  lirc_prog, name, line);
514  if (overflow || i > (1 << CHAR_BIT) - 1) {
515  i &= (1 << CHAR_BIT) - 1;
516  lirc_printf("%s: hex escape sequence out "
517  "of range in %s:%d\n", lirc_prog, name,
518  line);
519  }
520  return (char)i;
521  }
522  default:
523  if (c >= '@' && c <= 'Z')
524  return c - '@';
525  return c;
526  }
527 }
528 
529 
530 static void lirc_parse_string(char* s, const char* name, int line)
531 {
532  char* t;
533 
534  t = s;
535  while (*s != 0) {
536  if (*s == '\\') {
537  s++;
538  *t = lirc_parse_escape(&s, name, line);
539  t++;
540  } else {
541  *t = *s;
542  s++;
543  t++;
544  }
545  }
546  *t = 0;
547 }
548 
549 
550 static void lirc_parse_include(char* s, const char* name, int line)
551 {
552  char last;
553  size_t len;
554 
555  len = strlen(s);
556  if (len < 2)
557  return;
558  last = s[len - 1];
559  if (*s != '"' && *s != '<')
560  return;
561  if (*s == '"' && last != '"')
562  return;
563  else if (*s == '<' && last != '>')
564  return;
565  s[len - 1] = 0;
566  memmove(s, s + 1, len - 2 + 1); /* terminating 0 is copied */
567 }
568 
569 
570 int lirc_mode(char* token, char* token2, char** mode,
571  struct lirc_config_entry** new_config,
572  struct lirc_config_entry** first_config,
573  struct lirc_config_entry** last_config,
574  int (check) (char* s),
575  const char* name,
576  int line)
577 {
578  struct lirc_config_entry* new_entry;
579 
580  new_entry = *new_config;
581  if (strcasecmp(token, "begin") == 0) {
582  if (token2 == NULL) {
583  if (new_entry == NULL) {
584  new_entry = (struct lirc_config_entry*)
585  malloc(sizeof(struct lirc_config_entry));
586  if (new_entry == NULL) {
587  lirc_printf("%s: out of memory\n",
588  lirc_prog);
589  return -1;
590  }
591  new_entry->prog = NULL;
592  new_entry->code = NULL;
593  new_entry->rep_delay = 0;
594  new_entry->ign_first_events = 0;
595  new_entry->rep = 0;
596  new_entry->config = NULL;
597  new_entry->change_mode = NULL;
598  new_entry->flags = none;
599  new_entry->mode = NULL;
600  new_entry->next_config = NULL;
601  new_entry->next_code = NULL;
602  new_entry->next = NULL;
603  *new_config = new_entry;
604  } else {
605  lirc_printf("%s: bad file format, %s:%d\n",
606  lirc_prog, name, line);
607  return -1;
608  }
609  } else {
610  if (new_entry == NULL && *mode == NULL) {
611  *mode = strdup(token2);
612  if (*mode == NULL)
613  return -1;
614  } else {
615  lirc_printf("%s: bad file format, %s:%d\n",
616  lirc_prog, name, line);
617  return -1;
618  }
619  }
620  } else if (strcasecmp(token, "end") == 0) {
621  if (token2 == NULL) {
622  if (new_entry != NULL) {
623 #if 0
624  if (new_entry->prog == NULL) {
625  lirc_printf(
626  "%s: prog missing in config before line %d\n", lirc_prog,
627  line);
628  lirc_freeconfigentries(new_entry);
629  *new_config = NULL;
630  return -1;
631  }
632  if (strcasecmp(new_entry->prog,
633  lirc_prog) != 0) {
634  lirc_freeconfigentries(new_entry);
635  *new_config = NULL;
636  return 0;
637  }
638 #endif
639  new_entry->next_code = new_entry->code;
640  new_entry->next_config = new_entry->config;
641  if (*last_config == NULL) {
642  *first_config = new_entry;
643  *last_config = new_entry;
644  } else {
645  (*last_config)->next = new_entry;
646  *last_config = new_entry;
647  }
648  *new_config = NULL;
649 
650  if (*mode != NULL) {
651  new_entry->mode = strdup(*mode);
652  if (new_entry->mode == NULL) {
653  lirc_printf(
654  "%s: out of memory\n",
655  lirc_prog);
656  return -1;
657  }
658  }
659 
660  if (check != NULL &&
661  new_entry->prog != NULL &&
662  strcasecmp(new_entry->prog,
663  lirc_prog) == 0) {
664  struct lirc_list* list;
665 
666  list = new_entry->config;
667  while (list != NULL) {
668  if (check(list->string) == -1)
669  return -1;
670  list = list->next;
671  }
672  }
673 
674  if (new_entry->rep_delay == 0 &&
675  new_entry->rep > 0)
676  new_entry->rep_delay = new_entry->rep -
677  1;
678  } else {
679  lirc_printf(
680  "%s: %s:%d: 'end' without 'begin'\n",
681  lirc_prog, name, line);
682  return -1;
683  }
684  } else {
685  if (*mode != NULL) {
686  if (new_entry != NULL) {
687  lirc_printf(
688  "%s: %s:%d: missing 'end' token\n",
689  lirc_prog, name, line);
690  return -1;
691  }
692  if (strcasecmp(*mode, token2) == 0) {
693  free(*mode);
694  *mode = NULL;
695  } else {
696  lirc_printf("%s: \"%s\" doesn't "
697  "match mode \"%s\"\n",
698  lirc_prog, token2, *mode);
699  return -1;
700  }
701  } else {
702  lirc_printf(
703  "%s: %s:%d: 'end %s' without 'begin'\n",
704  lirc_prog, name, line, token2);
705  return -1;
706  }
707  }
708  } else {
709  lirc_printf("%s: unknown token \"%s\" in %s:%d ignored\n",
710  lirc_prog, token, name, line);
711  }
712  return 0;
713 }
714 
715 
716 unsigned int lirc_flags(char* string)
717 {
718  char* s;
719  unsigned int flags;
720 
721  flags = none;
722  s = strtok(string, " \t|");
723  while (s) {
724  if (strcasecmp(s, "once") == 0)
725  flags |= once;
726  else if (strcasecmp(s, "quit") == 0)
727  flags |= quit;
728  else if (strcasecmp(s, "mode") == 0)
729  flags |= mode;
730  else if (strcasecmp(s, "startup_mode") == 0)
731  flags |= startup_mode;
732  else if (strcasecmp(s, "toggle_reset") == 0)
733  flags |= toggle_reset;
734  else
735  lirc_printf("%s: unknown flag \"%s\"\n", lirc_prog, s);
736  s = strtok(NULL, " \t");
737  }
738  return flags;
739 }
740 
741 
742 
743 
744 
745 
751 static char* get_homepath(void)
752 {
753  char* home;
754  char* filename;
755 
756  filename = malloc(MAXPATHLEN);
757  if (filename == NULL) {
758  lirc_printf("%s: out of memory\n", lirc_prog);
759  return NULL;
760  }
761  home = getenv("HOME");
762  home = home == NULL ? "/" : home;
763  strncpy(filename, home, MAXPATHLEN);
764  if (filename[strlen(filename) - 1] == '/')
765  filename[strlen(filename) - 1] = '\0';
766  return filename;
767 }
768 
769 
775 static char* get_freedesktop_path(void)
776 {
777  char* path;
778 
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));
784  } else {
785  path = get_homepath();
786  if (path == NULL)
787  return NULL;
788  strncat(path, "/.config/lircrc", MAXPATHLEN - strlen(path) - 1);
789  }
790  if (access(path, R_OK) != 0)
791  path[0] = '\0';
792  return path;
793 }
794 
795 
796 static char* lirc_getfilename(const char* file, const char* current_file)
797 {
798  char* filename;
799 
800  if (file == NULL) {
801  filename = get_freedesktop_path();
802  if (filename == NULL) {
803  return NULL;
804  } else if (strlen(filename) == 0) {
805  free(filename);
806  filename = get_homepath();
807  if (filename == NULL)
808  return NULL;
809  strcat(filename, "/" LIRCRC_USER_FILE);
810  }
811  filename = realloc(filename, strlen(filename) + 1);
812  } else if (strncmp(file, "~/", 2) == 0) {
813  filename = get_homepath();
814  if (filename == NULL)
815  return NULL;
816  strcat(filename, file + 1);
817  filename = realloc(filename, strlen(filename) + 1);
818  } else if (file[0] == '/' || current_file == NULL) {
819  /* absolute path or root */
820  filename = strdup(file);
821  if (filename == NULL) {
822  lirc_printf("%s: out of memory\n", lirc_prog);
823  return NULL;
824  }
825  } else {
826  /* get path from parent filename */
827  int pathlen = strlen(current_file);
828 
829  while (pathlen > 0 && current_file[pathlen - 1] != '/')
830  pathlen--;
831  filename = (char*)malloc(pathlen + strlen(file) + 1);
832  if (filename == NULL) {
833  lirc_printf("%s: out of memory\n", lirc_prog);
834  return NULL;
835  }
836  memcpy(filename, current_file, pathlen);
837  filename[pathlen] = 0;
838  strcat(filename, file);
839  }
840  return filename;
841 }
842 
843 
844 static FILE* lirc_open(const char* file,
845  const char* current_file,
846  char** full_name)
847 {
848  FILE* fin;
849  char* filename;
850 
851  filename = lirc_getfilename(file, current_file);
852  if (filename == NULL)
853  return NULL;
854 
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,
858  filename);
859  lirc_perror(lirc_prog);
860  } else if (fin == NULL) {
861  const char* root_file = LIRCRC_ROOT_FILE;
862 
863  fin = fopen(root_file, "r");
864  if (fin == NULL && errno == ENOENT) {
865  int save_errno = errno;
866 
867  root_file = LIRCRC_OLD_ROOT_FILE;
868  fin = fopen(root_file, "r");
869  errno = save_errno;
870  }
871  if (fin == NULL && errno != ENOENT) {
872  lirc_printf("%s: could not open config file %s\n",
873  lirc_prog, LIRCRC_ROOT_FILE);
874  lirc_perror(lirc_prog);
875  } else if (fin == NULL) {
876  lirc_printf("%s: could not open config files "
877  "%s and %s\n", lirc_prog, filename,
879  lirc_perror(lirc_prog);
880  } else {
881  free(filename);
882  filename = strdup(root_file);
883  if (filename == NULL) {
884  fclose(fin);
885  lirc_printf("%s: out of memory\n", lirc_prog);
886  return NULL;
887  }
888  }
889  }
890  if (full_name && fin != NULL)
891  *full_name = filename;
892  else
893  free(filename);
894  return fin;
895 }
896 
897 
898 static struct filestack_t* stack_push(struct filestack_t* parent)
899 {
900  struct filestack_t* entry;
901 
902  entry = malloc(sizeof(struct filestack_t));
903  if (entry == NULL) {
904  lirc_printf("%s: out of memory\n", lirc_prog);
905  return NULL;
906  }
907  entry->file = NULL;
908  entry->name = NULL;
909  entry->line = 0;
910  entry->parent = parent;
911  return entry;
912 }
913 
914 
915 static struct filestack_t* stack_pop(struct filestack_t* entry)
916 {
917  struct filestack_t* parent = NULL;
918 
919  if (entry) {
920  parent = entry->parent;
921  if (entry->name)
922  free(entry->name);
923  free(entry);
924  }
925  return parent;
926 }
927 
928 
929 static void stack_free(struct filestack_t* entry)
930 {
931  while (entry)
932  entry = stack_pop(entry);
933 }
934 
935 
936 static char* lirc_startupmode(struct lirc_config_entry* first)
937 {
938  struct lirc_config_entry* scan;
939  char* startupmode;
940 
941  startupmode = NULL;
942  scan = first;
943  /* Set a startup mode based on flags=startup_mode */
944  while (scan != NULL) {
945  if (scan->flags & startup_mode) {
946  if (scan->change_mode != NULL) {
947  startupmode = scan->change_mode;
948  /* Remove the startup mode or it confuses lirc mode system */
949  scan->change_mode = NULL;
950  break;
951  }
952  lirc_printf("%s: startup_mode flags requires 'mode ='\n", lirc_prog);
953  }
954  scan = scan->next;
955  }
956 
957  /* Set a default mode if we find a mode = client app name */
958  if (startupmode == NULL) {
959  scan = first;
960  while (scan != NULL) {
961  if (scan->mode != NULL
962  && strcasecmp(lirc_prog, scan->mode) == 0) {
963  startupmode = lirc_prog;
964  break;
965  }
966  scan = scan->next;
967  }
968  }
969 
970  if (startupmode == NULL)
971  return NULL;
972  scan = first;
973  while (scan != NULL) {
974  if (scan->change_mode != NULL
975  && scan->flags & once
976  && strcasecmp(startupmode, scan->change_mode) == 0)
977  scan->flags |= ecno;
978  scan = scan->next;
979  }
980  return startupmode;
981 }
982 
983 
984 static void lirc_freeconfigentries(struct lirc_config_entry* first)
985 {
986  struct lirc_config_entry* c;
987  struct lirc_config_entry* config_temp;
988  struct lirc_list* list;
989  struct lirc_list* list_temp;
990  struct lirc_code* code;
991  struct lirc_code* code_temp;
992 
993  c = first;
994  while (c != NULL) {
995  if (c->prog)
996  free(c->prog);
997  if (c->change_mode)
998  free(c->change_mode);
999  if (c->mode)
1000  free(c->mode);
1001 
1002  code = c->code;
1003  while (code != NULL) {
1004  if (code->remote != NULL && code->remote != LIRC_ALL)
1005  free(code->remote);
1006  if (code->button != NULL && code->button != LIRC_ALL)
1007  free(code->button);
1008  code_temp = code->next;
1009  free(code);
1010  code = code_temp;
1011  }
1012 
1013  list = c->config;
1014  while (list != NULL) {
1015  if (list->string)
1016  free(list->string);
1017  list_temp = list->next;
1018  free(list);
1019  list = list_temp;
1020  }
1021  config_temp = c->next;
1022  free(c);
1023  c = config_temp;
1024  }
1025 }
1026 
1027 
1028 static void
1029 parse_shebang(char* line, int depth, const char* path, char* buff, size_t size)
1030 {
1031  char* token;
1032  char my_path[128];
1033  const char* const SHEBANG_MSG =
1034  "Warning: Use of deprecated lircrc shebang."
1035  " Use lircrc_class instead.\n";
1036 
1037  token = strtok(line, "#! ");
1038  buff[0] = '\0';
1039  if (depth > 1) {
1040  lirc_printf("Warning: ignoring shebang in included file.");
1041  return;
1042  }
1043  if (strcmp(token, "lircrc") == 0) {
1044  strncpy(my_path, path, sizeof(my_path) - 1);
1045  strncat(buff, basename(my_path), size - 1);
1046  lirc_printf(SHEBANG_MSG);
1047  } else {
1048  lirc_printf("Warning: bad shebang (ignored)");
1049  }
1050 }
1051 
1052 
1053 static int lirc_readconfig_only_internal(const char* file,
1054  struct lirc_config** config,
1055  int (check)(char* s),
1056  char** full_name)
1057 {
1058  const char* const INCLUDED_LIRCRC_CLASS =
1059  "Warning: lirc_class in included file (ignored)";
1060  char* string;
1061  char* eq;
1062  char* token;
1063  char* token2;
1064  char* token3;
1065  struct filestack_t* filestack;
1066  struct filestack_t* stack_tmp;
1067  int open_files;
1068  char lircrc_class[128] = { '\0' };
1069  struct lirc_config_entry* new_entry;
1070  struct lirc_config_entry* first;
1071  struct lirc_config_entry* last;
1072  char* mode;
1073  char* remote;
1074  int ret = 0;
1075  int firstline = 1;
1076  char* save_full_name = NULL;
1077 
1078  filestack = stack_push(NULL);
1079  if (filestack == NULL)
1080  return -1;
1081  filestack->file = lirc_open(file, NULL, &(filestack->name));
1082  if (filestack->file == NULL) {
1083  stack_free(filestack);
1084  return -1;
1085  }
1086  filestack->line = 0;
1087  open_files = 1;
1088 
1089  first = new_entry = last = NULL;
1090  mode = NULL;
1091  remote = LIRC_ALL;
1092  while (filestack) {
1093  ret = lirc_readline(&string, filestack->file);
1094  if (ret == -1 || string == NULL) {
1095  fclose(filestack->file);
1096  if (open_files == 1 && full_name != NULL) {
1097  save_full_name = filestack->name;
1098  filestack->name = NULL;
1099  }
1100  filestack = stack_pop(filestack);
1101  open_files--;
1102  continue;
1103  }
1104  /* check for sha-bang */
1105  if (firstline) {
1106  firstline = 0;
1107  if (strncmp(string, "#!", 2) == 0) {
1108  parse_shebang(string,
1109  open_files,
1110  file,
1111  lircrc_class,
1112  sizeof(lircrc_class));
1113  }
1114  }
1115  filestack->line++;
1116  eq = strchr(string, '=');
1117  if (eq == NULL) {
1118  token = strtok(string, " \t");
1119  if (token == NULL) {
1120  /* ignore empty line */
1121  } else if (token[0] == '#') {
1122  /* ignore comment */
1123  } else if (strcasecmp(token, "lircrc_class") == 0) {
1124  token2 = lirc_trim(strtok(NULL, ""));
1125  if (strlen(token2) == 0) {
1126  lirc_printf(
1127  "Warning: no lircrc_class");
1128  } else if (open_files == 1) {
1129  strncpy(lircrc_class,
1130  token2,
1131  sizeof(lircrc_class) - 1);
1132  } else {
1133  lirc_printf(INCLUDED_LIRCRC_CLASS);
1134  }
1135  } else if (strcasecmp(token, "include") == 0) {
1136  if (open_files >= MAX_INCLUDES) {
1137  lirc_printf("%s: too many files "
1138  "included at %s:%d\n",
1139  lirc_prog, filestack->name,
1140  filestack->line);
1141  ret = -1;
1142  } else {
1143  token2 = strtok(NULL, "");
1144  token2 = lirc_trim(token2);
1145  lirc_parse_include(token2,
1146  filestack->name,
1147  filestack->line);
1148  stack_tmp = stack_push(filestack);
1149  if (stack_tmp == NULL) {
1150  ret = -1;
1151  } else {
1152  stack_tmp->file =
1153  lirc_open(token2,
1154  filestack->name,
1155  &(stack_tmp->
1156  name));
1157  stack_tmp->line = 0;
1158  if (stack_tmp->file) {
1159  open_files++;
1160  filestack = stack_tmp;
1161  } else {
1162  stack_pop(stack_tmp);
1163  ret = -1;
1164  }
1165  }
1166  }
1167  } else {
1168  token2 = strtok(NULL, " \t");
1169  if (token2)
1170  token3 = strtok(NULL, " \t");
1171  if (token2 != NULL && token3 != NULL) {
1172  lirc_printf("%s: unexpected token in line %s:%d\n",
1173  lirc_prog, filestack->name, filestack->line);
1174  } else {
1175  ret = lirc_mode(token, token2, &mode,
1176  &new_entry, &first,
1177  &last,
1178  check, filestack->name,
1179  filestack->line);
1180  if (ret == 0) {
1181  if (remote != LIRC_ALL)
1182  free(remote);
1183  remote = LIRC_ALL;
1184  } else {
1185  if (mode != NULL) {
1186  free(mode);
1187  mode = NULL;
1188  }
1189  if (new_entry != NULL) {
1190  lirc_freeconfigentries(
1191  new_entry);
1192  new_entry = NULL;
1193  }
1194  }
1195  }
1196  }
1197  } else {
1198  eq[0] = 0;
1199  token = lirc_trim(string);
1200  token2 = lirc_trim(eq + 1);
1201  if (token[0] == '#') {
1202  /* ignore comment */
1203  } else if (new_entry == NULL) {
1204  lirc_printf("%s: bad file format, %s:%d\n",
1205  lirc_prog, filestack->name,
1206  filestack->line);
1207  ret = -1;
1208  } else {
1209  token2 = strdup(token2);
1210  if (token2 == NULL) {
1211  lirc_printf("%s: out of memory\n",
1212  lirc_prog);
1213  ret = -1;
1214  } else if (strcasecmp(token, "prog") == 0) {
1215  if (new_entry->prog != NULL)
1216  free(new_entry->prog);
1217  new_entry->prog = token2;
1218  } else if (strcasecmp(token, "remote") == 0) {
1219  if (remote != LIRC_ALL)
1220  free(remote);
1221 
1222  if (strcasecmp("*", token2) == 0) {
1223  remote = LIRC_ALL;
1224  free(token2);
1225  } else {
1226  remote = token2;
1227  }
1228  } else if (strcasecmp(token, "button") == 0) {
1229  struct lirc_code* code;
1230 
1231  code = (struct lirc_code*)
1232  malloc(sizeof(struct lirc_code));
1233  if (code == NULL) {
1234  free(token2);
1235  lirc_printf(
1236  "%s: out of memory\n",
1237  lirc_prog);
1238  ret = -1;
1239  } else {
1240  code->remote = remote;
1241  if (strcasecmp("*",
1242  token2) == 0) {
1243  code->button = LIRC_ALL;
1244  free(token2);
1245  } else {
1246  code->button = token2;
1247  }
1248  code->next = NULL;
1249 
1250  if (new_entry->code == NULL)
1251  new_entry->code = code;
1252  else
1253  new_entry->next_code->
1254  next = code;
1255  new_entry->next_code = code;
1256  if (remote != LIRC_ALL) {
1257  remote = strdup(remote);
1258  if (remote == NULL) {
1259  lirc_printf(
1260  "%s: out of memory\n",
1261  lirc_prog);
1262  ret = -1;
1263  }
1264  }
1265  }
1266  } else if (strcasecmp(token, "delay") == 0) {
1267  char* end;
1268 
1269  errno = ERANGE + 1;
1270  new_entry->rep_delay = strtoul(token2,
1271  &end, 0);
1272  if ((new_entry->rep_delay ==
1273  ULONG_MAX && errno == ERANGE)
1274  || end[0] != 0 || strlen(token2) ==
1275  0)
1276  lirc_printf("%s: \"%s\" not"
1277  " a valid number for delay\n", lirc_prog,
1278  token2);
1279  free(token2);
1280  } else if (strcasecmp(token, "ignore_first_events") == 0) {
1281  char* end;
1282 
1283  errno = ERANGE + 1;
1284  new_entry->ign_first_events = strtoul(
1285  token2, &end, 0);
1286  if ((new_entry->ign_first_events ==
1287  ULONG_MAX && errno == ERANGE)
1288  || end[0] != 0 || strlen(token2) ==
1289  0)
1290  lirc_printf("%s: \"%s\" not"
1291  " a valid number for ignore_first_events\n",
1292  lirc_prog, token2);
1293  free(token2);
1294  } else if (strcasecmp(token, "repeat") == 0) {
1295  char* end;
1296 
1297  errno = ERANGE + 1;
1298  new_entry->rep =
1299  strtoul(token2, &end, 0);
1300  if ((new_entry->rep == ULONG_MAX &&
1301  errno == ERANGE)
1302  || end[0] != 0 || strlen(token2) ==
1303  0)
1304  lirc_printf("%s: \"%s\" not"
1305  " a valid number for repeat\n", lirc_prog,
1306  token2);
1307  free(token2);
1308  } else if (strcasecmp(token, "config") == 0) {
1309  struct lirc_list* new_list;
1310 
1311  new_list = (struct lirc_list*)
1312  malloc(sizeof(struct lirc_list));
1313  if (new_list == NULL) {
1314  free(token2);
1315  lirc_printf(
1316  "%s: out of memory\n",
1317  lirc_prog);
1318  ret = -1;
1319  } else {
1320  lirc_parse_string(token2,
1321  filestack->name,
1322  filestack->line);
1323  new_list->string = token2;
1324  new_list->next = NULL;
1325  if (new_entry->config == NULL)
1326  new_entry->config =
1327  new_list;
1328  else
1329  new_entry->next_config->
1330  next = new_list;
1331  new_entry->next_config =
1332  new_list;
1333  }
1334  } else if (strcasecmp(token, "mode") == 0) {
1335  if (new_entry->change_mode != NULL)
1336  free(new_entry->change_mode);
1337  new_entry->change_mode = token2;
1338  } else if (strcasecmp(token, "flags") == 0) {
1339  new_entry->flags = lirc_flags(token2);
1340  free(token2);
1341  } else {
1342  free(token2);
1343  lirc_printf(
1344  "%s: unknown token \"%s\" in %s:%d ignored\n",
1345  lirc_prog, token, filestack->name,
1346  filestack->line);
1347  }
1348  }
1349  }
1350  free(string);
1351  if (ret == -1)
1352  break;
1353  }
1354  if (remote != LIRC_ALL)
1355  free(remote);
1356  if (new_entry != NULL) {
1357  if (ret == 0) {
1358  ret = lirc_mode("end", NULL, &mode, &new_entry, &first,
1359  &last, check, "", 0);
1360  lirc_printf(
1361  "%s: warning: end token missing at end of file\n",
1362  lirc_prog);
1363  } else {
1364  lirc_freeconfigentries(new_entry);
1365  new_entry = NULL;
1366  }
1367  }
1368  if (mode != NULL) {
1369  if (ret == 0)
1370  lirc_printf(
1371  "%s: warning: no end token found for mode \"%s\"\n", lirc_prog,
1372  mode);
1373  free(mode);
1374  }
1375  if (ret == 0) {
1376  char* startupmode;
1377 
1378  *config = (struct lirc_config*)
1379  malloc(sizeof(struct lirc_config));
1380  if (*config == NULL) {
1381  lirc_printf("%s: out of memory\n", lirc_prog);
1382  lirc_freeconfigentries(first);
1383  return -1;
1384  }
1385  (*config)->first = first;
1386  (*config)->next = first;
1387  startupmode = lirc_startupmode((*config)->first);
1388  (*config)->current_mode =
1389  startupmode ? strdup(startupmode) : NULL;
1390  if (lircrc_class[0] != '\0')
1391  (*config)->lircrc_class = strdup(lircrc_class);
1392  else
1393  (*config)->lircrc_class = NULL;
1394  (*config)->sockfd = -1;
1395  if (full_name != NULL) {
1396  *full_name = save_full_name;
1397  save_full_name = NULL;
1398  }
1399  } else {
1400  *config = NULL;
1401  lirc_freeconfigentries(first);
1402  }
1403  if (filestack)
1404  stack_free(filestack);
1405  if (save_full_name)
1406  free(save_full_name);
1407  return ret;
1408 }
1409 
1410 
1411 int lirc_identify(int sockfd)
1412 {
1413  lirc_cmd_ctx cmd;
1414  int ret;
1415 
1416  ret = lirc_command_init(&cmd, "IDENT %s\n", lirc_prog);
1417  if (ret != 0)
1418  return ret;
1419  do
1420  ret = lirc_command_run(&cmd, sockfd);
1421  while (ret == EAGAIN || ret == EWOULDBLOCK);
1422  return ret == 0;
1423 }
1424 
1425 
1426 
1427 int lirc_readconfig(const char* file,
1428  struct lirc_config** config,
1429  int (check)(char* s))
1430 {
1431  struct sockaddr_un addr;
1432  int sockfd = -1;
1433  char* filename;
1434  char command[128];
1435  int ret;
1436 
1437  filename = NULL;
1438  if (lirc_readconfig_only_internal(file, config, check, &filename) == -1)
1439  return -1;
1440 
1441  if ((*config)->lircrc_class == NULL)
1442  goto lirc_readconfig_compat;
1443 
1444  /* connect to lircrcd */
1445 
1446  addr.sun_family = AF_UNIX;
1447  if (lirc_getsocketname((*config)->lircrc_class,
1448  addr.sun_path,
1449  sizeof(addr.sun_path)) > sizeof(addr.sun_path)) {
1450  lirc_printf("%s: WARNING: file name too long\n", lirc_prog);
1451  goto lirc_readconfig_compat;
1452  }
1453  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1454  if (sockfd == -1) {
1455  lirc_printf("%s: WARNING: could not open socket\n", lirc_prog);
1456  lirc_perror(lirc_prog);
1457  goto lirc_readconfig_compat;
1458  }
1459  if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) != -1) {
1460  (*config)->sockfd = sockfd;
1461  free(filename);
1462 
1463  /* tell daemon lirc_prog */
1464  if (lirc_identify(sockfd) == LIRC_RET_SUCCESS)
1465  /* we're connected */
1466  return 0;
1467  close(sockfd);
1468  lirc_freeconfig(*config);
1469  return -1;
1470  }
1471  close(sockfd);
1472  sockfd = -1;
1473 
1474  /* launch lircrcd */
1475  snprintf(command, sizeof(command),
1476  "lircrcd %s", (*config)->lircrc_class);
1477  ret = system(command);
1478  if (ret == -1 || WEXITSTATUS(ret) != EXIT_SUCCESS)
1479  goto lirc_readconfig_compat;
1480  free(filename);
1481 
1482  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1483  if (sockfd == -1) {
1484  lirc_printf("%s: WARNING: could not open socket\n", lirc_prog);
1485  lirc_perror(lirc_prog);
1486  goto lirc_readconfig_compat;
1487  }
1488  if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) != -1) {
1489  if (lirc_identify(sockfd) == LIRC_RET_SUCCESS) {
1490  (*config)->sockfd = sockfd;
1491  return 0;
1492  }
1493  }
1494  close(sockfd);
1495  lirc_freeconfig(*config);
1496  return -1;
1497 
1498 lirc_readconfig_compat:
1499  /* compat fallback */
1500  if (sockfd != -1)
1501  close(sockfd);
1502  return 0;
1503 }
1504 
1505 
1506 int lirc_readconfig_only(const char* file,
1507  struct lirc_config** config,
1508  int (check) (char* s))
1509 {
1510  return lirc_readconfig_only_internal(file, config, check, NULL);
1511 }
1512 
1513 
1514 void lirc_freeconfig(struct lirc_config* config)
1515 {
1516  if (config != NULL) {
1517  if (config->sockfd != -1) {
1518  (void)close(config->sockfd);
1519  config->sockfd = -1;
1520  }
1521  if (config->lircrc_class != NULL)
1522  free(config->lircrc_class);
1523  lirc_freeconfigentries(config->first);
1524  free(config->current_mode);
1525  free(config);
1526  }
1527 }
1528 
1529 
1530 static void lirc_clearmode(struct lirc_config* config)
1531 {
1532  struct lirc_config_entry* scan;
1533 
1534  if (config->current_mode == NULL)
1535  return;
1536  scan = config->first;
1537  while (scan != NULL) {
1538  if (scan->change_mode != NULL)
1539  if (strcasecmp(scan->change_mode,
1540  config->current_mode) == 0)
1541  scan->flags &= ~ecno;
1542  scan = scan->next;
1543  }
1544  free(config->current_mode);
1545  config->current_mode = NULL;
1546 }
1547 
1548 
1549 static char* lirc_execute(struct lirc_config* config,
1550  struct lirc_config_entry* scan)
1551 {
1552  char* s;
1553  int do_once = 1;
1554 
1555  if (scan->flags & mode)
1556  lirc_clearmode(config);
1557  if (scan->change_mode != NULL) {
1558  free(config->current_mode);
1559  config->current_mode = strdup(scan->change_mode);
1560  if (scan->flags & once) {
1561  if (scan->flags & ecno)
1562  do_once = 0;
1563  else
1564  scan->flags |= ecno;
1565  }
1566  }
1567  if (scan->next_config != NULL
1568  && scan->prog != NULL
1569  && (lirc_prog == NULL || strcasecmp(scan->prog, lirc_prog) == 0)
1570  && do_once == 1) {
1571  s = scan->next_config->string;
1572  scan->next_config = scan->next_config->next;
1573  if (scan->next_config == NULL)
1574  scan->next_config = scan->config;
1575  return s;
1576  }
1577  return NULL;
1578 }
1579 
1588 static int rep_filter(struct lirc_config_entry* scan, int rep)
1589 {
1590  int delay_start, rep_delay;
1591 
1592  if (scan->ign_first_events) {
1593  if (scan->rep_delay && rep == 0) /* warn user only once */
1594  lirc_printf(
1595  "%s: ignoring \"delay\" because \"ignore_first_events\" is also set\n",
1596  lirc_prog);
1597  rep_delay = scan->ign_first_events;
1598  delay_start = 0;
1599  } else {
1600  rep_delay = scan->rep_delay;
1601  delay_start = 1;
1602  }
1603  /* handle event before delay_start */
1604  if (rep < delay_start)
1605  return 1;
1606  /* special case: 1 event after delay when repeat is not set */
1607  if (scan->rep == 0 && rep_delay > 0 && rep == rep_delay + delay_start)
1608  return 1;
1609  /* handle repeat */
1610  if (scan->rep > 0 && rep >= rep_delay + delay_start) {
1611  rep -= rep_delay + delay_start;
1612  return (rep % scan->rep) == 0;
1613  }
1614  return 0;
1615 }
1616 
1617 static int lirc_iscode(struct lirc_config_entry* scan,
1618  char* remote,
1619  char* button,
1620  int rep)
1621 {
1622  struct lirc_code* codes;
1623 
1624  /* no remote/button specified */
1625  if (scan->code == NULL)
1626  return rep_filter(scan, rep);
1627 
1628  /* remote/button match? */
1629  if (scan->next_code->remote == LIRC_ALL
1630  || strcasecmp(scan->next_code->remote, remote) == 0) {
1631  if (scan->next_code->button == LIRC_ALL
1632  || strcasecmp(scan->next_code->button, button) == 0) {
1633  int iscode = 0;
1634  /* button sequence? */
1635  if (scan->code->next == NULL || rep == 0) {
1636  scan->next_code = scan->next_code->next;
1637  if (scan->code->next != NULL)
1638  iscode = 1;
1639  }
1640  /* sequence completed? */
1641  if (scan->next_code == NULL) {
1642  scan->next_code = scan->code;
1643  if (scan->code->next != NULL ||
1644  rep_filter(scan, rep))
1645  iscode = 2;
1646  }
1647  return iscode;
1648  }
1649  }
1650 
1651  if (rep != 0)
1652  return 0;
1653 
1654  /* handle toggle_reset */
1655  if (scan->flags & toggle_reset)
1656  scan->next_config = scan->config;
1657 
1658  codes = scan->code;
1659  if (codes == scan->next_code)
1660  return 0;
1661  codes = codes->next;
1662  /* rebase code sequence */
1663  while (codes != scan->next_code->next) {
1664  struct lirc_code* prev;
1665  struct lirc_code* next;
1666  int flag = 1;
1667 
1668  prev = scan->code;
1669  next = codes;
1670  while (next != scan->next_code) {
1671  if (prev->remote == LIRC_ALL
1672  || strcasecmp(prev->remote, next->remote) == 0) {
1673  if (prev->button == LIRC_ALL
1674  || strcasecmp(prev->button,
1675  next->button) == 0) {
1676  prev = prev->next;
1677  next = next->next;
1678  } else {
1679  flag = 0;
1680  break;
1681  }
1682  } else {
1683  flag = 0;
1684  break;
1685  }
1686  }
1687  if (flag == 1) {
1688  if (prev->remote == LIRC_ALL
1689  || strcasecmp(prev->remote, remote) == 0) {
1690  if (prev->button == LIRC_ALL
1691  || strcasecmp(prev->button, button) == 0) {
1692  if (rep == 0) {
1693  scan->next_code = prev->next;
1694  return 0;
1695  }
1696  }
1697  }
1698  }
1699  codes = codes->next;
1700  }
1701  scan->next_code = scan->code;
1702  return 0;
1703 }
1704 
1705 
1706 char* lirc_ir2char(struct lirc_config* config, char* code)
1707 {
1708  static int warning = 1;
1709  char* string;
1710 
1711  if (warning) {
1712  fprintf(stderr, "%s: warning: lirc_ir2char() is obsolete\n",
1713  lirc_prog);
1714  warning = 0;
1715  }
1716  if (lirc_code2char(config, code, &string) == -1)
1717  return NULL;
1718  return string;
1719 }
1720 
1721 
1722 static int lirc_code2char_internal(struct lirc_config* config,
1723  char* code,
1724  char** string,
1725  char** prog)
1726 {
1727  int rep;
1728  char* backup;
1729  char* remote;
1730  char* button;
1731  char* s = NULL;
1732  struct lirc_config_entry* scan;
1733  int exec_level;
1734  int quit_happened;
1735 
1736  *string = NULL;
1737  if (sscanf(code, "%*x %x %*s %*s\n", &rep) == 1) {
1738  backup = strdup(code);
1739  if (backup == NULL)
1740  return -1;
1741 
1742  strtok(backup, " ");
1743  strtok(NULL, " ");
1744  button = strtok(NULL, " ");
1745  remote = strtok(NULL, "\n");
1746 
1747  if (button == NULL || remote == NULL) {
1748  free(backup);
1749  return 0;
1750  }
1751 
1752  scan = config->next;
1753  quit_happened = 0;
1754  while (scan != NULL) {
1755  exec_level = lirc_iscode(scan, remote, button, rep);
1756  if (exec_level > 0 &&
1757  (scan->mode == NULL ||
1758  (scan->mode != NULL &&
1759  config->current_mode != NULL &&
1760  strcasecmp(scan->mode,
1761  config->current_mode) == 0)) &&
1762  quit_happened == 0) {
1763  if (exec_level > 1) {
1764  s = lirc_execute(config, scan);
1765  if (s != NULL && prog != NULL)
1766  *prog = scan->prog;
1767  } else {
1768  s = NULL;
1769  }
1770  if (scan->flags & quit) {
1771  quit_happened = 1;
1772  config->next = NULL;
1773  scan = scan->next;
1774  continue;
1775  } else if (s != NULL) {
1776  config->next = scan->next;
1777  break;
1778  }
1779  }
1780  scan = scan->next;
1781  }
1782  free(backup);
1783  if (s != NULL) {
1784  *string = s;
1785  return 0;
1786  }
1787  }
1788  config->next = config->first;
1789  return 0;
1790 }
1791 
1792 
1793 int lirc_code2char(struct lirc_config* config, char* code, char** string)
1794 {
1795  lirc_cmd_ctx cmd;
1796  static char static_buff[PACKET_SIZE];
1797  int ret;
1798 
1799  ret = lirc_command_init(&cmd, "CODE %s\n", code);
1800  if (ret != 0)
1801  return -1;
1802  if (config->sockfd != -1) {
1803  do
1804  ret = lirc_command_run(&cmd, config->sockfd);
1805  while (ret == EAGAIN || ret == EWOULDBLOCK);
1806  if (ret == 0) {
1807  strncpy(static_buff, cmd.buffer, PACKET_SIZE);
1808  *string = static_buff;
1809  }
1810  return ret == 0 ? 0 : -1;
1811  }
1812  return lirc_code2char_internal(config, code, string, NULL);
1813 }
1814 
1815 
1816 int lirc_code2charprog(struct lirc_config* config,
1817  char* code,
1818  char** string,
1819  char** prog)
1820 {
1821  char* backup;
1822  int ret;
1823 
1824  backup = lirc_prog;
1825  lirc_prog = NULL;
1826 
1827  ret = lirc_code2char_internal(config, code, string, prog);
1828 
1829  lirc_prog = backup;
1830  return ret;
1831 }
1832 
1833 
1834 char* lirc_nextir(void)
1835 {
1836  static int warning = 1;
1837  char* code;
1838  int ret;
1839 
1840  if (warning) {
1841  fprintf(stderr, "%s: warning: lirc_nextir() is obsolete\n",
1842  lirc_prog);
1843  warning = 0;
1844  }
1845  ret = lirc_nextcode(&code);
1846  if (ret == -1)
1847  return NULL;
1848  return code;
1849 }
1850 
1851 
1852 int lirc_nextcode(char** code)
1853 {
1854  static int packet_size = PACKET_SIZE;
1855  static int end_len = 0;
1856  ssize_t len = 0;
1857  char* end;
1858  char c;
1859 
1860  *code = NULL;
1861  if (lirc_buffer == NULL) {
1862  lirc_buffer = (char*)malloc(packet_size + 1);
1863  if (lirc_buffer == NULL) {
1864  lirc_printf("%s: out of memory\n", lirc_prog);
1865  return -1;
1866  }
1867  lirc_buffer[0] = 0;
1868  }
1869  while ((end = strchr(lirc_buffer, '\n')) == NULL) {
1870  if (end_len >= packet_size) {
1871  char* new_buffer;
1872 
1873  packet_size += PACKET_SIZE;
1874  new_buffer =
1875  (char*)realloc(lirc_buffer, packet_size + 1);
1876  if (new_buffer == NULL)
1877  return -1;
1878  lirc_buffer = new_buffer;
1879  }
1880  len = read(lirc_lircd, lirc_buffer + end_len,
1881  packet_size - end_len);
1882  if (len <= 0) {
1883  if (len == -1 && errno == EAGAIN)
1884  return 0;
1885  else
1886  return -1;
1887  }
1888  end_len += len;
1889  lirc_buffer[end_len] = 0;
1890  /* return if next code not yet available completely */
1891  end = strchr(lirc_buffer, '\n');
1892  if (end == NULL)
1893  return 0;
1894  }
1895  /* copy first line to buffer (code) and move remaining chars to
1896  * lirc_buffers start */
1897  end++;
1898  end_len = strlen(end);
1899  c = end[0];
1900  end[0] = 0;
1901  *code = strdup(lirc_buffer);
1902  end[0] = c;
1903  memmove(lirc_buffer, end, end_len + 1);
1904  if (*code == NULL)
1905  return -1;
1906  return 0;
1907 }
1908 
1909 
1910 size_t lirc_getsocketname(const char* id, char* buf, size_t size)
1911 {
1912  id = id != NULL ? id : "default";
1913  snprintf(buf, size, VARRUNDIR "/%d-%s-lircrcd.socket", getuid(), id);
1914  return strlen(buf);
1915 }
1916 
1917 
1918 
1919 const char* lirc_getmode(struct lirc_config* config)
1920 {
1921  lirc_cmd_ctx cmd;
1922  static char static_buff[PACKET_SIZE];
1923  int ret;
1924 
1925  if (config->sockfd != -1) {
1926  lirc_command_init(&cmd, "GETMODE\n");
1927  do
1928  ret = lirc_command_run(&cmd, config->sockfd);
1929  while (ret == EAGAIN || ret == EWOULDBLOCK);
1930  if (ret == 0) {
1931  strncpy(static_buff, cmd.reply, PACKET_SIZE);
1932  return static_buff;
1933  }
1934  return NULL;
1935  }
1936  return config->current_mode;
1937 }
1938 
1939 
1940 const char* lirc_setmode(struct lirc_config* config, const char* mode)
1941 {
1942  lirc_cmd_ctx cmd;
1943  int r;
1944  static char static_buff[PACKET_SIZE];
1945 
1946  if (config->sockfd != -1) {
1947  if (mode != NULL)
1948  r = lirc_command_init(&cmd, "SETMODE %s\n", mode);
1949  else
1950  r = lirc_command_init(&cmd, "SETMODE\n");
1951  if (r != 0)
1952  return NULL;
1953  do
1954  r = lirc_command_run(&cmd, config->sockfd);
1955  while (r == EAGAIN || r == EWOULDBLOCK);
1956  if (r == 0) {
1957  strncpy(static_buff, cmd.reply, PACKET_SIZE);
1958  return static_buff;
1959  }
1960  return NULL;
1961  }
1962  free(config->current_mode);
1963  config->current_mode = mode ? strdup(mode) : NULL;
1964  return config->current_mode;
1965 }
1966 
1967 
1968 int lirc_send_one(int fd, const char* remote, const char* keysym)
1969 {
1970  int r;
1971  lirc_cmd_ctx command;
1972 
1973  r = lirc_command_init(&command, "SEND_ONCE %s %s\n", remote, keysym);
1974  if (r != 0)
1975  return EMSGSIZE;
1976  do
1977  r = lirc_command_run(&command, fd);
1978  while (r == EAGAIN);
1979  return r;
1980 }
1981 
1982 
1983 int lirc_simulate(int fd,
1984  const char* remote,
1985  const char* keysym,
1986  int scancode,
1987  int repeat)
1988 {
1989  lirc_cmd_ctx cmd;
1990  int r;
1991 
1992  r = lirc_command_init(&cmd, "SIMULATE %016x %02x %s %s\n",
1993  scancode, repeat, keysym, remote);
1994  if (r != 0)
1995  return EMSGSIZE;
1996  do
1997  r = lirc_command_run(&cmd, fd);
1998  while (r == EAGAIN);
1999  return r;
2000 }
2001 
2002 
2004 static int
2005 do_connect(int domain, struct sockaddr* addr, size_t size, int quiet)
2006 {
2007  int fd;
2008 
2009  fd = socket(domain, SOCK_STREAM, 0);
2010  if (fd == -1) {
2011  if (!quiet) {
2012  fprintf(stderr, "do_connect: could not open socket\n");
2013  perror("open");
2014  }
2015  return -errno;
2016  }
2017  if (connect(fd, addr, size) == -1) {
2018  if (!quiet) {
2019  fprintf(stderr,
2020  "do_connect: could not connect to socket\n");
2021  perror("connect");
2022  }
2023  return -errno;
2024  }
2025  return fd;
2026 }
2027 
2028 
2029 int lirc_get_local_socket(const char* path, int quiet)
2030 {
2031  const char* socket_path;
2032  struct sockaddr_un addr_un;
2033 
2034  socket_path = path ? path : getenv("LIRC_SOCKET_PATH");
2035  socket_path = socket_path ? socket_path : LIRCD;
2036  if (strlen(socket_path) + 1 > sizeof(addr_un.sun_path)) {
2037  /* path is longer than sockaddr_un.sun_path field (!) */
2038  if (!quiet)
2039  fprintf(stderr, "%s: socket name is too long\n", prog);
2040  return -ENAMETOOLONG;
2041  }
2042  addr_un.sun_family = AF_UNIX;
2043  strcpy(addr_un.sun_path, socket_path);
2044  return do_connect(AF_UNIX,
2045  (struct sockaddr*)&addr_un,
2046  sizeof(addr_un),
2047  quiet);
2048 }
2049 
2050 
2051 int lirc_get_remote_socket(const char* address, int port, int quiet)
2052 {
2053  struct addrinfo* addrinfos;
2054  struct addrinfo* a;
2055  char service[64];
2056  int r;
2057 
2058  snprintf(service, sizeof(service),
2059  "%d", port > 0 ? port : LIRC_INET_PORT);
2060  r = getaddrinfo(address, service, NULL, &addrinfos);
2061  if (r < 0) {
2062  if (!quiet)
2063  fprintf(stderr, "get_remote_socket: host %s unknown\n",
2064  address);
2065  return -EADDRNOTAVAIL;
2066  }
2067  for (a = addrinfos; a != NULL; a = a->ai_next) {
2068  r = do_connect(a->ai_family, a->ai_addr, a->ai_addrlen, quiet);
2069  if (r >= 0)
2070  break;
2071  };
2072  freeaddrinfo(addrinfos);
2073  return r;
2074 }
#define LIRCRC_ROOT_FILE
Definition: lirc_config.h:68
#define chk_write(fd, buf, count)
Definition: lirc_log.h:215
void lirc_command_reply_to_stdout(lirc_cmd_ctx *ctx)
Definition: lirc_client.c:122
Definition: lirc_client.h:168
int lirc_init(const char *prog, int verbose)
Definition: lirc_client.c:333
const char * lirc_setmode(struct lirc_config *config, const char *mode)
Definition: lirc_client.c:1940
char reply[PACKET_SIZE+1]
Definition: lirc_client.h:194
int lirc_get_local_socket(const char *path, int quiet)
Definition: lirc_client.c:2029
char buffer[PACKET_SIZE+1]
Definition: lirc_client.h:193
int lirc_command_run(lirc_cmd_ctx *ctx, int fd)
Definition: lirc_client.c:180
#define LIRCRC_OLD_ROOT_FILE
Definition: lirc_config.h:71
char * lircrc_class
Definition: lirc_client.h:160
const char * lirc_getmode(struct lirc_config *config)
Definition: lirc_client.c:1919
#define PACKET_SIZE
Definition: lirc_config.h:98
int lirc_simulate(int fd, const char *remote, const char *keysym, int scancode, int repeat)
Definition: lirc_client.c:1983
size_t lirc_getsocketname(const char *id, char *buf, size_t size)
Definition: lirc_client.c:1910
int lirc_command_init(lirc_cmd_ctx *ctx, const char *fmt,...)
Definition: lirc_client.c:105
packet_state
Definition: lirc_client.c:71
#define LIRC_INET_PORT
Definition: lirc_config.h:34
int lirc_nextcode(char **code)
Definition: lirc_client.c:1852
int lirc_get_remote_socket(const char *address, int port, int quiet)
Definition: lirc_client.c:2051
int lirc_code2char(struct lirc_config *config, char *code, char **string)
Definition: lirc_client.c:1793
int lirc_readconfig_only(const char *file, struct lirc_config **config, int(check)(char *s))
Definition: lirc_client.c:1506
char packet[PACKET_SIZE+1]
Definition: lirc_client.h:192
int lirc_readconfig(const char *file, struct lirc_config **config, int(check)(char *s))
Definition: lirc_client.c:1427
int lirc_send_one(int fd, const char *remote, const char *keysym)
Definition: lirc_client.c:1968
int reply_to_stdout
Definition: lirc_client.h:196
void lirc_freeconfig(struct lirc_config *config)
Definition: lirc_client.c:1514
#define LIRCRC_USER_FILE
Definition: lirc_config.h:65
#define CFG_LIRCRC
Definition: lirc_config.h:28
3-rd party application interface.
#define LIRCD
Definition: lirc_config.h:48
char * lirc_nextir(void)
Definition: lirc_client.c:1834
int lirc_deinit(void)
Definition: lirc_client.c:354
char * lirc_ir2char(struct lirc_config *config, char *code)
Definition: lirc_client.c:1706