/* * Lengen Copyright 2005 Michael John Wensley * This program reads from standard in until there is no more to read. * It then outputs the length of data read in bytes followed by the data itself. * * The purpose of this program is to wrap CGI output so * that web servers may do http pipelining for greater efficiency. * * To compile: gcc -o lengen lengen.c */ #include #include #include #include #include #include #include #include extern int optind, opterr, optopt; static struct option long_options[] = { {"help", 0, 0, 'h'}, {"http", 0, 0, 'w'}, {"gopher", 0, 0, 'g'}, {0, 0, 0, 0} }; int main(argc, argv) int argc; char *argv[]; { char c; char format = ' '; int capacity = 4; int size = 0; int option_index = 0; opterr = 0; while ((c = getopt_long(argc, argv, "hwg", long_options, &option_index)) != -1) { switch(c) { case 'h': printf("lengen Copyright 2005 Michael John Wensley\n"); printf("This program reads in a file on standard in, calculates its length\n"); printf("then outputs that followed by the file on the standard out.\n"); printf("\n"); printf("Use --http or -w for HTTP/1.1 style Content-Length.\n"); printf("Use --gopher or -g for Gopher Plus style length\n"); return EXIT_SUCCESS; ;; case 'w': format = 'w'; break; ;; case 'g': format = 'g'; break; ;; default: fprintf(stderr, "Usage: %s [--help|--http|--gopher]\n", argv[0]); return EXIT_FAILURE; } } void *ram = 0; while (! feof(stdin)) { /* buffer full...? double the capacity like java does */ if (size == capacity) capacity *= 2; ram = realloc(ram, capacity); if (ram == 0) { perror("lengen out of ram"); return EXIT_FAILURE; } clearerr(stdin); size += fread(ram + size, 1, capacity - size, stdin); if (ferror(stdin)) { perror("lengen problem with stdin"); return EXIT_FAILURE; } } switch(format) { /* gopherplus style */ case 'g': printf("+%d\n", size); break ;; /* http style */ case 'w': printf("Content-Length: %d\r\n\r\n", size); break;; default: printf("%d\n", size); break; } fwrite(ram, 1, size, stdout); return EXIT_SUCCESS; }