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