#---------------------------------- cut here ---------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Alexander Carlton on Tue May 9 13:09:31 2000 # # This archive contains: # spec99cadscan.c spec99cgi.c spec99fcgi.c spec99gp.c # # Error checking via wc(1) will be performed. # Error checking via sum(1) will be performed. LANG=""; export LANG PATH=/bin:/usr/bin:/usr/sbin:/usr/ccs/bin:$PATH; export PATH EXIT_STATUS=0 if sum -r /dev/null 2>&1 then sumopt='-r' else sumopt='' fi echo x - spec99cadscan.c cat >spec99cadscan.c <<'@EOF' /* ** Copyright (c) 1999 by HEWLETT-PACKARD COMPANY. All Rights Reserved. ** ** The information contained in this document is subject to change without ** notice. ** ** HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THE MATERIAL, ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARANTIES OF MERCHANTABILITY ** AND FITNESS FOR A PARTICULAR PURPOSE. ** ** Hewlett-Packard shall not be liable for errors contained herein or for ** incidental or consequential damages in connection with furnishing, ** performance, or use of this material. Hewlett-Packard assumes no ** responsibility for the use or reliability of its software on equipment ** that is not furnished by Hewlett-Packard. This document contains proprietary ** information that is protected by copyright. All rights are reserved. No ** part of this document may be photocopied, reproduced, or translated to ** another language without the prior written consent of Hewlett-Packard ** Company. */ /* ** spec99cadscan.c ** Web server application for SPECweb99 dynamic requests. ** This module uses ISAPI to interface with the Web server. ** ** usage 1: GET with Cookie ** GET /spec/isapi/cadscan.sl?/spec/file_set/dir/class_ ** Cookie: my_cookie=user_id=&last_id= ** ** Revision History: ** 07/23/99 (Yea-Cheng Wang) ** For SPECweb99 blind submission. */ #include #include #include #include #include #include #include #include #include #include #include /* DOCUMENT ROOT */ #define TOPDIR "/spec/web99" #define BUF_SIZE 256 #define HTTP_BUF_SIZE 256 #define COOKIE_BUF_SIZE 256 #define HTML_BUF_SIZE 1024 #define TITLE "\nSPECweb99 Dynamic GET & POST Test\ \n\n

SERVER_SOFTWARE = " #define SCRIPT "\n

SCRIPT_NAME = " #define REMOTE "\n

REMOTE_ADDR = " #define QUERY "\n

QUERY_STRING = " #define BODY "\n

\n"
#define SUFFIX "\n
\n\n" #define SPACE 64; /* for sendRespMsg() */ #define HTTP_HEADER "Content-Type: text/html\n" /************************** ** Global Variables ** **************************/ char prefix[HTML_BUF_SIZE]; int prefixLen=0; char *html; char fullName[MAXPATHLEN] = TOPDIR; char* urlName = fullName + sizeof(TOPDIR) -1; /* Used by HttpExtensionProc(), and customAdRotation() */ char *cookiePtr, *adPtr; static char httpCookie[] = "200 OK\nContent-Type: text/html\nSet-Cookie: found_cookie=Ad_id=360&Ad_weight=0000&Expired=0\nContent-Length:12345\n"; char* httpContentCookiePtr = httpCookie + 7; char* httpSetCookiePtr = httpCookie + 31; char* httpCookieIdPtr = httpCookie + 62; char httpWtCookie[] = "&Ad_weight=00000"; char* httpWtPtr = httpWtCookie + 11; char httpExp0Cookie[] = "&Expired=0"; char httpExp1Cookie[] = "&Expired=1"; char* customAdRotation (int * index); char* readCAD (); #define CAD_TEMPLATE "lpszQueryString int sendRespMsg (LPEXTENSION_CONTROL_BLOCK ecb, char *httpHeaderPtr, char *htmlHeader, int htmlLen, char *msg); /**************************** *** ISAPI Extension **** ****************************/ BOOL WINAPI GetExtensionVersion( HSE_VERSION_INFO *pVer ) { /* ISAPI initialization routine */ /*pVer->dwExtensionVersion = HSE_VERSION_MAJOR;*/ pVer->dwExtensionVersion = 1; strncpy(pVer->lpszExtensionDesc, "Specweb99", HSE_MAX_EXT_DLL_NAME_LEN); /* default with everything being zero. */ html = malloc(urlFileBufLen+HTML_BUF_SIZE+sizeof(SUFFIX)); return TRUE; } #define CONTENT_COOKIE_ERR_OFFS 7 int WINAPI HttpExtensionProc( LPEXTENSION_CONTROL_BLOCK ecb ) { /* This ISAPI HTTP Extension function is called when there is a */ /* HTTP request on this application module. */ int hseStatus; char cookieStr[COOKIE_BUF_SIZE]; char *this; char *htmlPtr; int htmlLen, length; int tLen; HSE_TF_INFO tf1; /* Set up the HTML Page */ if (0 == prefixLen) { /* the first time */ strcpy (html, TITLE); htmlPtr = html + sizeof(TITLE)-1; length = SPACE; ecb->GetServerVariable(ecb->ConnID, "SERVER_SOFTWARE", htmlPtr, &length); htmlPtr += --length; strcpy (htmlPtr, SCRIPT); htmlPtr = htmlPtr + sizeof(SCRIPT)-1; length = SPACE; ecb->GetServerVariable(ecb->ConnID, "SCRIPT_NAME", htmlPtr, &length); htmlPtr += --length; strcpy (htmlPtr, REMOTE); htmlPtr = htmlPtr + sizeof(REMOTE)-1; prefixLen = htmlPtr - html; strcpy (prefix, html); } htmlPtr = html + prefixLen; length = SPACE; ecb->GetServerVariable(ecb->ConnID, "REMOTE_ADDR", htmlPtr, &length); htmlPtr += --length; sprintf(htmlPtr, "%s%s%s", QUERY, QUERY_STR, BODY); htmlLen = strlen (html); length = COOKIE_BUF_SIZE; ecb->GetServerVariable(ecb->ConnID, "ALL_HTTP", cookieStr, &length); /* Cookie: my_cookie=user_id=10012&last_ad=120 */ cookiePtr = adPtr = NULL; if (NULL != (this = strchr(cookieStr, '='))) { if (NULL != (this = strchr(++this, '='))) { cookiePtr = ++this; this = cookiePtr + 5; *this = '\0'; adPtr = this = this + 8; if (NULL != (this = strchr(this, '\n'))) *this = '\0'; } } /* Process the HTTP Request */ if (0 == strcmp(ecb->lpszMethod, "GET")) { /*********************/ /*** GET REQUEST ***/ /*********************/ if ( strlen(QUERY_STR) > 0) { int adID; char *classPtr; char *cookieMsgPtr; int urlFileLen; /* return the file in query string */ strcpy(urlName, QUERY_STR); /* Need to process WEB99CAD if it is class1/class2 */ if ( ((classPtr = strstr (urlName, "class")) != NULL) && (49 == *(classPtr+5) || 50 == *(classPtr+5)) ){ cookieMsgPtr = (char *) customAdRotation(&adID); if ( -1 == adID ) { hseStatus = sendRespMsg(ecb, cookieMsgPtr+CONTENT_COOKIE_ERR_OFFS, html, htmlLen, "Bad Cookie ID!\n"); } else { if (-1 == (urlFileLen = cadScan(fullName, adID, &html[htmlLen]))){ hseStatus = sendRespMsg(ecb, httpContentCookiePtr, html, htmlLen, NULL); } else { int length; length = strlen (httpContentCookiePtr); sprintf (&httpContentCookiePtr[length], "\nContent-Length: %d\n", htmlLen+urlFileLen+sizeof(SUFFIX)-1); hseStatus = sendRespMsg(ecb, httpContentCookiePtr, html, htmlLen+urlFileLen, NULL); } } } else { /* class0 or class2 */ memset( &tf1, 0, sizeof( HSE_TF_INFO ) ); /* customAdRotation returns either valid */ /* cookie string, or error information about */ /* cookie string */ ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_ALLOC_MEM, &tf1.pHead,&htmlLen,0); tf1.pHead=(PVOID)html; tf1.TailLength=tLen=sizeof(SUFFIX)-1; ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_ALLOC_MEM, &tf1.pTail,&tLen,0); tf1.pTail=(PVOID)SUFFIX; tf1.dwFlags = HSE_IO_SEND_HEADERS|HSE_IO_DISCONNECT_AFTER_SEND| HSE_IO_HANDLE_IS_FILENAME; tf1.pszStatusCode = (const char *) customAdRotation(&adID); tf1.HeadLength = htmlLen; tf1.hFile = (HANDLE)fullName; if( ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_TRANSMIT_FILE, &tf1, 0, 0 ) == TRUE ) return HSE_STATUS_SUCCESS_AND_KEEP_CONN; return HSE_STATUS_ERROR; } /* WEB99CAD: non class1/class2 */ } else { /* respond now with the message */ hseStatus = sendRespMsg(ecb, (char *)NULL, html, htmlLen, "QUERY_STRING not set!\n"); } } /* GET request */ return hseStatus; } #define newURLLen 14 int cadScan (char *fileName, int adID, char *urlFileBuf) { int fd; int readLen; char *template; char newURL[newURLLen+1]; int len; if ((fd = open (fileName, O_RDONLY, NULL)) == -1) { sprintf (urlFileBuf, "Cannot open file '%s' (%s)\n", fileName, strerror(errno) ); return -1; } readLen = (int) read (fd, urlFileBuf, urlFileBufLen); close (fd); urlFileBuf[readLen] = '\0'; template = urlFileBuf; sprintf (newURL, "%05d/class%d_%d", adID/36, (adID%36)/9, adID%9); while (NULL != (template = strstr(template, CAD_TEMPLATE))) { template += CAD_TEMPLATE_LEN; strncpy(template, newURL, newURLLen); template += newURLLen; } return readLen; } /******************************************************************* *** Customized Ad Rotation *** ********************************************************************/ #define GENDER_MASK 0x30000000 #define AGE_GROUP_MASK 0x0f000000 #define REGION_MASK 0x00f00000 #define INTEREST1_MASK 0x000ffc00 #define INTEREST2_MASK 0x000003ff #define CADFILE TOPDIR"/Custom.Ads" #define UPFILE TOPDIR"/User.Personality" #define USER_REC_LEN 15 #define USER_DEMO_OFFS 6 #define USER_DEMO_LEN USER_REC_LEN - USER_DEMO_OFFS #define CADFILE_ENTRIES 360 #define CAD_REC_LEN 39 #define CAD_DEMO_OFFS 6 #define CAD_WEIGHT_OFFS 15 #define CAD_MIN_OFFS 24 #define CAD_EXPIRE_OFFS 28 /* Status and Set-Cookie error string */ #define LAST_AD_ERR "200 OK\nContent-Type: text/html\n\ Set-Cookie: Ad_id=-10&Ad_weight=00&Expired=1" #define UPF_OPEN_ERR "200 OK\nContent-Type: text/html\n\ Set-Cookie: Ad_id=-9&Ad_weight=00&Expired=0" #define CAD_OPEN_ERR "200 OK\nContent-Type: text/html\n\ Set-Cookie: Ad_id=-9&Ad_weight=00&Expired=1" #define UPF_SEEK_ERR "200 OK\nContent-Type: text/html\n\ Set-Cookie: Ad_id=-8&Ad_weight=00&Expired=0" #define UPF_READ_ERR "200 OK\nContent-Type: text/html\n\ Set-Cookie: Ad_id=-7&Ad_weight=00&Expired=0" #define CAD_READ_ERR "200 OK\nContent-Type: text/html\n\ Set-Cookie: Ad_id=-7&Ad_weight=00&Expired=1" #define UPF_RECORD_ERR "200 OK\nContent-Type: text/html\n\ Set-Cookie: Ad_id=-6&Ad_weight=00&Expired=0" #define CAD_RECORD_ERR "200 OK\nContent-Type: text/html\n\ Set-Cookie: Ad_id=-6&Ad_weight=00&Expired=1" #define RECORD_NOT_FOUND "200 OK\nContent-Type: text/html\n\ Set-Cookie: Ad_id=-1&Ad_weight=00&Expired=0" #define CAD_NOT_MATCHED "200 OK\nContent-Type: text/html\n\ Set-Cookie: Ad_id=-1&Ad_weight=00&Expired=1" FILE *upfPtr=NULL; time_t lastTime; /* The following are defined in readCAD(), referred to in customAdRotation() */ unsigned int adDemograf[CADFILE_ENTRIES]; int adMinMatch[CADFILE_ENTRIES]; int adExpiration[CADFILE_ENTRIES]; int adWtGender[CADFILE_ENTRIES]; int adWtAge[CADFILE_ENTRIES]; int adWtRegion[CADFILE_ENTRIES]; int adWtInterest1[CADFILE_ENTRIES]; int adWtInterest2[CADFILE_ENTRIES]; /*************************************************************************** If customAdRotation() can retrieve the adIndex successfully, it will return the constructed cookie string in httpCookie[].The cookieIndex will then be the adIndex, httpCookie[] is the returned pointer. If it cannot retrieve the adIndex successfully, it will set cookieIndex to -1, and return one of the predefined Set-Cookie error HTML status strings. ***************************************************************************/ char* customAdRotation (int *cookieIndex) { int myUser, adIndex, ad; long int offset; char demographics[USER_REC_LEN]; unsigned int userDemograf, combined; struct stat cadStat; int weight; char *cookieStatus; *cookieIndex = -1; /* in case it failed to get the proper adIndex */ /* Get the User Profile from the UPFILE */ myUser = atoi(cookiePtr) - 10000; offset = myUser * USER_REC_LEN + USER_DEMO_OFFS; if (NULL == upfPtr) if (NULL == (upfPtr = fopen (UPFILE, "r"))) { syslog (LOG_ERR, "SPECweb99 Cookie: UPF file: '%s' open error (%s)", UPFILE, strerror(errno)); return UPF_OPEN_ERR; } if (0 != fseek(upfPtr, (long int) offset, SEEK_SET)) { syslog (LOG_ERR, "SPECweb99 Cookie: UPF file: '%s' seek error (%s)", UPFILE, strerror(errno)); return UPF_SEEK_ERR; } if ( USER_DEMO_LEN != fread(demographics, (size_t)sizeof(char), (size_t)USER_DEMO_LEN, upfPtr)) { syslog (LOG_ERR, "SPECweb99 Cookie: UPF Demographics read error (%s)", strerror(errno)); return UPF_READ_ERR; } if ( 0 == (userDemograf = (int) strtoul(demographics,(char **)NULL, 16))){ syslog (LOG_ERR, "SPECweb99 Cookie: Demographics strtoul() error (%s)", strerror(errno)); return UPF_RECORD_ERR; } adIndex = atoi(adPtr); if (( adIndex >= CADFILE_ENTRIES) || (adIndex < 0 )) { syslog (LOG_ERR, "SPECweb99 Cookie: Invalid Ad Index (%d)", adIndex); return LAST_AD_ERR; } adIndex++; if ( CADFILE_ENTRIES == adIndex ) adIndex = 0; /* Has the file been modified? */ if (stat(CADFILE, &cadStat) <0) { syslog (LOG_ERR, "SPECweb99 Cookie: stat failed on %s (%s)\n", CADFILE, strerror(errno)); } if (cadStat.st_mtime > lastTime) { lastTime = cadStat.st_mtime; /* read in the latest CADFILE */ if (NULL != (cookieStatus =readCAD())) return cookieStatus; } /* CADFILE has been successfully read in */ /* Now loop for the matched CAD record starting at adIndex */ for (ad = 0; ad= adMinMatch[adIndex]) { /* customAdRotation is successful */ *cookieIndex = adIndex; strcpy (httpCookieIdPtr, ltoa(adIndex)); strcpy (httpWtPtr, ltoa(weight)); strcat (httpCookie, httpWtCookie); /* Check for expiry */ if (time(NULL) > adExpiration[adIndex]) strcat (httpCookie,httpExp1Cookie); else strcat (httpCookie,httpExp0Cookie); /* return the new cookie string */ return httpCookie; } adIndex++; if ( CADFILE_ENTRIES == adIndex ) adIndex = 0; } /* Loop for the next CAD record */ return CAD_NOT_MATCHED; } /* The following are used only in readCAD() */ char cadRec[CAD_REC_LEN]; char* cadDemoPtr = cadRec + CAD_DEMO_OFFS; char* cadWeightPtr = cadRec + CAD_WEIGHT_OFFS; char* cadMinPtr = cadRec + CAD_MIN_OFFS; char* cadExpirePtr = cadRec + +CAD_EXPIRE_OFFS; char* readCAD () { int index; unsigned int adWeight; FILE *cadfPtr; if (NULL == (cadfPtr = fopen (CADFILE, "r"))) { syslog (LOG_ERR, "SPECweb99 Cookie: CAD file open error (%s)", strerror(errno)); return CAD_OPEN_ERR; } for (index = 0; index> 4) & 0x0000000f; adWtRegion[index] = (adWeight >> 8) & 0x0000000f; adWtAge[index] = (adWeight >> 12) & 0x0000000f; adWtGender[index] = (adWeight >> 16) & 0x0000000f; } /* for index loop */ return NULL; } /* ** Send the HTTP response back to the client. ** */ int sendRespMsg (LPEXTENSION_CONTROL_BLOCK ecb, char* httpHeaderPtr, char *htmlHeader, int htmlLen, char *msg) { int status; int length; int buffer[256]; /* Set the response header using ISAPI HSE Support function. */ /* - if httpHeaderPtr is NULL, use the predefined HTTP_HEADER, */ /* otherwise use the given string. */ /* Send the HTTP response back using ISAPI WriteClient funciton. */ /* - If msg is not NULL, then send this message in addition to the */ /* HTML close tag to the client. */ /* Set the http header for the response message */ if (NULL == httpHeaderPtr) { length = sizeof (HTTP_HEADER) -1; strcpy((char *)buffer,HTTP_HEADER); if (!ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, 0, &length, (int*)buffer)) return HSE_STATUS_ERROR; } else { length = strlen (httpHeaderPtr) - 1; strcpy((char *)buffer,httpHeaderPtr); if (!ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, 0, &length, (int*)buffer)) return HSE_STATUS_ERROR; } /* Send the html OPEN tags, msg if any, and close tag */ /* using WriteCleint() support function */ if (NULL != msg) { /* send both the msg and the HTTP CLOSE to the client using */ /* WriteClient() support function. */ if (ecb->WriteClient(ecb->ConnID, htmlHeader, &htmlLen, 0)) return HSE_STATUS_SUCCESS_AND_KEEP_CONN; else return HSE_STATUS_ERROR; length =strlen(msg); if (ecb->WriteClient(ecb->ConnID, msg, &length, 0)) return HSE_STATUS_SUCCESS_AND_KEEP_CONN; else return HSE_STATUS_ERROR; length =strlen(SUFFIX); if (ecb->WriteClient(ecb->ConnID, SUFFIX, &length, 0)) return HSE_STATUS_SUCCESS_AND_KEEP_CONN; else return HSE_STATUS_ERROR; } else { /* send just the HTML CLOSE tag */ length =strlen(SUFFIX); ecb->WriteClient(ecb->ConnID, htmlHeader, &htmlLen, 0); if (ecb->WriteClient(ecb->ConnID, SUFFIX, &length, 0)) return HSE_STATUS_SUCCESS_AND_KEEP_CONN; else return HSE_STATUS_ERROR; } } @EOF set `sum $sumopt spec99cgi.c <<'@EOF' /* ** Copyright (c) 1999 by HEWLETT-PACKARD COMPANY. All Rights Reserved. ** ** The information contained in this document is subject to change without ** notice. ** ** HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THE MATERIAL, ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARANTIES OF MERCHANTABILITY ** AND FITNESS FOR A PARTICULAR PURPOSE. ** ** Hewlett-Packard shall not be liable for errors contained herein or for ** incidental or consequential damages in connection with furnishing, ** performance, or use of this material. Hewlett-Packard assumes no ** responsibility for the use or reliability of its software on equipment ** that is not furnished by Hewlett-Packard. This document contains proprietary ** information that is protected by copyright. All rights are reserved. No ** part of this document may be photocopied, reproduced, or translated to ** another language without the prior written consent of Hewlett-Packard ** Company. */ /* ** spec99cgi.c ** ** CGI module for SPECweb99. ** ** usage 1: cgi GET ** GET /spec/cgi-bin/spec99.cgi?/spec/file_set/dir/class_ **/ #include #include #include #include #include #include #include #include #include #include #define TITLE "\nSPECweb99 Dynamic GET & POST Test\ \n\n

SERVER_SOFTWARE = " #define BUF_LEN 1024*1025 #define TOPDIR "/spec/web99" #define TOPDIR_LEN sizeof(TOPDIR)-1 size_t printFile(char *where, size_t length, char *fileName); void main(int argc, char **argv) { char *query; char *method; char urlFileBuf[BUF_LEN]; size_t len=0; ssize_t tmp; int fid; char fullname[MAXPATHLEN]=TOPDIR; len+=sprintf(urlFileBuf, "%s%s\n", TITLE, getenv("SERVER_SOFTWARE")); len+=sprintf(urlFileBuf+len, "

REMOTE_ADDR = %s\n", getenv("REMOTE_ADDR")); len+=sprintf(urlFileBuf+len, "

SCRIPT_NAME = %s\n", getenv("SCRIPT_NAME")); query = getenv("QUERY_STRING"); len+=sprintf(urlFileBuf+len, "

QUERY_STRING = %s\n

\n", query);

	if ( (method = getenv("REQUEST_METHOD")) &&
	    (strcmp(method, "GET") == 0) )
	{
		/*********************/
		/***  GET REQUEST  ***/
		/*********************/

		if (query && (sizeof(query) < MAXPATHLEN))
		{
			/* return the file in query string */
			sprintf(fullname+TOPDIR_LEN, "%s", query);
			len+=printFile(urlFileBuf+len, (size_t) (BUF_LEN-len), fullname);
		} else if (!query)
			len+=sprintf(urlFileBuf+len,"QUERY STRING not set!\n");
		else len+=sprintf(urlFileBuf+len,
		    "QUERY STRING is longer than %d bytes\n", MAXPATHLEN);

	} /* GET request */

	len+=sprintf(urlFileBuf+len, "\n
\n\n"); fid=atoi(argv[2]); tmp = write(fid, urlFileBuf, (size_t)len); } size_t printFile(char *where, size_t length, char *fileName) { int fd; ssize_t byteRead; size_t new_len=0; if ((fd = open(fileName, O_RDONLY)) < 0) { new_len+=sprintf(where, "Could not open file for reading - \"%s\" (%s)", fileName, strerror(errno)); } else { byteRead = read(fd, where, (ssize_t)length); if (byteRead < 0) new_len+=sprintf(where, "Error reading file '%s': error is %s\n", fileName, strerror(errno)); else new_len+=byteRead; if (close(fd) < 0) new_len+=sprintf(where+new_len, "Could not close file - \"%s\" (%s)", fileName, strerror(errno)); } return new_len; } @EOF set `sum $sumopt spec99fcgi.c <<'@EOF' /* ** Copyright (c) 1999 by HEWLETT-PACKARD COMPANY. All Rights Reserved. ** ** The information contained in this document is subject to change without ** notice. ** ** HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THE MATERIAL, ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARANTIES OF MERCHANTABILITY ** AND FITNESS FOR A PARTICULAR PURPOSE. ** ** Hewlett-Packard shall not be liable for errors contained herein or for ** incidental or consequential damages in connection with furnishing, ** performance, or use of this material. Hewlett-Packard assumes no ** responsibility for the use or reliability of its software on equipment ** that is not furnished by Hewlett-Packard. This document contains proprietary ** information that is protected by copyright. All rights are reserved. No ** part of this document may be photocopied, reproduced, or translated to ** another language without the prior written consent of Hewlett-Packard ** Company. */ /* ** spec99cgi.c ** ** CGI module for SPECweb99. ** ** usage 1: cgi GET ** GET /spec/cgi-bin/spec99.cgi?/spec/file_set/dir/class_ **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #define BUFFLEN 1049600 extern char ** environ; cgimain() { char *query; char *method; int len,i=0; int n,pid; static char *childargs[4]= {"spec.cgi","1","2",0}; char inbuff[1024]; int in[2],out[2]; char buff[BUFFLEN]; int count; int rc; rc = pipe(in); if( rc < 0 ) { syslog(LOG_ERR, "Cannot pipe in (%d)\n", errno); exit(1); } rc = pipe(out); if( rc < 0 ) { syslog(LOG_ERR, "Cannot pipe out (%d)\n", errno); exit(1); } sprintf(childargs[1], "%d", out[0]); sprintf(childargs[2], "%d", in[1]); pid = vfork(); if( pid == 0 ) { close(out[1]); close(in[0]); execve("/SPEC/web99/cgi-bin/spec.cgi", childargs, environ); syslog(LOG_ERR, "Failed exec (%d)\n", errno); _exit(1); } /* parent */ close(out[0]); close(in[1]); while ( (n= read(in[0],&buff[len], 8192)) >0) len+=n; buff[len]='\0'; printf("%s",buff); waitpid(pid,NULL,0); close(out[1]); close(in[0]); } void main() { int count, fd; /* Disconnect everything from parent */ count = 0; for( fd=1 ; fd= 0 ) { count++; } } syslog(LOG_ERR, "FastCGI: In parent we closed %d files\n",count); while ( FCGI_Accept() >= 0 ) { cgimain(); } } @EOF set `sum $sumopt spec99gp.c <<'@EOF' /* ** Copyright (c) 1999 by HEWLETT-PACKARD COMPANY. All Rights Reserved. ** ** The information contained in this document is subject to change without ** notice. ** ** HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THE MATERIAL, ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARANTIES OF MERCHANTABILITY ** AND FITNESS FOR A PARTICULAR PURPOSE. ** ** Hewlett-Packard shall not be liable for errors contained herein or for ** incidental or consequential damages in connection with furnishing, ** performance, or use of this material. Hewlett-Packard assumes no ** responsibility for the use or reliability of its software on equipment ** that is not furnished by Hewlett-Packard. This document contains proprietary ** information that is protected by copyright. All rights are reserved. No ** part of this document may be photocopied, reproduced, or translated to ** another language without the prior written consent of Hewlett-Packard ** Company. */ /* ** spec99gp.c ** ** Web server application for SPECweb99 dynamic requests. ** This module uses ISAPI to interface with the Web server. ** ** usage 1: GET ** GET /spec/isapi/spec99gp.sl?/spec/file_set/dir/class_ ** ** usage 2: commands ** GET /spec/isapi/spec99gp.sl?command/Reset&ml=n&pt=t&th=t&exp=l ** GET /spec/isapi/spec99gp.sl?command/Fetch ** ** usage 3: POST ** POST /spec/isapi/spec99gp.sl ** Content-length: ** ** urlroot=/spec/file_set/&dir=&class=&num=&client= ** ** ("key=val" are separated by a "&") ** ** Change History: ** 07/23/99 (Yea-Cheng Wang) ** For SPECweb99 blind submission. */ #include #include #include #include #include #include #include #include #include #include #include /* DOCUMENT ROOT */ #define TOPDIR "/spec/web99" #define CADGEN_CMD "/spec/web99/cadgen99" #define UPFGEN_CMD "/spec/web99/upfgen99" #define BUF_SIZE 256 #define HTTP_BUF_SIZE 256 #define HTML_BUF_SIZE 1024 #define READ_BUF_SIZE 4096 #define COOKIE_BUF_SIZE 256 #define POST_BUF_SIZE 512 #define COUNT_LEN 10 #define POST_LOG "/logs/post.log" #define TITLE "\nSPECweb99 Dynamic GET & POST Test\ \n\n

SERVER_SOFTWARE = " #define SCRIPT "\n

SCRIPT_NAME = " #define REMOTE "\n

REMOTE_ADDR = " #define QUERY "\n

QUERY_STRING = " #define QUERYnBODY "\n

QUERY_STRING = \n

\n"
#define BODY   "\n
\n"
#define SUFFIX "\n
\n\n" #define SPACE 64; #define HTTP_HEADER "Content-Type: text/html\n" #define HTTP_STATUS "Content-Type: text/html\r\n" /************************** ** Global Variables ** **************************/ char prefix[HTML_BUF_SIZE]; int prefixLen=0; char html[HTML_BUF_SIZE]; char fullName[MAXPATHLEN] = TOPDIR; char* urlName = fullName + sizeof(TOPDIR) -1; char logFile[MAXPATHLEN] = POST_LOG; static char httpCookie[] = "200 OK\r\nSet-Cookie: my_cookie=360----\r\n"; char* cookieIdPtr = httpCookie + 30; char *cookiePtr; pid_t mypid; int logfd=0; char tmpBuf[BUF_SIZE]; int sem_id; extern int errno; /****************************** *** ISAPI Extension **** ******************************/ #include "httpext.h" #include "wintypes.h" #define QUERY_STR ecb->lpszQueryString int sendRespMsg (LPEXTENSION_CONTROL_BLOCK ecb, char *htmlHeader, int htmlLen, char *msg); int createLogSendResp (LPEXTENSION_CONTROL_BLOCK ecb, char *htmlHeader, int htmlLen, char *fileName); int sendRespLogFile (LPEXTENSION_CONTROL_BLOCK ecb, char *htmlHeader, int htmlLen, char *fileName); int sem_init(); int get_sema(); int release_sema(); void remove_sema(); static unsigned int gct=0; BOOL WINAPI GetExtensionVersion( HSE_VERSION_INFO *pVer ) { /* ISAPI initialization routine */ pVer->dwExtensionVersion = 1; strncpy(pVer->lpszExtensionDesc, "SPECweb99 v1.0", HSE_MAX_EXT_DLL_NAME_LEN); /* default with everything being zero. */ mypid = getpid(); sem_init(); atexit(remove_sema); /* cleanup semaphore before exit */ return TRUE; } int WINAPI HttpExtensionProc( LPEXTENSION_CONTROL_BLOCK ecb ) { /* This ISAPI HTTP Extension function is called when there is a */ /* HTTP request on this application module. */ int hseStatus; char *maxldPtr, *pttPtr, *thPtr, *expPtr, *this; char cmdCAD[BUF_SIZE] = CADGEN_CMD; char cmdUPF[BUF_SIZE] = UPFGEN_CMD; HSE_TF_INFO tf; /* html[]: applicaton's HTML Page */ char *htmlPtr; int htmlLen, length; int tLen; memset( &tf, 0, sizeof( HSE_TF_INFO ) ); tf.HeadLength=htmlLen=strlen(html); ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_ALLOC_MEM, &tf.pHead,&htmlLen,0); tf.pHead=(PVOID)html; tf.TailLength=tLen=sizeof(SUFFIX)-1; ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_ALLOC_MEM, &tf.pTail,&tLen,0); tf.pTail=(PVOID)SUFFIX; tf.dwFlags = HSE_IO_SEND_HEADERS|HSE_IO_DISCONNECT_AFTER_SEND| HSE_IO_HANDLE_IS_FILENAME; gct++; /* Set up the HTML Page */ if (0 == prefixLen) { strcpy (html, TITLE); htmlPtr = html + sizeof(TITLE) - 1; length = SPACE; ecb->GetServerVariable(ecb->ConnID, "SERVER_SOFTWARE", htmlPtr, &length); htmlPtr += --length; strcpy (htmlPtr, SCRIPT); htmlPtr = htmlPtr + sizeof(SCRIPT) - 1; length = SPACE; ecb->GetServerVariable(ecb->ConnID, "SCRIPT_NAME", htmlPtr, &length); htmlPtr += --length; strcpy (htmlPtr, REMOTE); htmlPtr = htmlPtr + sizeof(REMOTE) - 1; prefixLen = htmlPtr - html; strcpy (prefix, html); } htmlPtr = html + prefixLen; length = SPACE; ecb->GetServerVariable(ecb->ConnID, "REMOTE_ADDR", htmlPtr, &length); htmlPtr += --length; /* Process the HTTP Request */ if (0 == strcmp(ecb->lpszMethod, "GET")) { /*********************/ /*** GET REQUEST ***/ /*********************/ sprintf(htmlPtr, "%s%s%s", QUERY, QUERY_STR, BODY); if ( NULL != strchr(QUERY_STR,'-')) syslog(LOG_ERR,"INCORRECT STR PASSED =%s\n",QUERY_STR); htmlLen = strlen (html); if ( strlen(QUERY_STR) > 0) { if (strncmp(QUERY_STR, "command/Reset", 13) == 0) { /* command/Reset&maxload=n&pttime=time&maxthread=th&exp=list */ if (NULL != (this = strchr(QUERY_STR, '='))) { maxldPtr = ++this; if (NULL != (this = strchr(this, '&'))) { *this = '\0'; if (NULL != (this = strchr(++this, '='))) { pttPtr = ++this; if (NULL != (this = strchr(this, '&'))) { *this = '\0'; if (NULL != (this = strchr(++this, '='))) { /* code folded from here */ thPtr = ++this; if (NULL != (this = strchr(this, '&'))) { *this = '\0'; if (NULL != (this = strchr(++this, '='))) { expPtr = ++this; if (NULL != (this = strchr(this, ','))) { *this = ' '; } } } /* unfolding */ } } } } } sprintf(cmdUPF+strlen(cmdUPF), " -C %s -n %s -t %s", TOPDIR, maxldPtr, thPtr); sprintf(cmdCAD+strlen(cmdCAD), " -C %s -e %s -t %s %s", TOPDIR, pttPtr, thPtr, expPtr); system (cmdUPF); system (cmdCAD); syslog (LOG_ERR, "cmdUPF: %s\n", cmdUPF); syslog (LOG_ERR, "cmdCAD: %s\n", cmdCAD); /* create the log file */ hseStatus = createLogSendResp(ecb, html, htmlLen, logFile); } else if (strcmp(QUERY_STR, "command/Fetch") == 0) { /* return the log file */ hseStatus = sendRespLogFile(ecb, html, htmlLen, logFile); } else { /* return the file in query string */ strcpy(urlName, QUERY_STR); tf.pHead = (PVOID)html; tf.pTail = (PVOID)SUFFIX; tf.TailLength = sizeof(SUFFIX) - 1; tf.dwFlags = HSE_IO_SEND_HEADERS|HSE_IO_DISCONNECT_AFTER_SEND| HSE_IO_HANDLE_IS_FILENAME; tf.pszStatusCode = (const char *) HTTP_STATUS; tf.hFile = (HANDLE)fullName; tf.HeadLength = htmlLen; if ( NULL != strchr(tf.hFile,'-')) syslog(LOG_ERR,"hFile INCORRECT STR PASSED =%s\n",QUERY_STR); if( ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_TRANSMIT_FILE, &tf, 0, 0 ) == TRUE ) return HSE_STATUS_SUCCESS_AND_KEEP_CONN; return HSE_STATUS_ERROR; } } else { /* respond now with the message */ hseStatus = sendRespMsg(ecb, html, htmlLen, "QUERY_STRING not set!\n"); } } else if (0 == strcmp(ecb->lpszMethod, "POST")) { /**********************/ /*** POST REQUEST ***/ /**********************/ char cookieStr[COOKIE_BUF_SIZE]; char contentBuf[POST_BUF_SIZE]; char *bufPtr; int bufLength; /* parsing the POST content */ char *urlrootptr=NULL, *dirptr=NULL, *classptr=NULL, *numptr=NULL, *clientptr=NULL; char *this; int found; /* post.log file processing */ char countBuf[2*COUNT_LEN+1]; time_t timeinsec; int postRemain, readLength; strcpy(htmlPtr, QUERYnBODY); htmlLen = strlen (html); /* Get the cookie string */ length = COOKIE_BUF_SIZE; ecb->GetServerVariable(ecb->ConnID, "ALL_HTTP", cookieStr, &length); /* HTTP_COOKIE: my_cookie=user_id=10012&last_ad=120 */ cookiePtr = NULL; if (NULL != (this = strchr(cookieStr, '='))) { if (NULL != (this = strchr(++this, '='))) { cookiePtr = ++this; this = cookiePtr + 5; *this = '\0'; strcpy (cookieIdPtr, cookiePtr); } } /**********************/ /*** POST REQUEST ***/ /**********************/ /* Get the POST content */ postRemain = ecb->cbTotalBytes; if (postRemain == ecb->cbAvailable) { strncpy(contentBuf, (char *)ecb->lpbData, postRemain); bufPtr = contentBuf + postRemain; /* for debugging purpose */ syslog (LOG_ERR, "strncpy POST CONTENT\n"); } else { bufPtr = contentBuf; while (postRemain > 0 ) { readLength = postRemain; ecb->ReadClient(ecb->ConnID, bufPtr, &readLength); postRemain -= readLength; bufPtr += readLength; } } /* contentBuf must be '\0' terminated. */ *bufPtr ='\0'; /* bufPtr always point to the end */ urlrootptr=dirptr=classptr=numptr=clientptr=NULL; this = contentBuf; /* Parse the POST content */ found = 0; while (*this != '\0') { /****** parseKeyValue() ********/ if (strncmp(this, "urlroot=", 8) == 0) { urlrootptr = this += 8; found++; if (NULL == (this = strchr(this, '&'))) this = bufPtr; /* *bufPtr == '\0' */ else { *this = '\0'; this++; } } if (strncmp(this, "dir=", 4) == 0) { dirptr = this += 4; found++; if (NULL == (this = strchr(this, '&'))) this = bufPtr; /* *bufPtr == '\0' */ else { *this = '\0'; this++; } } if (strncmp(this, "class=", 6) == 0) { classptr = this += 6; found++; if (NULL == (this = strchr(this, '&'))) this = bufPtr; /* *bufPtr == '\0' */ else { *this = '\0'; this++; } } if (strncmp(this, "num=", 4) == 0) { numptr = this += 4; found++; if (NULL == (this = strchr(this, '&'))) this = bufPtr; /* *bufPtr == '\0' */ else { *this = '\0'; this++; } } if (strncmp(this, "client=", 7) == 0) { clientptr = this += 7; found++; if (NULL == (this = strchr(this, '&'))) this = bufPtr; /* *bufPtr == '\0' */ else { *this = '\0'; this++; } } if (found == 0) this++; else found = 0; } sprintf(urlName, "%sdir%5s/class%1s_%1s", urlrootptr,dirptr,classptr,numptr); if (!urlrootptr || !dirptr || !classptr || !numptr || !clientptr) { sprintf(tmpBuf, "Incorrect POST Input: '%s'\nPOST Content-length: %d\nPOST does" "not contain complete pathname and client information.\n", fullName, bufPtr-contentBuf); /* respond now with the message */ hseStatus = sendRespMsg(ecb, html, htmlLen, tmpBuf); } else { /* Update the log file */ timeinsec = time((time_t *) NULL); if (-1 == (logfd = open(logFile, O_RDWR))) { sprintf(tmpBuf, "Cannot open %s(%s)\n",logFile,strerror(errno)); hseStatus = sendRespMsg(ecb, html, htmlLen, tmpBuf); return hseStatus; } get_sema(); /* read, increment and then write the counter from/to log file */ (void) read (logfd, countBuf, (size_t)COUNT_LEN); countBuf[COUNT_LEN] = '\0'; sprintf (countBuf, "%10d", atoi(countBuf)+1); (void) lseek (logfd, 0, SEEK_SET); write (logfd, countBuf, (size_t)COUNT_LEN); /* append to the log file information on the requested URL */ (void) lseek (logfd, 0, SEEK_END); bufLength = sprintf(tmpBuf, "%s %10d %10d %5s %2s %2s %10s %-60.60s %10d\n", countBuf, timeinsec, mypid,dirptr, classptr, numptr, clientptr, urlName, mypid); (void) write (logfd, tmpBuf, bufLength); release_sema(); close(logfd); /* return the requested URL */ tf.pHead = (PVOID)html; tf.pTail = (PVOID)SUFFIX; tf.TailLength = sizeof(SUFFIX) - 1; tf.dwFlags = HSE_IO_SEND_HEADERS|HSE_IO_DISCONNECT_AFTER_SEND| HSE_IO_HANDLE_IS_FILENAME; tf.pHead = (PVOID)html; tf.pszStatusCode = (const char *) httpCookie; tf.HeadLength = htmlLen; tf.hFile = (HANDLE)fullName; if( ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_TRANSMIT_FILE, &tf, 0, 0 ) == TRUE ) { return HSE_STATUS_SUCCESS_AND_KEEP_CONN; } return HSE_STATUS_ERROR; } } /* POST */ return hseStatus; } /* ** Send the HTTP response back to the client. ** */ int sendRespMsg (LPEXTENSION_CONTROL_BLOCK ecb, char *htmlHeader, int htmlLen, char *msg) { int status; int length; int http_hdr[256]; /* Set the response header using ISAPI HSE Support function. */ /* - The header and its lenght are defined prior to this call. */ /* Send the HTTP response back using ISAPI WriteClient funciton. */ /* - If msg is not NULL, then send this message in addition to the */ /* HTML close tag to the client. */ length = sizeof (HTTP_HEADER) -1; strcpy((char *) http_hdr,HTTP_HEADER); if (!ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, 0, &length, (int*)http_hdr)) return HSE_STATUS_ERROR; length = htmlLen; if (!ecb->WriteClient(ecb->ConnID, htmlHeader, &length, 0)) return HSE_STATUS_ERROR; if (msg) { /* send both the msg and the HTTP CLOSE to the client using */ /* WriteClient() support function. */ length = snprintf(tmpBuf, (size_t)BUF_SIZE, "%s%s\n", msg, SUFFIX); if (ecb->WriteClient(ecb->ConnID, tmpBuf, &length, 0)) return HSE_STATUS_SUCCESS_AND_KEEP_CONN; else return HSE_STATUS_ERROR; } else { /* excluding '\0' */ length = sizeof(SUFFIX) -1; if (ecb->WriteClient(ecb->ConnID, SUFFIX, &length, 0)) return HSE_STATUS_SUCCESS_AND_KEEP_CONN; else return HSE_STATUS_ERROR; } } int createLogSendResp (LPEXTENSION_CONTROL_BLOCK ecb, char *htmlHeader, int htmlLen, char *fileName) { FILE *fptr; int status; unlink (fileName); fptr = fopen(fileName, "w"); if (NULL == fptr) { sprintf(tmpBuf, "Could not create file - \"%s\" (%s)",fileName, strerror(errno)); status = sendRespMsg(ecb, htmlHeader, htmlLen, tmpBuf); } else { /* Write 0 to the first line */ if ( fprintf (fptr, "%10d\n", 0) <=0 ) { sprintf(tmpBuf, "Could not initialize Log file - \"%s\" (%s)", fileName, strerror(errno)); status = sendRespMsg(ecb, htmlHeader, htmlLen, tmpBuf); } else if (EOF == fclose(fptr)) { sprintf(tmpBuf, "Could not close file - \"%s\" (%s)", fileName, strerror(errno)); status = sendRespMsg(ecb, htmlHeader, htmlLen, tmpBuf); } else status = sendRespMsg(ecb, htmlHeader, htmlLen, 0); } return status; } int sendRespLogFile (LPEXTENSION_CONTROL_BLOCK ecb, char *htmlHeader, int htmlLen, char *fileName) { int fd; char buffer[READ_BUF_SIZE]; ssize_t byteRead; ssize_t tmp; int status; int length; if ((fd = open(fileName, O_RDONLY)) < 0) { sprintf(tmpBuf, "Could not open file for reading - \"%s\" (%s)", fileName, strerror(errno)); status = sendRespMsg(ecb, htmlHeader, htmlLen, tmpBuf); } else { length = htmlLen; if (!ecb->WriteClient(ecb->ConnID, htmlHeader, &length, 0)) return HSE_STATUS_ERROR; do { byteRead = read(fd, buffer, (size_t)READ_BUF_SIZE); if (byteRead < 0) { sprintf(tmpBuf, "Error reading file '%s': error is %s\n", fileName, strerror(errno)); status = sendRespMsg(ecb, htmlHeader, htmlLen, tmpBuf); break; } length = byteRead; if (!(ecb->WriteClient(ecb->ConnID, buffer, &length, 0))) return HSE_STATUS_ERROR; } while (READ_BUF_SIZE == byteRead); /* excluding '\0' */ length = sizeof(SUFFIX) -1; if (ecb->WriteClient(ecb->ConnID, SUFFIX, &length, 0)) return HSE_STATUS_SUCCESS_AND_KEEP_CONN; else return HSE_STATUS_ERROR; if (close(fd) < 0) { sprintf(tmpBuf, "Could not close file - \"%s\" (%s)", fileName, strerror(errno)); status = sendRespMsg(ecb, htmlHeader, htmlLen, tmpBuf); } } return status; } /* * sem_init() * * create a semaphore for file control - lock POST_LOG */ int sem_init () { if ((sem_id = semget((key_t)8989, 1, 0666 | IPC_CREAT )) == -1) { if (errno == EEXIST) { syslog (LOG_ERR, "ISAPI Error: semaphore already in use! key=8989\n"); return (-1); } else { syslog(LOG_ERR, "Error: ISAPI semaphore creation failed ! key=8989, errno=%d\n",errno); return (-1); } } else { /* initialize a semaphore to the value of 1 */ if (semctl(sem_id, 0, SETVAL, 1) == -1) { syslog(LOG_ERR,"Error: ISAPI semctl(id, 0, SETVAL, 1)failed\n"); return (-1); } else return (sem_id); } } /* * get semaphore */ int get_sema() { struct sembuf p_buf; int NOT_GET = TRUE; int retry_number = 0; int semop_ret; p_buf.sem_num = 0; p_buf.sem_op = -1; p_buf.sem_flg = SEM_UNDO ; while (NOT_GET) { errno=0; semop_ret = semop(sem_id, &p_buf, 1); if (semop_ret == -1) { if (errno == EAGAIN || errno == ENOSPC || errno == ERANGE || errno == 0 ) { syslog(LOG_ERR, "getsema(): semop(sem_id=%d) failed! errno=%d\n", sem_id, errno); } else { if (errno == EINTR) { syslog(LOG_ERR,"get_sema(): get sema gets EINTR\n"); return (-1); } else { syslog(LOG_ERR, "Error: getsema(): semop(sem_id=%d) failed! errno=%d\n", sem_id, errno); return (-1); } } } else { return (semop_ret); } } } /* * release_sema() * */ int release_sema() { struct sembuf p_buf; int NOT_RELEASE = TRUE; int retry_number = 0; int semop_ret; p_buf.sem_num = 0; p_buf.sem_op = 1; p_buf.sem_flg = SEM_UNDO; while (NOT_RELEASE) { if ((semop_ret = semop(sem_id, &p_buf, 1)) == -1) { if (errno == EAGAIN || errno == ENOSPC || errno == ERANGE) { syslog(LOG_ERR, "Warning: release_sema(%d): semop retry time out ! \n", sem_id); return (-1); } else { if (errno == EINTR) { syslog(LOG_ERR,"Release_sema(): release sema gets EINTR\n"); return (-1); } else { syslog(LOG_ERR, "Error: release_sema(): semop(sem_id=%d) failed !\n", sem_id, errno); return (-1); } } } else { return (semop_ret); } } } /* * remove_sema */ void remove_sema() { if (semctl(sem_id, 0, IPC_RMID, 0) == -1) syslog(LOG_ERR, "Error: ISAPI semctl(id, 0, IPC_RMID, 1)failed, errno=%d\n",errno); } @EOF set `sum $sumopt