--- fbgrab-1.0/fbgrab.c 2002-04-15 22:22:54.000000000 +0200 +++ fbgrab/fbgrab.c 2006-05-31 15:08:09.000000000 +0200 @@ -9,6 +9,9 @@ * * For features and differences, read the manual page. * + * Support for transporting images over network + * (C) 2006 by Harald Welte + * * This program has been checked with "splint +posixlib" without * warnings. Splint is available from http://www.splint.org/ . * Patches and enhancements of fbgrab have to fulfill this too. @@ -18,7 +21,13 @@ #include #include #include +#include #include +#include +#include +#include +#include +#include #include #include /* to handle vt changing */ @@ -30,6 +39,10 @@ #define MAX_LEN 512 #define UNDEFINED -1 +static int quiet; + +#define qrintf(x, args...) do { if (!quiet) printf(x, ## args); } while (0) + /*@noreturn@*/ static void fatal_error(char *message) { fprintf(stderr, "%s\n", message); @@ -38,8 +51,8 @@ static void usage(char *binary) { - printf("Usage: %s\t[-hi] [-{C|c} vt] [-d dev] [-s n]\n" - "\t\t[-f fromfile -w n -h n -b n] filename.png\n", binary); + printf("Usage: %s\t[-hi] [-{C|c} vt] [-d dev] [-s n] [-D]\n" + "\t\t[-f fromfile -w n -h n -b n] [-H host [-P port]] filename.png\n", binary); } static void help(char *binary) @@ -62,6 +75,10 @@ static void help(char *binary) printf("\t-w n \tset width to n pixels, required when reading from file\n" "\t\tcan be used to force width when reading from framebuffer\n"); printf("\t-? \tprint this usage information\n"); + printf("\t-H host\thostname to where the image is to be sent\n"); + printf("\t-P port\tport number at destination host (default 2342)\n"); + printf("\t-D\tdaemonize\n"); + printf("\t-q\tquiet\n"); } @@ -228,7 +245,8 @@ static void write_PNG(unsigned char *out png_init_io(png_ptr, outfile); - png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); + //png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); + png_set_compression_level(png_ptr, Z_BEST_SPEED); bit_depth = 8; color_type = PNG_COLOR_TYPE_RGB_ALPHA; @@ -241,7 +259,7 @@ static void write_PNG(unsigned char *out png_write_info(png_ptr, info_ptr); - printf ("Now writing PNG file\n"); + qrintf ("Now writing PNG file\n"); png_write_image(png_ptr, row_pointers); @@ -266,7 +284,7 @@ static void convert_and_write(unsigned c memset(outbuffer, 0, bufsize); - printf ("Converting image from %i\n", bits); + qrintf ("Converting image from %i\n", bits); switch(bits) { @@ -295,6 +313,77 @@ static void convert_and_write(unsigned c } +static int net_init(const char *host, const char *service) +{ + struct addrinfo hints, *res, *ressave; + int n, sockfd = -1; + + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + + n = getaddrinfo(host, service, &hints, &res); + if (n < 0) { + fprintf(stderr, "getaddrinfo() error %s\n", + gai_strerror(n)); + return -1; + } + + ressave = res; + while (res) { + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sockfd >= 0) { + if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0) + break; + close(sockfd); + sockfd = -1; + } + res = res->ai_next; + } + + freeaddrinfo(ressave); + return sockfd; +} + +#define NET_FILE_HDR_MAGIC 0x23421102 + +struct net_file_hdr { + u_int32_t magic; + u_int32_t size; +}; + +static int net_send_file(int sockfd, const char *fname) +{ + int rc, fd = open(fname, O_RDONLY); + struct stat st; + off_t off = 0; + struct net_file_hdr nh; + + if (fd < 0) + return fd; + + rc = fstat(fd, &st); + if (rc < 0) { + close(fd); + return rc; + } + + nh.magic = htonl(NET_FILE_HDR_MAGIC); + nh.size = htonl(st.st_size); + + rc = write(sockfd, &nh, sizeof(nh)); + if (rc < 0) { + close(fd); + return rc; + } + + rc = sendfile(sockfd, fd, &off, st.st_size); + + close(fd); + + return rc; +} + + /******** * MAIN * ********/ @@ -312,6 +401,9 @@ int main(int argc, char **argv) struct fb_var_screeninfo fb_varinfo; int waitbfg=0; /* wait before grabbing (for -C )... */ int interlace = PNG_INTERLACE_NONE; + char *hostname = NULL, *service = "2342"; + int loop = 0, sockfd = -1; + int daemonize = 0; memset(infile, 0, MAX_LEN); memset(&fb_varinfo, 0, sizeof(struct fb_var_screeninfo)); @@ -319,7 +411,7 @@ int main(int argc, char **argv) for(;;) { - optc=getopt(argc, argv, "f:w:b:gh:iC:c:d:s:?"); + optc=getopt(argc, argv, "f:w:b:gh:iC:c:Dd:qs:?H:P:l"); if (optc==-1) break; switch (optc) @@ -337,6 +429,9 @@ int main(int argc, char **argv) case 'd': device = optarg; break; + case 'D': + daemonize = 1; + break; case 'f': strncpy(infile, optarg, MAX_LEN); break; @@ -349,12 +444,24 @@ int main(int argc, char **argv) case 'i': interlace = PNG_INTERLACE_ADAM7; break; + case 'l': + loop = 1; + break; + case 'q': + quiet = 1; + break; case 's': (void) sleep((unsigned int) atoi(optarg)); break; case 'w': width = atoi(optarg); break; + case 'H': + hostname = optarg; + break; + case 'P': + service = optarg; + break; default: usage(argv[0]); } @@ -412,6 +519,16 @@ int main(int argc, char **argv) if(buf_p == NULL) fatal_error("Not enough memory"); + if (hostname) { + sockfd = net_init(hostname, service); + if (sockfd < 0) { + fprintf(stderr, "unable to connect to %s:%s\n", + hostname, service); + exit(1); + } + } + +loop: memset(buf_p, 0, buf_size); read_framebuffer(infile, buf_size, buf_p); @@ -421,6 +538,11 @@ int main(int argc, char **argv) convert_and_write(buf_p, outfile, width, height, bitdepth, interlace); + if (sockfd >= 0) + net_send_file(sockfd, outfile); + if (loop) + goto loop; + (void) free(buf_p); return 0;