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

📄 command.c

📁 Red-Button
💻 C
📖 第 1 页 / 共 2 页
字号:
boolcmd_avstream(struct listen_data *listen_data, FILE *client, int argc, char *argv[]){	struct carousel *car = listen_data->carousel;	int audio_tag;	int video_tag;	uint16_t audio_pid;	uint16_t video_pid;	uint8_t audio_type;	uint8_t video_type;	int audio_fd;	int video_fd;	int ts_fd;	char hdr[64];	CHECK_USAGE(3, "avstream <AudioTag> <VideoTag>");	audio_tag = strtol(argv[1], NULL, 0);	video_tag = strtol(argv[2], NULL, 0);	/* map the tags to PIDs and stream types, or use the defaults */	if(audio_tag == -1)	{		/* check we have a default stream */		if(car->audio_pid == 0)		{			SEND_RESPONSE(500, "Unable to find audio PID");			return false;		}		audio_pid = car->audio_pid;		audio_type = car->audio_type;	}	else	{		audio_pid = stream2pid(&car->assoc, audio_tag);		audio_type = stream2type(&car->assoc, audio_tag);	}	if(video_tag == -1)	{		/* check we have a default stream */		if(car->video_pid == 0)		{			SEND_RESPONSE(500, "Unable to find video PID");			return false;		}		video_pid = car->video_pid;		video_type = car->video_type;	}	else	{		video_pid = stream2pid(&car->assoc, video_tag);		video_type = stream2type(&car->assoc, video_tag);	}	/* add the PIDs to the demux device */	if((audio_fd = add_demux_filter(car->demux_device, audio_pid, DMX_PES_AUDIO)) < 0)	{		SEND_RESPONSE(500, "Unable to open audio PID");		return false;	}	if((video_fd = add_demux_filter(car->demux_device, video_pid, DMX_PES_VIDEO)) < 0)	{		SEND_RESPONSE(500, "Unable to open video PID");		close(audio_fd);		return false;	}	/* we can now read a transport stream from the dvr device */	if((ts_fd = open(car->dvr_device, O_RDONLY)) < 0)	{		SEND_RESPONSE(500, "Unable to open DVB device");		close(audio_fd);		close(video_fd);		return false;	}	/* send the OK code */	SEND_RESPONSE(200, "OK");	/* tell the client what PIDs and stream types the component tags resolved to */	snprintf(hdr, sizeof(hdr), "AudioPID %u AudioType %u VideoPID %u VideoType %u\n", audio_pid, audio_type, video_pid, video_type);	fputs(hdr, client);	/* shovel the transport stream down client_sock until the client closes it or we get an error */	stream_ts(ts_fd, client);	/* clean up */	close(ts_fd);	close(audio_fd);	close(video_fd);	/* close the connection */	return true;}/* * check <ContentReference> * check if the given file is on the carousel * ContentReference should be absolute, ie start with "~//" */boolcmd_check(struct listen_data *listen_data, FILE *client, int argc, char *argv[]){	char *filename;	FILE *file;	CHECK_USAGE(2, "check <ContentReference>");	if((filename = external_filename(listen_data, argv[1])) == NULL)	{		SEND_RESPONSE(500, "Invalid ContentReference");		return false;	}	if((file = fopen(filename, "r")) != NULL)	{		fclose(file);		SEND_RESPONSE(200, "OK");	}	else	{		SEND_RESPONSE(404, "Not found");	}	return false;}/* * file <ContentReference> * send the given file down client_sock * ContentReference should be absolute, ie start with "~//" */boolcmd_file(struct listen_data *listen_data, FILE *client, int argc, char *argv[]){	char *filename;	FILE *file;	long size;	char hdr[64];	long left;	size_t nread;	char buff[1024 * 8];	CHECK_USAGE(2, "file <ContentReference>");	if((filename = external_filename(listen_data, argv[1])) == NULL)	{		SEND_RESPONSE(500, "Invalid ContentReference");		return false;	}	if((file = fopen(filename, "r")) == NULL)	{		SEND_RESPONSE(404, "Not found");		return false;	}	/* find the file length */	if(fseek(file, 0, SEEK_END) < 0	|| (size = ftell(file)) < 0)	{		SEND_RESPONSE(500, "Error reading file");		return false;	}	rewind(file);	SEND_RESPONSE(200, "OK");	/* send the file length */	snprintf(hdr, sizeof(hdr), "Length %ld\n", size);	fputs(hdr, client);	/* send the file contents */	left = size;	while(left > 0)	{		nread = fread(buff, 1, sizeof(buff), file);		fwrite(buff, 1, nread, client);		left -= nread;	}	fclose(file);	return false;}/* * help */boolcmd_help(struct listen_data *listen_data, FILE *client, int argc, char *argv[]){	int i;	char name_args[64];	char help_line[128];	SEND_RESPONSE(200, "OK");	for(i=0; command[i].name != NULL; i++)	{		snprintf(name_args, sizeof(name_args), "%s %s", command[i].name, command[i].args);		snprintf(help_line, sizeof(help_line), "%-30s %s\n", name_args, command[i].help);		fputs(help_line, client);	}	return false;}/* * quit */boolcmd_quit(struct listen_data *listen_data, FILE *client, int argc, char *argv[]){	return true;}/* * return a filename that can be used to load the given ContentReference from the filesystem * returns a static string that will be overwritten by the next call to this routine * returns NULL if the ContentReference is invalid (does not start with ~// or has too many .. components) */static char _external[PATH_MAX];char *external_filename(struct listen_data *listen_data, char *cref){	char *canon_cref;	/* is ContentReference absolute */	if(strlen(cref) < 3 || strncmp(cref, "~//", 3) != 0)		return NULL;	/* strip off the ~// prefix, and canonicalise the reference */	canon_cref = canonical_filename(cref + 3);	/* if the canonical name starts with "../", it is invalid */	if(strcmp(canon_cref, "..") == 0 || strncmp(canon_cref, "../", 3) == 0)		return NULL;	/* create the carousel filename, ie prepend the servive gateway directory */	snprintf(_external, sizeof(_external), "%s/%u/%s", SERVICES_DIR, listen_data->carousel->service_id, canon_cref);	return _external;}/* * return a string that recursively removes all sequences of the form '/x/../' in path * returns a static string that will be overwritten by the next call to this routine */static char _canon[PATH_MAX];char *canonical_filename(char *path){	char *start;	char *slash;	size_t len;	/* copy path into the output buffer */	strncpy(_canon, path, sizeof(_canon));	/* just in case */	_canon[sizeof(_canon)-1] = '\0';	/* keep removing "/x/../" until there are none left */	start = _canon;	while(true)	{		/* find the start of the first path component that is not "../" */		while(strncmp(start, "../", 3) == 0)			start += 3;		/* find the next slash in the path */		slash = start;		while(*slash != '/' && *slash != '\0')			slash ++;		/* no more slashes => nothing left to do */		if(*slash == '\0')			return _canon;		/* if this component is empty (ie ./ or /) remove it */		if(strncmp(start, "./", 2) == 0 || *start == '/')		{			/* include \0 terminator */			len = strlen(slash + 1) + 1;			memmove(start, slash + 1, len);			/* restart the search */			start = _canon;		}		/* if the next path component is "../", eat this one */		else if(strncmp(slash, "/../", 4) == 0)		{			/* include \0 terminator */			len = strlen(slash + 4) + 1;			memmove(start, slash + 4, len);			/* restart the search */			start = _canon;		}		else		{			/* move to the next component */			start = slash + 1;		}	}	/* not reached */	return NULL;}

⌨️ 快捷键说明

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