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