示例#1
0
文件: file_stat.c 项目: nal/C_samples
/*  Main function prints file size of self in bytes or argv[1] if supplied.
    Works only for regular files.
*/
int main( int argc, char *argv[] ) {
    long file_size = 0L;
    char *file_path;

    if ( argc == 2 ) {
        file_path = argv[1];
    }
    else {
        file_path = argv[0];
    }

    file_size = get_file_size( file_path );

    if ( file_size < 0 ) {
        local_perror();
        return 0;
    }

    printf("File size of file %s is %ld bytes\n", file_path, file_size);
    return 0;
}
示例#2
0
/*
 * Remote log
 */
void dvb_remote_log(int level, const char *fmt, ...)
{
	int ret;
	char *buf;

	va_list ap;

	va_start(ap, fmt);
	ret = vasprintf(&buf, fmt, ap);
	if (ret <= 0) {
		local_perror("vasprintf");
		return;
	}

	va_end(ap);

	if (dvb_fd > 0)
		send_data(dvb_fd, "%i%s%i%s", 0, "log", level, buf);
	else
		local_log(level, buf);

	free(buf);
}
示例#3
0
static int send_buf(int fd, const char *buf, size_t size)
{
	int ret;
	int32_t i32;

	if (fd < 0)
		return ECONNRESET;

	pthread_mutex_lock(&msg_mutex);
	i32 = htobe32(size);
	ret = send(fd, (void *)&i32, 4, MSG_MORE);
	if (ret >= 0)
		ret = send(fd, buf, size, 0);
	pthread_mutex_unlock(&msg_mutex);
	if (ret < 0) {
		local_perror("write");
		if (ret == ECONNRESET)
			close_all_devs();

		return errno;
	}

	return ret;
}
示例#4
0
static int dev_open(uint32_t seq, char *cmd, int fd, char *buf, ssize_t size)
{
	struct dvb_open_descriptor *open_dev;
	struct dvb_dev_list *dev;
	struct dvb_descriptors *desc, **p;
	int ret, flags, uid;
	char sysname[REMOTE_BUF_SIZE];

	desc = calloc(1, sizeof(*desc));
	if (!desc) {
		local_perror("calloc");
		ret = -ENOMEM;
		goto error;
	}

	ret = scan_data(buf, size, "%s%i", sysname, &flags);
	if (ret < 0) {
		free(desc);
		goto error;
	}

	/*
	 * Discard requests for O_NONBLOCK, as the daemon will use threads
	 * to handle unblocked reads.
	 */
	flags &= ~O_NONBLOCK;

	open_dev = dvb_dev_open(dvb, sysname, flags);
	if (!open_dev) {
		ret = -errno;
		free(desc);
		goto error;
	}


	if (verbose)
		dbg("open dev handler for %s: %p with uid#%d", sysname, open_dev, open_dev->fd);

	dev = open_dev->dev;
	if (dev->dvb_type == DVB_DEVICE_DEMUX ||
	    dev->dvb_type == DVB_DEVICE_DVR) {
		pthread_mutex_lock(&dvb_read_mutex);
		fds[numfds].fd = open_dev->fd;
		fds[numfds].events = POLLIN | POLLPRI;
		numfds++;
		pthread_mutex_unlock(&dvb_read_mutex);
	}

	if (!read_id) {
		ret = pthread_create(&read_id, NULL, read_data, NULL);
		if (ret < 0) {
			local_perror("pthread_create");
			pthread_mutex_unlock(&msg_mutex);
			free(desc);
			return -1;
		}
	}

	pthread_mutex_unlock(&msg_mutex);
	uid = open_dev->fd;

	desc->uid = uid;
	desc->open_dev = open_dev;

	/* Add element to the desc_root tree */
	p = tsearch(desc, &desc_root, dvb_desc_compare);
	if (!p) {
		local_perror("tsearch");
		uid = 0;
	}
	if (*p != desc) {
		err("uid %d was already opened!");
	}

	pthread_mutex_unlock(&msg_mutex);

	ret = uid;
error:
	return send_data(fd, "%i%s%i", seq, cmd, ret);
}
示例#5
0
int main(int argc, char *argv[])
{
	int ret;
	int sockfd;
	socklen_t addrlen;
	struct sockaddr_in serv_addr, cli_addr;

#ifdef ENABLE_NLS
	setlocale (LC_ALL, "");
	bindtextdomain (PACKAGE, LOCALEDIR);
	textdomain (PACKAGE);
#endif

	if (argp_parse(&argp, argc, argv, ARGP_NO_HELP | ARGP_NO_EXIT, 0, 0)) {
		argp_help(&argp, stderr, ARGP_HELP_SHORT_USAGE, PROGRAM_NAME);
		return -1;
	}

	if (!port) {
		argp_help(&argp, stderr, ARGP_HELP_SHORT_USAGE, PROGRAM_NAME);
		return -1;
	}

	/* Allocate DVB structure and start seek for devices */
	dvb = dvb_dev_alloc();
	if (!dvb) {
		err("Can't allocate DVB data\n");
		return -1;
	}

	dvb_dev_find(dvb, 0, NULL);

	/* Create a socket */
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0) {
		local_perror("socket");
		goto error;
	}

	/* Initialize listen address struct */
	bzero((char *) &serv_addr, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(port);

	/* Bind to the address */
	ret = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
	if (ret < 0) {
		local_perror("bind");
		goto error;
	}

	/* FIXME: should allow the caller to set the verbosity */
	dvb_dev_set_log(dvb, 1, dvb_remote_log);

	/* Listen up to 5 connections */
	listen(sockfd, 5);
	addrlen = sizeof(cli_addr);

	start_signal_handler();
	pthread_mutex_init(&msg_mutex, NULL);
	pthread_mutex_init(&dvb_read_mutex, NULL);

	/* Accept actual connection from the client */

	warn("Support for Digital TV remote access is still highly experimental.\n"
	     "\nKnown issues:\n"
	     "  - Abort needed to be implemented in a proper way;\n"
	     "  - Need to make more stuff opaque, as touching on fields at the local\n"
	     "    end is not automatically reflected remotely;\n"
	     "  - The libdvbv5 API support is incomplete: it misses satellite, scan\n"
	     "    and other functions;\n\n");

	info(PROGRAM_NAME" started.");

	while (1) {
		int fd;
		pthread_t id;

		if (verbose)
			dbg("waiting for connections");
		fd = accept(sockfd, (struct sockaddr *)&cli_addr, &addrlen);
		if (fd < 0) {
			local_perror("accept");
			break;
		}

		if (verbose)
			dbg("accepted connection %d", fd);
		ret = pthread_create(&id, NULL, start_server, (void *)&fd);
		if (ret < 0) {
			local_perror("pthread_create");
			break;
		}
	}

	/* Just in case we add some way for the remote part to stop the daemon */
	stop_signal_handler();

error:
	info(PROGRAM_NAME" stopped.");

	pthread_exit(NULL);

	if (dvb)
		dvb_dev_free(dvb);

	return -1;
}