char_t *ejEvalFile(int eid, char_t *path, char_t **emsg) { gstat_t sbuf; ej_t *ep; char_t *script, *rs; char *fileBuf; int fd; a_assert(path && *path); if (emsg) { *emsg = NULL; } if ((ep = ejPtr(eid)) == NULL) { return NULL; } if ((fd = gopen(path, O_RDONLY | O_BINARY, 0666)) < 0) { ejError(ep, T("Bad handle %d"), eid); return NULL; } if (gstat(path, &sbuf) < 0) { gclose(fd); ejError(ep, T("Cant stat %s"), path); return NULL; } if ((fileBuf = balloc(B_L, sbuf.st_size + 1)) == NULL) { gclose(fd); ejError(ep, T("Cant malloc %d"), sbuf.st_size); return NULL; } if (gread(fd, fileBuf, sbuf.st_size) != (int)sbuf.st_size) { gclose(fd); bfree(B_L, fileBuf); ejError(ep, T("Error reading %s"), path); return NULL; } fileBuf[sbuf.st_size] = '\0'; gclose(fd); if ((script = ballocAscToUni(fileBuf, sbuf.st_size)) == NULL) { bfree(B_L, fileBuf); ejError(ep, T("Cant malloc %d"), sbuf.st_size + 1); return NULL; } bfree(B_L, fileBuf); rs = ejEvalBlock(eid, script, emsg); bfree(B_L, script); return rs; }
int websPageStat(webs_t wp, char_t *lpath, char_t *path, websStatType* sbuf) { #ifdef WEBS_PAGE_ROM return websRomPageStat(path, sbuf); #else gstat_t s; if (gstat(lpath, &s) < 0) { return -1; } sbuf->size = s.st_size; sbuf->mtime = s.st_mtime; sbuf->isDir = s.st_mode & S_IFDIR; return 0; #endif }
int websPageIsDirectory(char_t *lpath) { #ifdef WEBS_PAGE_ROM websStatType sbuf; if (websRomPageStat(lpath, &sbuf) >= 0) { return(sbuf.isDir); } else { return 0; } #else gstat_t sbuf; if (gstat(lpath, &sbuf) >= 0) { return(sbuf.st_mode & S_IFDIR); } else { return 0; } #endif }
/* * 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 } } } }
int dbLoad(int did, char_t *filename, int flags) { gstat_t sbuf; char_t *buf, *keyword, *value, *path, *ptr; char_t *tablename; int fd, tid, row; dbTable_t *pTable; a_assert(did >= 0); fmtAlloc(&path, FNAMESIZE, T("%s/%s"), basicGetProductDir(), filename); trace(4, T("DB: About to read data file <%s>\n"), path); if (gstat(path, &sbuf) < 0) { trace(3, T("DB: Failed to stat persistent data file.\n")); bfree(B_L, path); return -1; } fd = gopen(path, O_RDONLY | O_BINARY, 0666); bfree(B_L, path); if (fd < 0) { trace(3, T("DB: No persistent data file present.\n")); return -1; } if (sbuf.st_size <= 0) { trace(3, T("DB: Persistent data file is empty.\n")); gclose(fd); return -1; } /* * Read entire file into temporary buffer */ buf = balloc(B_L, sbuf.st_size + 1); #ifdef CE if (readAscToUni(fd, &buf, sbuf.st_size) != (int)sbuf.st_size) { #else if (gread(fd, buf, sbuf.st_size) != (int)sbuf.st_size) { #endif trace(3, T("DB: Persistent data read failed.\n")); bfree(B_L, buf); gclose(fd); return -1; } gclose(fd); *(buf + sbuf.st_size) = '\0'; row = -1; tid = -1; pTable = NULL; ptr = gstrtok(buf, T("\n")); tablename = NULL; do { if (crack(ptr, &keyword, &value) < 0) { trace(5, T("DB: Failed to crack line %s\n"), ptr); continue; } a_assert(keyword && *keyword); if (gstrcmp(keyword, KEYWORD_TABLE) == 0) { /* * Table name found, check to see if it's registered */ if (tablename) { bfree(B_L, tablename); } tablename = bstrdup(B_L, value); tid = dbGetTableId(did, tablename); if (tid >= 0) { pTable = dbListTables[tid]; } else { pTable = NULL; } } else if (gstrcmp(keyword, KEYWORD_ROW) == 0) { /* * Row/Record indicator found, add a new row to table */ if (tid >= 0) { int nRows = dbGetTableNrow(did, tablename); if (dbSetTableNrow(did, tablename, nRows + 1) == 0) { row = nRows; } } } else if (row != -1) { /* * some other data found, assume it's a COLUMN=value */ int nColumn = GetColumnIndex(tid, keyword); if ((nColumn >= 0) && (pTable != NULL)) { int nColumnType = pTable->columnTypes[nColumn]; if (nColumnType == T_STRING) { dbWriteStr(did, tablename, keyword, row, value); } else { dbWriteInt(did, tablename, keyword, row, gstrtoi(value)); } } } } while ((ptr = gstrtok(NULL, T("\n"))) != NULL); if (tablename) { bfree(B_L, tablename); } bfree(B_L, buf); return 0; } /******************************************************************************/ /* * Return a table id given the table name */ int dbGetTableId(int did, char_t *tablename) { int tid; dbTable_t *pTable; a_assert(tablename); for (tid = 0; (tid < dbMaxTables); tid++) { if ((pTable = dbListTables[tid]) != NULL) { if (gstrcmp(tablename, pTable->name) == 0) { return tid; } } } return -1; }
static int compile( char_t* fileList, char_t* prefix ) { gstat_t sbuf; FILE* lp; time_t now; char_t file[FNAMESIZE]; char_t* cp, *sl; char buf[512]; unsigned char* p; int j, i, len, fd, nFile; /* * Open list of files */ if ( ( lp = fopen( fileList, "r" ) ) == NULL ) { fprintf( stderr, "Can't open file list %s\n", fileList ); return -1; } time( &now ); fprintf( stdout, "/*\n * webrom.c -- Compiled Web Pages\n *\n" ); fprintf( stdout, " * Compiled by GoAhead WebCompile: %s */\n\n", gctime( &now ) ); fprintf( stdout, "#include \"wsIntrn.h\"\n\n" ); fprintf( stdout, "#ifndef WEBS_PAGE_ROM\n" ); fprintf( stdout, "websRomPageIndexType websRomPageIndex[] = {\n" ); fprintf( stdout, " { 0, 0, 0 },\n};\n" ); fprintf( stdout, "#else\n" ); /* * Open each input file and compile each web page */ nFile = 0; while ( fgets( file, sizeof( file ), lp ) != NULL ) { if ( ( p = strchr( file, '\n' ) ) || ( p = strchr( file, '\r' ) ) ) { *p = '\0'; } if ( *file == '\0' ) { continue; } if ( gstat( file, &sbuf ) == 0 && sbuf.st_mode & S_IFDIR ) { continue; } if ( ( fd = gopen( file, O_RDONLY | O_BINARY ) ) < 0 ) { fprintf( stderr, "Can't open file %s\n", file ); return -1; } fprintf( stdout, "static unsigned char page_%d[] = {\n", nFile ); while ( ( len = read( fd, buf, sizeof( buf ) ) ) > 0 ) { p = buf; for ( i = 0; i < len; ) { fprintf( stdout, " " ); for ( j = 0; p < &buf[len] && j < 16; j++, p++ ) { fprintf( stdout, "%3d,", *p ); } i += j; fprintf( stdout, "\n" ); } } fprintf( stdout, " 0 };\n\n" ); close( fd ); nFile++; } fclose( lp ); /* * Now output the page index */ fprintf( stdout, "websRomPageIndexType websRomPageIndex[] = {\n" ); if ( ( lp = fopen( fileList, "r" ) ) == NULL ) { fprintf( stderr, "Can't open file list %s\n", fileList ); return -1; } nFile = 0; while ( fgets( file, sizeof( file ), lp ) != NULL ) { if ( ( p = strchr( file, '\n' ) ) || ( p = strchr( file, '\r' ) ) ) { *p = '\0'; } if ( *file == '\0' ) { continue; } /* * Remove the prefix and add a leading "/" when we print the path */ if ( strncmp( file, prefix, gstrlen( prefix ) ) == 0 ) { cp = &file[gstrlen( prefix )]; } else { cp = file; } while ( ( sl = strchr( file, '\\' ) ) != NULL ) { *sl = '/'; } if ( *cp == '/' ) { cp++; } if ( gstat( file, &sbuf ) == 0 && sbuf.st_mode & S_IFDIR ) { fprintf( stdout, " { T(\"/%s\"), 0, 0 },\n", cp ); continue; } fprintf( stdout, " { T(\"/%s\"), page_%d, %d },\n", cp, nFile, sbuf.st_size ); nFile++; } fclose( lp ); fprintf( stdout, " { 0, 0, 0 },\n" ); fprintf( stdout, "};\n" ); fprintf( stdout, "#endif /* WEBS_PAGE_ROM */\n" ); fclose( lp ); fflush( stdout ); return 0; }