Example #1
0
int lirc_readconfig(const struct lirc_state *state,
                    const char *file,
                    struct lirc_config **config,
                    int (check)(char *s))
{
	struct sockaddr_un addr;
	int sockfd = -1;
	char *sha_bang, *filename;
	const char *sha_bang2;
	char *command;
	unsigned int ret;
	
	filename = NULL;
	sha_bang = NULL;
	if(lirc_readconfig_only_internal(state,file,config,check,&filename,&sha_bang)==-1)
	{
		return -1;
	}
	
	if(sha_bang == NULL)
	{
		goto lirc_readconfig_compat;
	}
	
	/* connect to lircrcd */

	addr.sun_family=AF_UNIX;
	if(lirc_getsocketname(filename, addr.sun_path, sizeof(addr.sun_path))>sizeof(addr.sun_path))
	{
		lirc_printf(state, "%s: WARNING: file name too long\n", state->lirc_prog);
		goto lirc_readconfig_compat;
	}
	sockfd=socket(AF_UNIX,SOCK_STREAM,0);
	if(sockfd==-1)
	{
		lirc_printf(state, "%s: WARNING: could not open socket\n",state->lirc_prog);
		lirc_perror(state, state->lirc_prog);
		goto lirc_readconfig_compat;
	}
	if(connect(sockfd, (struct sockaddr *)&addr, sizeof(addr))!=-1)
	{
		if(sha_bang!=NULL) free(sha_bang);
		(*config)->sockfd=sockfd;
		free(filename);
		
		/* tell daemon state->lirc_prog */
		if(lirc_identify(state, sockfd) == LIRC_RET_SUCCESS)
		{
			/* we're connected */
			return 0;
		}
		close(sockfd);
		lirc_freeconfig(*config);
		return -1;
	}
	close(sockfd);
	sockfd = -1;
	
	/* launch lircrcd */
	sha_bang2=sha_bang!=NULL ? sha_bang:"lircrcd";
	
	command=malloc(strlen(sha_bang2)+1+strlen(filename)+1);
	if(command==NULL)
	{
		goto lirc_readconfig_compat;
	}
	strcpy(command, sha_bang2);
	strcat(command, " ");
	strcat(command, filename);
	
	ret = myth_system_c(command, kMSNone, 0);
	free(command);
	
	if(ret!=EXIT_SUCCESS)
	{
		goto lirc_readconfig_compat;
	}
	
	if(sha_bang!=NULL) { free(sha_bang); sha_bang = NULL; }
	free(filename); filename = NULL;
	
	sockfd=socket(AF_UNIX,SOCK_STREAM,0);
	if(sockfd==-1)
	{
		lirc_printf(state, "%s: WARNING: could not open socket\n",state->lirc_prog);
		lirc_perror(state, state->lirc_prog);
		goto lirc_readconfig_compat;
	}
	if(connect(sockfd, (struct sockaddr *)&addr, sizeof(addr))!=-1)
	{
		if(lirc_identify(state, sockfd) == LIRC_RET_SUCCESS)
		{
			(*config)->sockfd=sockfd;
			return 0;
		}
	}
	close(sockfd);
	lirc_freeconfig(*config);
	return -1;
	
 lirc_readconfig_compat:
	/* compat fallback */
	if(sockfd != -1) close(sockfd);
	if(sha_bang!=NULL) free(sha_bang);
	free(filename);
	return 0;
}
Example #2
0
static int opensocket(const char* socket_id, const char* socketname, mode_t permission, struct sockaddr_un* addr)
{
	int sockfd;
	struct stat s;
	int new_socket = 1;
	int ret;

	/* get socket name */
	if ((socketname == NULL &&
	     lirc_getsocketname(socket_id,
				addr->sun_path, sizeof(addr->sun_path)) >
	     sizeof(addr->sun_path)) || (socketname != NULL && strlen(socketname) >= sizeof(addr->sun_path))) {
		fprintf(stderr, "%s: filename too long", progname);
		return -1;
	}
	if (socketname != NULL)
		strcpy(addr->sun_path, socketname);

	/* create socket */
	sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (sockfd == -1) {
		perror("could not create socket");
		return -1;
	}

	/*
	 * get owner, permissions, etc.
	 * so new socket can be the same since we
	 * have to delete the old socket.
	 */
	ret = stat(addr->sun_path, &s);
	if (ret == -1 && errno != ENOENT) {
		perrorf("could not get file information for %s",
			addr->sun_path);
		goto opensocket_failed;
	}

	if (ret != -1) {
		new_socket = 0;
		ret = unlink(addr->sun_path);
		if (ret == -1) {
			perrorf("could not delete %s", addr->sun_path);
			goto opensocket_failed;
		}
	}

	addr->sun_family = AF_UNIX;
	if (bind(sockfd, (struct sockaddr*)addr, sizeof(*addr)) == -1) {
		perror("could not assign address to socket");
		goto opensocket_failed;
	}

	if (new_socket ?
	    chmod(addr->sun_path, permission) :
	    (chmod(addr->sun_path, s.st_mode) == -1 || chown(addr->sun_path, s.st_uid, s.st_gid) == -1)
	    ) {
		perrorf("could not set file permissions on %s", addr->sun_path);
		goto opensocket_failed;
	}

	listen(sockfd, 3);
	nolinger(sockfd);

	return sockfd;

opensocket_failed:
	close(sockfd);
	return -1;
}