/* 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; }
/* * 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); }
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; }
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); }
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; }