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

📄 lircd.c

📁 很少见的linux下的红外口的工具
💻 C
📖 第 1 页 / 共 3 页
字号:
		}	}	if(length==0) /* EOF: connection closed by client */	{		return(0);	}	return(1);}void start_server(mode_t permission,int nodaemon){	struct sockaddr_un serv_addr;	struct sockaddr_in serv_addr_in;	struct stat s;	int ret;	int new=1;	int fd;		/* create pid lockfile in /var/run */	if((fd=open(PIDFILE,O_RDWR|O_CREAT,0644))==-1 ||	   (pidfile=fdopen(fd,"r+"))==NULL)	{		fprintf(stderr,"%s: can't open or create %s\n",			progname,PIDFILE);		perror(progname);		exit(EXIT_FAILURE);	}	if(flock(fd,LOCK_EX|LOCK_NB)==-1)	{		pid_t otherpid;				if(fscanf(pidfile,"%d\n",&otherpid)>0)		{			fprintf(stderr,"%s: there seems to already be "				"a lircd process with pid %d\n",				progname,otherpid);			fprintf(stderr,"%s: otherwise delete stale "				"lockfile %s\n",progname,PIDFILE);		}		else		{			fprintf(stderr,"%s: invalid %s encountered\n",				progname,PIDFILE);		}		exit(EXIT_FAILURE);	}	(void) fcntl(fd,F_SETFD,FD_CLOEXEC);	rewind(pidfile);	(void) fprintf(pidfile,"%d\n",getpid());	(void) fflush(pidfile);	(void) ftruncate(fileno(pidfile),ftell(pidfile));	/* create socket*/	sockfd=socket(AF_UNIX,SOCK_STREAM,0);	if(sockfd==-1)	{		fprintf(stderr,"%s: could not create socket\n",progname);		perror(progname);		fclose(pidfile);		(void) unlink(PIDFILE);		exit(EXIT_FAILURE);	};		/* 	   get owner, permissions, etc.	   so new socket can be the same since we	   have to delete the old socket.  	*/	ret=stat(LIRCD,&s);	if(ret==-1 && errno!=ENOENT)	{		fprintf(stderr,"%s: could not get file information for %s\n",			progname,LIRCD);		perror(progname);		close(sockfd);		fclose(pidfile);		(void) unlink(PIDFILE);		exit(EXIT_FAILURE);	}	if(ret!=-1)	{		new=0;		ret=unlink(LIRCD);		if(ret==-1)		{			fprintf(stderr,"%s: could not delete %s\n",				progname,LIRCD);			perror(NULL);			close(sockfd);			fclose(pidfile);			(void) unlink(PIDFILE);			exit(EXIT_FAILURE);		}	}		serv_addr.sun_family=AF_UNIX;	strcpy(serv_addr.sun_path,LIRCD);	if(bind(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))==-1)	{		fprintf(stderr,"%s: could not assign address to socket\n",			progname);		perror(progname);		close(sockfd);		fclose(pidfile);		(void) unlink(PIDFILE);		exit(EXIT_FAILURE);	}		if(new ?	   chmod(LIRCD,permission):	   (chmod(LIRCD,s.st_mode)==-1 || chown(LIRCD,s.st_uid,s.st_gid)==-1)	   )	{		fprintf(stderr,"%s: could not set file permissions\n",			progname);		perror(progname);		close(sockfd);		fclose(pidfile);		(void) unlink(PIDFILE);		exit(EXIT_FAILURE);	}		listen(sockfd,3);	nolinger(sockfd);	if(listen_tcpip)	{		int enable=1;		/* create socket*/		sockinet=socket(PF_INET,SOCK_STREAM,IPPROTO_IP);		if(sockinet==-1)		{			fprintf(stderr,"%s: could not create TCP/IP socket\n",				progname);			perror(progname);			close(sockfd);			fclose(pidfile);			(void) unlink(PIDFILE);			exit(EXIT_FAILURE);		};		(void) setsockopt(sockinet,SOL_SOCKET,SO_REUSEADDR,				  &enable,sizeof(enable));		serv_addr_in.sin_family=AF_INET;		serv_addr_in.sin_addr.s_addr=htonl(INADDR_ANY);		serv_addr_in.sin_port=htons(port);				if(bind(sockinet,(struct sockaddr *) &serv_addr_in,			sizeof(serv_addr_in))==-1)		{			fprintf(stderr,"%s: could not assign address to socket\n",				progname);			perror(progname);			close(sockinet);			close(sockfd);			fclose(pidfile);			(void) unlink(PIDFILE);			exit(EXIT_FAILURE);		}				listen(sockinet,3);		nolinger(sockinet);	}	#ifdef USE_SYSLOG#ifdef DAEMONIZE	if(nodaemon)	{		openlog(progname,LOG_CONS|LOG_PID|LOG_PERROR,LIRC_SYSLOG);	}	else	{		openlog(progname,LOG_CONS|LOG_PID,LIRC_SYSLOG);	}#else	openlog(progname,LOG_CONS|LOG_PID|LOG_PERROR,LIRC_SYSLOG);#endif#else	lf=fopen(logfile,"a");	if(lf==NULL)	{		fprintf(stderr,"%s: could not open logfile\n",progname);		perror(progname);		if(listen_tcpip)		{			close(sockinet);		}		close(sockfd);		fclose(pidfile);		(void) unlink(PIDFILE);		exit(EXIT_FAILURE);	}	gethostname(hostname,HOSTNAME_LEN);#endif	LOGPRINTF(1,"started server socket");}#ifndef USE_SYSLOGvoid logprintf(int prio,char *format_str, ...){	time_t current;	char *currents;	va_list ap;  		current=time(&current);	currents=ctime(&current);		if(lf) fprintf(lf,"%15.15s %s %s: ",currents+4,hostname,progname);	if(!daemonized) fprintf(stderr,"%s: ",progname);	va_start(ap,format_str);	if(lf)	{		if(prio==LOG_WARNING) fprintf(lf,"WARNING: ");		vfprintf(lf,format_str,ap);		fputc('\n',lf);fflush(lf);	}	if(!daemonized)	{		if(prio==LOG_WARNING) fprintf(stderr,"WARNING: ");		vfprintf(stderr,format_str,ap);		fputc('\n',stderr);fflush(stderr);	}	va_end(ap);}void logperror(int prio,const char *s){	if(s!=NULL)	{		logprintf(prio,"%s: %s",s,strerror(errno));	}	else	{		logprintf(prio,"%s",strerror(errno));	}}#endif#ifdef DAEMONIZEvoid daemonize(void){	if(daemon(0,0)==-1)	{		logprintf(LOG_ERR,"daemon() failed");		logperror(LOG_ERR,NULL);		dosigterm(SIGTERM);	}	umask(0);	rewind(pidfile);	(void) fprintf(pidfile,"%d\n",getpid());	(void) fflush(pidfile);	(void) ftruncate(fileno(pidfile),ftell(pidfile));	daemonized=1;}#endif /* DAEMONIZE */void sigalrm(int sig){	alrm=1;}void dosigalrm(int sig){	struct itimerval repeat_timer;		if(repeat_remote->last_code!=repeat_code)	{		/* we received a different code from the original		   remote control we could repeat the wrong code so		   better stop repeating */		repeat_remote=NULL;		repeat_code=NULL;		repeat_fd=-1;		if(repeat_message!=NULL)		{			free(repeat_message);			repeat_message=NULL;		}		if(clin==0 && repeat_remote==NULL && hw.deinit_func)		{			hw.deinit_func();		}		return;	}	repeat_remote->repeat_countdown--;	if(hw.send_func(repeat_remote,repeat_code) &&	   repeat_remote->repeat_countdown>0)	{		repeat_timer.it_value.tv_sec=0;		repeat_timer.it_value.tv_usec=repeat_remote->remaining_gap;		repeat_timer.it_interval.tv_sec=0;		repeat_timer.it_interval.tv_usec=0;				setitimer(ITIMER_REAL,&repeat_timer,NULL);		return;	}	repeat_remote=NULL;	repeat_code=NULL;	if(repeat_fd!=-1)	{		send_success(repeat_fd,repeat_message);		free(repeat_message);		repeat_message=NULL;		repeat_fd=-1;	}	if(clin==0 && repeat_remote==NULL && hw.deinit_func)	{		hw.deinit_func();	}}int parse_rc(int fd,char *message,char *arguments,struct ir_remote **remote,	     struct ir_ncode **code,int *reps,int n){	char *name=NULL,*command=NULL,*repeats,*end_ptr=NULL;	*remote=NULL;	*code=NULL;	if(arguments==NULL) return(1);	name=strtok(arguments,WHITE_SPACE);	if(name==NULL) return(1);	*remote=get_ir_remote(remotes,name);	if(*remote==NULL)	{		return(send_error(fd,message,"unknown remote: \"%s\"\n",				  name));	}	command=strtok(NULL,WHITE_SPACE);	if(command==NULL) return(1);	*code=get_ir_code(*remote,command);	if(*code==NULL)	{		return(send_error(fd,message,"unknown command: \"%s\"\n",				  command));	}	if(reps!=NULL)	{		repeats=strtok(NULL,WHITE_SPACE);		if (repeats!=NULL)		{			*reps=strtol(repeats,&end_ptr,10);			if (*end_ptr || *reps<0 )			{				return(send_error(fd,message,						  "bad send packet\n"));			}			if (*reps>REPEAT_MAX)			{				return(send_error				       (fd,message,					"too many repeats: \"%d\"\n",*reps));			}		}		else		{			*reps=-1;		}	}	if(strtok(NULL,WHITE_SPACE)!=NULL)	{		return(send_error(fd,message,"bad send packet\n"));	}	if(n>0 && *remote==NULL)	{		return(send_error(fd,message,"remote missing\n"));	}	if(n>1 && *code==NULL)	{		return(send_error(fd,message,"code missing\n"));	}	return(1);}int send_success(int fd,char *message){	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_END]))) return(0);	return(1);}int send_error(int fd,char *message,char *format_str, ...){	char lines[4],buffer[PACKET_SIZE+1];	int i,n,len;	va_list ap;  	char *s1,*s2;		va_start(ap,format_str);	vsprintf(buffer,format_str,ap);	va_end(ap);		s1=strrchr(message,'\n');	s2=strrchr(buffer,'\n');	if(s1!=NULL) s1[0]=0;	if(s2!=NULL) s2[0]=0;	logprintf(LOG_ERR,"error processing command: %s",message);	logprintf(LOG_ERR,"%s",buffer);	if(s1!=NULL) s1[0]='\n';	if(s2!=NULL) s2[0]='\n';	n=0;	len=strlen(buffer);	for(i=0;i<len;i++) if(buffer[i]=='\n') n++;	sprintf(lines,"%d\n",n);		if(!(write_socket_len(fd,protocol_string[P_BEGIN]) &&	     write_socket_len(fd,message) &&	     write_socket_len(fd,protocol_string[P_ERROR]) &&	     write_socket_len(fd,protocol_string[P_DATA]) &&	     write_socket_len(fd,lines) &&	     write_socket_len(fd,buffer) &&	     write_socket_len(fd,protocol_string[P_END]))) return(0);	return(1);}int send_remote_list(int fd,char *message){	char buffer[PACKET_SIZE+1];	struct ir_remote *all;	int n,len;		n=0;	all=remotes;	while(all)	{		n++;		all=all->next;	}	if(!(write_socket_len(fd,protocol_string[P_BEGIN]) &&	     write_socket_len(fd,message) &&	     write_socket_len(fd,protocol_string[P_SUCCESS]))) return(0);		if(n==0)	{		return(write_socket_len(fd,protocol_string[P_END]));	}	sprintf(buffer,"%d\n",n);	len=strlen(buffer);	if(!(write_socket_len(fd,protocol_string[P_DATA]) &&	     write_socket_len(fd,buffer))) return(0);	all=remotes;	while(all)	{		len=snprintf(buffer,PACKET_SIZE+1,"%s\n",all->name);		if(len==PACKET_SIZE+1)		{			len=sprintf(buffer,"name_too_long\n");		}		if(write_socket(fd,buffer,len)<len) return(0);		all=all->next;	}	return(write_socket_len(fd,protocol_string[P_END]));}int send_remote(int fd,char *message,struct ir_remote *remote){	struct ir_ncode *codes;	char buffer[PACKET_SIZE+1];	int n,len;	n=0;	codes=remote->codes;	if(codes!=NULL)	{		while(codes->name!=NULL)		{			n++;			codes++;		}	}	if(!(write_socket_len(fd,protocol_string[P_BEGIN]) &&	     write_socket_len(fd,message) &&	     write_socket_len(fd,protocol_string[P_SUCCESS]))) return(0);	if(n==0)	{		return(write_socket_len(fd,protocol_string[P_END]));	}	sprintf(buffer,"%d\n",n);	if(!(write_socket_len(fd,protocol_string[P_DATA]) &&	     write_socket_len(fd,buffer))) return(0);	codes=remote->codes;	while(codes->name!=NULL)	{#ifdef __GLIBC__		/* It seems you can't print 64-bit longs on glibc */				len=snprintf(buffer,PACKET_SIZE+1,"%08lx%08lx %s\n",			     (unsigned long) (codes->code>>32),			     (unsigned long) (codes->code&0xFFFFFFFF),			     codes->name);#else		len=snprintf(buffer,PACKET_SIZE,"%016llx %s\n",			     codes->code,			     codes->name);#endif		if(len==PACKET_SIZE+1)		{			len=sprintf(buffer,"code_too_long\n");		}		if(write_socket(fd,buffer,len)<len) return(0);		codes++;	}	return(write_socket_len(fd,protocol_string[P_END]));}int send_name(int fd,char *message,struct ir_ncode *code){	char buffer[PACKET_SIZE+1];	int len;	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]))) return(0);#ifdef __GLIBC__	/* It seems you can't print 64-bit longs on glibc */		len=snprintf(buffer,PACKET_SIZE+1,"1\n%08lx%08lx %s\n",		     (unsigned long) (code->code>>32),		     (unsigned long) (code->code&0xFFFFFFFF),		     code->name);#else	len=snprintf(buffer,PACKET_SIZE,"1\n%016llx %s\n",		     code->code,		     code->name);#endif	if(len==PACKET_SIZE+1)	{		len=sprintf(buffer,"1\ncode_too_long\n");	}	if(write_socket(fd,buffer,len)<len) return(0);	return(write_socket_len(fd,protocol_string[P_END]));}int list(int fd,char *message,char *arguments){	struct ir_remote *remote;	struct ir_ncode *code;	if(parse_rc(fd,message,arguments,&remote,&code,NULL,0)==0) return(0);		if(remote==NULL)	{		return(send_remote_list(fd,message));	}	if(code==NULL)	{		return(send_remote(fd,message,remote));	}	return(send_name(fd,message,code));}int send_once(int fd,char *message,char *arguments){	return(send_core(fd,message,arguments,1));}int send_start(int fd,char *message,char *arguments){	return(send_core(fd,message,arguments,0));}int send_core(int fd,char *message,char *arguments,int once){	struct ir_remote *remote;	struct ir_ncode *code;	struct itimerval repeat_timer;	int reps;		if(hw.send_mode==0) return(send_error(fd,message,"hardware does not "					      "support sending\n"));		if(parse_rc(fd,message,arguments,&remote,&code,		    once ? &reps:NULL,2)==0) return(0);		if(remote==NULL || code==NULL) return(1);	if(once)	{		if(repeat_remote!=NULL)		{			return(send_error(fd,message,"busy: repeating\n"));		}	}	else	{		if(repeat_remote!=NULL)		{			return(send_error(fd,message,"already repeating\n"));		}	}	if(has_toggle_mask(remote))	{		remote->toggle_mask_state=0;	}	if(remote->toggle_bit>0)		remote->repeat_state=		!remote->repeat_state;	if(!hw.send_func(remote,code))	{		return(send_error(fd,message,"transmission failed\n"));	}	if(once)	{		remote->repeat_countdown=max(remote->min_repeat,reps);	}	else	{		/* you've been warned, now we have a limit */		remote->repeat_countdown=REPEAT_MAX;	}	if(remote->repeat_countdown>0)	{		repeat_remote=remote;		repeat_code=code;		repeat_timer.it_value.tv_sec=0;		repeat_timer.it_value.tv_usec=			remote->remaining_gap;		repeat_timer.it_interval.tv_sec=0;		repeat_timer.it_interval.tv_usec=0;		if(once)		{			repeat_message=strdup(message);			if(repeat_message==NULL)			{				repeat_remote=NULL;				repeat_code=NULL;				return(send_error(fd,message,						  "out of memory\n"));			}			repeat_fd=fd;		}		else if(!send_success(fd,message))		{			repeat_remote=NULL;			repeat_code=NULL;			return(0);		}		setitimer(ITIMER_REAL,&repeat_timer,NULL);		return(1);	}	else	{		return(send_success(fd,message));	}}

⌨️ 快捷键说明

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