static int ConnCopy(Ns_Conn *conn, size_t tocopy, Ns_DString *dsPtr, Tcl_Channel chan, FILE *fp, int fd) { int nwrote, avail; int ncopy = (int) tocopy; char *next; if (NsConnContent(conn, &next, &avail) == NULL || avail < ncopy) { return NS_ERROR; } while (ncopy > 0) { if (dsPtr != NULL) { Ns_DStringNAppend(dsPtr, next, ncopy); nwrote = ncopy; } else if (chan != NULL) { nwrote = Tcl_Write(chan, next, ncopy); } else if (fp != NULL) { nwrote = fwrite(next, 1, (size_t) ncopy, fp); if (ferror(fp)) { nwrote = -1; } } else { nwrote = write(fd, next, (size_t)ncopy); } if (nwrote < 0) { return NS_ERROR; } ncopy -= nwrote; next += nwrote; NsConnSeek(conn, nwrote); } return NS_OK; }
int Ns_ConnReadLine(Ns_Conn *conn, Ns_DString *dsPtr, int *nreadPtr) { Conn *connPtr = (Conn *) conn; Driver *drvPtr = connPtr->drvPtr; char *eol, *next; int nread, ncopy, avail; if (NsConnContent(conn, &next, &avail) == NULL) { return NS_ERROR; } eol = memchr(next, '\n', avail); if (eol == NULL) { eol = next + avail; } nread = eol - next; if (nread > drvPtr->maxline) { return NS_ERROR; } ncopy = nread; ++nread; if (nreadPtr != NULL) { *nreadPtr = nread; } if (ncopy > 0 && eol[-1] == '\r') { --ncopy; } Ns_DStringNAppend(dsPtr, next, ncopy); NsConnSeek(conn, nread); return NS_OK; }
void Ns_QuoteHtml(Ns_DString *pds, char *string) { char *end, *next; end = string + strlen(string); do { next = Tcl_UtfNext(string); switch (*string) { case '<': Ns_DStringAppend(pds, "<"); break; case '>': Ns_DStringAppend(pds, ">"); break; case '&': Ns_DStringAppend(pds, "&"); break; case '\'': Ns_DStringAppend(pds, "'"); break; case '"': Ns_DStringAppend(pds, """); break; default: Ns_DStringNAppend(pds, string, next - string); break; } string = next; } while (string < end); }
static void SetUrl(Ns_Request *request, char *url, Tcl_Encoding encoding) { Ns_Conn *conn; Ns_DString ds1, ds2; char *p; Ns_DStringInit(&ds1); Ns_DStringInit(&ds2); /* * Look for a query string at the end of the URL. */ p = strchr(url, '?'); if (p != NULL) { *p++ = '\0'; if (request->query != NULL) { ns_free(request->query); } request->query = ns_strdup(p); } /* * Decode and normalize the URL. If the encoding isn't specified, * use the encoding of the current connection, if any. */ if (encoding == NULL && (conn = Ns_GetConn()) != NULL) { encoding = Ns_ConnGetUrlEncoding(conn); } p = Ns_DecodeUrlWithEncoding(&ds1, url, encoding); if (p == NULL) { p = url; } Ns_NormalizePath(&ds2, p); Ns_DStringTrunc(&ds1, 0); /* * Append a trailing slash to the normalized URL if the original URL * ended in slash that wasn't also the leading slash. */ while (*url == '/') { ++url; } if (*url != '\0' && url[strlen(url) - 1] == '/') { Ns_DStringAppend(&ds2, "/"); } request->url = ns_strdup(ds2.string); Ns_DStringFree(&ds2); /* * Build the urlv and set urlc. */ p = ns_strdup(request->url + 1); Ns_DStringNAppend(&ds1, (char *) &p, sizeof(char *)); while (*p != '\0') { if (*p == '/') { *p++ = '\0'; if (*p == '\0') { /* * Stop on a trailing slash. */ break; } Ns_DStringNAppend(&ds1, (char *) &p, sizeof(char *)); } ++p; } request->urlc = ds1.length / (sizeof(char *)); p = NULL; Ns_DStringNAppend(&ds1, (char *) &p, sizeof(char *)); request->urlv = (char **) ns_malloc((size_t)ds1.length); memcpy(request->urlv, ds1.string, (size_t)ds1.length); Ns_DStringFree(&ds1); }
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 }