1 /* $Id: irsend.c,v 5.5 2007/09/29 17:13:14 lirc Exp $ */
5 irsend - application for sending IR-codes via lirc
7 Copyright (C) 1998 Christoph Bartelmus (lirc@bartelmus.de)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 #include <sys/socket.h>
37 #include <sys/types.h>
44 #define PACKET_SIZE 256
56 const char *read_string(int fd
)
58 static char buffer
[PACKET_SIZE
+1]="";
65 memmove(buffer
,buffer
+ptr
,strlen(buffer
+ptr
)+1);
67 end
=strchr(buffer
,'\n');
78 fprintf(stderr
,"%s: bad packet\n",progname
);
82 ret
=read(fd
,buffer
+ptr
,PACKET_SIZE
-ptr
);
88 fprintf(stderr
,"%s: timeout\n",progname
);
99 end
=strchr(buffer
,'\n');
104 ptr
=strlen(buffer
)+1;
106 printf("buffer: -%s-\n",buffer
);
122 int send_packet(int fd
,const char *packet
)
125 const char *string
,*data
;
127 enum packet_state state
;
129 unsigned long data_n
=0;
135 done
=write(fd
,(void *) data
,todo
);
138 fprintf(stderr
,"%s: could not send packet\n",
153 string
=read_string(fd
);
154 if(string
==NULL
) return(-1);
158 if(strcasecmp(string
,"BEGIN")!=0)
165 if(strncasecmp(string
,packet
,strlen(string
))!=0 ||
166 strlen(string
)+1!=strlen(packet
))
174 if(strcasecmp(string
,"SUCCESS")==0)
178 else if(strcasecmp(string
,"END")==0)
183 else if(strcasecmp(string
,"ERROR")==0)
185 fprintf(stderr
,"%s: command failed: %s",
196 if(strcasecmp(string
,"END")==0)
200 else if(strcasecmp(string
,"DATA")==0)
208 data_n
=strtoul(string
,&endptr
,0);
209 if(!*string
|| *endptr
)
223 fprintf(stderr
,"%s: %s\n",progname
,string
);
225 if(n
==data_n
) state
=P_END
;
228 if(strcasecmp(string
,"END")==0)
237 fprintf(stderr
,"%s: bad return packet\n",progname
);
241 int main(int argc
,char **argv
)
248 unsigned short port
= LIRC_INET_PORT
;
249 unsigned long count
=1;
250 struct sockaddr_un addr_un
;
251 struct sockaddr_in addr_in
;
253 char buffer
[PACKET_SIZE
+1];
254 struct sigaction act
;
261 static struct option long_options
[] =
263 {"help",no_argument
,NULL
,'h'},
264 {"version",no_argument
,NULL
,'v'},
265 {"device",required_argument
,NULL
,'d'},
266 {"address",required_argument
,NULL
,'a'},
267 {"count",required_argument
,NULL
,'#'},
270 c
= getopt_long(argc
,argv
,"hvd:a:#:",long_options
,NULL
);
276 printf("Usage: %s [options] DIRECTIVE REMOTE CODE [CODE...]\n",progname
);
277 printf("\t -h --help\t\t\tdisplay usage summary\n");
278 printf("\t -v --version\t\t\tdisplay version\n");
279 printf("\t -d --device\t\t\tuse given lircd socket [%s]\n", LIRCD
);
280 printf("\t -a --address=host[:port]\tconnect to "
281 "lircd at this address\n");
282 printf("\t -# --count=n\t\t\tsend command n times\n");
283 return(EXIT_SUCCESS
);
285 printf("%s %s\n", progname
, VERSION
);
286 return(EXIT_SUCCESS
);
296 address
= strdup(optarg
);
299 fprintf(stderr
, "%s: out of memory\n",
301 return(EXIT_FAILURE
);
303 p
= strchr(address
, ':');
306 val
= strtoul(p
+1, &end
, 10);
307 if (!(*(p
+1)) || *end
||
308 val
<1 || val
>USHRT_MAX
)
311 "%s: invalid port number: "
312 "%s\n", progname
, p
+1);
313 return(EXIT_FAILURE
);
315 port
= (unsigned short) val
;
324 count
= strtoul(optarg
, &end
, 10);
327 fprintf(stderr
, "%s: invalid count value: "
328 "%s\n", progname
, optarg
);
329 return(EXIT_FAILURE
);
334 return(EXIT_FAILURE
);
337 if (optind
+ 2 > argc
)
339 fprintf(stderr
,"%s: not enough arguments\n",progname
);
340 return(EXIT_FAILURE
);
349 if(strlen(lircd
)+1 > sizeof(addr_un
.sun_path
))
351 /* lircd is longer than sockaddr_un.sun_path field */
352 fprintf(stderr
, "%s: socket name is too long\n",
354 return(EXIT_FAILURE
);
358 act
.sa_handler
=sigalrm
;
359 sigemptyset(&act
.sa_mask
);
360 act
.sa_flags
=0; /* we need EINTR */
361 sigaction(SIGALRM
,&act
,NULL
);
363 if (address
== NULL
) {
364 addr_un
.sun_family
=AF_UNIX
;
365 strcpy(addr_un
.sun_path
,lircd
);
366 fd
=socket(AF_UNIX
,SOCK_STREAM
,0);
370 struct hostent
*hostInfo
;
372 hostInfo
= gethostbyname(address
);
373 if (hostInfo
== NULL
) {
374 fprintf(stderr
,"%s: host %s unknown\n", progname
,
376 return(EXIT_FAILURE
);
378 addr_in
.sin_family
= hostInfo
->h_addrtype
;
379 memcpy((char *) &addr_in
.sin_addr
.s_addr
,
380 hostInfo
->h_addr_list
[0], hostInfo
->h_length
);
381 addr_in
.sin_port
= htons(port
);
382 fd
=socket(AF_INET
,SOCK_STREAM
,0);
387 fprintf(stderr
,"%s: could not open socket\n",progname
);
393 address
? (struct sockaddr
*) &addr_in
:
394 (struct sockaddr
*) &addr_un
,
395 address
? sizeof(addr_in
) : sizeof(addr_un
)) == -1)
397 fprintf(stderr
,"%s: could not connect to socket\n",progname
);
402 if(address
) free(address
);
405 directive
=argv
[optind
++];
407 if(strcasecmp(directive
,"set_transmitters")==0)
410 if (strlen(directive
)+strlen(code
)+2<PACKET_SIZE
)
412 sprintf(buffer
,"%s %s",directive
,code
);
416 fprintf(stderr
,"%s: input too long\n",progname
);
422 if (strlen(buffer
)+strlen(code
)+2<PACKET_SIZE
)
424 sprintf(buffer
+strlen(buffer
)," %s",code
);
428 fprintf(stderr
,"%s: input too long\n",progname
);
433 if(send_packet(fd
,buffer
)==-1)
438 if(strcasecmp(directive
,"simulate")==0)
443 fprintf(stderr
, "%s: invalid argument count\n",
447 if(strlen(directive
)+strlen(code
)+2<PACKET_SIZE
)
449 sprintf(buffer
,"%s %s\n",directive
,code
);
453 fprintf(stderr
,"%s: input too long\n",progname
);
456 if(send_packet(fd
,buffer
)==-1)
463 remote
=argv
[optind
++];
467 fprintf(stderr
,"%s: not enough arguments\n",progname
);
474 if(strlen(directive
)+strlen(remote
)+strlen(code
)+3<PACKET_SIZE
)
476 if(strcasecmp(directive
,"SEND_ONCE")==0 && count
>1)
478 sprintf(buffer
,"%s %s %s %lu\n",
479 directive
,remote
,code
,count
);
483 sprintf(buffer
,"%s %s %s\n",directive
,remote
,code
);
485 if(send_packet(fd
,buffer
)==-1)
492 fprintf(stderr
,"%s: input too long\n",progname
);
498 return(EXIT_SUCCESS
);