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