⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lircd.c

📁 很少见的linux下的红外口的工具
💻 C
📖 第 1 页 / 共 3 页
字号:
int send_stop(int fd,char *message,char *arguments){	struct ir_remote *remote;	struct ir_ncode *code;	struct itimerval repeat_timer;		if(parse_rc(fd,message,arguments,&remote,&code,NULL,2)==0) return(0);		if(remote==NULL || code==NULL) return(1);	if(repeat_remote && repeat_code &&	   strcasecmp(remote->name,repeat_remote->name)==0 && 	   strcasecmp(code->name,repeat_code->name)==0)	{		int done;		done=REPEAT_MAX-remote->repeat_countdown;		if(done<remote->min_repeat)		{			/* we still have some repeats to do */			remote->repeat_countdown=remote->min_repeat-done;			return(send_success(fd,message));		}		repeat_timer.it_value.tv_sec=0;		repeat_timer.it_value.tv_usec=0;		repeat_timer.it_interval.tv_sec=0;		repeat_timer.it_interval.tv_usec=0;				setitimer(ITIMER_REAL,&repeat_timer,NULL);				repeat_remote->toggle_mask_state=0;		repeat_remote=NULL;		repeat_code=NULL;		/* clin!=0, so we don't have to deinit hardware */		alrm=0;		return(send_success(fd,message));	}	else	{		return(send_error(fd,message,"not repeating\n"));	}}int version(int fd,char *message,char *arguments){	char buffer[PACKET_SIZE+1];	if(arguments!=NULL)	{		return(send_error(fd,message,"bad send packet\n"));	}	sprintf(buffer,"1\n%s\n",VERSION);	if(!(write_socket_len(fd,protocol_string[P_BEGIN]) &&	     write_socket_len(fd,message) &&	     write_socket_len(fd,protocol_string[P_SUCCESS]) &&	     write_socket_len(fd,protocol_string[P_DATA]) &&	     write_socket_len(fd,buffer) &&	     write_socket_len(fd,protocol_string[P_END]))) return(0);	return(1);}int get_command(int fd){	int length;	char buffer[PACKET_SIZE+1],backup[PACKET_SIZE+1];	char *end;	int packet_length,i;	char *directive;	length=read_timeout(fd,buffer,PACKET_SIZE,0);	packet_length=0;	while(length>packet_length)	{		buffer[length]=0;		end=strchr(buffer,'\n');		if(end==NULL)		{			logprintf(LOG_ERR,"bad send packet: \"%s\"",buffer);			/* remove clients that behave badly */			return(0);		}		end[0]=0;		LOGPRINTF(1,"received command: \"%s\"",buffer);		packet_length=strlen(buffer)+1;		strcpy(backup,buffer);strcat(backup,"\n");		directive=strtok(buffer,WHITE_SPACE);		if(directive==NULL)		{			if(!send_error(fd,backup,"bad send packet\n"))				return(0);			goto skip;		}		for(i=0;directives[i].name!=NULL;i++)		{			if(strcasecmp(directive,directives[i].name)==0)			{				if(!directives[i].				   function(fd,backup,strtok(NULL,"")))					return(0);				goto skip;			}		}				if(!send_error(fd,backup,"unknown directive: \"%s\"\n",			       directive))			return(0);	skip:		if(length>packet_length)		{			int new_length;			memmove(buffer,buffer+packet_length,				length-packet_length+1);			if(strchr(buffer,'\n')==NULL)			{				new_length=read_timeout(fd,buffer+length-							packet_length,							PACKET_SIZE-							(length-							 packet_length),5);				if(new_length>0)				{					length=length-packet_length+new_length;				}				else				{					length=new_length;				}			}			else			{				length-=packet_length;			}			packet_length=0;		}	}	if(length==0) /* EOF: connection closed by client */	{		return(0);	}	return(1);}void free_old_remotes(){	struct ir_remote *scan_remotes,*found;	struct ir_ncode *code;	if(last_remote!=NULL)	{		scan_remotes=free_remotes;		while(scan_remotes!=NULL)		{			if(last_remote==scan_remotes)			{				found=get_ir_remote(remotes,last_remote->name);				if(found!=NULL)				{					code=get_ir_code(found,last_remote->last_code->name);					if(code!=NULL)					{						found->reps=last_remote->reps;						found->repeat_state=last_remote->repeat_state;						found->remaining_gap=last_remote->remaining_gap;						last_remote=found;						last_remote->last_code=code;					}				}				break;			}			scan_remotes=scan_remotes->next;		}		if(scan_remotes==NULL) last_remote=NULL;	}	/* check if last config is still needed */	found=NULL;	if(repeat_remote!=NULL)	{		scan_remotes=free_remotes;		while(scan_remotes!=NULL)		{			if(repeat_remote==scan_remotes)			{				found=repeat_remote;				break;			}			scan_remotes=scan_remotes->next;		}		if(found!=NULL)		{			found=get_ir_remote(remotes,repeat_remote->name);			if(found!=NULL)			{				code=get_ir_code(found,repeat_code->name);				if(code!=NULL)				{					struct itimerval repeat_timer;					repeat_timer.it_value.tv_sec=0;					repeat_timer.it_value.tv_usec=0;					repeat_timer.it_interval.tv_sec=0;					repeat_timer.it_interval.tv_usec=0;					found->last_code=code;					found->last_send=repeat_remote->last_send;					found->repeat_state=repeat_remote->repeat_state;					found->remaining_gap=repeat_remote->remaining_gap;					setitimer(ITIMER_REAL,&repeat_timer,&repeat_timer);					/* "atomic" (shouldn't be necessary any more) */					repeat_remote=found;					repeat_code=code;					/* end "atomic" */					setitimer(ITIMER_REAL,&repeat_timer,NULL);					found=NULL;				}			}			else			{				found=repeat_remote;			}		}	}	if(found==NULL && decoding!=free_remotes)	{		free_config(free_remotes);		free_remotes=NULL;	}	else	{		LOGPRINTF(1,"free_remotes still in use");	}}int waitfordata(long maxusec){	fd_set fds;	int maxfd,i,ret,reconnect;	struct timeval tv,start,now;	while(1)	{		do{			/* handle signals */			if(term)			{				dosigterm(termsig);				/* never reached */			}			if(hup)			{				dosighup(SIGHUP);				hup=0;			}			if(alrm)			{				dosigalrm(SIGALRM);				alrm=0;			}			FD_ZERO(&fds);			FD_SET(sockfd,&fds);			maxfd=sockfd;			if(listen_tcpip)			{				FD_SET(sockinet,&fds);				maxfd=max(maxfd,sockinet);			}			if(clin>0 && hw.rec_mode!=0)			{				FD_SET(hw.fd,&fds);				maxfd=max(maxfd,hw.fd);			}						for(i=0;i<clin;i++)			{				/* Ignore this client until codes have been				   sent and it will get an answer. Otherwise				   we could mix up answer packets and send				   them back in the wrong order.*/				if(clis[i]!=repeat_fd)				{					FD_SET(clis[i],&fds);					maxfd=max(maxfd,clis[i]);				}			}			timerclear(&tv);			reconnect=0;			for(i=0;i<peern;i++)			{				if(peers[i]->socket!=-1)				{					FD_SET(peers[i]->socket,&fds);					maxfd=max(maxfd,peers[i]->socket);				}				else if(timerisset(&tv))				{					if(timercmp					   (&tv,&peers[i]->reconnect,>))					{						tv=peers[i]->reconnect;					}				}				else				{					tv=peers[i]->reconnect;				}			}			if(timerisset(&tv))			{				gettimeofday(&now,NULL);				if(timercmp(&now,&tv,>))				{					timerclear(&tv);				}				else				{					timersub(&tv,&now,&start);					tv=start;				}				reconnect=1;			}			gettimeofday(&start,NULL);			if(maxusec>0)			{				tv.tv_sec=0;				tv.tv_usec=maxusec;			}#ifdef SIM_REC			ret=select(maxfd+1,&fds,NULL,NULL,NULL);#else			if(timerisset(&tv) || reconnect)			{				ret=select(maxfd+1,&fds,NULL,NULL,&tv);			}			else			{				ret=select(maxfd+1,&fds,NULL,NULL,NULL);			}#endif			if(ret==-1 && errno!=EINTR)			{				logprintf(LOG_ERR,"select() failed");				logperror(LOG_ERR,NULL);				raise(SIGTERM);				continue;			}			gettimeofday(&now,NULL);			if(free_remotes!=NULL)			{				free_old_remotes();			}			if(maxusec>0)			{				if(ret==0)				{					return(0);				}				if(time_elapsed(&start,&now)>=maxusec)				{					return(0);				}				else				{					maxusec-=time_elapsed(&start,&now);				}							}			if(reconnect)			{				connect_to_peers();			}		}		while(ret==-1 && errno==EINTR);				for(i=0;i<clin;i++)		{			if(FD_ISSET(clis[i],&fds))			{				FD_CLR(clis[i],&fds);				if(get_command(clis[i])==0)				{					remove_client(clis[i]);					i--;				}			}		}		for(i=0;i<peern;i++)		{			if(peers[i]->socket!=-1 &&			   FD_ISSET(peers[i]->socket,&fds))			{				if(get_peer_message(peers[i])==0)				{					shutdown(peers[i]->socket,2);					close(peers[i]->socket);					peers[i]->socket=-1;					peers[i]->connection_failure = 1;					gettimeofday(&peers[i]->reconnect,NULL);					peers[i]->reconnect.tv_sec+=5;				}			}		}		if(FD_ISSET(sockfd,&fds))		{			LOGPRINTF(1,"registering local client");			add_client(sockfd);		}		if(listen_tcpip && FD_ISSET(sockinet,&fds))		{			LOGPRINTF(1,"registering inet client");			add_client(sockinet);		}                if(clin>0 && hw.rec_mode!=0 && FD_ISSET(hw.fd,&fds))                {                        /* we will read later */			return(1);                }	}}void loop(){	char *message;	int len,i;		logprintf(LOG_NOTICE,"lircd(%s) ready",LIRC_DRIVER);	while(1)	{		(void) waitfordata(0);		if(!hw.rec_func) continue;		message=hw.rec_func(remotes);				if(message!=NULL)		{			len=strlen(message);						for (i=0; i<clin; i++)			{				LOGPRINTF(1,"writing to client %d",i);				if(write_socket(clis[i],message,len)<len)				{					remove_client(clis[i]);					i--;				}						}		}	}}int main(int argc,char **argv){	struct sigaction act;	int nodaemon=0;	mode_t permission=S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;	hw_choose_driver(NULL);	while(1)	{		int c;		static struct option long_options[] =		{			{"help",no_argument,NULL,'h'},			{"version",no_argument,NULL,'v'},			{"nodaemon",no_argument,NULL,'n'},			{"permission",required_argument,NULL,'p'},			{"driver",required_argument,NULL,'H'},			{"device",required_argument,NULL,'d'},			{"listen",optional_argument,NULL,'l'},			{"connect",required_argument,NULL,'c'},#                       ifdef DEBUG			{"debug",optional_argument,NULL,'D'},#                       endif			{0, 0, 0, 0}		};#               ifdef DEBUG		c = getopt_long(argc,argv,"hvnp:H:d:l::c:D::",long_options,NULL);#               else		c = getopt_long(argc,argv,"hvnp:H:d:l::c:",long_options,NULL);#               endif		if(c==-1)			break;		switch (c)		{		case 'h':			printf("Usage: %s [options] [config-file]\n",progname);			printf("\t -h --help\t\t\tdisplay this message\n");			printf("\t -v --version\t\t\tdisplay version\n");			printf("\t -n --nodaemon\t\t\tdon't fork to background\n");			printf("\t -p --permission=mode\t\tfile permissions for " LIRCD "\n");			printf("\t -H --driver=driver\t\tuse given driver\n");			printf("\t -d --device=device\t\tread from given device\n");			printf("\t -l --listen[=port]\t\tlisten for network connections on port\n");			printf("\t -c --connect=host[:port]\t\tconnect to remote lircd server\n");#                       ifdef DEBUG			printf("\t -D[debug_level] --debug[=debug_level]\n");#                       endif			return(EXIT_SUCCESS);		case 'v':			printf("%s\n",progname);			return(EXIT_SUCCESS);		case 'n':			nodaemon=1;			break;		case 'p':			if(oatoi(optarg)==-1)			{				fprintf(stderr,"%s: invalid mode\n",progname);				return(EXIT_FAILURE);			}			permission=oatoi(optarg);			break;		case 'H':			if(hw_choose_driver(optarg) != 0){				fprintf(stderr, "Driver `%s' not supported.\n",					optarg);				hw_print_drivers(stderr);				exit (EXIT_FAILURE);			}			break;		case 'd':			hw.device=optarg;			break;		case 'l':			listen_tcpip=1;			if(optarg)			{				long p;				char *endptr;								p=strtol(optarg,&endptr,10);				if(!*optarg || *endptr || p<1 || p>USHRT_MAX)				{					fprintf(stderr,						"%s: bad port number \"%s\"\n",						progname,optarg);					return(EXIT_FAILURE);				}				port=(unsigned short int) p;			}			else			{				port=LIRC_INET_PORT;			}			break;		case 'c':			if(!add_peer_connection(optarg))				return(EXIT_FAILURE);			break;#               ifdef DEBUG		case 'D':			if(optarg==NULL) debug=1;			else			{				/* don't check for errors */				debug=atoi(optarg);			}			break;#               endif		default:			printf("Usage: %s [options] [config-file]\n",progname);			return(EXIT_FAILURE);		}	}	if(optind==argc-1)	{	        configfile=argv[optind];	}	else if(optind!=argc)	{		fprintf(stderr,"%s: invalid argument count\n",progname);		return(EXIT_FAILURE);	}		if(strcmp(hw.name, "null")==0 && peern==0)	{		fprintf(stderr,"%s: there's no hardware I can use and "			"no peers are specified\n",progname);		return(EXIT_FAILURE);	}	signal(SIGPIPE,SIG_IGN);		start_server(permission,nodaemon);		act.sa_handler=sigterm;	sigfillset(&act.sa_mask);	act.sa_flags=SA_RESTART;           /* don't fiddle with EINTR */	sigaction(SIGTERM,&act,NULL);	sigaction(SIGINT,&act,NULL);		act.sa_handler=sigalrm;	sigemptyset(&act.sa_mask);	act.sa_flags=SA_RESTART;           /* don't fiddle with EINTR */	sigaction(SIGALRM,&act,NULL);		remotes=NULL;	config();                          /* read config file */		act.sa_handler=sighup;	sigemptyset(&act.sa_mask);	act.sa_flags=SA_RESTART;           /* don't fiddle with EINTR */	sigaction(SIGHUP,&act,NULL);	#ifdef DAEMONIZE	/* ready to accept connections */	if(!nodaemon) daemonize();#endif	#if defined(SIM_SEND) && !defined(DAEMONIZE)	{		struct ir_remote *r;		struct ir_ncode *c;				if(hw.init_func)		{			if(!hw.init_func()) dosigterm(SIGTERM);		}				printf("space 1000000\n");		r=remotes;		while(r!=NULL)		{			c=r->codes;			while(c->name!=NULL)			{				repeat_remote=NULL;				repeat_code=NULL;				hw.send_func(r,c);				repeat_remote=r;				repeat_code=c;				hw.send_func(r,c);				hw.send_func(r,c);				hw.send_func(r,c);				hw.send_func(r,c);				c++;			}			r=r->next;		}		fflush(stdout);		if(hw.deinit_func) hw.deinit_func();	}	fprintf(stderr,"Ready.\n");	dosigterm(SIGTERM);#endif	loop();	/* never reached */	return(EXIT_SUCCESS); }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -