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