/****************************************************************************** * * This code has been modified to compose a filmloop of image files. * * This code is released into the public domain. * * Last modfied by Rus Berrett, SurfUtah.Com (http://www.surfutah.com) * November 28, 1995 * * example of how to use "push.cgi" to push 8 images located in a directory- * * image0.gif * image1.gif * image2.gif * image3.gif * image4.gif * image5.gif * image6.gif * image7.gif * * * |---------------||---------------------| |--------| |----------| * path to cgi path to images basename last frame * executable that are pushed of images * * Other options: firstframe, delay, reverse, numloops, imagetype * * By default- * firstframe will be "0" * the delay will be "0" * reverse will be "0" (FALSE) * numloops will be "1" * imagetype will be "gif" * * So, if the you had 8 jpeg's in the same directory (as the example above) * and want to cycle 1-8 then 8-1 and also to do it twice. I could use the * following cgi call as the "src": * * /cgi-bin/push.cgi/usr/local/httpd/images?base=image&lastframe=7&reverse=1&numloops=2&imagetype=jpeg * * Please note that name/value arguments are separated by an ampersand "&", * and that no spaces (or carriage returns) are present. * * I know, I know- it's really long. Well. too bad- feel free to modify * the source in any way you see fit. * * Also... note that server push only works for Netscape 1.1+, so I just * display the first image in the loop for other HTTP_USER_AGENTs * *****************************************************************************/ /* * doit.c: Quick hack to play a sequence of image files. * * Rob McCool * * This code is released into the public domain. Do whatever * you want with it. * */ #define _INCLUDE_POSIX_SOURCE 1 #define _INCLUDE_XOPEN_SOURCE 1 #define _INCLUDE_AES_SOURCE 1 #include #include #include #include #include #include #include #include #define HEADER "Content-type: multipart/x-mixed-replace;boundary=ThisRandomString\n" #define RANDOMSTRING "\n--ThisRandomString\n" #define ENDSTRING "\n--ThisRandomString--\n" char CTSTRING[256]; #define DEBUG 0 /*---------------------------------------------------------------------------*/ static int HexToDecimal(char first, char second) { int value; first = tolower(first); second = tolower(second); switch (first) { case '0': value = 16 * 0; break; case '1': value = 16 * 1; break; case '2': value = 16 * 2; break; case '3': value = 16 * 3; break; case '4': value = 16 * 4; break; case '5': value = 16 * 5; break; case '6': value = 16 * 6; break; case '7': value = 16 * 7; break; case '8': value = 16 * 8; break; case '9': value = 16 * 9; break; case 'a': value = 16 * 10; break; case 'b': value = 16 * 11; break; case 'c': value = 16 * 12; break; case 'd': value = 16 * 13; break; case 'e': value = 16 * 14; break; case 'f': value = 16 * 15; break; } switch (second) { case '0': value += 0; break; case '1': value += 1; break; case '2': value += 2; break; case '3': value += 3; break; case '4': value += 4; break; case '5': value += 5; break; case '6': value += 6; break; case '7': value += 7; break; case '8': value += 8; break; case '9': value += 9; break; case 'a': value += 10; break; case 'b': value += 11; break; case 'c': value += 12; break; case 'd': value += 13; break; case 'e': value += 14; break; case 'f': value += 15; break; } return(value); } /* HexToDecimal */ /*---------------------------------------------------------------------------*/ static int ReadNameValuePair(char *thestring, char *name, char *thevalue) { char *cptr = NULL, *endcptr = NULL; cptr = strstr(thestring, "="); cptr[0] = '\0'; strcpy(name, thestring); cptr++; endcptr = strstr(cptr, "&"); if (endcptr) { endcptr++; endcptr[-1] = '\0'; } /* copy the value of before the original string gets overwritten */ strcpy(thevalue, cptr); if (endcptr) strcpy(thestring, endcptr); if (strstr(thestring, "=")) return(0); else return(1); } /* ReadNameValuePair */ /*---------------------------------------------------------------------------*/ void main(int argc, char *argv[]) { /* variables set by cgi arguments */ char PATH_NAME[1000]; /* the path name of the images */ char IMAGE_BASE_NAME[256]; /* the base name of the images */ int LAST_FRAME; /* the number of images */ int FIRST_FRAME = 0; /* id of first frame (usually 0 or 1) */ int DELAY = 0; /* seconds to delay between each image */ int REVERSE_LOOP = 0; /* turn reverseing ON (1) or OFF (0) */ int NUM_LOOPS = 1; /* the number of loops to show >= 1 */ char IMAGE_TYPE[32]; /* the content type, "gif", "jpeg" */ /* other local variables */ struct stat fi; char fn[512]; caddr_t fp; int fd, enhanced = 0; int done, i, len, forward = 1, nindex, index; int frameid = FIRST_FRAME; char thestring[2000], agent[512], *cptr = NULL; char name[256], value[256]; strcpy(IMAGE_TYPE, "gif"); sprintf(PATH_NAME, "%s", getenv("PATH_INFO")); len = strlen(PATH_NAME); if (PATH_NAME[len-1] != '/') { PATH_NAME[len] = '/'; PATH_NAME[len+1] = '\0'; } sprintf(thestring, "%s", getenv("QUERY_STRING")); nindex = 0; len = strlen(thestring); for (index = 0; index < len; index++) { if (thestring[index] == '+') { thestring[nindex++] = ' '; } else if (thestring[index] == '%') { /* convert hex to decimal */ thestring[nindex++] = (char)HexToDecimal(thestring[index+1], thestring[index+2]); index+=2; } else { thestring[nindex++] = thestring[index]; } } thestring[nindex] = '\0'; done = 0; while (!done) { done = ReadNameValuePair(thestring, name, value); if (!strcmp(name, "base")) strcpy(IMAGE_BASE_NAME, value); else if (!strcmp(name, "lastframe")) sscanf(value, "%d", &LAST_FRAME); else if (!strcmp(name, "firstframe")) sscanf(value, "%d", &FIRST_FRAME); else if (!strcmp(name, "delay")) sscanf(value, "%d", &DELAY); else if (!strcmp(name, "reverse")) sscanf(value, "%d", &REVERSE_LOOP); else if (!strcmp(name, "numloops")) sscanf(value, "%d", &NUM_LOOPS); else if (!strcmp(name, "imagetype")) strcpy(IMAGE_TYPE, value); } /* debugging */ if (DEBUG) { printf("Content-Type: text/html\n\n"); printf("path = %s\n

\n", PATH_NAME); printf("basename = %s\n

\n", IMAGE_BASE_NAME); printf("lastframe = %d\n

\n", LAST_FRAME); printf("firstframe = %d\n

\n", FIRST_FRAME); printf("delay = %d\n

\n", DELAY); printf("reverseloop = %d\n

\n", REVERSE_LOOP); printf("numloops = %d\n

\n", NUM_LOOPS); printf("imagetype = %s\n

\n", IMAGE_TYPE); } sprintf(CTSTRING, "Content-type: image/%s\n\n", IMAGE_TYPE); /* test for Netscape 1.1 or higher */ sprintf(agent, "%s", getenv("HTTP_USER_AGENT")); cptr = strstr(agent, "Mozilla"); if (cptr) { cptr += 8; if (strncmp("1.1", cptr, 3) <= 0) enhanced = 1; } if (enhanced) { if(write(STDOUT_FILENO, HEADER, strlen(HEADER)) == -1) exit(0); if(write(STDOUT_FILENO, RANDOMSTRING, strlen(RANDOMSTRING)) == -1) exit(0); for (i = 0; i < NUM_LOOPS; i++) { done = 0; forward = 1; frameid = FIRST_FRAME; while (!done) { if (!DEBUG) { if(write(STDOUT_FILENO, CTSTRING, strlen(CTSTRING)) == -1) exit(0); sprintf(fn, "%s%s%d.%s", PATH_NAME, IMAGE_BASE_NAME, frameid, IMAGE_TYPE); if((fd = open(fn, O_RDONLY)) == -1) continue; fstat(fd, &fi); fp = mmap(NULL, fi.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if(fp == (caddr_t) -1) exit(0); if(write(STDOUT_FILENO, (void *)fp, fi.st_size) == -1) exit(0); munmap(fp, fi.st_size); close(fd); if(write(STDOUT_FILENO, RANDOMSTRING, strlen(RANDOMSTRING)) == -1) exit(0); } else { printf("filename = %s%s%d.%s
\n", PATH_NAME, IMAGE_BASE_NAME, frameid, IMAGE_TYPE); } if (REVERSE_LOOP) { if (frameid >= LAST_FRAME) forward = 0; done = (!forward && frameid == FIRST_FRAME); } else { done = (frameid >= LAST_FRAME); } if (forward) frameid++; else frameid--; if (DELAY) sleep(DELAY); } } /* write(STDOUT_FILENO, ENDSTRING, strlen(ENDSTRING)); */ } else { if(write(STDOUT_FILENO, CTSTRING, strlen(CTSTRING)) == -1) exit(0); sprintf(fn, "%s%s%d.%s", PATH_NAME, IMAGE_BASE_NAME, frameid, IMAGE_TYPE); if((fd = open(fn, O_RDONLY)) == -1) exit(0); fstat(fd, &fi); fp = mmap(NULL, fi.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if(fp == (caddr_t) -1) exit(0); if(write(STDOUT_FILENO, (void *)fp, fi.st_size) == -1) exit(0); munmap(fp, fi.st_size); close(fd); } } /* main */ /*---------------------------------------------------------------------------*/ /* eof */