#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 */