static ssize writeBody(HttpConn *conn, MprList *files) { MprFile *file; char buf[BIT_MAX_BUFFER], *path, *pair; ssize bytes, len, count, nbytes, sofar; int next; if (app->upload) { if (httpWriteUploadData(conn, app->files, app->formData) < 0) { return MPR_ERR_CANT_WRITE; } } else { if (app->formData) { count = mprGetListLength(app->formData); for (next = 0; (pair = mprGetNextItem(app->formData, &next)) != 0; ) { len = strlen(pair); if (next < count) { len = slen(pair); if (httpWrite(conn->writeq, pair, len) != len || httpWrite(conn->writeq, "&", 1) != 1) { return MPR_ERR_CANT_WRITE; } } else { if (httpWrite(conn->writeq, pair, len) != len) { return MPR_ERR_CANT_WRITE; } } } } if (files) { assert(mprGetListLength(files) == 1); for (next = 0; (path = mprGetNextItem(files, &next)) != 0; ) { if (strcmp(path, "-") == 0) { file = mprAttachFileFd(0, "stdin", O_RDONLY | O_BINARY); } else { file = mprOpenFile(path, O_RDONLY | O_BINARY, 0); } if (file == 0) { mprError("Cannot open \"%s\"", path); return MPR_ERR_CANT_OPEN; } app->inFile = file; if (app->verbose) { mprPrintf("uploading: %s\n", path); } while ((bytes = mprReadFile(file, buf, sizeof(buf))) > 0) { sofar = 0; while (bytes > 0) { if ((nbytes = httpWriteBlock(conn->writeq, &buf[sofar], bytes, HTTP_BLOCK)) < 0) { mprCloseFile(file); return MPR_ERR_CANT_WRITE; } bytes -= nbytes; sofar += nbytes; assert(bytes >= 0); } mprYield(0); } /* This is a blocking write */ httpFlushQueue(conn->writeq, 1); mprCloseFile(file); app->inFile = 0; } } if (app->bodyData) { len = mprGetBufLength(app->bodyData); if (httpWriteBlock(conn->writeq, mprGetBufStart(app->bodyData), len, HTTP_BLOCK) != len) { return MPR_ERR_CANT_WRITE; } } } return 0; }
/* Compile a view or controller cacheName MD5 cache name (not a full path) source ESP source file name module Module file name */ bool espCompile(HttpConn *conn, cchar *source, cchar *module, cchar *cacheName, int isView) { MprFile *fp; HttpRx *rx; HttpRoute *route; EspRoute *eroute; cchar *csource; char *layout, *script, *page, *err; ssize len; rx = conn->rx; route = rx->route; eroute = route->eroute; layout = 0; if (isView) { if ((page = mprReadPathContents(source, &len)) == 0) { httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't read %s", source); return 0; } /* Use layouts iff there is a source defined on the route. Only MVC/controllers based apps do this. */ if (eroute->layoutsDir) { #if UNUSED layout = mprSamePath(eroute->layoutsDir, route->dir) ? 0 : mprJoinPath(eroute->layoutsDir, "default.esp"); #else layout = mprJoinPath(eroute->layoutsDir, "default.esp"); #endif } if ((script = espBuildScript(route, page, source, cacheName, layout, &err)) == 0) { httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't build %s, error %s", source, err); return 0; } csource = mprJoinPathExt(mprTrimPathExt(module), ".c"); if ((fp = mprOpenFile(csource, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0664)) == 0) { httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't open compiled script file %s", csource); return 0; } len = slen(script); if (mprWriteFile(fp, script, len) != len) { httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't write compiled script file %s", csource); mprCloseFile(fp); return 0; } mprCloseFile(fp); } else { csource = source; } mprMakeDir(eroute->cacheDir, 0775, -1, -1, 1); /* WARNING: GC yield here */ if (runCommand(conn, eroute->compile, csource, module) < 0) { return 0; } if (eroute->link) { /* WARNING: GC yield here */ if (runCommand(conn, eroute->link, csource, module) < 0) { return 0; } #if !(BLD_DEBUG && MACOSX) /* MAC needs the object for debug information */ mprDeletePath(mprJoinPathExt(mprTrimPathExt(module), BLD_OBJ)); #endif } #if BLD_WIN_LIKE { /* Windows leaves intermediate object in the current directory */ cchar *obj; obj = mprReplacePathExt(mprGetPathBase(csource), BLD_OBJ); if (mprPathExists(obj, F_OK)) { mprDeletePath(obj); } } #endif if (!eroute->keepSource && isView) { mprDeletePath(csource); } return 1; }
/* Loader completion routine. Process listing records and emit the listing file. */ static void lstClose(EjsMod *mp, MprList *modules, int firstModule) { EjsModule *module; Lst *lst; bool headerOutput; int next, nextModule, count; for (nextModule = firstModule; (module = (EjsModule*) mprGetNextItem(modules, &nextModule)) != 0; ) { headerOutput = 0; count = 0; for (next = 0; (lst = (Lst*) mprGetNextItem(mp->lstRecords, &next)) != 0; ) { if (lst->module != module) { continue; } if (!headerOutput) { lstModule(mp, lst->module); headerOutput = 1; } switch (lst->kind) { case EJS_SECT_BLOCK: lstBlock(mp, lst->module, lst->owner, lst->slotNum, lst->name, lst->numProp); count++; break; case EJS_SECT_CLASS: lstClass(mp, lst->module, lst->slotNum, lst->type, lst->attributes); count++; break; case EJS_SECT_DEPENDENCY: lstDependency(mp, lst->module, lst->dependency); break; case EJS_SECT_EXCEPTION: lstException(mp, lst->module, lst->fun); break; case EJS_SECT_FUNCTION: lstFunction(mp, lst->module, lst->owner, lst->slotNum, lst->qname, lst->fun, lst->attributes); count++; break; case EJS_SECT_PROPERTY: lstProperty(mp, lst->module, lst->owner, lst->slotNum, lst->qname, lst->attributes, lst->typeName); count++; break; default: case EJS_SECT_START: case EJS_SECT_END: mprAssert(0); break; } } if (count > 0) { lstEndModule(mp, module); } } mprCloseFile(mp->file); mp->file = 0; }
/* If the program has a UNIX style "#!/program" string at the start of the file that program will be selected and the original program will be passed as the first arg to that program with argv[] appended after that. If the program is not found, this routine supports a safe intelligent search for the command. If all else fails, we just return in program the fileName we were passed in. script will be set if we are modifying the program to run and we have extracted the name of the file to run as a script. */ static void findExecutable(HttpConn *conn, char **program, char **script, char **bangScript, cchar *fileName) { HttpRx *rx; HttpTx *tx; HttpRoute *route; MprKey *kp; MprFile *file; cchar *actionProgram, *ext, *cmdShell, *cp, *start, *path; char *tok, buf[ME_MAX_FNAME + 1]; rx = conn->rx; tx = conn->tx; route = rx->route; *bangScript = 0; *script = 0; *program = 0; path = 0; actionProgram = mprGetMimeProgram(rx->route->mimeTypes, rx->mimeType); ext = tx->ext; /* If not found, go looking for the fileName with the extensions defined in appweb.conf. NOTE: we don't use PATH deliberately!!! */ if (access(fileName, X_OK) < 0) { for (kp = 0; (kp = mprGetNextKey(route->extensions, kp)) != 0; ) { path = sjoin(fileName, ".", kp->key, NULL); if (access(path, X_OK) == 0) { break; } path = 0; } if (kp) { ext = kp->key; } else { path = fileName; } } else { path = fileName; } assert(path && *path); #if ME_WIN_LIKE if (ext && (strcmp(ext, ".bat") == 0 || strcmp(ext, ".cmd") == 0)) { /* Let a mime action override COMSPEC */ if (actionProgram) { cmdShell = actionProgram; } else { cmdShell = getenv("COMSPEC"); } if (cmdShell == 0) { cmdShell = "cmd.exe"; } *script = sclone(path); *program = sclone(cmdShell); return; } #endif if (actionProgram) { *program = sclone(actionProgram); } else if ((file = mprOpenFile(path, O_RDONLY, 0)) != 0) { if (mprReadFile(file, buf, ME_MAX_FNAME) > 0) { mprCloseFile(file); buf[ME_MAX_FNAME] = '\0'; if (buf[0] == '#' && buf[1] == '!') { cp = start = &buf[2]; cmdShell = stok(&buf[2], "\r\n", &tok); if (!mprIsPathAbs(cmdShell)) { /* If we can't access the command shell and the command is not an absolute path, look in the same directory as the script. */ if (mprPathExists(cmdShell, X_OK)) { cmdShell = mprJoinPath(mprGetPathDir(path), cmdShell); } } *program = sclone(cmdShell); *bangScript = sclone(path); return; } } else { mprCloseFile(file); } } if (actionProgram) { *program = sclone(actionProgram); *bangScript = sclone(path); } else { *program = sclone(path); } return; }
/* Encode the files as C code */ static int binToC(MprList *files, char *romName, char *prefix) { MprPath info; MprFile *file; char buf[512]; char *filename, *cp, *sl, *p; ssize len; int next, i, j; mprPrintf("/*\n %s -- Compiled Files\n */\n", romName); mprPrintf("#include \"mpr.h\"\n\n"); mprPrintf("#if BLD_FEATURE_ROMFS\n"); /* Open each input file and compile */ for (next = 0; (filename = mprGetNextItem(files, &next)) != 0; ) { if (mprGetPathInfo(filename, &info) == 0 && info.isDir) { continue; } if ((file = mprOpenFile(filename, O_RDONLY | O_BINARY, 0666)) < 0) { mprError("Can't open file %s\n", filename); return -1; } mprPrintf("static uchar _file_%d[] = {\n", next); while ((len = mprReadFile(file, buf, sizeof(buf))) > 0) { p = buf; for (i = 0; i < len; ) { mprPrintf(" "); for (j = 0; p < &buf[len] && j < 16; j++, p++) { mprPrintf("%3d,", (unsigned char) *p); } i += j; mprPrintf("\n"); } } mprPrintf(" 0 };\n\n"); mprCloseFile(file); } /* Now output the page index */ mprPrintf("MprRomInode %s[] = {\n", romName); for (next = 0; (filename = mprGetNextItem(files, &next)) != 0; ) { /* Replace the prefix with a leading "/" */ if (strncmp(filename, prefix, strlen(prefix)) == 0) { cp = &filename[strlen(prefix)]; } else { cp = filename; } while((sl = strchr(filename, '\\')) != NULL) { *sl = '/'; } if (*cp == '/') { cp++; } if (*cp == '.' && cp[1] == '\0') { cp++; } if (mprGetPathInfo(filename, &info) == 0 && info.isDir) { mprPrintf(" { \"%s\", 0, 0, 0 },\n", cp); continue; } mprPrintf(" { \"%s\", _file_%d, %d, %d },\n", cp, next, (int) info.size, next); } mprPrintf(" { 0, 0, 0, 0 },\n"); mprPrintf("};\n"); mprPrintf("#endif /* BLD_FEATURE_ROMFS */\n"); return 0; }