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