LIRC libraries
LinuxInfraredRemoteControl
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Modules Pages
config_file.c
Go to the documentation of this file.
1 
2 /****************************************************************************
3  ** config_file.c ***********************************************************
4  ****************************************************************************
5  *
6  *
7  * Copyright (C) 1998 Pablo d'Angelo <pablo@ag-trek.allgaeu.org>
8  *
9  */
10 
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 
22 #include <dirent.h>
23 #include <errno.h>
24 #include <glob.h>
25 #include <limits.h>
26 #include <unistd.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <libgen.h>
31 #include <sys/socket.h>
32 #include <sys/un.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <fcntl.h>
36 #include <ctype.h>
37 
38 #include "include/media/lirc.h"
39 #include "lirc/lirc_log.h"
40 #include "lirc/lirc_options.h"
41 #include "lirc/ir_remote.h"
42 #include "lirc/config_file.h"
43 #include "lirc/transmit.h"
44 #include "lirc/config_flags.h"
45 
46 
47 enum directive { ID_none, ID_remote, ID_codes, ID_raw_codes, ID_raw_name };
48 
49 struct ptr_array {
50  void **ptr;
51  size_t nr_items;
52  size_t chunk_size;
53 };
54 
55 struct void_array {
56  void *ptr;
57  size_t item_size;
58  size_t nr_items;
59  size_t chunk_size;
60 };
61 
62 
63 #define LINE_LEN 1024
64 #define MAX_INCLUDES 10
65 
66 const char *whitespace = " \t";
67 
68 static int line;
69 static int parse_error;
70 
71 static struct ir_remote *read_config_recursive(FILE * f, const char *name, int depth);
72 static void calculate_signal_lengths(struct ir_remote *remote);
73 
74 void **init_void_array(struct void_array *ar, size_t chunk_size, size_t item_size)
75 {
76  ar->chunk_size = chunk_size;
77  ar->item_size = item_size;
78  ar->nr_items = 0;
79  if (!(ar->ptr = calloc(chunk_size, ar->item_size))) {
80  logprintf(LIRC_ERROR, "out of memory");
81  parse_error = 1;
82  return (NULL);
83  }
84  return (ar->ptr);
85 }
86 
87 const struct flaglist all_flags[] = {
88  {"RAW_CODES", RAW_CODES},
89  {"RC5", RC5},
90  {"SHIFT_ENC", SHIFT_ENC}, /* obsolete */
91  {"RC6", RC6},
92  {"RCMM", RCMM},
93  {"SPACE_ENC", SPACE_ENC},
94  {"SPACE_FIRST", SPACE_FIRST},
95  {"GOLDSTAR", GOLDSTAR},
96  {"GRUNDIG", GRUNDIG},
97  {"BO", BO},
98  {"SERIAL", SERIAL},
99  {"XMP", XMP},
100 
101  {"REVERSE", REVERSE},
102  {"NO_HEAD_REP", NO_HEAD_REP},
103  {"NO_FOOT_REP", NO_FOOT_REP},
104  {"CONST_LENGTH", CONST_LENGTH}, /* remember to adapt warning
105  message when changing this */
106  {"REPEAT_HEADER", REPEAT_HEADER},
107  {NULL, 0},
108 };
109 
110 
111 int add_void_array(struct void_array *ar, void *dataptr)
112 {
113  void *ptr;
114 
115  if ((ar->nr_items % ar->chunk_size) == (ar->chunk_size) - 1) {
116  /* I hope this works with the right alignment,
117  if not we're screwed */
118  if (!(ptr = realloc(ar->ptr, ar->item_size * ((ar->nr_items) + (ar->chunk_size + 1))))) {
119  logprintf(LIRC_ERROR, "out of memory");
120  parse_error = 1;
121  return (0);
122  }
123  ar->ptr = ptr;
124  }
125  memcpy((ar->ptr) + (ar->item_size * ar->nr_items), dataptr, ar->item_size);
126  ar->nr_items = (ar->nr_items) + 1;
127  memset((ar->ptr) + (ar->item_size * ar->nr_items), 0, ar->item_size);
128  return (1);
129 }
130 
131  void *get_void_array(struct void_array *ar)
132 {
133  return (ar->ptr);
134 }
135 
136 void *s_malloc(size_t size)
137 {
138  void *ptr;
139  if ((ptr = malloc(size)) == NULL) {
140  logprintf(LIRC_ERROR, "out of memory");
141  parse_error = 1;
142  return (NULL);
143  }
144  memset(ptr, 0, size);
145  return (ptr);
146 }
147 
148  char *s_strdup(char *string)
149 {
150  char *ptr;
151  if (!(ptr = strdup(string))) {
152  logprintf(LIRC_ERROR, "out of memory");
153  parse_error = 1;
154  return (NULL);
155  }
156  return (ptr);
157 }
158 
159  ir_code s_strtocode(const char *val)
160 {
161  ir_code code = 0;
162  char *endptr;
163 
164  errno = 0;
165  code = strtoull(val, &endptr, 0);
166  if ((code == (__u64) - 1 && errno == ERANGE) || strlen(endptr) != 0 || strlen(val) == 0) {
167  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
168  logprintf(LIRC_ERROR, "\"%s\": must be a valid (__u64) number", val);
169  parse_error = 1;
170  return (0);
171  }
172  return (code);
173 }
174 
175 __u32 s_strtou32(char *val)
176 {
177  __u32 n;
178  char *endptr;
179 
180  n = strtoul(val, &endptr, 0);
181  if (!*val || *endptr) {
182  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
183  logprintf(LIRC_ERROR, "\"%s\": must be a valid (__u32) number", val);
184  parse_error = 1;
185  return (0);
186  }
187  return (n);
188 }
189 
190 int s_strtoi(char *val)
191 {
192  char *endptr;
193  long n;
194  int h;
195 
196  n = strtol(val, &endptr, 0);
197  h = (int)n;
198  if (!*val || *endptr || n != ((long)h)) {
199  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
200  logprintf(LIRC_ERROR, "\"%s\": must be a valid (int) number", val);
201  parse_error = 1;
202  return (0);
203  }
204  return (h);
205 }
206 
207 unsigned int s_strtoui(char *val)
208 {
209  char *endptr;
210  __u32 n;
211  unsigned int h;
212 
213  n = strtoul(val, &endptr, 0);
214  h = (unsigned int)n;
215  if (!*val || *endptr || n != ((__u32) h)) {
216  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
217  logprintf(LIRC_ERROR, "\"%s\": must be a valid (unsigned int) number", val);
218  parse_error = 1;
219  return (0);
220  }
221  return (h);
222 }
223 
224 lirc_t s_strtolirc_t(char *val)
225 {
226  __u32 n;
227  lirc_t h;
228  char *endptr;
229 
230  n = strtoul(val, &endptr, 0);
231  h = (lirc_t) n;
232  if (!*val || *endptr || n != ((__u32) h)) {
233  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
234  logprintf(LIRC_ERROR, "\"%s\": must be a valid (lirc_t) number", val);
235  parse_error = 1;
236  return (0);
237  }
238  if (h < 0) {
239  logprintf(LIRC_WARNING, "error in configfile line %d:", line);
240  logprintf(LIRC_WARNING, "\"%s\" is out of range", val);
241  }
242  return (h);
243 }
244 
245 int checkMode(int is_mode, int c_mode, char *error)
246 {
247  if (is_mode != c_mode) {
248  logprintf(LIRC_ERROR, "fatal error in configfile line %d:", line);
249  logprintf(LIRC_ERROR, "\"%s\" isn't valid at this position", error);
250  parse_error = 1;
251  return (0);
252  }
253  return (1);
254 }
255 
256 int addSignal(struct void_array *signals, char *val)
257 {
258  unsigned int t;
259 
260  t = s_strtoui(val);
261  if (parse_error)
262  return 0;
263  if (!add_void_array(signals, &t))
264  return 0;
265 
266  return 1;
267 }
268 
269 struct ir_ncode *defineCode(char *key, char *val, struct ir_ncode *code)
270 {
271  memset(code, 0, sizeof(*code));
272  code->name = s_strdup(key);
273  code->code = s_strtocode(val);
274  LOGPRINTF(3, " %-20s 0x%016llX", code->name, code->code);
275  return (code);
276 }
277 
278 struct ir_code_node *defineNode(struct ir_ncode *code, const char *val)
279 {
280  struct ir_code_node *node;
281 
282  node = s_malloc(sizeof(*node));
283  if (node == NULL)
284  return NULL;
285 
286  node->code = s_strtocode(val);
287  node->next = NULL;
288 
289  LOGPRINTF(3, " 0x%016llX", node->code);
290 
291  if (code->current == NULL) {
292  code->next = node;
293  code->current = node;
294  } else {
295  code->current->next = node;
296  code->current = node;
297  }
298  return node;
299 }
300 
301 int parseFlags(char *val)
302 {
303  const struct flaglist *flaglptr;
304  int flags = 0;
305  char *flag, *help;
306 
307  flag = help = val;
308  while (flag != NULL) {
309  while (*help != '|' && *help != 0)
310  help++;
311  if (*help == '|') {
312  *help = 0;
313  help++;
314  } else {
315  help = NULL;
316  }
317 
318  flaglptr = all_flags;
319  while (flaglptr->name != NULL) {
320  if (strcasecmp(flaglptr->name, flag) == 0) {
321  if (flaglptr->flag & IR_PROTOCOL_MASK && flags & IR_PROTOCOL_MASK) {
322  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
323  logprintf(LIRC_ERROR, "multiple protocols given in flags: \"%s\"", flag);
324  parse_error = 1;
325  return (0);
326  }
327  flags = flags | flaglptr->flag;
328  LOGPRINTF(3, "flag %s recognized", flaglptr->name);
329  break;
330  }
331  flaglptr++;
332  }
333  if (flaglptr->name == NULL) {
334  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
335  logprintf(LIRC_ERROR, "unknown flag: \"%s\"", flag);
336  parse_error = 1;
337  return (0);
338  }
339  flag = help;
340  }
341  LOGPRINTF(2, "flags value: %d", flags);
342 
343  return (flags);
344 }
345 
346 int defineRemote(char *key, char *val, char *val2, struct ir_remote *rem)
347 {
348  if ((strcasecmp("name", key)) == 0) {
349  if (rem->name != NULL)
350  free((void*) (rem->name));
351  rem->name = s_strdup(val);
352  logprintf(LIRC_INFO, "Using remote: %s.", val);
353  return (1);
354  }
355  if (options_getboolean("lircd:dynamic-codes")) {
356  if ((strcasecmp("dyncodes_name", key)) == 0) {
357  if (rem->dyncodes_name != NULL) {
358  free(rem->dyncodes_name);
359  }
360  rem->dyncodes_name = s_strdup(val);
361  return (1);
362  }
363  }
364  else if (strcasecmp("driver", key) == 0) {
365  if (rem->driver != NULL) {
366  free((void*)(rem->driver));
367  }
368  rem->driver = s_strdup(val);
369  return 1;
370  }
371  else if ((strcasecmp("bits", key)) == 0) {
372  rem->bits = s_strtoi(val);
373  return (1);
374  } else if (strcasecmp("flags", key) == 0) {
375  rem->flags |= parseFlags(val);
376  return (1);
377  } else if (strcasecmp("eps", key) == 0) {
378  rem->eps = s_strtoi(val);
379  return (1);
380  } else if (strcasecmp("aeps", key) == 0) {
381  rem->aeps = s_strtoi(val);
382  return (1);
383  } else if (strcasecmp("plead", key) == 0) {
384  rem->plead = s_strtolirc_t(val);
385  return (1);
386  } else if (strcasecmp("ptrail", key) == 0) {
387  rem->ptrail = s_strtolirc_t(val);
388  return (1);
389  } else if (strcasecmp("pre_data_bits", key) == 0) {
390  rem->pre_data_bits = s_strtoi(val);
391  return (1);
392  } else if (strcasecmp("pre_data", key) == 0) {
393  rem->pre_data = s_strtocode(val);
394  return (1);
395  } else if (strcasecmp("post_data_bits", key) == 0) {
396  rem->post_data_bits = s_strtoi(val);
397  return (1);
398  } else if (strcasecmp("post_data", key) == 0) {
399  rem->post_data = s_strtocode(val);
400  return (1);
401  } else if (strcasecmp("gap", key) == 0) {
402  if (val2 != NULL) {
403  rem->gap2 = s_strtou32(val2);
404  }
405  rem->gap = s_strtou32(val);
406  return (val2 != NULL ? 2 : 1);
407  } else if (strcasecmp("repeat_gap", key) == 0) {
408  rem->repeat_gap = s_strtou32(val);
409  return (1);
410  } else if (strcasecmp("repeat_mask", key) == 0) {
411  rem->repeat_mask = s_strtocode(val);
412  return (1);
413  }
414  /* obsolete: use toggle_bit_mask instead */
415  else if (strcasecmp("toggle_bit", key) == 0) {
416  rem->toggle_bit = s_strtoi(val);
417  return 1;
418  } else if (strcasecmp("toggle_bit_mask", key) == 0) {
419  rem->toggle_bit_mask = s_strtocode(val);
420  return 1;
421  } else if (strcasecmp("toggle_mask", key) == 0) {
422  rem->toggle_mask = s_strtocode(val);
423  return (1);
424  } else if (strcasecmp("rc6_mask", key) == 0) {
425  rem->rc6_mask = s_strtocode(val);
426  return (1);
427  } else if (strcasecmp("ignore_mask", key) == 0) {
428  rem->ignore_mask = s_strtocode(val);
429  return (1);
430  } else if (strcasecmp("manual_sort", key) == 0) {
431  rem->manual_sort = s_strtoi(val);
432  return (1);
433  }
434  /* obsolete name */
435  else if (strcasecmp("repeat_bit", key) == 0) {
436  rem->toggle_bit = s_strtoi(val);
437  return (1);
438  } else if (strcasecmp("suppress_repeat", key) == 0) {
439  rem->suppress_repeat = s_strtoi(val);
440  return (1);
441  } else if (strcasecmp("min_repeat", key) == 0) {
442  rem->min_repeat = s_strtoi(val);
443  return (1);
444  } else if (strcasecmp("min_code_repeat", key) == 0) {
445  rem->min_code_repeat = s_strtoi(val);
446  return (1);
447  } else if (strcasecmp("frequency", key) == 0) {
448  rem->freq = s_strtoui(val);
449  return (1);
450  } else if (strcasecmp("duty_cycle", key) == 0) {
451  rem->duty_cycle = s_strtoui(val);
452  return (1);
453  } else if (strcasecmp("baud", key) == 0) {
454  rem->baud = s_strtoui(val);
455  return (1);
456  } else if (strcasecmp("serial_mode", key) == 0) {
457  if (val[0] < '5' || val[0] > '9') {
458  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
459  logprintf(LIRC_ERROR, "bad bit count");
460  parse_error = 1;
461  return 0;
462  }
463  rem->bits_in_byte = val[0] - '0';
464  switch (toupper(val[1])) {
465  case 'N':
466  rem->parity = IR_PARITY_NONE;
467  break;
468  case 'E':
469  rem->parity = IR_PARITY_EVEN;
470  break;
471  case 'O':
472  rem->parity = IR_PARITY_ODD;
473  break;
474  default:
475  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
476  logprintf(LIRC_ERROR, "unsupported parity mode");
477  parse_error = 1;
478  return 0;
479  }
480  if (strcmp(val + 2, "1.5") == 0) {
481  rem->stop_bits = 3;
482  } else {
483  rem->stop_bits = s_strtoui(val + 2) * 2;
484  }
485  return (1);
486  } else if (val2 != NULL) {
487  if (strcasecmp("header", key) == 0) {
488  rem->phead = s_strtolirc_t(val);
489  rem->shead = s_strtolirc_t(val2);
490  return (2);
491  } else if (strcasecmp("three", key) == 0) {
492  rem->pthree = s_strtolirc_t(val);
493  rem->sthree = s_strtolirc_t(val2);
494  return (2);
495  } else if (strcasecmp("two", key) == 0) {
496  rem->ptwo = s_strtolirc_t(val);
497  rem->stwo = s_strtolirc_t(val2);
498  return (2);
499  } else if (strcasecmp("one", key) == 0) {
500  rem->pone = s_strtolirc_t(val);
501  rem->sone = s_strtolirc_t(val2);
502  return (2);
503  } else if (strcasecmp("zero", key) == 0) {
504  rem->pzero = s_strtolirc_t(val);
505  rem->szero = s_strtolirc_t(val2);
506  return (2);
507  } else if (strcasecmp("foot", key) == 0) {
508  rem->pfoot = s_strtolirc_t(val);
509  rem->sfoot = s_strtolirc_t(val2);
510  return (2);
511  } else if (strcasecmp("repeat", key) == 0) {
512  rem->prepeat = s_strtolirc_t(val);
513  rem->srepeat = s_strtolirc_t(val2);
514  return (2);
515  } else if (strcasecmp("pre", key) == 0) {
516  rem->pre_p = s_strtolirc_t(val);
517  rem->pre_s = s_strtolirc_t(val2);
518  return (2);
519  } else if (strcasecmp("post", key) == 0) {
520  rem->post_p = s_strtolirc_t(val);
521  rem->post_s = s_strtolirc_t(val2);
522  return (2);
523  }
524  }
525  if (val2) {
526  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
527  logprintf(LIRC_ERROR, "unknown definiton: \"%s %s %s\"", key, val, val2);
528  } else {
529  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
530  logprintf(LIRC_ERROR, "unknown definiton or too few arguments: \"%s %s\"", key, val);
531  }
532  parse_error = 1;
533  return (0);
534 }
535 
536 static int sanityChecks(struct ir_remote *rem)
537 {
538  struct ir_ncode *codes;
539  struct ir_code_node *node;
540 
541  if (!rem->name) {
542  logprintf(LIRC_ERROR, "you must specify a remote name");
543  return 0;
544  }
545  if (rem->gap == 0) {
546  logprintf(LIRC_WARNING,
547  "%s: you should specify a valid gap value",
548  rem->name);
549  }
550  if (has_repeat_gap(rem) && is_const(rem)) {
551  logprintf(LIRC_WARNING,
552  "%s: repeat_gap will be ignored if CONST_LENGTH flag is set",
553  rem->name);
554  }
555 
556  if (is_raw(rem))
557  return 1;
558 
559  if ((rem->pre_data & gen_mask(rem->pre_data_bits)) != rem->pre_data) {
560  logprintf(LIRC_WARNING, "invalid pre_data found for %s", rem->name);
561  rem->pre_data &= gen_mask(rem->pre_data_bits);
562  }
563  if ((rem->post_data & gen_mask(rem->post_data_bits)) != rem->post_data) {
564  logprintf(LIRC_WARNING, "invalid post_data found for %s", rem->name);
565  rem->post_data &= gen_mask(rem->post_data_bits);
566  }
567  for (codes = rem->codes; codes->name != NULL; codes++) {
568  if ((codes->code & gen_mask(rem->bits)) != codes->code) {
569  logprintf(LIRC_WARNING, "invalid code found for %s: %s", rem->name, codes->name);
570  codes->code &= gen_mask(rem->bits);
571  }
572  for (node = codes->next; node != NULL; node = node->next) {
573  if ((node->code & gen_mask(rem->bits)) != node->code) {
574  logprintf(LIRC_WARNING, "invalid code found for %s: %s", rem->name, codes->name);
575  node->code &= gen_mask(rem->bits);
576  }
577  }
578  }
579 
580  return 1;
581 }
582 
589 static int remote_bits_cmp(struct ir_remote* r1, struct ir_remote* r2)
590 {
591  int r1_size;
592  int r2_size;
593  struct ir_ncode* c;
594 
595  int r1_is_raw = is_raw(r1);
596  int r2_is_raw = is_raw(r2);
597 
598  if (!r1_is_raw && r2_is_raw) return -1;
599  if (r1_is_raw && !r2_is_raw) return 1;
600 
601  if (r1_is_raw && r2_is_raw){
602  for (c = r1->codes, r1_size = 0; c->name != NULL; c++)
603  r1_size += 1;
604  for (c = r2->codes, r2_size = 0; c->name != NULL; c++)
605  r2_size += 1;
606  } else {
607  r1_size = bit_count(r1);
608  r2_size = bit_count(r2);
609  }
610  if (r1_size == r2_size) return 0;
611  return r1_size < r2_size ? -1 : 1;
612 }
613 
614 
619 static struct ir_remote *sort_by_bit_count(struct ir_remote *remotes)
620 {
621 
622  struct ir_remote *top, *rem, *next, *prev, *scan, *r;
623 
624  for (r = remotes; r != NULL && r != (void*)-1; r = r->next) {
625  if (r->manual_sort) {
626  return remotes;
627  }
628  }
629  rem = remotes;
630  top = NULL;
631  while (rem != NULL && rem != (void*)-1) {
632  next = rem->next;
633 
634  scan = top;
635  prev = NULL;
636  while (scan && remote_bits_cmp(scan, rem) <= 0) {
637  prev = scan;
638  scan = scan->next;
639  }
640  if (prev) {
641  prev->next = rem;
642  } else {
643  top = rem;
644  }
645  if (scan) {
646  rem->next = scan;
647  } else {
648  rem->next = NULL;
649  }
650 
651  rem = next;
652  }
653 
654  return top;
655 }
656 
657 static const char *lirc_parse_include(char *s)
658 {
659  char *last;
660  size_t len;
661 
662  len = strlen(s);
663  if (len < 2) {
664  return NULL;
665  }
666  last = s + len - 1;
667  while (last > s && strchr(whitespace, *last) != NULL) {
668  last--;
669  }
670  if (last <= s) {
671  return NULL;
672  }
673  if (*s != '"' && *s != '<') {
674  return NULL;
675  }
676  if (*s == '"' && *last != '"') {
677  return NULL;
678  } else if (*s == '<' && *last != '>') {
679  return NULL;
680  }
681  *last = 0;
682  memmove(s, s + 1, len - 2 + 1); /* terminating 0 is copied, and
683  maybe more, but we don't care */
684  return s;
685 }
686 
687 
689 static const char *lirc_parse_relative(char *dst,
690  size_t dst_size,
691  const char *child,
692  const char *current)
693 {
694  char *dir;
695  size_t dirlen;
696 
697  if (!current)
698  return child;
699 
700  /* Not a relative path */
701  if (*child == '/')
702  return child;
703 
704  if (strlen(current) >= dst_size) {
705  return NULL;
706  }
707  strcpy(dst, current);
708  dir = dirname(dst);
709  dirlen = strlen(dir);
710  if (dir != dst) {
711  memmove(dst, dir, dirlen + 1);
712  }
713 
714  if (dirlen + 1 + strlen(child) + 1 > dst_size) {
715  return NULL;
716  }
717  strcat(dst, "/");
718  strcat(dst, child);
719 
720  return dst;
721 }
722 
723 
725 static struct ir_remote*
726 ir_remotes_append(struct ir_remote* root, struct ir_remote* what)
727 {
728  struct ir_remote* r;
729 
730  if (root == (struct ir_remote*)-1)
731  root = NULL;
732  if (what == (struct ir_remote*)-1)
733  what = NULL;
734  if (root == NULL && what != NULL)
735  return what;
736  if (what == NULL)
737  return root;
738  for (r = root; r->next != NULL; r = r->next)
739  ;
740  r->next = what;
741  what->next = NULL;
742  return root;
743 }
744 
745 
746 struct ir_remote* read_config(FILE * f, const char *name)
747 {
748  struct ir_remote* head;
749 
750  head = read_config_recursive(f, name, 0);
751  head = sort_by_bit_count(head);
752  return head;
753 }
754 
755 
766 static struct ir_remote*
767 read_included(const char* name, int depth, char* val, struct ir_remote* top_rem)
768 {
769  FILE *childFile;
770  const char *childName;
771  struct ir_remote* rem = NULL;
772 
773  if (depth > MAX_INCLUDES) {
774  logprintf(LIRC_ERROR, "error opening child file defined at %s:%d", name, line);
775  logprintf(LIRC_ERROR, "too many files included");
776  return top_rem;
777  }
778  childName = lirc_parse_include(val);
779  if (!childName) {
780  logprintf(LIRC_ERROR, "error parsing child file value defined at line %d:", line);
781  logprintf(LIRC_ERROR, "invalid quoting");
782  return top_rem;
783  }
784  childFile = fopen(childName, "r");
785  if (childFile == NULL) {
786  logprintf(LIRC_ERROR, "error opening child file '%s' defined at line %d:",
787  childName, line);
788  logprintf(LIRC_ERROR, "ignoring this child file for now.");
789  return NULL;
790  } else {
791  rem = read_config_recursive(childFile, childName, depth + 1);
792  top_rem = ir_remotes_append(top_rem, rem);
793  }
794  fclose(childFile);
795  return top_rem;
796 }
797 
798 
809 static struct ir_remote* read_all_included(const char* name,
810  int depth,
811  char* val,
812  struct ir_remote* top_rem)
813 {
814  int i;
815  glob_t globbuf;
816  char buff[256] = {'\0'};
817 
818  memset(&globbuf, 0, sizeof(globbuf));
819  val = val + 1; // Strip quotes
820  val[strlen(val) - 1] = '\0';
821  lirc_parse_relative(buff, sizeof(buff), val, name);
822  glob(buff, 0, NULL, &globbuf);
823  for (i = 0; i < globbuf.gl_pathc; i +=1) {
824  snprintf(buff, sizeof(buff), "\"%s\"", globbuf.gl_pathv[i]);
825  top_rem = read_included(name, depth, buff, top_rem);
826  }
827  globfree(&globbuf);
828  return top_rem;
829 }
830 
831 static struct ir_remote*
832 read_config_recursive(FILE * f, const char *name, int depth)
833 {
834  char buf[LINE_LEN + 1], *key, *val, *val2;
835  int len, argc;
836  struct ir_remote *top_rem = NULL, *rem = NULL;
837  struct void_array codes_list, raw_codes, signals;
838  struct ir_ncode raw_code = { NULL, 0, 0, NULL };
839  struct ir_ncode name_code = { NULL, 0, 0, NULL };
840  struct ir_ncode *code;
841  int mode = ID_none;
842 
843  line = 0;
844  parse_error = 0;
845  LOGPRINTF(2, "parsing '%s'", name);
846 
847  while (fgets(buf, LINE_LEN, f) != NULL) {
848  line++;
849  len = strlen(buf);
850  if (len == LINE_LEN && buf[len - 1] != '\n') {
851  logprintf(LIRC_ERROR, "line %d too long in config file", line);
852  parse_error = 1;
853  break;
854  }
855 
856  if (len > 0) {
857  len--;
858  if (buf[len] == '\n')
859  buf[len] = 0;
860  }
861  if (len > 0) {
862  len--;
863  if (buf[len] == '\r')
864  buf[len] = 0;
865  }
866  /* ignore comments */
867  if (buf[0] == '#') {
868  continue;
869  }
870  key = strtok(buf, whitespace);
871  /* ignore empty lines */
872  if (key == NULL)
873  continue;
874  val = strtok(NULL, whitespace);
875  if (val != NULL) {
876  val2 = strtok(NULL, whitespace);
877  LOGPRINTF(3, "Tokens: \"%s\" \"%s\" \"%s\"", key, val, (val2 == NULL ? "(null)" : val));
878  if (strcasecmp("include", key) == 0) {
879  int save_line = line;
880  top_rem = read_all_included(name,
881  depth,
882  val,
883  top_rem);
884  line = save_line;
885  } else if (strcasecmp("begin", key) == 0) {
886  if (strcasecmp("codes", val) == 0) {
887  /* init codes mode */
888  LOGPRINTF(2, " begin codes");
889  if (!checkMode(mode, ID_remote, "begin codes"))
890  break;
891  if (rem->codes) {
892  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
893  logprintf(LIRC_ERROR, "codes are already defined");
894  parse_error = 1;
895  break;
896  }
897 
898  init_void_array(&codes_list, 30, sizeof(struct ir_ncode));
899  mode = ID_codes;
900  } else if (strcasecmp("raw_codes", val) == 0) {
901  /* init raw_codes mode */
902  LOGPRINTF(2, " begin raw_codes");
903  if (!checkMode(mode, ID_remote, "begin raw_codes"))
904  break;
905  if (rem->codes) {
906  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
907  logprintf(LIRC_ERROR, "codes are already defined");
908  parse_error = 1;
909  break;
910  }
911  set_protocol(rem, RAW_CODES);
912  raw_code.code = 0;
913  init_void_array(&raw_codes, 30, sizeof(struct ir_ncode));
914  mode = ID_raw_codes;
915  } else if (strcasecmp("remote", val) == 0) {
916  /* create new remote */
917  LOGPRINTF(1, "parsing remote");
918  if (!checkMode(mode, ID_none, "begin remote"))
919  break;
920  mode = ID_remote;
921  if (!top_rem) {
922  /* create first remote */
923  LOGPRINTF(2, "creating first remote");
924  rem = top_rem = s_malloc(sizeof(struct ir_remote));
925  } else {
926  /* create new remote */
927  LOGPRINTF(2, "creating next remote");
928  rem = s_malloc(sizeof(struct ir_remote));
929  ir_remotes_append(top_rem, rem);
930  }
931 
932  } else if (mode == ID_codes) {
933  code = defineCode(key, val, &name_code);
934  while (!parse_error && val2 != NULL) {
935  if (val2[0] == '#')
936  break; /* comment */
937  defineNode(code, val2);
938  val2 = strtok(NULL, whitespace);
939  }
940  code->current = NULL;
941  add_void_array(&codes_list, code);
942  } else {
943  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
944  logprintf(LIRC_ERROR, "unknown section \"%s\"", val);
945  parse_error = 1;
946  }
947  if (!parse_error && val2 != NULL) {
948  logprintf(LIRC_WARNING,
949  "%s: garbage after '%s' token "
950  "in line %d ignored",
951  rem->name, val, line);
952  }
953  } else if (strcasecmp("end", key) == 0) {
954 
955  if (strcasecmp("codes", val) == 0) {
956  /* end Codes mode */
957  LOGPRINTF(2, " end codes");
958  if (!checkMode(mode, ID_codes, "end codes"))
959  break;
960  rem->codes = get_void_array(&codes_list);
961  mode = ID_remote; /* switch back */
962 
963  } else if (strcasecmp("raw_codes", val) == 0) {
964  /* end raw codes mode */
965  LOGPRINTF(2, " end raw_codes");
966 
967  if (mode == ID_raw_name) {
968  raw_code.signals = get_void_array(&signals);
969  raw_code.length = signals.nr_items;
970  if (raw_code.length % 2 == 0) {
971  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
972  logprintf(LIRC_ERROR, "bad signal length");
973  parse_error = 1;
974  }
975  if (!add_void_array(&raw_codes, &raw_code))
976  break;
977  mode = ID_raw_codes;
978  }
979  if (!checkMode(mode, ID_raw_codes, "end raw_codes"))
980  break;
981  rem->codes = get_void_array(&raw_codes);
982  mode = ID_remote; /* switch back */
983  } else if (strcasecmp("remote", val) == 0) {
984  /* end remote mode */
985  LOGPRINTF(2, "end remote");
986  /* print_remote(rem); */
987  if (!checkMode(mode, ID_remote, "end remote"))
988  break;
989  if (!sanityChecks(rem)) {
990  parse_error = 1;
991  break;
992  }
993  if (options_getboolean("lircd:dynamic-codes")) {
994  if (rem->dyncodes_name == NULL) {
995  rem->dyncodes_name = s_strdup("unknown");
996  }
997  rem->dyncodes[0].name = rem->dyncodes_name;
998  rem->dyncodes[1].name = rem->dyncodes_name;
999  }
1000  /* not really necessary because we
1001  clear the alloced memory */
1002  rem->next = NULL;
1003  rem->last_code = NULL;
1004  mode = ID_none; /* switch back */
1005  } else if (mode == ID_codes) {
1006  code = defineCode(key, val, &name_code);
1007  while (!parse_error && val2 != NULL) {
1008  if (val2[0] == '#')
1009  break; /* comment */
1010  defineNode(code, val2);
1011  val2 = strtok(NULL, whitespace);
1012  }
1013  code->current = NULL;
1014  add_void_array(&codes_list, code);
1015  } else {
1016  logprintf(LIRC_ERROR, "error in configfile line %d:", line);
1017  logprintf(LIRC_ERROR, "unknown section %s", val);
1018  parse_error = 1;
1019  }
1020  if (!parse_error && val2 != NULL) {
1021  logprintf(LIRC_WARNING,
1022  "%s: garbage after '%s'"
1023  " token in line %d ignored",
1024  rem->name, val, line);
1025  }
1026  } else {
1027  switch (mode) {
1028  case ID_remote:
1029  argc = defineRemote(key, val, val2, rem);
1030  if (!parse_error
1031  && ((argc == 1 && val2 != NULL)
1032  || (argc == 2 && val2 != NULL && strtok(NULL, whitespace) != NULL))) {
1033  logprintf(LIRC_WARNING,
1034  "%s: garbage after '%s'"
1035  " token in line %d ignored",
1036  rem->name, key, line);
1037  }
1038  break;
1039  case ID_codes:
1040  code = defineCode(key, val, &name_code);
1041  while (!parse_error && val2 != NULL) {
1042  if (val2[0] == '#')
1043  break; /* comment */
1044  defineNode(code, val2);
1045  val2 = strtok(NULL, whitespace);
1046  }
1047  code->current = NULL;
1048  add_void_array(&codes_list, code);
1049  break;
1050  case ID_raw_codes:
1051  case ID_raw_name:
1052  if (strcasecmp("name", key) == 0) {
1053  LOGPRINTF(3, "Button: \"%s\"", val);
1054  if (mode == ID_raw_name) {
1055  raw_code.signals = get_void_array(&signals);
1056  raw_code.length = signals.nr_items;
1057  if (raw_code.length % 2 == 0) {
1058  logprintf(LIRC_ERROR, "error in configfile line %d:",
1059  line);
1060  logprintf(LIRC_ERROR, "bad signal length");
1061  parse_error = 1;
1062  }
1063  if (!add_void_array(&raw_codes, &raw_code))
1064  break;
1065  }
1066  if (!(raw_code.name = s_strdup(val))) {
1067  break;
1068  }
1069  raw_code.code++;
1070  init_void_array(&signals, 50, sizeof(lirc_t));
1071  mode = ID_raw_name;
1072  if (!parse_error && val2 != NULL) {
1073  logprintf(LIRC_WARNING,
1074  "%s: garbage after '%s'"
1075  " token in line %d ignored",
1076  rem->name, key, line);
1077  }
1078  } else {
1079  if (mode == ID_raw_codes) {
1080  logprintf(LIRC_ERROR, "no name for signal defined at line %d",
1081  line);
1082  parse_error = 1;
1083  break;
1084  }
1085  if (!addSignal(&signals, key))
1086  break;
1087  if (!addSignal(&signals, val))
1088  break;
1089  if (val2) {
1090  if (!addSignal(&signals, val2)) {
1091  break;
1092  }
1093  }
1094  while ((val = strtok(NULL, whitespace))) {
1095  if (!addSignal(&signals, val))
1096  break;
1097  }
1098  }
1099  break;
1100  }
1101  }
1102  } else if (mode == ID_raw_name) {
1103  if (!addSignal(&signals, key)) {
1104  break;
1105  }
1106  } else {
1107  logprintf(LIRC_ERROR, "error in configfile line %d", line);
1108  parse_error = 1;
1109  break;
1110  }
1111  if (parse_error) {
1112  break;
1113  }
1114  }
1115  if (mode != ID_none) {
1116  switch (mode) {
1117  case ID_raw_name:
1118  if (raw_code.name != NULL) {
1119  free(raw_code.name);
1120  if (get_void_array(&signals) != NULL)
1121  free(get_void_array(&signals));
1122  }
1123  case ID_raw_codes:
1124  rem->codes = get_void_array(&raw_codes);
1125  break;
1126  case ID_codes:
1127  rem->codes = get_void_array(&codes_list);
1128  break;
1129  }
1130  if (!parse_error) {
1131  logprintf(LIRC_ERROR, "unexpected end of file");
1132  parse_error = 1;
1133  }
1134  }
1135  if (parse_error) {
1136  static int print_error = 1;
1137 
1138  if (print_error) {
1139  logprintf(LIRC_ERROR, "reading of file '%s' failed", name);
1140  print_error = 0;
1141  }
1142  free_config(top_rem);
1143  if (depth == 0)
1144  print_error = 1;
1145  return ((void *)-1);
1146  }
1147  /* kick reverse flag */
1148  /* handle RC6 flag to be backwards compatible: previous RC-6
1149  config files did not set rc6_mask */
1150  rem = top_rem;
1151  while (rem != NULL) {
1152  if ((!is_raw(rem)) && rem->flags & REVERSE) {
1153  struct ir_ncode *codes;
1154 
1155  if (has_pre(rem)) {
1156  rem->pre_data = reverse(rem->pre_data, rem->pre_data_bits);
1157  }
1158  if (has_post(rem)) {
1159  rem->post_data = reverse(rem->post_data, rem->post_data_bits);
1160  }
1161  codes = rem->codes;
1162  while (codes->name != NULL) {
1163  codes->code = reverse(codes->code, rem->bits);
1164  codes++;
1165  }
1166  rem->flags = rem->flags & (~REVERSE);
1167  rem->flags = rem->flags | COMPAT_REVERSE;
1168  /* don't delete the flag because we still need
1169  it to remain compatible with older versions
1170  */
1171  }
1172  if (rem->flags & RC6 && rem->rc6_mask == 0 && rem->toggle_bit > 0) {
1173  int all_bits = bit_count(rem);
1174 
1175  rem->rc6_mask = ((ir_code) 1) << (all_bits - rem->toggle_bit);
1176  }
1177  if (rem->toggle_bit > 0) {
1178  int all_bits = bit_count(rem);
1179 
1180  if (has_toggle_bit_mask(rem)) {
1181  logprintf(LIRC_WARNING, "%s uses both toggle_bit and toggle_bit_mask", rem->name);
1182  } else {
1183  rem->toggle_bit_mask = ((ir_code) 1) << (all_bits - rem->toggle_bit);
1184  }
1185  rem->toggle_bit = 0;
1186  }
1187  if (has_toggle_bit_mask(rem)) {
1188  if (!is_raw(rem) && rem->codes) {
1189  rem->toggle_bit_mask_state = (rem->codes->code & rem->toggle_bit_mask);
1190  if (rem->toggle_bit_mask_state) {
1191  /* start with state set to 0 for backwards compatibility */
1192  rem->toggle_bit_mask_state ^= rem->toggle_bit_mask;
1193  }
1194  }
1195  }
1196  if (is_serial(rem)) {
1197  lirc_t base;
1198 
1199  if (rem->baud > 0) {
1200  base = 1000000 / rem->baud;
1201  if (rem->pzero == 0 && rem->szero == 0) {
1202  rem->pzero = base;
1203  }
1204  if (rem->pone == 0 && rem->sone == 0) {
1205  rem->sone = base;
1206  }
1207  }
1208  if (rem->bits_in_byte == 0) {
1209  rem->bits_in_byte = 8;
1210  }
1211  }
1212  if (rem->min_code_repeat > 0) {
1213  if (!has_repeat(rem) || rem->min_code_repeat > rem->min_repeat) {
1214  logprintf(LIRC_WARNING, "invalid min_code_repeat value");
1215  rem->min_code_repeat = 0;
1216  }
1217  }
1218  calculate_signal_lengths(rem);
1219  rem = rem->next;
1220  }
1221 
1222  return (top_rem);
1223 }
1224 
1225 void calculate_signal_lengths(struct ir_remote *remote)
1226 {
1227  if (is_const(remote)) {
1228  remote->min_total_signal_length = min_gap(remote);
1229  remote->max_total_signal_length = max_gap(remote);
1230  } else {
1231  remote->min_gap_length = min_gap(remote);
1232  remote->max_gap_length = max_gap(remote);
1233  }
1234 
1235  lirc_t min_signal_length = 0, max_signal_length = 0;
1236  lirc_t max_pulse = 0, max_space = 0;
1237  int first_sum = 1;
1238  struct ir_ncode *c = remote->codes;
1239  int i;
1240 
1241  while (c->name) {
1242  struct ir_ncode code = *c;
1243  struct ir_code_node *next = code.next;
1244  int first = 1;
1245  int repeat = 0;
1246  do {
1247  if (first) {
1248  first = 0;
1249  } else {
1250  code.code = next->code;
1251  next = next->next;
1252  }
1253  for (repeat = 0; repeat < 2; repeat++) {
1254  if (init_sim(remote, &code, repeat)) {
1255  lirc_t sum = send_buffer_sum();
1256 
1257  if (sum) {
1258  if (first_sum || sum < min_signal_length) {
1259  min_signal_length = sum;
1260  }
1261  if (first_sum || sum > max_signal_length) {
1262  max_signal_length = sum;
1263  }
1264  first_sum = 0;
1265  }
1266  for (i = 0; i < send_buffer_length(); i++) {
1267  if (i & 1) { /* space */
1268  if (send_buffer_data()[i] > max_space) {
1269  max_space = send_buffer_data()[i];
1270  }
1271  } else { /* pulse */
1272 
1273  if (send_buffer_data()[i] > max_pulse) {
1274  max_pulse = send_buffer_data()[i];
1275  }
1276  }
1277  }
1278  }
1279  }
1280  } while (next);
1281  c++;
1282  }
1283  if (first_sum) {
1284  /* no timing data, so assume gap is the actual total
1285  length */
1286  remote->min_total_signal_length = min_gap(remote);
1287  remote->max_total_signal_length = max_gap(remote);
1288  remote->min_gap_length = min_gap(remote);
1289  remote->max_gap_length = max_gap(remote);
1290  } else if (is_const(remote)) {
1291  if (remote->min_total_signal_length > max_signal_length) {
1292  remote->min_gap_length = remote->min_total_signal_length - max_signal_length;
1293  } else {
1294  logprintf(LIRC_WARNING,
1295  "min_gap_length is 0 for '%s' remote",
1296  remote->name);
1297  remote->min_gap_length = 0;
1298  }
1299  if (remote->max_total_signal_length > min_signal_length) {
1300  remote->max_gap_length = remote->max_total_signal_length - min_signal_length;
1301  } else {
1302  logprintf(LIRC_WARNING, "max_gap_length is 0 for '%s' remote", remote->name);
1303  remote->max_gap_length = 0;
1304  }
1305  } else {
1306  remote->min_total_signal_length = min_signal_length + remote->min_gap_length;
1307  remote->max_total_signal_length = max_signal_length + remote->max_gap_length;
1308  }
1309  LOGPRINTF(1, "lengths: %lu %lu %lu %lu", remote->min_total_signal_length, remote->max_total_signal_length,
1310  remote->min_gap_length, remote->max_gap_length);
1311 }
1312 
1313 void free_config(struct ir_remote *remotes)
1314 {
1315  struct ir_remote *next;
1316  struct ir_ncode *codes;
1317 
1318  while (remotes != NULL) {
1319  next = remotes->next;
1320 
1321  if (remotes->dyncodes_name != NULL)
1322  free(remotes->dyncodes_name);
1323  if (remotes->name != NULL)
1324  free((void*)(remotes->name));
1325  if (remotes->codes != NULL) {
1326  codes = remotes->codes;
1327  while (codes->name != NULL) {
1328  struct ir_code_node *node, *next_node;
1329 
1330  free(codes->name);
1331  if (codes->signals != NULL)
1332  free(codes->signals);
1333  node = codes->next;
1334  while (node) {
1335  next_node = node->next;
1336  free(node);
1337  node = next_node;
1338  }
1339  codes++;
1340  }
1341  free(remotes->codes);
1342  }
1343  free(remotes);
1344  remotes = next;
1345  }
1346 }
lirc_t min_total_signal_length
#define NO_FOOT_REP
#define RC6
unsigned int freq
lirc_t max_gap_length
#define GOLDSTAR
lirc_t max_total_signal_length
ir_code post_data
ir_code repeat_mask
struct ir_code_node * next
unsigned int baud
const char * name
#define SPACE_ENC
void free_config(struct ir_remote *remotes)
Definition: config_file.c:1313
lirc_t * signals
lirc_t send_buffer_sum()
Definition: transmit.c:390
#define COMPAT_REVERSE
unsigned int parity
__u64 ir_code
lirc_t min_gap_length
char * name
int send_buffer_length()
Definition: transmit.c:379
struct ir_code_node * current
unsigned int duty_cycle
#define RCMM
ir_code toggle_mask
ir_code pre_data
#define RC5
char * dyncodes_name
#define REPEAT_HEADER
#define SPACE_FIRST
const lirc_t * send_buffer_data()
Definition: transmit.c:385
__u32 repeat_gap
#define CONST_LENGTH
#define NO_HEAD_REP
unsigned int stop_bits
#define GRUNDIG
#define LOGPRINTF(level, fmt, args...)
Definition: lirc_log.h:76
lirc_t srepeat
#define SERIAL
#define SHIFT_ENC
#define BO
ir_code code
const char * driver
unsigned int min_code_repeat
const struct flaglist all_flags[]
Definition: config_file.c:87
char * name
Definition: config_flags.h:15
ir_code rc6_mask
ir_code toggle_bit_mask
#define RAW_CODES
struct ir_remote * read_config(FILE *f, const char *name)
Definition: config_file.c:746
ir_code ignore_mask
#define XMP
unsigned int bits_in_byte