char * Ns_ConfigGetPath(char *server, char *module, ...) { va_list ap; char *s; Ns_DString ds; Ns_Set *set; Ns_DStringInit(&ds); Ns_DStringAppend(&ds, "ns"); if (server != NULL) { Ns_DStringVarAppend(&ds, "/server/", server, NULL); } if (module != NULL) { Ns_DStringVarAppend(&ds, "/module/", module, NULL); } va_start(ap, module); while ((s = va_arg(ap, char *)) != NULL) { Ns_DStringAppend(&ds, "/"); while (*s != '\0' && ISSLASH(*s)) { ++s; } Ns_DStringAppend(&ds, s); while (ISSLASH(ds.string[ds.length - 1])) { ds.string[--ds.length] = '\0'; } } va_end(ap); set = Ns_ConfigGetSection(ds.string); Ns_DStringFree(&ds); return (set ? Ns_SetName(set) : NULL); }
int Ns_ParseHeader(Ns_Set *set, char *line, Ns_HeaderCaseDisposition disp) { char *key, *sep; char *value; int index; Ns_DString ds; /* * Header lines are first checked if they continue a previous * header indicated by any preceeding white space. Otherwise, * they must be in well form key: value form. */ if (isspace(UCHAR(*line))) { index = Ns_SetLast(set); if (index < 0) { return NS_ERROR; /* Continue before first header. */ } while (isspace(UCHAR(*line))) { ++line; } if (*line != '\0') { value = Ns_SetValue(set, index); Ns_DStringInit(&ds); Ns_DStringVarAppend(&ds, value, " ", line, NULL); Ns_SetPutValue(set, index, ds.string); Ns_DStringFree(&ds); } } else { sep = strchr(line, ':'); if (sep == NULL) { return NS_ERROR; /* Malformed header. */ } *sep = '\0'; value = sep + 1; while (*value != '\0' && isspace(UCHAR(*value))) { ++value; } index = Ns_SetPut(set, line, value); key = Ns_SetKey(set, index); if (disp == ToLower) { while (*key != '\0') { if (isupper(UCHAR(*key))) { *key = tolower(UCHAR(*key)); } ++key; } } else if (disp == ToUpper) { while (*key != '\0') { if (islower(UCHAR(*key))) { *key = toupper(UCHAR(*key)); } ++key; } } *sep = ':'; } return NS_OK; }
int Ns_AbsoluteUrl(Ns_DString *dsPtr, char *url, char *base) { char *protocol, *host, *port, *path, *tail, *baseprotocol, *basehost, *baseport, *basepath, *basetail; int status = NS_OK; /* * Copy the URL's to allow Ns_ParseUrl to destory them. */ url = ns_strdup(url); base = ns_strdup(base); Ns_ParseUrl(url, &protocol, &host, &port, &path, &tail); Ns_ParseUrl(base, &baseprotocol, &basehost, &baseport, &basepath, &basetail); if (baseprotocol == NULL || basehost == NULL || basepath == NULL) { status = NS_ERROR; goto done; } if (protocol == NULL) { protocol = baseprotocol; } if (host == NULL) { host = basehost; port = baseport; } if (path == NULL) { path = basepath; } Ns_DStringVarAppend(dsPtr, protocol, "://", host, NULL); if (port != NULL) { Ns_DStringVarAppend(dsPtr, ":", port, NULL); } if (*path == '\0') { Ns_DStringVarAppend(dsPtr, "/", tail, NULL); } else { Ns_DStringVarAppend(dsPtr, "/", path, "/", tail, NULL); } done: ns_free(url); ns_free(base); return status; }
int Ns_ExecArgv(char *exec, char *dir, int fdin, int fdout, char **argv, Ns_Set *env) { #ifdef _WIN32 /* * Win32 ExecArgv simply calls ExecArgblk. */ int pid; Ns_DString ads; char *args; int i; Ns_DStringInit(&ads); if (argv == NULL) { args = NULL; } else { for (i = 0; argv[i] != NULL; ++i) { Ns_DStringNAppend(&ads, argv[i], strlen(argv[i]) + 1); } args = ads.string; } pid = Ns_ExecArgblk(exec, dir, fdin, fdout, args, env); Ns_DStringFree(&ads); return pid; #else Ns_DString eds; char *argvSh[4], **envp; int i, pid; if (exec == NULL) { return -1; } if (argv == NULL) { argv = argvSh; argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = exec; argv[3] = NULL; exec = argv[0]; } Ns_DStringInit(&eds); if (env == NULL) { envp = Ns_CopyEnviron(&eds); } else { for (i = 0; i < Ns_SetSize(env); ++i) { Ns_DStringVarAppend(&eds, Ns_SetKey(env, i), "=", Ns_SetValue(env, i), NULL); Ns_DStringNAppend(&eds, "", 1); } Ns_DStringNAppend(&eds, "", 1); envp = Ns_DStringAppendArgv(&eds); } if (fdin < 0) { fdin = 0; } if (fdout < 0) { fdout = 1; } pid = ExecProc(exec, dir, fdin, fdout, argv, envp); Ns_DStringFree(&eds); return pid; #endif }
int Ns_ExecArgblk(char *exec, char *dir, int fdin, int fdout, char *args, Ns_Set *env) { #ifndef _WIN32 int pid; char **argv; Ns_DString vds; Ns_DStringInit(&vds); if (args == NULL) { argv = NULL; } else { while (*args != '\0') { Ns_DStringNAppend(&vds, (char *) &args, sizeof(args)); args += strlen(args) + 1; } args = NULL; Ns_DStringNAppend(&vds, (char *) &args, sizeof(args)); argv = (char **) vds.string; } pid = Ns_ExecArgv(exec, dir, fdin, fdout, argv, env); Ns_DStringFree(&vds); return pid; #else STARTUPINFO si; PROCESS_INFORMATION pi; HANDLE hCurrentProcess; int pid; Ns_DString cds, xds, eds; char *envp; OSVERSIONINFO oinfo; char *cmd; if (exec == NULL) { return -1; } oinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (GetVersionEx(&oinfo) == TRUE && oinfo.dwPlatformId != VER_PLATFORM_WIN32_NT) { cmd = "command.com"; } else { cmd = "cmd.exe"; } /* * Setup STARTUPINFO with stdin, stdout, and stderr. */ memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdError = (HANDLE) _get_osfhandle(_fileno(stderr)); hCurrentProcess = GetCurrentProcess(); if (fdout < 0) { fdout = 1; } if (DuplicateHandle(hCurrentProcess, (HANDLE) _get_osfhandle(fdout), hCurrentProcess, &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS) != TRUE) { Ns_Log(Error, "exec: failed to duplicate handle: %s", NsWin32ErrMsg(GetLastError())); return -1; } if (fdin < 0) { fdin = 0; } if (DuplicateHandle(hCurrentProcess, (HANDLE) _get_osfhandle(fdin), hCurrentProcess, &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS) != TRUE) { Ns_Log(Error, "exec: failed to duplicate handle: %s", NsWin32ErrMsg(GetLastError())); (void) CloseHandle(si.hStdOutput); return -1; } /* * Setup the command line and environment block and create the new * subprocess. */ Ns_DStringInit(&cds); Ns_DStringInit(&xds); Ns_DStringInit(&eds); if (args == NULL) { /* NB: exec specifies a complete cmd.exe command string. */ Ns_DStringVarAppend(&cds, cmd, " /c ", exec, NULL); exec = NULL; } else { char *s; s = args; while (*s != '\0') { int len; len = strlen(s); Ns_DStringNAppend(&cds, s, len); s += len + 1; if (*s != '\0') { Ns_DStringNAppend(&cds, " ", 1); } } Ns_NormalizePath(&xds, exec); s = xds.string; while (*s != '\0') { if (*s == '/') { *s = '\\'; } ++s; } exec = xds.string; } if (env == NULL) { envp = NULL; } else { Set2Argv(&eds, env); envp = eds.string; } if (CreateProcess(exec, cds.string, NULL, NULL, TRUE, 0, envp, dir, &si, &pi) != TRUE) { Ns_Log(Error, "exec: failed to create process: %s: %s", exec ? exec : cds.string, NsWin32ErrMsg(GetLastError())); pid = -1; } else { CloseHandle(pi.hThread); pid = (int) pi.hProcess; } Ns_DStringFree(&cds); Ns_DStringFree(&xds); Ns_DStringFree(&eds); CloseHandle(si.hStdInput); CloseHandle(si.hStdOutput); return pid; #endif }