Esempio n. 1
0
void ejCloseEngine(int eid)
{
	ej_t	*ep;
	int		i;

	if ((ep = ejPtr(eid)) == NULL) {
		return;
	}

#ifdef EMF
	ejEmfClose(eid);
#endif

	bfreeSafe(B_L, ep->error);
	ep->error = NULL;
	bfreeSafe(B_L, ep->result);
	ep->result = NULL;

	ejLexClose(ep);

	for (i = ep->variableMax - 1; i >= 0; i--) {
		if (ep->flags & FLAGS_VARIABLES) {
			symClose(ep->variables[i] - EJ_OFFSET);
		}
		ep->variableMax = hFree((void***) &ep->variables, i);
	}

	if (ep->flags & FLAGS_FUNCTIONS) {
		symClose(ep->functions);
	}

	ejMax = hFree((void***) &ejHandles, ep->eid);
	bfree(B_L, ep);
}
Esempio n. 2
0
char_t *websCalcDigest(webs_t wp)
{
#ifdef DIGEST_ACCESS_SUPPORT
	char_t	*digest, *a1, *a1prime, *a2, *a2prime, *preDigest, *method;

	a_assert(wp);
	digest = NULL;

/*
 *	Calculate first portion of digest H(A1)
 */
	a1 = NULL;
	fmtAlloc(&a1, 255, T("%s:%s:%s"), wp->userName, wp->realm, wp->password);
	a_assert(a1);
	a1prime = websMD5(a1);
	bfreeSafe(B_L, a1);
/*
 *	Calculate second portion of digest H(A2)
 */
	method = websGetVar(wp, T("REQUEST_METHOD"), NULL);
	a_assert(method);
	a2 = NULL;
	fmtAlloc(&a2, 255, T("%s:%s"), method, wp->uri);
	a_assert(a2);
	a2prime = websMD5(a2);
	bfreeSafe(B_L, a2);
/*
 *	Construct final digest KD(H(A1):nonce:H(A2))
 */
	a_assert(a1prime);
	a_assert(a2prime);
	a_assert(wp->nonce);

	preDigest = NULL;
	if (!wp->qop) {
		fmtAlloc(&preDigest, 255, T("%s:%s:%s"), a1prime, wp->nonce, a2prime);
	} else {
		fmtAlloc(&preDigest, 255, T("%s:%s:%s:%s:%s:%s"), 
			a1prime, 
			wp->nonce,
			wp->nc,
			wp->cnonce,
			wp->qop,
			a2prime);
	}

	a_assert(preDigest);
	digest = websMD5(preDigest);
/*
 *	Now clean up
 */
	bfreeSafe(B_L, a1prime);
	bfreeSafe(B_L, a2prime);
	bfreeSafe(B_L, preDigest);
	return digest;
#else
	return NULL;
#endif /* DIGEST_ACCESS_SUPPORT */
}
Esempio n. 3
0
char_t *websCalcUrlDigest(webs_t wp)
{
	char_t	*digest, *a1, *a1prime, *a2, *a2prime, *preDigest, *method;

	a_assert(wp);
	digest = NULL;

/*
 *	Calculate first portion of digest H(A1)
 */
	a1 = NULL;
	fmtAlloc(&a1, 255, T("%s:%s:%s"), wp->userName, wp->realm, wp->password);
	a_assert(a1);
	a1prime = websMD5(a1);
	bfreeSafe(B_L, a1);
/*
 *	Calculate second portion of digest H(A2)
 */
	method = websGetVar(wp, T("REQUEST_METHOD"), NULL);
	a_assert(method);
	/* Fixes by Richard Laing, 2003/7/15 */
	a2 = balloc(B_L, (gstrlen(method) +2 + gstrlen(wp->url) ) * sizeof(char_t));
	a_assert(a2);
	gsprintf(a2, T("%s:%s"), method, wp->url);
	a2prime = websMD5(a2);
	bfreeSafe(B_L, a2);
/*
 *	Construct final digest KD(H(A1):nonce:H(A2))
 */
	a_assert(a1prime);
	a_assert(a2prime);
	a_assert(wp->nonce);

	preDigest = NULL;
	if (!wp->qop) {
		fmtAlloc(&preDigest, 255, T("%s:%s:%s"), a1prime, wp->nonce, a2prime);
	} else {
		fmtAlloc(&preDigest, 255, T("%s:%s:%s:%s:%s:%s"), 
			a1prime, 
			wp->nonce,
			wp->nc,
			wp->cnonce,
			wp->qop,
			a2prime);
	}

	a_assert(preDigest);
	digest = websMD5(preDigest);
/*
 *	Now clean up
 */
	bfreeSafe(B_L, a1prime);
	bfreeSafe(B_L, a2prime);
	bfreeSafe(B_L, preDigest);
	return digest;
}
Esempio n. 4
0
void dbClose(int did)
{
    int			table, column;
    dbTable_t	*pTable;

    /*
     *	Before doing anything, delete all the contents of the database
     */
    dbZero(did);

    /*
     *	Now delete the tables
     */
    for (table = 0; table < dbMaxTables; table++) {
        pTable = dbListTables[table];

        if (pTable != NULL) {
            /*
             *			Delete the table schema
             */
            if (pTable->nColumns) {
                for (column = 0; column < pTable->nColumns; column++) {
                    bfreeSafe(B_L, pTable->columnNames[column]);
                }
                bfreeSafe(B_L, pTable->columnNames);
                bfreeSafe(B_L, pTable->columnTypes);
            }
            /*
             *			Delete the table name
             */
            bfreeSafe(B_L, pTable->name);
            /*
             *			Free the table
             */
            bfreeSafe(B_L, pTable);
            hFree((void ***) &dbListTables, table);
        }
    }

    if (dbListTables) {
        bfree(B_L, dbListTables);
    }

    /*
     *	Set the global table list to a safe value
     */
    dbListTables = NULL;
    dbMaxTables = 0;
}
Esempio n. 5
0
void dbZero(int did)
{
    int			table, row, column, nRows, nColumns;
    int			*pRow;
    dbTable_t	*pTable;

    /*
     *	Delete all data from all tables
     */
    for (table = 0; table < dbMaxTables; table++) {
        pTable = dbListTables[table];
        /*
         *		Delete the row data contained within the schema
         */
        if (pTable) {
            nColumns = pTable->nColumns;
            nRows = pTable->nRows;
            for (row = 0; row < nRows; row++) {
                pRow = pTable->rows[row];
                if (pRow) {
                    /*
                     *					Only delete the contents of rows not previously deleted!
                     */
                    for (column = 0; column < nColumns; column++) {
                        if (pTable->columnTypes[column] == T_STRING) {
                            bfreeSafe(B_L, (char_t *)(pRow[column]));
                            pRow[column] = (int)NULL;
                        }
                    }

                    bfreeSafe(B_L, pRow);
                    hFree((void ***) &pTable->rows, row);
                }
            }

            pTable->rows = NULL;
            pTable->nRows = 0;
        }
    }
}
Esempio n. 6
0
int dbDeleteRow(int did, char_t *tablename, int row)
{
    int			tid, nColumns, nRows;
    dbTable_t	*pTable;

    a_assert(tablename);
    tid = dbGetTableId(0, tablename);
    a_assert(tid >= 0);

    if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
        pTable = dbListTables[tid];
    } else {
        return DB_ERR_TABLE_NOT_FOUND;
    }

    nColumns = pTable->nColumns;
    nRows = pTable->nRows;

    if ((row >= 0) && (row < nRows)) {
        int *pRow = pTable->rows[row];

        if (pRow) {
            int	column = 0;
            /*
             *			Free up any allocated strings
             */
            while (column < nColumns) {
                if (pRow[column] &&
                        (pTable->columnTypes[column] == T_STRING)) {
                    bfree(B_L, (char_t *)pRow[column]);
                }

                column++;
            }
            /*
             *			Zero out the row for safety
             */
            memset(pRow, 0, nColumns * max(sizeof(int), sizeof(char_t *)));

            bfreeSafe(B_L, pRow);
            pTable->nRows = hFree((void ***)&pTable->rows, row);
            trace(5, T("DB: Deleted row <%d> from table <%s>\n"),
                  row, tablename);
        }
        return 0;
    } else {
        trace(3, T("DB: Unable to delete row <%d> from table <%s>\n"),
              row, tablename);
    }

    return -1;
}
Esempio n. 7
0
char_t *websCalcNonce(webs_t wp)
{
	char_t		*nonce, *prenonce;
	time_t		longTime;
#if defined(WIN32)
	char_t		buf[26];
	errno_t	error;
	struct tm	newtime;
#else
	struct tm	*newtime;
#endif

	a_assert(wp);
/*
 *	Get time as long integer.
 */
	time(&longTime);
/*
 *	Convert to local time.
 */
#if !defined(WIN32)
	newtime = localtime(&longTime);
#else
	
	error = localtime_s(&newtime, &longTime);
#endif
/*
 *	Create prenonce string.
 */
#if !defined(WIN32)
	prenonce = NULL;
	fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime),
		wp->realm); 
#else
	asctime_s(buf, elementsof(buf), &newtime);
	fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, buf, 
		RANDOMKEY); 
#endif

	a_assert(prenonce);
/*
 *	Create the nonce
 */
    nonce = websMD5(prenonce);
/*
 *	Cleanup
 */
	bfreeSafe(B_L, prenonce);

	return nonce;
}
Esempio n. 8
0
void trace(int level, char_t *fmt, ...)
{
	va_list 	args;
	char_t		*buf;

	va_start(args, fmt);
	fmtValloc(&buf, VALUE_MAX_STRING, fmt, args);

	if (traceHandler) {
		traceHandler(level, buf);
	}
	bfreeSafe(B_L, buf);
	va_end(args);
}
Esempio n. 9
0
int	socketWriteString(int sid, char_t *buf)
{
 #ifdef UNICODE
 	char	*byteBuf;
 	int		r, len;
 
 	len = gstrlen(buf);
 	byteBuf = ballocUniToAsc(buf, len);
 	r = socketWrite(sid, byteBuf, len);
 	bfreeSafe(B_L, byteBuf);
 	return r;
 #else
 	return socketWrite(sid, buf, strlen(buf));
 #endif /* UNICODE */
}
Esempio n. 10
0
void error( E_ARGS_DEC, int etype, char_t* fmt, ... )
{
    va_list 	args;
    char_t*		fmtBuf, *buf;
    va_start( args, fmt );
    fmtValloc( &fmtBuf, E_MAX_ERROR, fmt, args );

    if ( etype == E_LOG )
    {
        fmtAlloc( &buf, E_MAX_ERROR, T( "%s\n" ), fmtBuf );
        /*#ifdef DEV*/
    }

    else if ( etype == E_ASSERT )
    {
        fmtAlloc( &buf, E_MAX_ERROR,
                  T( "Assertion %s, failed at %s %d\n" ), fmtBuf, E_ARGS );
        /*#endif*/
    }

    else if ( etype == E_USER )
    {
        fmtAlloc( &buf, E_MAX_ERROR, T( "%s\n" ), fmtBuf );
    }

    /*
     * bugfix -- if etype is not E_LOG, E_ASSERT, or E_USER, the call to
     * bfreeSafe(B_L, buf) below will fail, because 'buf' is randomly
     * initialized. To be nice, we format a message saying that this is an
     * unknown message type, and in doing so give buf a valid value. Thanks
     * to Simon Byholm.
     */
    else
    {
        fmtAlloc( &buf, E_MAX_ERROR, T( "Unknown error" ) );
    }

    va_end( args );
    bfree( B_L, fmtBuf );

    if ( errorHandler )
    {
        errorHandler( etype, buf );
    }

    bfreeSafe( B_L, buf );
}
Esempio n. 11
0
char_t *websCalcNonce(webs_t wp)
{
	char_t		*nonce, *prenonce;
	struct tm	*newtime;
	time_t		longTime;

	a_assert(wp);
/*
 *	Get time as long integer.
 */
	time(&longTime);
/*
 *	Convert to local time.
 */
	newtime = localtime(&longTime);
/*
 *	Create prenonce string.
 */
	prenonce = NULL;
#ifdef DIGEST_ACCESS_SUPPORT
	fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime),
		wp->realm); 
#else
	fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime), 
		RANDOMKEY); 
#endif
	a_assert(prenonce);
/*
 *	Create the nonce
 */
    nonce = websMD5(prenonce);
/*
 *	Cleanup
 */
	bfreeSafe(B_L, prenonce);

	return nonce;
}
Esempio n. 12
0
void websDefaultClose()
{
#ifdef WEBS_WHITELIST_SUPPORT
#ifdef WEBS_SSL_SUPPORT
	sslList_t	*l;
	while (sslList != NULL) {
		l = sslList;
		sslList = sslList->next;
		bfreeSafe(B_L, l->url);
		bfree(B_L, l);
	}	
#endif
	websDeleteWhitelist();
#endif /* WEBS_WHITELIST_SUPPORT */
	if (websDefaultPage) {
		bfree(B_L, websDefaultPage);
		websDefaultPage = NULL;
	}
	if (websDefaultDir) {
		bfree(B_L, websDefaultDir);
		websDefaultDir = NULL;
	}
}
Esempio n. 13
0
int websDefaultHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
						char_t *url, char_t *path, char_t *query)
{
	websStatType	sbuf;
	char_t			*lpath, *tmp, *date;
	int				bytes, flags, nchars;

	a_assert(websValid(wp));
	a_assert(url && *url);
	a_assert(path);
	a_assert(query);

/*
 *	Validate the URL and ensure that ".."s don't give access to unwanted files
 */
	flags = websGetRequestFlags(wp);

	if (websValidateUrl(wp, path) < 0) {
		websError(wp, 500, T("Invalid URL %s"), url);
		return 1;
	}
	lpath = websGetRequestLpath(wp);
	nchars = gstrlen(lpath) - 1;
	if (lpath[nchars] == '/' || lpath[nchars] == '\\') {
		lpath[nchars] = '\0';
	}

/*
 *	If the file is a directory, redirect using the nominated default page
 */
	if (websPageIsDirectory(lpath)) {
		nchars = gstrlen(path);
		if (path[nchars-1] == '/' || path[nchars-1] == '\\') {
			path[--nchars] = '\0';
		}
		nchars += gstrlen(websDefaultPage) + 2;
		fmtAlloc(&tmp, nchars, T("%s/%s"), path, websDefaultPage);
		websRedirect(wp, tmp);
		bfreeSafe(B_L, tmp);
		return 1;
	}

/*
 *	Open the document. Stat for later use.
 */
	if (websPageOpen(wp, lpath, path, SOCKET_RDONLY | SOCKET_BINARY,
		0666) < 0) {
		websError(wp, 400, T("Cannot open URL <b>%s</b>"), url);
		return 1;
	}

	if (websPageStat(wp, lpath, path, &sbuf) < 0) {
		websError(wp, 400, T("Cannot stat page for URL <b>%s</b>"), url);
		return 1;
	}

/*
 *	If the page has not been modified since the user last received it and it
 *	is not dynamically generated each time (ASP), then optimize request by
 *	sending a 304 Use local copy response
 */
	websStats.localHits++;
#ifdef WEBS_IF_MODIFIED_SUPPORT
	if (flags & WEBS_IF_MODIFIED && !(flags & WEBS_ASP)) {
		if (sbuf.mtime <= wp->since) {
			websWrite(wp, T("HTTP/1.0 304 Use local copy\r\n"));

/*
 *			by license terms the following line of code must
 *			not be modified.
 */
			websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);

			if (flags & WEBS_KEEP_ALIVE) {
				websWrite(wp, T("Connection: keep-alive\r\n"));
			}
			websWrite(wp, T("\r\n"));
			websSetRequestFlags(wp, flags |= WEBS_HEADER_DONE);
			websDone(wp, 304);
			return 1;
		}
	}
#endif

/*
 *	Output the normal HTTP response header
 */
	if ((date = websGetDateString(NULL)) != NULL) {
		websWrite(wp, T("HTTP/1.0 200 OK\r\nDate: %s\r\n"), date);

/*
 *		By license terms the following line of code must not be modified.
 */
		websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
		bfree(B_L, date);
	}
	flags |= WEBS_HEADER_DONE;

/*
 *	If this is an ASP request, ensure the remote browser doesn't cache it.
 *	Send back both HTTP/1.0 and HTTP/1.1 cache control directives
 */
	if (flags & WEBS_ASP) {
		bytes = 0;
		websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n"));

	} else {
		if ((date = websGetDateString(&sbuf)) != NULL) {
			websWrite(wp, T("Last-modified: %s\r\n"), date);
			bfree(B_L, date);
		}
		bytes = sbuf.size;
	}

	if (bytes) {
		websWrite(wp, T("Content-length: %d\r\n"), bytes);
		websSetRequestBytes(wp, bytes);
	}
	websWrite(wp, T("Content-type: %s\r\n"), websGetRequestType(wp));

	if ((flags & WEBS_KEEP_ALIVE) && !(flags & WEBS_ASP)) {
		websWrite(wp, T("Connection: keep-alive\r\n"));
	}
	websWrite(wp, T("\r\n"));

/*
 *	All done if the browser did a HEAD request
 */
	if (flags & WEBS_HEAD_REQUEST) {
		websDone(wp, 200);
		return 1;
	}

/*
 *	Evaluate ASP requests
 */
	if (flags & WEBS_ASP) {
		if (websAspRequest(wp, lpath) < 0) {
			return 1;
		}
		websDone(wp, 200);
		return 1;
	}

#ifdef WEBS_SSL_SUPPORT
	if (wp->flags & WEBS_SECURE) {
		websDefaultWriteEvent(wp);
	} else {
		websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);
	}
#else
/*
 *	For normal web documents, return the data via background write
 */
	websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);
#endif
	return 1;
}
Esempio n. 14
0
int websDefaultHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
						char_t *url, char_t *path, char_t *query)
{
	websStatType	sbuf;
	char_t			*lpath, *tmp, *date;
	int				bytes, flags, nchars, rc;

	a_assert(websValid(wp));
	a_assert(url && *url);
	a_assert(path);
	a_assert(query);

	flags = websGetRequestFlags(wp);
/*
 *	We do whitelist validation in addition to standard URL validation.
 *	The whitelist should really catch anything invalid first.
 *	If the whitelist check fails, rebuild the list and try again.
 *	Also validate if we are not on a secure connection, but the whitelist
 *	entry has the SSL flag set, do not serve the page.
 */
#ifdef WEBS_WHITELIST_SUPPORT
printf ("wp->url: (%s)\n", wp->url);
	if ((rc = websWhitelistCheck(wp->url)) < 0) {
		websBuildWhitelist();
		if ((rc = websWhitelistCheck(wp->url)) < 0) {
			websError(wp, 404, T("Cannot open URL: type 1"));
			return 1;
		}
	}
	if (!(flags & WEBS_SECURE) && (rc & WHITELIST_SSL)) {
		websError(wp, 500, T("HTTPS access required"));
		return 1;
	}
#endif /* WEBS_WHITELIST_SUPPORT */
/*
 *	Validate the URL and ensure that ".."s don't give access to unwanted files
 */
	if (websValidateUrl(wp, path) < 0) {
      /* 
       * preventing a cross-site scripting exploit -- you may restore the
       * following line of code to revert to the original behavior...
		websError(wp, 500, T("Invalid URL %s"), url);
       */
		websError(wp, 500, T("Invalid URL"));
		websBuildWhitelist();
		return 1;
	}
	lpath = websGetRequestLpath(wp);
	nchars = gstrlen(lpath) - 1;
	if (lpath[nchars] == '/' || lpath[nchars] == '\\') {
		lpath[nchars] = '\0';
	}

/*
 *	If the file is a directory, redirect using the nominated default page
 */
	if (websPageIsDirectory(lpath)) {
		nchars = gstrlen(path);
		if (path[nchars-1] == '/' || path[nchars-1] == '\\') {
			path[--nchars] = '\0';
		}
		nchars += gstrlen(websDefaultPage) + 2;
		fmtAlloc(&tmp, nchars, T("%s/%s"), path, websDefaultPage);
printf ("websDefaultHandler: tmp(%s)\n", tmp);
		websRedirect(wp, tmp);
		bfreeSafe(B_L, tmp);
		return 1;
	}

printf ("we now open the web pages\n");
printf ("lpath(%s), path(%s)\n", lpath, path);

/*
 *	Open the document. Stat for later use.
 */
	if (websPageOpen(wp, lpath, path, O_RDONLY | O_BINARY, 
		0666) < 0) 
   {
      /* 10 Dec 02 BgP -- according to 
       * <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>, 
       * the proper code to return here is NOT 400 (old code), which is used
       * to indicate a malformed request. Here, the request is good, but the
       * error we need to tell the client about is 404 (Not Found).
       */
      /* 
       * 17 Mar 03 BgP -- prevent a cross-site scripting exploit
		websError(wp, 404, T("Cannot open URL %s"), url);
       */
      
		websError(wp, 404, T("Cannot open URL, type 2"));
		websBuildWhitelist();
		return 1;
	} 

printf ("lpath(%s), path(%s)\n", lpath, path);
	if (websPageStat(wp, lpath, path, &sbuf) < 0) {
      /*
       * 17 Mar 03 BgP
       * prevent a cross-site scripting exploit
		websError(wp, 400, T("Cannot stat page for URL %s"), url);
       */
		websError(wp, 400, T("Cannot stat page for URL"));
		websBuildWhitelist();
		return 1;
	}

/*
 *	If the page has not been modified since the user last received it and it
 *	is not dynamically generated each time (ASP), then optimize request by
 *	sending a 304 Use local copy response
 */
	websStats.localHits++;
#ifdef WEBS_IF_MODIFIED_SUPPORT
	if (flags & WEBS_IF_MODIFIED && !(flags & WEBS_ASP)) {
		if (sbuf.mtime <= wp->since) {
			websWrite(wp, T("HTTP/1.0 304 Use local copy\r\n"));

/*
 *			by license terms the following line of code must
 *			not be modified.
 */
			websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);

			if (flags & WEBS_KEEP_ALIVE) {
				websWrite(wp, T("Connection: keep-alive\r\n"));
			}
			websWrite(wp, T("\r\n"));
			websSetRequestFlags(wp, flags |= WEBS_HEADER_DONE);
			websDone(wp, 304);
			return 1;
		}
	}
#endif

/*
 *	Output the normal HTTP response header
 */
	if ((date = websGetDateString(NULL)) != NULL) {
		websWrite(wp, T("HTTP/1.0 200 OK\r\nDate: %s\r\n"), date);
/*
 *		The Server HTTP header below must not be modified unless
 *		explicitly allowed by licensing terms.
 */
#ifdef WEBS_SSL_SUPPORT
		websWrite(wp, T("Server: %s/%s %s/%s\r\n"), 
			WEBS_NAME, WEBS_VERSION, SSL_NAME, SSL_VERSION);
#else
		websWrite(wp, T("Server: %s/%s\r\n"), WEBS_NAME, WEBS_VERSION);
#endif
		bfree(B_L, date);
	}
	flags |= WEBS_HEADER_DONE;

/*
 *	If this is an ASP request, ensure the remote browser doesn't cache it.
 *	Send back both HTTP/1.0 and HTTP/1.1 cache control directives
 */
	if (flags & WEBS_ASP) {
		bytes = 0;
		websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n"));

	} else {
		if ((date = websGetDateString(&sbuf)) != NULL) {
			websWrite(wp, T("Last-modified: %s\r\n"), date);
			bfree(B_L, date);
		}
		bytes = sbuf.size;
	}

	if (bytes) {
		websWrite(wp, T("Content-length: %d\r\n"), bytes);
		websSetRequestBytes(wp, bytes);
	}
	websWrite(wp, T("Content-type: %s\r\n"), websGetRequestType(wp));

	if ((flags & WEBS_KEEP_ALIVE) && !(flags & WEBS_ASP)) {
		websWrite(wp, T("Connection: keep-alive\r\n"));
	}
	websWrite(wp, T("\r\n"));

/*
 *	All done if the browser did a HEAD request
 */
	if (flags & WEBS_HEAD_REQUEST) {
		websDone(wp, 200);
		return 1;
	}

/*
 *	Evaluate ASP requests
 */
	if (flags & WEBS_ASP) {
		if (websAspRequest(wp, lpath) < 0) {
			return 1;
		}
		websDone(wp, 200);
		return 1;
	}
/*
 *	Return the data via background write
 */
	websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);
	return 1;
}
Esempio n. 15
0
/*
 *	Process a form request. Returns 1 always to indicate it handled the URL
 */
int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, 
		char_t *url, char_t *path, char_t* query)
{
	cgiRec		*cgip;
	sym_t		*s;
	char_t		cgiBuf[FNAMESIZE], *stdIn, *stdOut, cwd[FNAMESIZE];
	char_t		*cp, *cgiName, *cgiPath, **argp, **envp, **ep;
	int			n, envpsize, argpsize, pHandle, cid;
	a_assert(websValid(wp));
	a_assert(url && *url);
	a_assert(path && *path == '/');
	websStats.cgiHits++;
/*
 *	Extract the form name and then build the full path name.  The form
 *	name will follow the first '/' in path.
 */
	gstrncpy(cgiBuf, path, TSZ(cgiBuf));
	if ((cgiName = gstrchr(&cgiBuf[1], '/')) == NULL) {
		websError(wp, 200, T("Missing CGI name"));
		return 1;
	}
	cgiName++;
	if ((cp = gstrchr(cgiName, '/')) != NULL) {
		*cp = '\0';
	}
	fmtAlloc(&cgiPath, FNAMESIZE, T("%s/%s/%s"), websGetDefaultDir(),
		CGI_BIN, cgiName);
#ifndef VXWORKS
/*
 *	See if the file exists and is executable.  If not error out.
 *	Don't do this step for VxWorks, since the module may already
 *	be part of the OS image, rather than in the file system.
 */
	{
		gstat_t		sbuf;
		if (gstat(cgiPath, &sbuf) != 0 || (sbuf.st_mode & S_IFREG) == 0) {
			websError(wp, 200, T("CGI process file does not exist"));
			bfree(B_L, cgiPath);
			return 1;
		}
#if (defined (WIN) || defined (CE))
		if (gstrstr(cgiPath, T(".exe")) == NULL &&
			gstrstr(cgiPath, T(".bat")) == NULL) {
#elif (defined (NW))
			if (gstrstr(cgiPath, T(".nlm")) == NULL) {
#else
		if (gaccess(cgiPath, X_OK) != 0) {
#endif /* WIN || CE */
			websError(wp, 200, T("CGI process file is not executable"));
			bfree(B_L, cgiPath);
			return 1;
		}
	}
#endif /* ! VXWORKS */

         
/*
 *	Get the CWD for resetting after launching the child process CGI
 */
	ggetcwd(cwd, FNAMESIZE);
/*
 *	Retrieve the directory of the child process CGI
 */
	if ((cp = gstrrchr(cgiPath, '/')) != NULL) {
		*cp = '\0';
		gchdir(cgiPath);
		*cp = '/';
	}

/*
 *	Build command line arguments.  Only used if there is no non-encoded
 *	= character.  This is indicative of a ISINDEX query.  POST separators
 *	are & and others are +.  argp will point to a balloc'd array of 
 *	pointers.  Each pointer will point to substring within the
 *	query string.  This array of string pointers is how the spawn or 
 *	exec routines expect command line arguments to be passed.  Since 
 *	we don't know ahead of time how many individual items there are in
 *	the query string, the for loop includes logic to grow the array 
 *	size via brealloc.
 */

	argpsize = 10;
	argp = balloc(B_L, argpsize * sizeof(char_t *));
	*argp = cgiPath;

	n = 1;
	if (gstrchr(query, '=') == NULL) {

		websDecodeUrl(query, query, gstrlen(query));
		for (cp = gstrtok(query, T(" ")); cp != NULL; ) {
			*(argp+n) = cp;
			n++;

			if (n >= argpsize) {
				argpsize *= 2;
				argp = brealloc(B_L, argp, argpsize * sizeof(char_t *));

			}
			cp = gstrtok(NULL, T(" "));

		}
	}
	*(argp+n) = NULL;

/*
 *	Add all CGI variables to the environment strings to be passed
 *	to the spawned CGI process.  This includes a few we don't 
 *	already have in the symbol table, plus all those that are in
 *	the cgiVars symbol table.  envp will point to a balloc'd array of 
 *	pointers.  Each pointer will point to a balloc'd string containing
 *	the keyword value pair in the form keyword=value.  Since we don't
 *	know ahead of time how many environment strings there will be the
 *	for loop includes logic to grow the array size via brealloc.
 */

	envpsize = WEBS_SYM_INIT;
	envp = balloc(B_L, envpsize * sizeof(char_t *));
	n = 0;
	fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("PATH_TRANSLATED"), cgiPath);
	n++;
	fmtAlloc(envp+n, FNAMESIZE, T("%s=%s/%s"),T("SCRIPT_NAME"),
		CGI_BIN, cgiName);
	n++;
	fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("REMOTE_USER"), wp->userName);
	n++;
	fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("AUTH_TYPE"), wp->authType);

	n++;
	for (s = symFirst(wp->cgiVars); s != NULL; s = symNext(wp->cgiVars)) {

		if (s->content.valid && s->content.type == string &&
			gstrcmp(s->name.value.string, T("REMOTE_HOST")) != 0 &&
			gstrcmp(s->name.value.string, T("HTTP_AUTHORIZATION")) != 0) {
			fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), s->name.value.string,
				s->content.value.string);

			n++;
			if (n >= envpsize) {

				envpsize *= 2;
				envp = brealloc(B_L, envp, envpsize * sizeof(char_t *));
			}
		}
	}


	if (wp->flags & WEBS_CGI_UPLOAD){
		// set filename into enviornment variables 
		fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), T("UPLOAD_FILENAME"), wp->cgiStdin);
		n++;
	}


	*(envp+n) = NULL;
/*
 *	Create temporary file name(s) for the child's stdin and stdout.
 *	For POST data the stdin temp file (and name) should already exist.
 */

	if (wp->cgiStdin == NULL) {
		wp->cgiStdin = websGetCgiCommName(wp);
	} 
	stdIn = wp->cgiStdin;
	stdOut = websGetCgiCommName(wp);

/*
 *	Now launch the process.  If not successful, do the cleanup of resources.
 *	If successful, the cleanup will be done after the process completes.
 */
	if ((pHandle = websLaunchCgiProc(cgiPath, argp, envp, stdIn, stdOut)) 
		== -1) {
		websError(wp, 200, T("failed to spawn CGI task"));
		for (ep = envp; *ep != NULL; ep++) {
			bfreeSafe(B_L, *ep);
		}
		bfreeSafe(B_L, cgiPath);
		bfreeSafe(B_L, argp);
		bfreeSafe(B_L, envp);
		bfreeSafe(B_L, stdOut);
	} else {
/*
 *		If the spawn was successful, put this wp on a queue to be
 *		checked for completion.
 */
		cid = hAllocEntry((void***) &cgiList, &cgiMax, sizeof(cgiRec));
		cgip = cgiList[cid];
		cgip->handle = pHandle;
		cgip->stdIn = stdIn;
		cgip->stdOut = stdOut;
		cgip->cgiPath = cgiPath;
		cgip->argp = argp;
		cgip->envp = envp;
		cgip->wp = wp;
		cgip->fplacemark = 0;
		websTimeoutCancel(wp);
	}
/*
 *	Restore the current working directory after spawning child CGI
 */
 	gchdir(cwd);
	return 1;
}



/******************************************************************************/
/*
 *	Any entry in the cgiList need to be checked to see if it has
 */
void websCgiGatherOutput (cgiRec *cgip)
{
	gstat_t	sbuf;
	char_t	cgiBuf[FNAMESIZE];
	if ((gstat(cgip->stdOut, &sbuf) == 0) && 
		(sbuf.st_size > cgip->fplacemark)) {
		int fdout;
		fdout = gopen(cgip->stdOut, O_RDONLY | O_BINARY, 0444 );
/*
 *		Check to see if any data is available in the
 *		output file and send its contents to the socket.
 */
		if (fdout >= 0) {
			webs_t	wp = cgip->wp;
			int		nRead;
/*
 *			Write the HTTP header on our first pass
 */
			if (cgip->fplacemark == 0) {
				websWrite(wp, T("HTTP/1.0 200 OK\r\n"));
			}
			glseek(fdout, cgip->fplacemark, SEEK_SET);
			while ((nRead = gread(fdout, cgiBuf, FNAMESIZE)) > 0) {
				websWriteBlock(wp, cgiBuf, nRead);
				cgip->fplacemark += nRead;
			}
			gclose(fdout);
		}
	}
}


/******************************************************************************/
/*
 *	Any entry in the cgiList need to be checked to see if it has
 *	completed, and if so, process its output and clean up.
 */
void websCgiCleanup()
{
	cgiRec	*cgip;
	webs_t	wp;
	char_t	**ep;
	int		cid, nTries;
	for (cid = 0; cid < cgiMax; cid++) {
		if ((cgip = cgiList[cid]) != NULL) {
			int exit_status;
			wp = cgip->wp;
			websCgiGatherOutput (cgip);
			if ( websCheckCgiProc(cgip->handle, &exit_status) == 0) {
/*
 *				We get here if the CGI process has terminated.  Clean up.
 */
				nTries = 0;
/*				
 *				Make sure we didn't miss something during a task switch.
 *				Maximum wait is 100 times 10 msecs (1 second).
 */
				while ((cgip->fplacemark == 0) && (nTries < 100)) {
					websCgiGatherOutput(cgip);
/*					
 *					There are some cases when we detect app exit 
 *					before the file is ready. 
 */
					if (cgip->fplacemark == 0) {
#ifdef WIN
						Sleep(10);
#endif /* WIN*/
					}
					nTries++;
				}
				if (cgip->fplacemark == 0) {
					websError(wp, 200, T("CGI generated no output"));
				} else {
					websDone(wp, 200);
				}
/*
 *				Remove the temporary re-direction files
 */
				gunlink(cgip->stdIn);
				gunlink(cgip->stdOut);
/*
 *				Free all the memory buffers pointed to by cgip.
 *				The stdin file name (wp->cgiStdin) gets freed as
 *				part of websFree().
 */
				cgiMax = hFree((void***) &cgiList, cid);
				for (ep = cgip->envp; ep != NULL && *ep != NULL; ep++) {
					bfreeSafe(B_L, *ep);
				}
				bfreeSafe(B_L, cgip->cgiPath);
				bfreeSafe(B_L, cgip->argp);
				bfreeSafe(B_L, cgip->envp);
				bfreeSafe(B_L, cgip->stdOut);
				bfreeSafe(B_L, cgip);
#if 0 //DAVIDM - we do not want this, netflash does it for us
				if(wp->has_firmware_upload_clean){
					if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) != 0)
						return;
					sync();
					doSystem("sleep 3 && reboot &");
				}
#endif
			}
		}
	}
}
Esempio n. 16
0
int websAspRequest(webs_t wp, char_t *lpath)
{
	websStatType	sbuf;
	char			*rbuf;
	char_t			*token, *lang, *result, *path, *ep, *cp, *buf, *nextp;
	char_t			*last;
	int				rc, engine, len, ejid;

	a_assert(websValid(wp));
	a_assert(lpath && *lpath);

	rc = -1;
	buf = NULL;
	rbuf = NULL;
	engine = EMF_SCRIPT_EJSCRIPT;
	wp->flags |= WEBS_HEADER_DONE;
	path = websGetRequestPath(wp);

/*
 *	Create Ejscript instance in case it is needed
 */
	ejid = ejOpenEngine(wp->cgiVars, websAspFunctions);
	if (ejid < 0) {
		websError(wp, 200, T("Can't create Ejscript engine"));
		goto done;
	}
	ejSetUserHandle(ejid, (int) wp);

	if (websPageStat(wp, lpath, path, &sbuf) < 0) {
		websError(wp, 200, T("Can't stat %s"), lpath);
		goto done;
	}

/*
 *	Create a buffer to hold the ASP file in-memory
 */
	len = sbuf.size * sizeof(char);
	if ((rbuf = balloc(B_L, len + 1)) == NULL) {
		websError(wp, 200, T("Can't get memory"));
		goto done;
	}
	rbuf[len] = '\0';

	if (websPageReadData(wp, rbuf, len) != len) {
		websError(wp, 200, T("Cant read %s"), lpath);
		goto done;
	}
	websPageClose(wp);

/*
 *	Convert to UNICODE if necessary.
 */
	if ((buf = ballocAscToUni(rbuf, len)) == NULL) {
		websError(wp, 200, T("Can't get memory"));
		goto done;
	}

/*
 *	Scan for the next "<%"
 */
	last = buf;
	rc = 0;
	while (rc == 0 && *last && ((nextp = gstrstr(last, T("<%"))) != NULL)) {
		websWriteBlock(wp, last, (nextp - last));
		nextp = skipWhite(nextp + 2);

/*
 *		Decode the language
 */
		token = T("language");

		if ((lang = strtokcmp(nextp, token)) != NULL) {
			if ((cp = strtokcmp(lang, T("=javascript"))) != NULL) {
				engine = EMF_SCRIPT_EJSCRIPT;
			} else {
				cp = nextp;
			}
			nextp = cp;
		}

/*
 *		Find tailing bracket and then evaluate the script
 */
		if ((ep = gstrstr(nextp, T("%>"))) != NULL) {

			*ep = '\0';
			last = ep + 2;
			nextp = skipWhite(nextp);
/*
 *			Handle backquoted newlines
 */
			for (cp = nextp; *cp; ) {
				if (*cp == '\\' && (cp[1] == '\r' || cp[1] == '\n')) {
					*cp++ = ' ';
					while (*cp == '\r' || *cp == '\n') {
						*cp++ = ' ';
					}
				} else {
					cp++;
				}
			}

/*
 *			Now call the relevant script engine. Output is done directly
 *			by the ASP script procedure by calling websWrite()
 */
			if (*nextp) {
				result = NULL;
				if (engine == EMF_SCRIPT_EJSCRIPT) {
					rc = scriptEval(engine, nextp, &result, ejid);
				} else {
					rc = scriptEval(engine, nextp, &result, (int) wp);
				}
				if (rc < 0) {
/*
 *					On an error, discard all output accumulated so far
 *					and store the error in the result buffer. Be careful if the
 *					user has called websError() already.
 */
					if (websValid(wp)) {
						if (result) {
							websWrite(wp, T("<h2><b>ASP Error: %s</b></h2>\n"), 
								result);
							websWrite(wp, T("<pre>%s</pre>"), nextp);
							bfree(B_L, result);
						} else {
							websWrite(wp, T("<h2><b>ASP Error</b></h2>\n%s\n"),
								nextp);
						}
						websWrite(wp, T("</body></html>\n"));
						rc = 0;
					}
					goto done;
				}
			}

		} else {
			websError(wp, 200, T("Unterminated script in %s: \n"), lpath);
			rc = -1;
			goto done;
		}
	}
/*
 *	Output any trailing HTML page text
 */
	if (last && *last && rc == 0) {
		websWriteBlock(wp, last, gstrlen(last));
	}
	rc = 0;

/*
 *	Common exit and cleanup
 */
done:
	if (websValid(wp)) {
		websPageClose(wp);
		if (ejid >= 0) {
			ejCloseEngine(ejid);
		}
	}
	bfreeSafe(B_L, buf);
	bfreeSafe(B_L, rbuf);
	return rc;
}
Esempio n. 17
0
int dbSave(int did, char_t *filename, int flags)
{
    int			row, column, nColumns, nRows, fd, rc;
    int			*colTypes, *pRow, nRet, tid;
    char_t		*path, *tmpFile, *tmpNum;
    char_t		**colNames;
    dbTable_t	*pTable;

    trace(5, T("DB: About to save database to file\n"));

    a_assert(dbMaxTables > 0);

    /*
     *	First write to a temporary file, then switch around later.
     */
    fmtAlloc(&tmpFile, FNAMESIZE, T("%s/data.tmp"), basicGetProductDir());
    if ((fd = gopen(tmpFile,
                    O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) < 0) {
        trace(1, T("WARNING: Failed to open file %s\n"), tmpFile);
        bfree(B_L, tmpFile);
        return -1;
    }

    nRet = 0;

    for (tid = 0; (tid < dbMaxTables) && (nRet != -1); tid++) {
        pTable = dbListTables[tid];

        if (pTable) {
            /*
             *			Print the TABLE=tableName directive to the file
             */
            rc = dbWriteKeyValue(fd, KEYWORD_TABLE, pTable->name);

            nColumns = pTable->nColumns;
            nRows = pTable->nRows;

            for (row = 0; (row < nRows) && (nRet == 0); row++) {
                pRow = pTable->rows[row];
                /*
                 *				if row is NULL, the row has been deleted, so don't
                 *				write it out.
                 */
                if ((pRow == NULL) || (pRow[0] == '\0') ||
                        (*(char_t *)(pRow[0]) == '\0')) {
                    continue;
                }
                /*
                 *				Print the ROW=rowNumber directive to the file
                 */
                fmtAlloc(&tmpNum, 20, T("%d"), row);
                rc = dbWriteKeyValue(fd, KEYWORD_ROW, tmpNum);
                bfreeSafe(B_L, tmpNum);

                colNames = pTable->columnNames;
                colTypes = pTable->columnTypes;
                /*
                 *				Print the key-value pairs (COLUMN=value) for data cells
                 */
                for (column = 0; (column < nColumns) && (rc >= 0);
                        column++, colNames++, colTypes++) {
                    if (*colTypes == T_STRING) {
                        rc = dbWriteKeyValue(fd, *colNames,
                                             (char_t *)(pRow[column]));
                    } else {
                        fmtAlloc(&tmpNum, 20, T("%d"), pRow[column]);
                        rc = dbWriteKeyValue(fd, *colNames, tmpNum);
                        bfreeSafe(B_L, tmpNum);
                    }
                }

                if (rc < 0) {
                    trace(1, T("WARNING: Failed to write to file %s\n"),
                          tmpFile);
                    nRet = -1;
                }
            }
        }
    }

    gclose(fd);

    /*
     *	Replace the existing file with the temporary file, if no errors
     */
    if (nRet == 0) {
        fmtAlloc(&path, FNAMESIZE, T("%s/%s"), basicGetProductDir(), filename);

        gunlink(path);
        if (grename(tmpFile, path) != 0) {
            trace(1, T("WARNING: Failed to rename %s to %s\n"), tmpFile, path);
            nRet = -1;
        }

        bfree(B_L, path);
    }

    bfree(B_L, tmpFile);

    return nRet;
}
Esempio n. 18
0
int websLaunchCgiProc(char_t *cgiPath, char_t **argp, char_t **envp,
					  char_t *stdIn, char_t *stdOut)
{
	SYM_TYPE	ptype;
	char_t		*p, *basename, *pEntry, *pname, *entryAddr, **pp;
	int			priority, rc, fd;

/*
 *	Determine the basename, which is without path or the extension.
 */
	if ((int)(p = gstrrchr(cgiPath, '/') + 1) == 1) {
		p = cgiPath;
	}
	basename = bstrdup(B_L, p);
	if ((p = gstrrchr(basename, '.')) != NULL) {
		*p = '\0';
	}

/*
 *	Unload the module, if it is already loaded.  Get the current task
 *	priority.
 */
	unld(cgiPath, 0);
	taskPriorityGet(taskIdSelf(), &priority);
	rc = fd = -1;

/*
 *	Set the entry point symbol name as described above.  Look for an already
 *	loaded entry point; if it exists, spawn the task accordingly.
 */
	for (pp = envp, pEntry = NULL; pp != NULL && *pp != NULL; pp++) {
		if (gstrncmp(*pp, T("cgientry="), 9) == 0) {
			pEntry = bstrdup(B_L, *pp + 9);
			break;
		}
	}
	if (pEntry == NULL) {
		fmtAlloc(&pEntry, LF_PATHSIZE, T("%s_%s"), basename, T("cgientry"));
	}

	entryAddr = 0;
	if (symFindByName(sysSymTbl, pEntry, &entryAddr, &ptype) == -1) {
		fmtAlloc(&pname, VALUE_MAX_STRING, T("_%s"), pEntry);
		symFindByName(sysSymTbl, pname, &entryAddr, &ptype);
		bfreeSafe(B_L, pname);
	}
	if (entryAddr != 0) {
		rc = taskSpawn(pEntry, priority, 0, 20000, (void *)vxWebsCgiEntry,
			(int)entryAddr, (int)argp, (int)envp, (int)stdIn, (int)stdOut,
			0, 0, 0, 0, 0);
		goto DONE;
	}

/*
 *	Try to load the module.
 */
	if ((fd = gopen(cgiPath, O_RDONLY | O_BINARY, 0666)) < 0 ||
		loadModule(fd, LOAD_GLOBAL_SYMBOLS) == NULL) {
		goto DONE;
	}
	if ((symFindByName(sysSymTbl, pEntry, &entryAddr, &ptype)) == -1) {
		fmtAlloc(&pname, VALUE_MAX_STRING, T("_%s"), pEntry);
		symFindByName(sysSymTbl, pname, &entryAddr, &ptype);
		bfreeSafe(B_L, pname);
	}
	if (entryAddr != 0) {
		rc = taskSpawn(pEntry, priority, 0, 20000, (void *)vxWebsCgiEntry,
			(int)entryAddr, (int)argp, (int)envp, (int)stdIn, (int)stdOut,
			0, 0, 0, 0, 0);
	}

DONE:
	if (fd != -1) {
		gclose(fd);
	}
	bfree(B_L, basename);
	bfree(B_L, pEntry);
	return rc;
}