1 /* $Id: lirc_client.c,v 5.27 2008/05/20 18:54:37 lirc Exp $ */
3 /****************************************************************************
4 ** lirc_client.c ***********************************************************
5 ****************************************************************************
7 * lirc_client - common routines for lircd clients
9 * Copyright (C) 1998 Trent Piepho <xyzzy@u.washington.edu>
10 * Copyright (C) 1998 Christoph Bartelmus <lirc@bartelmus.de>
12 * System wide LIRCRC support by Michal Svec <rebel@atrey.karlin.mff.cuni.cz>
26 #include <sys/socket.h>
29 #include <sys/types.h>
32 #include "lirc_client.h"
35 /* internal defines */
36 #define MAX_INCLUDES 10
38 #define LIRC_PACKET_SIZE 255
40 #define LIRC_TIMEOUT 3
42 /* internal data structures */
47 struct filestack_t
*parent
;
61 /* internal functions */
62 static void lirc_printf(char *format_str
, ...);
63 static void lirc_perror(const char *s
);
64 static int lirc_readline(char **line
,FILE *f
);
65 static char *lirc_trim(char *s
);
66 static char lirc_parse_escape(char **s
,const char *name
,int line
);
67 static void lirc_parse_string(char *s
,const char *name
,int line
);
68 static void lirc_parse_include(char *s
,const char *name
,int line
);
69 static int lirc_mode(char *token
,char *token2
,char **mode
,
70 struct lirc_config_entry
**new_config
,
71 struct lirc_config_entry
**first_config
,
72 struct lirc_config_entry
**last_config
,
74 const char *name
,int line
);
76 lircrc_config relies on this function, hence don't make it static
77 but it's not part of the official interface, so there's no guarantee
78 that it will stay available in the future
80 unsigned int lirc_flags(char *string
);
81 static char *lirc_getfilename(const char *file
, const char *current_file
);
82 static FILE *lirc_open(const char *file
, const char *current_file
,
84 static struct filestack_t
*stack_push(struct filestack_t
*parent
);
85 static struct filestack_t
*stack_pop(struct filestack_t
*entry
);
86 static void stack_free(struct filestack_t
*entry
);
87 static int lirc_readconfig_only_internal(char *file
,
88 struct lirc_config
**config
,
92 static char *lirc_startupmode(struct lirc_config_entry
*first
);
93 static void lirc_freeconfigentries(struct lirc_config_entry
*first
);
94 static void lirc_clearmode(struct lirc_config
*config
);
95 static char *lirc_execute(struct lirc_config
*config
,
96 struct lirc_config_entry
*scan
);
97 static int lirc_iscode(struct lirc_config_entry
*scan
, char *remote
,
98 char *button
,int rep
);
99 static int lirc_code2char_internal(struct lirc_config
*config
,char *code
,
100 char **string
, char **prog
);
101 static const char *lirc_read_string(int fd
);
102 static int lirc_identify(int sockfd
);
104 static int lirc_send_command(int sockfd
, const char *command
, char *buf
, size_t *buf_len
, int *ret_status
);
106 static int lirc_lircd
;
107 static int lirc_verbose
=0;
108 static char *lirc_prog
=NULL
;
109 static char *lirc_buffer
=NULL
;
111 static void lirc_printf(char *format_str
, ...)
115 if(!lirc_verbose
) return;
117 va_start(ap
,format_str
);
118 vfprintf(stderr
,format_str
,ap
);
122 static void lirc_perror(const char *s
)
124 if(!lirc_verbose
) return;
129 int lirc_init(char *prog
,int verbose
)
131 struct sockaddr_un addr
;
133 /* connect to lircd */
135 if(prog
==NULL
|| lirc_prog
!=NULL
) return(-1);
136 lirc_prog
=strdup(prog
);
137 lirc_verbose
=verbose
;
140 lirc_printf("%s: out of memory\n",prog
);
144 addr
.sun_family
=AF_UNIX
;
145 strcpy(addr
.sun_path
,LIRCD
);
146 lirc_lircd
=socket(AF_UNIX
,SOCK_STREAM
,0);
149 lirc_printf("%s: could not open socket\n",lirc_prog
);
150 lirc_perror(lirc_prog
);
155 if(connect(lirc_lircd
,(struct sockaddr
*)&addr
,sizeof(addr
))==-1)
158 lirc_printf("%s: could not connect to socket\n",lirc_prog
);
159 lirc_perror(lirc_prog
);
167 int lirc_deinit(void)
174 if(lirc_buffer
!=NULL
)
179 return(close(lirc_lircd
));
182 static int lirc_readline(char **line
,FILE *f
)
184 char *newline
,*ret
,*enlargeline
;
187 newline
=(char *) malloc(LIRC_READ
+1);
190 lirc_printf("%s: out of memory\n",lirc_prog
);
196 ret
=fgets(newline
+len
,LIRC_READ
+1,f
);
211 if(newline
[len
-1]=='\n')
218 enlargeline
=(char *) realloc(newline
,len
+1+LIRC_READ
);
219 if(enlargeline
==NULL
)
222 lirc_printf("%s: out of memory\n",lirc_prog
);
229 static char *lirc_trim(char *s
)
233 while(s
[0]==' ' || s
[0]=='\t') s
++;
238 if(s
[len
]==' ' || s
[len
]=='\t') s
[len
]=0;
244 /* parse standard C escape sequences + \@,\A-\Z is ^@,^A-^Z */
246 static char lirc_parse_escape(char **s
,const char *name
,int line
)
250 unsigned int i
,overflow
,count
;
251 int digits_found
,digit
;
263 case 'E': /* this should become ^E */
305 if(i
>(1<<CHAR_BIT
)-1)
308 lirc_printf("%s: octal escape sequence "
309 "out of range in %s:%d\n",lirc_prog
,
323 else if(c
>='a' && c
<='f')
325 else if(c
>='A' && c
<='F')
332 overflow
|=i
^(i
<<4>>4);
338 lirc_printf("%s: \\x used with no "
339 "following hex digits in %s:%d\n",
340 lirc_prog
,name
,line
);
342 if(overflow
|| i
>(1<<CHAR_BIT
)-1)
345 lirc_printf("%s: hex escape sequence out "
346 "of range in %s:%d\n",
347 lirc_prog
,name
,line
);
352 if(c
>='@' && c
<='Z') return(c
-'@');
357 static void lirc_parse_string(char *s
,const char *name
,int line
)
367 *t
=lirc_parse_escape(&s
,name
,line
);
380 static void lirc_parse_include(char *s
,const char *name
,int line
)
391 if(*s
!='"' && *s
!='<')
395 if(*s
=='"' && last
!='"')
399 else if(*s
=='<' && last
!='>')
404 memmove(s
, s
+1, len
-2+1); /* terminating 0 is copied */
407 int lirc_mode(char *token
,char *token2
,char **mode
,
408 struct lirc_config_entry
**new_config
,
409 struct lirc_config_entry
**first_config
,
410 struct lirc_config_entry
**last_config
,
411 int (check
)(char *s
),
412 const char *name
,int line
)
414 struct lirc_config_entry
*new_entry
;
416 new_entry
=*new_config
;
417 if(strcasecmp(token
,"begin")==0)
423 new_entry
=(struct lirc_config_entry
*)
424 malloc(sizeof(struct lirc_config_entry
));
427 lirc_printf("%s: out of memory\n",
433 new_entry
->prog
=NULL
;
434 new_entry
->code
=NULL
;
435 new_entry
->rep_delay
=0;
437 new_entry
->config
=NULL
;
438 new_entry
->change_mode
=NULL
;
439 new_entry
->flags
=none
;
440 new_entry
->mode
=NULL
;
441 new_entry
->next_config
=NULL
;
442 new_entry
->next_code
=NULL
;
443 new_entry
->next
=NULL
;
445 *new_config
=new_entry
;
450 lirc_printf("%s: bad file format, "
451 "%s:%d\n",lirc_prog
,name
,line
);
457 if(new_entry
==NULL
&& *mode
==NULL
)
459 *mode
=strdup(token2
);
467 lirc_printf("%s: bad file format, "
468 "%s:%d\n",lirc_prog
,name
,line
);
473 else if(strcasecmp(token
,"end")==0)
480 if(new_entry
->prog
==NULL
)
482 lirc_printf("%s: prog missing in "
483 "config before line %d\n",
485 lirc_freeconfigentries(new_entry
);
489 if(strcasecmp(new_entry
->prog
,lirc_prog
)!=0)
491 lirc_freeconfigentries(new_entry
);
496 new_entry
->next_code
=new_entry
->code
;
497 new_entry
->next_config
=new_entry
->config
;
498 if(*last_config
==NULL
)
500 *first_config
=new_entry
;
501 *last_config
=new_entry
;
505 (*last_config
)->next
=new_entry
;
506 *last_config
=new_entry
;
512 new_entry
->mode
=strdup(*mode
);
513 if(new_entry
->mode
==NULL
)
515 lirc_printf("%s: out of "
523 new_entry
->prog
!=NULL
&&
524 strcasecmp(new_entry
->prog
,lirc_prog
)==0)
526 struct lirc_list
*list
;
528 list
=new_entry
->config
;
531 if(check(list
->string
)==-1)
539 if (new_entry
->rep_delay
==0 &&
542 new_entry
->rep_delay
=new_entry
->rep
-1;
547 lirc_printf("%s: %s:%d: 'end' without "
548 "'begin'\n",lirc_prog
,name
,line
);
558 lirc_printf("%s: %s:%d: missing "
559 "'end' token\n",lirc_prog
,
563 if(strcasecmp(*mode
,token2
)==0)
570 lirc_printf("%s: \"%s\" doesn't "
571 "match mode \"%s\"\n",
572 lirc_prog
,token2
,*mode
);
578 lirc_printf("%s: %s:%d: 'end %s' without "
579 "'begin'\n",lirc_prog
,name
,line
,
587 lirc_printf("%s: unknown token \"%s\" in %s:%d ignored\n",
588 lirc_prog
,token
,name
,line
);
593 unsigned int lirc_flags(char *string
)
599 s
=strtok(string
," \t|");
602 if(strcasecmp(s
,"once")==0)
606 else if(strcasecmp(s
,"quit")==0)
610 else if(strcasecmp(s
,"mode")==0)
614 else if(strcasecmp(s
,"startup_mode")==0)
618 else if(strcasecmp(s
,"toggle_reset")==0)
624 lirc_printf("%s: unknown flag \"%s\"\n",lirc_prog
,s
);
626 s
=strtok(NULL
," \t");
631 static char *lirc_getfilename(const char *file
, const char *current_file
)
633 char *home
, *filename
;
642 filename
=(char *) malloc(strlen(home
)+1+
643 strlen(LIRCRC_USER_FILE
)+1);
646 lirc_printf("%s: out of memory\n",lirc_prog
);
649 strcpy(filename
,home
);
650 if(strlen(home
)>0 && filename
[strlen(filename
)-1]!='/')
652 strcat(filename
,"/");
654 strcat(filename
,LIRCRC_USER_FILE
);
656 else if(strncmp(file
, "~/", 2)==0)
663 filename
=(char *) malloc(strlen(home
)+strlen(file
)+1);
666 lirc_printf("%s: out of memory\n",lirc_prog
);
669 strcpy(filename
,home
);
670 strcat(filename
,file
+1);
672 else if(file
[0]=='/' || current_file
==NULL
)
674 /* absulute path or root */
675 filename
=strdup(file
);
678 lirc_printf("%s: out of memory\n",lirc_prog
);
684 /* get path from parent filename */
685 int pathlen
= strlen(current_file
);
686 while (pathlen
>0 && current_file
[pathlen
-1]!='/')
688 filename
=(char *) malloc(pathlen
+strlen(file
)+1);
691 lirc_printf("%s: out of memory\n",lirc_prog
);
694 memcpy(filename
,current_file
,pathlen
);
696 strcat(filename
,file
);
701 static FILE *lirc_open(const char *file
, const char *current_file
,
707 filename
=lirc_getfilename(file
, current_file
);
713 fin
=fopen(filename
,"r");
714 if(fin
==NULL
&& (file
!=NULL
|| errno
!=ENOENT
))
716 lirc_printf("%s: could not open config file %s\n",
718 lirc_perror(lirc_prog
);
722 fin
=fopen(LIRCRC_ROOT_FILE
,"r");
723 if(fin
==NULL
&& errno
!=ENOENT
)
725 lirc_printf("%s: could not open config file %s\n",
726 lirc_prog
,LIRCRC_ROOT_FILE
);
727 lirc_perror(lirc_prog
);
731 lirc_printf("%s: could not open config files "
733 lirc_prog
,filename
,LIRCRC_ROOT_FILE
);
734 lirc_perror(lirc_prog
);
739 filename
= strdup(LIRCRC_ROOT_FILE
);
743 lirc_printf("%s: out of memory\n",lirc_prog
);
748 if(full_name
&& fin
!=NULL
)
750 *full_name
= filename
;
759 static struct filestack_t
*stack_push(struct filestack_t
*parent
)
761 struct filestack_t
*entry
;
762 entry
= malloc(sizeof(struct filestack_t
));
765 lirc_printf("%s: out of memory\n",lirc_prog
);
771 entry
->parent
= parent
;
775 static struct filestack_t
*stack_pop(struct filestack_t
*entry
)
777 struct filestack_t
*parent
= NULL
;
780 parent
= entry
->parent
;
788 static void stack_free(struct filestack_t
*entry
)
792 entry
= stack_pop(entry
);
796 int lirc_readconfig(char *file
,
797 struct lirc_config
**config
,
798 int (check
)(char *s
))
800 struct sockaddr_un addr
;
802 char *sha_bang
, *sha_bang2
, *filename
;
808 if(lirc_readconfig_only_internal(file
,config
,check
,&filename
,&sha_bang
)==-1)
815 goto lirc_readconfig_compat
;
818 /* connect to lircrcd */
820 addr
.sun_family
=AF_UNIX
;
821 if(lirc_getsocketname(filename
, addr
.sun_path
, sizeof(addr
.sun_path
))>sizeof(addr
.sun_path
))
823 lirc_printf("%s: WARNING: file name too long\n", lirc_prog
);
824 goto lirc_readconfig_compat
;
826 sockfd
=socket(AF_UNIX
,SOCK_STREAM
,0);
829 lirc_printf("%s: WARNING: could not open socket\n",lirc_prog
);
830 lirc_perror(lirc_prog
);
831 goto lirc_readconfig_compat
;
833 if(connect(sockfd
, (struct sockaddr
*)&addr
, sizeof(addr
))!=-1)
835 if(sha_bang
!=NULL
) free(sha_bang
);
836 (*config
)->sockfd
=sockfd
;
839 /* tell daemon lirc_prog */
840 if(lirc_identify(sockfd
) == LIRC_RET_SUCCESS
)
842 /* we're connected */
846 lirc_freeconfig(*config
);
853 sha_bang2
=sha_bang
!=NULL
? sha_bang
:"lircrcd";
855 command
=malloc(strlen(sha_bang2
)+1+strlen(filename
)+1);
858 goto lirc_readconfig_compat
;
860 strcpy(command
, sha_bang2
);
861 strcat(command
, " ");
862 strcat(command
, filename
);
866 if(ret
==-1 || WEXITSTATUS(ret
)!=EXIT_SUCCESS
)
868 goto lirc_readconfig_compat
;
871 if(sha_bang
!=NULL
) free(sha_bang
);
874 sockfd
=socket(AF_UNIX
,SOCK_STREAM
,0);
877 lirc_printf("%s: WARNING: could not open socket\n",lirc_prog
);
878 lirc_perror(lirc_prog
);
879 goto lirc_readconfig_compat
;
881 if(connect(sockfd
, (struct sockaddr
*)&addr
, sizeof(addr
))!=-1)
883 if(lirc_identify(sockfd
) == LIRC_RET_SUCCESS
)
885 (*config
)->sockfd
=sockfd
;
890 lirc_freeconfig(*config
);
893 lirc_readconfig_compat
:
894 /* compat fallback */
895 if(sockfd
!= -1) close(sockfd
);
896 if(sha_bang
!=NULL
) free(sha_bang
);
901 int lirc_readconfig_only(char *file
,
902 struct lirc_config
**config
,
903 int (check
)(char *s
))
905 return lirc_readconfig_only_internal(file
, config
, check
, NULL
, NULL
);
908 static int lirc_readconfig_only_internal(char *file
,
909 struct lirc_config
**config
,
910 int (check
)(char *s
),
914 char *string
,*eq
,*token
,*token2
,*token3
;
915 struct filestack_t
*filestack
, *stack_tmp
;
917 struct lirc_config_entry
*new_entry
,*first
,*last
;
921 char *save_full_name
= NULL
;
923 filestack
= stack_push(NULL
);
924 if (filestack
== NULL
)
928 filestack
->file
= lirc_open(file
, NULL
, &(filestack
->name
));
929 if (filestack
->file
== NULL
)
931 stack_free(filestack
);
937 first
=new_entry
=last
=NULL
;
942 if((ret
=lirc_readline(&string
,filestack
->file
))==-1 ||
945 fclose(filestack
->file
);
946 if(open_files
== 1 && full_name
!= NULL
)
948 save_full_name
= filestack
->name
;
949 filestack
->name
= NULL
;
951 filestack
= stack_pop(filestack
);
955 /* check for sha-bang */
956 if(firstline
&& sha_bang
)
959 if(strncmp(string
, "#!", 2)==0)
961 *sha_bang
=strdup(string
+2);
964 lirc_printf("%s: out of memory\n",
973 eq
=strchr(string
,'=');
976 token
=strtok(string
," \t");
979 /* ignore empty line */
981 else if(token
[0]=='#')
985 else if(strcasecmp(token
, "include") == 0)
987 if (open_files
>= MAX_INCLUDES
)
989 lirc_printf("%s: too many files "
990 "included at %s:%d\n",
998 token2
= strtok(NULL
, "");
999 token2
= lirc_trim(token2
);
1001 (token2
, filestack
->name
,
1003 stack_tmp
= stack_push(filestack
);
1004 if (stack_tmp
== NULL
)
1010 stack_tmp
->file
= lirc_open(token2
, filestack
->name
, &(stack_tmp
->name
));
1011 stack_tmp
->line
= 0;
1012 if (stack_tmp
->file
)
1015 filestack
= stack_tmp
;
1019 stack_pop(stack_tmp
);
1027 token2
=strtok(NULL
," \t");
1029 (token3
=strtok(NULL
," \t"))!=NULL
)
1031 lirc_printf("%s: unexpected token in line %s:%d\n",
1032 lirc_prog
,filestack
->name
,filestack
->line
);
1036 ret
=lirc_mode(token
,token2
,&mode
,
1037 &new_entry
,&first
,&last
,
1043 if(remote
!=LIRC_ALL
)
1056 lirc_freeconfigentries
1067 token
=lirc_trim(string
);
1068 token2
=lirc_trim(eq
+1);
1071 /* ignore comment */
1073 else if(new_entry
==NULL
)
1075 lirc_printf("%s: bad file format, %s:%d\n",
1076 lirc_prog
,filestack
->name
,filestack
->line
);
1081 token2
=strdup(token2
);
1084 lirc_printf("%s: out of memory\n",
1088 else if(strcasecmp(token
,"prog")==0)
1090 if(new_entry
->prog
!=NULL
) free(new_entry
->prog
);
1091 new_entry
->prog
=token2
;
1093 else if(strcasecmp(token
,"remote")==0)
1095 if(remote
!=LIRC_ALL
)
1098 if(strcasecmp("*",token2
)==0)
1108 else if(strcasecmp(token
,"button")==0)
1110 struct lirc_code
*code
;
1112 code
=(struct lirc_code
*)
1113 malloc(sizeof(struct lirc_code
));
1117 lirc_printf("%s: out of "
1124 code
->remote
=remote
;
1125 if(strcasecmp("*",token2
)==0)
1127 code
->button
=LIRC_ALL
;
1132 code
->button
=token2
;
1136 if(new_entry
->code
==NULL
)
1138 new_entry
->code
=code
;
1142 new_entry
->next_code
->next
1145 new_entry
->next_code
=code
;
1146 if(remote
!=LIRC_ALL
)
1148 remote
=strdup(remote
);
1151 lirc_printf("%s: out of memory\n",lirc_prog
);
1157 else if(strcasecmp(token
,"delay")==0)
1162 new_entry
->rep_delay
=strtoul(token2
,&end
,0);
1163 if((new_entry
->rep_delay
==ULONG_MAX
1166 || strlen(token2
)==0)
1168 lirc_printf("%s: \"%s\" not"
1169 " a valid number for "
1170 "delay\n",lirc_prog
,
1175 else if(strcasecmp(token
,"repeat")==0)
1180 new_entry
->rep
=strtoul(token2
,&end
,0);
1181 if((new_entry
->rep
==ULONG_MAX
1184 || strlen(token2
)==0)
1186 lirc_printf("%s: \"%s\" not"
1187 " a valid number for "
1188 "repeat\n",lirc_prog
,
1193 else if(strcasecmp(token
,"config")==0)
1195 struct lirc_list
*new_list
;
1197 new_list
=(struct lirc_list
*)
1198 malloc(sizeof(struct lirc_list
));
1202 lirc_printf("%s: out of "
1209 lirc_parse_string(token2
,filestack
->name
,filestack
->line
);
1210 new_list
->string
=token2
;
1211 new_list
->next
=NULL
;
1212 if(new_entry
->config
==NULL
)
1214 new_entry
->config
=new_list
;
1218 new_entry
->next_config
->next
1221 new_entry
->next_config
=new_list
;
1224 else if(strcasecmp(token
,"mode")==0)
1226 if(new_entry
->change_mode
!=NULL
) free(new_entry
->change_mode
);
1227 new_entry
->change_mode
=token2
;
1229 else if(strcasecmp(token
,"flags")==0)
1231 new_entry
->flags
=lirc_flags(token2
);
1237 lirc_printf("%s: unknown token \"%s\" in %s:%d ignored\n",
1238 lirc_prog
,token
,filestack
->name
,filestack
->line
);
1245 if(remote
!=LIRC_ALL
)
1251 ret
=lirc_mode("end",NULL
,&mode
,&new_entry
,
1252 &first
,&last
,check
,"",0);
1253 lirc_printf("%s: warning: end token missing at end "
1254 "of file\n",lirc_prog
);
1258 lirc_freeconfigentries(new_entry
);
1266 lirc_printf("%s: warning: no end token found for mode "
1267 "\"%s\"\n",lirc_prog
,mode
);
1275 *config
=(struct lirc_config
*)
1276 malloc(sizeof(struct lirc_config
));
1279 lirc_printf("%s: out of memory\n",lirc_prog
);
1280 lirc_freeconfigentries(first
);
1283 (*config
)->first
=first
;
1284 (*config
)->next
=first
;
1285 startupmode
= lirc_startupmode((*config
)->first
);
1286 (*config
)->current_mode
=startupmode
? strdup(startupmode
):NULL
;
1287 (*config
)->sockfd
=-1;
1288 if(full_name
!= NULL
)
1290 *full_name
= save_full_name
;
1291 save_full_name
= NULL
;
1297 lirc_freeconfigentries(first
);
1306 stack_free(filestack
);
1310 free(save_full_name
);
1315 static char *lirc_startupmode(struct lirc_config_entry
*first
)
1317 struct lirc_config_entry
*scan
;
1322 /* Set a startup mode based on flags=startup_mode */
1325 if(scan
->flags
&startup_mode
) {
1326 if(scan
->change_mode
!=NULL
) {
1327 startupmode
=scan
->change_mode
;
1328 /* Remove the startup mode or it confuses lirc mode system */
1329 scan
->change_mode
=NULL
;
1333 lirc_printf("%s: startup_mode flags requires 'mode ='\n",
1340 /* Set a default mode if we find a mode = client app name */
1341 if(startupmode
==NULL
) {
1345 if(scan
->mode
!=NULL
&& strcasecmp(lirc_prog
,scan
->mode
)==0)
1347 startupmode
=lirc_prog
;
1354 if(startupmode
==NULL
) return(NULL
);
1358 if(scan
->change_mode
!=NULL
&& scan
->flags
&once
&&
1359 strcasecmp(startupmode
,scan
->change_mode
)==0)
1365 return(startupmode
);
1368 void lirc_freeconfig(struct lirc_config
*config
)
1372 if(config
->sockfd
!=-1)
1374 (void) close(config
->sockfd
);
1377 lirc_freeconfigentries(config
->first
);
1378 free(config
->current_mode
);
1383 static void lirc_freeconfigentries(struct lirc_config_entry
*first
)
1385 struct lirc_config_entry
*c
,*config_temp
;
1386 struct lirc_list
*list
,*list_temp
;
1387 struct lirc_code
*code
,*code_temp
;
1392 if(c
->prog
) free(c
->prog
);
1393 if(c
->change_mode
) free(c
->change_mode
);
1394 if(c
->mode
) free(c
->mode
);
1399 if(code
->remote
!=NULL
&& code
->remote
!=LIRC_ALL
)
1401 if(code
->button
!=NULL
&& code
->button
!=LIRC_ALL
)
1403 code_temp
=code
->next
;
1411 if(list
->string
) free(list
->string
);
1412 list_temp
=list
->next
;
1416 config_temp
=c
->next
;
1422 static void lirc_clearmode(struct lirc_config
*config
)
1424 struct lirc_config_entry
*scan
;
1426 if(config
->current_mode
==NULL
)
1433 if(scan
->change_mode
!=NULL
)
1435 if(strcasecmp(scan
->change_mode
,config
->current_mode
)==0)
1442 free(config
->current_mode
);
1443 config
->current_mode
=NULL
;
1446 static char *lirc_execute(struct lirc_config
*config
,
1447 struct lirc_config_entry
*scan
)
1452 if(scan
->flags
&mode
)
1454 lirc_clearmode(config
);
1456 if(scan
->change_mode
!=NULL
)
1458 free(config
->current_mode
);
1459 config
->current_mode
=strdup(scan
->change_mode
);
1460 if(scan
->flags
&once
)
1462 if(scan
->flags
&ecno
)
1472 if(scan
->next_config
!=NULL
&&
1474 (lirc_prog
== NULL
|| strcasecmp(scan
->prog
,lirc_prog
)==0) &&
1477 s
=scan
->next_config
->string
;
1478 scan
->next_config
=scan
->next_config
->next
;
1479 if(scan
->next_config
==NULL
)
1480 scan
->next_config
=scan
->config
;
1486 static int lirc_iscode(struct lirc_config_entry
*scan
, char *remote
,
1487 char *button
,int rep
)
1489 struct lirc_code
*codes
;
1491 /* no remote/button specified */
1492 if(scan
->code
==NULL
)
1495 (scan
->rep
>0 && rep
>scan
->rep_delay
&&
1496 ((rep
-scan
->rep_delay
-1)%scan
->rep
)==0);
1499 /* remote/button match? */
1500 if(scan
->next_code
->remote
==LIRC_ALL
||
1501 strcasecmp(scan
->next_code
->remote
,remote
)==0)
1503 if(scan
->next_code
->button
==LIRC_ALL
||
1504 strcasecmp(scan
->next_code
->button
,button
)==0)
1507 /* button sequence? */
1508 if(scan
->code
->next
==NULL
|| rep
==0)
1510 scan
->next_code
=scan
->next_code
->next
;
1512 /* sequence completed? */
1513 if(scan
->next_code
==NULL
)
1515 scan
->next_code
=scan
->code
;
1516 iscode
=scan
->code
->next
!=NULL
|| rep
==0 ||
1517 (scan
->rep
>0 && rep
>scan
->rep_delay
&&
1518 ((rep
-scan
->rep_delay
-1)%scan
->rep
)==0);
1524 if(rep
!=0) return(0);
1526 /* handle toggle_reset */
1527 if(scan
->flags
& toggle_reset
)
1529 scan
->next_config
= scan
->config
;
1533 if(codes
==scan
->next_code
) return(0);
1535 /* rebase code sequence */
1536 while(codes
!=scan
->next_code
->next
)
1538 struct lirc_code
*prev
,*next
;
1543 while(next
!=scan
->next_code
)
1545 if(prev
->remote
==LIRC_ALL
||
1546 strcasecmp(prev
->remote
,next
->remote
)==0)
1548 if(prev
->button
==LIRC_ALL
||
1549 strcasecmp(prev
->button
,next
->button
)==0)
1566 if(prev
->remote
==LIRC_ALL
||
1567 strcasecmp(prev
->remote
,remote
)==0)
1569 if(prev
->button
==LIRC_ALL
||
1570 strcasecmp(prev
->button
,button
)==0)
1574 scan
->next_code
=prev
->next
;
1582 scan
->next_code
=scan
->code
;
1586 char *lirc_ir2char(struct lirc_config
*config
,char *code
)
1588 static int warning
=1;
1593 fprintf(stderr
,"%s: warning: lirc_ir2char() is obsolete\n",
1597 if(lirc_code2char(config
,code
,&string
)==-1) return(NULL
);
1601 int lirc_code2char(struct lirc_config
*config
,char *code
,char **string
)
1603 if(config
->sockfd
!=-1)
1605 char command
[10+strlen(code
)+1+1];
1606 static char buf
[LIRC_PACKET_SIZE
];
1607 size_t buf_len
= LIRC_PACKET_SIZE
;
1611 sprintf(command
, "CODE %s", code
);
1613 ret
= lirc_send_command(config
->sockfd
, command
,
1614 buf
, &buf_len
, &success
);
1615 if(success
== LIRC_RET_SUCCESS
)
1625 return LIRC_RET_SUCCESS
;
1627 return LIRC_RET_ERROR
;
1629 return lirc_code2char_internal(config
, code
, string
, NULL
);
1632 int lirc_code2charprog(struct lirc_config
*config
,char *code
,char **string
,
1641 ret
= lirc_code2char_internal(config
, code
, string
, prog
);
1647 static int lirc_code2char_internal(struct lirc_config
*config
,char *code
,
1648 char **string
, char **prog
)
1652 char *remote
,*button
;
1654 struct lirc_config_entry
*scan
;
1658 if(sscanf(code
,"%*x %x %*s %*s\n",&rep
)==1)
1660 backup
=strdup(code
);
1661 if(backup
==NULL
) return(-1);
1665 button
=strtok(NULL
," ");
1666 remote
=strtok(NULL
,"\n");
1668 if(button
==NULL
|| remote
==NULL
)
1678 if(lirc_iscode(scan
,remote
,button
,rep
) &&
1679 (scan
->mode
==NULL
||
1680 (scan
->mode
!=NULL
&&
1681 config
->current_mode
!=NULL
&&
1682 strcasecmp(scan
->mode
,config
->current_mode
)==0)) &&
1686 s
=lirc_execute(config
,scan
);
1687 if(s
!= NULL
&& prog
!= NULL
)
1691 if(scan
->flags
&quit
)
1700 config
->next
=scan
->next
;
1713 config
->next
=config
->first
;
1717 #define PACKET_SIZE 100
1719 char *lirc_nextir(void)
1721 static int warning
=1;
1727 fprintf(stderr
,"%s: warning: lirc_nextir() is obsolete\n",
1731 ret
=lirc_nextcode(&code
);
1732 if(ret
==-1) return(NULL
);
1737 int lirc_nextcode(char **code
)
1739 static int packet_size
=PACKET_SIZE
;
1740 static int end_len
=0;
1745 if(lirc_buffer
==NULL
)
1747 lirc_buffer
=(char *) malloc(packet_size
+1);
1748 if(lirc_buffer
==NULL
)
1750 lirc_printf("%s: out of memory\n",lirc_prog
);
1755 while((end
=strchr(lirc_buffer
,'\n'))==NULL
)
1757 if(end_len
>=packet_size
)
1761 packet_size
+=PACKET_SIZE
;
1762 new_buffer
=(char *) realloc(lirc_buffer
,packet_size
+1);
1763 if(new_buffer
==NULL
)
1767 lirc_buffer
=new_buffer
;
1769 len
=read(lirc_lircd
,lirc_buffer
+end_len
,packet_size
-end_len
);
1772 if(len
==-1 && errno
==EAGAIN
) return(0);
1776 lirc_buffer
[end_len
]=0;
1777 /* return if next code not yet available completely */
1778 if((end
=strchr(lirc_buffer
,'\n'))==NULL
)
1783 /* copy first line to buffer (code) and move remaining chars to
1784 lirc_buffers start */
1786 end_len
=strlen(end
);
1789 *code
=strdup(lirc_buffer
);
1791 memmove(lirc_buffer
,end
,end_len
+1);
1792 if(*code
==NULL
) return(-1);
1796 size_t lirc_getsocketname(const char *filename
, char *buf
, size_t size
)
1798 if(strlen(filename
)+2<=size
)
1800 strcpy(buf
, filename
);
1803 return strlen(filename
)+2;
1806 const char *lirc_getmode(struct lirc_config
*config
)
1808 if(config
->sockfd
!=-1)
1810 static char buf
[LIRC_PACKET_SIZE
];
1811 size_t buf_len
= LIRC_PACKET_SIZE
;
1815 ret
= lirc_send_command(config
->sockfd
, "GETMODE\n",
1816 buf
, &buf_len
, &success
);
1817 if(success
== LIRC_RET_SUCCESS
)
1830 return config
->current_mode
;
1833 const char *lirc_setmode(struct lirc_config
*config
, const char *mode
)
1835 if(config
->sockfd
!=-1)
1837 static char buf
[LIRC_PACKET_SIZE
];
1838 size_t buf_len
= LIRC_PACKET_SIZE
;
1841 char cmd
[LIRC_PACKET_SIZE
];
1842 if(snprintf(cmd
, LIRC_PACKET_SIZE
, "SETMODE%s%s\n",
1845 >= LIRC_PACKET_SIZE
)
1850 ret
= lirc_send_command(config
->sockfd
, cmd
,
1851 buf
, &buf_len
, &success
);
1852 if(success
== LIRC_RET_SUCCESS
)
1866 free(config
->current_mode
);
1867 config
->current_mode
= mode
? strdup(mode
) : NULL
;
1868 return config
->current_mode
;
1871 static const char *lirc_read_string(int fd
)
1873 static char buffer
[LIRC_PACKET_SIZE
+1]="";
1875 static int head
=0, tail
=0;
1883 memmove(buffer
,buffer
+head
,tail
-head
+1);
1886 end
=strchr(buffer
,'\n');
1892 if(strlen(buffer
)!=tail
)
1894 lirc_printf("%s: protocol error\n", lirc_prog
);
1895 goto lirc_read_string_error
;
1900 if(LIRC_PACKET_SIZE
<=tail
)
1902 lirc_printf("%s: bad packet\n", lirc_prog
);
1903 goto lirc_read_string_error
;
1908 tv
.tv_sec
=LIRC_TIMEOUT
;
1912 ret
=select(fd
+1,&fds
,NULL
,NULL
,&tv
);
1914 while(ret
==-1 && errno
==EINTR
);
1917 lirc_printf("%s: select() failed\n", lirc_prog
);
1918 lirc_perror(lirc_prog
);
1919 goto lirc_read_string_error
;
1923 lirc_printf("%s: timeout\n", lirc_prog
);
1924 goto lirc_read_string_error
;
1927 n
=read(fd
, buffer
+tail
, LIRC_PACKET_SIZE
-tail
);
1930 lirc_printf("%s: read() failed\n", lirc_prog
);
1931 lirc_perror(lirc_prog
);
1932 goto lirc_read_string_error
;
1936 end
=strchr(buffer
,'\n');
1940 head
=strlen(buffer
)+1;
1943 lirc_read_string_error
:
1949 int lirc_send_command(int sockfd
, const char *command
, char *buf
, size_t *buf_len
, int *ret_status
)
1952 const char *string
,*data
;
1954 enum packet_state state
;
1956 unsigned long data_n
=0;
1957 size_t written
=0, max
=0, len
;
1963 todo
=strlen(command
);
1967 done
=write(sockfd
,(void *) data
,todo
);
1970 lirc_printf("%s: could not send packet\n",
1972 lirc_perror(lirc_prog
);
1980 status
=LIRC_RET_SUCCESS
;
1985 string
=lirc_read_string(sockfd
);
1986 if(string
==NULL
) return(-1);
1990 if(strcasecmp(string
,"BEGIN")!=0)
1997 if(strncasecmp(string
,command
,strlen(string
))!=0 ||
1998 strlen(string
)+1!=strlen(command
))
2006 if(strcasecmp(string
,"SUCCESS")==0)
2008 status
=LIRC_RET_SUCCESS
;
2010 else if(strcasecmp(string
,"END")==0)
2012 status
=LIRC_RET_SUCCESS
;
2015 else if(strcasecmp(string
,"ERROR")==0)
2017 lirc_printf("%s: command failed: %s",
2018 lirc_prog
, command
);
2019 status
=LIRC_RET_ERROR
;
2028 if(strcasecmp(string
,"END")==0)
2032 else if(strcasecmp(string
,"DATA")==0)
2040 data_n
=strtoul(string
,&endptr
,0);
2041 if(!*string
|| *endptr
)
2056 if(buf
!=NULL
&& written
+len
+1<max
)
2058 memcpy(buf
+written
, string
, len
+1);
2062 if(n
==data_n
) state
=P_END
;
2065 if(strcasecmp(string
,"END")==0)
2077 lirc_printf("%s: bad return packet\n", lirc_prog
);
2081 if(ret_status
!=NULL
)
2089 return (int) data_n
;
2092 int lirc_identify(int sockfd
)
2094 char command
[10+strlen(lirc_prog
)+1+1];
2097 sprintf(command
, "IDENT %s\n", lirc_prog
);
2099 (void) lirc_send_command(sockfd
, command
, NULL
, NULL
, &success
);