static void testTransform(MprTestGroup *gp) { char *path; path = mprTransformPath("/", MPR_PATH_ABS); assert(mprIsPathAbs(path)); path = mprTransformPath("/", MPR_PATH_REL); assert(mprIsPathRel(path)); assert(path[0] == '.'); path = mprTransformPath("/", 0); assert(strcmp(path, "/") == 0); path = mprTransformPath("/", MPR_PATH_ABS); mprAssert(mprIsPathAbs(path)); #if BIT_WIN_LIKE || CYGWIN /* Test MapSeparators */ path = sclone("\\a\\b\\c\\d"); mprMapSeparators(path, '/'); assert(*path == '/'); assert(strchr(path, '\\') == 0); /* Test PortablePath */ path = sclone("\\a\\b\\c\\d"); path = mprGetPortablePath(path); mprAssert(*path == '/'); assert(strchr(path, '\\') == 0); assert(mprIsPathAbs(path)); #endif #if CYGWIN path = mprGetAbsPath("c:/a/b"); assert(smatch(path, "/cygdrive/c/a/b")); path = mprGetAbsPath("/a/b"); assert(smatch(path, "/a/b")); path = mprGetAbsPath("c:/cygwin/a/b"); assert(smatch(path, "/a/b")); path = mprGetWinPath("c:/a/b"); assert(smatch(path, "C:\\a\\b")); path = mprGetWinPath("/cygdrive/c/a/b"); assert(smatch(path, "C:\\a\\b")); #endif }
static void testAbsPath(MprTestGroup *gp) { char *path; #if MANUAL_TESTING path = mprNormalizePath("/"); path = mprNormalizePath("C:/"); path = mprNormalizePath("C:/abc"); path = mprNormalizePath(""); path = mprNormalizePath("c:abc"); path = mprNormalizePath("abc"); path = mprGetAbsPath("/"); path = mprGetAbsPath("C:/"); path = mprGetAbsPath("C:/abc"); path = mprGetAbsPath(""); path = mprGetAbsPath("c:abc"); path = mprGetAbsPath("abc"); #endif path = mprGetAbsPath(""); assert(mprIsPathAbs(path)); path = mprGetAbsPath("/"); assert(mprIsPathAbs(path)); path = mprGetAbsPath("../../../../../../../../../../.."); assert(mprIsPathAbs(path)); assert(mprIsPathAbs(mprGetAbsPath("Makefile"))); /* Manually check incase mprIsAbs gets it wrong */ path = mprGetAbsPath("Makefile"); assert(path && *path); assert(mprIsPathAbs(path)); #if BIT_WIN_LIKE assert(isalpha(path[0])); assert(path[1] == ':' && path[2] == '\\'); #elif BIT_UNIX_LIKE assert(path[0] == '/' && path[1] != '/'); #endif assert(strcmp(mprGetPathBase(path), "Makefile") == 0); }
static void testTemp(MprTestGroup *gp) { char *path; path = mprGetTempPath(NULL); assert(path && *path); assert(mprIsPathAbs(path)); assert(mprPathExists(path, F_OK)); mprDeletePath(path); }
static void testRelPath(MprTestGroup *gp) { char *path, *absPath; path = mprGetRelPath("Makefile", 0); assert(strcmp(path, "Makefile") == 0); path = mprNormalizePath("../a.b"); assert(strcmp(path, "../a.b") == 0); path = mprGetRelPath("/", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath("//", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath("/tmp", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath("/Unknown/someone/junk", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath("/Users/mob/junk", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath("/Users/mob/././../mob/junk", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath(".", 0); assert(strcmp(path, ".") == 0); path = mprGetRelPath("..", 0); assert(strcmp(path, "..") == 0); path = mprGetRelPath("/Users/mob/github/admin", 0); assert(sstarts(path, "..")); path = mprGetRelPath("/Users/mob/git", 0); path = mprGetRelPath("/Users/mob/git/mpr/test", 0); /* Can't really test the result of this */ absPath = mprGetAbsPath("Makefile"); assert(mprIsPathAbs(absPath)); path = mprGetRelPath(absPath, 0); assert(!mprIsPathAbs(path)); assert(strcmp(path, "Makefile") == 0); #if FUTURE // MOB - problem in that we don't know the cwd when testMpr runs // Test relative to an origin out = mprGetAbsPath("../../out"); cwd = mprGetCurrentPath(); assert(smatch(mprGetRelPath(cwd, out), "../src/test")); #endif }
/* Determine the windows program to invoke. Support UNIX style "#!/program" bang directives on windows. Also supports ".cmd" and ".bat" alternatives. */ static void prepWinProgram(MprCmd *cmd) { #if ME_WIN_LIKE MprFile *file; cchar *bat, *ext, *shell, *cp, *start; char bang[ME_MAX_FNAME + 1], *path, *pp; /* Map separators, convert carriage-returns and newlines to spaces and remove quotes on the command */ path = mprAlloc(slen(cmd->argv[0]) * 2 + 1); strcpy(path, cmd->argv[0]); for (pp = path; *pp; pp++) { if (*pp == '/') { *pp = '\\'; } else if (*pp == '\r' || *pp == '\n') { *pp = ' '; } } if (*path == '\"') { if ((pp = strrchr(++path, '"')) != 0) { *pp = '\0'; } path = sclone(path); } cmd->argv[0] = path; /* Support ".cmd" and ".bat" files that take precedence */ if ((ext = mprGetPathExt(path)) == 0) { if ((bat = mprSearchPath(mprJoinPathExt(path, ".cmd"), MPR_SEARCH_EXE, cmd->searchPath, NULL)) == 0) { bat = mprSearchPath(mprJoinPathExt(path, ".bat"), MPR_SEARCH_EXE, cmd->searchPath, NULL); } if (bat) { if ((shell = getenv("COMSPEC")) == 0) { shell = "cmd.exe"; } cmd->argv = mprRealloc((void*) cmd->argv, (cmd->argc + 4) * sizeof(char*)); memmove((void*) &cmd->argv[3], (void*) cmd->argv, sizeof(char*) * (cmd->argc + 1)); cmd->argv[0] = sclone(shell); cmd->argv[1] = sclone("/Q"); cmd->argv[2] = sclone("/C"); cmd->argv[3] = bat; cmd->argc += 3; cmd->argv[cmd->argc] = 0; return; } } if ((file = mprOpenFile(path, O_RDONLY, 0)) != 0) { if (mprReadFile(file, bang, ME_MAX_FNAME) > 0) { mprCloseFile(file); bang[ME_MAX_FNAME] = '\0'; if (bang[0] == '#' && bang[1] == '!') { cp = start = &bang[2]; shell = ssplit(&bang[2], "\r\n", NULL); if (!mprIsPathAbs(shell)) { /* If we cannot access the command shell and the command is not an absolute path, look in the same directory as the script. */ if (mprPathExists(shell, X_OK)) { shell = mprJoinPath(mprGetPathDir(path), shell); } } /* Get length of argv with NULL and add one */ assert(cmd->argv[cmd->argc] == 0); cmd->argv = mprRealloc((void*) cmd->argv, (cmd->argc + 2) * sizeof(char*)); cmd->argv[cmd->argc + 1] = 0; /* Copy up to make room to insert the shell argument. This copies the original NULL */ memmove((void*) &cmd->argv[1], (void*) cmd->argv, sizeof(char*) * cmd->argc); cmd->argv[0] = sclone(shell); cmd->argv[1] = path; cmd->argc += 1; assert(cmd->argv[cmd->argc] == 0); } } else { mprCloseFile(file); } } #endif }
/* 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 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 = ssplit(&buf[2], "\r\n", NULL); if (!mprIsPathAbs(cmdShell)) { /* If we cannot 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; }