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