Added lirc.
[irreco.git] / lirc-0.8.4a / tools / lircrcd.c
blob7aaaef55e503a8bcbf931b6e4edb0ff2afe34cc8
1 /* $Id: lircrcd.c,v 5.3 2006/05/06 09:40:07 lirc Exp $ */
3 /****************************************************************************
4 ** lircrcd.c ***************************************************************
5 ****************************************************************************
7 * lircrcd - daemon that manages current mode for all applications
9 * Copyright (C) 2004 Christoph Bartelmus <lirc@bartelmus.de>
11 */
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
17 #include <getopt.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <string.h>
26 #include <limits.h>
27 #include <signal.h>
28 #include <time.h>
29 #include <sys/socket.h>
30 #include <sys/un.h>
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #include <syslog.h>
35 #include "lirc_client.h"
37 #define MAX_CLIENTS 100
38 #define PACKET_SIZE (256)
39 #define WHITE_SPACE " \t"
41 struct config_info
43 char *config_string;
44 struct config_info *next;
47 struct event_info
49 char *code;
50 struct config_info *first;
51 struct event_info *next;
54 struct client_data
56 int fd;
57 char *ident_string;
58 struct event_info *first_event;
59 char *pending_code;
62 struct protocol_directive
64 char *name;
65 int (*function)(int fd,char *message,char *arguments);
68 static int code_func(int fd,char *message,char *arguments);
69 static int ident_func(int fd,char *message,char *arguments);
70 static int getmode_func(int fd,char *message,char *arguments);
71 static int setmode_func(int fd,char *message,char *arguments);
72 static int send_result(int fd, char *message, const char *result);
73 static int send_success(int fd,char *message);
75 struct protocol_directive directives[] =
77 {"CODE",code_func},
78 {"IDENT",ident_func},
79 {"GETMODE",getmode_func},
80 {"SETMODE",setmode_func},
81 {NULL,NULL}
83 {"DEBUG",debug},
84 {"DEBUG_LEVEL",debug_level},
88 enum protocol_string_num {
89 P_BEGIN=0,
90 P_DATA,
91 P_END,
92 P_ERROR,
93 P_SUCCESS,
94 P_SIGHUP
97 char *protocol_string[] =
99 "BEGIN\n",
100 "DATA\n",
101 "END\n",
102 "ERROR\n",
103 "SUCCESS\n",
104 "SIGHUP\n"
107 static int debug;
109 #ifdef DEBUG
110 #define LOGPRINTF(level,fmt,args...) \
111 if(level<=debug) logprintf(LOG_DEBUG,fmt, ## args )
112 #define LOGPERROR(level,s) \
113 if(level<=debug) logperror(LOG_DEBUG,s)
114 #else
115 #define LOGPRINTF(level,fmt,args...) \
116 do {} while(0)
117 #define LOGPERROR(level,s) \
118 do {} while(0)
119 #endif
121 #define logprintf syslog
122 #define logperror(prio,s) if((s)!=NULL) syslog(prio,"%s: %m\n",(char *) s); else syslog(prio,"%m\n")
124 const char *progname="lircrcd";
126 static sig_atomic_t term=0;
127 static int termsig;
128 static int clin=0;
129 static struct client_data clis[MAX_CLIENTS];
131 static int daemonized=0;
133 static struct lirc_config *config;
135 static int send_error(int fd,char *message,char *format_str, ...);
136 static int handle_input();
138 static inline int max(int a,int b)
140 return(a>b ? a:b);
143 static int get_client_index(int fd)
145 int i;
147 for(i=0; i<clin; i++)
149 if(fd == clis[i].fd)
151 return i;
154 /* shouldn't ever happen */
155 return -1;
158 /* cut'n'paste from fileutils-3.16: */
160 #define isodigit(c) ((c) >= '0' && (c) <= '7')
162 /* Return a positive integer containing the value of the ASCII
163 octal number S. If S is not an octal number, return -1. */
165 static int
166 oatoi (s)
167 char *s;
169 register int i;
171 if (*s == 0)
172 return -1;
173 for (i = 0; isodigit (*s); ++s)
174 i = i * 8 + *s - '0';
175 if (*s)
176 return -1;
177 return i;
180 /* A safer write(), since sockets might not write all but only some of the
181 bytes requested */
183 inline int write_socket(int fd, char *buf, int len)
185 int done,todo=len;
187 while(todo)
189 done=write(fd,buf,todo);
190 if(done<=0) return(done);
191 buf+=done;
192 todo-=done;
194 return(len);
197 inline int write_socket_len(int fd, char *buf)
199 int len;
201 len=strlen(buf);
202 if(write_socket(fd,buf,len)<len) return(0);
203 return(1);
206 inline int read_timeout(int fd,char *buf,int len,int timeout)
208 fd_set fds;
209 struct timeval tv;
210 int ret,n;
212 FD_ZERO(&fds);
213 FD_SET(fd,&fds);
214 tv.tv_sec=timeout;
215 tv.tv_usec=0;
217 /* CAVEAT: (from libc documentation)
218 Any signal will cause `select' to return immediately. So if your
219 program uses signals, you can't rely on `select' to keep waiting
220 for the full time specified. If you want to be sure of waiting
221 for a particular amount of time, you must check for `EINTR' and
222 repeat the `select' with a newly calculated timeout based on the
223 current time. See the example below.
225 Obviously the timeout is not recalculated in the example because
226 this is done automatically on Linux systems...
231 ret=select(fd+1,&fds,NULL,NULL,&tv);
233 while(ret==-1 && errno==EINTR);
234 if(ret==-1)
236 logprintf(LOG_ERR,"select() failed");
237 logperror(LOG_ERR,NULL);
238 return(-1);
240 else if(ret==0) return(0); /* timeout */
241 n=read(fd,buf,len);
242 if(n==-1)
244 logprintf(LOG_ERR,"read() failed");
245 logperror(LOG_ERR,NULL);
246 return(-1);
248 return(n);
251 static void sigterm(int sig)
253 /* all signals are blocked now */
254 if(term) return;
255 term=1;
256 termsig=sig;
259 static void nolinger(int sock)
261 static struct linger linger = {0, 0};
262 int lsize = sizeof(struct linger);
263 setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, lsize);
266 static void free_config_info(struct config_info *ci)
268 struct config_info *next;
270 while(ci != NULL)
272 if(ci->config_string != NULL) free(ci->config_string);
274 next = ci->next;
275 free(ci);
276 ci = next;
280 static void free_event_info(struct event_info *ei)
282 struct event_info *next;
284 while(ei != NULL)
286 if(ei->code != NULL) free(ei->code);
288 free_config_info(ei->first);
290 next = ei->next;
291 free(ei);
292 ei = next;
296 static void remove_client(int i)
298 shutdown(clis[i].fd,2);
299 close(clis[i].fd);
300 if(clis[i].ident_string) free(clis[i].ident_string);
301 if(clis[i].pending_code) free(clis[i].pending_code);
302 free_event_info(clis[i].first_event);
304 LOGPRINTF(1, "removed client");
306 clin--;
307 for(;i<clin;i++)
309 clis[i]=clis[i+1];
313 void add_client(int sock)
315 int fd;
316 int clilen;
317 struct sockaddr client_addr;
318 int flags;
320 clilen=sizeof(client_addr);
321 fd=accept(sock,(struct sockaddr *)&client_addr,&clilen);
322 if(fd==-1)
324 logprintf(LOG_ERR,"accept() failed for new client");
325 logperror(LOG_ERR,NULL);
326 return;
329 if(fd>=FD_SETSIZE || clin>=MAX_CLIENTS)
331 logprintf(LOG_ERR,"connection rejected");
332 shutdown(fd,2);
333 close(fd);
334 return;
336 nolinger(fd);
337 flags=fcntl(fd,F_GETFL,0);
338 if(flags!=-1)
340 fcntl(fd,F_SETFL,flags|O_NONBLOCK);
342 LOGPRINTF(1, "accepted new client");
343 clis[clin].fd=fd;
344 clis[clin].ident_string = NULL;
345 clis[clin].first_event = NULL;
346 clis[clin].pending_code = NULL;
347 clin++;
350 static int opensocket(const char *configfile, const char *socketname,
351 mode_t permission, struct sockaddr_un *addr)
353 int sockfd;
354 struct stat s;
355 int new=1;
356 int ret;
358 /* get socket name */
359 if((socketname==NULL &&
360 lirc_getsocketname(configfile,
361 addr->sun_path, sizeof(addr->sun_path)) >
362 sizeof(addr->sun_path)) ||
363 (socketname!=NULL &&
364 strlen(socketname)>=sizeof(addr->sun_path)))
366 fprintf(stderr, "%s: filename too long", progname);
367 return -1;
369 if(socketname!=NULL)
371 strcpy(addr->sun_path, socketname);
374 /* create socket*/
375 sockfd=socket(AF_UNIX,SOCK_STREAM,0);
376 if(sockfd==-1)
378 fprintf(stderr,"%s: could not create socket\n",progname);
379 perror(progname);
380 return -1;
384 get owner, permissions, etc.
385 so new socket can be the same since we
386 have to delete the old socket.
388 ret=stat(addr->sun_path, &s);
389 if(ret==-1 && errno!=ENOENT)
391 fprintf(stderr,"%s: could not get file information for %s\n",
392 progname, addr->sun_path);
393 perror(progname);
394 goto opensocket_failed;
397 if(ret!=-1)
399 new=0;
400 ret=unlink(addr->sun_path);
401 if(ret==-1)
403 fprintf(stderr,"%s: could not delete %s\n",
404 progname, addr->sun_path);
405 perror(progname);
406 goto opensocket_failed;
410 addr->sun_family=AF_UNIX;
411 if(bind(sockfd, (struct sockaddr *) addr, sizeof(*addr))==-1)
413 fprintf(stderr,"%s: could not assign address to socket\n",
414 progname);
415 perror(progname);
416 goto opensocket_failed;
419 if(new ?
420 chmod(addr->sun_path, permission):
421 (chmod(addr->sun_path, s.st_mode)==-1 ||
422 chown(addr->sun_path, s.st_uid, s.st_gid)==-1)
425 fprintf(stderr,"%s: could not set file permissions\n",
426 progname);
427 perror(progname);
428 goto opensocket_failed;
431 listen(sockfd,3);
432 nolinger(sockfd);
434 return sockfd;
436 opensocket_failed:
437 close(sockfd);
438 return -1;
441 static int code_func(int fd,char *message,char *arguments)
443 int index;
444 struct event_info *ei;
445 struct config_info *ci;
446 int ret;
448 index = get_client_index(fd);
449 if(index == -1)
451 return send_error(fd, message, "identify yourself first!\n");
453 if(clis[index].pending_code != NULL)
455 return send_error(fd, message, "protocol error\n");
458 LOGPRINTF(3, "%s asking for code -%s-",
459 clis[index].ident_string, arguments);
461 ei = clis[index].first_event;
462 if(ei != NULL)
464 LOGPRINTF(3, "compare: -%s- -%s-", ei->code, arguments);
465 if(strcmp(ei->code, arguments) == 0)
468 ci = ei->first;
469 if(ci != NULL)
471 LOGPRINTF(3, "result: -%s-",
472 ci->config_string);
473 ret = send_result(fd, message,
474 ci->config_string);
475 ei->first = ci->next;
476 free(ci->config_string);
477 free(ci);
478 return ret;
480 else
482 clis[index].first_event = ei->next;
483 free(ei->code);
484 free(ei);
485 return send_success(fd, message);
488 else
490 return send_success(fd, message);
494 clis[index].pending_code = strdup(arguments);
495 if(clis[index].pending_code == NULL)
497 return send_error(fd, message, "out of memory\n");
499 return 1;
502 static int ident_func(int fd,char *message,char *arguments)
504 int index;
506 if(arguments == NULL)
508 return send_error(fd, message, "protocol error\n");
510 LOGPRINTF(2, "IDENT %s", arguments);
511 index = get_client_index(fd);
512 if(clis[index].ident_string != NULL)
514 return send_error(fd, message, "protocol error\n");
516 clis[index].ident_string = strdup(arguments);
517 if(clis[index].ident_string == NULL)
519 return send_error(fd, message, "out of memory\n");
522 LOGPRINTF(1, "%s connected", clis[index].ident_string);
523 return(send_success(fd,message));
526 static int getmode_func(int fd,char *message,char *arguments)
528 if(arguments != NULL)
530 return send_error(fd, message, "protocol error\n");
532 LOGPRINTF(2, "GETMODE");
533 if(lirc_getmode(config))
535 return send_result(fd, message, lirc_getmode(config));
537 return(send_success(fd,message));
540 static int setmode_func(int fd,char *message,char *arguments)
542 const char *mode = NULL;
544 LOGPRINTF(2, arguments!=NULL ? "SETMODE %s":"SETMODE", arguments);
545 if((mode = lirc_setmode(config, arguments)))
547 return send_result(fd, message, mode);
549 return arguments==NULL ?
550 send_success(fd,message):
551 send_error(fd, message, "out of memory\n");
554 static int send_result(int fd, char *message, const char *result)
556 char *count = "1\n";
557 char buffer[strlen(result)+1+1];
559 sprintf(buffer, "%s\n", result);
561 if(!(write_socket_len(fd,protocol_string[P_BEGIN]) &&
562 write_socket_len(fd,message) &&
563 write_socket_len(fd,protocol_string[P_SUCCESS]) &&
564 write_socket_len(fd,protocol_string[P_DATA]) &&
565 write_socket_len(fd,count) &&
566 write_socket_len(fd,buffer) &&
567 write_socket_len(fd,protocol_string[P_END]))) return(0);
568 return(1);
571 static int send_success(int fd,char *message)
573 if(!(write_socket_len(fd,protocol_string[P_BEGIN]) &&
574 write_socket_len(fd,message) &&
575 write_socket_len(fd,protocol_string[P_SUCCESS]) &&
576 write_socket_len(fd,protocol_string[P_END]))) return(0);
577 return(1);
580 static int send_error(int fd,char *message,char *format_str, ...)
582 char lines[4],buffer[PACKET_SIZE+1];
583 int i,n,len;
584 va_list ap;
585 char *s1,*s2;
587 va_start(ap,format_str);
588 vsprintf(buffer,format_str,ap);
589 va_end(ap);
591 s1=strrchr(message,'\n');
592 s2=strrchr(buffer,'\n');
593 if(s1!=NULL) s1[0]=0;
594 if(s2!=NULL) s2[0]=0;
595 logprintf(LOG_ERR,"error processing command: %s",message);
596 logprintf(LOG_ERR,"%s",buffer);
597 if(s1!=NULL) s1[0]='\n';
598 if(s2!=NULL) s2[0]='\n';
600 n=0;
601 len=strlen(buffer);
602 for(i=0;i<len;i++) if(buffer[i]=='\n') n++;
603 sprintf(lines,"%d\n",n);
605 if(!(write_socket_len(fd,protocol_string[P_BEGIN]) &&
606 write_socket_len(fd,message) &&
607 write_socket_len(fd,protocol_string[P_ERROR]) &&
608 write_socket_len(fd,protocol_string[P_DATA]) &&
609 write_socket_len(fd,lines) &&
610 write_socket_len(fd,buffer) &&
611 write_socket_len(fd,protocol_string[P_END]))) return(0);
612 return(1);
615 static int get_command(int fd)
617 int length;
618 char buffer[PACKET_SIZE+1],backup[PACKET_SIZE+1];
619 char *end;
620 int packet_length,i;
621 char *directive;
623 length=read_timeout(fd,buffer,PACKET_SIZE,0);
624 packet_length=0;
625 while(length>packet_length)
627 buffer[length]=0;
628 end=strchr(buffer,'\n');
629 if(end==NULL)
631 logprintf(LOG_ERR,"bad send packet: \"%s\"",buffer);
632 /* remove clients that behave badly */
633 return(0);
635 end[0]=0;
636 LOGPRINTF(1,"received command: \"%s\"",buffer);
637 packet_length=strlen(buffer)+1;
639 strcpy(backup,buffer);strcat(backup,"\n");
640 directive=strtok(buffer,WHITE_SPACE);
641 if(directive==NULL)
643 if(!send_error(fd,backup,"bad send packet\n"))
644 return(0);
645 goto skip;
647 for(i=0;directives[i].name!=NULL;i++)
649 if(strcasecmp(directive,directives[i].name)==0)
651 if(!directives[i].
652 function(fd,backup,strtok(NULL,"")))
653 return(0);
654 goto skip;
658 if(!send_error(fd,backup,"unknown directive: \"%s\"\n",
659 directive))
660 return(0);
661 skip:
662 if(length>packet_length)
664 int new_length;
666 memmove(buffer,buffer+packet_length,
667 length-packet_length+1);
668 if(strchr(buffer,'\n')==NULL)
670 new_length=read_timeout(fd,buffer+length-
671 packet_length,
672 PACKET_SIZE-
673 (length-
674 packet_length),5);
675 if(new_length>0)
677 length=length-packet_length+new_length;
679 else
681 length=new_length;
684 else
686 length-=packet_length;
688 packet_length=0;
692 if(length==0) /* EOF: connection closed by client */
694 return(0);
696 return(1);
699 static void loop(int sockfd, int lircdfd)
701 fd_set fds;
702 int maxfd,i;
703 int ret;
705 while(1)
708 /* handle signals */
709 if(term)
711 logprintf(LOG_NOTICE,"caught signal");
712 return;
714 FD_ZERO(&fds);
715 FD_SET(sockfd,&fds);
716 FD_SET(lircdfd,&fds);
717 maxfd=max(sockfd, lircdfd);
719 for(i=0;i<clin;i++)
721 FD_SET(clis[i].fd,&fds);
722 maxfd=max(maxfd,clis[i].fd);
724 LOGPRINTF(3, "select");
725 ret=select(maxfd+1,&fds,NULL,NULL,NULL);
727 if(ret==-1 && errno!=EINTR)
729 logprintf(LOG_ERR,"select() failed");
730 logperror(LOG_ERR,NULL);
731 raise(SIGTERM);
732 continue;
735 while(ret==-1 && errno==EINTR);
737 for(i=0;i<clin;i++)
739 if(FD_ISSET(clis[i].fd,&fds))
741 FD_CLR(clis[i].fd,&fds);
742 if(get_command(clis[i].fd)==0)
744 remove_client(i);
745 i--;
746 if(clin == 0)
748 logprintf(LOG_INFO, "last client disconnected, shutting down");
749 return;
754 if(FD_ISSET(sockfd,&fds))
756 LOGPRINTF(1,"registering local client");
757 add_client(sockfd);
759 if(FD_ISSET(lircdfd,&fds))
761 if(!handle_input())
763 while(clin>0)
765 remove_client(0);
767 logprintf(LOG_ERR, "connection lost");
768 return;
774 static int schedule(int index, char *config_string)
776 struct event_info *e;
777 struct config_info *c, *n;
778 LOGPRINTF(2, "schedule(%s): -%s-",
779 clis[index].ident_string, config_string);
781 e = clis[index].first_event;
782 while(e->next) e = e->next;
784 c = e->first;
785 while(c && c->next) c = c->next;
787 n = malloc(sizeof(*c));
789 if(n == NULL)
791 return 0;
794 n->config_string = strdup(config_string);
796 if(n->config_string == NULL)
798 free(n);
799 return 0;
801 n->next = NULL;
803 if(c == NULL)
805 e->first = n;
807 else
809 c->next = n;
811 return 1;
814 static int handle_input()
816 char *code;
817 char *config_string;
818 char *prog;
819 int ret;
820 struct event_info *e, *n;
821 int i;
823 LOGPRINTF(1,"input from lircd");
824 if(lirc_nextcode(&code) != 0)
826 return 0;
829 for(i=0; i<clin; i++)
831 n = malloc(sizeof(*n));
833 if(n == NULL)
835 return 0;
838 n->code = strdup(code);
840 if(n->code == NULL)
842 free(n);
843 return 0;
846 /* remove trailing \n */
847 n->code[strlen(n->code)-1] = 0;
849 n->first = NULL;
850 n->next = NULL;
852 e = clis[i].first_event;
853 while(e && e->next) e = e->next;
855 if(e == NULL)
857 clis[i].first_event = n;
859 else
861 e->next = n;
864 LOGPRINTF(3, "input from lircd: \"%s\"", code);
865 while((ret=lirc_code2charprog(config, code, &config_string, &prog))==0 &&
866 config_string!=NULL)
868 int i;
870 LOGPRINTF(3, "%s: -%s-", prog, config_string);
871 for(i=0; i<clin; i++)
873 if(strcmp(prog, clis[i].ident_string) == 0)
875 if(!schedule(i, config_string))
877 return 0;
882 for(i=0; i<clin; i++)
884 if(clis[i].pending_code != NULL)
886 char message[strlen(clis[i].pending_code)+1];
887 char *backup;
889 LOGPRINTF(3, "pending_code(%s): -%s-",
890 clis[i].ident_string, clis[i].pending_code);
891 backup = clis[i].pending_code;
892 clis[i].pending_code = NULL;
894 sprintf(message, "CODE %s\n", backup);
895 (void) code_func(clis[i].fd, message, backup);
896 free(backup);
899 free(code);
901 return 1;
904 int main(int argc, char **argv)
906 char *configfile;
907 const char *socketfile = NULL;
908 mode_t permission=S_IRUSR|S_IWUSR;
909 int socket;
910 int lircdfd;
911 struct sigaction act;
912 struct sockaddr_un addr;
913 char dir[FILENAME_MAX+1] = { 0 };
915 debug = 0;
916 while(1)
918 int c;
919 static struct option long_options[] =
921 {"help",no_argument,NULL,'h'},
922 {"version",no_argument,NULL,'v'},
923 {"permission",required_argument,NULL,'p'},
924 {"output",required_argument,NULL,'o'},
925 {0, 0, 0, 0}
927 c = getopt_long(argc,argv,"hvp:o:",long_options,NULL);
928 if(c==-1)
929 break;
930 switch (c)
932 case 'h':
933 printf("Usage: %s [options] config-file\n",progname);
934 printf("\t -h --help\t\t\tdisplay this message\n");
935 printf("\t -v --version\t\t\tdisplay version\n");
936 printf("\t -p --permission=mode\t\tfile permissions for socket\n");
937 printf("\t -o --output=socket\t\toutput socket filename\n");
938 return(EXIT_SUCCESS);
939 case 'v':
940 printf("%s %s\n",progname,VERSION);
941 return(EXIT_SUCCESS);
942 case 'p':
943 if(oatoi(optarg)==-1)
945 fprintf(stderr,"%s: invalid mode\n",progname);
946 return(EXIT_FAILURE);
948 permission=oatoi(optarg);
949 break;
950 case 'o':
951 socketfile=optarg;
952 break;
953 default:
954 printf("Usage: %s [options] config-file\n",progname);
955 return(EXIT_FAILURE);
958 if(optind==argc-1)
960 configfile=argv[optind];
962 else
964 fprintf(stderr,"%s: invalid argument count\n",progname);
965 return EXIT_FAILURE;
968 lircdfd=lirc_init("lircrcd", 0);
969 if(lircdfd == -1)
971 return EXIT_FAILURE;
974 /* read config file */
975 if(lirc_readconfig_only(configfile,&config,NULL)!=0)
977 lirc_deinit();
978 return EXIT_FAILURE;
981 /* open socket */
982 socket=opensocket(configfile, socketfile, permission, &addr);
983 if(socket==-1)
985 lirc_freeconfig(config);
986 lirc_deinit();
987 return EXIT_FAILURE;
990 /* fork */
991 getcwd(dir, sizeof(dir));
992 if(daemon(0,0)==-1)
994 fprintf(stderr, "%s: daemon() failed\n", progname);
995 perror(progname);
996 shutdown(socket, 2);
997 close(socket);
998 lirc_freeconfig(config);
999 return -1;
1001 daemonized=1;
1003 openlog(progname, LOG_CONS|LOG_PID, LOG_USER);
1004 umask(0);
1005 signal(SIGPIPE,SIG_IGN);
1007 act.sa_handler=sigterm;
1008 sigfillset(&act.sa_mask);
1009 act.sa_flags=SA_RESTART; /* don't fiddle with EINTR */
1010 sigaction(SIGTERM,&act,NULL);
1011 sigaction(SIGINT,&act,NULL);
1012 sigaction(SIGHUP,&act,NULL);
1014 logprintf(LOG_NOTICE, "%s started", progname);
1015 loop(socket, lircdfd);
1017 closelog();
1018 shutdown(socket, 2);
1019 close(socket);
1020 if(chdir(dir) == 0) unlink(addr.sun_path);
1021 lirc_freeconfig(config);
1022 lirc_deinit();
1023 return EXIT_SUCCESS;