Mostly minor fixes up until version 0.8.10.
[irreco.git] / lirc-0.8.4a / tools / lirc_client.c
blob3572d2e8e415a4784a8e046650740ec8b7bad2b9
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>
13 */
15 #ifdef HAVE_CONFIG_H
16 # include <config.h>
17 #endif
19 #include <errno.h>
20 #include <unistd.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <limits.h>
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
32 #include "lirc_client.h"
35 /* internal defines */
36 #define MAX_INCLUDES 10
37 #define LIRC_READ 255
38 #define LIRC_PACKET_SIZE 255
39 /* three seconds */
40 #define LIRC_TIMEOUT 3
42 /* internal data structures */
43 struct filestack_t {
44 FILE *file;
45 char *name;
46 int line;
47 struct filestack_t *parent;
50 enum packet_state
52 P_BEGIN,
53 P_MESSAGE,
54 P_STATUS,
55 P_DATA,
56 P_N,
57 P_DATA_N,
58 P_END
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,
73 int (check)(char *s),
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,
83 char **full_name);
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,
89 int (check)(char *s),
90 char **full_name,
91 char **sha_bang);
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, ...)
113 va_list ap;
115 if(!lirc_verbose) return;
117 va_start(ap,format_str);
118 vfprintf(stderr,format_str,ap);
119 va_end(ap);
122 static void lirc_perror(const char *s)
124 if(!lirc_verbose) return;
126 perror(s);
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;
138 if(lirc_prog==NULL)
140 lirc_printf("%s: out of memory\n",prog);
141 return(-1);
144 addr.sun_family=AF_UNIX;
145 strcpy(addr.sun_path,LIRCD);
146 lirc_lircd=socket(AF_UNIX,SOCK_STREAM,0);
147 if(lirc_lircd==-1)
149 lirc_printf("%s: could not open socket\n",lirc_prog);
150 lirc_perror(lirc_prog);
151 free(lirc_prog);
152 lirc_prog=NULL;
153 return(-1);
155 if(connect(lirc_lircd,(struct sockaddr *)&addr,sizeof(addr))==-1)
157 close(lirc_lircd);
158 lirc_printf("%s: could not connect to socket\n",lirc_prog);
159 lirc_perror(lirc_prog);
160 free(lirc_prog);
161 lirc_prog=NULL;
162 return(-1);
164 return(lirc_lircd);
167 int lirc_deinit(void)
169 if(lirc_prog!=NULL)
171 free(lirc_prog);
172 lirc_prog=NULL;
174 if(lirc_buffer!=NULL)
176 free(lirc_buffer);
177 lirc_buffer=NULL;
179 return(close(lirc_lircd));
182 static int lirc_readline(char **line,FILE *f)
184 char *newline,*ret,*enlargeline;
185 int len;
187 newline=(char *) malloc(LIRC_READ+1);
188 if(newline==NULL)
190 lirc_printf("%s: out of memory\n",lirc_prog);
191 return(-1);
193 len=0;
194 while(1)
196 ret=fgets(newline+len,LIRC_READ+1,f);
197 if(ret==NULL)
199 if(feof(f) && len>0)
201 *line=newline;
203 else
205 free(newline);
206 *line=NULL;
208 return(0);
210 len=strlen(newline);
211 if(newline[len-1]=='\n')
213 newline[len-1]=0;
214 *line=newline;
215 return(0);
218 enlargeline=(char *) realloc(newline,len+1+LIRC_READ);
219 if(enlargeline==NULL)
221 free(newline);
222 lirc_printf("%s: out of memory\n",lirc_prog);
223 return(-1);
225 newline=enlargeline;
229 static char *lirc_trim(char *s)
231 int len;
233 while(s[0]==' ' || s[0]=='\t') s++;
234 len=strlen(s);
235 while(len>0)
237 len--;
238 if(s[len]==' ' || s[len]=='\t') s[len]=0;
239 else break;
241 return(s);
244 /* parse standard C escape sequences + \@,\A-\Z is ^@,^A-^Z */
246 static char lirc_parse_escape(char **s,const char *name,int line)
249 char c;
250 unsigned int i,overflow,count;
251 int digits_found,digit;
253 c=**s;
254 (*s)++;
255 switch(c)
257 case 'a':
258 return('\a');
259 case 'b':
260 return('\b');
261 case 'e':
262 #if 0
263 case 'E': /* this should become ^E */
264 #endif
265 return(033);
266 case 'f':
267 return('\f');
268 case 'n':
269 return('\n');
270 case 'r':
271 return('\r');
272 case 't':
273 return('\t');
274 case 'v':
275 return('\v');
276 case '\n':
277 return(0);
278 case 0:
279 (*s)--;
280 return 0;
281 case '0':
282 case '1':
283 case '2':
284 case '3':
285 case '4':
286 case '5':
287 case '6':
288 case '7':
289 i=c-'0';
290 count=0;
292 while(++count<3)
294 c=*(*s)++;
295 if(c>='0' && c<='7')
297 i=(i << 3)+c-'0';
299 else
301 (*s)--;
302 break;
305 if(i>(1<<CHAR_BIT)-1)
307 i&=(1<<CHAR_BIT)-1;
308 lirc_printf("%s: octal escape sequence "
309 "out of range in %s:%d\n",lirc_prog,
310 name,line);
312 return((char) i);
313 case 'x':
315 i=0;
316 overflow=0;
317 digits_found=0;
318 for (;;)
320 c = *(*s)++;
321 if(c>='0' && c<='9')
322 digit=c-'0';
323 else if(c>='a' && c<='f')
324 digit=c-'a'+10;
325 else if(c>='A' && c<='F')
326 digit=c-'A'+10;
327 else
329 (*s)--;
330 break;
332 overflow|=i^(i<<4>>4);
333 i=(i<<4)+digit;
334 digits_found=1;
336 if(!digits_found)
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)
344 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);
349 return((char) i);
351 default:
352 if(c>='@' && c<='Z') return(c-'@');
353 return(c);
357 static void lirc_parse_string(char *s,const char *name,int line)
359 char *t;
361 t=s;
362 while(*s!=0)
364 if(*s=='\\')
366 s++;
367 *t=lirc_parse_escape(&s,name,line);
368 t++;
370 else
372 *t=*s;
373 s++;
374 t++;
377 *t=0;
380 static void lirc_parse_include(char *s,const char *name,int line)
382 char last;
383 size_t len;
385 len=strlen(s);
386 if(len<2)
388 return;
390 last=s[len-1];
391 if(*s!='"' && *s!='<')
393 return;
395 if(*s=='"' && last!='"')
397 return;
399 else if(*s=='<' && last!='>')
401 return;
403 s[len-1]=0;
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)
419 if(token2==NULL)
421 if(new_entry==NULL)
423 new_entry=(struct lirc_config_entry *)
424 malloc(sizeof(struct lirc_config_entry));
425 if(new_entry==NULL)
427 lirc_printf("%s: out of memory\n",
428 lirc_prog);
429 return(-1);
431 else
433 new_entry->prog=NULL;
434 new_entry->code=NULL;
435 new_entry->rep_delay=0;
436 new_entry->rep=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;
448 else
450 lirc_printf("%s: bad file format, "
451 "%s:%d\n",lirc_prog,name,line);
452 return(-1);
455 else
457 if(new_entry==NULL && *mode==NULL)
459 *mode=strdup(token2);
460 if(*mode==NULL)
462 return(-1);
465 else
467 lirc_printf("%s: bad file format, "
468 "%s:%d\n",lirc_prog,name,line);
469 return(-1);
473 else if(strcasecmp(token,"end")==0)
475 if(token2==NULL)
477 if(new_entry!=NULL)
479 #if 0
480 if(new_entry->prog==NULL)
482 lirc_printf("%s: prog missing in "
483 "config before line %d\n",
484 lirc_prog,line);
485 lirc_freeconfigentries(new_entry);
486 *new_config=NULL;
487 return(-1);
489 if(strcasecmp(new_entry->prog,lirc_prog)!=0)
491 lirc_freeconfigentries(new_entry);
492 *new_config=NULL;
493 return(0);
495 #endif
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;
503 else
505 (*last_config)->next=new_entry;
506 *last_config=new_entry;
508 *new_config=NULL;
510 if(*mode!=NULL)
512 new_entry->mode=strdup(*mode);
513 if(new_entry->mode==NULL)
515 lirc_printf("%s: out of "
516 "memory\n",
517 lirc_prog);
518 return(-1);
522 if(check!=NULL &&
523 new_entry->prog!=NULL &&
524 strcasecmp(new_entry->prog,lirc_prog)==0)
526 struct lirc_list *list;
528 list=new_entry->config;
529 while(list!=NULL)
531 if(check(list->string)==-1)
533 return(-1);
535 list=list->next;
539 if (new_entry->rep_delay==0 &&
540 new_entry->rep>0)
542 new_entry->rep_delay=new_entry->rep-1;
545 else
547 lirc_printf("%s: %s:%d: 'end' without "
548 "'begin'\n",lirc_prog,name,line);
549 return(-1);
552 else
554 if(*mode!=NULL)
556 if(new_entry!=NULL)
558 lirc_printf("%s: %s:%d: missing "
559 "'end' token\n",lirc_prog,
560 name,line);
561 return(-1);
563 if(strcasecmp(*mode,token2)==0)
565 free(*mode);
566 *mode=NULL;
568 else
570 lirc_printf("%s: \"%s\" doesn't "
571 "match mode \"%s\"\n",
572 lirc_prog,token2,*mode);
573 return(-1);
576 else
578 lirc_printf("%s: %s:%d: 'end %s' without "
579 "'begin'\n",lirc_prog,name,line,
580 token2);
581 return(-1);
585 else
587 lirc_printf("%s: unknown token \"%s\" in %s:%d ignored\n",
588 lirc_prog,token,name,line);
590 return(0);
593 unsigned int lirc_flags(char *string)
595 char *s;
596 unsigned int flags;
598 flags=none;
599 s=strtok(string," \t|");
600 while(s)
602 if(strcasecmp(s,"once")==0)
604 flags|=once;
606 else if(strcasecmp(s,"quit")==0)
608 flags|=quit;
610 else if(strcasecmp(s,"mode")==0)
612 flags|=mode;
614 else if(strcasecmp(s,"startup_mode")==0)
616 flags|=startup_mode;
618 else if(strcasecmp(s,"toggle_reset")==0)
620 flags|=toggle_reset;
622 else
624 lirc_printf("%s: unknown flag \"%s\"\n",lirc_prog,s);
626 s=strtok(NULL," \t");
628 return(flags);
631 static char *lirc_getfilename(const char *file, const char *current_file)
633 char *home, *filename;
635 if(file==NULL)
637 home=getenv("HOME");
638 if(home==NULL)
640 home="/";
642 filename=(char *) malloc(strlen(home)+1+
643 strlen(LIRCRC_USER_FILE)+1);
644 if(filename==NULL)
646 lirc_printf("%s: out of memory\n",lirc_prog);
647 return NULL;
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)
658 home=getenv("HOME");
659 if(home==NULL)
661 home="/";
663 filename=(char *) malloc(strlen(home)+strlen(file)+1);
664 if(filename==NULL)
666 lirc_printf("%s: out of memory\n",lirc_prog);
667 return NULL;
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);
676 if(filename==NULL)
678 lirc_printf("%s: out of memory\n",lirc_prog);
679 return NULL;
682 else
684 /* get path from parent filename */
685 int pathlen = strlen(current_file);
686 while (pathlen>0 && current_file[pathlen-1]!='/')
687 pathlen--;
688 filename=(char *) malloc(pathlen+strlen(file)+1);
689 if(filename==NULL)
691 lirc_printf("%s: out of memory\n",lirc_prog);
692 return NULL;
694 memcpy(filename,current_file,pathlen);
695 filename[pathlen]=0;
696 strcat(filename,file);
698 return filename;
701 static FILE *lirc_open(const char *file, const char *current_file,
702 char **full_name)
704 FILE *fin;
705 char *filename;
707 filename=lirc_getfilename(file, current_file);
708 if(filename==NULL)
710 return NULL;
713 fin=fopen(filename,"r");
714 if(fin==NULL && (file!=NULL || errno!=ENOENT))
716 lirc_printf("%s: could not open config file %s\n",
717 lirc_prog,filename);
718 lirc_perror(lirc_prog);
720 else if(fin==NULL)
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);
729 else if(fin==NULL)
731 lirc_printf("%s: could not open config files "
732 "%s and %s\n",
733 lirc_prog,filename,LIRCRC_ROOT_FILE);
734 lirc_perror(lirc_prog);
736 else
738 free(filename);
739 filename = strdup(LIRCRC_ROOT_FILE);
740 if(filename==NULL)
742 fclose(fin);
743 lirc_printf("%s: out of memory\n",lirc_prog);
744 return NULL;
748 if(full_name && fin!=NULL)
750 *full_name = filename;
752 else
754 free(filename);
756 return fin;
759 static struct filestack_t *stack_push(struct filestack_t *parent)
761 struct filestack_t *entry;
762 entry = malloc(sizeof(struct filestack_t));
763 if (entry == NULL)
765 lirc_printf("%s: out of memory\n",lirc_prog);
766 return NULL;
768 entry->file = NULL;
769 entry->name = NULL;
770 entry->line = 0;
771 entry->parent = parent;
772 return entry;
775 static struct filestack_t *stack_pop(struct filestack_t *entry)
777 struct filestack_t *parent = NULL;
778 if (entry)
780 parent = entry->parent;
781 if (entry->name)
782 free(entry->name);
783 free(entry);
785 return parent;
788 static void stack_free(struct filestack_t *entry)
790 while (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;
801 int sockfd = -1;
802 char *sha_bang, *sha_bang2, *filename;
803 char *command;
804 int ret;
806 filename = NULL;
807 sha_bang = NULL;
808 if(lirc_readconfig_only_internal(file,config,check,&filename,&sha_bang)==-1)
810 return -1;
813 if(sha_bang == NULL)
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);
827 if(sockfd==-1)
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;
837 free(filename);
839 /* tell daemon lirc_prog */
840 if(lirc_identify(sockfd) == LIRC_RET_SUCCESS)
842 /* we're connected */
843 return 0;
845 close(sockfd);
846 lirc_freeconfig(*config);
847 return -1;
849 close(sockfd);
850 sockfd = -1;
852 /* launch lircrcd */
853 sha_bang2=sha_bang!=NULL ? sha_bang:"lircrcd";
855 command=malloc(strlen(sha_bang2)+1+strlen(filename)+1);
856 if(command==NULL)
858 goto lirc_readconfig_compat;
860 strcpy(command, sha_bang2);
861 strcat(command, " ");
862 strcat(command, filename);
864 ret=system(command);
866 if(ret==-1 || WEXITSTATUS(ret)!=EXIT_SUCCESS)
868 goto lirc_readconfig_compat;
871 if(sha_bang!=NULL) free(sha_bang);
872 free(filename);
874 sockfd=socket(AF_UNIX,SOCK_STREAM,0);
875 if(sockfd==-1)
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;
886 return 0;
889 close(sockfd);
890 lirc_freeconfig(*config);
891 return -1;
893 lirc_readconfig_compat:
894 /* compat fallback */
895 if(sockfd != -1) close(sockfd);
896 if(sha_bang!=NULL) free(sha_bang);
897 free(filename);
898 return 0;
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),
911 char **full_name,
912 char **sha_bang)
914 char *string,*eq,*token,*token2,*token3;
915 struct filestack_t *filestack, *stack_tmp;
916 int open_files;
917 struct lirc_config_entry *new_entry,*first,*last;
918 char *mode,*remote;
919 int ret=0;
920 int firstline=1;
921 char *save_full_name = NULL;
923 filestack = stack_push(NULL);
924 if (filestack == NULL)
926 return -1;
928 filestack->file = lirc_open(file, NULL, &(filestack->name));
929 if (filestack->file == NULL)
931 stack_free(filestack);
932 return -1;
934 filestack->line = 0;
935 open_files = 1;
937 first=new_entry=last=NULL;
938 mode=NULL;
939 remote=LIRC_ALL;
940 while (filestack)
942 if((ret=lirc_readline(&string,filestack->file))==-1 ||
943 string==NULL)
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);
952 open_files--;
953 continue;
955 /* check for sha-bang */
956 if(firstline && sha_bang)
958 firstline = 0;
959 if(strncmp(string, "#!", 2)==0)
961 *sha_bang=strdup(string+2);
962 if(*sha_bang==NULL)
964 lirc_printf("%s: out of memory\n",
965 lirc_prog);
966 ret=-1;
967 free(string);
968 break;
972 filestack->line++;
973 eq=strchr(string,'=');
974 if(eq==NULL)
976 token=strtok(string," \t");
977 if(token==NULL)
979 /* ignore empty line */
981 else if(token[0]=='#')
983 /* ignore comment */
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",
991 lirc_prog,
992 filestack->name,
993 filestack->line);
994 ret=-1;
996 else
998 token2 = strtok(NULL, "");
999 token2 = lirc_trim(token2);
1000 lirc_parse_include
1001 (token2, filestack->name,
1002 filestack->line);
1003 stack_tmp = stack_push(filestack);
1004 if (stack_tmp == NULL)
1006 ret=-1;
1008 else
1010 stack_tmp->file = lirc_open(token2, filestack->name, &(stack_tmp->name));
1011 stack_tmp->line = 0;
1012 if (stack_tmp->file)
1014 open_files++;
1015 filestack = stack_tmp;
1017 else
1019 stack_pop(stack_tmp);
1020 ret=-1;
1025 else
1027 token2=strtok(NULL," \t");
1028 if(token2!=NULL &&
1029 (token3=strtok(NULL," \t"))!=NULL)
1031 lirc_printf("%s: unexpected token in line %s:%d\n",
1032 lirc_prog,filestack->name,filestack->line);
1034 else
1036 ret=lirc_mode(token,token2,&mode,
1037 &new_entry,&first,&last,
1038 check,
1039 filestack->name,
1040 filestack->line);
1041 if(ret==0)
1043 if(remote!=LIRC_ALL)
1044 free(remote);
1045 remote=LIRC_ALL;
1047 else
1049 if(mode!=NULL)
1051 free(mode);
1052 mode=NULL;
1054 if(new_entry!=NULL)
1056 lirc_freeconfigentries
1057 (new_entry);
1058 new_entry=NULL;
1064 else
1066 eq[0]=0;
1067 token=lirc_trim(string);
1068 token2=lirc_trim(eq+1);
1069 if(token[0]=='#')
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);
1077 ret=-1;
1079 else
1081 token2=strdup(token2);
1082 if(token2==NULL)
1084 lirc_printf("%s: out of memory\n",
1085 lirc_prog);
1086 ret=-1;
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)
1096 free(remote);
1098 if(strcasecmp("*",token2)==0)
1100 remote=LIRC_ALL;
1101 free(token2);
1103 else
1105 remote=token2;
1108 else if(strcasecmp(token,"button")==0)
1110 struct lirc_code *code;
1112 code=(struct lirc_code *)
1113 malloc(sizeof(struct lirc_code));
1114 if(code==NULL)
1116 free(token2);
1117 lirc_printf("%s: out of "
1118 "memory\n",
1119 lirc_prog);
1120 ret=-1;
1122 else
1124 code->remote=remote;
1125 if(strcasecmp("*",token2)==0)
1127 code->button=LIRC_ALL;
1128 free(token2);
1130 else
1132 code->button=token2;
1134 code->next=NULL;
1136 if(new_entry->code==NULL)
1138 new_entry->code=code;
1140 else
1142 new_entry->next_code->next
1143 =code;
1145 new_entry->next_code=code;
1146 if(remote!=LIRC_ALL)
1148 remote=strdup(remote);
1149 if(remote==NULL)
1151 lirc_printf("%s: out of memory\n",lirc_prog);
1152 ret=-1;
1157 else if(strcasecmp(token,"delay")==0)
1159 char *end;
1161 errno=ERANGE+1;
1162 new_entry->rep_delay=strtoul(token2,&end,0);
1163 if((new_entry->rep_delay==ULONG_MAX
1164 && errno==ERANGE)
1165 || end[0]!=0
1166 || strlen(token2)==0)
1168 lirc_printf("%s: \"%s\" not"
1169 " a valid number for "
1170 "delay\n",lirc_prog,
1171 token2);
1173 free(token2);
1175 else if(strcasecmp(token,"repeat")==0)
1177 char *end;
1179 errno=ERANGE+1;
1180 new_entry->rep=strtoul(token2,&end,0);
1181 if((new_entry->rep==ULONG_MAX
1182 && errno==ERANGE)
1183 || end[0]!=0
1184 || strlen(token2)==0)
1186 lirc_printf("%s: \"%s\" not"
1187 " a valid number for "
1188 "repeat\n",lirc_prog,
1189 token2);
1191 free(token2);
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));
1199 if(new_list==NULL)
1201 free(token2);
1202 lirc_printf("%s: out of "
1203 "memory\n",
1204 lirc_prog);
1205 ret=-1;
1207 else
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;
1216 else
1218 new_entry->next_config->next
1219 =new_list;
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);
1232 free(token2);
1234 else
1236 free(token2);
1237 lirc_printf("%s: unknown token \"%s\" in %s:%d ignored\n",
1238 lirc_prog,token,filestack->name,filestack->line);
1242 free(string);
1243 if(ret==-1) break;
1245 if(remote!=LIRC_ALL)
1246 free(remote);
1247 if(new_entry!=NULL)
1249 if(ret==0)
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);
1256 else
1258 lirc_freeconfigentries(new_entry);
1259 new_entry=NULL;
1262 if(mode!=NULL)
1264 if(ret==0)
1266 lirc_printf("%s: warning: no end token found for mode "
1267 "\"%s\"\n",lirc_prog,mode);
1269 free(mode);
1271 if(ret==0)
1273 char *startupmode;
1275 *config=(struct lirc_config *)
1276 malloc(sizeof(struct lirc_config));
1277 if(*config==NULL)
1279 lirc_printf("%s: out of memory\n",lirc_prog);
1280 lirc_freeconfigentries(first);
1281 return(-1);
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;
1294 else
1296 *config=NULL;
1297 lirc_freeconfigentries(first);
1298 if(*sha_bang!=NULL)
1300 free(*sha_bang);
1301 *sha_bang=NULL;
1304 if(filestack)
1306 stack_free(filestack);
1308 if(save_full_name)
1310 free(save_full_name);
1312 return(ret);
1315 static char *lirc_startupmode(struct lirc_config_entry *first)
1317 struct lirc_config_entry *scan;
1318 char *startupmode;
1320 startupmode=NULL;
1321 scan=first;
1322 /* Set a startup mode based on flags=startup_mode */
1323 while(scan!=NULL)
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;
1330 break;
1332 else {
1333 lirc_printf("%s: startup_mode flags requires 'mode ='\n",
1334 lirc_prog);
1337 scan=scan->next;
1340 /* Set a default mode if we find a mode = client app name */
1341 if(startupmode==NULL) {
1342 scan=first;
1343 while(scan!=NULL)
1345 if(scan->mode!=NULL && strcasecmp(lirc_prog,scan->mode)==0)
1347 startupmode=lirc_prog;
1348 break;
1350 scan=scan->next;
1354 if(startupmode==NULL) return(NULL);
1355 scan=first;
1356 while(scan!=NULL)
1358 if(scan->change_mode!=NULL && scan->flags&once &&
1359 strcasecmp(startupmode,scan->change_mode)==0)
1361 scan->flags|=ecno;
1363 scan=scan->next;
1365 return(startupmode);
1368 void lirc_freeconfig(struct lirc_config *config)
1370 if(config!=NULL)
1372 if(config->sockfd!=-1)
1374 (void) close(config->sockfd);
1375 config->sockfd=-1;
1377 lirc_freeconfigentries(config->first);
1378 free(config->current_mode);
1379 free(config);
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;
1389 c=first;
1390 while(c!=NULL)
1392 if(c->prog) free(c->prog);
1393 if(c->change_mode) free(c->change_mode);
1394 if(c->mode) free(c->mode);
1396 code=c->code;
1397 while(code!=NULL)
1399 if(code->remote!=NULL && code->remote!=LIRC_ALL)
1400 free(code->remote);
1401 if(code->button!=NULL && code->button!=LIRC_ALL)
1402 free(code->button);
1403 code_temp=code->next;
1404 free(code);
1405 code=code_temp;
1408 list=c->config;
1409 while(list!=NULL)
1411 if(list->string) free(list->string);
1412 list_temp=list->next;
1413 free(list);
1414 list=list_temp;
1416 config_temp=c->next;
1417 free(c);
1418 c=config_temp;
1422 static void lirc_clearmode(struct lirc_config *config)
1424 struct lirc_config_entry *scan;
1426 if(config->current_mode==NULL)
1428 return;
1430 scan=config->first;
1431 while(scan!=NULL)
1433 if(scan->change_mode!=NULL)
1435 if(strcasecmp(scan->change_mode,config->current_mode)==0)
1437 scan->flags&=~ecno;
1440 scan=scan->next;
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)
1449 char *s;
1450 int do_once=1;
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)
1464 do_once=0;
1466 else
1468 scan->flags|=ecno;
1472 if(scan->next_config!=NULL &&
1473 scan->prog!=NULL &&
1474 (lirc_prog == NULL || strcasecmp(scan->prog,lirc_prog)==0) &&
1475 do_once==1)
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;
1481 return(s);
1483 return(NULL);
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)
1494 return rep==0 ||
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)
1506 int iscode=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);
1520 return iscode;
1524 if(rep!=0) return(0);
1526 /* handle toggle_reset */
1527 if(scan->flags & toggle_reset)
1529 scan->next_config = scan->config;
1532 codes=scan->code;
1533 if(codes==scan->next_code) return(0);
1534 codes=codes->next;
1535 /* rebase code sequence */
1536 while(codes!=scan->next_code->next)
1538 struct lirc_code *prev,*next;
1539 int flag=1;
1541 prev=scan->code;
1542 next=codes;
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)
1551 prev=prev->next;
1552 next=next->next;
1554 else
1556 flag=0;break;
1559 else
1561 flag=0;break;
1564 if(flag==1)
1566 if(prev->remote==LIRC_ALL ||
1567 strcasecmp(prev->remote,remote)==0)
1569 if(prev->button==LIRC_ALL ||
1570 strcasecmp(prev->button,button)==0)
1572 if(rep==0)
1574 scan->next_code=prev->next;
1575 return(0);
1580 codes=codes->next;
1582 scan->next_code=scan->code;
1583 return(0);
1586 char *lirc_ir2char(struct lirc_config *config,char *code)
1588 static int warning=1;
1589 char *string;
1591 if(warning)
1593 fprintf(stderr,"%s: warning: lirc_ir2char() is obsolete\n",
1594 lirc_prog);
1595 warning=0;
1597 if(lirc_code2char(config,code,&string)==-1) return(NULL);
1598 return(string);
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;
1608 int success;
1609 int ret;
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)
1617 if(ret > 0)
1619 *string = buf;
1621 else
1623 *string = NULL;
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,
1633 char **prog)
1635 char *backup;
1636 int ret;
1638 backup = lirc_prog;
1639 lirc_prog = NULL;
1641 ret = lirc_code2char_internal(config, code, string, prog);
1643 lirc_prog = backup;
1644 return ret;
1647 static int lirc_code2char_internal(struct lirc_config *config,char *code,
1648 char **string, char **prog)
1650 int rep;
1651 char *backup;
1652 char *remote,*button;
1653 char *s=NULL;
1654 struct lirc_config_entry *scan;
1655 int quit_happened;
1657 *string=NULL;
1658 if(sscanf(code,"%*x %x %*s %*s\n",&rep)==1)
1660 backup=strdup(code);
1661 if(backup==NULL) return(-1);
1663 strtok(backup," ");
1664 strtok(NULL," ");
1665 button=strtok(NULL," ");
1666 remote=strtok(NULL,"\n");
1668 if(button==NULL || remote==NULL)
1670 free(backup);
1671 return(0);
1674 scan=config->next;
1675 quit_happened=0;
1676 while(scan!=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)) &&
1683 quit_happened==0
1686 s=lirc_execute(config,scan);
1687 if(s != NULL && prog != NULL)
1689 *prog = scan->prog;
1691 if(scan->flags&quit)
1693 quit_happened=1;
1694 config->next=NULL;
1695 scan=scan->next;
1696 continue;
1698 else if(s!=NULL)
1700 config->next=scan->next;
1701 break;
1704 scan=scan->next;
1706 free(backup);
1707 if(s!=NULL)
1709 *string=s;
1710 return(0);
1713 config->next=config->first;
1714 return(0);
1717 #define PACKET_SIZE 100
1719 char *lirc_nextir(void)
1721 static int warning=1;
1722 char *code;
1723 int ret;
1725 if(warning)
1727 fprintf(stderr,"%s: warning: lirc_nextir() is obsolete\n",
1728 lirc_prog);
1729 warning=0;
1731 ret=lirc_nextcode(&code);
1732 if(ret==-1) return(NULL);
1733 return(code);
1737 int lirc_nextcode(char **code)
1739 static int packet_size=PACKET_SIZE;
1740 static int end_len=0;
1741 ssize_t len=0;
1742 char *end,c;
1744 *code=NULL;
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);
1751 return(-1);
1753 lirc_buffer[0]=0;
1755 while((end=strchr(lirc_buffer,'\n'))==NULL)
1757 if(end_len>=packet_size)
1759 char *new_buffer;
1761 packet_size+=PACKET_SIZE;
1762 new_buffer=(char *) realloc(lirc_buffer,packet_size+1);
1763 if(new_buffer==NULL)
1765 return(-1);
1767 lirc_buffer=new_buffer;
1769 len=read(lirc_lircd,lirc_buffer+end_len,packet_size-end_len);
1770 if(len<=0)
1772 if(len==-1 && errno==EAGAIN) return(0);
1773 else return(-1);
1775 end_len+=len;
1776 lirc_buffer[end_len]=0;
1777 /* return if next code not yet available completely */
1778 if((end=strchr(lirc_buffer,'\n'))==NULL)
1780 return(0);
1783 /* copy first line to buffer (code) and move remaining chars to
1784 lirc_buffers start */
1785 end++;
1786 end_len=strlen(end);
1787 c=end[0];
1788 end[0]=0;
1789 *code=strdup(lirc_buffer);
1790 end[0]=c;
1791 memmove(lirc_buffer,end,end_len+1);
1792 if(*code==NULL) return(-1);
1793 return(0);
1796 size_t lirc_getsocketname(const char *filename, char *buf, size_t size)
1798 if(strlen(filename)+2<=size)
1800 strcpy(buf, filename);
1801 strcat(buf, "d");
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;
1812 int success;
1813 int ret;
1815 ret = lirc_send_command(config->sockfd, "GETMODE\n",
1816 buf, &buf_len, &success);
1817 if(success == LIRC_RET_SUCCESS)
1819 if(ret > 0)
1821 return buf;
1823 else
1825 return NULL;
1828 return NULL;
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;
1839 int success;
1840 int ret;
1841 char cmd[LIRC_PACKET_SIZE];
1842 if(snprintf(cmd, LIRC_PACKET_SIZE, "SETMODE%s%s\n",
1843 mode ? " ":"",
1844 mode ? mode:"")
1845 >= LIRC_PACKET_SIZE)
1847 return NULL;
1850 ret = lirc_send_command(config->sockfd, cmd,
1851 buf, &buf_len, &success);
1852 if(success == LIRC_RET_SUCCESS)
1854 if(ret > 0)
1856 return buf;
1858 else
1860 return NULL;
1863 return NULL;
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]="";
1874 char *end;
1875 static int head=0, tail=0;
1876 int ret;
1877 ssize_t n;
1878 fd_set fds;
1879 struct timeval tv;
1881 if(head>0)
1883 memmove(buffer,buffer+head,tail-head+1);
1884 tail-=head;
1885 head=0;
1886 end=strchr(buffer,'\n');
1888 else
1890 end=NULL;
1892 if(strlen(buffer)!=tail)
1894 lirc_printf("%s: protocol error\n", lirc_prog);
1895 goto lirc_read_string_error;
1898 while(end==NULL)
1900 if(LIRC_PACKET_SIZE<=tail)
1902 lirc_printf("%s: bad packet\n", lirc_prog);
1903 goto lirc_read_string_error;
1906 FD_ZERO(&fds);
1907 FD_SET(fd,&fds);
1908 tv.tv_sec=LIRC_TIMEOUT;
1909 tv.tv_usec=0;
1912 ret=select(fd+1,&fds,NULL,NULL,&tv);
1914 while(ret==-1 && errno==EINTR);
1915 if(ret==-1)
1917 lirc_printf("%s: select() failed\n", lirc_prog);
1918 lirc_perror(lirc_prog);
1919 goto lirc_read_string_error;
1921 else if(ret==0)
1923 lirc_printf("%s: timeout\n", lirc_prog);
1924 goto lirc_read_string_error;
1927 n=read(fd, buffer+tail, LIRC_PACKET_SIZE-tail);
1928 if(n<=0)
1930 lirc_printf("%s: read() failed\n", lirc_prog);
1931 lirc_perror(lirc_prog);
1932 goto lirc_read_string_error;
1934 buffer[tail+n]=0;
1935 tail+=n;
1936 end=strchr(buffer,'\n');
1939 end[0]=0;
1940 head=strlen(buffer)+1;
1941 return(buffer);
1943 lirc_read_string_error:
1944 head=tail=0;
1945 buffer[0]=0;
1946 return(NULL);
1949 int lirc_send_command(int sockfd, const char *command, char *buf, size_t *buf_len, int *ret_status)
1951 int done,todo;
1952 const char *string,*data;
1953 char *endptr;
1954 enum packet_state state;
1955 int status,n;
1956 unsigned long data_n=0;
1957 size_t written=0, max=0, len;
1959 if(buf_len!=NULL)
1961 max=*buf_len;
1963 todo=strlen(command);
1964 data=command;
1965 while(todo>0)
1967 done=write(sockfd,(void *) data,todo);
1968 if(done<0)
1970 lirc_printf("%s: could not send packet\n",
1971 lirc_prog);
1972 lirc_perror(lirc_prog);
1973 return(-1);
1975 data+=done;
1976 todo-=done;
1979 /* get response */
1980 status=LIRC_RET_SUCCESS;
1981 state=P_BEGIN;
1982 n=0;
1983 while(1)
1985 string=lirc_read_string(sockfd);
1986 if(string==NULL) return(-1);
1987 switch(state)
1989 case P_BEGIN:
1990 if(strcasecmp(string,"BEGIN")!=0)
1992 continue;
1994 state=P_MESSAGE;
1995 break;
1996 case P_MESSAGE:
1997 if(strncasecmp(string,command,strlen(string))!=0 ||
1998 strlen(string)+1!=strlen(command))
2000 state=P_BEGIN;
2001 continue;
2003 state=P_STATUS;
2004 break;
2005 case P_STATUS:
2006 if(strcasecmp(string,"SUCCESS")==0)
2008 status=LIRC_RET_SUCCESS;
2010 else if(strcasecmp(string,"END")==0)
2012 status=LIRC_RET_SUCCESS;
2013 goto good_packet;
2015 else if(strcasecmp(string,"ERROR")==0)
2017 lirc_printf("%s: command failed: %s",
2018 lirc_prog, command);
2019 status=LIRC_RET_ERROR;
2021 else
2023 goto bad_packet;
2025 state=P_DATA;
2026 break;
2027 case P_DATA:
2028 if(strcasecmp(string,"END")==0)
2030 goto good_packet;
2032 else if(strcasecmp(string,"DATA")==0)
2034 state=P_N;
2035 break;
2037 goto bad_packet;
2038 case P_N:
2039 errno=0;
2040 data_n=strtoul(string,&endptr,0);
2041 if(!*string || *endptr)
2043 goto bad_packet;
2045 if(data_n==0)
2047 state=P_END;
2049 else
2051 state=P_DATA_N;
2053 break;
2054 case P_DATA_N:
2055 len=strlen(string);
2056 if(buf!=NULL && written+len+1<max)
2058 memcpy(buf+written, string, len+1);
2060 written+=len+1;
2061 n++;
2062 if(n==data_n) state=P_END;
2063 break;
2064 case P_END:
2065 if(strcasecmp(string,"END")==0)
2067 goto good_packet;
2069 goto bad_packet;
2070 break;
2074 /* never reached */
2076 bad_packet:
2077 lirc_printf("%s: bad return packet\n", lirc_prog);
2078 return(-1);
2080 good_packet:
2081 if(ret_status!=NULL)
2083 *ret_status=status;
2085 if(buf_len!=NULL)
2087 *buf_len=written;
2089 return (int) data_n;
2092 int lirc_identify(int sockfd)
2094 char command[10+strlen(lirc_prog)+1+1];
2095 int success;
2097 sprintf(command, "IDENT %s\n", lirc_prog);
2099 (void) lirc_send_command(sockfd, command, NULL, NULL, &success);
2100 return success;