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